Repository: ctreminiom/go-atlassian
Pull request #235 (2023-08-14 05:56:35)

:sparkles: Added the Page.Gets() method on the Confluence V2 module
1. Created a method called Gets() under the PageConnector interface

2. Deprecated the Bulk() method because the Gets() method enables the possibility to set filter criteria.

3. Removed the BulkFiltered() method

4. Added the Unit Test Cases with a 95% of coverage.


Patch:
diff --git a/confluence/internal/page_impl.go b/confluence/internal/page_impl.go
index b084a55..dc317d3 100644
--- a/confluence/internal/page_impl.go
+++ b/confluence/internal/page_impl.go
@@ -30,38 +30,28 @@ func (p *PageService) Get(ctx context.Context, pageID int, format string, draft
 	return p.internalClient.Get(ctx, pageID, format, draft, version)
 }
 
-// Bulk returns all pages.
-//
-// # The number of results is limited by the limit parameter and additional results
-//
-// (if available) will be available through the next cursor
+// Gets returns all pages.
 //
 // GET /wiki/api/v2/pages
 //
 // https://docs.go-atlassian.io/confluence-cloud/v2/page#get-pages
-func (p *PageService) Bulk(ctx context.Context, cursor string, limit int) (*model.PageChunkScheme, *model.ResponseScheme, error) {
-	return p.internalClient.Bulk(ctx, cursor, limit)
+func (p *PageService) Gets(ctx context.Context, options *model.PageOptionsScheme, cursor string, limit int) (*model.PageChunkScheme, *model.ResponseScheme, error) {
+	return p.internalClient.Gets(ctx, options, cursor, limit)
 }
 
-// BulkFiltered returns all pages that fit the filtering criteria
-//
-// # The number of results is limited by the limit parameter and additional results
+// Bulk returns all pages.
 //
-// (if available) will be available through the next cursor
+// Deprecated. Please use Page.Gets() instead.
 //
 // 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...)
+func (p *PageService) Bulk(ctx context.Context, cursor string, limit int) (*model.PageChunkScheme, *model.ResponseScheme, error) {
+	return p.internalClient.Bulk(ctx, cursor, limit)
 }
 
 // GetsByLabel returns the pages of specified label.
 //
-// # 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/labels/{id}/pages
 //
 // https://docs.go-atlassian.io/confluence-cloud/v2/page#get-pages-for-label
@@ -117,85 +107,108 @@ type internalPageImpl struct {
 	c service.Connector
 }
 
-func (i *internalPageImpl) Get(ctx context.Context, pageID int, format string, draft bool, version int) (*model.PageScheme, *model.ResponseScheme, error) {
-
-	if pageID == 0 {
-		return nil, nil, model.ErrNoPageIDError
-	}
+func (i *internalPageImpl) Gets(ctx context.Context, options *model.PageOptionsScheme, cursor string, limit int) (*model.PageChunkScheme, *model.ResponseScheme, error) {
 
 	query := url.Values{}
+	query.Add("limit", strconv.Itoa(limit))
 
-	if format != "" {
-		query.Add("body-format", format)
+	if cursor != "" {
+		query.Add("cursor", cursor)
 	}
 
-	if draft {
-		query.Add("get-draft", "true")
-	}
+	if options != nil {
 
-	if version != 0 {
-		query.Add("version", strconv.Itoa(version))
+		if options.Title != "" {
+			query.Add("title", options.Title)
+		}
+
+		if options.Sort != "" {
+			query.Add("sort", options.Sort)
+		}
+
+		if options.BodyFormat != "" {
+			query.Add("body-format", options.BodyFormat)
+		}
+
+		if options.Status != nil {
+			query.Add("status", strings.Join(options.Status, ","))
+		}
+
+		if len(options.PageIDs) > 0 {
+
+			var pageIDs = make([]string, 0, len(options.PageIDs))
+			for _, pageIDAsInt := range options.PageIDs {
+				pageIDs = append(pageIDs, strconv.Itoa(pageIDAsInt))
+			}
+
+			query.Add("id", strings.Join(pageIDs, ","))
+		}
+
+		if len(options.SpaceIDs) > 0 {
+
+			var spaceIDs = make([]string, 0, len(options.SpaceIDs))
+			for _, spaceIDAsInt := range options.SpaceIDs {
+				spaceIDs = append(spaceIDs, strconv.Itoa(spaceIDAsInt))
+			}
+
+			query.Add("space-id", strings.Join(spaceIDs, ","))
+		}
 	}
 
-	endpoint := fmt.Sprintf("wiki/api/v2/pages/%v?%v", pageID, query.Encode())
+	endpoint := fmt.Sprintf("wiki/api/v2/pages?%v", query.Encode())
 
 	request, err := i.c.NewRequest(ctx, http.MethodGet, endpoint, "", nil)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	page := new(model.PageScheme)
-	response, err := i.c.Call(request, page)
+	chunk := new(model.PageChunkScheme)
+	response, err := i.c.Call(request, chunk)
 	if err != nil {
 		return nil, response, err
 	}
 
-	return page, response, nil
+	return chunk, response, nil
 }
 
-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) Get(ctx context.Context, pageID int, format string, draft bool, version int) (*model.PageScheme, *model.ResponseScheme, error) {
 
-func (i *internalPageImpl) BulkFiltered(ctx context.Context, status, format, cursor string, limit int, pageIDs ...int) (*model.PageChunkScheme, *model.ResponseScheme, error) {
+	if pageID == 0 {
+		return nil, nil, model.ErrNoPageIDError
+	}
 
 	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 draft {
+		query.Add("get-draft", "true")
 	}
 
-	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, ","))
+	if version != 0 {
+		query.Add("version", strconv.Itoa(version))
 	}
 
-	endpoint := fmt.Sprintf("wiki/api/v2/pages?%v", query.Encode())
+	endpoint := fmt.Sprintf("wiki/api/v2/pages/%v?%v", pageID, query.Encode())
 
 	request, err := i.c.NewRequest(ctx, http.MethodGet, endpoint, "", nil)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	chunk := new(model.PageChunkScheme)
-	response, err := i.c.Call(request, chunk)
+	page := new(model.PageScheme)
+	response, err := i.c.Call(request, page)
 	if err != nil {
 		return nil, response, err
 	}
 
-	return chunk, response, nil
+	return page, response, nil
+}
+
+func (i *internalPageImpl) Bulk(ctx context.Context, cursor string, limit int) (*model.PageChunkScheme, *model.ResponseScheme, error) {
+	return i.Gets(ctx, nil, cursor, limit)
 }
 
 func (i *internalPageImpl) GetsByLabel(ctx context.Context, labelID int, sort, cursor string, limit int) (*model.PageChunkScheme, *model.ResponseScheme, error) {
diff --git a/pkg/infra/models/confluence_page.go b/pkg/infra/models/confluence_page.go
index 2d9a3e6..2011666 100644
--- a/pkg/infra/models/confluence_page.go
+++ b/pkg/infra/models/confluence_page.go
@@ -1,5 +1,14 @@
 package models
 
+type PageOptionsScheme struct {
+	PageIDs    []int
+	SpaceIDs   []int
+	Sort       string
+	Status     []string
+	Title      string
+	BodyFormat string
+}
+
 type PageChunkScheme struct {
 	Results []*PageScheme         `json:"results,omitempty"`
 	Links   *PageChunkLinksScheme `json:"_links,omitempty"`
@@ -10,15 +19,17 @@ type PageChunkLinksScheme struct {
 }
 
 type PageScheme struct {
-	ID        int                `json:"id,omitempty"`
-	Status    string             `json:"status,omitempty"`
-	Title     string             `json:"title,omitempty"`
-	SpaceID   int                `json:"spaceId,omitempty"`
-	ParentID  int                `json:"parentId,omitempty"`
-	AuthorID  string             `json:"authorId,omitempty"`
-	CreatedAt string             `json:"createdAt,omitempty"`
-	Version   *PageVersionScheme `json:"version,omitempty"`
-	Body      *PageBodyScheme    `json:"body,omitempty"`
+	ID         string             `json:"id,omitempty"`
+	Status     string             `json:"status,omitempty"`
+	Title      string             `json:"title,omitempty"`
+	SpaceID    string             `json:"spaceId,omitempty"`
+	ParentID   string             `json:"parentId,omitempty"`
+	AuthorID   string             `json:"authorId,omitempty"`
+	CreatedAt  string             `json:"createdAt,omitempty"`
+	ParentType string             `json:"parentType,omitempty"`
+	Position   int                `json:"position,omitempty"`
+	Version    *PageVersionScheme `json:"version,omitempty"`
+	Body       *PageBodyScheme    `json:"body,omitempty"`
 }
 
 type PageVersionScheme struct {
diff --git a/service/confluence/page.go b/service/confluence/page.go
index 2b9528e..fcca672 100644
--- a/service/confluence/page.go
+++ b/service/confluence/page.go
@@ -22,12 +22,13 @@ type PageConnector interface {
 	//
 	// (if available) will be available through the next cursor
 	//
+	// Deprecated. Please use Page.Gets() instead.
+	//
 	// GET /wiki/api/v2/pages
 	//
-	// 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.
+	// Gets returns all pages that fit the filtering criteria.
 	//
 	// The number of results is limited by the limit parameter and additional results
 	//
@@ -36,7 +37,7 @@ type PageConnector interface {
 	// 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)
+	Gets(ctx context.Context, options *models.PageOptionsScheme, cursor string, limit int) (*models.PageChunkScheme, *models.ResponseScheme, error)
 
 	// GetsByLabel returns the pages of specified label.
 	//


Test patch:
diff --git a/confluence/internal/page_impl_test.go b/confluence/internal/page_impl_test.go
index 635d6f1..08dd4f7 100644
--- a/confluence/internal/page_impl_test.go
+++ b/confluence/internal/page_impl_test.go
@@ -131,16 +131,17 @@ func Test_internalPageImpl_Get(t *testing.T) {
 	}
 }
 
-func Test_internalPageImpl_Bulk(t *testing.T) {
+func Test_internalPageImpl_Gets(t *testing.T) {
 
 	type fields struct {
 		c service.Connector
 	}
 
 	type args struct {
-		ctx    context.Context
-		cursor string
-		limit  int
+		ctx     context.Context
+		options *model.PageOptionsScheme
+		cursor  string
+		limit   int
 	}
 
 	testCases := []struct {
@@ -154,7 +155,15 @@ func Test_internalPageImpl_Bulk(t *testing.T) {
 		{
 			name: "when the parameters are correct",
 			args: args{
-				ctx:    context.TODO(),
+				ctx: context.TODO(),
+				options: &model.PageOptionsScheme{
+					PageIDs:    []int{112, 1223},
+					SpaceIDs:   []int{3040, 3040},
+					Sort:       "-created-date",
+					Status:     []string{"current", "trashed"},
+					Title:      "Title sample!!",
+					BodyFormat: "atlas_doc_format",
+				},
 				cursor: "cursor-sample",
 				limit:  200,
 			},
@@ -165,7 +174,7 @@ func Test_internalPageImpl_Bulk(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"wiki/api/v2/pages?cursor=cursor-sample&limit=200",
+					"wiki/api/v2/pages?body-format=atlas_doc_format&cursor=cursor-sample&id=112%2C1223&limit=200&sort=-created-date&space-id=3040%2C3040&status=current%2Ctrashed&title=Title+sample%21%21",
 					"", nil).
 					Return(&http.Request{}, nil)
 
@@ -183,7 +192,15 @@ func Test_internalPageImpl_Bulk(t *testing.T) {
 			args: args{
 				ctx:    context.TODO(),
 				cursor: "cursor-sample",
-				limit:  200,
+				options: &model.PageOptionsScheme{
+					PageIDs:    []int{112, 1223},
+					SpaceIDs:   []int{3040, 3040},
+					Sort:       "-created-date",
+					Status:     []string{"current", "trashed"},
+					Title:      "Title sample!!",
+					BodyFormat: "atlas_doc_format",
+				},
+				limit: 200,
 			},
 			on: func(fields *fields) {
 
@@ -192,7 +209,7 @@ func Test_internalPageImpl_Bulk(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"wiki/api/v2/pages?cursor=cursor-sample&limit=200",
+					"wiki/api/v2/pages?body-format=atlas_doc_format&cursor=cursor-sample&id=112%2C1223&limit=200&sort=-created-date&space-id=3040%2C3040&status=current%2Ctrashed&title=Title+sample%21%21",
 					"", nil).
 					Return(&http.Request{}, errors.New("error, unable to create the http request"))
 
@@ -213,7 +230,7 @@ func Test_internalPageImpl_Bulk(t *testing.T) {
 
 			newService := NewPageService(testCase.fields.c)
 
-			gotResult, gotResponse, err := newService.Bulk(testCase.args.ctx, testCase.args.cursor, testCase.args.limit)
+			gotResult, gotResponse, err := newService.Gets(testCase.args.ctx, testCase.args.options, testCase.args.cursor, testCase.args.limit)
 
 			if testCase.wantErr {
 
@@ -233,19 +250,16 @@ func Test_internalPageImpl_Bulk(t *testing.T) {
 	}
 }
 
-func Test_internalPageImpl_BulkFiltered(t *testing.T) {
+func Test_internalPageImpl_Bulk(t *testing.T) {
 
 	type fields struct {
 		c service.Connector
 	}
 
 	type args struct {
-		ctx     context.Context
-		status  string
-		format  string
-		cursor  string
-		limit   int
-		pageIDs []int
+		ctx    context.Context
+		cursor string
+		limit  int
 	}
 
 	testCases := []struct {
@@ -257,7 +271,7 @@ func Test_internalPageImpl_BulkFiltered(t *testing.T) {
 		Err     error
 	}{
 		{
-			name: "when the parameters are minimally correct",
+			name: "when the parameters are correct",
 			args: args{
 				ctx:    context.TODO(),
 				cursor: "cursor-sample",
@@ -283,36 +297,6 @@ func Test_internalPageImpl_BulkFiltered(t *testing.T) {
 			},
 		},
 
-		{
-			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.NewConnector(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{
@@ -348,14 +332,7 @@ func Test_internalPageImpl_BulkFiltered(t *testing.T) {
 
 			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...,
-			)
+			gotResult, gotResponse, err := newService.Bulk(testCase.args.ctx, testCase.args.cursor, testCase.args.limit)
 
 			if testCase.wantErr {