cli + tui to publish to leaflet (wip) & manage tasks, notes & watch/read lists 馃崈
charm leaflet readability golang
29
fork

Configure Feed

Select the types of activity you want to include in your feed.

at d2c4ecc217c2c1655026bba3b364c124b3a95a8a 272 lines 8.0 kB view raw
1package services 2 3import ( 4 "bytes" 5 "context" 6 "strings" 7 "testing" 8 9 "github.com/stormlightlabs/noteleaf/internal/models" 10) 11 12func TestMediaServices(t *testing.T) { 13 t.Run("MovieService", func(t *testing.T) { 14 t.Run("Search", func(t *testing.T) { 15 t.Run("successful search", func(t *testing.T) { 16 cleanup := SetupSuccessfulMovieMocks(t) 17 defer cleanup() 18 19 service := CreateMovieService() 20 TestMovieSearch(t, service, "Fantastic Four", "Fantastic Four") 21 }) 22 23 t.Run("search returns error", func(t *testing.T) { 24 cleanup := SetupFailureMocks(t, "search error") 25 defer cleanup() 26 27 service := CreateMovieService() 28 _, err := service.Search(context.Background(), "error", 1, 10) 29 AssertErrorContains(t, err, "search error") 30 }) 31 }) 32 33 t.Run("Get", func(t *testing.T) { 34 t.Run("successful get", func(t *testing.T) { 35 cleanup := SetupSuccessfulMovieMocks(t) 36 defer cleanup() 37 38 service := CreateMovieService() 39 result, err := service.Get(context.Background(), "some-url") 40 if err != nil { 41 t.Fatalf("Get failed: %v", err) 42 } 43 movie, ok := (*result).(*models.Movie) 44 if !ok { 45 t.Fatalf("expected a movie model, got %T", *result) 46 } 47 if movie.Title == "" { 48 t.Error("expected non-empty movie title") 49 } 50 }) 51 52 t.Run("get returns error", func(t *testing.T) { 53 cleanup := SetupFailureMocks(t, "fetch error") 54 defer cleanup() 55 56 service := CreateMovieService() 57 _, err := service.Get(context.Background(), "error") 58 AssertErrorContains(t, err, "fetch error") 59 }) 60 }) 61 62 t.Run("Check", func(t *testing.T) { 63 t.Run("successful check", func(t *testing.T) { 64 cleanup := SetupSuccessfulMovieMocks(t) 65 defer cleanup() 66 67 service := CreateMovieService() 68 err := service.Check(context.Background()) 69 if err != nil { 70 t.Fatalf("Check failed: %v", err) 71 } 72 }) 73 74 t.Run("check returns error", func(t *testing.T) { 75 cleanup := SetupFailureMocks(t, "html fetch error") 76 defer cleanup() 77 78 service := CreateMovieService() 79 err := service.Check(context.Background()) 80 AssertErrorContains(t, err, "html fetch error") 81 }) 82 }) 83 84 t.Run("Parse Search results", func(t *testing.T) { 85 results, err := ParseSearch(bytes.NewReader(SearchSample)) 86 if err != nil { 87 t.Fatalf("ParseSearch failed: %v", err) 88 } 89 if len(results) == 0 { 90 t.Fatal("expected non-empty search results") 91 } 92 }) 93 94 t.Run("Parse Search error", func(t *testing.T) { 95 results, err := ParseSearch(strings.NewReader("\x00bad html")) 96 if err != nil { 97 t.Fatalf("unexpected error for malformed HTML: %v", err) 98 } 99 if len(results) != 0 { 100 t.Errorf("expected 0 results for malformed HTML, got %d", len(results)) 101 } 102 103 html := `<a class="score-list-item"><span>Test</span></a>` 104 results, err = ParseSearch(strings.NewReader(html)) 105 if err != nil { 106 t.Fatalf("unexpected error: %v", err) 107 } 108 if len(results) != 0 { 109 t.Errorf("expected 0 results, got %d", len(results)) 110 } 111 }) 112 113 t.Run("Extract Metadata", func(t *testing.T) { 114 movie, err := ExtractMovieMetadata(bytes.NewReader(MovieSample)) 115 if err != nil { 116 t.Fatalf("ExtractMovieMetadata failed: %v", err) 117 } 118 if movie.Type != "Movie" { 119 t.Errorf("expected Type=Movie, got %s", movie.Type) 120 } 121 if movie.Name == "" { 122 t.Error("expected non-empty Name") 123 } 124 }) 125 126 t.Run("Extract Metadata Errors", func(t *testing.T) { 127 if _, err := ExtractMovieMetadata(strings.NewReader("not html")); err == nil { 128 t.Error("expected error for invalid HTML") 129 } 130 131 html := `<script type="application/ld+json">{"@type":"Other"}</script>` 132 if _, err := ExtractMovieMetadata(strings.NewReader(html)); err == nil || !strings.Contains(err.Error(), "no Movie JSON-LD") { 133 t.Errorf("expected 'no Movie JSON-LD', got %v", err) 134 } 135 136 html = `<script type="application/ld+json">{oops}</script>` 137 if _, err := ExtractMovieMetadata(strings.NewReader(html)); err == nil { 138 t.Error("expected error for invalid JSON") 139 } 140 }) 141 142 t.Run("Extract TV Series Metadata", func(t *testing.T) { 143 series, err := ExtractTVSeriesMetadata(bytes.NewReader(SeriesSample)) 144 if err != nil { 145 t.Fatalf("ExtractTVSeriesMetadata failed: %v", err) 146 } 147 if series.Type != "TVSeries" { 148 t.Errorf("expected Type=TVSeries, got %s", series.Type) 149 } 150 if series.NumberOfSeasons <= 0 { 151 t.Error("expected NumberOfSeasons > 0") 152 } 153 }) 154 155 t.Run("Extract TV Series Metadata Errors", func(t *testing.T) { 156 if _, err := ExtractTVSeriesMetadata(strings.NewReader("not html")); err == nil { 157 t.Error("expected error for invalid HTML") 158 } 159 160 html := `<script type="application/ld+json">{"@type":"Other"}</script>` 161 if _, err := ExtractTVSeriesMetadata(strings.NewReader(html)); err == nil || !strings.Contains(err.Error(), "no TVSeries JSON-LD") { 162 t.Errorf("expected 'no TVSeries JSON-LD', got %v", err) 163 } 164 }) 165 166 t.Run("Extract TV Series Season metadata", func(t *testing.T) { 167 season, err := ExtractTVSeasonMetadata(bytes.NewReader(SeasonSample)) 168 if err != nil { 169 t.Fatalf("ExtractTVSeasonMetadata failed: %v", err) 170 } 171 if season.Type != "TVSeason" { 172 t.Errorf("expected Type=TVSeason, got %s", season.Type) 173 } 174 if season.SeasonNumber <= 0 { 175 t.Error("expected SeasonNumber > 0") 176 } 177 if season.PartOfSeries.Name == "" { 178 t.Error("expected non-empty PartOfSeries.Name") 179 } 180 }) 181 182 t.Run("Extract TV Series Season errors", func(t *testing.T) { 183 if _, err := ExtractTVSeasonMetadata(strings.NewReader("not html")); err == nil { 184 t.Error("expected error for invalid HTML") 185 } 186 187 html := `<script type="application/ld+json">{"@type":"Other"}</script>` 188 if _, err := ExtractTVSeasonMetadata(strings.NewReader(html)); err == nil || !strings.Contains(err.Error(), "no TVSeason JSON-LD") { 189 t.Errorf("expected 'no TVSeason JSON-LD', got %v", err) 190 } 191 }) 192 193 t.Run("Fetch HTML errors", func(t *testing.T) { 194 if _, err := FetchHTML("://bad-url"); err == nil { 195 t.Error("expected error for invalid URL") 196 } 197 }) 198 199 }) 200 201 t.Run("TVService", func(t *testing.T) { 202 t.Run("Search", func(t *testing.T) { 203 t.Run("successful search", func(t *testing.T) { 204 cleanup := SetupSuccessfulTVMocks(t) 205 defer cleanup() 206 207 service := CreateTVService() 208 TestTVSearch(t, service, "peacemaker", "Peacemaker") 209 }) 210 211 t.Run("search returns error", func(t *testing.T) { 212 cleanup := SetupFailureMocks(t, "search error") 213 defer cleanup() 214 215 service := CreateTVService() 216 _, err := service.Search(context.Background(), "error", 1, 10) 217 AssertErrorContains(t, err, "search error") 218 }) 219 }) 220 221 t.Run("Get", func(t *testing.T) { 222 t.Run("successful get", func(t *testing.T) { 223 cleanup := SetupSuccessfulTVMocks(t) 224 defer cleanup() 225 226 service := CreateTVService() 227 result, err := service.Get(context.Background(), "some-url") 228 if err != nil { 229 t.Fatalf("Get failed: %v", err) 230 } 231 show, ok := (*result).(*models.TVShow) 232 if !ok { 233 t.Fatalf("expected a tv show model, got %T", *result) 234 } 235 if show.Title == "" { 236 t.Error("expected non-empty TV show title") 237 } 238 }) 239 240 t.Run("get returns error", func(t *testing.T) { 241 cleanup := SetupFailureMocks(t, "fetch error") 242 defer cleanup() 243 244 service := CreateTVService() 245 _, err := service.Get(context.Background(), "error") 246 AssertErrorContains(t, err, "fetch error") 247 }) 248 }) 249 250 t.Run("Check", func(t *testing.T) { 251 t.Run("successful check", func(t *testing.T) { 252 cleanup := SetupSuccessfulTVMocks(t) 253 defer cleanup() 254 255 service := CreateTVService() 256 err := service.Check(context.Background()) 257 if err != nil { 258 t.Fatalf("Check failed: %v", err) 259 } 260 }) 261 262 t.Run("check returns error", func(t *testing.T) { 263 cleanup := SetupFailureMocks(t, "html fetch error") 264 defer cleanup() 265 266 service := CreateTVService() 267 err := service.Check(context.Background()) 268 AssertErrorContains(t, err, "html fetch error") 269 }) 270 }) 271 }) 272}