diff --git a/README.md b/README.md index 8a6c1bc..8ef9321 100644 --- a/README.md +++ b/README.md @@ -173,7 +173,7 @@ for { for _, room := range page.Items { fmt.Println(room.Title) } - if !page.HasNext() { + if !page.HasNext { break } page, err = page.Next() diff --git a/people/people.go b/people/people.go index e5ad426..4f02e84 100644 --- a/people/people.go +++ b/people/people.go @@ -56,6 +56,40 @@ type PeoplePage struct { *webexsdk.Page } +// Next retrieves and decodes the next page of people. +func (p *PeoplePage) Next() (*PeoplePage, error) { + page, err := p.Page.Next() + if err != nil { + return nil, err + } + return newPeoplePage(page) +} + +// Prev retrieves and decodes the previous page of people. +func (p *PeoplePage) Prev() (*PeoplePage, error) { + page, err := p.Page.Prev() + if err != nil { + return nil, err + } + return newPeoplePage(page) +} + +// newPeoplePage converts a generic SDK page into a typed people page. +func newPeoplePage(page *webexsdk.Page) (*PeoplePage, error) { + peoplePage := &PeoplePage{ + Page: page, + Items: make([]Person, len(page.Items)), + } + + for i, item := range page.Items { + if err := json.Unmarshal(item, &peoplePage.Items[i]); err != nil { + return nil, err + } + } + + return peoplePage, nil +} + // Config holds the configuration for the People plugin type Config struct { // BatcherWait is the time to wait before processing a batch request @@ -389,19 +423,5 @@ func (c *Client) List(options *ListOptions) (*PeoplePage, error) { return nil, err } - // Unmarshal items into People - peoplePage := &PeoplePage{ - Page: page, - Items: make([]Person, len(page.Items)), - } - - for i, item := range page.Items { - var person Person - if err := json.Unmarshal(item, &person); err != nil { - return nil, err - } - peoplePage.Items[i] = person - } - - return peoplePage, nil + return newPeoplePage(page) } diff --git a/people/people_test.go b/people/people_test.go index 8bccef2..5947ffb 100644 --- a/people/people_test.go +++ b/people/people_test.go @@ -8,6 +8,7 @@ package people import ( "encoding/json" + "fmt" "net/http" "net/http/httptest" "net/url" @@ -159,6 +160,54 @@ func TestList(t *testing.T) { } } +func TestPeoplePageNextAndPrev(t *testing.T) { + var server *httptest.Server + server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + if r.URL.Query().Get("page") == "2" { + w.Header().Set("Link", fmt.Sprintf("<%s/people?page=1>; rel=\"prev\"", server.URL)) + _, _ = w.Write([]byte(`{"items":[{"id":"person-2","displayName":"Second Person","emails":["second@example.com"]}]}`)) + return + } + + w.Header().Set("Link", fmt.Sprintf("<%s/people?page=2>; rel=\"next\"", server.URL)) + _, _ = w.Write([]byte(`{"items":[{"id":"person-1","displayName":"First Person","emails":["first@example.com"]}]}`)) + })) + defer server.Close() + + baseURL, _ := url.Parse(server.URL) + client, err := webexsdk.NewClient("test-token", &webexsdk.Config{ + BaseURL: server.URL, + Timeout: 5 * time.Second, + HttpClient: server.Client(), + }) + if err != nil { + t.Fatalf("Failed to create client: %v", err) + } + client.BaseURL = baseURL + + page, err := New(client, nil).List(&ListOptions{}) + if err != nil { + t.Fatalf("List returned an error: %v", err) + } + + nextPage, err := page.Next() + if err != nil { + t.Fatalf("Next returned an error: %v", err) + } + if len(nextPage.Items) != 1 || nextPage.Items[0].ID != "person-2" { + t.Fatalf("Next returned unexpected people: %+v", nextPage.Items) + } + + previousPage, err := nextPage.Prev() + if err != nil { + t.Fatalf("Prev returned an error: %v", err) + } + if len(previousPage.Items) != 1 || previousPage.Items[0].ID != "person-1" { + t.Fatalf("Prev returned unexpected people: %+v", previousPage.Items) + } +} + func TestInferPersonIDFromUUID(t *testing.T) { testCases := []struct { name string