Skip to content

Commit

Permalink
Merge pull request #187 from ctreminiom/feature/confluence-v2-space-s…
Browse files Browse the repository at this point in the history
…ervice

✨ Created the Confluence Space V2 service.
  • Loading branch information
ctreminiom authored Apr 13, 2023
2 parents 1f36690 + 3c69d7e commit 5fa3e53
Show file tree
Hide file tree
Showing 5 changed files with 454 additions and 4 deletions.
143 changes: 143 additions & 0 deletions confluence/internal/space_v2_impl.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package internal

import (
"context"
"fmt"
model "github.com/ctreminiom/go-atlassian/pkg/infra/models"
"github.com/ctreminiom/go-atlassian/service"
"github.com/ctreminiom/go-atlassian/service/confluence"
"net/http"
"net/url"
"strconv"
"strings"
)

type SpaceV2Service struct {
internalClient confluence.SpaceV2Connector
}

// Bulk returns all spaces.
//
// The results will be sorted by id ascending.
//
// The number of results is limited by the limit parameter and additional results (if available)
//
// will be available through the next URL present in the Link response header.
//
// GET /wiki/api/v2/spaces
//
// https://docs.go-atlassian.io/confluence-cloud/v2/space#get-spaces
func (s *SpaceV2Service) Bulk(ctx context.Context, options *model.GetSpacesOptionSchemeV2, cursor string, limit int) (*model.SpaceChunkV2Scheme, *model.ResponseScheme, error) {
return s.internalClient.Bulk(ctx, options, cursor, limit)
}

// Get returns a specific space.
//
// GET /wiki/api/v2/spaces/{id}
//
// https://docs.go-atlassian.io/confluence-cloud/v2/space#get-space-by-id
func (s *SpaceV2Service) Get(ctx context.Context, spaceID int, descriptionFormat string) (*model.SpaceSchemeV2, *model.ResponseScheme, error) {
return s.internalClient.Get(ctx, spaceID, descriptionFormat)
}

func NewSpaceV2Service(client service.Client) *SpaceV2Service {

return &SpaceV2Service{
internalClient: &internalSpaceV2Impl{c: client},
}
}

type internalSpaceV2Impl struct {
c service.Client
}

func (i *internalSpaceV2Impl) Bulk(ctx context.Context, options *model.GetSpacesOptionSchemeV2, cursor string, limit int) (*model.SpaceChunkV2Scheme, *model.ResponseScheme, error) {

query := url.Values{}
query.Add("limit", strconv.Itoa(limit))

if cursor != "" {
query.Add("cursor", cursor)
}

if options != nil {

if len(options.IDs) != 0 {
query.Add("ids", strings.Trim(strings.Join(strings.Fields(fmt.Sprint(options.IDs)), ","), "[]"))
}

if len(options.Keys) != 0 {
query.Add("keys", strings.Join(options.Keys, ","))
}

if options.Type != "" {
query.Add("type", options.Type)
}

if options.Status != "" {
query.Add("status", options.Status)
}

if len(options.Labels) != 0 {
query.Add("labels", strings.Join(options.Labels, ","))
}

if options.Sort != "" {
query.Add("sort", options.Sort)
}

if options.DescriptionFormat != "" {
query.Add("description-format", options.DescriptionFormat)
}

if options.SerializeIDs {
query.Add("serialize-ids-as-strings", "true")
}

}

endpoint := fmt.Sprintf("wiki/api/v2/spaces?%v", query.Encode())

request, err := i.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
if err != nil {
return nil, nil, err
}

chunk := new(model.SpaceChunkV2Scheme)
response, err := i.c.Call(request, chunk)
if err != nil {
return nil, response, err
}

return chunk, response, nil
}

func (i *internalSpaceV2Impl) Get(ctx context.Context, spaceID int, descriptionFormat string) (*model.SpaceSchemeV2, *model.ResponseScheme, error) {

if spaceID == 0 {
return nil, nil, model.ErrNoSpaceIDError
}

var endpoint strings.Builder
endpoint.WriteString(fmt.Sprintf("wiki/api/v2/spaces/%v", spaceID))

if descriptionFormat != "" {
query := url.Values{}
query.Add("description-format", descriptionFormat)

endpoint.WriteString(fmt.Sprintf("?%v", query.Encode()))
}

request, err := i.c.NewRequest(ctx, http.MethodGet, endpoint.String(), nil)
if err != nil {
return nil, nil, err
}

space := new(model.SpaceSchemeV2)
response, err := i.c.Call(request, space)
if err != nil {
return nil, response, err
}

return space, response, nil
}
244 changes: 244 additions & 0 deletions confluence/internal/space_v2_impl_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
package internal

import (
"context"
"errors"
model "github.com/ctreminiom/go-atlassian/pkg/infra/models"
"github.com/ctreminiom/go-atlassian/service"
"github.com/ctreminiom/go-atlassian/service/mocks"
"github.com/stretchr/testify/assert"
"net/http"
"testing"
)

func Test_internalSpaceV2Impl_Bulk(t *testing.T) {

optionsMocked := &model.GetSpacesOptionSchemeV2{
IDs: []int{10001, 10002},
Keys: []string{"DUMMY"},
Type: "global",
Status: "current",
Labels: []string{"test-label"},
Sort: "-name",
DescriptionFormat: "view",
SerializeIDs: true,
}

type fields struct {
c service.Client
}

type args struct {
ctx context.Context
options *model.GetSpacesOptionSchemeV2
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(),
options: optionsMocked,
cursor: "cursor_sample_uuid",
limit: 50,
},
on: func(fields *fields) {

client := mocks.NewClient(t)

client.On("NewRequest",
context.Background(),
http.MethodGet,
"wiki/api/v2/spaces?cursor=cursor_sample_uuid&description-format=view&ids=10001%2C10002&keys=DUMMY&labels=test-label&limit=50&serialize-ids-as-strings=true&sort=-name&status=current&type=global",
nil).
Return(&http.Request{}, nil)

client.On("Call",
&http.Request{},
&model.SpaceChunkV2Scheme{}).
Return(&model.ResponseScheme{}, nil)

fields.c = client

},
},

{
name: "when the http request cannot be created",
args: args{
ctx: context.TODO(),
options: optionsMocked,
cursor: "cursor_sample_uuid",
limit: 50,
},
on: func(fields *fields) {

client := mocks.NewClient(t)

client.On("NewRequest",
context.Background(),
http.MethodGet,
"wiki/api/v2/spaces?cursor=cursor_sample_uuid&description-format=view&ids=10001%2C10002&keys=DUMMY&labels=test-label&limit=50&serialize-ids-as-strings=true&sort=-name&status=current&type=global",
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 := NewSpaceV2Service(testCase.fields.c)

gotResult, gotResponse, err := newService.Bulk(testCase.args.ctx, testCase.args.options, 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_internalSpaceV2Impl_Get(t *testing.T) {

type fields struct {
c service.Client
}

type args struct {
ctx context.Context
spaceID int
descriptionFormat string
}

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(),
spaceID: 10001,
descriptionFormat: "view",
},
on: func(fields *fields) {

client := mocks.NewClient(t)

client.On("NewRequest",
context.Background(),
http.MethodGet,
"wiki/api/v2/spaces/10001?description-format=view",
nil).
Return(&http.Request{}, nil)

client.On("Call",
&http.Request{},
&model.SpaceSchemeV2{}).
Return(&model.ResponseScheme{}, nil)

fields.c = client

},
},

{
name: "when the space id is not provided",
args: args{
ctx: context.TODO(),
},
wantErr: true,
Err: model.ErrNoSpaceIDError,
},

{
name: "when the http request cannot be created",
args: args{
ctx: context.TODO(),
spaceID: 10001,
descriptionFormat: "view",
},
on: func(fields *fields) {

client := mocks.NewClient(t)

client.On("NewRequest",
context.Background(),
http.MethodGet,
"wiki/api/v2/spaces/10001?description-format=view",
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 := NewSpaceV2Service(testCase.fields.c)

gotResult, gotResponse, err := newService.Get(testCase.args.ctx, testCase.args.spaceID, testCase.args.descriptionFormat)

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)
}

})
}
}
Loading

0 comments on commit 5fa3e53

Please sign in to comment.