package httpapi import ( "encoding/json" "fmt" "io" "net/http" "net/http/httptest" "strings" "testing" ) func TestNestedModuleListPagination(t *testing.T) { srv, err := New(Options{InsecureDev: true, SeedDemo: true, BundleSeedHex: testBundleSeed}) if err != nil { t.Fatal(err) } defer srv.Close() tenant, _, modIP, _, _ := srv.Store().DemoIDs() mustSetTestAPIKeys(t, srv, "edkey|"+tenant+"|editor") ts := httptest.NewServer(srv.Handler()) defer ts.Close() client := ts.Client() base := ts.URL mid := modIP for i := 0; i < 3; i++ { body := strings.NewReader(fmt.Sprintf(`{"prefix":"10.%d.0.0/24"}`, 200+i)) req, _ := http.NewRequest(http.MethodPost, base+"/v1/modules/"+mid+"/ip-range-entries", body) req.Header.Set("Authorization", "Bearer edkey") req.Header.Set("Content-Type", "application/json") resp, err := client.Do(req) if err != nil { t.Fatal(err) } _, _ = io.Copy(io.Discard, resp.Body) _ = resp.Body.Close() if resp.StatusCode != http.StatusCreated { t.Fatalf("create entry %d: status %d", i, resp.StatusCode) } } req, _ := http.NewRequest(http.MethodGet, base+"/v1/modules/"+mid+"/ip-range-entries?limit=2", nil) req.Header.Set("Authorization", "Bearer edkey") resp, err := client.Do(req) if err != nil { t.Fatal(err) } defer func() { _ = resp.Body.Close() }() if resp.StatusCode != http.StatusOK { b, _ := io.ReadAll(resp.Body) t.Fatalf("list status %d: %s", resp.StatusCode, b) } var page1 struct { Items []map[string]any `json:"items"` NextCursor *string `json:"next_cursor"` HasMore bool `json:"has_more"` } if err := json.NewDecoder(resp.Body).Decode(&page1); err != nil { t.Fatal(err) } if len(page1.Items) != 2 { t.Fatalf("page1 items: got %d want 2", len(page1.Items)) } if !page1.HasMore || page1.NextCursor == nil || *page1.NextCursor == "" { t.Fatalf("page1: has_more=%v next_cursor=%v", page1.HasMore, page1.NextCursor) } req2, _ := http.NewRequest(http.MethodGet, base+"/v1/modules/"+mid+"/ip-range-entries?limit=2&cursor="+*page1.NextCursor, nil) req2.Header.Set("Authorization", "Bearer edkey") resp2, err := client.Do(req2) if err != nil { t.Fatal(err) } defer func() { _ = resp2.Body.Close() }() var page2 struct { Items []map[string]any `json:"items"` HasMore bool `json:"has_more"` } if err := json.NewDecoder(resp2.Body).Decode(&page2); err != nil { t.Fatal(err) } if len(page1.Items)+len(page2.Items) < 3 { t.Fatalf("expected at least 3 entries across pages, got %d+%d", len(page1.Items), len(page2.Items)) } }