-
Notifications
You must be signed in to change notification settings - Fork 65
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feature/issue 54 tweet recent counts (#55)
* tweet recent counts initial commit * added unit tests * added a example * update README.md * added comments * use enum for granularity update a example * replace TweetCountsRaw to []*TweetCount
- Loading branch information
1 parent
010a699
commit b6f7281
Showing
7 changed files
with
393 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"flag" | ||
"fmt" | ||
"log" | ||
"net/http" | ||
|
||
twitter "github.com/g8rswimmer/go-twitter/v2" | ||
) | ||
|
||
type authorize struct { | ||
Token string | ||
} | ||
|
||
func (a authorize) Add(req *http.Request) { | ||
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", a.Token)) | ||
} | ||
func main() { | ||
token := flag.String("token", "", "twitter API token") | ||
query := flag.String("query", "", "twitter query") | ||
flag.Parse() | ||
|
||
client := &twitter.Client{ | ||
Authorizer: authorize{ | ||
Token: *token, | ||
}, | ||
Client: http.DefaultClient, | ||
Host: "https://api.twitter.com", | ||
} | ||
opts := twitter.TweetRecentCountsOpts{ | ||
Granularity: twitter.GranularityHour, | ||
} | ||
|
||
fmt.Println("Callout to tweet recent counts callout") | ||
|
||
tweetResponse, err := client.TweetRecentCounts(context.Background(), *query, opts) | ||
if err != nil { | ||
log.Panicf("tweet recent counts error: %v", err) | ||
} | ||
|
||
enc, err := json.MarshalIndent(tweetResponse.TweetCounts, "", " ") | ||
if err != nil { | ||
log.Panic(err) | ||
} | ||
fmt.Println(string(enc)) | ||
|
||
metaBytes, err := json.MarshalIndent(tweetResponse.Meta, "", " ") | ||
if err != nil { | ||
log.Panic(err) | ||
} | ||
fmt.Println(string(metaBytes)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,206 @@ | ||
package twitter | ||
|
||
import ( | ||
"context" | ||
"io/ioutil" | ||
"log" | ||
"net/http" | ||
"reflect" | ||
"strings" | ||
"testing" | ||
"time" | ||
) | ||
|
||
func TestClient_TweetRecentCounts(t *testing.T) { | ||
type fields struct { | ||
Authorizer Authorizer | ||
Client *http.Client | ||
Host string | ||
} | ||
type args struct { | ||
query string | ||
opts TweetRecentCountsOpts | ||
} | ||
tests := []struct { | ||
name string | ||
fields fields | ||
args args | ||
want *TweetRecentCountsResponse | ||
wantErr bool | ||
}{ | ||
{ | ||
name: "success", | ||
fields: fields{ | ||
Authorizer: &mockAuth{}, | ||
Host: "https://www.test.com", | ||
Client: mockHTTPClient(func(req *http.Request) *http.Response { | ||
if req.Method != http.MethodGet { | ||
log.Panicf("the method is not correct %s %s", req.Method, http.MethodGet) | ||
} | ||
if strings.Contains(req.URL.String(), string(tweetRecentCountsEndpoint)) == false { | ||
log.Panicf("the url is not correct %s %s", req.URL.String(), tweetRecentCountsEndpoint) | ||
} | ||
body := `{ | ||
"data": [ | ||
{ | ||
"end": "2021-05-27t00:00:00.000z", | ||
"start": "2021-05-26t23:00:00.000z", | ||
"tweet_count": 2 | ||
}, | ||
{ | ||
"end": "2021-05-27t01:00:00.000z", | ||
"start": "2021-05-27t00:00:00.000z", | ||
"tweet_count": 2 | ||
} | ||
], | ||
"meta": { | ||
"total_tweet_count": 4 | ||
} | ||
}` | ||
return &http.Response{ | ||
StatusCode: http.StatusOK, | ||
Body: ioutil.NopCloser(strings.NewReader(body)), | ||
} | ||
}), | ||
}, | ||
args: args{ | ||
query: "python", | ||
}, | ||
want: &TweetRecentCountsResponse{ | ||
TweetCounts: []*TweetCount{ | ||
{ | ||
End: "2021-05-27t00:00:00.000z", | ||
Start: "2021-05-26t23:00:00.000z", | ||
TweetCount: 2, | ||
}, | ||
{ | ||
End: "2021-05-27t01:00:00.000z", | ||
Start: "2021-05-27t00:00:00.000z", | ||
TweetCount: 2, | ||
}, | ||
}, | ||
Meta: &TweetRecentCountsMeta{ | ||
TotalTweetCount: 4, | ||
}, | ||
}, | ||
wantErr: false, | ||
}, | ||
{ | ||
name: "success-optional", | ||
fields: fields{ | ||
Authorizer: &mockAuth{}, | ||
Host: "https://www.test.com", | ||
Client: mockHTTPClient(func(req *http.Request) *http.Response { | ||
if req.Method != http.MethodGet { | ||
log.Panicf("the method is not correct %s %s", req.Method, http.MethodGet) | ||
} | ||
if strings.Contains(req.URL.String(), string(tweetRecentCountsEndpoint)) == false { | ||
log.Panicf("the url is not correct %s %s", req.URL.String(), tweetRecentCountsEndpoint) | ||
} | ||
body := `{ | ||
"data": [ | ||
{ | ||
"start": "2021-10-08T15:29:42.000Z", | ||
"end": "2021-10-09T00:00:00.000Z", | ||
"tweet_count": 2 | ||
}, | ||
{ | ||
"start": "2021-10-09T00:00:00.000Z", | ||
"end": "2021-10-09T15:29:33.000Z", | ||
"tweet_count": 2 | ||
} | ||
], | ||
"meta": { | ||
"total_tweet_count": 4 | ||
} | ||
}` | ||
return &http.Response{ | ||
StatusCode: http.StatusOK, | ||
Body: ioutil.NopCloser(strings.NewReader(body)), | ||
} | ||
}), | ||
}, | ||
args: args{ | ||
query: "python", | ||
opts: TweetRecentCountsOpts{ | ||
StartTime: time.Now().Add(-24 * time.Hour), | ||
Granularity: Granularity("day"), | ||
}, | ||
}, | ||
want: &TweetRecentCountsResponse{ | ||
TweetCounts: []*TweetCount{ | ||
{ | ||
End: "2021-10-09T00:00:00.000Z", | ||
Start: "2021-10-08T15:29:42.000Z", | ||
TweetCount: 2, | ||
}, | ||
{ | ||
End: "2021-10-09T15:29:33.000Z", | ||
Start: "2021-10-09T00:00:00.000Z", | ||
TweetCount: 2, | ||
}, | ||
}, | ||
Meta: &TweetRecentCountsMeta{ | ||
TotalTweetCount: 4, | ||
}, | ||
}, | ||
wantErr: false, | ||
}, | ||
{ | ||
name: "Bad Request", | ||
fields: fields{ | ||
Authorizer: &mockAuth{}, | ||
Host: "https://www.test.com", | ||
Client: mockHTTPClient(func(req *http.Request) *http.Response { | ||
if req.Method != http.MethodGet { | ||
log.Panicf("the method is not correct %s %s", req.Method, http.MethodGet) | ||
} | ||
if strings.Contains(req.URL.String(), string(tweetRecentCountsEndpoint)) == false { | ||
log.Panicf("the url is not correct %s %s", req.URL.String(), tweetRecentCountsEndpoint) | ||
} | ||
body := `{ | ||
"errors": [ | ||
{ | ||
"parameters": { | ||
"id": [ | ||
"aassd" | ||
] | ||
}, | ||
"message": "The id query parameter value [aassd] does not match ^[0-9]{1,19}$" | ||
} | ||
], | ||
"title": "Invalid Request", | ||
"detail": "One or more parameters to your request was invalid.", | ||
"type": "https://api.twitter.com/2/problems/invalid-request" | ||
}` | ||
return &http.Response{ | ||
StatusCode: http.StatusBadRequest, | ||
Body: ioutil.NopCloser(strings.NewReader(body)), | ||
} | ||
}), | ||
}, | ||
args: args{ | ||
query: "nothing", | ||
}, | ||
want: nil, | ||
wantErr: true, | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
c := &Client{ | ||
Authorizer: tt.fields.Authorizer, | ||
Client: tt.fields.Client, | ||
Host: tt.fields.Host, | ||
} | ||
got, err := c.TweetRecentCounts(context.Background(), tt.args.query, tt.args.opts) | ||
if (err != nil) != tt.wantErr { | ||
t.Errorf("Client.TweetRecentCounts() error = %v, wantErr %v", err, tt.wantErr) | ||
return | ||
} | ||
if !reflect.DeepEqual(got, tt.want) { | ||
t.Errorf("Client.TweetRecentCounts() = %v, want %v", got, tt.want) | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package twitter | ||
|
||
// TweetRecentCountsResponse contains all of the information from a tweet recent counts | ||
type TweetRecentCountsResponse struct { | ||
TweetCounts []*TweetCount `json:"data"` | ||
Meta *TweetRecentCountsMeta `json:"meta"` | ||
} | ||
|
||
// TweetRecentCountsMeta contains the meta data from the recent counts information | ||
type TweetRecentCountsMeta struct { | ||
TotalTweetCount int `json:"total_tweet_count"` | ||
} | ||
|
||
// TweetCount is the object on the tweet counts endpoints | ||
type TweetCount struct { | ||
Start string `json:"start"` | ||
End string `json:"end"` | ||
TweetCount int `json:"tweet_count"` | ||
} |
Oops, something went wrong.