Skip to content

Commit

Permalink
fix: ensure hydration doesn't cause nil pointer when followers_n file…
Browse files Browse the repository at this point in the history
…s aren't present
  • Loading branch information
cecobask committed Dec 22, 2023
1 parent 265a2f6 commit 6e896ff
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 22 deletions.
41 changes: 23 additions & 18 deletions pkg/instagram/followdata/followdata.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ type handler struct {
func NewHandler() Interface {
return &handler{
fileSystem: filesystem.NewFs(),
followData: &followData{},
followData: newFollowData(),
}
}

Expand Down Expand Up @@ -84,35 +84,33 @@ type followData struct {
Unfollowers *userList
}

type userData struct {
UserData []userOriginal `json:"string_list_data"`
}

func newUserList(users []user, showTimestamp bool) *userList {
return &userList{
users: users,
showTimestamp: showTimestamp,
func newFollowData() *followData {
return &followData{
Following: newUserList(true),
Followers: newUserList(true),
Unfollowers: newUserList(false),
}
}

type userData struct {
UserData []userOriginal `json:"string_list_data"`
}

func (fd *followData) hydrateFollowers(data []byte) error {
var jsonData []userData
if err := json.Unmarshal(data, &jsonData); err != nil {
return err
}
users := make([]user, 0, len(jsonData))
for i := range jsonData {
ud := jsonData[i].UserData[0]
users = append(users, user{
fd.Followers.Append(user{
ProfileUrl: ud.Href,
Username: ud.Value,
Timestamp: &timestamp{
Time: time.Unix(int64(ud.Timestamp), 0),
},
})
}
fd.Followers = newUserList(users, true)
return nil
}

Expand All @@ -121,33 +119,29 @@ func (fd *followData) hydrateFollowing(data []byte) error {
if err := json.Unmarshal(data, &jsonData); err != nil {
return err
}
users := make([]user, 0, len(jsonData))
for i := range jsonData["relationships_following"] {
ud := jsonData["relationships_following"][i].UserData[0]
users = append(users, user{
fd.Following.Append(user{
ProfileUrl: ud.Href,
Username: ud.Value,
Timestamp: &timestamp{
Time: time.Unix(int64(ud.Timestamp), 0),
},
})
}
fd.Following = newUserList(users, true)
return nil
}

func (fd *followData) hydrateUnfollowers() {
users := make([]user, 0)
for i := range fd.Following.users {
current := fd.Following.users[i]
index := slices.IndexFunc(fd.Followers.users, func(u user) bool {
return u.Username == current.Username
})
if index == -1 {
users = append(users, current)
fd.Unfollowers.Append(current)
}
}
fd.Unfollowers = newUserList(users, false)
}

type timestamp struct {
Expand Down Expand Up @@ -192,6 +186,13 @@ type userList struct {
showTimestamp bool
}

func newUserList(showTimestamp bool) *userList {
return &userList{
users: make([]user, 0),
showTimestamp: showTimestamp,
}
}

func (ul *userList) output(format string) (*string, error) {
switch format {
case instagram.OutputJson:
Expand Down Expand Up @@ -292,3 +293,7 @@ func (ul *userList) Limit(limit int) {
ul.users = ul.users[:limit]
}
}

func (ul *userList) Append(u user) {
ul.users = append(ul.users, u)
}
24 changes: 20 additions & 4 deletions pkg/instagram/followdata/followdata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func Test_handler_Followers(t *testing.T) {
wantErr bool
}{
{
name: "succeeds to output followers",
name: "succeeds to output followers when single followers_n file is present",
expectations: func(f *fields) {
f.fileSystem.On("FindFiles", instagram.PathFollowers).Return([]string{"file1"}, nil)
f.fileSystem.On("ReadFile", "file1").Return([]byte(`[{"string_list_data":[{"href":"https://www.instagram.com/username","value":"username","timestamp":0}]}]`), nil)
Expand All @@ -33,6 +33,22 @@ func Test_handler_Followers(t *testing.T) {
},
wantErr: false,
},
{
name: "succeeds to output followers when multiple followers_n files are present",
expectations: func(f *fields) {
f.fileSystem.On("FindFiles", instagram.PathFollowers).Return([]string{
"file1",
"file2",
}, nil)
f.fileSystem.On("ReadFile", "file1").Return([]byte(`[{"string_list_data":[{"href":"https://www.instagram.com/username1","value":"username1","timestamp":0}]}]`), nil)
f.fileSystem.On("ReadFile", "file2").Return([]byte(`[{"string_list_data":[{"href":"https://www.instagram.com/username2","value":"username2","timestamp":0}]}]`), nil)
},
assertions: func(t *testing.T, f *fields) {
f.fileSystem.AssertNumberOfCalls(t, "FindFiles", 1)
f.fileSystem.AssertNumberOfCalls(t, "ReadFile", 2)
},
wantErr: false,
},
{
name: "fails to find files",
expectations: func(f *fields) {
Expand Down Expand Up @@ -72,7 +88,7 @@ func Test_handler_Followers(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
f := &fields{
fileSystem: &filesystem.MockFs{},
followData: &followData{},
followData: newFollowData(),
}
h := &handler{
fileSystem: f.fileSystem,
Expand Down Expand Up @@ -137,7 +153,7 @@ func Test_handler_Following(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
f := &fields{
fileSystem: &filesystem.MockFs{},
followData: &followData{},
followData: newFollowData(),
}
h := &handler{
fileSystem: f.fileSystem,
Expand Down Expand Up @@ -208,7 +224,7 @@ func Test_handler_Unfollowers(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
f := &fields{
fileSystem: &filesystem.MockFs{},
followData: &followData{},
followData: newFollowData(),
}
h := &handler{
fileSystem: f.fileSystem,
Expand Down

0 comments on commit 6e896ff

Please sign in to comment.