-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support for Property Definitions (#308)
support for property definitions --- Co-authored-by: Rocktavious <[email protected]> Co-authored-by: Kyle <[email protected]> Co-authored-by: David Bloss <[email protected]>
- Loading branch information
1 parent
aaf9641
commit 26b6ad8
Showing
3 changed files
with
227 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
kind: Feature | ||
body: Add support for Property Definitions | ||
time: 2023-12-07T15:22:26.29648-05:00 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
package opslevel | ||
|
||
import "fmt" | ||
|
||
type PropertyDefinitionInput struct { | ||
Name string `json:"name"` | ||
Schema JSONString `json:"schema"` | ||
} | ||
|
||
type PropertyDefinition struct { | ||
Aliases []string `graphql:"aliases" json:"aliases"` | ||
Id ID `graphql:"id" json:"id"` | ||
Name string `graphql:"name" json:"name"` | ||
Schema JSON `json:"schema" scalar:"true"` // Do not add graphql struct tag here | ||
} | ||
|
||
type PropertyDefinitionConnection struct { | ||
Nodes []PropertyDefinition | ||
PageInfo PageInfo | ||
TotalCount int `graphql:"-"` | ||
} | ||
|
||
func (client *Client) CreatePropertyDefinition(input PropertyDefinitionInput) (*PropertyDefinition, error) { | ||
var m struct { | ||
Payload struct { | ||
Definition PropertyDefinition `graphql:"definition"` | ||
Errors []OpsLevelErrors `graphql:"errors"` | ||
} `graphql:"propertyDefinitionCreate(input: $input)"` | ||
} | ||
v := PayloadVariables{ | ||
"input": input, | ||
} | ||
err := client.Mutate(&m, v, WithName("PropertyDefinitionCreate")) | ||
return &m.Payload.Definition, HandleErrors(err, m.Payload.Errors) | ||
} | ||
|
||
func (client *Client) GetPropertyDefinition(input string) (*PropertyDefinition, error) { | ||
var q struct { | ||
Account struct { | ||
Definition PropertyDefinition `graphql:"propertyDefinition(input: $input)"` | ||
} | ||
} | ||
v := PayloadVariables{ | ||
"input": *NewIdentifier(input), | ||
} | ||
err := client.Query(&q, v, WithName("PropertyDefinitionGet")) | ||
if q.Account.Definition.Id == "" { | ||
err = fmt.Errorf("PropertyDefinition with ID or Alias matching '%s' not found", input) | ||
} | ||
return &q.Account.Definition, HandleErrors(err, nil) | ||
} | ||
|
||
func (client *Client) ListPropertyDefinitions(variables *PayloadVariables) (PropertyDefinitionConnection, error) { | ||
var q struct { | ||
Account struct { | ||
Definitions PropertyDefinitionConnection `graphql:"propertyDefinitions(after: $after, first: $first)"` | ||
} | ||
} | ||
if variables == nil { | ||
variables = client.InitialPageVariablesPointer() | ||
} | ||
if err := client.Query(&q, *variables, WithName("PropertyDefinitionList")); err != nil { | ||
return PropertyDefinitionConnection{}, err | ||
} | ||
for q.Account.Definitions.PageInfo.HasNextPage { | ||
(*variables)["after"] = q.Account.Definitions.PageInfo.End | ||
resp, err := client.ListPropertyDefinitions(variables) | ||
if err != nil { | ||
return PropertyDefinitionConnection{}, err | ||
} | ||
q.Account.Definitions.Nodes = append(q.Account.Definitions.Nodes, resp.Nodes...) | ||
q.Account.Definitions.PageInfo = resp.PageInfo | ||
q.Account.Definitions.TotalCount += len(q.Account.Definitions.Nodes) | ||
} | ||
return q.Account.Definitions, nil | ||
} | ||
|
||
func (client *Client) DeletePropertyDefinition(input string) error { | ||
var m struct { | ||
Payload struct { | ||
Errors []OpsLevelErrors `graphql:"errors"` | ||
} `graphql:"propertyDefinitionDelete(resource: $input)"` | ||
} | ||
v := PayloadVariables{ | ||
"input": *NewIdentifier(input), | ||
} | ||
err := client.Mutate(&m, v, WithName("PropertyDefinitionDelete")) | ||
return HandleErrors(err, m.Payload.Errors) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
package opslevel_test | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
ol "github.com/opslevel/opslevel-go/v2023" | ||
"github.com/rocktavious/autopilot/v2023" | ||
) | ||
|
||
const schemaString = `{"$ref":"#/$defs/MyProp","$defs":{"MyProp":{"properties":{"name":{"type":"string","title":"the name","description":"The name of a friend","default":"alex","examples":["joe","lucy"]}},"additionalProperties":false,"type":"object","required":["name"]}}}` | ||
|
||
func TestCreatePropertyDefinition(t *testing.T) { | ||
// Arrange | ||
schema := ol.NewJSON(schemaString) | ||
expectedPropertyDefinition := autopilot.Register[ol.PropertyDefinition]("expected_property_definition", ol.PropertyDefinition{ | ||
Aliases: []string{"my_prop"}, | ||
Id: "XXX", | ||
Name: "my-prop", | ||
Schema: schema, | ||
}) | ||
propertyDefinitionInput := autopilot.Register[ol.PropertyDefinitionInput]("property_definition_input", ol.PropertyDefinitionInput{ | ||
Name: "my-prop", | ||
Schema: ol.JSONString(schemaString), | ||
}) | ||
testRequest := NewTestRequest( | ||
`"mutation PropertyDefinitionCreate($input:PropertyDefinitionInput!){propertyDefinitionCreate(input: $input){definition{aliases,id,name,schema},errors{message,path}}}"`, | ||
`{"input": {{ template "property_definition_input" }} }`, | ||
fmt.Sprintf(`{"data":{"propertyDefinitionCreate":{"definition": {"aliases":["my_prop"],"id":"XXX","name":"my-prop","schema": %s}, "errors":[] }}}`, schema.ToJSON()), | ||
) | ||
client := BestTestClient(t, "properties/definition_create", testRequest) | ||
|
||
// Act | ||
actualPropertyDefinition, err := client.CreatePropertyDefinition(propertyDefinitionInput) | ||
|
||
// Assert | ||
autopilot.Ok(t, err) | ||
autopilot.Equals(t, expectedPropertyDefinition, *actualPropertyDefinition) | ||
autopilot.Equals(t, ol.JSON(propertyDefinitionInput.Schema.Map()), actualPropertyDefinition.Schema) | ||
} | ||
|
||
func TestDeletePropertyDefinition(t *testing.T) { | ||
// Arrange | ||
testRequest := NewTestRequest( | ||
`"mutation PropertyDefinitionDelete($input:IdentifierInput!){propertyDefinitionDelete(resource: $input){errors{message,path}}}"`, | ||
`{"input":{"alias":"my_prop"}}`, | ||
`{"data":{"propertyDefinitionDelete":{"errors":[]}}}`, | ||
) | ||
client := BestTestClient(t, "properties/definition_delete", testRequest) | ||
|
||
// Act | ||
err := client.DeletePropertyDefinition("my_prop") | ||
|
||
// Assert | ||
autopilot.Ok(t, err) | ||
} | ||
|
||
func TestGetPropertyDefinition(t *testing.T) { | ||
// Arrange | ||
schema := ol.NewJSON(schemaString) | ||
expectedPropertyDefinition := autopilot.Register[ol.PropertyDefinition]("expected_property_definition", | ||
ol.PropertyDefinition{ | ||
Aliases: []string{"my_prop"}, | ||
Id: "XXX", | ||
Name: "my-prop", | ||
Schema: schema, | ||
}) | ||
testRequest := NewTestRequest( | ||
`"query PropertyDefinitionGet($input:IdentifierInput!){account{propertyDefinition(input: $input){aliases,id,name,schema}}}"`, | ||
`{"input":{"alias":"my_prop"}}`, | ||
fmt.Sprintf(`{"data":{"account":{"propertyDefinition": {"aliases":["my_prop"],"id":"XXX","name":"my-prop","schema": %s }}}}`, schema.ToJSON()), | ||
) | ||
client := BestTestClient(t, "properties/definition_get", testRequest) | ||
|
||
// Act | ||
property, err := client.GetPropertyDefinition("my_prop") | ||
|
||
// Assert | ||
autopilot.Ok(t, err) | ||
autopilot.Equals(t, "XXX", string(property.Id)) | ||
autopilot.Equals(t, expectedPropertyDefinition, *property) | ||
autopilot.Equals(t, "my-prop", property.Name) | ||
autopilot.Equals(t, schema, property.Schema) | ||
} | ||
|
||
func TestListPropertyDefinitions(t *testing.T) { | ||
// Arrange | ||
schema := ol.NewJSON(schemaString) | ||
expectedPropDefsPageOne := autopilot.Register[[]ol.PropertyDefinition]("property_definitions", []ol.PropertyDefinition{ | ||
{ | ||
Aliases: []string{"prop1"}, | ||
Id: "XXX", | ||
Name: "prop1", | ||
Schema: ol.NewJSON(schemaString), | ||
}, | ||
{ | ||
Aliases: []string{"prop2"}, | ||
Id: "XXX", | ||
Name: "prop2", | ||
Schema: ol.NewJSON(schemaString), | ||
}, | ||
}) | ||
expectedPropDefPageTwo := autopilot.Register[ol.PropertyDefinition]("property_definition_3", ol.PropertyDefinition{ | ||
Aliases: []string{"prop3"}, | ||
Id: "XXX", | ||
Name: "prop3", | ||
Schema: ol.NewJSON(schemaString), | ||
}) | ||
testRequestOne := NewTestRequest( | ||
`"query PropertyDefinitionList($after:String!$first:Int!){account{propertyDefinitions(after: $after, first: $first){nodes{aliases,id,name,schema},{{ template "pagination_request" }}}}}"`, | ||
`{{ template "pagination_initial_query_variables" }}`, | ||
fmt.Sprintf(`{"data":{"account":{"propertyDefinitions":{"nodes":[{"aliases":["prop1"],"id":"XXX","name":"prop1","schema": %s},{"aliases":["prop2"],"id":"XXX","name":"prop2","schema": %s}],{{ template "pagination_initial_pageInfo_response" }}}}}}`, schema.ToJSON(), schema.ToJSON()), | ||
) | ||
testRequestTwo := NewTestRequest( | ||
`"query PropertyDefinitionList($after:String!$first:Int!){account{propertyDefinitions(after: $after, first: $first){nodes{aliases,id,name,schema},{{ template "pagination_request" }}}}}"`, | ||
`{{ template "pagination_second_query_variables" }}`, | ||
fmt.Sprintf(`{"data":{"account":{"propertyDefinitions":{"nodes":[{"aliases":["prop3"],"id":"XXX","name":"prop3","schema": %s}],{{ template "pagination_second_pageInfo_response" }}}}}}`, schema.ToJSON()), | ||
) | ||
requests := []TestRequest{testRequestOne, testRequestTwo} | ||
client := BestTestClient(t, "properties/definition_list", requests...) | ||
|
||
// Act | ||
properties, err := client.ListPropertyDefinitions(nil) | ||
result := properties.Nodes | ||
|
||
// Assert | ||
autopilot.Ok(t, err) | ||
autopilot.Equals(t, 3, len(result)) | ||
autopilot.Equals(t, expectedPropDefsPageOne[0], result[0]) | ||
autopilot.Equals(t, expectedPropDefsPageOne[1], result[1]) | ||
autopilot.Equals(t, expectedPropDefPageTwo, result[2]) | ||
autopilot.Equals(t, expectedPropDefsPageOne[0].Schema, result[0].Schema) | ||
autopilot.Equals(t, expectedPropDefsPageOne[1].Schema, result[1].Schema) | ||
autopilot.Equals(t, expectedPropDefPageTwo.Schema, result[2].Schema) | ||
} |