diff options
author | Alessandro Desantis <desa.alessandro@gmail.com> | 2020-10-08 12:02:23 +0200 |
---|---|---|
committer | Alessandro Desantis <desa.alessandro@gmail.com> | 2020-10-08 13:34:54 +0200 |
commit | 1f6e8d5747f6fa995fb18443d1e264dbd779d124 (patch) | |
tree | 83940eec6d1e693cf43e4c3b95a6d2e8233b9cd8 | |
parent | 0b2c5c9a3826aff11025335188cca5e2c29c51ce (diff) |
Migrate to request specs for testing API controllers
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 |