github.com/akamai/AkamaiOPEN-edgegrid-golang/v8@v8.1.0/pkg/iam/groups_test.go (about)

     1  package iam
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"io/ioutil"
     7  	"net/http"
     8  	"net/http/httptest"
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/require"
    12  	"github.com/tj/assert"
    13  )
    14  
    15  func TestCreateGroup(t *testing.T) {
    16  	tests := map[string]struct {
    17  		params              GroupRequest
    18  		responseStatus      int
    19  		responseBody        string
    20  		expectedPath        string
    21  		expectedRequestBody string
    22  		expectedResponse    *Group
    23  		withError           error
    24  	}{
    25  		"201 OK": {
    26  			params: GroupRequest{
    27  				GroupID:   12345,
    28  				GroupName: "Test Group",
    29  			},
    30  			responseStatus: http.StatusCreated,
    31  			responseBody: `
    32  {
    33  	"groupId": 98765,
    34  	"groupName": "Test Group",
    35  	"parentGroupId": 12345,
    36  	"createdDate": "2012-04-28T00:00:00.000Z",
    37  	"createdBy": "johndoe",
    38  	"modifiedDate": "2012-04-28T00:00:00.000Z",
    39  	"modifiedBy": "johndoe"
    40  }`,
    41  			expectedPath:        "/identity-management/v2/user-admin/groups/12345",
    42  			expectedRequestBody: `{"groupName":"Test Group"}`,
    43  			expectedResponse: &Group{
    44  				GroupID:       98765,
    45  				GroupName:     "Test Group",
    46  				ParentGroupID: 12345,
    47  				CreatedDate:   "2012-04-28T00:00:00.000Z",
    48  				CreatedBy:     "johndoe",
    49  				ModifiedDate:  "2012-04-28T00:00:00.000Z",
    50  				ModifiedBy:    "johndoe",
    51  			},
    52  		},
    53  		"500 internal server error": {
    54  			params: GroupRequest{
    55  				GroupID:   12345,
    56  				GroupName: "Test Group",
    57  			},
    58  			responseStatus: http.StatusInternalServerError,
    59  			responseBody: `
    60  {
    61  	"type": "internal_error",
    62      "title": "Internal Server Error",
    63      "detail": "Error making request",
    64      "status": 500
    65  }`,
    66  			expectedPath: "/identity-management/v2/user-admin/groups/12345",
    67  			withError: &Error{
    68  				Type:       "internal_error",
    69  				Title:      "Internal Server Error",
    70  				Detail:     "Error making request",
    71  				StatusCode: http.StatusInternalServerError,
    72  			},
    73  		},
    74  		"missing group id": {
    75  			params: GroupRequest{
    76  				GroupName: "Test Group",
    77  			},
    78  			withError: ErrStructValidation,
    79  		},
    80  		"missing group name": {
    81  			params: GroupRequest{
    82  				GroupID: 12345,
    83  			},
    84  			withError: ErrStructValidation,
    85  		},
    86  	}
    87  
    88  	for name, test := range tests {
    89  		t.Run(name, func(t *testing.T) {
    90  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    91  				assert.Equal(t, test.expectedPath, r.URL.String())
    92  				assert.Equal(t, http.MethodPost, r.Method)
    93  				w.WriteHeader(test.responseStatus)
    94  				_, err := w.Write([]byte(test.responseBody))
    95  				assert.NoError(t, err)
    96  
    97  				if len(test.expectedRequestBody) > 0 {
    98  					body, err := ioutil.ReadAll(r.Body)
    99  					require.NoError(t, err)
   100  					assert.Equal(t, test.expectedRequestBody, string(body))
   101  				}
   102  			}))
   103  			client := mockAPIClient(t, mockServer)
   104  			result, err := client.CreateGroup(context.Background(), test.params)
   105  			if test.withError != nil {
   106  				assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
   107  				return
   108  			}
   109  			require.NoError(t, err)
   110  			assert.Equal(t, test.expectedResponse, result)
   111  		})
   112  	}
   113  }
   114  
   115  func TestMoveGroup(t *testing.T) {
   116  	tests := map[string]struct {
   117  		params              MoveGroupRequest
   118  		expectedRequestBody string
   119  		responseStatus      int
   120  		withError           error
   121  		responseBody        string
   122  	}{
   123  		"204 ok": {
   124  			responseStatus:      http.StatusNoContent,
   125  			expectedRequestBody: `{"sourceGroupId":1,"destinationGroupId":1}`,
   126  			params:              MoveGroupRequest{DestinationGroupID: 1, SourceGroupID: 1},
   127  		},
   128  		"500 internal server error": {
   129  			responseStatus:      http.StatusInternalServerError,
   130  			params:              MoveGroupRequest{DestinationGroupID: 1, SourceGroupID: 1},
   131  			expectedRequestBody: `{"sourceGroupId":1,"destinationGroupId":1}`,
   132  			withError:           ErrMoveGroup,
   133  		},
   134  		"validation error": {
   135  			params:    MoveGroupRequest{},
   136  			withError: ErrStructValidation,
   137  		},
   138  	}
   139  
   140  	for name, test := range tests {
   141  		t.Run(name, func(t *testing.T) {
   142  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   143  				assert.Equal(t, "/identity-management/v2/user-admin/groups/move", r.URL.String())
   144  				assert.Equal(t, http.MethodPost, r.Method)
   145  				body, err := ioutil.ReadAll(r.Body)
   146  				require.NoError(t, err)
   147  				assert.Equal(t, test.expectedRequestBody, string(body))
   148  				w.WriteHeader(test.responseStatus)
   149  				_, err = w.Write([]byte(test.responseBody))
   150  				assert.NoError(t, err)
   151  			}))
   152  			client := mockAPIClient(t, mockServer)
   153  			err := client.MoveGroup(context.Background(), test.params)
   154  			if test.withError != nil {
   155  				assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
   156  				return
   157  			}
   158  			require.NoError(t, err)
   159  		})
   160  	}
   161  }
   162  
   163  func TestGetGroup(t *testing.T) {
   164  	tests := map[string]struct {
   165  		params           GetGroupRequest
   166  		responseStatus   int
   167  		responseBody     string
   168  		expectedPath     string
   169  		expectedResponse *Group
   170  		withError        error
   171  	}{
   172  		"200 OK with actions": {
   173  			params: GetGroupRequest{
   174  				GroupID: 12345,
   175  				Actions: true,
   176  			},
   177  			responseStatus: http.StatusOK,
   178  			responseBody: `
   179  {
   180  	"groupId": 12345,
   181  	"groupName": "Top Level group",
   182  	"createdDate": "2012-04-28T00:00:00.000Z",
   183  	"createdBy": "johndoe",
   184  	"modifiedDate": "2012-04-28T00:00:00.000Z",
   185  	"modifiedBy": "johndoe",
   186  	"actions": {
   187  		"edit": true,
   188  		"delete": true
   189  	}
   190  }`,
   191  			expectedPath: "/identity-management/v2/user-admin/groups/12345?actions=true",
   192  			expectedResponse: &Group{
   193  				GroupID:      12345,
   194  				GroupName:    "Top Level group",
   195  				CreatedDate:  "2012-04-28T00:00:00.000Z",
   196  				CreatedBy:    "johndoe",
   197  				ModifiedDate: "2012-04-28T00:00:00.000Z",
   198  				ModifiedBy:   "johndoe",
   199  				Actions: &GroupActions{
   200  					Edit:   true,
   201  					Delete: true,
   202  				},
   203  			},
   204  		},
   205  		"200 OK with no actions": {
   206  			params: GetGroupRequest{
   207  				GroupID: 12345,
   208  			},
   209  			responseStatus: http.StatusOK,
   210  			responseBody: `
   211  {
   212  	"groupId": 12345,
   213  	"groupName": "Top Level group",
   214  	"createdDate": "2012-04-28T00:00:00.000Z",
   215  	"createdBy": "johndoe",
   216  	"modifiedDate": "2012-04-28T00:00:00.000Z",
   217  	"modifiedBy": "johndoe"
   218  }`,
   219  			expectedPath: "/identity-management/v2/user-admin/groups/12345?actions=false",
   220  			expectedResponse: &Group{
   221  				GroupID:      12345,
   222  				GroupName:    "Top Level group",
   223  				CreatedDate:  "2012-04-28T00:00:00.000Z",
   224  				CreatedBy:    "johndoe",
   225  				ModifiedDate: "2012-04-28T00:00:00.000Z",
   226  				ModifiedBy:   "johndoe",
   227  			},
   228  		},
   229  		"500 internal server error": {
   230  			params: GetGroupRequest{
   231  				GroupID: 12345,
   232  			},
   233  			responseStatus: http.StatusInternalServerError,
   234  			responseBody: `
   235  {
   236  	"type": "internal_error",
   237      "title": "Internal Server Error",
   238      "detail": "Error making request",
   239      "status": 500
   240  }`,
   241  			expectedPath: "/identity-management/v2/user-admin/groups/12345?actions=false",
   242  			withError: &Error{
   243  				Type:       "internal_error",
   244  				Title:      "Internal Server Error",
   245  				Detail:     "Error making request",
   246  				StatusCode: http.StatusInternalServerError,
   247  			},
   248  		},
   249  		"missing group id": {
   250  			params: GetGroupRequest{
   251  				Actions: true,
   252  			},
   253  			withError: ErrStructValidation,
   254  		},
   255  	}
   256  
   257  	for name, test := range tests {
   258  		t.Run(name, func(t *testing.T) {
   259  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   260  				assert.Equal(t, test.expectedPath, r.URL.String())
   261  				assert.Equal(t, http.MethodGet, r.Method)
   262  				w.WriteHeader(test.responseStatus)
   263  				_, err := w.Write([]byte(test.responseBody))
   264  				assert.NoError(t, err)
   265  			}))
   266  			client := mockAPIClient(t, mockServer)
   267  			result, err := client.GetGroup(context.Background(), test.params)
   268  			if test.withError != nil {
   269  				assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
   270  				return
   271  			}
   272  			require.NoError(t, err)
   273  			assert.Equal(t, test.expectedResponse, result)
   274  		})
   275  	}
   276  }
   277  
   278  func TestListAffectedUsers(t *testing.T) {
   279  	tests := map[string]struct {
   280  		params           ListAffectedUsersRequest
   281  		responseStatus   int
   282  		responseBody     string
   283  		expectedPath     string
   284  		expectedResponse []GroupUser
   285  		withError        error
   286  	}{
   287  		"200 OK": {
   288  			params: ListAffectedUsersRequest{
   289  				DestinationGroupID: 12345,
   290  				SourceGroupID:      12344,
   291  				UserType:           GainAccessUsers,
   292  			},
   293  			responseStatus: http.StatusOK,
   294  			responseBody: `
   295  [
   296      {
   297          "uiIdentityId": "test-identity",
   298          "firstName": "jhon",
   299          "lastName": "doe",
   300          "accountId": "test-account",
   301          "email": "john.doe@mycompany.com",
   302          "uiUserName": "john.doe@mycompany.com",
   303          "lastLoginDate": "2022-02-22T17:06:50.000Z"
   304      }
   305  ]`,
   306  			expectedPath: "/identity-management/v2/user-admin/groups/move/12344/12345/affected-users?userType=gainAccess",
   307  			expectedResponse: []GroupUser{
   308  				{
   309  					IdentityID:    "test-identity",
   310  					FirstName:     "jhon",
   311  					LastName:      "doe",
   312  					AccountID:     "test-account",
   313  					Email:         "john.doe@mycompany.com",
   314  					UserName:      "john.doe@mycompany.com",
   315  					LastLoginDate: "2022-02-22T17:06:50.000Z",
   316  				},
   317  			},
   318  		},
   319  		"500 internal server error": {
   320  			params: ListAffectedUsersRequest{
   321  				DestinationGroupID: 12345,
   322  				SourceGroupID:      12344,
   323  				UserType:           GainAccessUsers,
   324  			},
   325  			responseStatus: http.StatusInternalServerError,
   326  			responseBody: `
   327  {
   328  	"type": "internal_error",
   329      "title": "Internal Server Error",
   330      "detail": "Error making request",
   331      "status": 500
   332  }`,
   333  			expectedPath: "/identity-management/v2/user-admin/groups/move/12344/12345/affected-users?userType=gainAccess",
   334  			withError: &Error{
   335  				Type:       "internal_error",
   336  				Title:      "Internal Server Error",
   337  				Detail:     "Error making request",
   338  				StatusCode: http.StatusInternalServerError,
   339  			},
   340  		},
   341  		"missing destination group id": {
   342  			params: ListAffectedUsersRequest{
   343  				SourceGroupID: 12344,
   344  				UserType:      GainAccessUsers,
   345  			},
   346  			withError: ErrStructValidation,
   347  		},
   348  		"missing source group id": {
   349  			params: ListAffectedUsersRequest{
   350  				DestinationGroupID: 12345,
   351  				UserType:           GainAccessUsers,
   352  			},
   353  			withError: ErrStructValidation,
   354  		},
   355  		"invalid user type": {
   356  			params: ListAffectedUsersRequest{
   357  				DestinationGroupID: 12345,
   358  				SourceGroupID:      12344,
   359  				UserType:           "different",
   360  			},
   361  			withError: ErrStructValidation,
   362  		},
   363  	}
   364  
   365  	for name, test := range tests {
   366  		t.Run(name, func(t *testing.T) {
   367  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   368  				assert.Equal(t, test.expectedPath, r.URL.String())
   369  				assert.Equal(t, http.MethodGet, r.Method)
   370  				w.WriteHeader(test.responseStatus)
   371  				_, err := w.Write([]byte(test.responseBody))
   372  				assert.NoError(t, err)
   373  			}))
   374  			client := mockAPIClient(t, mockServer)
   375  			result, err := client.ListAffectedUsers(context.Background(), test.params)
   376  			if test.withError != nil {
   377  				assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
   378  				return
   379  			}
   380  			require.NoError(t, err)
   381  			assert.Equal(t, test.expectedResponse, result)
   382  		})
   383  	}
   384  }
   385  
   386  func TestListGroups(t *testing.T) {
   387  	tests := map[string]struct {
   388  		params           ListGroupsRequest
   389  		responseStatus   int
   390  		responseBody     string
   391  		expectedPath     string
   392  		expectedResponse []Group
   393  		withError        func(*testing.T, error)
   394  	}{
   395  		"200 OK with actions": {
   396  			params: ListGroupsRequest{
   397  				Actions: true,
   398  			},
   399  			responseStatus: http.StatusOK,
   400  			responseBody: `
   401  			[
   402  				{
   403  					"groupId": 12345,
   404  					"groupName": "Top Level group",
   405  					"createdDate": "2012-04-28T00:00:00.000Z",
   406  					"createdBy": "johndoe",
   407  					"modifiedDate": "2012-04-28T00:00:00.000Z",
   408  					"modifiedBy": "johndoe",
   409  					"actions": {
   410  						"edit": true,
   411  						"delete": true
   412  					}
   413  				}
   414  			]`,
   415  			expectedPath: "/identity-management/v2/user-admin/groups?actions=true",
   416  			expectedResponse: []Group{
   417  				{
   418  					GroupID:      12345,
   419  					GroupName:    "Top Level group",
   420  					CreatedDate:  "2012-04-28T00:00:00.000Z",
   421  					CreatedBy:    "johndoe",
   422  					ModifiedDate: "2012-04-28T00:00:00.000Z",
   423  					ModifiedBy:   "johndoe",
   424  					Actions: &GroupActions{
   425  						Edit:   true,
   426  						Delete: true,
   427  					},
   428  				},
   429  			},
   430  		},
   431  		"200 OK with no actions": {
   432  			params: ListGroupsRequest{
   433  				Actions: false,
   434  			},
   435  			responseStatus: http.StatusOK,
   436  			responseBody: `
   437  			[
   438  				{
   439  					"groupId": 12345,
   440  					"groupName": "Top Level group",
   441  					"createdDate": "2012-04-28T00:00:00.000Z",
   442  					"createdBy": "johndoe",
   443  					"modifiedDate": "2012-04-28T00:00:00.000Z",
   444  					"modifiedBy": "johndoe"
   445  				}
   446  			]`,
   447  			expectedPath: "/identity-management/v2/user-admin/groups?actions=false",
   448  			expectedResponse: []Group{
   449  				{
   450  					GroupID:      12345,
   451  					GroupName:    "Top Level group",
   452  					CreatedDate:  "2012-04-28T00:00:00.000Z",
   453  					CreatedBy:    "johndoe",
   454  					ModifiedDate: "2012-04-28T00:00:00.000Z",
   455  					ModifiedBy:   "johndoe",
   456  				},
   457  			},
   458  		},
   459  		"500 internal server error": {
   460  			params: ListGroupsRequest{
   461  				Actions: true,
   462  			},
   463  			responseStatus: http.StatusInternalServerError,
   464  			responseBody: `
   465  {
   466  	"type": "internal_error",
   467      "title": "Internal Server Error",
   468      "detail": "Error making request",
   469      "status": 500
   470  }`,
   471  			expectedPath: "/identity-management/v2/user-admin/groups?actions=true",
   472  			withError: func(t *testing.T, err error) {
   473  				want := &Error{
   474  					Type:       "internal_error",
   475  					Title:      "Internal Server Error",
   476  					Detail:     "Error making request",
   477  					StatusCode: http.StatusInternalServerError,
   478  				}
   479  				assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err)
   480  			},
   481  		},
   482  	}
   483  
   484  	for name, test := range tests {
   485  		t.Run(name, func(t *testing.T) {
   486  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   487  				assert.Equal(t, test.expectedPath, r.URL.String())
   488  				assert.Equal(t, http.MethodGet, r.Method)
   489  				w.WriteHeader(test.responseStatus)
   490  				_, err := w.Write([]byte(test.responseBody))
   491  				assert.NoError(t, err)
   492  			}))
   493  			client := mockAPIClient(t, mockServer)
   494  			result, err := client.ListGroups(context.Background(), test.params)
   495  			if test.withError != nil {
   496  				test.withError(t, err)
   497  				return
   498  			}
   499  			require.NoError(t, err)
   500  			assert.Equal(t, test.expectedResponse, result)
   501  		})
   502  	}
   503  }
   504  
   505  func TestRemoveGroup(t *testing.T) {
   506  	tests := map[string]struct {
   507  		params         RemoveGroupRequest
   508  		responseStatus int
   509  		responseBody   string
   510  		expectedPath   string
   511  		withError      error
   512  	}{
   513  		"204 deleted": {
   514  			params: RemoveGroupRequest{
   515  				GroupID: 12345,
   516  			},
   517  			responseStatus: http.StatusNoContent,
   518  			expectedPath:   "/identity-management/v2/user-admin/groups/12345",
   519  		},
   520  		"500 internal server error": {
   521  			params: RemoveGroupRequest{
   522  				GroupID: 12345,
   523  			},
   524  			responseStatus: http.StatusInternalServerError,
   525  			responseBody: `
   526  {
   527  	"type": "internal_error",
   528      "title": "Internal Server Error",
   529      "detail": "Error making request",
   530      "status": 500
   531  }`,
   532  			expectedPath: "/identity-management/v2/user-admin/groups/12345",
   533  			withError: &Error{
   534  				Type:       "internal_error",
   535  				Title:      "Internal Server Error",
   536  				Detail:     "Error making request",
   537  				StatusCode: http.StatusInternalServerError,
   538  			},
   539  		},
   540  		"403 not authorised": {
   541  			params: RemoveGroupRequest{
   542  				GroupID: 12345,
   543  			},
   544  			responseStatus: http.StatusForbidden,
   545  			responseBody: `
   546  {
   547      "instance": "",
   548      "httpStatus": 403,
   549      "detail": "Not Authorized to perform this action",
   550      "title": "Forbidden",
   551      "type": "/useradmin-api/error-types/1001"
   552  }`,
   553  			expectedPath: "/identity-management/v2/user-admin/groups/12345",
   554  			withError: &Error{
   555  				Instance:   "",
   556  				StatusCode: http.StatusForbidden,
   557  				Detail:     "Not Authorized to perform this action",
   558  				Title:      "Forbidden",
   559  				Type:       "/useradmin-api/error-types/1001",
   560  				HTTPStatus: http.StatusForbidden,
   561  			},
   562  		},
   563  		"missing group id": {
   564  			params:    RemoveGroupRequest{},
   565  			withError: ErrStructValidation,
   566  		},
   567  	}
   568  
   569  	for name, test := range tests {
   570  		t.Run(name, func(t *testing.T) {
   571  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   572  				assert.Equal(t, test.expectedPath, r.URL.String())
   573  				assert.Equal(t, http.MethodDelete, r.Method)
   574  				w.WriteHeader(test.responseStatus)
   575  				_, err := w.Write([]byte(test.responseBody))
   576  				assert.NoError(t, err)
   577  			}))
   578  			client := mockAPIClient(t, mockServer)
   579  			err := client.RemoveGroup(context.Background(), test.params)
   580  			if test.withError != nil {
   581  				assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
   582  				return
   583  			}
   584  			require.NoError(t, err)
   585  		})
   586  	}
   587  }
   588  
   589  func TestUpdateGroupName(t *testing.T) {
   590  	tests := map[string]struct {
   591  		params              GroupRequest
   592  		responseStatus      int
   593  		responseBody        string
   594  		expectedPath        string
   595  		expectedRequestBody string
   596  		expectedResponse    *Group
   597  		withError           error
   598  	}{
   599  		"200 updated": {
   600  			params: GroupRequest{
   601  				GroupID:   12345,
   602  				GroupName: "New Group Name",
   603  			},
   604  			responseStatus: http.StatusOK,
   605  			responseBody: `
   606  {
   607  	"groupId": 12345,
   608  	"groupName": "New Group Name",
   609  	"parentGroupId": 12344,
   610  	"createdDate": "2012-04-28T00:00:00.000Z",
   611  	"createdBy": "johndoe",
   612  	"modifiedDate": "2012-04-28T00:00:00.000Z",
   613  	"modifiedBy": "johndoe"
   614  }`,
   615  			expectedPath:        "/identity-management/v2/user-admin/groups/12345",
   616  			expectedRequestBody: `{"groupName":"New Group Name"}`,
   617  			expectedResponse: &Group{
   618  				GroupID:       12345,
   619  				GroupName:     "New Group Name",
   620  				ParentGroupID: 12344,
   621  				CreatedDate:   "2012-04-28T00:00:00.000Z",
   622  				CreatedBy:     "johndoe",
   623  				ModifiedDate:  "2012-04-28T00:00:00.000Z",
   624  				ModifiedBy:    "johndoe",
   625  			},
   626  		},
   627  		"500 internal server error": {
   628  			params: GroupRequest{
   629  				GroupID:   12345,
   630  				GroupName: "New Group Name",
   631  			},
   632  			responseStatus: http.StatusInternalServerError,
   633  			responseBody: `
   634  {
   635  	"type": "internal_error",
   636      "title": "Internal Server Error",
   637      "detail": "Error making request",
   638      "status": 500
   639  }`,
   640  			expectedPath: "/identity-management/v2/user-admin/groups/12345",
   641  			withError: &Error{
   642  				Type:       "internal_error",
   643  				Title:      "Internal Server Error",
   644  				Detail:     "Error making request",
   645  				StatusCode: http.StatusInternalServerError,
   646  			},
   647  		},
   648  		"missing group id": {
   649  			params: GroupRequest{
   650  				GroupName: "New Group Name",
   651  			},
   652  			withError: ErrStructValidation,
   653  		},
   654  		"missing group name": {
   655  			params: GroupRequest{
   656  				GroupID: 12345,
   657  			},
   658  			withError: ErrStructValidation,
   659  		},
   660  	}
   661  
   662  	for name, test := range tests {
   663  		t.Run(name, func(t *testing.T) {
   664  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   665  				assert.Equal(t, test.expectedPath, r.URL.String())
   666  				assert.Equal(t, http.MethodPut, r.Method)
   667  				w.WriteHeader(test.responseStatus)
   668  				_, err := w.Write([]byte(test.responseBody))
   669  				assert.NoError(t, err)
   670  
   671  				if len(test.expectedRequestBody) > 0 {
   672  					body, err := ioutil.ReadAll(r.Body)
   673  					require.NoError(t, err)
   674  					assert.Equal(t, test.expectedRequestBody, string(body))
   675  				}
   676  			}))
   677  			client := mockAPIClient(t, mockServer)
   678  			result, err := client.UpdateGroupName(context.Background(), test.params)
   679  			if test.withError != nil {
   680  				assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
   681  				return
   682  			}
   683  			require.NoError(t, err)
   684  			assert.Equal(t, test.expectedResponse, result)
   685  		})
   686  	}
   687  }