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