...

Source file src/github.com/google/go-github/v55/github/scim_test.go

Documentation: github.com/google/go-github/v55/github

     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  	client, mux, _, teardown := setup()
    20  	defer teardown()
    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: Int(1),
    75  		ItemsPerPage: Int(1),
    76  		StartIndex:   Int(1),
    77  		Resources: []*SCIMUserAttributes{
    78  			{
    79  				ID: String("5fc0c238-1112-11e8-8e45-920c87bdbd75"),
    80  				Meta: &SCIMMeta{
    81  					ResourceType: String("User"),
    82  					Created:      &date,
    83  					LastModified: &date,
    84  					Location:     String("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:  String("Mona Octocat"),
    91  				},
    92  				DisplayName: String("Mona Octocat"),
    93  				Emails: []*SCIMUserEmail{
    94  					{
    95  						Value:   "octocat@github.com",
    96  						Primary: Bool(true),
    97  					},
    98  				},
    99  				Schemas:    []string{"urn:ietf:params:scim:schemas:core:2.0:User"},
   100  				ExternalID: String("00u1dhhb1fkIGP7RL1d8"),
   101  				Groups:     nil,
   102  				Active:     Bool(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_ProvisionAndInviteSCIMUser(t *testing.T) {
   125  	client, mux, _, teardown := setup()
   126  	defer teardown()
   127  
   128  	mux.HandleFunc("/scim/v2/organizations/o/Users", func(w http.ResponseWriter, r *http.Request) {
   129  		testMethod(t, r, "POST")
   130  		w.WriteHeader(http.StatusOK)
   131  	})
   132  
   133  	ctx := context.Background()
   134  	opts := &SCIMUserAttributes{
   135  		UserName: "userName",
   136  		Name: SCIMUserName{
   137  			GivenName:  "givenName",
   138  			FamilyName: "familyName",
   139  		},
   140  		Emails: []*SCIMUserEmail{
   141  			{
   142  				Value: "octocat@github.com",
   143  			},
   144  		},
   145  	}
   146  	_, err := client.SCIM.ProvisionAndInviteSCIMUser(ctx, "o", opts)
   147  	if err != nil {
   148  		t.Errorf("SCIM.ListSCIMProvisionedIdentities returned error: %v", err)
   149  	}
   150  
   151  	const methodName = "ProvisionAndInviteSCIMUser"
   152  	testBadOptions(t, methodName, func() (err error) {
   153  		_, err = client.SCIM.ProvisionAndInviteSCIMUser(ctx, "\n", opts)
   154  		return err
   155  	})
   156  
   157  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   158  		return client.SCIM.ProvisionAndInviteSCIMUser(ctx, "o", opts)
   159  	})
   160  }
   161  
   162  func TestSCIMService_GetSCIMProvisioningInfoForUser(t *testing.T) {
   163  	client, mux, _, teardown := setup()
   164  	defer teardown()
   165  
   166  	mux.HandleFunc("/scim/v2/organizations/o/Users/123", func(w http.ResponseWriter, r *http.Request) {
   167  		testMethod(t, r, "GET")
   168  		w.WriteHeader(http.StatusOK)
   169  		_, _ = w.Write([]byte(`{
   170  			"schemas": [
   171  			  "urn:ietf:params:scim:schemas:core:2.0:User"
   172  			],
   173  			"id": "edefdfedf-050c-11e7-8d32",
   174  			"externalId": "a7d0f98382",
   175  			"userName": "mona.octocat@okta.example.com",
   176  			"displayName": "Mona Octocat",
   177  			"name": {
   178  			  "givenName": "Mona",
   179  			  "familyName": "Octocat",
   180  			  "formatted": "Mona Octocat"
   181  			},
   182  			"emails": [
   183  			  {
   184  				"value": "mona.octocat@okta.example.com",
   185  				"primary": true
   186  			  },
   187  			  {
   188  				"value": "mona@octocat.github.com"
   189  			  }
   190  			],
   191  			"active": true,
   192  			"meta": {
   193  			  "resourceType": "User",
   194  			  "created": "2017-03-09T16:11:13-00:00",
   195  			  "lastModified": "2017-03-09T16:11:13-00:00",
   196  			  "location": "https://api.github.com/scim/v2/organizations/octo-org/Users/edefdfedf-050c-11e7-8d32"
   197  			}
   198  		  }`))
   199  	})
   200  
   201  	ctx := context.Background()
   202  	user, _, err := client.SCIM.GetSCIMProvisioningInfoForUser(ctx, "o", "123")
   203  	if err != nil {
   204  		t.Errorf("SCIM.GetSCIMProvisioningInfoForUser returned error: %v", err)
   205  	}
   206  
   207  	date := Timestamp{time.Date(2017, time.March, 9, 16, 11, 13, 0, time.UTC)}
   208  	want := SCIMUserAttributes{
   209  		ID: String("edefdfedf-050c-11e7-8d32"),
   210  		Meta: &SCIMMeta{
   211  			ResourceType: String("User"),
   212  			Created:      &date,
   213  			LastModified: &date,
   214  			Location:     String("https://api.github.com/scim/v2/organizations/octo-org/Users/edefdfedf-050c-11e7-8d32"),
   215  		},
   216  		UserName: "mona.octocat@okta.example.com",
   217  		Name: SCIMUserName{
   218  			GivenName:  "Mona",
   219  			FamilyName: "Octocat",
   220  			Formatted:  String("Mona Octocat"),
   221  		},
   222  		DisplayName: String("Mona Octocat"),
   223  		Emails: []*SCIMUserEmail{
   224  			{
   225  				Value:   "mona.octocat@okta.example.com",
   226  				Primary: Bool(true),
   227  			},
   228  			{
   229  				Value: "mona@octocat.github.com",
   230  			},
   231  		},
   232  		Schemas:    []string{"urn:ietf:params:scim:schemas:core:2.0:User"},
   233  		ExternalID: String("a7d0f98382"),
   234  		Groups:     nil,
   235  		Active:     Bool(true),
   236  	}
   237  
   238  	if !cmp.Equal(user, &want) {
   239  		diff := cmp.Diff(user, want)
   240  		t.Errorf("SCIM.ListSCIMProvisionedIdentities returned %+v, want %+v: diff %+v", user, want, diff)
   241  	}
   242  
   243  	const methodName = "GetSCIMProvisioningInfoForUser"
   244  	testBadOptions(t, methodName, func() error {
   245  		_, _, err := client.SCIM.GetSCIMProvisioningInfoForUser(ctx, "\n", "123")
   246  		return err
   247  	})
   248  
   249  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   250  		_, r, err := client.SCIM.GetSCIMProvisioningInfoForUser(ctx, "o", "123")
   251  		return r, err
   252  	})
   253  }
   254  
   255  func TestSCIMService_UpdateProvisionedOrgMembership(t *testing.T) {
   256  	client, mux, _, teardown := setup()
   257  	defer teardown()
   258  
   259  	mux.HandleFunc("/scim/v2/organizations/o/Users/123", func(w http.ResponseWriter, r *http.Request) {
   260  		testMethod(t, r, "PUT")
   261  		w.WriteHeader(http.StatusOK)
   262  	})
   263  
   264  	ctx := context.Background()
   265  	opts := &SCIMUserAttributes{
   266  		UserName: "userName",
   267  		Name: SCIMUserName{
   268  			GivenName:  "givenName",
   269  			FamilyName: "familyName",
   270  		},
   271  		Emails: []*SCIMUserEmail{
   272  			{
   273  				Value: "octocat@github.com",
   274  			},
   275  		},
   276  	}
   277  	_, err := client.SCIM.UpdateProvisionedOrgMembership(ctx, "o", "123", opts)
   278  	if err != nil {
   279  		t.Errorf("SCIM.UpdateProvisionedOrgMembership returned error: %v", err)
   280  	}
   281  
   282  	const methodName = "UpdateProvisionedOrgMembership"
   283  	testBadOptions(t, methodName, func() error {
   284  		_, err := client.SCIM.UpdateProvisionedOrgMembership(ctx, "\n", "123", opts)
   285  		return err
   286  	})
   287  
   288  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   289  		return client.SCIM.UpdateProvisionedOrgMembership(ctx, "o", "123", opts)
   290  	})
   291  }
   292  
   293  func TestSCIMService_UpdateAttributeForSCIMUser(t *testing.T) {
   294  	client, mux, _, teardown := setup()
   295  	defer teardown()
   296  
   297  	mux.HandleFunc("/scim/v2/organizations/o/Users/123", func(w http.ResponseWriter, r *http.Request) {
   298  		testMethod(t, r, "PATCH")
   299  		w.WriteHeader(http.StatusNoContent)
   300  	})
   301  
   302  	ctx := context.Background()
   303  	opts := &UpdateAttributeForSCIMUserOptions{}
   304  	_, err := client.SCIM.UpdateAttributeForSCIMUser(ctx, "o", "123", opts)
   305  	if err != nil {
   306  		t.Errorf("SCIM.UpdateAttributeForSCIMUser returned error: %v", err)
   307  	}
   308  
   309  	const methodName = "UpdateAttributeForSCIMUser"
   310  	testBadOptions(t, methodName, func() error {
   311  		_, err := client.SCIM.UpdateAttributeForSCIMUser(ctx, "\n", "123", opts)
   312  		return err
   313  	})
   314  
   315  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   316  		return client.SCIM.UpdateAttributeForSCIMUser(ctx, "o", "123", opts)
   317  	})
   318  }
   319  
   320  func TestSCIMService_DeleteSCIMUserFromOrg(t *testing.T) {
   321  	client, mux, _, teardown := setup()
   322  	defer teardown()
   323  
   324  	mux.HandleFunc("/scim/v2/organizations/o/Users/123", func(w http.ResponseWriter, r *http.Request) {
   325  		testMethod(t, r, "DELETE")
   326  		w.WriteHeader(http.StatusNoContent)
   327  	})
   328  
   329  	ctx := context.Background()
   330  	_, err := client.SCIM.DeleteSCIMUserFromOrg(ctx, "o", "123")
   331  	if err != nil {
   332  		t.Errorf("SCIM.DeleteSCIMUserFromOrg returned error: %v", err)
   333  	}
   334  
   335  	const methodName = "DeleteSCIMUserFromOrg"
   336  	testBadOptions(t, methodName, func() error {
   337  		_, err := client.SCIM.DeleteSCIMUserFromOrg(ctx, "\n", "")
   338  		return err
   339  	})
   340  
   341  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   342  		return client.SCIM.DeleteSCIMUserFromOrg(ctx, "o", "123")
   343  	})
   344  }
   345  
   346  func TestSCIMUserAttributes_Marshal(t *testing.T) {
   347  	testJSONMarshal(t, &SCIMUserAttributes{}, `{
   348  		"userName":"","name":{"givenName":"","familyName":""},"emails":null
   349  	}`)
   350  
   351  	u := &SCIMUserAttributes{
   352  		UserName: "userName1",
   353  		Name: SCIMUserName{
   354  			GivenName:  "Name1",
   355  			FamilyName: "Fname",
   356  			Formatted:  String("formatted name"),
   357  		},
   358  		DisplayName: String("Name"),
   359  		Emails: []*SCIMUserEmail{
   360  			{
   361  				Value:   "value",
   362  				Primary: Bool(false),
   363  				Type:    String("type"),
   364  			},
   365  		},
   366  		Schemas:    []string{"schema1"},
   367  		ExternalID: String("id"),
   368  		Groups:     []string{"group1"},
   369  		Active:     Bool(true),
   370  	}
   371  
   372  	want := `{
   373  		"userName": "userName1",
   374  		"name": {
   375  			"givenName": "Name1",
   376  			"familyName": "Fname",
   377  			"formatted": "formatted name"
   378  		},
   379  		"displayName": "Name",
   380  		"emails": [{
   381  			"value": "value",
   382  			"primary": false,
   383  			"type": "type"
   384  		}],
   385  		"schemas": ["schema1"],
   386  		"externalId": "id",
   387  		"groups": ["group1"],
   388  		"active": true
   389  	}`
   390  
   391  	testJSONMarshal(t, u, want)
   392  }
   393  
   394  func TestUpdateAttributeForSCIMUserOperations_Marshal(t *testing.T) {
   395  	testJSONMarshal(t, &UpdateAttributeForSCIMUserOperations{}, `{}`)
   396  
   397  	u := &UpdateAttributeForSCIMUserOperations{
   398  		Op:   "TestOp",
   399  		Path: String("path"),
   400  	}
   401  
   402  	want := `{
   403  		"op": "TestOp",
   404  		"path": "path"
   405  	}`
   406  
   407  	testJSONMarshal(t, u, want)
   408  }
   409  
   410  func TestUpdateAttributeForSCIMUserOptions_Marshal(t *testing.T) {
   411  	testJSONMarshal(t, &UpdateAttributeForSCIMUserOptions{}, `{}`)
   412  
   413  	u := &UpdateAttributeForSCIMUserOptions{
   414  		Schemas: []string{"test", "schema"},
   415  		Operations: UpdateAttributeForSCIMUserOperations{
   416  			Op:   "TestOp",
   417  			Path: String("path"),
   418  		},
   419  	}
   420  
   421  	want := `{
   422  		"schemas": ["test", "schema"],
   423  		"operations": {
   424  			"op": "TestOp",
   425  			"path": "path"
   426  		}
   427  	}`
   428  
   429  	testJSONMarshal(t, u, want)
   430  }
   431  
   432  func TestListSCIMProvisionedIdentitiesOptions_addOptions(t *testing.T) {
   433  	testJSONMarshal(t, &ListSCIMProvisionedIdentitiesOptions{}, `{
   434  		"StartIndex": null,
   435  		"Count": null,
   436  		"Filter": null
   437  	}`)
   438  
   439  	url := "some/path"
   440  
   441  	testAddURLOptions(t, url, &ListSCIMProvisionedIdentitiesOptions{}, url)
   442  
   443  	testAddURLOptions(
   444  		t,
   445  		url,
   446  		&ListSCIMProvisionedIdentitiesOptions{
   447  			StartIndex: Int(1),
   448  			Count:      Int(10),
   449  		},
   450  		fmt.Sprintf("%s?count=10&startIndex=1", url),
   451  	)
   452  
   453  	testAddURLOptions(
   454  		t,
   455  		url,
   456  		&ListSCIMProvisionedIdentitiesOptions{
   457  			StartIndex: Int(1),
   458  			Count:      Int(10),
   459  			Filter:     String("test"),
   460  		},
   461  		fmt.Sprintf("%s?count=10&filter=test&startIndex=1", url),
   462  	)
   463  }
   464  
   465  func TestSCIMUserName_Marshal(t *testing.T) {
   466  	testJSONMarshal(t, &SCIMUserName{}, `{
   467  		"givenName":"","familyName":""
   468  	}`)
   469  
   470  	u := &SCIMUserName{
   471  		GivenName:  "Name1",
   472  		FamilyName: "Fname",
   473  		Formatted:  String("formatted name"),
   474  	}
   475  
   476  	want := `{
   477  			"givenName": "Name1",
   478  			"familyName": "Fname",
   479  			"formatted": "formatted name"	
   480  	}`
   481  	testJSONMarshal(t, u, want)
   482  }
   483  
   484  func TestSCIMMeta_Marshal(t *testing.T) {
   485  	testJSONMarshal(t, &SCIMMeta{}, `{}`)
   486  
   487  	u := &SCIMMeta{
   488  		ResourceType: String("test"),
   489  		Location:     String("test"),
   490  	}
   491  
   492  	want := `{
   493  		"resourceType": "test",
   494  		"location": "test"
   495  	}`
   496  
   497  	testJSONMarshal(t, u, want)
   498  }
   499  
   500  func TestSCIMProvisionedIdentities_Marshal(t *testing.T) {
   501  	testJSONMarshal(t, &SCIMProvisionedIdentities{}, `{}`)
   502  
   503  	u := &SCIMProvisionedIdentities{
   504  		Schemas:      []string{"test", "schema"},
   505  		TotalResults: Int(1),
   506  		ItemsPerPage: Int(2),
   507  		StartIndex:   Int(1),
   508  		Resources: []*SCIMUserAttributes{
   509  			{
   510  				UserName: "SCIM",
   511  				Name: SCIMUserName{
   512  					GivenName:  "scim",
   513  					FamilyName: "test",
   514  					Formatted:  String("SCIM"),
   515  				},
   516  				DisplayName: String("Test SCIM"),
   517  				Emails: []*SCIMUserEmail{
   518  					{
   519  						Value:   "test",
   520  						Primary: Bool(true),
   521  						Type:    String("test"),
   522  					},
   523  				},
   524  				Schemas:    []string{"schema1"},
   525  				ExternalID: String("id"),
   526  				Groups:     []string{"group1"},
   527  				Active:     Bool(true),
   528  			},
   529  		},
   530  	}
   531  
   532  	want := `{
   533  		"schemas": ["test", "schema"],
   534  		"totalResults": 1,
   535  		"itemsPerPage": 2,
   536  		"startIndex": 1,
   537  		"Resources": [{
   538  			"userName": "SCIM",
   539  			"name": {
   540  				"givenName": "scim",
   541  				"familyName": "test",
   542  				"formatted": "SCIM"
   543  			},
   544  			"displayName": "Test SCIM",
   545  			"emails": [{
   546  				"value": "test",
   547  				"primary": true,
   548  				"type": "test"
   549  			}],
   550  			"schemas": ["schema1"],
   551  			"externalId": "id",
   552  			"groups": ["group1"],
   553  			"active": true
   554  		}]
   555  	}`
   556  
   557  	testJSONMarshal(t, u, want)
   558  }
   559  

View as plain text