diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 05e4bdfc..89ad4a36 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -37,7 +37,7 @@ to . > If you want to ask a question, we assume that you have read the available [Documentation](https://docs.go-atlassian.io/). -Before you ask a question, it is best to search for existing [Issues](https://github.com/ctreminiom/go-atlassianissues) that might help you. In case you have found a suitable issue and still need clarification, you can write your question in this issue. It is also advisable to search the internet for answers first. +Before you ask a question, it is best to search for existing [Issues](https://github.com/ctreminiom/go-atlassian/issues) that might help you. In case you have found a suitable issue and still need clarification, you can write your question in this issue. It is also advisable to search the internet for answers first. If you then still feel the need to ask a question and need clarification, we recommend the following: diff --git a/confluence/internal/page_impl.go b/confluence/internal/page_impl.go index dc317d31..ec8831af 100644 --- a/confluence/internal/page_impl.go +++ b/confluence/internal/page_impl.go @@ -72,6 +72,19 @@ func (p *PageService) GetsBySpace(ctx context.Context, spaceID int, cursor strin return p.internalClient.GetsBySpace(ctx, spaceID, cursor, limit) } +// GetsByParent returns all children of a page. +// +// 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/{id}/children +// +// https://docs.go-atlassian.io/confluence-cloud/v2/page#get-pages-by-parent +func (p *PageService) GetsByParent(ctx context.Context, pageID int, cursor string, limit int) (*model.ChildPageChunkScheme, *model.ResponseScheme, error) { + return p.internalClient.GetsByParent(ctx, pageID, cursor, limit) +} + // Create creates a page in the space. // // Pages are created as published by default unless specified as a draft in the status field. @@ -273,6 +286,35 @@ func (i *internalPageImpl) GetsBySpace(ctx context.Context, spaceID int, cursor return chunk, response, nil } +func (i *internalPageImpl) GetsByParent(ctx context.Context, parentID int, cursor string, limit int) (*model.ChildPageChunkScheme, *model.ResponseScheme, error) { + + if parentID == 0 { + return nil, nil, model.ErrNoPageIDError + } + + query := url.Values{} + query.Add("limit", strconv.Itoa(limit)) + + if cursor != "" { + query.Add("cursor", cursor) + } + + endpoint := fmt.Sprintf("wiki/api/v2/pages/%v/children?%v", parentID, query.Encode()) + + request, err := i.c.NewRequest(ctx, http.MethodGet, endpoint, "", nil) + if err != nil { + return nil, nil, err + } + + chunk := new(model.ChildPageChunkScheme) + response, err := i.c.Call(request, chunk) + if err != nil { + return nil, response, err + } + + return chunk, response, nil +} + func (i *internalPageImpl) Create(ctx context.Context, payload *model.PageCreatePayloadScheme) (*model.PageScheme, *model.ResponseScheme, error) { endpoint := "wiki/api/v2/pages" diff --git a/confluence/internal/page_impl_test.go b/confluence/internal/page_impl_test.go index 5953c05b..1f8874d3 100644 --- a/confluence/internal/page_impl_test.go +++ b/confluence/internal/page_impl_test.go @@ -584,6 +584,152 @@ func Test_internalPageImpl_GetsBySpace(t *testing.T) { } } +func Test_internalPageImpl_GetsByParent(t *testing.T) { + + type fields struct { + c service.Connector + } + + type args struct { + ctx context.Context + parentID int + cursor string + limit int + } + + testCases := []struct { + name string + fields fields + args args + on func(*fields) + wantErr bool + Err error + }{ + { + name: "when the parameters are correct", + args: args{ + ctx: context.TODO(), + parentID: 20001, + cursor: "cursor-sample", + limit: 200, + }, + on: func(fields *fields) { + + client := mocks.NewConnector(t) + + client.On("NewRequest", + context.Background(), + http.MethodGet, + "wiki/api/v2/pages/20001/children?cursor=cursor-sample&limit=200", + "", nil). + Return(&http.Request{}, nil) + + client.On("Call", + &http.Request{}, + &model.ChildPageChunkScheme{}). + Return(&model.ResponseScheme{}, nil) + + fields.c = client + }, + }, + + { + name: "when the parent id is not provided", + args: args{ + ctx: context.TODO(), + }, + wantErr: true, + Err: model.ErrNoPageIDError, + }, + + { + name: "when the http request cannot be created", + args: args{ + ctx: context.TODO(), + parentID: 20001, + cursor: "cursor-sample", + limit: 200, + }, + on: func(fields *fields) { + + client := mocks.NewConnector(t) + + client.On("NewRequest", + context.Background(), + http.MethodGet, + "wiki/api/v2/pages/20001/children?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"), + }, + + { + name: "when the call fails", + args: args{ + ctx: context.TODO(), + parentID: 20001, + cursor: "cursor-sample", + limit: 200, + }, + on: func(fields *fields) { + + client := mocks.NewConnector(t) + + client.On("NewRequest", + context.Background(), + http.MethodGet, + "wiki/api/v2/pages/20001/children?cursor=cursor-sample&limit=200", + "", nil). + Return(&http.Request{}, nil) + + client.On("Call", + &http.Request{}, + &model.ChildPageChunkScheme{}). + Return(&model.ResponseScheme{}, errors.New("error, request failed")) + + fields.c = client + }, + + wantErr: true, + Err: errors.New("error, request failed"), + }, + } + + 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.GetsByParent(testCase.args.ctx, testCase.args.parentID, + testCase.args.cursor, testCase.args.limit) + + 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_Delete(t *testing.T) { type fields struct { diff --git a/go-atlassian.iml b/go-atlassian.iml new file mode 100644 index 00000000..eacc75a3 --- /dev/null +++ b/go-atlassian.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/pkg/infra/models/confluence_page.go b/pkg/infra/models/confluence_page.go index 1fb40cc8..167378c2 100644 --- a/pkg/infra/models/confluence_page.go +++ b/pkg/infra/models/confluence_page.go @@ -1,5 +1,22 @@ package models +type ChildPageChunkLinksScheme struct { + Next string `json:"next,omitempty"` +} + +type ChildPageChunkScheme struct { + Results []*ChildPageScheme `json:"results,omitempty"` + Links *ChildPageChunkLinksScheme `json:"_links,omitempty"` +} + +type ChildPageScheme struct { + ID string `json:"id,omitempty"` + Status string `json:"status,omitempty"` + Title string `json:"title,omitempty"` + SpaceID string `json:"spaceId,omitempty"` + ChildPosition int `json:"childPosition,omitempty"` +} + type PageOptionsScheme struct { PageIDs []int SpaceIDs []int diff --git a/service/confluence/page.go b/service/confluence/page.go index fcca6725..b9c9fed5 100644 --- a/service/confluence/page.go +++ b/service/confluence/page.go @@ -61,6 +61,17 @@ type PageConnector interface { // https://docs.go-atlassian.io/confluence-cloud/v2/page#get-pages-in-space GetsBySpace(ctx context.Context, spaceID int, cursor string, limit int) (*models.PageChunkScheme, *models.ResponseScheme, error) + // GetsByParent returns all children of a page. + // + // 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/{id}/children + // + // https://docs.go-atlassian.io/confluence-cloud/v2/page#get-pages-by-parent + GetsByParent(ctx context.Context, spaceID int, cursor string, limit int) (*models.ChildPageChunkScheme, *models.ResponseScheme, error) + // Create creates a page in the space. // // Pages are created as published by default unless specified as a draft in the status field.