Add marshaling and unmarshaling of API objects so state can be persisted between runs

This commit is contained in:
Alessio 2023-01-01 21:57:08 -05:00
parent c3494cfe19
commit 390c831541
2 changed files with 94 additions and 1 deletions

View File

@ -24,6 +24,53 @@ type API struct {
CSRFToken string CSRFToken string
} }
type api_outstruct struct {
Cookies []*http.Cookie
UserHandle UserHandle
IsAuthenticated bool
GuestToken string
CSRFToken string
}
var TWITTER_BASE_URL = url.URL{Scheme: "https", Host: "twitter.com"}
func (api API) MarshalJSON() ([]byte, error) {
result, err := json.Marshal(api_outstruct{
Cookies: api.Client.Jar.Cookies(&TWITTER_BASE_URL),
UserHandle: api.UserHandle,
IsAuthenticated: api.IsAuthenticated,
GuestToken: api.GuestToken,
CSRFToken: api.CSRFToken,
})
if err != nil {
return result, fmt.Errorf("Unable to JSONify the api:\n %w", err)
}
return result, nil
}
func (api *API) UnmarshalJSON(data []byte) error {
var in_struct api_outstruct
err := json.Unmarshal(data, &in_struct)
if err != nil {
return fmt.Errorf("Unable to unmarshal:\n %w", err)
}
cookie_jar, err := cookiejar.New(nil)
if err != nil {
panic(err)
}
cookie_jar.SetCookies(&TWITTER_BASE_URL, in_struct.Cookies)
api.IsAuthenticated = in_struct.IsAuthenticated
api.GuestToken = in_struct.GuestToken
api.UserHandle = in_struct.UserHandle
api.Client = http.Client{
Timeout: 10 * time.Second,
Jar: cookie_jar,
}
api.CSRFToken = in_struct.CSRFToken
return nil
}
func (api API) add_authentication_headers(req *http.Request) { func (api API) add_authentication_headers(req *http.Request) {
// Params for every request // Params for every request
req.Header.Set("Authorization", "Bearer "+BEARER_TOKEN) req.Header.Set("Authorization", "Bearer "+BEARER_TOKEN)

View File

@ -1,13 +1,21 @@
package scraper_test package scraper_test
import ( import (
. "offline_twitter/scraper" "encoding/json"
"testing" "testing"
"time"
"net/http"
"net/http/cookiejar"
"github.com/go-test/deep"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
. "offline_twitter/scraper"
) )
// TODO authentication: this has to be removed and replaced with an integration test once the feature is stable-ish
func TestAuthentication(t *testing.T) { func TestAuthentication(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
require := require.New(t) require := require.New(t)
@ -28,3 +36,41 @@ func TestAuthentication(t *testing.T) {
require.NoError(err) require.NoError(err)
assert.True(len(trove.Tweets) > 0) assert.True(len(trove.Tweets) > 0)
} }
// An API object should serialize and then deserialize to give the same session state from before.
func TestJsonifyApi(t *testing.T) {
assert := assert.New(t)
require := require.New(t)
cookie_jar, err := cookiejar.New(nil)
require.NoError(err)
cookie_jar.SetCookies(&TWITTER_BASE_URL, []*http.Cookie{
{Name: "name1", Value: "name1", Secure: true},
{Name: "name2", Value: "name2", HttpOnly: true},
})
api := API{
UserHandle: UserHandle("userhandle"),
IsAuthenticated: true,
GuestToken: "guest token",
Client: http.Client{
Timeout: 10 * time.Second,
Jar: cookie_jar,
},
CSRFToken: "csrf token",
}
bytes, err := json.Marshal(api)
require.NoError(err)
var new_api API
err = json.Unmarshal(bytes, &new_api)
require.NoError(err)
cookies := api.Client.Jar.Cookies(&TWITTER_BASE_URL)
assert.Equal(cookies[0].Name, "name1")
assert.Equal(cookies[0].Value, "name1")
if diff := deep.Equal(api, new_api); diff != nil {
t.Error(diff)
}
}