summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlessandro Desantis <desa.alessandro@gmail.com>2020-10-08 12:02:23 +0200
committerAlessandro Desantis <desa.alessandro@gmail.com>2020-10-08 13:34:54 +0200
commit1f6e8d5747f6fa995fb18443d1e264dbd779d124 (patch)
tree83940eec6d1e693cf43e4c3b95a6d2e8233b9cd8
parent0b2c5c9a3826aff11025335188cca5e2c29c51ce (diff)
Migrate to request specs for testing API controllers
-rw-r--r--.rubocop.yml4
-rw-r--r--app/controllers/solidus_subscriptions/api/v1/base_controller.rb2
-rw-r--r--app/controllers/solidus_subscriptions/api/v1/line_items_controller.rb17
-rw-r--r--app/controllers/solidus_subscriptions/api/v1/subscriptions_controller.rb8
-rw-r--r--config/routes.rb2
-rw-r--r--spec/controllers/solidus_subscriptions/api/v1/line_items_controller_spec.rb74
-rw-r--r--spec/controllers/solidus_subscriptions/api/v1/subscriptions_controller_spec.rb121
-rw-r--r--spec/requests/api/v1/line_items_spec.rb114
-rw-r--r--spec/requests/api/v1/subscriptions_spec.rb155
9 files changed, 292 insertions, 205 deletions
diff --git a/.rubocop.yml b/.rubocop.yml
index 4714d8d..48c6a23 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -2,3 +2,7 @@ inherit_from: .rubocop_todo.yml
require:
- solidus_dev_support/rubocop
+
+RSpec/DescribeClass:
+ Exclude:
+ - spec/requests/**/*
diff --git a/app/controllers/solidus_subscriptions/api/v1/base_controller.rb b/app/controllers/solidus_subscriptions/api/v1/base_controller.rb
index 0058697..a1cbb06 100644
--- a/app/controllers/solidus_subscriptions/api/v1/base_controller.rb
+++ b/app/controllers/solidus_subscriptions/api/v1/base_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module SolidusSubscriptions
module Api
module V1
diff --git a/app/controllers/solidus_subscriptions/api/v1/line_items_controller.rb b/app/controllers/solidus_subscriptions/api/v1/line_items_controller.rb
index 15d35d0..b7a2507 100644
--- a/app/controllers/solidus_subscriptions/api/v1/line_items_controller.rb
+++ b/app/controllers/solidus_subscriptions/api/v1/line_items_controller.rb
@@ -4,11 +4,13 @@ module SolidusSubscriptions
module Api
module V1
class LineItemsController < BaseController
- before_action :load_line_item, only: [:update, :destroy]
+ protect_from_forgery unless: -> { request.format.json? }
+
wrap_parameters :subscription_line_item
def update
- authorize! :update, @line_item, subscription_guest_token
+ load_line_item
+
if @line_item.update(line_item_params)
render json: @line_item.to_json
else
@@ -17,7 +19,7 @@ module SolidusSubscriptions
end
def destroy
- authorize! :destroy, @line_item, subscription_guest_token
+ load_line_item
@line_item.destroy!
@@ -30,15 +32,16 @@ module SolidusSubscriptions
private
+ def load_line_item
+ @line_item = SolidusSubscriptions::LineItem.find(params[:id])
+ authorize! action_name, @line_item, subscription_guest_token
+ end
+
def line_item_params
params.require(:subscription_line_item).permit(
SolidusSubscriptions::PermittedAttributes.subscription_line_item_attributes - [:subscribable_id]
)
end
-
- def load_line_item
- @line_item = SolidusSubscriptions::LineItem.find(params[:id])
- end
end
end
end
diff --git a/app/controllers/solidus_subscriptions/api/v1/subscriptions_controller.rb b/app/controllers/solidus_subscriptions/api/v1/subscriptions_controller.rb
index 12b46cb..4449a5d 100644
--- a/app/controllers/solidus_subscriptions/api/v1/subscriptions_controller.rb
+++ b/app/controllers/solidus_subscriptions/api/v1/subscriptions_controller.rb
@@ -4,11 +4,11 @@ module SolidusSubscriptions
module Api
module V1
class SubscriptionsController < BaseController
- before_action :load_subscription, only: [:cancel, :update, :skip]
-
protect_from_forgery unless: -> { request.format.json? }
def update
+ load_subscription
+
if @subscription.update(subscription_params)
render json: @subscription.to_json(include: [:line_items, :shipping_address, :billing_address])
else
@@ -17,6 +17,8 @@ module SolidusSubscriptions
end
def skip
+ load_subscription
+
if @subscription.skip
render json: @subscription.to_json
else
@@ -25,6 +27,8 @@ module SolidusSubscriptions
end
def cancel
+ load_subscription
+
if @subscription.cancel
render json: @subscription.to_json
else
diff --git a/config/routes.rb b/config/routes.rb
index eb4c8f3..147f747 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
SolidusSubscriptions::Engine.routes.draw do
- namespace :api do
+ namespace :api, defaults: { format: :json } do
namespace :v1 do
resources :line_items, only: [:update, :destroy]
resources :subscriptions, only: [:update] do
diff --git a/spec/controllers/solidus_subscriptions/api/v1/line_items_controller_spec.rb b/spec/controllers/solidus_subscriptions/api/v1/line_items_controller_spec.rb
deleted file mode 100644
index ab5b828..0000000
--- a/spec/controllers/solidus_subscriptions/api/v1/line_items_controller_spec.rb
+++ /dev/null
@@ -1,74 +0,0 @@
-require 'spec_helper'
-
-RSpec.describe SolidusSubscriptions::Api::V1::LineItemsController, type: :controller do
- routes { SolidusSubscriptions::Engine.routes }
-
- let!(:user) { create(:user) }
- let(:line) { create :subscription_line_item, subscription: subscription }
-
- before { user.generate_spree_api_key! }
-
- describe "#update" do
- subject { post :update, params: params }
-
- let(:params) do
- {
- id: line.id,
- subscription_line_item: { quantity: 21 },
- token: user.spree_api_key,
- format: :json
- }
- end
-
- context "when the subscription belongs to the user" do
- let(:subscription) { create :subscription, user: user }
-
- context "with valid params" do
- let(:json_body) { JSON.parse(subject.body) }
-
- it { is_expected.to be_successful }
-
- it "returns the updated record" do
- expect(json_body["quantity"]).to eq 21
- end
- end
-
- context "with invalid params" do
- let(:params) do
- {
- id: line.id,
- subscription_line_item: { quantity: -1 },
- token: user.spree_api_key,
- format: :json
- }
- end
-
- it { is_expected.to be_unprocessable }
- end
- end
-
- context "when the subscription belongs to someone else" do
- let(:subscription) { create :subscription, user: create(:user) }
-
- it { is_expected.to be_unauthorized }
- end
- end
-
- describe "#destroy" do
- subject { delete :destroy, params: params }
-
- let(:params) {
- {
- id: line.id,
- token: user.spree_api_key,
- format: :json
- }
- }
-
- context "when the subscription is not ours" do
- let(:subscription) { create :subscription, user: create(:user) }
-
- it { is_expected.to be_unauthorized }
- end
- end
-end
diff --git a/spec/controllers/solidus_subscriptions/api/v1/subscriptions_controller_spec.rb b/spec/controllers/solidus_subscriptions/api/v1/subscriptions_controller_spec.rb
deleted file mode 100644
index 2c9007f..0000000
--- a/spec/controllers/solidus_subscriptions/api/v1/subscriptions_controller_spec.rb
+++ /dev/null
@@ -1,121 +0,0 @@
-require 'spec_helper'
-
-RSpec.describe SolidusSubscriptions::Api::V1::SubscriptionsController do
- routes { SolidusSubscriptions::Engine.routes }
-
- let!(:user) { create :user }
-
- before { user.generate_spree_api_key! }
-
- shared_examples "an authenticated subscription" do
- context "when the subscription belongs to user" do
- let!(:subscription) do
- create(
- :subscription,
- :with_line_item,
- actionable_date: (Date.current + 1.month ),
- user: user
- )
- end
-
- it { is_expected.to be_successful }
- end
-
- context "when the subscription belongs to someone else" do
- let!(:subscription) { create :subscription, user: create(:user) }
-
- it { is_expected.to be_unauthorized }
- end
-
- context 'when the subscription is canceled' do
- let!(:subscription) { create :subscription, user: user, state: 'canceled' }
-
- it { is_expected.to be_unprocessable }
- end
- end
-
- describe 'PATCH :update' do
- subject { patch :update, params: params }
-
- let(:params) do
- {
- id: subscription.id,
- token: user.spree_api_key,
- subscription: subscription_params
- }
- end
-
- let(:address_country) { create(:country) }
- let(:address_state) { create(:state, country: address_country) }
-
- let(:subscription_params) do
- {
- line_items_attributes: [{
- id: subscription.line_items.first.id,
- quantity: 6
- }],
- shipping_address_attributes: {
- firstname: 'Ash',
- lastname: 'Ketchum',
- address1: '1 Rainbow Road',
- city: 'Palette Town',
- country_id: address_country.id,
- state_id: address_state.id,
- phone: '999-999-999',
- zipcode: '10001'
- },
- billing_address_attributes: {
- firstname: 'Ash',
- lastname: 'Ketchum',
- address1: '1 Rainbow Road',
- city: 'Palette Town',
- country_id: address_country.id,
- state_id: address_state.id,
- phone: '999-999-999',
- zipcode: '10001'
- }
- }
- end
-
- context 'when the subscription belongs to the user' do
- let!(:subscription) { create :subscription, :with_line_item, user: user }
-
- it { is_expected.to be_successful }
-
- context 'when the params are not valid' do
- let(:subscription_params) do
- {
- line_items_attributes: [{
- id: subscription.line_items.first.id,
- quantity: -6
- }]
- }
- end
-
- it { is_expected.to have_http_status(:unprocessable_entity) }
- end
- end
-
- context 'when the subscription belongs to someone else' do
- let!(:subscription) { create :subscription, :with_line_item, user: create(:user) }
-
- it { is_expected.to be_unauthorized }
- end
- end
-
- describe "POST :skip" do
- subject { post :skip, params: params }
-
- let(:params) { { id: subscription.id, token: user.spree_api_key } }
-
- it_behaves_like "an authenticated subscription"
- end
-
- describe "POST :cancel" do
- subject { post :cancel, params: params }
-
- let(:params) { { id: subscription.id, token: user.spree_api_key } }
-
- it_behaves_like "an authenticated subscription"
- end
-end
diff --git a/spec/requests/api/v1/line_items_spec.rb b/spec/requests/api/v1/line_items_spec.rb
new file mode 100644
index 0000000..c6e34e6
--- /dev/null
+++ b/spec/requests/api/v1/line_items_spec.rb
@@ -0,0 +1,114 @@
+RSpec.describe '/api/v1/line_items' do
+ include SolidusSubscriptions::Engine.routes.url_helpers
+
+ describe 'PATCH /:id' do
+ context 'when the subscription belongs to the user' do
+ context 'with valid params' do
+ it 'responds with 200 OK' do
+ user = create(:user, &:generate_spree_api_key!)
+ subscription = create(:subscription, user: user)
+ line_item = create(:subscription_line_item, subscription: subscription)
+
+ patch(
+ api_v1_line_item_path(line_item),
+ params: { subscription_line_item: { quantity: 11 } },
+ headers: { 'Authorization' => "Bearer #{user.spree_api_key}" },
+ )
+
+ expect(response.status).to eq(200)
+ end
+
+ it 'updates the line item' do
+ user = create(:user, &:generate_spree_api_key!)
+ subscription = create(:subscription, user: user)
+ line_item = create(:subscription_line_item, subscription: subscription)
+
+ patch(
+ api_v1_line_item_path(line_item),
+ params: { subscription_line_item: { quantity: 11 } },
+ headers: { 'Authorization' => "Bearer #{user.spree_api_key}" },
+ )
+
+ expect(line_item.reload.quantity).to eq(11)
+ end
+ end
+
+ context 'with invalid params' do
+ it 'responds with 422 Unprocessable Entity' do
+ user = create(:user, &:generate_spree_api_key!)
+ subscription = create(:subscription, user: user)
+ line_item = create(:subscription_line_item, subscription: subscription)
+
+ patch(
+ api_v1_line_item_path(line_item),
+ params: { subscription_line_item: { quantity: -1 } },
+ headers: { 'Authorization' => "Bearer #{user.spree_api_key}" },
+ )
+
+ expect(response.status).to eq(422)
+ end
+ end
+ end
+
+ context 'when the subscription does not belong to the user' do
+ it 'responds with 401 Unauthorized' do
+ user = create(:user, &:generate_spree_api_key!)
+ subscription = create(:subscription)
+ line_item = create(:subscription_line_item, subscription: subscription)
+
+ patch(
+ api_v1_line_item_path(line_item),
+ params: { subscription_line_item: { quantity: 11 } },
+ headers: { 'Authorization' => "Bearer #{user.spree_api_key}" },
+ )
+
+ expect(response.status).to eq(401)
+ end
+ end
+ end
+
+ describe 'DELETE /:id' do
+ context 'when the subscription belongs to the user' do
+ it 'responds with 200 OK' do
+ user = create(:user, &:generate_spree_api_key!)
+ subscription = create(:subscription, user: user)
+ line_item = create(:subscription_line_item, subscription: subscription)
+
+ delete(
+ api_v1_line_item_path(line_item),
+ headers: { 'Authorization' => "Bearer #{user.spree_api_key}" },
+ )
+
+ expect(response.status).to eq(200)
+ end
+
+ it 'deletes the line item' do
+ user = create(:user, &:generate_spree_api_key!)
+ subscription = create(:subscription, user: user)
+ line_item = create(:subscription_line_item, subscription: subscription)
+
+ delete(
+ api_v1_line_item_path(line_item),
+ headers: { 'Authorization' => "Bearer #{user.spree_api_key}" },
+ )
+
+ expect { line_item.reload }.to raise_error(ActiveRecord::RecordNotFound)
+ end
+ end
+
+ context 'when the subscription does not belong to the user' do
+ it 'responds with 401 Unauthorized' do
+ user = create(:user, &:generate_spree_api_key!)
+ subscription = create(:subscription)
+ line_item = create(:subscription_line_item, subscription: subscription)
+
+ delete(
+ api_v1_line_item_path(line_item),
+ headers: { 'Authorization' => "Bearer #{user.spree_api_key}" },
+ )
+
+ expect(response.status).to eq(401)
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/v1/subscriptions_spec.rb b/spec/requests/api/v1/subscriptions_spec.rb
new file mode 100644
index 0000000..0406ea7
--- /dev/null
+++ b/spec/requests/api/v1/subscriptions_spec.rb
@@ -0,0 +1,155 @@
+RSpec.describe '/api/v1/subscriptions' do
+ include SolidusSubscriptions::Engine.routes.url_helpers
+
+ describe 'PATCH /:id' do
+ context 'when the subscription belongs to the user' do
+ context 'with valid params' do
+ it 'responds with 200 OK' do
+ user = create(:user, &:generate_spree_api_key!)
+ subscription = create(:subscription, user: user)
+
+ patch(
+ api_v1_subscription_path(subscription),
+ params: { subscription: { interval_length: 11 } },
+ headers: { 'Authorization' => "Bearer #{user.spree_api_key}" },
+ )
+
+ expect(response.status).to eq(200)
+ end
+
+ it 'updates the subscription' do
+ user = create(:user, &:generate_spree_api_key!)
+ subscription = create(:subscription, user: user)
+
+ patch(
+ api_v1_subscription_path(subscription),
+ params: { subscription: { interval_length: 11 } },
+ headers: { 'Authorization' => "Bearer #{user.spree_api_key}" },
+ )
+
+ expect(subscription.reload.interval_length).to eq(11)
+ end
+ end
+
+ context 'with invalid params' do
+ it 'responds with 422 Unprocessable Entity' do
+ user = create(:user, &:generate_spree_api_key!)
+ subscription = create(:subscription, user: user)
+
+ patch(
+ api_v1_subscription_path(subscription),
+ params: { subscription: { interval_length: -1 } },
+ headers: { 'Authorization' => "Bearer #{user.spree_api_key}" },
+ )
+
+ expect(response.status).to eq(422)
+ end
+ end
+ end
+
+ context 'when the subscription does not belong to the user' do
+ it 'responds with 401 Unauthorized' do
+ user = create(:user, &:generate_spree_api_key!)
+ subscription = create(:subscription)
+
+ patch(
+ api_v1_subscription_path(subscription),
+ params: { subscription: { interval_length: 11 } },
+ headers: { 'Authorization' => "Bearer #{user.spree_api_key}" },
+ )
+
+ expect(response.status).to eq(401)
+ end
+ end
+ end
+
+ describe 'POST /:id/skip' do
+ context 'when the subscription belongs to the user' do
+ it 'responds with 200 OK' do
+ user = create(:user, &:generate_spree_api_key!)
+ subscription = create(:subscription, user: user)
+
+ post(
+ skip_api_v1_subscription_path(subscription),
+ headers: { 'Authorization' => "Bearer #{user.spree_api_key}" },
+ )
+
+ expect(response.status).to eq(200)
+ end
+
+ it 'skips the subscription' do
+ user = create(:user, &:generate_spree_api_key!)
+ subscription = create(
+ :subscription,
+ user: user,
+ interval_length: 1,
+ interval_units: 'week',
+ actionable_date: Time.zone.today,
+ )
+
+ post(
+ skip_api_v1_subscription_path(subscription),
+ headers: { 'Authorization' => "Bearer #{user.spree_api_key}" },
+ )
+
+ expect(subscription.reload.actionable_date).to eq(Time.zone.today + 1.week)
+ end
+ end
+
+ context 'when the subscription does not belong to the user' do
+ it 'responds with 401 Unauthorized' do
+ user = create(:user, &:generate_spree_api_key!)
+ subscription = create(:subscription)
+
+ post(
+ skip_api_v1_subscription_path(subscription),
+ headers: { 'Authorization' => "Bearer #{user.spree_api_key}" },
+ )
+
+ expect(response.status).to eq(401)
+ end
+ end
+ end
+
+ describe 'POST /:id/cancel' do
+ context 'when the subscription belongs to the user' do
+ it 'responds with 200 OK' do
+ user = create(:user, &:generate_spree_api_key!)
+ subscription = create(:subscription, user: user)
+
+ post(
+ cancel_api_v1_subscription_path(subscription),
+ headers: { 'Authorization' => "Bearer #{user.spree_api_key}" },
+ )
+
+ expect(response.status).to eq(200)
+ end
+
+ it 'cancels the subscription' do
+ user = create(:user, &:generate_spree_api_key!)
+ subscription = create(:subscription, user: user)
+
+ post(
+ cancel_api_v1_subscription_path(subscription),
+ headers: { 'Authorization' => "Bearer #{user.spree_api_key}" },
+ )
+
+ expect(subscription.reload.state).to eq('canceled')
+ end
+ end
+
+ context 'when the subscription does not belong to the user' do
+ it 'responds with 401 Unauthorized' do
+ user = create(:user, &:generate_spree_api_key!)
+ subscription = create(:subscription)
+
+ post(
+ cancel_api_v1_subscription_path(subscription),
+ headers: { 'Authorization' => "Bearer #{user.spree_api_key}" },
+ )
+
+ expect(response.status).to eq(401)
+ end
+ end
+ end
+end