diff --git a/owner.go b/owner.go index 050db146..45896087 100644 --- a/owner.go +++ b/owner.go @@ -28,3 +28,27 @@ func (entityOwnerService *EntityOwnerService) Aliases() []string { func (entityOwnerService *EntityOwnerService) Id() ID { return entityOwnerService.OnService.Id } + +// HasPropertiesOwner represents the owner of a Property (Service or Team). +// GraphQL type: HasProperties (interface implemented by Service and Team). +type HasPropertiesOwner struct { + OnService ServiceId `graphql:"... on Service"` + OnTeam EntityOwnerTeam `graphql:"... on Team"` +} + +func (o HasPropertiesOwner) Id() ID { + if o.OnService.Id != "" { + return o.OnService.Id + } + return o.OnTeam.Id +} + +func (o HasPropertiesOwner) Alias() string { + if o.OnService.Id != "" { + if len(o.OnService.Aliases) > 0 { + return o.OnService.Aliases[0] + } + return "" + } + return o.OnTeam.Alias +} diff --git a/payload.go b/payload.go index 658d3c4a..1fe8ebff 100644 --- a/payload.go +++ b/payload.go @@ -196,8 +196,8 @@ type PropertyPayload struct { // PropertyUnassignPayload The payload for unassigning a property type PropertyUnassignPayload struct { - Definition PropertyDefinition // The definition of the property that was unassigned (Optional) - Owner EntityOwnerService // The entity that the property was unassigned from (Optional) + Definition PropertyDefinition // The definition of the property that was unassigned (Optional) + Owner HasPropertiesOwner // The entity that the property was unassigned from (Optional) BasePayload } diff --git a/property.go b/property.go index eef61e15..6244f07e 100644 --- a/property.go +++ b/property.go @@ -21,13 +21,13 @@ type PropertyDefinitionId struct { Aliases []string `json:"aliases,omitempty"` } -// Property represents a custom property value assigned to an entity. +// Property represents a custom property value assigned to an entity (Service or Team). type Property struct { Definition PropertyDefinitionId `graphql:"definition"` Locked bool `graphql:"locked"` - Owner EntityOwnerService `graphql:"owner"` + Owner HasPropertiesOwner `graphql:"owner"` ValidationErrors []Error `graphql:"validationErrors"` - Value *JsonString `graphql:"value"` + Value *JsonString `graphql:"value"` } type ServicePropertiesConnection struct { @@ -136,14 +136,17 @@ func (client *Client) PropertyAssign(input PropertyInput) (*Property, error) { return &m.Payload.Property, HandleErrors(err, m.Payload.Errors) } -func (client *Client) PropertyUnassign(owner string, definition string) error { +func (client *Client) PropertyUnassign(owner string, definition string, ownerType *PropertyOwnerTypeEnum) error { var m struct { - Payload BasePayload `graphql:"propertyUnassign(owner: $owner, definition: $definition)"` + Payload BasePayload `graphql:"propertyUnassign(owner: $owner, definition: $definition, ownerType: $ownerType)"` } v := PayloadVariables{ "owner": *NewIdentifier(owner), "definition": *NewIdentifier(definition), } + if ownerType != nil { + v["ownerType"] = *ownerType + } err := client.Mutate(&m, v, WithName("PropertyUnassign")) return HandleErrors(err, m.Payload.Errors) } diff --git a/property_test.go b/property_test.go index 95eaf7ae..552863a3 100644 --- a/property_test.go +++ b/property_test.go @@ -195,7 +195,7 @@ func TestListPropertyDefinitions(t *testing.T) { func TestGetProperty(t *testing.T) { // Arrange testRequest := autopilot.NewTestRequest( - `query PropertyGet($definition:IdentifierInput!$owner:IdentifierInput!){account{property(owner: $owner, definition: $definition){definition{id,aliases},locked,owner{... on Service{id,aliases}},validationErrors{message,path},value}}}`, + `query PropertyGet($definition:IdentifierInput!$owner:IdentifierInput!){account{property(owner: $owner, definition: $definition){definition{id,aliases},locked,owner{... on Service{id,aliases},... on Team{teamAlias:alias,id}},validationErrors{message,path},value}}}`, `{"owner":{"alias":"monolith"},"definition":{"alias":"is_beta_feature"}}`, `{"data":{"account":{"property":{"definition":{"id":"{{ template "id2_string" }}"},"locked":true,"owner":{"id":"{{ template "id1_string" }}"},"validationErrors":[],"value":"true"}}}}`, ) @@ -216,7 +216,7 @@ func TestGetProperty(t *testing.T) { func TestGetPropertyHasErrors(t *testing.T) { // Arrange testRequest := autopilot.NewTestRequest( - `query PropertyGet($definition:IdentifierInput!$owner:IdentifierInput!){account{property(owner: $owner, definition: $definition){definition{id,aliases},locked,owner{... on Service{id,aliases}},validationErrors{message,path},value}}}`, + `query PropertyGet($definition:IdentifierInput!$owner:IdentifierInput!){account{property(owner: $owner, definition: $definition){definition{id,aliases},locked,owner{... on Service{id,aliases},... on Team{teamAlias:alias,id}},validationErrors{message,path},value}}}`, `{"owner":{"alias":"monolith"},"definition":{"alias":"dropdown"}}`, `{"data":{"account":{"property":{"definition":{"id":"{{ template "id2_string" }}"},"locked":false,"owner":{"id":"{{ template "id1_string" }}"},"validationErrors":[{"message":"vmessage1","path":["vmp1","vmp2"]},{"message":"vmessage2","path":["vmp3"]}],"value":"\"orange\""}}}}`, ) @@ -246,7 +246,7 @@ func TestGetPropertyHasErrors(t *testing.T) { func TestGetPropertyHasNullValue(t *testing.T) { // Arrange testRequest := autopilot.NewTestRequest( - `query PropertyGet($definition:IdentifierInput!$owner:IdentifierInput!){account{property(owner: $owner, definition: $definition){definition{id,aliases},locked,owner{... on Service{id,aliases}},validationErrors{message,path},value}}}`, + `query PropertyGet($definition:IdentifierInput!$owner:IdentifierInput!){account{property(owner: $owner, definition: $definition){definition{id,aliases},locked,owner{... on Service{id,aliases},... on Team{teamAlias:alias,id}},validationErrors{message,path},value}}}`, `{"owner":{"alias":"monolith"},"definition":{"alias":"is_beta_feature"}}`, `{"data":{"account":{"property":{"definition":{"id":"{{ template "id2_string" }}"},"locked":true,"owner":{"id":"{{ template "id1_string" }}"},"validationErrors":[],"value":null}}}}`, ) @@ -272,7 +272,7 @@ func TestAssignProperty(t *testing.T) { Value: "true", } testRequest := autopilot.NewTestRequest( - `mutation PropertyAssign($input:PropertyInput!){propertyAssign(input: $input){property{definition{id,aliases},locked,owner{... on Service{id,aliases}},validationErrors{message,path},value},errors{message,path}}}`, + `mutation PropertyAssign($input:PropertyInput!){propertyAssign(input: $input){property{definition{id,aliases},locked,owner{... on Service{id,aliases},... on Team{teamAlias:alias,id}},validationErrors{message,path},value},errors{message,path}}}`, `{"input": {{ template "property_assign_input" }} }`, `{"data":{"propertyAssign":{"property":{"definition":{"id":"{{ template "id2_string" }}"},"locked":true,"owner":{"id":"{{ template "id1_string" }}"},"validationErrors":[],"value":"true"},"errors":[]}}}`, ) @@ -293,14 +293,14 @@ func TestAssignProperty(t *testing.T) { func TestUnassignProperty(t *testing.T) { // Arrange testRequest := autopilot.NewTestRequest( - `mutation PropertyUnassign($definition:IdentifierInput!$owner:IdentifierInput!){propertyUnassign(owner: $owner, definition: $definition){errors{message,path}}}`, + `mutation PropertyUnassign($definition:IdentifierInput!$owner:IdentifierInput!){propertyUnassign(owner: $owner, definition: $definition, ownerType: $ownerType){errors{message,path}}}`, `{"owner":{"alias":"monolith"},"definition":{"alias":"is_beta_feature"}}`, `{"data":{"propertyUnassign":{"errors":[]}}}`, ) client := BestTestClient(t, "properties/property_unassign", testRequest) // Act - err := client.PropertyUnassign("monolith", "is_beta_feature") + err := client.PropertyUnassign("monolith", "is_beta_feature", nil) // Assert autopilot.Ok(t, err) @@ -314,8 +314,10 @@ func TestGetServiceProperties(t *testing.T) { service := ol.Service{ ServiceId: serviceId, } - owner := ol.EntityOwnerService{ + // When API returns a Service owner, the GraphQL client may set both OnService and OnTeam.Id from the "id" field + owner := ol.HasPropertiesOwner{ OnService: serviceId, + OnTeam: ol.EntityOwnerTeam{Id: id1}, } value1 := ol.JsonString("true") value2 := ol.JsonString("false") @@ -352,12 +354,12 @@ func TestGetServiceProperties(t *testing.T) { }, }) testRequestOne := autopilot.NewTestRequest( - `query ServicePropertiesList($after:String!$first:Int!$service:ID!){account{service(id: $service){properties(after: $after, first: $first){nodes{definition{id,aliases},locked,owner{... on Service{id,aliases}},validationErrors{message,path},value},{{ template "pagination_request" }}}}}}`, + `query ServicePropertiesList($after:String!$first:Int!$service:ID!){account{service(id: $service){properties(after: $after, first: $first){nodes{definition{id,aliases},locked,owner{... on Service{id,aliases},... on Team{teamAlias:alias,id}},validationErrors{message,path},value},{{ template "pagination_request" }}}}}}`, `{ {{ template "first_page_variables" }}, "service": "{{ template "id1_string" }}" }`, `{"data":{"account":{"service":{"properties":{"nodes":[{{ template "service_properties_page_1" }}],{{ template "pagination_initial_pageInfo_response" }}}}}}}`, ) testRequestTwo := autopilot.NewTestRequest( - `query ServicePropertiesList($after:String!$first:Int!$service:ID!){account{service(id: $service){properties(after: $after, first: $first){nodes{definition{id,aliases},locked,owner{... on Service{id,aliases}},validationErrors{message,path},value},{{ template "pagination_request" }}}}}}`, + `query ServicePropertiesList($after:String!$first:Int!$service:ID!){account{service(id: $service){properties(after: $after, first: $first){nodes{definition{id,aliases},locked,owner{... on Service{id,aliases},... on Team{teamAlias:alias,id}},validationErrors{message,path},value},{{ template "pagination_request" }}}}}}`, `{ {{ template "second_page_variables" }}, "service": "{{ template "id1_string" }}" }`, `{"data":{"account":{"service":{"properties":{"nodes":[{{ template "service_properties_page_2" }}],{{ template "pagination_second_pageInfo_response" }}}}}}}`, )