github.com/google/go-github/v74@v74.0.0/github/scim_test.go (about)

     1  // Copyright 2021 The go-github AUTHORS. All rights reserved.
     2  //
     3  // Use of this source code is governed by a BSD-style
     4  // license that can be found in the LICENSE file.
     5  
     6  package github
     7  
     8  import (
     9  	"context"
    10  	"fmt"
    11  	"net/http"
    12  	"testing"
    13  	"time"
    14  
    15  	"github.com/google/go-cmp/cmp"
    16  )
    17  
    18  func TestSCIMService_ListSCIMProvisionedIdentities(t *testing.T) {
    19  	t.Parallel()
    20  	client, mux, _ := setup(t)
    21  
    22  	mux.HandleFunc("/scim/v2/organizations/o/Users", func(w http.ResponseWriter, r *http.Request) {
    23  		testMethod(t, r, "GET")
    24  		w.WriteHeader(http.StatusOK)
    25  		_, _ = w.Write([]byte(`{
    26  			"schemas": [
    27  			  "urn:ietf:params:scim:api:messages:2.0:ListResponse"
    28  			],
    29  			"totalResults": 1,
    30  			"itemsPerPage": 1,
    31  			"startIndex": 1,
    32  			"Resources": [
    33  			  {
    34  				"schemas": [
    35  				  "urn:ietf:params:scim:schemas:core:2.0:User"
    36  				],
    37  				"id": "5fc0c238-1112-11e8-8e45-920c87bdbd75",
    38  				"externalId": "00u1dhhb1fkIGP7RL1d8",
    39  				"userName": "octocat@github.com",
    40  				"displayName": "Mona Octocat",
    41  				"name": {
    42  				  "givenName": "Mona",
    43  				  "familyName": "Octocat",
    44  				  "formatted": "Mona Octocat"
    45  				},
    46  				"emails": [
    47  				  {
    48  					"value": "octocat@github.com",
    49  					"primary": true
    50  				  }
    51  				],
    52  				"active": true,
    53  				"meta": {
    54  				  "resourceType": "User",
    55  				  "created": "2018-02-13T15:05:24.000-00:00",
    56  				  "lastModified": "2018-02-13T15:05:24.000-00:00",
    57  				  "location": "https://api.github.com/scim/v2/organizations/octo-org/Users/5fc0c238-1112-11e8-8e45-920c87bdbd75"
    58  				}
    59  			  }
    60  			]
    61  		  }`))
    62  	})
    63  
    64  	ctx := context.Background()
    65  	opts := &ListSCIMProvisionedIdentitiesOptions{}
    66  	identities, _, err := client.SCIM.ListSCIMProvisionedIdentities(ctx, "o", opts)
    67  	if err != nil {
    68  		t.Errorf("SCIM.ListSCIMProvisionedIdentities returned error: %v", err)
    69  	}
    70  
    71  	date := Timestamp{time.Date(2018, time.February, 13, 15, 5, 24, 0, time.UTC)}
    72  	want := SCIMProvisionedIdentities{
    73  		Schemas:      []string{"urn:ietf:params:scim:api:messages:2.0:ListResponse"},
    74  		TotalResults: Ptr(1),
    75  		ItemsPerPage: Ptr(1),
    76  		StartIndex:   Ptr(1),
    77  		Resources: []*SCIMUserAttributes{
    78  			{
    79  				ID: Ptr("5fc0c238-1112-11e8-8e45-920c87bdbd75"),
    80  				Meta: &SCIMMeta{
    81  					ResourceType: Ptr("User"),
    82  					Created:      &date,
    83  					LastModified: &date,
    84  					Location:     Ptr("https://api.github.com/scim/v2/organizations/octo-org/Users/5fc0c238-1112-11e8-8e45-920c87bdbd75"),
    85  				},
    86  				UserName: "octocat@github.com",
    87  				Name: SCIMUserName{
    88  					GivenName:  "Mona",
    89  					FamilyName: "Octocat",
    90  					Formatted:  Ptr("Mona Octocat"),
    91  				},
    92  				DisplayName: Ptr("Mona Octocat"),
    93  				Emails: []*SCIMUserEmail{
    94  					{
    95  						Value:   "octocat@github.com",
    96  						Primary: Ptr(true),
    97  					},
    98  				},
    99  				Schemas:    []string{"urn:ietf:params:scim:schemas:core:2.0:User"},
   100  				ExternalID: Ptr("00u1dhhb1fkIGP7RL1d8"),
   101  				Groups:     nil,
   102  				Active:     Ptr(true),
   103  			},
   104  		},
   105  	}
   106  
   107  	if !cmp.Equal(identities, &want) {
   108  		diff := cmp.Diff(identities, want)
   109  		t.Errorf("SCIM.ListSCIMProvisionedIdentities returned %+v, want %+v: diff %+v", identities, want, diff)
   110  	}
   111  
   112  	const methodName = "ListSCIMProvisionedIdentities"
   113  	testBadOptions(t, methodName, func() (err error) {
   114  		_, _, err = client.SCIM.ListSCIMProvisionedIdentities(ctx, "\n", opts)
   115  		return err
   116  	})
   117  
   118  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   119  		_, r, err := client.SCIM.ListSCIMProvisionedIdentities(ctx, "o", opts)
   120  		return r, err
   121  	})
   122  }
   123  
   124  func TestSCIMService_ListSCIMProvisionedGroups(t *testing.T) {
   125  	t.Parallel()
   126  	client, mux, _ := setup(t)
   127  
   128  	mux.HandleFunc("/scim/v2/enterprises/o/Groups", func(w http.ResponseWriter, r *http.Request) {
   129  		testMethod(t, r, "GET")
   130  		testFormValues(t, r, values{
   131  			"startIndex":         "1",
   132  			"excludedAttributes": "members,meta",
   133  			"count":              "3",
   134  			"filter":             `externalId eq "00u1dhhb1fkIGP7RL1d8"`,
   135  		})
   136  		w.WriteHeader(http.StatusOK)
   137  		_, _ = w.Write([]byte(`{
   138  			"schemas": [
   139  			  "urn:ietf:params:scim:api:messages:2.0:ListResponse"
   140  			],
   141  			"totalResults": 1,
   142  			"itemsPerPage": 1,
   143  			"startIndex": 1,
   144  			"Resources": [
   145  			  {
   146  				"schemas": [
   147  				  "urn:ietf:params:scim:schemas:core:2.0:Group"
   148  				],
   149  				"id": "123e4567-e89b-12d3-a456-426614174000",
   150  				"externalId": "00u1dhhb1fkIGP7RL1d8",
   151  				"displayName": "Mona Octocat",
   152  				"meta": {
   153  				  "resourceType": "Group",
   154  				  "created": "2018-02-13T15:05:24.000-00:00",
   155  				  "lastModified": "2018-02-13T15:05:24.000-00:00",
   156  				  "location": "https://api.github.com/scim/v2/enterprises/octo/Groups/123e4567-e89b-12d3-a456-426614174000"
   157  				},
   158  				"members": [
   159  				  {
   160  					"value": "5fc0c238-1112-11e8-8e45-920c87bdbd75",
   161  					"$ref": "https://api.github.com/scim/v2/enterprises/octo/Users/5fc0c238-1112-11e8-8e45-920c87bdbd75",
   162  					"display": "Mona Octocat"
   163  				  }
   164  				]
   165  			  }
   166  			]
   167  		  }`))
   168  	})
   169  
   170  	ctx := context.Background()
   171  	opts := &ListSCIMProvisionedGroupsForEnterpriseOptions{
   172  		StartIndex:         Ptr(1),
   173  		ExcludedAttributes: Ptr("members,meta"),
   174  		Count:              Ptr(3),
   175  		Filter:             Ptr(`externalId eq "00u1dhhb1fkIGP7RL1d8"`),
   176  	}
   177  	groups, _, err := client.SCIM.ListSCIMProvisionedGroupsForEnterprise(ctx, "o", opts)
   178  	if err != nil {
   179  		t.Errorf("SCIM.ListSCIMProvisionedIdentities returned error: %v", err)
   180  	}
   181  
   182  	date := Timestamp{time.Date(2018, time.February, 13, 15, 5, 24, 0, time.UTC)}
   183  	want := SCIMProvisionedGroups{
   184  		Schemas:      []string{"urn:ietf:params:scim:api:messages:2.0:ListResponse"},
   185  		TotalResults: Ptr(1),
   186  		ItemsPerPage: Ptr(1),
   187  		StartIndex:   Ptr(1),
   188  		Resources: []*SCIMGroupAttributes{
   189  			{
   190  				ID: Ptr("123e4567-e89b-12d3-a456-426614174000"),
   191  				Meta: &SCIMMeta{
   192  					ResourceType: Ptr("Group"),
   193  					Created:      &date,
   194  					LastModified: &date,
   195  					Location:     Ptr("https://api.github.com/scim/v2/enterprises/octo/Groups/123e4567-e89b-12d3-a456-426614174000"),
   196  				},
   197  
   198  				DisplayName: Ptr("Mona Octocat"),
   199  				Schemas:     []string{"urn:ietf:params:scim:schemas:core:2.0:Group"},
   200  				ExternalID:  Ptr("00u1dhhb1fkIGP7RL1d8"),
   201  				Members: []*SCIMDisplayReference{
   202  					{
   203  						Value:   "5fc0c238-1112-11e8-8e45-920c87bdbd75",
   204  						Ref:     "https://api.github.com/scim/v2/enterprises/octo/Users/5fc0c238-1112-11e8-8e45-920c87bdbd75",
   205  						Display: Ptr("Mona Octocat"),
   206  					},
   207  				},
   208  			},
   209  		},
   210  	}
   211  
   212  	if !cmp.Equal(groups, &want) {
   213  		diff := cmp.Diff(groups, want)
   214  		t.Errorf("SCIM.ListSCIMProvisionedGroupsForEnterprise returned %+v, want %+v: diff %+v", groups, want, diff)
   215  	}
   216  
   217  	const methodName = "ListSCIMProvisionedGroupsForEnterprise"
   218  	testBadOptions(t, methodName, func() (err error) {
   219  		_, _, err = client.SCIM.ListSCIMProvisionedGroupsForEnterprise(ctx, "\n", opts)
   220  		return err
   221  	})
   222  
   223  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   224  		_, r, err := client.SCIM.ListSCIMProvisionedGroupsForEnterprise(ctx, "o", opts)
   225  		return r, err
   226  	})
   227  }
   228  
   229  func TestSCIMService_ProvisionAndInviteSCIMUser(t *testing.T) {
   230  	t.Parallel()
   231  	client, mux, _ := setup(t)
   232  
   233  	mux.HandleFunc("/scim/v2/organizations/o/Users", func(w http.ResponseWriter, r *http.Request) {
   234  		testMethod(t, r, "POST")
   235  		w.WriteHeader(http.StatusCreated)
   236  		fmt.Fprint(w, `{"id":"1234567890","userName":"userName"}`)
   237  	})
   238  
   239  	ctx := context.Background()
   240  	opts := &SCIMUserAttributes{
   241  		UserName: "userName",
   242  		Name: SCIMUserName{
   243  			GivenName:  "givenName",
   244  			FamilyName: "familyName",
   245  		},
   246  		Emails: []*SCIMUserEmail{
   247  			{
   248  				Value: "octocat@github.com",
   249  			},
   250  		},
   251  	}
   252  	user, _, err := client.SCIM.ProvisionAndInviteSCIMUser(ctx, "o", opts)
   253  	if err != nil {
   254  		t.Errorf("SCIM.ProvisionAndInviteSCIMUser returned error: %v", err)
   255  	}
   256  
   257  	want := &SCIMUserAttributes{
   258  		ID:       Ptr("1234567890"),
   259  		UserName: "userName",
   260  	}
   261  	if !cmp.Equal(user, want) {
   262  		t.Errorf("SCIM.ProvisionAndInviteSCIMUser returned %+v, want %+v", user, want)
   263  	}
   264  
   265  	const methodName = "ProvisionAndInviteSCIMUser"
   266  	testBadOptions(t, methodName, func() (err error) {
   267  		_, _, err = client.SCIM.ProvisionAndInviteSCIMUser(ctx, "\n", opts)
   268  		return err
   269  	})
   270  
   271  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   272  		got, resp, err := client.SCIM.ProvisionAndInviteSCIMUser(ctx, "o", opts)
   273  		if got != nil {
   274  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   275  		}
   276  		return resp, err
   277  	})
   278  }
   279  
   280  func TestSCIMService_GetSCIMProvisioningInfoForUser(t *testing.T) {
   281  	t.Parallel()
   282  	client, mux, _ := setup(t)
   283  
   284  	mux.HandleFunc("/scim/v2/organizations/o/Users/123", func(w http.ResponseWriter, r *http.Request) {
   285  		testMethod(t, r, "GET")
   286  		w.WriteHeader(http.StatusOK)
   287  		_, _ = w.Write([]byte(`{
   288  			"schemas": [
   289  			  "urn:ietf:params:scim:schemas:core:2.0:User"
   290  			],
   291  			"id": "edefdfedf-050c-11e7-8d32",
   292  			"externalId": "a7d0f98382",
   293  			"userName": "mona.octocat@okta.example.com",
   294  			"displayName": "Mona Octocat",
   295  			"name": {
   296  			  "givenName": "Mona",
   297  			  "familyName": "Octocat",
   298  			  "formatted": "Mona Octocat"
   299  			},
   300  			"emails": [
   301  			  {
   302  				"value": "mona.octocat@okta.example.com",
   303  				"primary": true
   304  			  },
   305  			  {
   306  				"value": "mona@octocat.github.com"
   307  			  }
   308  			],
   309  			"active": true,
   310  			"meta": {
   311  			  "resourceType": "User",
   312  			  "created": "2017-03-09T16:11:13-00:00",
   313  			  "lastModified": "2017-03-09T16:11:13-00:00",
   314  			  "location": "https://api.github.com/scim/v2/organizations/octo-org/Users/edefdfedf-050c-11e7-8d32"
   315  			}
   316  		  }`))
   317  	})
   318  
   319  	ctx := context.Background()
   320  	user, _, err := client.SCIM.GetSCIMProvisioningInfoForUser(ctx, "o", "123")
   321  	if err != nil {
   322  		t.Errorf("SCIM.GetSCIMProvisioningInfoForUser returned error: %v", err)
   323  	}
   324  
   325  	date := Timestamp{time.Date(2017, time.March, 9, 16, 11, 13, 0, time.UTC)}
   326  	want := SCIMUserAttributes{
   327  		ID: Ptr("edefdfedf-050c-11e7-8d32"),
   328  		Meta: &SCIMMeta{
   329  			ResourceType: Ptr("User"),
   330  			Created:      &date,
   331  			LastModified: &date,
   332  			Location:     Ptr("https://api.github.com/scim/v2/organizations/octo-org/Users/edefdfedf-050c-11e7-8d32"),
   333  		},
   334  		UserName: "mona.octocat@okta.example.com",
   335  		Name: SCIMUserName{
   336  			GivenName:  "Mona",
   337  			FamilyName: "Octocat",
   338  			Formatted:  Ptr("Mona Octocat"),
   339  		},
   340  		DisplayName: Ptr("Mona Octocat"),
   341  		Emails: []*SCIMUserEmail{
   342  			{
   343  				Value:   "mona.octocat@okta.example.com",
   344  				Primary: Ptr(true),
   345  			},
   346  			{
   347  				Value: "mona@octocat.github.com",
   348  			},
   349  		},
   350  		Schemas:    []string{"urn:ietf:params:scim:schemas:core:2.0:User"},
   351  		ExternalID: Ptr("a7d0f98382"),
   352  		Groups:     nil,
   353  		Active:     Ptr(true),
   354  	}
   355  
   356  	if !cmp.Equal(user, &want) {
   357  		diff := cmp.Diff(user, want)
   358  		t.Errorf("SCIM.ListSCIMProvisionedIdentities returned %+v, want %+v: diff %+v", user, want, diff)
   359  	}
   360  
   361  	const methodName = "GetSCIMProvisioningInfoForUser"
   362  	testBadOptions(t, methodName, func() error {
   363  		_, _, err := client.SCIM.GetSCIMProvisioningInfoForUser(ctx, "\n", "123")
   364  		return err
   365  	})
   366  
   367  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   368  		_, r, err := client.SCIM.GetSCIMProvisioningInfoForUser(ctx, "o", "123")
   369  		return r, err
   370  	})
   371  }
   372  
   373  func TestSCIMService_UpdateProvisionedOrgMembership(t *testing.T) {
   374  	t.Parallel()
   375  	client, mux, _ := setup(t)
   376  
   377  	mux.HandleFunc("/scim/v2/organizations/o/Users/123", func(w http.ResponseWriter, r *http.Request) {
   378  		testMethod(t, r, "PUT")
   379  		w.WriteHeader(http.StatusOK)
   380  	})
   381  
   382  	ctx := context.Background()
   383  	opts := &SCIMUserAttributes{
   384  		UserName: "userName",
   385  		Name: SCIMUserName{
   386  			GivenName:  "givenName",
   387  			FamilyName: "familyName",
   388  		},
   389  		Emails: []*SCIMUserEmail{
   390  			{
   391  				Value: "octocat@github.com",
   392  			},
   393  		},
   394  	}
   395  	_, err := client.SCIM.UpdateProvisionedOrgMembership(ctx, "o", "123", opts)
   396  	if err != nil {
   397  		t.Errorf("SCIM.UpdateProvisionedOrgMembership returned error: %v", err)
   398  	}
   399  
   400  	const methodName = "UpdateProvisionedOrgMembership"
   401  	testBadOptions(t, methodName, func() error {
   402  		_, err := client.SCIM.UpdateProvisionedOrgMembership(ctx, "\n", "123", opts)
   403  		return err
   404  	})
   405  
   406  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   407  		return client.SCIM.UpdateProvisionedOrgMembership(ctx, "o", "123", opts)
   408  	})
   409  }
   410  
   411  func TestSCIMService_UpdateAttributeForSCIMUser(t *testing.T) {
   412  	t.Parallel()
   413  	client, mux, _ := setup(t)
   414  
   415  	mux.HandleFunc("/scim/v2/organizations/o/Users/123", func(w http.ResponseWriter, r *http.Request) {
   416  		testMethod(t, r, "PATCH")
   417  		w.WriteHeader(http.StatusNoContent)
   418  	})
   419  
   420  	ctx := context.Background()
   421  	opts := &UpdateAttributeForSCIMUserOptions{}
   422  	_, err := client.SCIM.UpdateAttributeForSCIMUser(ctx, "o", "123", opts)
   423  	if err != nil {
   424  		t.Errorf("SCIM.UpdateAttributeForSCIMUser returned error: %v", err)
   425  	}
   426  
   427  	const methodName = "UpdateAttributeForSCIMUser"
   428  	testBadOptions(t, methodName, func() error {
   429  		_, err := client.SCIM.UpdateAttributeForSCIMUser(ctx, "\n", "123", opts)
   430  		return err
   431  	})
   432  
   433  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   434  		return client.SCIM.UpdateAttributeForSCIMUser(ctx, "o", "123", opts)
   435  	})
   436  }
   437  
   438  func TestSCIMService_DeleteSCIMUserFromOrg(t *testing.T) {
   439  	t.Parallel()
   440  	client, mux, _ := setup(t)
   441  
   442  	mux.HandleFunc("/scim/v2/organizations/o/Users/123", func(w http.ResponseWriter, r *http.Request) {
   443  		testMethod(t, r, "DELETE")
   444  		w.WriteHeader(http.StatusNoContent)
   445  	})
   446  
   447  	ctx := context.Background()
   448  	_, err := client.SCIM.DeleteSCIMUserFromOrg(ctx, "o", "123")
   449  	if err != nil {
   450  		t.Errorf("SCIM.DeleteSCIMUserFromOrg returned error: %v", err)
   451  	}
   452  
   453  	const methodName = "DeleteSCIMUserFromOrg"
   454  	testBadOptions(t, methodName, func() error {
   455  		_, err := client.SCIM.DeleteSCIMUserFromOrg(ctx, "\n", "")
   456  		return err
   457  	})
   458  
   459  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   460  		return client.SCIM.DeleteSCIMUserFromOrg(ctx, "o", "123")
   461  	})
   462  }
   463  
   464  func TestSCIMUserAttributes_Marshal(t *testing.T) {
   465  	t.Parallel()
   466  	testJSONMarshal(t, &SCIMUserAttributes{}, `{
   467  		"userName":"","name":{"givenName":"","familyName":""},"emails":null
   468  	}`)
   469  
   470  	u := &SCIMUserAttributes{
   471  		UserName: "userName1",
   472  		Name: SCIMUserName{
   473  			GivenName:  "Name1",
   474  			FamilyName: "Fname",
   475  			Formatted:  Ptr("formatted name"),
   476  		},
   477  		DisplayName: Ptr("Name"),
   478  		Emails: []*SCIMUserEmail{
   479  			{
   480  				Value:   "value",
   481  				Primary: Ptr(false),
   482  				Type:    Ptr("type"),
   483  			},
   484  		},
   485  		Schemas:    []string{"schema1"},
   486  		ExternalID: Ptr("id"),
   487  		Groups:     []string{"group1"},
   488  		Active:     Ptr(true),
   489  	}
   490  
   491  	want := `{
   492  		"userName": "userName1",
   493  		"name": {
   494  			"givenName": "Name1",
   495  			"familyName": "Fname",
   496  			"formatted": "formatted name"
   497  		},
   498  		"displayName": "Name",
   499  		"emails": [{
   500  			"value": "value",
   501  			"primary": false,
   502  			"type": "type"
   503  		}],
   504  		"schemas": ["schema1"],
   505  		"externalId": "id",
   506  		"groups": ["group1"],
   507  		"active": true
   508  	}`
   509  
   510  	testJSONMarshal(t, u, want)
   511  }
   512  
   513  func TestUpdateAttributeForSCIMUserOperations_Marshal(t *testing.T) {
   514  	t.Parallel()
   515  	testJSONMarshal(t, &UpdateAttributeForSCIMUserOperations{}, `{}`)
   516  
   517  	u := &UpdateAttributeForSCIMUserOperations{
   518  		Op:   "TestOp",
   519  		Path: Ptr("path"),
   520  	}
   521  
   522  	want := `{
   523  		"op": "TestOp",
   524  		"path": "path"
   525  	}`
   526  
   527  	testJSONMarshal(t, u, want)
   528  }
   529  
   530  func TestUpdateAttributeForSCIMUserOptions_Marshal(t *testing.T) {
   531  	t.Parallel()
   532  	testJSONMarshal(t, &UpdateAttributeForSCIMUserOptions{}, `{}`)
   533  
   534  	u := &UpdateAttributeForSCIMUserOptions{
   535  		Schemas: []string{"test", "schema"},
   536  		Operations: UpdateAttributeForSCIMUserOperations{
   537  			Op:   "TestOp",
   538  			Path: Ptr("path"),
   539  		},
   540  	}
   541  
   542  	want := `{
   543  		"schemas": ["test", "schema"],
   544  		"operations": {
   545  			"op": "TestOp",
   546  			"path": "path"
   547  		}
   548  	}`
   549  
   550  	testJSONMarshal(t, u, want)
   551  }
   552  
   553  func TestListSCIMProvisionedIdentitiesOptions_addOptions(t *testing.T) {
   554  	t.Parallel()
   555  	testJSONMarshal(t, &ListSCIMProvisionedIdentitiesOptions{}, `{
   556  		"StartIndex": null,
   557  		"Count": null,
   558  		"Filter": null
   559  	}`)
   560  
   561  	url := "some/path"
   562  
   563  	testAddURLOptions(t, url, &ListSCIMProvisionedIdentitiesOptions{}, url)
   564  
   565  	testAddURLOptions(
   566  		t,
   567  		url,
   568  		&ListSCIMProvisionedIdentitiesOptions{
   569  			StartIndex: Ptr(1),
   570  			Count:      Ptr(10),
   571  		},
   572  		fmt.Sprintf("%s?count=10&startIndex=1", url),
   573  	)
   574  
   575  	testAddURLOptions(
   576  		t,
   577  		url,
   578  		&ListSCIMProvisionedIdentitiesOptions{
   579  			StartIndex: Ptr(1),
   580  			Count:      Ptr(10),
   581  			Filter:     Ptr("test"),
   582  		},
   583  		fmt.Sprintf("%s?count=10&filter=test&startIndex=1", url),
   584  	)
   585  }
   586  
   587  func TestSCIMUserName_Marshal(t *testing.T) {
   588  	t.Parallel()
   589  	testJSONMarshal(t, &SCIMUserName{}, `{
   590  		"givenName":"","familyName":""
   591  	}`)
   592  
   593  	u := &SCIMUserName{
   594  		GivenName:  "Name1",
   595  		FamilyName: "Fname",
   596  		Formatted:  Ptr("formatted name"),
   597  	}
   598  
   599  	want := `{
   600  			"givenName": "Name1",
   601  			"familyName": "Fname",
   602  			"formatted": "formatted name"
   603  	}`
   604  	testJSONMarshal(t, u, want)
   605  }
   606  
   607  func TestSCIMMeta_Marshal(t *testing.T) {
   608  	t.Parallel()
   609  	testJSONMarshal(t, &SCIMMeta{}, `{}`)
   610  
   611  	u := &SCIMMeta{
   612  		ResourceType: Ptr("test"),
   613  		Location:     Ptr("test"),
   614  	}
   615  
   616  	want := `{
   617  		"resourceType": "test",
   618  		"location": "test"
   619  	}`
   620  
   621  	testJSONMarshal(t, u, want)
   622  }
   623  
   624  func TestSCIMProvisionedIdentities_Marshal(t *testing.T) {
   625  	t.Parallel()
   626  	testJSONMarshal(t, &SCIMProvisionedIdentities{}, `{}`)
   627  
   628  	u := &SCIMProvisionedIdentities{
   629  		Schemas:      []string{"test", "schema"},
   630  		TotalResults: Ptr(1),
   631  		ItemsPerPage: Ptr(2),
   632  		StartIndex:   Ptr(1),
   633  		Resources: []*SCIMUserAttributes{
   634  			{
   635  				UserName: "SCIM",
   636  				Name: SCIMUserName{
   637  					GivenName:  "scim",
   638  					FamilyName: "test",
   639  					Formatted:  Ptr("SCIM"),
   640  				},
   641  				DisplayName: Ptr("Test SCIM"),
   642  				Emails: []*SCIMUserEmail{
   643  					{
   644  						Value:   "test",
   645  						Primary: Ptr(true),
   646  						Type:    Ptr("test"),
   647  					},
   648  				},
   649  				Schemas:    []string{"schema1"},
   650  				ExternalID: Ptr("id"),
   651  				Groups:     []string{"group1"},
   652  				Active:     Ptr(true),
   653  			},
   654  		},
   655  	}
   656  
   657  	want := `{
   658  		"schemas": ["test", "schema"],
   659  		"totalResults": 1,
   660  		"itemsPerPage": 2,
   661  		"startIndex": 1,
   662  		"Resources": [{
   663  			"userName": "SCIM",
   664  			"name": {
   665  				"givenName": "scim",
   666  				"familyName": "test",
   667  				"formatted": "SCIM"
   668  			},
   669  			"displayName": "Test SCIM",
   670  			"emails": [{
   671  				"value": "test",
   672  				"primary": true,
   673  				"type": "test"
   674  			}],
   675  			"schemas": ["schema1"],
   676  			"externalId": "id",
   677  			"groups": ["group1"],
   678  			"active": true
   679  		}]
   680  	}`
   681  
   682  	testJSONMarshal(t, u, want)
   683  }