2021-12-07 10:18:01 +02:00
package twitterscraper_test
2019-09-21 12:18:34 +03:00
import (
2020-06-12 21:31:08 +08:00
"context"
2023-07-02 01:41:48 +03:00
"os"
2019-09-21 12:18:34 +03:00
"testing"
2021-03-09 10:40:22 +02:00
"time"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
2021-12-07 10:18:01 +02:00
twitterscraper "github.com/n0madic/twitter-scraper"
2019-09-21 12:18:34 +03:00
)
2021-07-30 14:46:38 +03:00
var cmpOptions = cmp . Options {
2021-12-07 10:18:01 +02:00
cmpopts . IgnoreFields ( twitterscraper . Tweet { } , "Likes" ) ,
cmpopts . IgnoreFields ( twitterscraper . Tweet { } , "Replies" ) ,
cmpopts . IgnoreFields ( twitterscraper . Tweet { } , "Retweets" ) ,
2021-07-30 14:46:38 +03:00
}
2019-09-21 12:18:34 +03:00
func TestGetTweets ( t * testing . T ) {
count := 0
2020-12-11 20:58:49 +02:00
maxTweetsNbr := 300
dupcheck := make ( map [ string ] bool )
2022-05-04 11:55:12 +03:00
scraper := twitterscraper . New ( )
2023-07-02 01:41:48 +03:00
err := scraper . LoginOpenAccount ( )
if err != nil {
t . Fatalf ( "LoginOpenAccount() error = %v" , err )
}
2022-05-04 11:55:12 +03:00
for tweet := range scraper . GetTweets ( context . Background ( ) , "Twitter" , maxTweetsNbr ) {
2019-09-21 12:18:34 +03:00
if tweet . Error != nil {
t . Error ( tweet . Error )
} else {
count ++
if tweet . ID == "" {
2021-04-22 20:35:33 +03:00
t . Error ( "Expected tweet ID is empty" )
2020-12-11 20:58:49 +02:00
} else {
if dupcheck [ tweet . ID ] {
t . Errorf ( "Detect duplicated tweet ID: %s" , tweet . ID )
} else {
dupcheck [ tweet . ID ] = true
}
}
if tweet . UserID == "" {
2021-04-22 20:35:33 +03:00
t . Error ( "Expected tweet UserID is empty" )
2019-09-21 12:18:34 +03:00
}
2020-06-15 16:38:51 +03:00
if tweet . Username == "" {
2021-04-22 20:35:33 +03:00
t . Error ( "Expected tweet Username is empty" )
2020-06-15 16:38:51 +03:00
}
2019-09-21 12:18:34 +03:00
if tweet . PermanentURL == "" {
2021-04-22 20:35:33 +03:00
t . Error ( "Expected tweet PermanentURL is empty" )
2019-09-21 12:18:34 +03:00
}
if tweet . Text == "" {
2021-04-22 20:35:33 +03:00
t . Error ( "Expected tweet Text is empty" )
2019-09-21 12:18:34 +03:00
}
if tweet . TimeParsed . IsZero ( ) {
2021-04-22 20:35:33 +03:00
t . Error ( "Expected tweet TimeParsed is zero" )
2019-09-21 12:18:34 +03:00
}
if tweet . Timestamp == 0 {
t . Error ( "Expected tweet Timestamp is greater than zero" )
}
2020-12-11 20:58:49 +02:00
for _ , video := range tweet . Videos {
if video . ID == "" {
2021-04-22 20:35:33 +03:00
t . Error ( "Expected tweet video ID is empty" )
2020-12-11 20:58:49 +02:00
}
if video . Preview == "" {
2021-04-22 20:35:33 +03:00
t . Error ( "Expected tweet video Preview is empty" )
2020-12-11 20:58:49 +02:00
}
if video . URL == "" {
2021-04-22 20:35:33 +03:00
t . Error ( "Expected tweet video URL is empty" )
2020-12-11 20:58:49 +02:00
}
}
2019-09-21 12:18:34 +03:00
}
}
2020-06-15 16:16:08 +03:00
if count != maxTweetsNbr {
t . Errorf ( "Expected tweets count=%v, got: %v" , maxTweetsNbr , count )
2019-09-21 12:18:34 +03:00
}
}
2021-03-09 10:40:22 +02:00
2023-06-18 19:13:26 +02:00
func assertGetTweet ( t * testing . T , expectedTweet * twitterscraper . Tweet ) {
2023-07-03 15:06:56 +03:00
actualTweet , err := testScraper . GetTweet ( expectedTweet . ID )
2023-06-18 19:13:26 +02:00
if err != nil {
t . Error ( err )
} else if diff := cmp . Diff ( expectedTweet , actualTweet , cmpOptions ... ) ; diff != "" {
t . Error ( "Resulting tweet does not match the sample" , diff )
}
}
func TestGetTweetWithVideo ( t * testing . T ) {
expectedTweet := twitterscraper . Tweet {
2023-06-05 13:49:56 +03:00
ConversationID : "1328684389388185600" ,
HTML : "That thing you didn’ t Tweet but wanted to but didn’ t but got so close but then were like nah. <br><br>We have a place for that now—Fleets! <br><br>Rolling out to everyone starting today. <br><a href=\"https://t.co/auQAHXZMfH\"><img src=\"https://pbs.twimg.com/amplify_video_thumb/1328684333599756289/img/cP5KwbIXbGunNSBy.jpg\"/></a>" ,
ID : "1328684389388185600" ,
Name : "Twitter" ,
PermanentURL : "https://twitter.com/Twitter/status/1328684389388185600" ,
Photos : nil ,
Text : "That thing you didn’ t Tweet but wanted to but didn’ t but got so close but then were like nah. \n\nWe have a place for that now—Fleets! \n\nRolling out to everyone starting today. https://t.co/auQAHXZMfH" ,
TimeParsed : time . Date ( 2020 , 11 , 17 , 13 , 0 , 18 , 0 , time . FixedZone ( "UTC" , 0 ) ) ,
Timestamp : 1605618018 ,
UserID : "783214" ,
Username : "Twitter" ,
2021-12-07 10:18:01 +02:00
Videos : [ ] twitterscraper . Video { {
2021-03-09 10:40:22 +02:00
ID : "1328684333599756289" ,
Preview : "https://pbs.twimg.com/amplify_video_thumb/1328684333599756289/img/cP5KwbIXbGunNSBy.jpg" ,
2021-09-13 17:04:23 +03:00
URL : "https://video.twimg.com/amplify_video/1328684333599756289/vid/960x720/PcL8yv8KhgQ48Qpt.mp4?tag=13" ,
2021-03-09 10:40:22 +02:00
} } ,
}
2023-06-18 19:13:26 +02:00
assertGetTweet ( t , & expectedTweet )
}
func TestGetTweetWithMultiplePhotos ( t * testing . T ) {
expectedTweet := twitterscraper . Tweet {
ConversationID : "1390026628957417473" ,
HTML : ` no bird too tall, no crop too short<br><br>introducing bigger and better images on iOS and Android, now available to everyone <br><a href="https://t.co/2buHfhfRAx"><img src="https://pbs.twimg.com/media/E0pd2L2XEAQ_gnn.jpg"/></a><br><img src="https://pbs.twimg.com/media/E0pd2hPXoAY9-TZ.jpg"/> ` ,
ID : "1390026628957417473" ,
Name : "Twitter" ,
PermanentURL : "https://twitter.com/Twitter/status/1390026628957417473" ,
Photos : [ ] twitterscraper . Photo {
{ ID : "1390026620472332292" , URL : "https://pbs.twimg.com/media/E0pd2L2XEAQ_gnn.jpg" } ,
{ ID : "1390026626214371334" , URL : "https://pbs.twimg.com/media/E0pd2hPXoAY9-TZ.jpg" } ,
} ,
Text : "no bird too tall, no crop too short\n\nintroducing bigger and better images on iOS and Android, now available to everyone https://t.co/2buHfhfRAx" ,
TimeParsed : time . Date ( 2021 , 5 , 5 , 19 , 32 , 28 , 0 , time . FixedZone ( "UTC" , 0 ) ) ,
Timestamp : 1620243148 ,
UserID : "783214" ,
Username : "Twitter" ,
}
assertGetTweet ( t , & expectedTweet )
}
func TestGetTweetWithGIF ( t * testing . T ) {
2023-07-02 01:41:48 +03:00
if os . Getenv ( "SKIP_AUTH_TEST" ) != "" {
t . Skip ( "Skipping test due to environment variable" )
}
2023-06-18 19:13:26 +02:00
expectedTweet := twitterscraper . Tweet {
ConversationID : "1288540609310056450" ,
GIFs : [ ] twitterscraper . GIF {
{
ID : "1288540582768517123" ,
Preview : "https://pbs.twimg.com/tweet_video_thumb/EeHQ1UKXoAMVxWB.jpg" ,
URL : "https://video.twimg.com/tweet_video/EeHQ1UKXoAMVxWB.mp4" ,
} ,
} ,
Hashtags : [ ] string { "CountdownToMars" } ,
HTML : ` Like for liftoff! <a href="https://twitter.com/hashtag/CountdownToMars">#CountdownToMars</a> <br><a href="https://t.co/yLe331pHfY"><img src="https://pbs.twimg.com/tweet_video_thumb/EeHQ1UKXoAMVxWB.jpg"/></a> ` ,
ID : "1288540609310056450" ,
Name : "Twitter" ,
PermanentURL : "https://twitter.com/Twitter/status/1288540609310056450" ,
Text : "Like for liftoff! #CountdownToMars https://t.co/yLe331pHfY" ,
TimeParsed : time . Date ( 2020 , 7 , 29 , 18 , 23 , 15 , 0 , time . FixedZone ( "UTC" , 0 ) ) ,
Timestamp : 1596046995 ,
UserID : "783214" ,
Username : "Twitter" ,
}
assertGetTweet ( t , & expectedTweet )
}
func TestGetTweetWithPhotoAndGIF ( t * testing . T ) {
2023-07-02 01:41:48 +03:00
if os . Getenv ( "SKIP_AUTH_TEST" ) != "" {
t . Skip ( "Skipping test due to environment variable" )
}
2023-06-18 19:13:26 +02:00
expectedTweet := twitterscraper . Tweet {
ConversationID : "1580661436132757506" ,
GIFs : [ ] twitterscraper . GIF {
{
ID : "1580661428335382531" ,
Preview : "https://pbs.twimg.com/tweet_video_thumb/Fe-jMcIXkAMXK_W.jpg" ,
URL : "https://video.twimg.com/tweet_video/Fe-jMcIXkAMXK_W.mp4" ,
} ,
} ,
HTML : ` a hit Tweet <br><a href="https://t.co/2C7cah4KzW"><img src="https://pbs.twimg.com/media/Fe-jMcGWQAAFWoG.jpg"/></a><br><img src="https://pbs.twimg.com/tweet_video_thumb/Fe-jMcIXkAMXK_W.jpg"/> ` ,
ID : "1580661436132757506" ,
Name : "Twitter" ,
PermanentURL : "https://twitter.com/Twitter/status/1580661436132757506" ,
Photos : [ ] twitterscraper . Photo { { ID : "1580661428326907904" , URL : "https://pbs.twimg.com/media/Fe-jMcGWQAAFWoG.jpg" } } ,
Text : "a hit Tweet https://t.co/2C7cah4KzW" ,
TimeParsed : time . Date ( 2022 , 10 , 13 , 20 , 47 , 8 , 0 , time . FixedZone ( "UTC" , 0 ) ) ,
Timestamp : 1665694028 ,
UserID : "783214" ,
Username : "Twitter" ,
2021-03-09 10:40:22 +02:00
}
2023-06-18 19:13:26 +02:00
assertGetTweet ( t , & expectedTweet )
2021-03-09 10:40:22 +02:00
}
2021-03-28 12:25:55 +03:00
2023-05-10 05:02:21 -07:00
func TestTweetMentions ( t * testing . T ) {
sample := [ ] twitterscraper . Mention { {
ID : "7018222" ,
Username : "davidmcraney" ,
Name : "David McRaney" ,
} }
2023-07-03 15:06:56 +03:00
tweet , err := testScraper . GetTweet ( "1554522888904101890" )
2023-05-10 05:02:21 -07:00
if err != nil {
t . Error ( err )
} else {
if diff := cmp . Diff ( sample , tweet . Mentions , cmpOptions ... ) ; diff != "" {
t . Error ( "Resulting tweet does not match the sample" , diff )
2021-03-09 10:40:22 +02:00
}
}
}
2021-03-28 12:25:55 +03:00
2021-07-16 12:21:41 +03:00
func TestQuotedAndReply ( t * testing . T ) {
2021-12-07 10:18:01 +02:00
sample := & twitterscraper . Tweet {
2023-06-05 13:49:56 +03:00
ConversationID : "1237110546383724547" ,
HTML : "The Easiest Problem Everyone Gets Wrong <br><br>[new video] --> <a href=\"https://youtu.be/ytfCdqWhmdg\">https://t.co/YdaeDYmPAU</a> <br><a href=\"https://t.co/iKu4Xs6o2V\"><img src=\"https://pbs.twimg.com/media/ESsZa9AXgAIAYnF.jpg\"/></a>" ,
ID : "1237110546383724547" ,
Likes : 485 ,
Name : "Vsauce2" ,
PermanentURL : "https://twitter.com/VsauceTwo/status/1237110546383724547" ,
2023-05-10 03:18:34 -07:00
Photos : [ ] twitterscraper . Photo { {
ID : "1237110473486729218" ,
URL : "https://pbs.twimg.com/media/ESsZa9AXgAIAYnF.jpg" ,
} } ,
Replies : 12 ,
Retweets : 18 ,
Text : "The Easiest Problem Everyone Gets Wrong \n\n[new video] --> https://t.co/YdaeDYmPAU https://t.co/iKu4Xs6o2V" ,
TimeParsed : time . Date ( 2020 , 0 o3 , 9 , 20 , 18 , 33 , 0 , time . FixedZone ( "UTC" , 0 ) ) ,
Timestamp : 1583785113 ,
URLs : [ ] string { "https://youtu.be/ytfCdqWhmdg" } ,
UserID : "978944851" ,
Username : "VsauceTwo" ,
2021-07-16 12:21:41 +03:00
}
2023-07-03 15:06:56 +03:00
tweet , err := testScraper . GetTweet ( "1237110897597976576" )
2021-07-16 12:21:41 +03:00
if err != nil {
t . Error ( err )
} else {
2021-07-16 12:39:11 +03:00
if ! tweet . IsQuoted {
t . Error ( "IsQuoted must be True" )
}
2021-08-09 14:02:35 +03:00
if diff := cmp . Diff ( sample , tweet . QuotedStatus , cmpOptions ... ) ; diff != "" {
2021-07-16 12:21:41 +03:00
t . Error ( "Resulting quote does not match the sample" , diff )
}
}
2023-07-03 15:06:56 +03:00
tweet , err = testScraper . GetTweet ( "1237111868445134850" )
2021-07-16 12:21:41 +03:00
if err != nil {
t . Error ( err )
} else {
2021-07-16 12:39:11 +03:00
if ! tweet . IsReply {
t . Error ( "IsReply must be True" )
}
2021-08-09 14:02:35 +03:00
if diff := cmp . Diff ( sample , tweet . InReplyToStatus , cmpOptions ... ) ; diff != "" {
2021-07-16 12:21:41 +03:00
t . Error ( "Resulting reply does not match the sample" , diff )
}
}
}
2021-03-28 12:25:55 +03:00
func TestRetweet ( t * testing . T ) {
2021-12-07 10:18:01 +02:00
sample := & twitterscraper . Tweet {
2023-06-05 13:49:56 +03:00
ConversationID : "1359151057872580612" ,
HTML : "We’ ve seen an increase in attacks against Asian communities and individuals around the world. It’ s important to know that this isn’ t new; throughout history, Asians have experienced violence and exclusion. However, their diverse lived experiences have largely been overlooked." ,
ID : "1359151057872580612" ,
2023-07-03 15:06:56 +03:00
IsSelfThread : false ,
2023-06-05 13:49:56 +03:00
Likes : 6683 ,
Name : "Twitter Together" ,
PermanentURL : "https://twitter.com/TwitterTogether/status/1359151057872580612" ,
Replies : 456 ,
Retweets : 1495 ,
Text : "We’ ve seen an increase in attacks against Asian communities and individuals around the world. It’ s important to know that this isn’ t new; throughout history, Asians have experienced violence and exclusion. However, their diverse lived experiences have largely been overlooked." ,
TimeParsed : time . Date ( 2021 , 02 , 9 , 14 , 43 , 58 , 0 , time . FixedZone ( "UTC" , 0 ) ) ,
Timestamp : 1612881838 ,
UserID : "773578328498372608" ,
Username : "TwitterTogether" ,
2021-03-28 12:25:55 +03:00
}
2023-07-03 15:06:56 +03:00
tweet , err := testScraper . GetTweet ( "1362849141248974853" )
2021-03-28 12:25:55 +03:00
if err != nil {
t . Error ( err )
} else {
2021-07-16 12:39:11 +03:00
if ! tweet . IsRetweet {
t . Error ( "IsRetweet must be True" )
}
2021-07-30 14:46:38 +03:00
if diff := cmp . Diff ( sample , tweet . RetweetedStatus , cmpOptions ... ) ; diff != "" {
2021-03-28 12:25:55 +03:00
t . Error ( "Resulting retweet does not match the sample" , diff )
}
}
}
2023-05-18 15:51:03 -04:00
func TestTweetViews ( t * testing . T ) {
sample := & twitterscraper . Tweet {
HTML : "Replies and likes don’ t tell the whole story. We’ re making it easier to tell *just* how many people have seen your Tweets with the addition of view counts, shown right next to likes. Now on iOS and Android, web coming soon." ,
ID : "1606055187348688896" ,
Likes : 2839 ,
Name : "Twitter Support" ,
PermanentURL : "https://twitter.com/TwitterSupport/status/1606055187348688896" ,
Replies : 3427 ,
Retweets : 783 ,
Text : "Replies and likes don’ t tell the whole story. We’ re making it easier to tell *just* how many people have seen your Tweets with the addition of view counts, shown right next to likes. Now on iOS and Android, web coming soon." ,
TimeParsed : time . Date ( 2022 , 12 , 22 , 22 , 32 , 50 , 0 , time . FixedZone ( "UTC" , 0 ) ) ,
Timestamp : 1612881838 ,
UserID : "17874544" ,
Username : "TwitterSupport" ,
Views : 3189278 ,
}
2023-07-03 15:06:56 +03:00
tweet , err := testScraper . GetTweet ( "1606055187348688896" )
2023-05-18 15:51:03 -04:00
if err != nil {
t . Error ( err )
} else {
if tweet . Views < sample . Views {
t . Error ( "Views must be greater than or equal to the sample" )
}
}
}
2023-06-05 13:49:56 +03:00
func TestTweetThread ( t * testing . T ) {
2023-07-02 01:41:48 +03:00
if os . Getenv ( "SKIP_AUTH_TEST" ) != "" {
t . Skip ( "Skipping test due to environment variable" )
}
2023-07-03 15:06:56 +03:00
tweet , err := testScraper . GetTweet ( "1665602315745673217" )
2023-06-05 13:49:56 +03:00
if err != nil {
t . Fatal ( err )
} else {
if ! tweet . IsSelfThread {
t . Error ( "IsSelfThread must be True" )
}
if len ( tweet . Thread ) != 7 {
t . Error ( "Thread length must be 7" )
}
}
}