Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: T-952 Add a new GraphQL query to expose a single customer #61

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions app/graphql/resolvers/customer_resolver.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true

module Resolvers
class CustomerResolver < GraphQL::Schema::Resolver
include AuthenticableApiUser
include RequiredOrganization

description 'Query a single customer of an organization'

argument :id, ID, required: true, description: 'Uniq ID of the customer'

type Types::Customers::SingleObject, null: true

def resolve(id: nil)
validate_organization!

current_organization.customers.find_by(id: id)
end
end
end
2 changes: 0 additions & 2 deletions app/graphql/types/customers/object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ class Object < Types::BaseObject
graphql_name 'Customer'

field :id, ID, null: false
field :subscriptions, [Types::Subscriptions::Object]
field :invoices, [Types::Invoices::Object]

field :customer_id, String, null: false
field :name, String
Expand Down
13 changes: 13 additions & 0 deletions app/graphql/types/customers/single_object.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

module Types
module Customers
class SingleObject < Types::BaseObject
graphql_name 'CustomerDetails'

field :customer, Types::Customers::Object, method: :itself
field :subscriptions, [Types::Subscriptions::Object]
field :invoices, [Types::Invoices::Object]
end
end
end
1 change: 1 addition & 0 deletions app/graphql/types/query_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class QueryType < Types::BaseObject

field :billable_metrics, resolver: Resolvers::BillableMetricsResolver
field :customers, resolver: Resolvers::CustomersResolver
field :customer, resolver: Resolvers::CustomerResolver
field :plans, resolver: Resolvers::PlansResolver
end
end
18 changes: 16 additions & 2 deletions schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,7 @@ type Customer {
createdAt: ISO8601DateTime!
customerId: String!
id: ID!
invoices: [Invoice!]
name: String
subscriptions: [Subscription!]
updatedAt: ISO8601DateTime!
}

Expand All @@ -137,6 +135,12 @@ type CustomerCollection {
metadata: CollectionMetadata!
}

type CustomerDetails {
customer: Customer
invoices: [Invoice!]
subscriptions: [Subscription!]
}

"""
Autogenerated input type of DestroyBillableMetric
"""
Expand Down Expand Up @@ -388,6 +392,16 @@ type Query {
"""
currentUser: User!

"""
Query a single customer of an organization
"""
customer(
"""
Uniq ID of the customer
"""
id: ID!
): CustomerDetails

"""
Query customers of an organization
"""
Expand Down
140 changes: 98 additions & 42 deletions schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1133,20 +1133,12 @@
]
},
{
"name": "invoices",
"name": "name",
"description": null,
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "Invoice",
"ofType": null
}
}
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null,
Expand All @@ -1155,32 +1147,53 @@
]
},
{
"name": "name",
"name": "updatedAt",
"description": null,
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ISO8601DateTime",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null,
"args": [

]
},
}
],
"inputFields": null,
"enumValues": null
},
{
"kind": "OBJECT",
"name": "CustomerCollection",
"description": null,
"interfaces": [

],
"possibleTypes": null,
"fields": [
{
"name": "subscriptions",
"name": "collection",
"description": null,
"type": {
"kind": "LIST",
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "NON_NULL",
"kind": "LIST",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "Subscription",
"ofType": null
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "Customer",
"ofType": null
}
}
}
},
Expand All @@ -1191,14 +1204,14 @@
]
},
{
"name": "updatedAt",
"name": "metadata",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ISO8601DateTime",
"kind": "OBJECT",
"name": "CollectionMetadata",
"ofType": null
}
},
Expand All @@ -1214,30 +1227,40 @@
},
{
"kind": "OBJECT",
"name": "CustomerCollection",
"name": "CustomerDetails",
"description": null,
"interfaces": [

],
"possibleTypes": null,
"fields": [
{
"name": "collection",
"name": "customer",
"description": null,
"type": {
"kind": "NON_NULL",
"kind": "OBJECT",
"name": "Customer",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null,
"args": [

]
},
{
"name": "invoices",
"description": null,
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "LIST",
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "Customer",
"ofType": null
}
"kind": "OBJECT",
"name": "Invoice",
"ofType": null
}
}
},
Expand All @@ -1248,15 +1271,19 @@
]
},
{
"name": "metadata",
"name": "subscriptions",
"description": null,
"type": {
"kind": "NON_NULL",
"kind": "LIST",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "CollectionMetadata",
"ofType": null
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "Subscription",
"ofType": null
}
}
},
"isDeprecated": false,
Expand Down Expand Up @@ -2820,6 +2847,35 @@

]
},
{
"name": "customer",
"description": "Query a single customer of an organization",
"type": {
"kind": "OBJECT",
"name": "CustomerDetails",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null,
"args": [
{
"name": "id",
"description": "Uniq ID of the customer",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
},
"defaultValue": null,
"isDeprecated": false,
"deprecationReason": null
}
]
},
{
"name": "customers",
"description": "Query customers of an organization",
Expand Down
59 changes: 59 additions & 0 deletions spec/graphql/resolvers/customer_resolver_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe Resolvers::CustomerResolver, type: :graphql do
let(:query) do
<<~GQL
query($customerId: ID!) {
customer(id: $customerId) {
customer { id customerId name }
invoices { id }
subscriptions { id }
}
}
GQL
end

let(:membership) { create(:membership) }
let(:organization) { membership.organization }
let(:customer) do
create(:customer, organization: organization)
end

it 'returns a single of customer' do
result = execute_graphql(
current_user: membership.user,
current_organization: organization,
query: query,
variables: {
customerId: customer.id,
},
)

customer_response = result['data']['customer']

aggregate_failures do
expect(customer_response['customer']['id']).to eq(customer.id)
expect(customer_response['subscriptions'].count).to eq(0)
expect(customer_response['invoices'].count).to eq(0)
end
end

context 'without current organization' do
it 'returns an error' do
result = execute_graphql(
current_user: membership.user,
query: query,
variables: {
customerId: customer.id,
},
)

expect_graphql_error(
result: result,
message: 'Missing organization id',
)
end
end
end
2 changes: 1 addition & 1 deletion spec/graphql/resolvers/customers_resolver_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

require 'rails_helper'

RSpec.describe Resolvers::PlansResolver, type: :graphql do
RSpec.describe Resolvers::CustomersResolver, type: :graphql do
let(:query) do
<<~GQL
query {
Expand Down