Created
April 15, 2015 15:32
-
-
Save zaeem/616174e5c461a208e001 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'spec_helper' | |
describe CartsController do | |
include Fdoc::SpecWatcher | |
it_behaves_like "a base cart controller", "carts", "/:id" | |
let(:sku){mock_sku} | |
let(:sku_2){mock_sku(id:20, code:'FLB-R-M', current_retail_price:Money.new(1900), current_sale_price:Money.new(1800), | |
current_stylist_price:Money.new(900), pqv:2800, display_category_ids:[1,2,3])} | |
let(:sku_3){mock_sku(id:1, code:'FLB-R-M', current_retail_price:Money.new(1900), current_sale_price:Money.new(1800), | |
current_stylist_price:Money.new(900), pqv:2800, display_category_ids:[1,2,3], product_type:"StarterKitProduct", | |
best_valued: true)} | |
let(:bundle) { mock_bundle } | |
let(:bundle_error) { mock_bundle({errors: double(messages: {'base' => ["Sku not part of bundle"]})}, 2) } | |
before do | |
CatalogService.stub(:get_sku).with(sku.id).and_return(sku) | |
CatalogService.stub(:get_sku).with(sku_2.id).and_return(sku_2) | |
CatalogService.stub(:get_sku).with(sku_3.id).and_return(sku_3) | |
CatalogService.stub(:starter_kits).and_return([sku_3]) | |
CatalogService.stub(:build_bundle).with(bundle.code, [bundle.skus.first.id]).and_return(bundle) | |
CatalogService.stub(:build_bundle).with(bundle_error.code, bundle_error.skus.map(&:id)).and_return(bundle_error) | |
@items = [] | |
InventoryService.stub(:in_stock?).with(any_args).and_return(true) | |
PromotionService.stub(:evaluate).and_return(double(items: [])) | |
UserService.stub(:get_user).and_return({"receive_marketing_emails_at" => "2014-07-17T14:20:11.000Z"}) | |
end | |
describe "DSR endpoints" do | |
before do | |
request.stub(:headers).and_return({"X-Rosi-Platform" => platform_key, "X-Rosi-Auth" => "abc"}) | |
@user = sign_in(User.new(id:1, role:"dsr", phone_number:"1234567890", email:"[email protected]", first_name:"Jane", last_name:"Doe")) | |
MyBusinessService.stub(:find_contact).and_return({}) | |
end | |
describe "destroy", fdoc: "cart_service/carts/:id" do | |
before do | |
UserService.stub(:credits).and_return({"store_credits"=>500, "hostess_credits"=>0, | |
"hostess_discounts_hash"=>{"count"=>0, "percentage"=>50}}) | |
@cart = FactoryGirl.create(:cart_with_items, store_credits_total:5) | |
end | |
it "should mark cart as 'pending_removal' but not delete it from database" do | |
delete :destroy, id: @cart.id, format: :json | |
expect(response).to be_success | |
@cart.reload | |
expect(@cart).to_not be_nil | |
expect(@cart.workflow_state).to eq("pending_removal") | |
end | |
end | |
describe "not_imported" do | |
before do | |
@cart = FactoryGirl.create(:cart_with_items, dsr_id: 1, workflow_state: "active") | |
end | |
context "valid", fdoc: 'cart_service/carts/not_imported' do | |
it "should return carts which are not imported yet" do | |
get :not_imported, format: :json | |
expect(response).to be_success | |
json_cart = JSON.parse(response.body) | |
expect(json_cart).to_not be_nil | |
end | |
end | |
end | |
describe "create" do | |
before do | |
@cart_create_params = {customer_first_name:"Jane", customer_last_name:"Doe", customer_email:"[email protected]", | |
customer_id:27, type_code:"dsr_customer", contact_id: 1, | |
billing_address_attributes: { | |
address1:"111 Sherbrook Drive", city:"Berkeley Heights", | |
state:"NJ", zip_code:"07922", first_name:"Jane", last_name:"Doe", phone:"123 4567 890"}, | |
format: :json} | |
end | |
context "valid call", fdoc: "cart_service/carts" do | |
it "it require customer_id and type_code parameters" do | |
post :create, customer_first_name:"Jane", customer_last_name:"Doe", customer_email:"[email protected]", format: :json | |
expect(response.status).to eq(422) | |
errors = JSON.parse(response.body) | |
expect(errors['fields']).to include('type_code') | |
expect(errors['fields']).to include('customer_id') | |
end | |
it "should respond with cart json representation (details can be tested in view spec)" do | |
post :create, @cart_create_params | |
expect(response).to be_success | |
json_cart = JSON.parse(response.body) | |
expect(json_cart).to_not be_nil | |
end | |
it "should accept shipping address" do | |
shipping_address_params = {address1:"111 Sherbrook Drive", city:"Berkeley Heights", | |
state:"NJ", zip_code:"07922", first_name:"Jane", last_name:"Doe", phone:"123 4567 890"} | |
post :create, @cart_create_params.merge({shipping_address_attributes: shipping_address_params}) | |
expect(response).to be_success | |
json_cart = JSON.parse(response.body) | |
expect(Cart.find(json_cart["id"]).shipping_address).not_to be_nil | |
expect(Cart.find(json_cart["id"]).shipping_address.address1).to eq("111 Sherbrook Drive") | |
end | |
it "should accept billing address" do | |
billing_address_params = {address1:"111 Sherbrook Drive", city:"Berkeley Heights", | |
state:"NJ", zip_code:"07922", first_name:"Jane", last_name:"Doe", phone:"123 4567 890"} | |
post :create, @cart_create_params.merge({billing_address_attributes: billing_address_params}) | |
expect(response).to be_success | |
json_cart = JSON.parse(response.body) | |
expect(Cart.find(json_cart["id"]).billing_address).not_to be_nil | |
expect(Cart.find(json_cart["id"]).billing_address.address1).to eq("111 Sherbrook Drive") | |
end | |
it "should validate shipping attributes if shipping_address_attributes is included" do | |
post :create, @cart_create_params.merge({shipping_address_attributes: {}}) | |
expect(response.status).to eq(422) | |
errors = JSON.parse(response.body) | |
expect(errors["fields"]).to match_array ["shipping_address.address1","shipping_address.city","shipping_address.state", | |
"shipping_address.zip_code", "shipping_address.first_name", "shipping_address.last_name", "shipping_address.phone"] | |
end | |
it "should validate billing attributes if billing_address_attributes is included" do | |
post :create, @cart_create_params.merge({billing_address_attributes: {}}) | |
expect(response.status).to eq(422) | |
errors = JSON.parse(response.body) | |
expect(errors["fields"]).to match_array ["billing_address.address1","billing_address.city","billing_address.state", | |
"billing_address.zip_code", "billing_address.first_name", "billing_address.last_name"] | |
end | |
context "when cart type is DSR" do | |
before do | |
@cart_create_params[:type_code]= "dsr" | |
expect(@user).to receive(:reload_user).and_return(@user) | |
end | |
it "should discard customer_name field and use DSR data" do | |
post :create, @cart_create_params | |
expect(response).to be_success | |
json_cart = JSON.parse(response.body) | |
expect(json_cart["customer_first_name"]).to eq(@user.first_name) | |
end | |
end | |
context "when cart type is StarterKit", platform: "keep" do | |
before do | |
@cart_create_params[:type_code]= "starter_kit" | |
expect(@user).to receive(:reload_user).and_return(@user) | |
end | |
it "should discard customer_name field and use DSR data" do | |
post :create, @cart_create_params | |
expect(response).to be_success | |
json_cart = JSON.parse(response.body) | |
expect(json_cart["customer_first_name"]).to eq(@user.first_name) | |
expect(json_cart["type_code"]).to eq("starter_kit") | |
end | |
it "should automatically have the best valued startert_kit_product added" do | |
post :create, @cart_create_params | |
expect(response).to be_success | |
json_cart = JSON.parse(response.body) | |
expect(json_cart['items'].size).to eq(1) | |
expect(json_cart['items'].first['sku_id']).to eq(1) | |
end | |
end | |
end | |
it "should disregard public_order_id value" do | |
post :create, @cart_create_params.merge({public_order_id:888}) | |
expect(response).to be_success | |
json_cart = JSON.parse(response.body) | |
expect(json_cart["public_order_id"]).to eq json_cart["id"] | |
end | |
end | |
context "when there exists a cart for the customer" do | |
before do | |
UserService.stub(:credits).and_return({"store_credits"=>500, "hostess_credits"=>0, | |
"hostess_discounts_hash"=>{"count"=>0, "percentage"=>50}}) | |
@cart = FactoryGirl.create(:cart_with_items, store_credits_total:5) | |
end | |
describe "show", fdoc: "cart_service/carts/:id" do | |
it "should return not found if cart is not found" do | |
get :show, id: 99, format: :json | |
expect(response.status).to eq(404) | |
errors = JSON.parse(response.body)['errors'] | |
expect(errors).to eq("Cart not found") | |
end | |
it "should return not found if cart is status is not editable" do | |
@cart.workflow_state = "pending_removal" | |
@cart.save | |
get :show, id: @cart.id, format: :json | |
expect(response.status).to eq(404) | |
errors = JSON.parse(response.body)['errors'] | |
expect(errors).to eq("Cart not found") | |
end | |
end | |
describe "create", fdoc: "cart_service/carts" do | |
it "should return existing cart from customer" do | |
post :create, customer_first_name:@cart.customer_first_name, customer_last_name:@cart.customer_last_name, | |
customer_email:@cart.customer_email, customer_id:@cart.customer_id, type_code:@cart.type_code, format: :json | |
expect(response).to be_success | |
json_cart = JSON.parse(response.body) | |
expect(json_cart["id"]).to eq(@cart.id) | |
end | |
end | |
describe "remove_bundle", fdoc: 'cart_service/carts/:id/remove_bundle' do | |
before do | |
@cart = FactoryGirl.create(:cart_with_bundle, store_credits_total:5) | |
current_user.stub_chain(:carts, :editable, :includes, :find).and_return(@cart) | |
expect(@cart).to receive(:update_totals).and_call_original | |
end | |
it "should remove the bundle" do | |
delete :remove_bundle, bundle_id: @cart.cart_items.first.bundle_id, id: @cart.id, format: :json | |
json_cart = JSON.parse(response.body) | |
expect(@cart.cart_items.count).to eq(0) | |
expect(response).to be_success | |
end | |
end | |
describe "add_bundle", fdoc: 'cart_service/carts/:id/add_bundle' do | |
it "should show unprocessable_entity error if quantity is greater than or equal to 100" do | |
sku_ids = bundle.skus.map(&:id) | |
post :add_bundle, id: @cart.id, code: bundle.code, sku_ids: sku_ids, quantity: 100, format: :json | |
expect(response.status).to eq(422) | |
errors = JSON.parse(response.body)['errors'] | |
expect(errors['base']).to include("quantity should be less than the product's maximum purchasable quantity: 100") | |
end | |
it "should show unprocessable_entity error if quantity is less or equal than 0" do | |
post :add_bundle, id: @cart.id, code: bundle.code, sku_ids: [1], quantity: 0, format: :json | |
expect(response.status).to eq(422) | |
errors = JSON.parse(response.body)['errors'] | |
expect(errors['base']).to include('quantity should be greater than zero') | |
end | |
it "it should show unprocessable_entity error if bundle is not valid" do | |
post :add_bundle, id: @cart.id, code: bundle_error.code, sku_ids:bundle_error.skus.map(&:id), quantity: 1, format: :json | |
expect(response.status).to eq(422) | |
errors = JSON.parse(response.body)['errors'] | |
expect(errors['base']).to include('Sku not part of bundle') | |
end | |
describe "successful calls" do | |
before do | |
current_user.stub_chain(:carts, :editable, :includes, :find).and_return(@cart) | |
expect(@cart).to receive(:update_totals).and_call_original | |
end | |
it "should add all sku_ids" do | |
quantity = 1 | |
sku_ids = bundle.skus.map(&:id) | |
old_size = @cart.cart_items.size | |
post :add_bundle, id: @cart.id, code: bundle.code, sku_ids: sku_ids, quantity: quantity, format: :json | |
expect(response).to be_success | |
json_cart = JSON.parse(response.body) | |
expect(json_cart['items'].size).to eq(old_size+(quantity * sku_ids.size)) | |
expect(json_cart['items'].count{|cart_item| cart_item['sku_id'] == sku_ids.first}).to eq(quantity) | |
end | |
end | |
end | |
describe "add_sku", fdoc: "cart_service/carts/:id/add_sku" do | |
it "should return not found if cart is not found" do | |
post :add_sku, id:99, sku_id: sku.id, format: :json | |
expect(response.status).to eq(404) | |
errors = JSON.parse(response.body)['errors'] | |
expect(errors).to eq("Cart not found") | |
end | |
it "should return not found if cart is status is not editable" do | |
@cart.workflow_state = "pending_removal" | |
@cart.save | |
post :add_sku, id:@cart.id, sku_id: sku.id, format: :json | |
expect(response.status).to eq(404) | |
errors = JSON.parse(response.body)['errors'] | |
expect(errors).to eq("Cart not found") | |
end | |
end | |
describe "remove_sku", fdoc: "cart_service/carts/:id/remove_sku" do | |
it "should return not found if cart is not found" do | |
delete :remove_sku, id:99, sku_id: sku.id, format: :json | |
expect(response.status).to eq(404) | |
errors = JSON.parse(response.body)['errors'] | |
expect(errors).to eq("Cart not found") | |
end | |
it "should return not found if cart is status is not editable" do | |
@cart.workflow_state = "pending_removal" | |
@cart.save | |
delete :remove_sku, id:@cart.id, sku_id: sku.id, format: :json | |
expect(response.status).to eq(404) | |
errors = JSON.parse(response.body)['errors'] | |
expect(errors).to eq("Cart not found") | |
end | |
end | |
describe "set_sku_quantity", fdoc: "cart_service/carts/:id/set_sku_quantity" do | |
describe "error handling" do | |
it "should return not found if cart is not found" do | |
patch :set_sku_quantity, id:99, sku_id: sku.id, format: :json | |
expect(response.status).to eq(404) | |
errors = JSON.parse(response.body)['errors'] | |
expect(errors).to eq("Cart not found") | |
end | |
it "should return not found if cart is status is not editable" do | |
@cart.workflow_state = "pending_removal" | |
@cart.save | |
patch :set_sku_quantity, id:@cart.id, sku_id: sku.id, format: :json | |
expect(response.status).to eq(404) | |
errors = JSON.parse(response.body)['errors'] | |
expect(errors).to eq("Cart not found") | |
end | |
end | |
end | |
describe "destroy", fdoc: "cart_service/carts/:id" do | |
it "should return not found if cart is not found" do | |
delete :destroy, id: 99, format: :json | |
expect(response.status).to eq(404) | |
errors = JSON.parse(response.body)['errors'] | |
expect(errors).to eq("Cart not found") | |
end | |
it "should return not found if cart is status is not editable" do | |
@cart.workflow_state = "pending_removal" | |
@cart.save | |
delete :destroy, id: @cart.id, format: :json | |
expect(response.status).to eq(404) | |
errors = JSON.parse(response.body)['errors'] | |
expect(errors).to eq("Cart not found") | |
end | |
end | |
describe "checkout_status", fdoc: "cart_service/carts/:id/checkout_status" do | |
it "should return not found if cart is not found" do | |
get :checkout_status, id: 99, format: :json | |
expect(response.status).to eq(404) | |
errors = JSON.parse(response.body)['errors'] | |
expect(errors).to eq("Cart not found") | |
end | |
context "when cart is removed" do | |
before do | |
@cart.update_attribute(:workflow_state, "pending_removal") | |
end | |
it "should return not found if cart is status is not editable" do | |
get :checkout_status, id: @cart.id, format: :json | |
expect(response.status).to eq(404) | |
errors = JSON.parse(response.body)['errors'] | |
expect(errors).to eq("Cart not found") | |
end | |
end | |
end | |
describe "hostess_credits", fdoc: 'cart_service/carts/:id/hostess_credits' do | |
before do | |
UserService.stub(:credits).and_return({"store_credits"=>1, "hostess_credits"=>1000, | |
"hostess_discounts_hash"=>{"count"=>1, "percentage"=>50}}) | |
@cart = FactoryGirl.create(:dsr_hostess_cart) | |
FactoryGirl.create_list(:cart_item,2,cart:@cart, sku_id:sku.id,price_cents:1800) | |
@cart.update_totals | |
end | |
it "should return not found if cart is not found" do | |
post :hostess_credits, id: 99, format: :json | |
expect(response.status).to eq(404) | |
errors = JSON.parse(response.body)['errors'] | |
expect(errors).to eq("Cart not found") | |
end | |
it "should show correctly the new hostess_credits_total" do | |
post :hostess_credits, id:@cart.id, amount:1000, format: :json | |
expect(response).to be_success | |
json_cart = JSON.parse(response.body) | |
expect(json_cart["hostess_credits_total"]["cents"]).to eq 1000 | |
end | |
context "when there is not enough balance" do | |
it "should render error response" do | |
post :hostess_credits, id:@cart.id, amount:1500, format: :json | |
expect(response.status).to eq(422) | |
error_hash = JSON.parse(response.body)["errors"] | |
expect(error_hash["hostess_credits_total_cents"]).to include("Available user credits are exceeded") | |
end | |
end | |
end | |
describe "product_credits", fdoc: 'cart_service/carts/:id/product_credits' do | |
before do | |
UserService.stub(:credits).and_return({"store_credits"=>1, "hostess_credits"=>1000, "product_credits" => 1000, | |
"hostess_discounts_hash"=>{"count"=>1, "percentage"=>50}}) | |
@cart = FactoryGirl.create(:dsr_cart) | |
FactoryGirl.create_list(:cart_item,2,cart:@cart, sku_id:sku.id,price_cents:1800) | |
@cart.update_totals | |
end | |
it "should return not found if cart is not found" do | |
post :product_credits, id: 99, format: :json | |
expect(response.status).to eq(404) | |
errors = JSON.parse(response.body)['errors'] | |
expect(errors).to eq("Cart not found") | |
end | |
it "should show correctly the new product_credits_total" do | |
post :product_credits, id:@cart.id, amount:1000, format: :json | |
expect(response).to be_success | |
json_cart = JSON.parse(response.body) | |
expect(json_cart["product_credits_total"]["cents"]).to eq 1000 | |
end | |
context "when there is not enough balance" do | |
it "should render error response" do | |
post :product_credits, id:@cart.id, amount:1500, format: :json | |
expect(response.status).to eq(422) | |
error_hash = JSON.parse(response.body)["errors"] | |
expect(error_hash["product_credits_total_cents"]).to include("Available user credits are exceeded") | |
end | |
end | |
end | |
describe "store_credits", fdoc: 'cart_service/carts/:id/store_credits' do | |
before do | |
UserService.stub(:credits).and_return({"store_credits"=>1000, "hostess_credits"=>1, | |
"hostess_discounts_hash"=>{"count"=>1, "percentage"=>50}}) | |
end | |
it "should return not found if cart is not found" do | |
post :store_credits, id: 99, format: :json | |
expect(response.status).to eq(404) | |
errors = JSON.parse(response.body)['errors'] | |
expect(errors).to eq("Cart not found") | |
end | |
it "should show correctly the new store_credits_total" do | |
post :store_credits, id:@cart.id, amount:1000, format: :json | |
expect(response).to be_success | |
json_cart = JSON.parse(response.body) | |
expect(json_cart["store_credits_total"]["cents"]).to eq 1000 | |
end | |
context "when there is not enough balance" do | |
it "should render error response" do | |
post :store_credits, id:@cart.id, amount:1500, format: :json | |
expect(response.status).to eq(422) | |
error_hash = JSON.parse(response.body)["errors"] | |
expect(error_hash["store_credits_total_cents"]).to include("Available user balance is exceeded") | |
end | |
end | |
end | |
end | |
end | |
describe "Invalid platform headers" do | |
context "when no platform no auth" do | |
it "should return bad request on not_imported" do | |
get :not_imported, id: 99, format: :json | |
end | |
it "should return bad request on create" do | |
post :create, {customer_first_name:"Jane", customer_last_name:"Doe", customer_email:"[email protected]", format: :json} | |
end | |
after do | |
expect(response.status).to eq(400) | |
expect(response.body).to eq({ error: { message: "Invalid platform parameters" } }.to_json) | |
end | |
end | |
context "when platform but no auth" do | |
before{request.stub(:headers).and_return({"X-Rosi-Platform" => platform_key})} | |
it "should return bad request on create" do | |
post :create, {customer_first_name:"Jane", customer_last_name:"Doe", customer_email:"[email protected]", format: :json} | |
end | |
it "should return bad request on show" do | |
get :show, id: 99, format: :json | |
end | |
it "should return bad request on add_sku" do | |
post :add_sku, id:99, sku_id: sku.id, format: :json | |
end | |
it "should return bad request on remove_sku" do | |
post :remove_sku, id:99, sku_id:1, format: :json | |
end | |
it "should return bad request on update" do | |
put :update, id:99, format: :json | |
end | |
it "should return bad request on set_sku_quantity" do | |
patch :set_sku_quantity, id:99, sku_id: sku.id, format: :json | |
end | |
it "should return bad request on destroy" do | |
delete :destroy, id: 99, format: :json | |
end | |
it "should return bad request on checkout_status" do | |
get :checkout_status, id: 99, format: :json | |
end | |
it "should return bad request on not_imported" do | |
get :not_imported, id: 99, format: :json | |
end | |
after do | |
expect(response.status).to eq(401) | |
expect(response.body).to eq({ error: { message: "Incorrect credentials" } }.to_json) | |
end | |
end | |
end | |
describe 'private_authentication endpoints' do | |
before do | |
request.stub(:headers).and_return({"X-Rosi-Platform" => platform_key, "X-Rosi-Auth" => RosiCommon.config_store.rosi.rosi_user.private_token}) | |
expect(controller).to receive(:private_authentication).and_call_original | |
expect(controller).to_not receive(:dsr_authentication) | |
end | |
describe 'update_tax', fdoc: 'cart_service/carts/:id/update_tax' do | |
subject { FactoryGirl.create(:cart_with_items) } | |
let(:cart_item_tax_cents){ 20 } | |
let(:cart_tax_cents){ cart_item_tax_cents * subject.cart_items.count } | |
let(:items){ | |
subject.cart_items.map{|item| | |
{'item_id' => item.id, 'tax_cents' => cart_item_tax_cents} | |
} | |
} | |
context 'correct private authentication' do | |
before do | |
Cart.stub(:editable).and_return Cart | |
Cart.stub(:find).with(subject.id.to_s).and_return subject | |
expect(Cart).to receive(:find).with(subject.id.to_s) | |
sign_in(User.new(id:1, role:"dsr")) | |
end | |
it "succesfully should call model's update_tax method, passing the adequate params" do | |
patch :update_tax, {id: subject.id, tax_cents: cart_tax_cents, tax_version: subject.tax_version, items: items, format: :json} | |
expect(response.status).to eq(200) | |
expect(response).to be_success | |
expect(response.body).to eq('{}') | |
end | |
context 'when there are missing params' do | |
it 'responds with 422' do | |
patch :update_tax, {id: subject.id, format: :json} | |
expect(response.status).to eq(422) | |
expect(response).to_not be_success | |
expect(response.body.blank?).to be_false | |
end | |
end | |
context 'when mismatching old tax_version is passed' do | |
it 'responds with 202' do | |
tax_version = subject.tax_version - 1 | |
patch :update_tax, {id: subject.id, tax_cents: cart_tax_cents, tax_version: tax_version, items: items, format: :json} | |
expect(response.status).to eq(202) | |
expect(response).to be_success | |
expect(response.body).to eq('{}') | |
end | |
end | |
end | |
context "when passed auth token doesn't match with this service's private_token" do | |
before do | |
request.stub(:headers).and_return({"X-Rosi-Platform" => platform_key, "X-Rosi-Auth" => "different #{RosiCommon.config_store.rosi.rosi_user.private_token}"}) | |
end | |
it 'responds with 401' do | |
patch :update_tax, {id: subject.id, tax_cents: cart_item_tax_cents, tax_version: subject.tax_version, items: items, format: :json} | |
expect(response.status).to eq(401) | |
expect(response).to_not be_success | |
end | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment