package api import ( "fmt" "net/http" "regexp" "strings" "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/umputun/remark42/backend/app/store" ) func TestServer_RssPost(t *testing.T) { ts, rst, teardown := startupT(t) defer teardown() waitOnSecChange() c1 := store.Comment{ ID: "1234567890", Text: "test 123", Locator: store.Locator{URL: "https://radio-t.com/blah1", SiteID: "remark42"}, User: store.User{ID: "u1", Name: "developer one"}, } id1, err := rst.DataService.Create(c1) require.NoError(t, err) assert.Equal(t, "1234567890", id1) pubDate := time.Now().Format(time.RFC1123Z) res, code := get(t, ts.URL+"/api/v1/rss/post?site=remark42&url=https://radio-t.com/blah1") assert.Equal(t, http.StatusOK, code) t.Log(res) expected := fmt.Sprintf(` Remark42 comments https://radio-t.com/blah1 post comments for https://radio-t.com/blah1 %s developer one https://radio-t.com/blah1#remark42__comment-1234567890 test 123 developer one 1234567890 %s `, pubDate, pubDate) expected, res = cleanRssFormatting(expected, res) assert.Equal(t, expected, res) _, code = get(t, ts.URL+"/api/v1/rss/post?site=remark42-bad&url=https://radio-t.com/blah1") assert.Equal(t, http.StatusBadRequest, code) } func TestServer_RssSite(t *testing.T) { ts, rst, teardown := startupT(t) defer teardown() waitOnSecChange() pubDate := time.Now().Format(time.RFC1123Z) c1 := store.Comment{ ID: "comment-id-1", Text: "test 123", Locator: store.Locator{URL: "https://radio-t.com/blah10", SiteID: "remark42"}, User: store.User{ID: "u1", Name: "developer one"}, } c2 := store.Comment{ ID: "comment-id-2", Text: "xyz test", Locator: store.Locator{URL: "https://radio-t.com/blah11", SiteID: "remark42"}, User: store.User{ID: "u1", Name: "developer one"}, } _, err := rst.DataService.Create(c1) require.NoError(t, err) _, err = rst.DataService.Create(c2) require.NoError(t, err) require.NoError(t, err) res, code := get(t, ts.URL+"/api/v1/rss/site?site=remark42") assert.Equal(t, http.StatusOK, code) t.Log(res) expected := fmt.Sprintf(` Remark42 comments remark42 site comment for remark42 %s developer one https://radio-t.com/blah11#remark42__comment-comment-id-2 xyz test developer one comment-id-2 %s developer one https://radio-t.com/blah10#remark42__comment-comment-id-1 test 123 developer one comment-id-1 %s `, pubDate, pubDate, pubDate) expected, res = cleanRssFormatting(expected, res) assert.Equal(t, expected, res) _, code = get(t, ts.URL+"/api/v1/rss/site?site=bad-radio-t") assert.Equal(t, http.StatusBadRequest, code) } func TestServer_RssWithReply(t *testing.T) { ts, rst, teardown := startupT(t) defer teardown() waitOnSecChange() pubDate := time.Now().Format(time.RFC1123Z) c1 := store.Comment{ ID: "comment-id-1", Text: "test 123", Locator: store.Locator{URL: "https://radio-t.com/blah10", SiteID: "remark42"}, User: store.User{ID: "u1", Name: "developer one"}, } c2 := store.Comment{ ID: "comment-id-2", ParentID: "comment-id-1", Text: "xyz test", Locator: store.Locator{URL: "https://radio-t.com/blah10", SiteID: "remark42"}, User: store.User{ID: "u1", Name: "developer one"}, } _, err := rst.DataService.Create(c1) require.NoError(t, err) _, err = rst.DataService.Create(c2) require.NoError(t, err) res, code := get(t, ts.URL+"/api/v1/rss/post?site=remark42&url=https://radio-t.com/blah10") assert.Equal(t, http.StatusOK, code) t.Log(res) expected := fmt.Sprintf(` Remark42 comments https://radio-t.com/blah10 post comments for https://radio-t.com/blah10 %s developer one > developer one https://radio-t.com/blah10#remark42__comment-comment-id-2 xyz test<blockquote><p>test 123</p></blockquote> developer one comment-id-2 %s developer one https://radio-t.com/blah10#remark42__comment-comment-id-1 test 123 developer one comment-id-1 %s `, pubDate, pubDate, pubDate) expected, res = cleanRssFormatting(expected, res) assert.Equal(t, expected, res) } func TestServer_RssReplies(t *testing.T) { ts, srv, teardown := startupT(t) defer teardown() waitOnSecChange() pubDate := time.Now().Format(time.RFC1123Z) c1 := store.Comment{ ID: "comment-1", Text: "c1", Locator: store.Locator{URL: "https://radio-t.com/blah1", SiteID: "remark42"}, User: store.User{ID: "user1", Name: "user1"}, } c2 := store.Comment{ ID: "comment-2", Text: "reply to c1 from user2", ParentID: "comment-1", Locator: store.Locator{URL: "https://radio-t.com/blah1", SiteID: "remark42"}, User: store.User{ID: "user2", Name: "user2"}, } c3 := store.Comment{ ID: "comment-3", Text: "reply to c1 from user3", ParentID: "comment-1", Locator: store.Locator{URL: "https://radio-t.com/blah1", SiteID: "remark42"}, User: store.User{ID: "user3", Name: "user3"}, } c4 := store.Comment{ ID: "comment-4", Text: "reply to c2 from developer one", ParentID: "comment-2", Locator: store.Locator{URL: "https://radio-t.com/blah1", SiteID: "remark42"}, User: store.User{ID: "dev", Name: "developer one"}, } c5 := store.Comment{ ID: "comment-5", Text: "developer one", Locator: store.Locator{URL: "https://radio-t.com/blah1", SiteID: "remark42"}, User: store.User{ID: "dev", Name: "developer one"}, } _, err := srv.DataService.Create(c1) require.NoError(t, err) _, err = srv.DataService.Create(c2) require.NoError(t, err) _, err = srv.DataService.Create(c3) require.NoError(t, err) _, err = srv.DataService.Create(c4) require.NoError(t, err) _, err = srv.DataService.Create(c5) require.NoError(t, err) // replies to c1 (user1). Must be [c3, c2] res, code := get(t, ts.URL+"/api/v1/rss/reply?user=user1&site=remark42") assert.Equal(t, http.StatusOK, code) t.Log(res) expected := fmt.Sprintf(` Remark42 comments remark42 replies to user1 %s user3 > user1 https://radio-t.com/blah1#remark42__comment-comment-3 reply to c1 from user3<blockquote><p>c1</p></blockquote> user3 comment-3 %s user2 > user1 https://radio-t.com/blah1#remark42__comment-comment-2 reply to c1 from user2<blockquote><p>c1</p></blockquote> user2 comment-2 %s `, pubDate, pubDate, pubDate) expected, res = cleanRssFormatting(expected, res) assert.Equal(t, expected, res) _, code = get(t, ts.URL+"/api/v1/rss/reply?user=user1&site=remark42-bad") assert.Equal(t, http.StatusBadRequest, code) } func waitOnSecChange() { for { if time.Now().Nanosecond() < 100000000 { break } time.Sleep(10 * time.Nanosecond) } } // clean formatting, i.e. multiple spaces, \t, \n func cleanRssFormatting(expected, actual string) (cleanExp, cleanAct string) { reSpaces := regexp.MustCompile(`[\s\p{Zs}]{2,}`) expected = strings.Replace(expected, "\n", " ", -1) expected = strings.Replace(expected, "\t", " ", -1) expected = reSpaces.ReplaceAllString(expected, " ") actual = strings.Replace(actual, "\n", " ", -1) actual = reSpaces.ReplaceAllString(actual, " ") return expected, actual }