From 3f0f92285fa92cd90c00412b2dfda09649c6b51e Mon Sep 17 00:00:00 2001 From: Matthias Preu <5973515+mpreu@users.noreply.github.com> Date: Thu, 27 Feb 2020 02:53:30 +0100 Subject: [PATCH] Fix missing options for GetUsersWithAnyPermission In the different variants the project key and repository slug were missing. Added as well was a struct to retrieve users and their permissions along with a getter function for the response. A basic test was included, too. --- api_response.go | 29 ++++++++---- api_response_test.go | 108 ++++++++++++++++++++++++++++++++++++++----- default_api.go | 7 ++- default_api_test.go | 11 +++-- 4 files changed, 129 insertions(+), 26 deletions(-) diff --git a/api_response.go b/api_response.go index 011d7ad..1a4d6fc 100644 --- a/api_response.go +++ b/api_response.go @@ -5,8 +5,8 @@ package bitbucketv1 import ( - "io/ioutil" "encoding/json" + "io/ioutil" "net/http" "strings" @@ -105,6 +105,12 @@ type UserWithMetadata struct { Status string `json:"status"` } +// UserPermission contains a user with its permission +type UserPermission struct { + User User `json:"user"` + Permission string `json:"permission"` +} + type MergeResult struct { Outcome string `json:"outcome"` Current bool `json:"current"` @@ -275,16 +281,16 @@ type Content struct { } type WebhookConfiguration struct { - Secret string `json:"secret"` + Secret string `json:"secret"` } type Webhook struct { - ID int `json:"id"` - Name string `json:"name"` - Events []string `json:"events"` - Url string `json:"url"` - Active bool `json:"active"` - Configuration WebhookConfiguration `json:"configuration"` + ID int `json:"id"` + Name string `json:"name"` + Events []string `json:"events"` + Url string `json:"url"` + Active bool `json:"active"` + Configuration WebhookConfiguration `json:"configuration"` } func (k *SSHKey) String() string { @@ -356,6 +362,13 @@ func GetContentResponse(r *APIResponse) (Content, error) { return c, err } +// GetUsersPermissionResponse casts user permissions into structure +func GetUsersPermissionResponse(r *APIResponse) ([]UserPermission, error) { + var c []UserPermission + err := mapstructure.Decode(r.Values["values"], &c) + return c, err +} + // GetWebhooksResponse cast Webhooks into structure func GetWebhooksResponse(r *APIResponse) ([]Webhook, error) { var h []Webhook diff --git a/api_response_test.go b/api_response_test.go index 726464e..836a102 100644 --- a/api_response_test.go +++ b/api_response_test.go @@ -233,10 +233,10 @@ func TestGetWebhooksResponse(t *testing.T) { name: "Empty list", args: args{ r: &APIResponse{ - Values: map[string]interface{}{ "values": []interface{}{} }, + Values: map[string]interface{}{"values": []interface{}{}}, }, }, - want: []Webhook{}, + want: []Webhook{}, wantErr: false, }, { @@ -245,11 +245,11 @@ func TestGetWebhooksResponse(t *testing.T) { r: &APIResponse{ Values: map[string]interface{}{ "values": []interface{}{map[string]interface{}{ - "id": 1, - "name": "foo", - "url": "http://bitbucket.localhost/hook", + "id": 1, + "name": "foo", + "url": "http://bitbucket.localhost/hook", "active": false, - "events": []string{ "repo:modified" }, + "events": []string{"repo:modified"}, "configuration": map[string]interface{}{ "secret": "password", }, @@ -259,11 +259,11 @@ func TestGetWebhooksResponse(t *testing.T) { }, want: []Webhook{ Webhook{ - ID: 1, - Name: "foo", - Url: "http://bitbucket.localhost/hook", + ID: 1, + Name: "foo", + Url: "http://bitbucket.localhost/hook", Active: false, - Events: []string{ "repo:modified" }, + Events: []string{"repo:modified"}, Configuration: WebhookConfiguration{ Secret: "password", }, @@ -275,10 +275,10 @@ func TestGetWebhooksResponse(t *testing.T) { name: "Bad response", args: args{ r: &APIResponse{ - Values: map[string]interface{}{ "values": "not an array" }, + Values: map[string]interface{}{"values": "not an array"}, }, }, - want: nil, + want: nil, wantErr: true, }, } @@ -296,6 +296,90 @@ func TestGetWebhooksResponse(t *testing.T) { } } +func TestGetUsersPermissionResponse(t *testing.T) { + type args struct { + r *APIResponse + } + tests := []struct { + name string + args args + want []UserPermission + wantErr bool + }{ + { + name: "Empty list", + args: args{ + r: &APIResponse{ + Values: map[string]interface{}{"values": []interface{}{}}, + }, + }, + want: []UserPermission{}, + wantErr: false, + }, + { + name: "Bad response", + args: args{ + r: &APIResponse{ + Values: map[string]interface{}{"values": "not an array"}, + }, + }, + want: nil, + wantErr: true, + }, + { + name: "Single user permission", + args: args{ + r: &APIResponse{ + Values: map[string]interface{}{ + "values": []interface{}{map[string]interface{}{ + "user": map[string]interface{}{ + "name": "jcitizen", + // TODO: This field should be emailAddress according to the REST API + // documentation, but is defined as Email in the User struct. Mapstruct # + // therefore only decodes this when reffered to as 'email', which is plain wrong. + // "email": "jane@example.com", + "id": 101, + "displayName": "Jane Citizen", + "active": true, + "slug": "jcitizen", + "type": "NORMAL", + }, + "permission": "REPO_ADMIN", + }}, + }, + }, + }, + want: []UserPermission{ + UserPermission{ + User: User{ + Name: "jcitizen", + // Email: "jane@example.com", + ID: 101, + DisplayName: "Jane Citizen", + Active: true, + Slug: "jcitizen", + Type: "NORMAL", + }, + Permission: "REPO_ADMIN", + }, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := GetUsersPermissionResponse(tt.args.r) + if err != nil && !tt.wantErr { + t.Errorf("GetUsersPermissionResponse() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetUsersPermissionResponse() = %v, want %v", got, tt.want) + } + }) + } +} + func TestNewAPIResponse(t *testing.T) { type args struct { r *http.Response diff --git a/default_api.go b/default_api.go index 798877e..ca6d982 100644 --- a/default_api.go +++ b/default_api.go @@ -7721,7 +7721,7 @@ func (a *DefaultApiService) GetUsersWithAnyPermission(localVarOptionals map[stri @param optional (nil or map[string]interface{}) with one or more of: @param "filter" (string) if specified only group names containing the supplied string will be returned @return */ -func (a *DefaultApiService) GetUsersWithAnyPermission_23(localVarOptionals map[string]interface{}) (*APIResponse, error) { +func (a *DefaultApiService) GetUsersWithAnyPermission_23(projectKey string, localVarOptionals map[string]interface{}) (*APIResponse, error) { var ( localVarHTTPMethod = strings.ToUpper("Get") localVarPostBody interface{} @@ -7731,6 +7731,7 @@ func (a *DefaultApiService) GetUsersWithAnyPermission_23(localVarOptionals map[s // create path and map variables localVarPath := a.client.cfg.BasePath + "/api/1.0/projects/{projectKey}/permissions/users" + localVarPath = strings.Replace(localVarPath, "{"+"projectKey"+"}", fmt.Sprintf("%v", projectKey), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -7784,7 +7785,7 @@ func (a *DefaultApiService) GetUsersWithAnyPermission_23(localVarOptionals map[s @param optional (nil or map[string]interface{}) with one or more of: @param "filter" (string) if specified only group names containing the supplied string will be returned @return */ -func (a *DefaultApiService) GetUsersWithAnyPermission_24(localVarOptionals map[string]interface{}) (*APIResponse, error) { +func (a *DefaultApiService) GetUsersWithAnyPermission_24(projectKey string, repositorySlug string, localVarOptionals map[string]interface{}) (*APIResponse, error) { var ( localVarHTTPMethod = strings.ToUpper("Get") localVarPostBody interface{} @@ -7794,6 +7795,8 @@ func (a *DefaultApiService) GetUsersWithAnyPermission_24(localVarOptionals map[s // create path and map variables localVarPath := a.client.cfg.BasePath + "/api/1.0/projects/{projectKey}/repos/{repositorySlug}/permissions/users" + localVarPath = strings.Replace(localVarPath, "{"+"projectKey"+"}", fmt.Sprintf("%v", projectKey), -1) + localVarPath = strings.Replace(localVarPath, "{"+"repositorySlug"+"}", fmt.Sprintf("%v", repositorySlug), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} diff --git a/default_api_test.go b/default_api_test.go index be44726..a0d9d15 100644 --- a/default_api_test.go +++ b/default_api_test.go @@ -4200,6 +4200,7 @@ func TestDefaultApiService_GetUsersWithAnyPermission_23(t *testing.T) { client *APIClient } type args struct { + projectKey string localVarOptionals map[string]interface{} } tests := []struct { @@ -4209,14 +4210,14 @@ func TestDefaultApiService_GetUsersWithAnyPermission_23(t *testing.T) { want *APIResponse wantErr bool }{ - {"networkErrorContextExceeded", fields{client: generateConfigFake()}, args{}, &APIResponse{Message: "Get https://stash.domain.com/rest/api/1.0/projects/%7BprojectKey%7D/permissions/users: context canceled"}, true}, + {"networkErrorContextExceeded", fields{client: generateConfigFake()}, args{}, &APIResponse{Message: "Get https://stash.domain.com/rest/api/1.0/projects//permissions/users: context canceled"}, true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { a := &DefaultApiService{ client: tt.fields.client, } - got, err := a.GetUsersWithAnyPermission_23(tt.args.localVarOptionals) + got, err := a.GetUsersWithAnyPermission_23(tt.args.projectKey, tt.args.localVarOptionals) if (err != nil) != tt.wantErr { t.Errorf("DefaultApiService.GetUsersWithAnyPermission_23() error = %v, wantErr %v", err, tt.wantErr) return @@ -4233,6 +4234,8 @@ func TestDefaultApiService_GetUsersWithAnyPermission_24(t *testing.T) { client *APIClient } type args struct { + projectKey string + repositorySlug string localVarOptionals map[string]interface{} } tests := []struct { @@ -4242,14 +4245,14 @@ func TestDefaultApiService_GetUsersWithAnyPermission_24(t *testing.T) { want *APIResponse wantErr bool }{ - {"networkErrorContextExceeded", fields{client: generateConfigFake()}, args{}, &APIResponse{Message: "Get https://stash.domain.com/rest/api/1.0/projects/%7BprojectKey%7D/repos/%7BrepositorySlug%7D/permissions/users: context canceled"}, true}, + {"networkErrorContextExceeded", fields{client: generateConfigFake()}, args{}, &APIResponse{Message: "Get https://stash.domain.com/rest/api/1.0/projects//repos//permissions/users: context canceled"}, true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { a := &DefaultApiService{ client: tt.fields.client, } - got, err := a.GetUsersWithAnyPermission_24(tt.args.localVarOptionals) + got, err := a.GetUsersWithAnyPermission_24(tt.args.projectKey, tt.args.repositorySlug, tt.args.localVarOptionals) if (err != nil) != tt.wantErr { t.Errorf("DefaultApiService.GetUsersWithAnyPermission_24() error = %v, wantErr %v", err, tt.wantErr) return