diff --git a/confluence/internal/page_impl.go b/confluence/internal/page_impl.go index 0667bd2b..9336c020 100644 --- a/confluence/internal/page_impl.go +++ b/confluence/internal/page_impl.go @@ -9,6 +9,7 @@ import ( "net/http" "net/url" "strconv" + "strings" ) // NewPageService returns a new Confluence V2 Page service @@ -44,6 +45,19 @@ func (p *PageService) Bulk(ctx context.Context, cursor string, limit int) (*mode return p.internalClient.Bulk(ctx, cursor, limit) } +// BulkFiltered returns all pages that fit the filtering criteria +// +// # The number of results is limited by the limit parameter and additional results +// +// (if available) will be available through the next cursor +// +// GET /wiki/api/v2/pages +// +// https://docs.go-atlassian.io/confluence-cloud/v2/page#get-pages +func (p *PageService) BulkFiltered(ctx context.Context, status, format, cursor string, limit int, pageIDs ...int) (*model.PageChunkScheme, *model.ResponseScheme, error) { + return p.internalClient.BulkFiltered(ctx, status, format, cursor, limit, pageIDs...) +} + // GetsByLabel returns the pages of specified label. // // # The number of results is limited by the limit parameter and additional results @@ -142,14 +156,34 @@ func (i *internalPageImpl) Get(ctx context.Context, pageID int, format string, d } func (i *internalPageImpl) Bulk(ctx context.Context, cursor string, limit int) (*model.PageChunkScheme, *model.ResponseScheme, error) { + return i.BulkFiltered(ctx, "", "", cursor, limit) +} + +func (i *internalPageImpl) BulkFiltered(ctx context.Context, status, format, cursor string, limit int, pageIDs ...int) (*model.PageChunkScheme, *model.ResponseScheme, error) { query := url.Values{} query.Add("limit", strconv.Itoa(limit)) + if status != "" { + query.Add("status", status) + } + + if format != "" { + query.Add("body-format", format) + } + if cursor != "" { query.Add("cursor", cursor) } + if len(pageIDs) > 0 { + ids := make([]string, 0, len(pageIDs)) + for _, id := range pageIDs { + ids = append(ids, strconv.Itoa(id)) + } + query.Add("id", strings.Join(ids, ",")) + } + endpoint := fmt.Sprintf("wiki/api/v2/pages?%v", query.Encode()) request, err := i.c.NewRequest(ctx, http.MethodGet, endpoint, nil) diff --git a/confluence/internal/page_impl_test.go b/confluence/internal/page_impl_test.go index 377f4db0..94cc2b4b 100644 --- a/confluence/internal/page_impl_test.go +++ b/confluence/internal/page_impl_test.go @@ -234,6 +234,148 @@ func Test_internalPageImpl_Bulk(t *testing.T) { } } +func Test_internalPageImpl_BulkFiltered(t *testing.T) { + + type fields struct { + c service.Client + } + + type args struct { + ctx context.Context + status string + format string + cursor string + limit int + pageIDs []int + } + + testCases := []struct { + name string + fields fields + args args + on func(*fields) + wantErr bool + Err error + }{ + { + name: "when the parameters are minimally correct", + args: args{ + ctx: context.TODO(), + cursor: "cursor-sample", + limit: 200, + }, + on: func(fields *fields) { + + client := mocks.NewClient(t) + + client.On("NewRequest", + context.Background(), + http.MethodGet, + "wiki/api/v2/pages?cursor=cursor-sample&limit=200", + nil). + Return(&http.Request{}, nil) + + client.On("Call", + &http.Request{}, + &model.PageChunkScheme{}). + Return(&model.ResponseScheme{}, nil) + + fields.c = client + }, + }, + + { + name: "when the parameters are maximally correct", + args: args{ + ctx: context.TODO(), + status: "status-sample", + format: "format-sample", + cursor: "cursor-sample", + limit: 200, + pageIDs: []int{1, 2, 3, 4, 5, 6}, + }, + on: func(fields *fields) { + + client := mocks.NewClient(t) + + client.On("NewRequest", + context.Background(), + http.MethodGet, + "wiki/api/v2/pages?body-format=format-sample&cursor=cursor-sample&id=1%2C2%2C3%2C4%2C5%2C6&limit=200&status=status-sample", + nil). + Return(&http.Request{}, nil) + + client.On("Call", + &http.Request{}, + &model.PageChunkScheme{}). + Return(&model.ResponseScheme{}, nil) + + fields.c = client + }, + }, + + { + name: "when the http request cannot be created", + args: args{ + ctx: context.TODO(), + cursor: "cursor-sample", + limit: 200, + }, + on: func(fields *fields) { + + client := mocks.NewClient(t) + + client.On("NewRequest", + context.Background(), + http.MethodGet, + "wiki/api/v2/pages?cursor=cursor-sample&limit=200", + nil). + Return(&http.Request{}, errors.New("error, unable to create the http request")) + + fields.c = client + + }, + wantErr: true, + Err: errors.New("error, unable to create the http request"), + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + + if testCase.on != nil { + testCase.on(&testCase.fields) + } + + newService := NewPageService(testCase.fields.c) + + gotResult, gotResponse, err := newService.BulkFiltered( + testCase.args.ctx, + testCase.args.status, + testCase.args.format, + testCase.args.cursor, + testCase.args.limit, + testCase.args.pageIDs..., + ) + + if testCase.wantErr { + + if err != nil { + t.Logf("error returned: %v", err.Error()) + } + + assert.EqualError(t, err, testCase.Err.Error()) + } else { + + assert.NoError(t, err) + assert.NotEqual(t, gotResponse, nil) + assert.NotEqual(t, gotResult, nil) + } + + }) + } +} + func Test_internalPageImpl_GetsByLabel(t *testing.T) { type fields struct { diff --git a/service/confluence/page.go b/service/confluence/page.go index 1df29729..2b9528e3 100644 --- a/service/confluence/page.go +++ b/service/confluence/page.go @@ -27,6 +27,17 @@ type PageConnector interface { // https://docs.go-atlassian.io/confluence-cloud/v2/page#get-pages Bulk(ctx context.Context, cursor string, limit int) (*models.PageChunkScheme, *models.ResponseScheme, error) + // BulkFiltered returns all pages that fit the filtering criteria. + // + // The number of results is limited by the limit parameter and additional results + // + // (if available) will be available through the next cursor + // + // GET /wiki/api/v2/pages + // + // https://docs.go-atlassian.io/confluence-cloud/v2/page#get-pages + BulkFiltered(ctx context.Context, status, format, cursor string, limit int, pageIDs ...int) (*models.PageChunkScheme, *models.ResponseScheme, error) + // GetsByLabel returns the pages of specified label. // // The number of results is limited by the limit parameter and additional results