From a49bc872f4acd39bbc30572a794a1f1040c54acd Mon Sep 17 00:00:00 2001 From: Mike Mondragon Date: Mon, 29 Nov 2021 16:37:46 -0800 Subject: [PATCH] Adding GroupProfileMap to GroupProfile OPENAPI_SPEC_BRANCH=2.9 make pull-spec make generate-files --- CHANGELOG.md | 3 +- okta/groupProfile.go | 43 ++++++++++++++++++++++ openapi/generator/index.js | 4 +++ openapi/generator/templates/model.go.hbs | 46 ++++++++++++++++++++++++ tests/integration/group_test.go | 40 +++++++++++++++++---- 5 files changed, 129 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cc42b9b5..189492516 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,8 @@ Running changelog of releases since `2.0.0-rc.4` ## v2.9.2 ### Updates -Adjustments were made the attributes on the `DeviceAccessPolicyRuleCondition` type. +- Adjustments were made the attributes on the `DeviceAccessPolicyRuleCondition` type. +- Adding `GroupProfileMap` attribute to `GroupProfile` struct to support additional properties. See #268 ## v2.9.1 diff --git a/okta/groupProfile.go b/okta/groupProfile.go index df84dfb31..d6f1fa1b6 100644 --- a/okta/groupProfile.go +++ b/okta/groupProfile.go @@ -18,7 +18,50 @@ package okta +import ( + "encoding/json" +) + +type GroupProfileMap map[string]interface{} + type GroupProfile struct { Description string `json:"description,omitempty"` Name string `json:"name,omitempty"` + GroupProfileMap +} + +func (a *GroupProfile) UnmarshalJSON(data []byte) error { + if string(data) == "null" || string(data) == `""` { + return nil + } + var profile map[string]interface{} + err := json.Unmarshal(data, &profile) + if err != nil { + return err + } + a.Name, _ = profile["name"].(string) + a.Description, _ = profile["description"].(string) + delete(profile, "name") + delete(profile, "description") + a.GroupProfileMap = profile + return nil +} + +func (a GroupProfile) MarshalJSON() ([]byte, error) { + if len(a.GroupProfileMap) == 0 { + return json.Marshal(&struct { + Name string `json:"name"` + Description string `json:"description"` + }{ + Name: a.Name, + Description: a.Description, + }) + } + if a.Name != "" { + a.GroupProfileMap["name"] = a.Name + } + if a.Description != "" { + a.GroupProfileMap["description"] = a.Description + } + return json.Marshal(a.GroupProfileMap) } diff --git a/openapi/generator/index.js b/openapi/generator/index.js index 379341546..6256cc7e0 100644 --- a/openapi/generator/index.js +++ b/openapi/generator/index.js @@ -225,6 +225,10 @@ function getImports(object) { imports.splice(imports.indexOf("fmt"), 1); } + if (object.model.modelName === "GroupProfile") { + imports.push("encoding/json"); + } + return imports; } diff --git a/openapi/generator/templates/model.go.hbs b/openapi/generator/templates/model.go.hbs index 13e2b2d21..cac6b5a04 100644 --- a/openapi/generator/templates/model.go.hbs +++ b/openapi/generator/templates/model.go.hbs @@ -36,6 +36,10 @@ type {{model.modelName}}Resource resource )}} type {{model.modelName}}Resource resource +{{/if}} +{{#if (eq model.modelName "GroupProfile")}} +type {{model.modelName}}Map map[string]interface{} + {{/if}} {{#if (eq model.modelName "ApplicationSettingsApplication")}} type {{model.modelName}} map[string]interface{} @@ -44,6 +48,9 @@ type {{model.modelName}} string {{else}} type {{model.modelName}} struct { {{{buildModelProperties model}}} +{{#if (eq model.modelName "GroupProfile")}} + {{model.modelName}}Map +{{/if}} } {{/if}} {{#if model.enum}} @@ -72,3 +79,42 @@ func (a *{{model.modelName}}) Is{{model.tags.[0]}}Instance() bool { {{> model.defaultMethod operation=operation alias=alias modelName=../model.modelName}} {{/each}} {{/if}} + +{{#if (eq model.modelName "GroupProfile")}} +func (a *{{model.modelName}}) UnmarshalJSON(data []byte) error { + if string(data) == "null" || string(data) == `""` { + return nil + } + var profile map[string]interface{} + err := json.Unmarshal(data, &profile) + if err != nil { + return err + } + a.Name, _ = profile["name"].(string) + a.Description, _ = profile["description"].(string) + delete(profile, "name") + delete(profile, "description") + a.{{model.modelName}}Map = profile + return nil +} + +func (a {{model.modelName}}) MarshalJSON() ([]byte, error) { + if len(a.{{model.modelName}}Map) == 0 { + return json.Marshal(&struct { + Name string `json:"name"` + Description string `json:"description"` + }{ + Name: a.Name, + Description: a.Description, + }) + } + if a.Name != "" { + a.{{model.modelName}}Map["name"] = a.Name + } + if a.Description != "" { + a.{{model.modelName}}Map["description"] = a.Description + } + return json.Marshal(a.{{model.modelName}}Map) +} + +{{/if}} \ No newline at end of file diff --git a/tests/integration/group_test.go b/tests/integration/group_test.go index e5c311d6e..439354895 100644 --- a/tests/integration/group_test.go +++ b/tests/integration/group_test.go @@ -18,6 +18,7 @@ package integration import ( "context" + "encoding/json" "net/http" "testing" "time" @@ -29,7 +30,7 @@ import ( "github.com/stretchr/testify/require" ) -func Test_can_get_a_group(t *testing.T) { +func TestCanGetAGroup(t *testing.T) { ctx, client, err := tests.NewClient(context.TODO()) require.NoError(t, err) // Create a new group → POST /api/v1/groups @@ -59,7 +60,7 @@ func Test_can_get_a_group(t *testing.T) { "Should have resulted in a 404 when finding a deleted group") } -func Test_can_list_groups(t *testing.T) { +func TestCanListGroups(t *testing.T) { ctx, client, err := tests.NewClient(context.TODO()) require.NoError(t, err) // Create a new group → POST /api/v1/groups @@ -89,7 +90,7 @@ func Test_can_list_groups(t *testing.T) { require.NoError(t, err, "Should not error when deleting a group") } -func Test_can_search_for_a_group(t *testing.T) { +func TestCanSearchForAGroup(t *testing.T) { ctx, client, err := tests.NewClient(context.TODO()) require.NoError(t, err) // Create a new group → POST /api/v1/groups @@ -121,7 +122,7 @@ func Test_can_search_for_a_group(t *testing.T) { require.NoError(t, err, "Should not error when deleting a group") } -func Test_can_update_a_group(t *testing.T) { +func TestCanUpdateAGroup(t *testing.T) { ctx, client, err := tests.NewClient(context.TODO()) require.NoError(t, err) // Create a new group → POST /api/v1/groups @@ -153,7 +154,7 @@ func Test_can_update_a_group(t *testing.T) { require.NoError(t, err, "Should not error when deleting a group") } -func Test_group_user_operations(t *testing.T) { +func TestGroupUserOperations(t *testing.T) { ctx, client, err := tests.NewClient(context.TODO()) require.NoError(t, err) // Create a user with credentials → POST /api/v1/users?activate=false @@ -218,7 +219,7 @@ func Test_group_user_operations(t *testing.T) { require.NoError(t, err, "Should not error when deleting a group") } -func Test_group_rule_operations(t *testing.T) { +func TestGroupRuleOperations(t *testing.T) { t.Skip("does not work properly in test org") ctx, client, err := tests.NewClient(context.TODO(), okta.WithCache(false)) // Create a user with credentials, activated by default → POST /api/v1/users?activate=true @@ -364,3 +365,30 @@ func Test_group_rule_operations(t *testing.T) { _, err = client.Group.DeleteGroupRule(ctx, groupRule.Id, &query.Params{}) require.NoError(t, err, "Should not error when deleting Rule") } + +func TestGroupProfileSerialization(t *testing.T) { + gp := okta.GroupProfile{ + Name: "test", + Description: "tester", + GroupProfileMap: okta.GroupProfileMap{ + "custom": "value", + }, + } + + gpExpected := okta.GroupProfile{ + Name: "test", + Description: "tester", + GroupProfileMap: okta.GroupProfileMap{ + "custom": "value", + }, + } + + b, err := json.Marshal(&gp) + require.NoError(t, err) + + var gpCopy okta.GroupProfile + err = json.Unmarshal(b, &gpCopy) + require.NoError(t, err) + + assert.Equal(t, gpExpected, gpCopy, "expected marshal to unmarshal to produce exact copy of group profile") +}