Skip to content

Commit

Permalink
feat: T-983-api-create-a-subscription-graphql-mutation (#63)
Browse files Browse the repository at this point in the history
* feat: T-983-api-create-a-subscription-graphql-mutation

* remove useless file
  • Loading branch information
jdenquin authored Apr 11, 2022
1 parent 813a4f8 commit 5ba69fb
Show file tree
Hide file tree
Showing 6 changed files with 249 additions and 13 deletions.
31 changes: 31 additions & 0 deletions app/graphql/mutations/subscriptions/create.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# frozen_string_literal: true

module Mutations
module Subscriptions
class Create < BaseMutation
include AuthenticableApiUser
include RequiredOrganization

graphql_name 'CreateSubscription'
description 'Create a new Subscription'

argument :customer_id, String, required: true
argument :plan_code, String, required: true

type Types::Subscriptions::Object

def resolve(**args)
validate_organization!

result = SubscriptionsService
.new
.create(
organization: current_organization,
params: args,
)

result.success? ? result.subscription : execution_error(code: result.error_code, message: result.error)
end
end
end
end
2 changes: 2 additions & 0 deletions app/graphql/types/mutation_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,7 @@ class MutationType < Types::BaseObject
field :destroy_plan, mutation: Mutations::Plans::Destroy

field :create_customer, mutation: Mutations::Customers::Create

field :create_subscription, mutation: Mutations::Subscriptions::Create
end
end
3 changes: 2 additions & 1 deletion app/graphql/types/subscriptions/object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ class Object < Types::BaseObject
graphql_name 'Subscription'

field :id, ID, null: false
field :plan, [Types::Plans::Object], null: false
field :customer, Types::Customers::Object, null: false
field :plan, Types::Plans::Object, null: false

field :status, Types::Subscriptions::StatusTypeEnum

Expand Down
25 changes: 24 additions & 1 deletion schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,18 @@ input CreatePlanInput {
vatRate: Float
}

"""
Autogenerated input type of CreateSubscription
"""
input CreateSubscriptionInput {
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
customerId: String!
planCode: String!
}

enum CurrencyEnum {
"""
Euro
Expand Down Expand Up @@ -277,6 +289,16 @@ type Mutation {
input: CreatePlanInput!
): Plan

"""
Create a new Subscription
"""
createSubscription(
"""
Parameters for CreateSubscription
"""
input: CreateSubscriptionInput!
): Subscription

"""
Deletes a Billable metric
"""
Expand Down Expand Up @@ -462,8 +484,9 @@ enum StatusTypeEnum {
type Subscription {
canceledAt: ISO8601DateTime
createdAt: ISO8601DateTime!
customer: Customer!
id: ID!
plan: [Plan!]!
plan: Plan!
startedAt: ISO8601DateTime
status: StatusTypeEnum
terminatedAt: ISO8601DateTime
Expand Down
116 changes: 105 additions & 11 deletions schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1046,6 +1046,61 @@
],
"enumValues": null
},
{
"kind": "INPUT_OBJECT",
"name": "CreateSubscriptionInput",
"description": "Autogenerated input type of CreateSubscription",
"interfaces": null,
"possibleTypes": null,
"fields": null,
"inputFields": [
{
"name": "clientMutationId",
"description": "A unique identifier for the client performing the mutation.",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "customerId",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"defaultValue": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "planCode",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"defaultValue": null,
"isDeprecated": false,
"deprecationReason": null
}
],
"enumValues": null
},
{
"kind": "ENUM",
"name": "CurrencyEnum",
Expand Down Expand Up @@ -2169,6 +2224,35 @@
}
]
},
{
"name": "createSubscription",
"description": "Create a new Subscription",
"type": {
"kind": "OBJECT",
"name": "Subscription",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null,
"args": [
{
"name": "input",
"description": "Parameters for CreateSubscription",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "INPUT_OBJECT",
"name": "CreateSubscriptionInput",
"ofType": null
}
},
"defaultValue": null,
"isDeprecated": false,
"deprecationReason": null
}
]
},
{
"name": "destroyBillableMetric",
"description": "Deletes a Billable metric",
Expand Down Expand Up @@ -3338,6 +3422,24 @@

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

]
},
{
"name": "id",
"description": null,
Expand All @@ -3363,17 +3465,9 @@
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "Plan",
"ofType": null
}
}
"kind": "OBJECT",
"name": "Plan",
"ofType": null
}
},
"isDeprecated": false,
Expand Down
85 changes: 85 additions & 0 deletions spec/graphql/mutations/subscriptions/create_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe Mutations::Plans::Create, type: :graphql do
let(:membership) { create(:membership) }
let(:organization) { membership.organization }
let(:plan) { create(:plan, organization: organization) }
let(:customer) { create(:customer, organization: organization) }
let(:mutation) do
<<~GQL
mutation($input: CreateSubscriptionInput!) {
createSubscription(input: $input) {
id,
status,
startedAt,
customer {
id
},
plan {
id
}
}
}
GQL
end

it 'creates a subscription' do
result = execute_graphql(
current_user: membership.user,
current_organization: organization,
query: mutation,
variables: {
input: {
customerId: customer.customer_id,
planCode: plan.code,
},
},
)

result_data = result['data']['createSubscription']

aggregate_failures do
expect(result_data['id']).to be_present
expect(result_data['status'].to_sym).to eq(:active)
expect(result_data['startedAt']).to be_present
expect(result_data['customer']['id']).to eq(customer.id)
expect(result_data['plan']['id']).to eq(plan.id)
end
end

context 'without current user' do
it 'returns an error' do
result = execute_graphql(
current_organization: membership.organization,
query: mutation,
variables: {
input: {
customerId: customer.customer_id,
planCode: plan.code,
},
},
)

expect_unauthorized_error(result)
end
end

context 'without current organization' do
it 'returns an error' do
result = execute_graphql(
current_user: membership.user,
query: mutation,
variables: {
input: {
customerId: customer.customer_id,
planCode: plan.code,
},
},
)

expect_forbidden_error(result)
end
end
end

0 comments on commit 5ba69fb

Please sign in to comment.