package royalroad import ( "context" "net/http" "net/http/httptest" "testing" "time" ) func TestParseJSONLD(t *testing.T) { tests := []struct { name string body string want Story wantErr bool }{ { name: "Success", body: ``, want: Story{ Name: "Test Story", DateModified: time.Date(2023, 7, 6, 17, 47, 41, 0, time.UTC), }, wantErr: false, }, { name: "Missing Script", body: `No JSON-LD here`, wantErr: true, }, { name: "Malformed JSON", body: ``, wantErr: true, }, { name: "Missing Name", body: ``, wantErr: true, }, { name: "Invalid Date", body: ``, wantErr: true, }, } s := NewScraper() for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, err := s.parseJSONLD([]byte(tt.body)) if (err != nil) != tt.wantErr { t.Errorf("parseJSONLD() error = %v, wantErr %v", err, tt.wantErr) return } if !tt.wantErr && got != tt.want { t.Errorf("parseJSONLD() = %v, want %v", got, tt.want) } }) } } func TestFetchStory_NonRoyalRoadHost(t *testing.T) { s := NewScraper() _, err := s.FetchStory(context.Background(), "https://google.com/fiction/123") if err == nil { t.Error("Expected error for non-RoyalRoad host, got nil") } } func TestFetchStory_ChapterURL(t *testing.T) { s := NewScraper() _, err := s.FetchStory(context.Background(), "https://www.royalroad.com/fiction/123/chapter/456") if err == nil { t.Error("Expected error for chapter URL, got nil") } } func TestFetchStory_HTTPError(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotFound) })) defer ts.Close() s := NewScraper() // We can't easily mock the host check for the server URL without custom logic, // but we can verify that a non-RR URL (the test server) fails at the host check // before it even hits the server. _, err := s.FetchStory(context.Background(), ts.URL+"/fiction/123") if err == nil { t.Error("Expected error for non-RoyalRoad host, got nil") } }