package monstersirenfetch_test import ( _ "embed" "errors" "os" "reflect" "testing" . "git.gensokyo.uk/yonah/monstersirenfetch" ) //go:embed testdata/song.json var songJSON []byte func TestSong(t *testing.T) { checkJSONRoundTrip(t, SongResponse{Data: Song{ CID: 48794, Name: "Warm and Small Light", AlbumCID: 6660, SourceURL: "https://res01.hycdn.cn/04ce5de54bb52eb85008644d541d40fa/68CA0442/siren/audio/20240709/a7f650238eaefc9c30a9627d7f78d819.wav", LyricURL: "https://web.hycdn.cn/siren/lyric/20240709/4a10c70629b68a187fdbef4a27bd32d8.lrc", Artists: []string{"塞壬唱片-MSR"}, }}, songJSON) t.Run("copy", func(t *testing.T) { testCases := []struct { name string a *Song variant int want Song wantOk bool }{ {"nil", nil, SongVariantBase, Song{CID: -0xdeadbeef}, false}, {"current", new(Song), SongVariantCurrent, Song{}, true}, {"full guard", new(Song), SongVariantFull, Song{CID: -0xdeadbeef}, false}, {"current full", &Song{ SourceURL: "\x00", }, SongVariantCurrent, Song{ SourceURL: "\x00", }, true}, {"oob", &Song{ SourceURL: "\x00", }, 0xbad, Song{CID: -0xdeadbeef}, false}, {"full", &Song{ CID: 48794, Name: "Warm and Small Light", AlbumCID: 6660, SourceURL: "https://res01.hycdn.cn/04ce5de54bb52eb85008644d541d40fa/68CA0442/siren/audio/20240709/a7f650238eaefc9c30a9627d7f78d819.wav", LyricURL: "https://web.hycdn.cn/siren/lyric/20240709/4a10c70629b68a187fdbef4a27bd32d8.lrc", Artists: []string{"塞壬唱片-MSR"}, }, SongVariantFull, Song{ CID: 48794, Name: "Warm and Small Light", AlbumCID: 6660, SourceURL: "https://res01.hycdn.cn/04ce5de54bb52eb85008644d541d40fa/68CA0442/siren/audio/20240709/a7f650238eaefc9c30a9627d7f78d819.wav", LyricURL: "https://web.hycdn.cn/siren/lyric/20240709/4a10c70629b68a187fdbef4a27bd32d8.lrc", Artists: []string{"塞壬唱片-MSR"}, }, true}, {"base", &Song{ CID: 48794, Name: "Warm and Small Light", AlbumCID: 6660, SourceURL: "https://res01.hycdn.cn/04ce5de54bb52eb85008644d541d40fa/68CA0442/siren/audio/20240709/a7f650238eaefc9c30a9627d7f78d819.wav", LyricURL: "https://web.hycdn.cn/siren/lyric/20240709/4a10c70629b68a187fdbef4a27bd32d8.lrc", Artists: []string{"塞壬唱片-MSR"}, }, SongVariantBase, Song{ CID: 48794, Name: "Warm and Small Light", AlbumCID: 6660, Artists: []string{"塞壬唱片-MSR"}, }, true}, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { got := Song{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 TestSongEnrich(t *testing.T) { testCases := []struct { name string base Song n Net want Song wantErr error }{ {"get", Song{ CID: 48794, Name: "Warm and Small Light", AlbumCID: 6660, Artists: []string{"塞壬唱片-MSR"}, }, stubNet{}, Song{}, errors.New("url https://monster-siren.hypergryph.com/api/song/048794 requested, but is not present")}, {"invalid response", Song{ CID: 48794, Name: "Warm and Small Light", AlbumCID: 6660, Artists: []string{"塞壬唱片-MSR"}, }, stubNet{ makeSongPath(48794): []byte{0}, }, Song{}, errors.Join(newSyntaxError("invalid character '\\x00' looking for beginning of value", 1))}, {"close", Song{ CID: 48794, Name: "Warm and Small Light", AlbumCID: 6660, Artists: []string{"塞壬唱片-MSR"}, }, stubNetErrorCloser{ makeSongPath(48794): songJSON, }, Song{}, os.ErrInvalid}, {"inconsistent cid", Song{ CID: 0xdeadbeef, Name: "Warm and Small Light", AlbumCID: 6660, Artists: []string{"塞壬唱片-MSR"}, }, stubNet{ makeSongPath(0xdeadbeef): songJSON, }, Song{}, &InconsistentEnrichError[StringInt]{ Field: "cid", Value: 0xdeadbeef, NewValue: 48794, }}, {"inconsistent name", Song{ CID: 48794, Name: "Warm and Small Light\x00", AlbumCID: 6660, Artists: []string{"塞壬唱片-MSR"}, }, stubNet{ makeSongPath(48794): songJSON, }, Song{}, &InconsistentEnrichError[string]{ Field: "name", Value: "Warm and Small Light\x00", NewValue: "Warm and Small Light", }}, {"inconsistent albumCid", Song{ CID: 48794, Name: "Warm and Small Light", AlbumCID: -1, Artists: []string{"塞壬唱片-MSR"}, }, stubNet{ makeSongPath(48794): songJSON, }, Song{}, &InconsistentEnrichError[StringInt]{ Field: "albumCid", Value: -1, NewValue: 6660, }}, {"inconsistent artists", Song{ CID: 48794, Name: "Warm and Small Light", AlbumCID: 6660, Artists: []string{"塞壬唱片-MSR", "\x00"}, }, stubNet{ makeSongPath(48794): songJSON, }, Song{}, &InconsistentEnrichError[[]string]{ Field: "artists", Value: []string{"塞壬唱片-MSR", "\x00"}, NewValue: []string{"塞壬唱片-MSR"}, }}, {"valid", Song{ CID: 48794, Name: "Warm and Small Light", AlbumCID: 6660, Artists: []string{"塞壬唱片-MSR"}, }, stubNet{ makeSongPath(48794): songJSON, }, Song{ CID: 48794, Name: "Warm and Small Light", AlbumCID: 6660, SourceURL: "https://res01.hycdn.cn/04ce5de54bb52eb85008644d541d40fa/68CA0442/siren/audio/20240709/a7f650238eaefc9c30a9627d7f78d819.wav", LyricURL: "https://web.hycdn.cn/siren/lyric/20240709/4a10c70629b68a187fdbef4a27bd32d8.lrc", MvURL: "", MvCoverURL: "", Artists: []string{"塞壬唱片-MSR"}, }, nil}, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { s := new(Song) *s = tc.base if err := s.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(s, &tc.want) { t.Errorf("Enrich: %#v, want %#v", s, &tc.want) } }) } t.Run("invalid", func(t *testing.T) { t.Run("nil", func(t *testing.T) { if err := (*Song)(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 := (&Song{SourceURL: "\x00"}).Enrich(t.Context(), nil); !errors.Is(err, os.ErrInvalid) { t.Errorf("Enrich: error = %v", err) } }) }) } func makeSongPath(cid StringInt) string { return APIPrefix + "/song/" + cid.String() }