@@ -14,6 +14,7 @@ import (
14
14
15
15
cache "github.com/go-pkgz/lcw/v2"
16
16
R "github.com/go-pkgz/rest"
17
+ "github.com/google/uuid"
17
18
"github.com/stretchr/testify/assert"
18
19
"github.com/stretchr/testify/require"
19
20
@@ -598,7 +599,7 @@ func TestPublic_FindCommentsCtrl_ConsistentCount(t *testing.T) {
598
599
setScore (commentLocator , ids [4 ], - 3 )
599
600
time .Sleep (time .Millisecond * 5 )
600
601
601
- c6 := store.Comment {Text : "third-level comment 2" , ParentID : ids [4 ], Locator : commentLocator }
602
+ c6 := store.Comment {Text : "deleted third-level comment 2" , ParentID : ids [4 ], Locator : commentLocator }
602
603
ids [5 ], timestamps [5 ] = addCommentGetCreatedTime (t , c6 , ts )
603
604
// deleted later so not visible in site-wide requests
604
605
setScore (commentLocator , ids [5 ], 10 )
@@ -612,7 +613,7 @@ func TestPublic_FindCommentsCtrl_ConsistentCount(t *testing.T) {
612
613
setScore (commentLocator , ids [6 ], 1 )
613
614
time .Sleep (time .Millisecond * 5 )
614
615
615
- c8 := store.Comment {Text : "second-level comment 3" , ParentID : ids [6 ], Locator : commentLocator }
616
+ c8 := store.Comment {Text : "deleted second-level comment 3" , ParentID : ids [6 ], Locator : commentLocator }
616
617
ids [7 ], timestamps [7 ] = addCommentGetCreatedTime (t , c8 , ts )
617
618
// deleted later so not visible in site-wide requests
618
619
setScore (commentLocator , ids [7 ], - 20 )
@@ -646,18 +647,19 @@ func TestPublic_FindCommentsCtrl_ConsistentCount(t *testing.T) {
646
647
params string
647
648
expectedBody string
648
649
}{
649
- {"" , fmt .Sprintf (`"info":{"count":7,"first_time":%q,"last_time":%q}` , formattedTS [0 ], formattedTS [8 ])},
650
- {"url=test-url" , fmt .Sprintf (`"info":{"url":"test-url","count":6,"first_time":%q,"last_time":%q}` , formattedTS [0 ], formattedTS [7 ])},
651
- {"format=plain" , fmt .Sprintf (`"info":{"count":7,"first_time":%q,"last_time":%q}` , formattedTS [0 ], formattedTS [8 ])},
652
- {"format=plain&url=test-url" , fmt .Sprintf (`"info":{"url":"test-url","count":6,"first_time":%q,"last_time":%q}` , formattedTS [0 ], formattedTS [7 ])},
653
- {"since=" + sinceTenSecondsAgo , fmt .Sprintf (`"info":{"count":7,"first_time":%q,"last_time":%q}` , formattedTS [0 ], formattedTS [8 ])},
654
- {"url=test-url&since=" + sinceTenSecondsAgo , fmt .Sprintf (`"info":{"url":"test-url","count":6,"first_time":%q,"last_time":%q}` , formattedTS [0 ], formattedTS [7 ])},
655
- {"since=" + sinceTS [0 ], fmt .Sprintf (`"info":{"count":7,"first_time":%q,"last_time":%q}` , formattedTS [0 ], formattedTS [8 ])},
656
- {"url=test-url&since=" + sinceTS [0 ], fmt .Sprintf (`"info":{"url":"test-url","count":6,"first_time":%q,"last_time":%q}` , formattedTS [0 ], formattedTS [7 ])},
657
- {"since=" + sinceTS [1 ], fmt .Sprintf (`"info":{"count":6,"first_time":%q,"last_time":%q}` , formattedTS [0 ], formattedTS [8 ])},
658
- {"url=test-url&since=" + sinceTS [1 ], fmt .Sprintf (`"info":{"url":"test-url","count":5,"first_time":%q,"last_time":%q}` , formattedTS [0 ], formattedTS [7 ])},
659
- {"since=" + sinceTS [4 ], fmt .Sprintf (`"info":{"count":3,"first_time":%q,"last_time":%q}` , formattedTS [0 ], formattedTS [8 ])},
660
- {"url=test-url&since=" + sinceTS [4 ], fmt .Sprintf (`"info":{"url":"test-url","count":2,"first_time":%q,"last_time":%q}` , formattedTS [0 ], formattedTS [7 ])},
650
+ // test parameters url, format, since, sort
651
+ {"" , fmt .Sprintf (`"info":{"count":7,"count_left":0,"first_time":%q,"last_time":%q}` , formattedTS [0 ], formattedTS [8 ])},
652
+ {"url=test-url" , fmt .Sprintf (`"info":{"url":"test-url","count":6,"count_left":0,"first_time":%q,"last_time":%q}` , formattedTS [0 ], formattedTS [7 ])},
653
+ {"format=plain" , fmt .Sprintf (`"info":{"count":7,"count_left":0,"first_time":%q,"last_time":%q}` , formattedTS [0 ], formattedTS [8 ])},
654
+ {"format=plain&url=test-url" , fmt .Sprintf (`"info":{"url":"test-url","count":6,"count_left":0,"first_time":%q,"last_time":%q}` , formattedTS [0 ], formattedTS [7 ])},
655
+ {"since=" + sinceTenSecondsAgo , fmt .Sprintf (`"info":{"count":7,"count_left":0,"first_time":%q,"last_time":%q}` , formattedTS [0 ], formattedTS [8 ])},
656
+ {"url=test-url&since=" + sinceTenSecondsAgo , fmt .Sprintf (`"info":{"url":"test-url","count":6,"count_left":0,"first_time":%q,"last_time":%q}` , formattedTS [0 ], formattedTS [7 ])},
657
+ {"since=" + sinceTS [0 ], fmt .Sprintf (`"info":{"count":7,"count_left":0,"first_time":%q,"last_time":%q}` , formattedTS [0 ], formattedTS [8 ])},
658
+ {"url=test-url&since=" + sinceTS [0 ], fmt .Sprintf (`"info":{"url":"test-url","count":6,"count_left":0,"first_time":%q,"last_time":%q}` , formattedTS [0 ], formattedTS [7 ])},
659
+ {"since=" + sinceTS [1 ], fmt .Sprintf (`"info":{"count":6,"count_left":0,"first_time":%q,"last_time":%q}` , formattedTS [0 ], formattedTS [8 ])},
660
+ {"url=test-url&since=" + sinceTS [1 ], fmt .Sprintf (`"info":{"url":"test-url","count":5,"count_left":0,"first_time":%q,"last_time":%q}` , formattedTS [0 ], formattedTS [7 ])},
661
+ {"since=" + sinceTS [4 ], fmt .Sprintf (`"info":{"count":3,"count_left":0,"first_time":%q,"last_time":%q}` , formattedTS [0 ], formattedTS [8 ])},
662
+ {"url=test-url&since=" + sinceTS [4 ], fmt .Sprintf (`"info":{"url":"test-url","count":2,"count_left":0,"first_time":%q,"last_time":%q}` , formattedTS [0 ], formattedTS [7 ])},
661
663
{"format=tree" , `"info":{"count":7` },
662
664
{"format=tree&url=test-url" , `"info":{"url":"test-url","count":6` },
663
665
{"format=tree&sort=+time" , `"info":{"count":7` },
@@ -677,19 +679,103 @@ func TestPublic_FindCommentsCtrl_ConsistentCount(t *testing.T) {
677
679
// three comments of which last one deleted and doesn't have controversy so returned last
678
680
{"sort=-controversy&url=test-url&since=" + sinceTS [5 ], fmt .Sprintf (`"score":0,"vote":0,"time":%q,"delete":true}],"info":{"url":"test-url","count":1` , formattedTS [7 ])},
679
681
// test readonly status for the post without comments
680
- {"url=readonly-test" , `"info":{"count":0,"read_only":true` },
681
- {"format=tree&url=readonly-test" , `"info":{"count":0,"read_only":true` },
682
+ {"url=readonly-test" , `"info":{"count":0,"count_left":0,"read_only":true` },
683
+ {"format=tree&url=readonly-test" , `"info":{"count":0,"count_left":0,"read_only":true` },
684
+
685
+ // test parameters limit, offset_id for format=plain
686
+ {"limit=bad" , `{"code":1,"details":"bad limit value","error":"strconv.Atoi: parsing \"bad\": invalid syntax"}` },
687
+ {"offset_id=bad" , `{"code":1,"details":"bad offset_id value","error":"invalid UUID length: 3"}` },
688
+ {"limit=2" , `"info":{"count":7,"count_left":5,"last_comment":"` + ids [1 ]},
689
+ {"limit=6" , `"info":{"count":7,"count_left":1,"last_comment":"` + ids [6 ]},
690
+ {"limit=7" , `"info":{"count":7,"count_left":0,"last_comment":"` + ids [8 ]},
691
+ {"limit=2&url=test-url" , `"info":{"url":"test-url","count":6,"count_left":6,"last_comment":"` + ids [1 ]},
692
+ {"limit=6&url=test-url" , `"info":{"url":"test-url","count":6,"count_left":2,"last_comment":"` + ids [5 ]},
693
+ {"limit=7&url=test-url" , `"info":{"url":"test-url","count":6,"count_left":1,"last_comment":"` + ids [6 ]},
694
+ {fmt .Sprintf ("limit=2&offset_id=%s" , ids [2 ]), `"info":{"count":7,"count_left":2,"last_comment":"` + ids [4 ]},
695
+ {fmt .Sprintf ("limit=2&offset_id=%s" , ids [3 ]), `"info":{"count":7,"count_left":1,"last_comment":"` + ids [6 ]},
696
+ {fmt .Sprintf ("limit=2&offset_id=%s" , ids [4 ]), `"info":{"count":7,"count_left":0` },
697
+ {fmt .Sprintf ("limit=1&offset_id=%s" , ids [6 ]), `"info":{"count":7,"count_left":0` },
698
+ {fmt .Sprintf ("limit=2&offset_id=%s" , ids [8 ]), `"info":{"count":7,"count_left":0` },
699
+ {fmt .Sprintf ("limit=2&url=test-url&offset_id=%s" , ids [2 ]), `"info":{"url":"test-url","count":6,"count_left":3,"last_comment":"` + ids [4 ]},
700
+ {fmt .Sprintf ("limit=2&url=test-url&offset_id=%s" , ids [3 ]), `"info":{"url":"test-url","count":6,"count_left":2,"last_comment":"` + ids [5 ]},
701
+ {fmt .Sprintf ("limit=2&url=test-url&offset_id=%s" , ids [4 ]), `"info":{"url":"test-url","count":6,"count_left":1,"last_comment":"` + ids [6 ]},
702
+ {fmt .Sprintf ("limit=1&url=test-url&offset_id=%s" , ids [6 ]), `"info":{"url":"test-url","count":6,"count_left":0,"last_comment":"` + ids [7 ]},
703
+ {fmt .Sprintf ("limit=2&url=test-url&offset_id=%s" , ids [8 ]), `"info":{"url":"test-url","count":6,"count_left":6,` },
704
+ // deleted comment, offset is ignored in site-wide request but not for particular URL
705
+ {fmt .Sprintf ("limit=2&offset_id=%s" , ids [5 ]), `"info":{"count":7,"count_left":5,"last_comment":"` + ids [1 ]},
706
+ {fmt .Sprintf ("limit=2&url=test-url&offset_id=%s" , ids [5 ]), `"info":{"url":"test-url","count":6,"count_left":0,"last_comment":"` + ids [7 ]},
707
+ // non-existing comment, offset is ignored, deleted comments included into request with "url"
708
+ {fmt .Sprintf ("limit=1&offset_id=%s" , uuid .New ().String ()), `"info":{"count":7,"count_left":6,"last_comment":"` + ids [0 ]},
709
+ {fmt .Sprintf ("limit=1&url=test-url&offset_id=%s" , uuid .New ().String ()), `"info":{"url":"test-url","count":6,"count_left":7,"last_comment":"` + ids [0 ]},
710
+ // since is ignored for tree format, so we test it only for plain
711
+ {"limit=6&since=" + sinceTenSecondsAgo , `"info":{"count":7,"count_left":1,"last_comment":"` + ids [6 ]},
712
+ {"limit=1&since=" + sinceTS [4 ], `"info":{"count":3,"count_left":2,"last_comment":"` + ids [4 ]},
713
+ {"limit=6&url=test-url&since=" + sinceTenSecondsAgo , `"info":{"url":"test-url","count":6,"count_left":2,"last_comment":"` + ids [5 ]},
714
+ {"limit=1&url=test-url&since=" + sinceTS [4 ], `"info":{"url":"test-url","count":2,"count_left":3,"last_comment":"` + ids [4 ]},
715
+ // start with deleted comment timestamp
716
+ {"limit=1&since=" + sinceTS [5 ], `"info":{"count":2,"count_left":1,"last_comment":"` + ids [6 ]},
717
+ {"limit=1&since=" + sinceTS [6 ], `"info":{"count":2,"count_left":1,"last_comment":"` + ids [6 ]},
718
+ {"limit=1&url=test-url&since=" + sinceTS [5 ], `"info":{"url":"test-url","count":1,"count_left":2,"last_comment":"` + ids [5 ]},
719
+ {"limit=1&url=test-url&since=" + sinceTS [6 ], `"info":{"url":"test-url","count":1,"count_left":1,"last_comment":"` + ids [6 ]},
720
+ // test sort
721
+ {"limit=1&sort=+time&url=test-url" , `"info":{"url":"test-url","count":6,"count_left":7,"last_comment":"` + ids [0 ]},
722
+ {"limit=1&sort=-time&url=test-url" , `"info":{"url":"test-url","count":6,"count_left":7,"last_comment":"` + ids [7 ]},
723
+ {"limit=1&sort=+score&url=test-url" , `"info":{"url":"test-url","count":6,"count_left":7,"last_comment":"` + ids [6 ]},
724
+ {"limit=1&sort=-score&url=test-url" , `"info":{"url":"test-url","count":6,"count_left":7,"last_comment":"` + ids [2 ]},
725
+ {"limit=1&sort=+controversy&url=test-url" , `"info":{"url":"test-url","count":6,"count_left":7,"last_comment":"` + ids [0 ]},
726
+ {"limit=1&sort=-controversy&url=test-url" , `"info":{"url":"test-url","count":6,"count_left":7,"last_comment":"` + ids [3 ]},
727
+
728
+ // test parameters limit, offset_id for format=tree
729
+ {"format=tree&limit=bad" , `{"code":1,"details":"bad limit value","error":"strconv.Atoi: parsing \"bad\": invalid syntax"}` },
730
+ {"format=tree&offset_id=bad" , `{"code":1,"details":"bad offset_id value","error":"invalid UUID length: 3"}` },
731
+ {"format=tree&limit=2" , `"info":{"count":7,"count_left":4,"last_comment":"` + ids [0 ]},
732
+ {"format=tree&limit=6" , `"info":{"count":7,"count_left":2,"last_comment":"` + ids [1 ]},
733
+ {"format=tree&limit=7" , `"info":{"count":7,"count_left":1,"last_comment":"` + ids [6 ]},
734
+ {"format=tree&url=test-url&limit=2" , `"info":{"url":"test-url","count":6,"count_left":3,"last_comment":"` + ids [0 ]},
735
+ {"format=tree&url=test-url&limit=6" , `"info":{"url":"test-url","count":6,"count_left":1,"last_comment":"` + ids [1 ]},
736
+ {"format=tree&url=test-url&limit=7" , `"info":{"url":"test-url","count":6,"count_left":0,"last_comment":"` + ids [6 ]},
737
+ // start after first top-level comment
738
+ {fmt .Sprintf ("format=tree&limit=2&offset_id=%s" , ids [0 ]), `"info":{"count":7,"count_left":2,"last_comment":"` + ids [1 ]},
739
+ {fmt .Sprintf ("format=tree&url=test-url&limit=2&offset_id=%s" , ids [0 ]), `"info":{"url":"test-url","count":6,"count_left":1,"last_comment":"` + ids [1 ]},
740
+ // start after second top-level comment
741
+ {fmt .Sprintf ("format=tree&limit=2&offset_id=%s" , ids [1 ]), `"info":{"count":7,"count_left":1,"last_comment":"` + ids [6 ]},
742
+ {fmt .Sprintf ("format=tree&url=test-url&limit=2&offset_id=%s" , ids [1 ]), `"info":{"url":"test-url","count":6,"count_left":0,"last_comment":"` + ids [6 ]},
743
+ // start after third top-level comment, so expect comment to post 2, or no comments on post 1 if "url" is set
744
+ {fmt .Sprintf ("format=tree&limit=1&offset_id=%s" , ids [6 ]), `"info":{"count":7,"count_left":0,"last_comment":"` + ids [8 ]},
745
+ {fmt .Sprintf ("format=tree&url=test-url&limit=1&offset_id=%s" , ids [6 ]), `"info":{"url":"test-url","count":6,"count_left":0` },
746
+ // non-root comment IDs or non-existing IDs are ignored
747
+ {fmt .Sprintf ("format=tree&limit=2&offset_id=%s" , ids [2 ]), `"info":{"count":7,"count_left":4,"last_comment":"` + ids [0 ]},
748
+ {fmt .Sprintf ("format=tree&limit=2&offset_id=%s" , ids [3 ]), `"info":{"count":7,"count_left":4,"last_comment":"` + ids [0 ]},
749
+ {fmt .Sprintf ("format=tree&limit=2&offset_id=%s" , ids [4 ]), `"info":{"count":7,"count_left":4,"last_comment":"` + ids [0 ]},
750
+ {fmt .Sprintf ("format=tree&limit=2&offset_id=%s" , ids [7 ]), `"info":{"count":7,"count_left":4,"last_comment":"` + ids [0 ]},
751
+ {fmt .Sprintf ("format=tree&limit=1&offset_id=%s" , uuid .New ().String ()), `"info":{"count":7,"count_left":4,"last_comment":"` + ids [0 ]},
752
+ {fmt .Sprintf ("format=tree&url=test-url&limit=2&offset_id=%s" , ids [2 ]), `"info":{"url":"test-url","count":6,"count_left":3,"last_comment":"` + ids [0 ]},
753
+ {fmt .Sprintf ("format=tree&url=test-url&limit=2&offset_id=%s" , ids [3 ]), `"info":{"url":"test-url","count":6,"count_left":3,"last_comment":"` + ids [0 ]},
754
+ {fmt .Sprintf ("format=tree&url=test-url&limit=2&offset_id=%s" , ids [4 ]), `"info":{"url":"test-url","count":6,"count_left":3,"last_comment":"` + ids [0 ]},
755
+ {fmt .Sprintf ("format=tree&url=test-url&limit=2&offset_id=%s" , ids [7 ]), `"info":{"url":"test-url","count":6,"count_left":3,"last_comment":"` + ids [0 ]},
756
+ {fmt .Sprintf ("format=tree&url=test-url&limit=1&offset_id=%s" , uuid .New ().String ()), `"info":{"url":"test-url","count":6,"count_left":3,"last_comment":"` + ids [0 ]},
757
+ // test sort
758
+ {"format=tree&limit=1&sort=+time&url=test-url" , `"info":{"url":"test-url","count":6,"count_left":3,"last_comment":"` + ids [0 ]},
759
+ {"format=tree&limit=1&sort=-time&url=test-url" , `"info":{"url":"test-url","count":6,"count_left":5,"last_comment":"` + ids [6 ]},
760
+ {"format=tree&limit=1&sort=+score&url=test-url" , `"info":{"url":"test-url","count":6,"count_left":5,"last_comment":"` + ids [6 ]},
761
+ {"format=tree&limit=1&sort=-score&url=test-url" , `"info":{"url":"test-url","count":6,"count_left":4,"last_comment":"` + ids [1 ]},
762
+ {"format=tree&limit=1&sort=+controversy&url=test-url" , `"info":{"url":"test-url","count":6,"count_left":3,"last_comment":"` + ids [0 ]},
763
+ {"format=tree&limit=1&sort=-controversy&url=test-url" , `"info":{"url":"test-url","count":6,"count_left":5,"last_comment":"` + ids [6 ]},
682
764
}
683
765
684
766
for _ , tc := range testCases {
685
767
t .Run (tc .params , func (t * testing.T ) {
686
768
url := fmt .Sprintf (ts .URL + "/api/v1/find?site=remark42&%s" , tc .params )
687
769
body , code := get (t , url )
688
- assert .Equal (t , http .StatusOK , code )
770
+ expectedStatus := http .StatusOK
771
+ if strings .Contains (tc .params , "=bad" ) {
772
+ expectedStatus = http .StatusBadRequest
773
+ }
774
+ assert .Equal (t , expectedStatus , code )
689
775
assert .Contains (t , body , tc .expectedBody )
690
776
t .Log (body )
691
777
// prevent hit limiter from engaging
692
- time .Sleep (50 * time .Millisecond )
778
+ time .Sleep (80 * time .Millisecond )
693
779
})
694
780
}
695
781
}
0 commit comments