package monstersirenfetch_test import ( _ "embed" "errors" "os" "reflect" "testing" . "git.gensokyo.uk/yonah/monstersirenfetch" ) var ( //go:embed testdata/album.data.json albumDataJSON []byte //go:embed testdata/album.detail.json albumDetailJSON []byte ) func TestAlbum(t *testing.T) { checkJSONRoundTrip(t, AlbumResponse{Data: Album{ CID: 1030, Name: "Speed of Light", Intro: "在无人告知方向的黑夜里,独自以光速探寻正确的道路。 \n无论看待世界是简单,亦或是复杂,大地和天空始终让开始与结束相连。 \n《Speed of Light》,通过乐调铺陈的驰放与内敛感,希望能为您呈现超脱于现实的惬意想象空间。 \n愿您掌心的小小地图一直指引着前路。像光一样前行,如企鹅物流般永不停歇。", Belong: "arknights", CoverDeURL: "https://web.hycdn.cn/siren/pic/20210322/0bf0d84e08b57acd2455b412224ba8e8.jpg", CoverURL: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg", Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}, }}, albumDataJSON) t.Run("copy", func(t *testing.T) { testCases := []struct { name string a *Album variant int want Album wantOk bool }{ {"nil", nil, AlbumVariantDetail, Album{CID: -0xdeadbeef}, false}, {"current", new(Album), AlbumVariantCurrent, Album{}, true}, {"full guard", new(Album), AlbumVariantDetail, Album{CID: -0xdeadbeef}, false}, {"current full", &Album{ Belong: "\x00", Songs: []AlbumSong{{}}, }, AlbumVariantCurrent, Album{ Belong: "\x00", Songs: []AlbumSong{{}}, }, true}, {"oob", &Album{ Belong: "\x00", Songs: []AlbumSong{{}}, }, 0xbad, Album{CID: -0xdeadbeef}, false}, {"full", &Album{ CID: 1030, Name: "Speed of Light", Intro: "在无人告知方向的黑夜里,独自以光速探寻正确的道路。 \n无论看待世界是简单,亦或是复杂,大地和天空始终让开始与结束相连。 \n《Speed of Light》,通过乐调铺陈的驰放与内敛感,希望能为您呈现超脱于现实的惬意想象空间。 \n愿您掌心的小小地图一直指引着前路。像光一样前行,如企鹅物流般永不停歇。", Belong: "arknights", CoverDeURL: "https://web.hycdn.cn/siren/pic/20210322/0bf0d84e08b57acd2455b412224ba8e8.jpg", CoverURL: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg", Songs: []AlbumSong{ {CID: 880374, Name: "Speed of Light", Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}}, {CID: 125012, Name: "Speed of Light (Instrumental)", Artists: []string{"DJ Okawari"}}, }, Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}, }, AlbumVariantFull, Album{ CID: 1030, Name: "Speed of Light", Intro: "在无人告知方向的黑夜里,独自以光速探寻正确的道路。 \n无论看待世界是简单,亦或是复杂,大地和天空始终让开始与结束相连。 \n《Speed of Light》,通过乐调铺陈的驰放与内敛感,希望能为您呈现超脱于现实的惬意想象空间。 \n愿您掌心的小小地图一直指引着前路。像光一样前行,如企鹅物流般永不停歇。", Belong: "arknights", CoverDeURL: "https://web.hycdn.cn/siren/pic/20210322/0bf0d84e08b57acd2455b412224ba8e8.jpg", CoverURL: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg", Songs: []AlbumSong{ {CID: 880374, Name: "Speed of Light", Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}}, {CID: 125012, Name: "Speed of Light (Instrumental)", Artists: []string{"DJ Okawari"}}, }, Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}, }, true}, {"detail", &Album{ CID: 1030, Name: "Speed of Light", Intro: "在无人告知方向的黑夜里,独自以光速探寻正确的道路。 \n无论看待世界是简单,亦或是复杂,大地和天空始终让开始与结束相连。 \n《Speed of Light》,通过乐调铺陈的驰放与内敛感,希望能为您呈现超脱于现实的惬意想象空间。 \n愿您掌心的小小地图一直指引着前路。像光一样前行,如企鹅物流般永不停歇。", Belong: "arknights", CoverDeURL: "https://web.hycdn.cn/siren/pic/20210322/0bf0d84e08b57acd2455b412224ba8e8.jpg", CoverURL: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg", Songs: []AlbumSong{ {CID: 880374, Name: "Speed of Light", Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}}, {CID: 125012, Name: "Speed of Light (Instrumental)", Artists: []string{"DJ Okawari"}}, }, Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}, }, AlbumVariantDetail, Album{ CID: 1030, Name: "Speed of Light", Intro: "在无人告知方向的黑夜里,独自以光速探寻正确的道路。 \n无论看待世界是简单,亦或是复杂,大地和天空始终让开始与结束相连。 \n《Speed of Light》,通过乐调铺陈的驰放与内敛感,希望能为您呈现超脱于现实的惬意想象空间。 \n愿您掌心的小小地图一直指引着前路。像光一样前行,如企鹅物流般永不停歇。", Belong: "arknights", CoverDeURL: "https://web.hycdn.cn/siren/pic/20210322/0bf0d84e08b57acd2455b412224ba8e8.jpg", CoverURL: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg", Songs: []AlbumSong{ {CID: 880374, Name: "Speed of Light", Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}}, {CID: 125012, Name: "Speed of Light (Instrumental)", Artists: []string{"DJ Okawari"}}, }, }, true}, {"data", &Album{ CID: 1030, Name: "Speed of Light", Intro: "在无人告知方向的黑夜里,独自以光速探寻正确的道路。 \n无论看待世界是简单,亦或是复杂,大地和天空始终让开始与结束相连。 \n《Speed of Light》,通过乐调铺陈的驰放与内敛感,希望能为您呈现超脱于现实的惬意想象空间。 \n愿您掌心的小小地图一直指引着前路。像光一样前行,如企鹅物流般永不停歇。", Belong: "arknights", CoverDeURL: "https://web.hycdn.cn/siren/pic/20210322/0bf0d84e08b57acd2455b412224ba8e8.jpg", CoverURL: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg", Songs: []AlbumSong{ {CID: 880374, Name: "Speed of Light", Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}}, {CID: 125012, Name: "Speed of Light (Instrumental)", Artists: []string{"DJ Okawari"}}, }, Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}, }, AlbumVariantData, Album{ CID: 1030, Name: "Speed of Light", Intro: "在无人告知方向的黑夜里,独自以光速探寻正确的道路。 \n无论看待世界是简单,亦或是复杂,大地和天空始终让开始与结束相连。 \n《Speed of Light》,通过乐调铺陈的驰放与内敛感,希望能为您呈现超脱于现实的惬意想象空间。 \n愿您掌心的小小地图一直指引着前路。像光一样前行,如企鹅物流般永不停歇。", Belong: "arknights", CoverDeURL: "https://web.hycdn.cn/siren/pic/20210322/0bf0d84e08b57acd2455b412224ba8e8.jpg", CoverURL: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg", Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}, }, true}, {"base", &Album{ CID: 1030, Name: "Speed of Light", Intro: "在无人告知方向的黑夜里,独自以光速探寻正确的道路。 \n无论看待世界是简单,亦或是复杂,大地和天空始终让开始与结束相连。 \n《Speed of Light》,通过乐调铺陈的驰放与内敛感,希望能为您呈现超脱于现实的惬意想象空间。 \n愿您掌心的小小地图一直指引着前路。像光一样前行,如企鹅物流般永不停歇。", Belong: "arknights", CoverDeURL: "https://web.hycdn.cn/siren/pic/20210322/0bf0d84e08b57acd2455b412224ba8e8.jpg", CoverURL: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg", Songs: []AlbumSong{ {CID: 880374, Name: "Speed of Light", Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}}, {CID: 125012, Name: "Speed of Light (Instrumental)", Artists: []string{"DJ Okawari"}}, }, Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}, }, AlbumVariantBase, Album{ CID: 1030, Name: "Speed of Light", CoverURL: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg", Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}, }, true}, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { got := Album{CID: -0xdeadbeef} if ok := tc.a.Copy(&got, tc.variant); ok != tc.wantOk { t.Errorf("Copy: ok = %v, want %v", ok, tc.wantOk) } if !reflect.DeepEqual(got, tc.want) { t.Errorf("Copy: %#v, want %#v", got, tc.want) } }) } }) } func TestAlbumEnrich(t *testing.T) { testCases := []struct { name string base Album n Net want Album wantErr error }{ {"get", Album{ CID: 1030, Name: "Speed of Light", CoverURL: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg", Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}, }, stubNet{}, Album{}, errors.New("url https://monster-siren.hypergryph.com/api/album/1030/detail requested, but is not present")}, {"invalid response", Album{ CID: 1030, Name: "Speed of Light", CoverURL: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg", Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}, }, stubNet{ makeAlbumPath(1030, true): []byte{0}, }, Album{}, errors.Join(newSyntaxError("invalid character '\\x00' looking for beginning of value", 1))}, {"status", Album{ CID: 1030, Name: "Speed of Light", CoverURL: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg", Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}, }, stubNetErrorCloser{ makeAlbumPath(1030, true): []byte{0xde, 0xad, 0xbe, 0xef}, }, Album{}, &ResponseStatusError{ URL: "https://monster-siren.hypergryph.com/api/album/1030/detail", StatusCode: 0xdeadbeef, CloseErr: os.ErrInvalid, }}, {"close", Album{ CID: 1030, Name: "Speed of Light", CoverURL: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg", Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}, }, stubNetErrorCloser{ makeAlbumPath(1030, true): albumDetailJSON, }, Album{}, os.ErrInvalid}, {"inconsistent cid", Album{ CID: 0xdeadbeef, Name: "Speed of Light", CoverURL: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg", Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}, }, stubNet{ makeAlbumPath(0xdeadbeef, true): albumDetailJSON, }, Album{}, &InconsistentEnrichError[StringInt]{ Field: "cid", Value: 0xdeadbeef, NewValue: 1030, }}, {"inconsistent name", Album{ CID: 1030, Name: "Speed of Light\x00", CoverURL: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg", Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}, }, stubNet{ makeAlbumPath(1030, true): albumDetailJSON, }, Album{}, &InconsistentEnrichError[string]{ Field: "name", Value: "Speed of Light\x00", NewValue: "Speed of Light", }}, {"inconsistent coverUrl", Album{ CID: 1030, Name: "Speed of Light", CoverURL: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg\x00", Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}, }, stubNet{ makeAlbumPath(1030, true): albumDetailJSON, }, Album{}, &InconsistentEnrichError[string]{ Field: "coverUrl", Value: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg\x00", NewValue: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg", }}, {"unexpected artists", Album{ CID: 1030, Name: "Speed of Light", CoverURL: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg", Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}, }, stubNet{ makeAlbumPath(1030, true): albumDataJSON, }, Album{}, &InconsistentEnrichError[[]string]{ Field: "artists", Value: nil, NewValue: []string{"塞壬唱片-MSR", "DJ Okawari"}, }}, {"valid", Album{ CID: 1030, Name: "Speed of Light", CoverURL: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg", Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}, }, stubNet{ makeAlbumPath(1030, true): albumDetailJSON, }, Album{ CID: 1030, Name: "Speed of Light", Intro: "在无人告知方向的黑夜里,独自以光速探寻正确的道路。 \n无论看待世界是简单,亦或是复杂,大地和天空始终让开始与结束相连。 \n《Speed of Light》,通过乐调铺陈的驰放与内敛感,希望能为您呈现超脱于现实的惬意想象空间。 \n愿您掌心的小小地图一直指引着前路。像光一样前行,如企鹅物流般永不停歇。", Belong: "arknights", CoverDeURL: "https://web.hycdn.cn/siren/pic/20210322/0bf0d84e08b57acd2455b412224ba8e8.jpg", CoverURL: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg", Songs: []AlbumSong{ {CID: 880374, Name: "Speed of Light", Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}}, {CID: 125012, Name: "Speed of Light (Instrumental)", Artists: []string{"DJ Okawari"}}, }, Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}, }, nil}, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { a := new(Album) *a = tc.base if err := a.Enrich(t.Context(), tc.n); !reflect.DeepEqual(err, tc.wantErr) { t.Errorf("Enrich: error = %v, want %v", err, tc.wantErr) } if tc.wantErr == nil && !reflect.DeepEqual(a, &tc.want) { t.Errorf("Enrich: %#v, want %#v", a, &tc.want) } }) } t.Run("invalid", func(t *testing.T) { t.Run("nil", func(t *testing.T) { if err := (*Album)(nil).Enrich(t.Context(), nil); !errors.Is(err, os.ErrInvalid) { t.Errorf("Enrich: error = %v", err) } }) t.Run("full", func(t *testing.T) { if err := (&Album{Belong: "\x00", Songs: []AlbumSong{{}}}).Enrich(t.Context(), nil); !errors.Is(err, os.ErrInvalid) { t.Errorf("Enrich: error = %v", err) } }) }) } func makeAlbumPath(cid StringInt, detail bool) string { suffix := "data" if detail { suffix = "detail" } return APIPrefix + "/album/" + cid.String() + "/" + suffix }