solidus_multi_domain 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +33 -0
  3. data/.rspec +4 -0
  4. data/.ruby-version +1 -0
  5. data/Gemfile +9 -0
  6. data/README.md +72 -0
  7. data/Rakefile +21 -0
  8. data/app/controllers/concerns/spree_multi_domain/create_line_item_support.rb +16 -0
  9. data/app/controllers/concerns/spree_multi_domain/show_product_support.rb +17 -0
  10. data/app/controllers/spree/admin/products_controller_decorator.rb +12 -0
  11. data/app/controllers/spree/admin/stores_controller.rb +24 -0
  12. data/app/controllers/spree/api/line_items_controller_decorator.rb +1 -0
  13. data/app/controllers/spree/api/orders_controller_decorator.rb +21 -0
  14. data/app/controllers/spree/api/products_controller_decorator.rb +1 -0
  15. data/app/controllers/spree/api/shipments_controller_decorator.rb +17 -0
  16. data/app/controllers/spree/home_controller_decorator.rb +7 -0
  17. data/app/controllers/spree/products_controller_decorator.rb +1 -0
  18. data/app/controllers/spree/taxons_controller_decorator.rb +10 -0
  19. data/app/helpers/spree/products_helper_decorator.rb +11 -0
  20. data/app/mailers/spree/carton_mailer_decorator.rb +13 -0
  21. data/app/mailers/spree/order_mailer.rb +35 -0
  22. data/app/models/spree/order_decorator.rb +8 -0
  23. data/app/models/spree/payment_method_decorator.rb +13 -0
  24. data/app/models/spree/product_decorator.rb +4 -0
  25. data/app/models/spree/promotion/rules/store.rb +30 -0
  26. data/app/models/spree/shipping_method_decorator.rb +18 -0
  27. data/app/models/spree/store_decorator.rb +25 -0
  28. data/app/models/spree/store_payment_method.rb +6 -0
  29. data/app/models/spree/store_shipping_method.rb +6 -0
  30. data/app/models/spree/taxon_decorator.rb +5 -0
  31. data/app/models/spree/taxonomy_decorator.rb +3 -0
  32. data/app/models/spree/tracker_decorator.rb +7 -0
  33. data/app/models/spree_multi_domain/line_item_decorator.rb +20 -0
  34. data/app/overrides/decorate_admin_configurations_index.rb +5 -0
  35. data/app/overrides/decorate_admin_products_form.rb +6 -0
  36. data/app/overrides/decorate_admin_products_index.rb +20 -0
  37. data/app/overrides/decorate_admin_trackers_form.rb +6 -0
  38. data/app/overrides/decorate_admin_trackers_index.rb +13 -0
  39. data/app/views/spree/admin/products/_index_headers.html.erb +1 -0
  40. data/app/views/spree/admin/products/_index_rows.html.erb +1 -0
  41. data/app/views/spree/admin/products/_index_search_fields.html.erb +4 -0
  42. data/app/views/spree/admin/products/_stores.html.erb +8 -0
  43. data/app/views/spree/admin/promotions/rules/_store.html.erb +8 -0
  44. data/app/views/spree/admin/stores/_form.html.erb +90 -0
  45. data/app/views/spree/admin/stores/edit.html.erb +29 -0
  46. data/app/views/spree/admin/stores/index.html.erb +43 -0
  47. data/app/views/spree/admin/stores/new.html.erb +29 -0
  48. data/app/views/spree/admin/taxonomies/_form.html.erb +12 -0
  49. data/app/views/spree/admin/trackers/_index_rows.html.erb +1 -0
  50. data/app/views/spree/admin/trackers/_store.html.erb +6 -0
  51. data/app/views/spree/shared/_google_analytics.html.erb +39 -0
  52. data/bin/rails +7 -0
  53. data/circle.yml +6 -0
  54. data/config/locales/en.yml +26 -0
  55. data/config/locales/fr.yml +9 -0
  56. data/config/locales/pl.yml +10 -0
  57. data/config/locales/ru.yml +9 -0
  58. data/config/routes.rb +5 -0
  59. data/db/migrate/20091202123245_add_order_store.rb +17 -0
  60. data/db/migrate/20100114020535_add_store_to_tracker.rb +25 -0
  61. data/db/migrate/20100227180338_create_products_stores.rb +13 -0
  62. data/db/migrate/20100616204303_store_id_for_taxonomies.rb +19 -0
  63. data/db/migrate/20110601125650_remove_datetime_columns_from_products_stores.rb +13 -0
  64. data/db/migrate/20110601145424_add_indexes_to_products_stores.rb +11 -0
  65. data/db/migrate/20120223183401_namespace.rb +9 -0
  66. data/db/migrate/20121210224018_add_store_payment_methods.rb +10 -0
  67. data/db/migrate/20130308084714_add_logo_to_stores.rb +13 -0
  68. data/db/migrate/20130325231147_add_store_shipping_methods.rb +14 -0
  69. data/db/migrate/20130412212659_add_spree_promotion_rules_stores.rb +8 -0
  70. data/db/migrate/20150304200122_add_indexes.rb +6 -0
  71. data/lib/assets/javascripts/spree/backend/solidus_multi_domain.js +1 -0
  72. data/lib/assets/javascripts/spree/backend/store_picker.js +34 -0
  73. data/lib/assets/javascripts/spree/frontend/solidus_multi_domain.js +0 -0
  74. data/lib/assets/stylesheets/spree/frontend/solidus_multi_domain.css +5 -0
  75. data/lib/generators/spree_multi_domain/install/install_generator.rb +24 -0
  76. data/lib/solidus_multi_domain.rb +3 -0
  77. data/lib/spree/controller_helpers/order_decorator.rb +11 -0
  78. data/lib/spree/search/multi_domain.rb +19 -0
  79. data/lib/spree_multi_domain/engine.rb +65 -0
  80. data/lib/spree_multi_domain/multi_domain_helpers.rb +31 -0
  81. data/solidus_multi_domain.gemspec +31 -0
  82. data/spec/controllers/spree/admin/products_controller_spec.rb +39 -0
  83. data/spec/controllers/spree/admin/stores_controller_spec.rb +12 -0
  84. data/spec/controllers/spree/api/line_items_controller_spec.rb +35 -0
  85. data/spec/controllers/spree/api/orders_controller_spec.rb +44 -0
  86. data/spec/controllers/spree/api/products_controller_spec.rb +52 -0
  87. data/spec/controllers/spree/api/shipments_controller_spec.rb +63 -0
  88. data/spec/controllers/spree/products_controller_spec.rb +49 -0
  89. data/spec/helpers/products_helper_decorator_spec.rb +22 -0
  90. data/spec/mailers/carton_mailer_spec.rb +41 -0
  91. data/spec/models/spree/line_item_spec.rb +39 -0
  92. data/spec/models/spree/order_spec.rb +18 -0
  93. data/spec/models/spree/payment_method_spec.rb +33 -0
  94. data/spec/models/spree/product_spec.rb +18 -0
  95. data/spec/models/spree/shipping_method_decorator_spec.rb +27 -0
  96. data/spec/models/spree/store_spec.rb +42 -0
  97. data/spec/models/spree/taxon_decorator_spec.rb +30 -0
  98. data/spec/models/spree/tracker_spec.rb +19 -0
  99. data/spec/requests/global_controller_helpers_spec.rb +65 -0
  100. data/spec/requests/template_renderer_spec.rb +25 -0
  101. data/spec/spec_helper.rb +33 -0
  102. data/spec/support/factory_overrides.rb +10 -0
  103. metadata +278 -0
@@ -0,0 +1,31 @@
1
+ # encoding: UTF-8
2
+
3
+ Gem::Specification.new do |s|
4
+ s.platform = Gem::Platform::RUBY
5
+ s.name = "solidus_multi_domain"
6
+ s.version = "1.0.0"
7
+ s.summary = "Adds multiple site support to Solidus"
8
+ s.description = "Multiple Solidus stores on different domains - single unified backed for processing orders."
9
+ s.required_ruby_version = ">= 2.1"
10
+
11
+ s.author = "Solidus Team"
12
+ s.email = "contact@solidus.io"
13
+ s.homepage = "https://solidus.io"
14
+ s.license = %q{BSD-3}
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.require_path = "lib"
19
+ s.requirements << "none"
20
+
21
+ s.add_dependency "solidus", [">= 1.0.0.pre", "< 2"]
22
+
23
+ s.add_development_dependency "rspec-rails", "~> 3.2"
24
+ s.add_development_dependency "simplecov"
25
+ s.add_development_dependency "sqlite3"
26
+ s.add_development_dependency "sass-rails", "~> 4.0.2"
27
+ s.add_development_dependency "coffee-rails", "~> 4.0.0"
28
+ s.add_development_dependency "factory_girl", "~> 4.5.0"
29
+ s.add_development_dependency "capybara", "~> 2.4"
30
+ s.add_development_dependency "ffaker"
31
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Admin::ProductsController do
4
+ stub_authorization!
5
+
6
+ describe "on :index" do
7
+ it "renders index" do
8
+ spree_get :index
9
+ expect(response).to be_success
10
+ end
11
+ end
12
+
13
+ describe "on a PUT to :update" do
14
+ before(:each) do
15
+ @product = FactoryGirl.create(:product)
16
+ @store = FactoryGirl.create(:store)
17
+ end
18
+
19
+ describe "when no stores are selected" do
20
+ it "clears stores if they previously existed" do
21
+ @product.stores << @store
22
+
23
+ spree_put :update, :id => @product.to_param,
24
+ :product => {:name => @product.name}, update_store_ids: 'true'
25
+
26
+ expect(@product.reload.store_ids).to be_empty
27
+ end
28
+ end
29
+
30
+ describe "when a store is selected" do
31
+ it "clears stores" do
32
+ spree_put :update, :id => @product.to_param,
33
+ :product => {:name => @product.name, :store_ids => [@store.id]}, update_store_ids: 'true'
34
+
35
+ expect(@product.reload.store_ids).to eq [@store.id]
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Admin::StoresController do
4
+ stub_authorization!
5
+
6
+ describe "on :index" do
7
+ it "renders index" do
8
+ spree_get :index
9
+ expect(response).to be_success
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Api::LineItemsController do
4
+
5
+ before(:each) do
6
+ stub_authentication!
7
+ end
8
+
9
+ describe "POST create" do
10
+ let(:user) { create(:user) }
11
+ let(:current_api_user) { user }
12
+ let(:order) { create(:order, user: user) }
13
+ let(:line_item) { build(:line_item, order: order) }
14
+
15
+ subject { spree_post :create, line_item: line_item, order_id: line_item.order.number }
16
+
17
+ context "A SpreeMultiDomain::LineItemDecorator::ProductDoesNotBelongToStoreError is raised" do
18
+ before(:each) do
19
+ def controller.create
20
+ raise SpreeMultiDomain::LineItemDecorator::ProductDoesNotBelongToStoreError
21
+ end
22
+ end
23
+
24
+ it "sets the correct status" do
25
+ subject
26
+ expect(response.status).to eq 422
27
+ end
28
+
29
+ it "contains the correct error message" do
30
+ subject
31
+ expect(JSON.parse(response.body)["message"]).to eq "Products from different stores may not be added to this order."
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Api::OrdersController do
4
+ let!(:user) { FactoryGirl.create(:user) }
5
+ let!(:store1) { FactoryGirl.create(:store) }
6
+ let!(:store2) { FactoryGirl.create(:store) }
7
+
8
+ before(:each) do
9
+ controller.stub(current_api_user: user)
10
+ end
11
+
12
+ describe '#mine' do
13
+ it 'should return only orders from the correct store' do
14
+ FactoryGirl.create(:order, store: store1, user: user)
15
+ FactoryGirl.create(:order, store: store2, user: user)
16
+
17
+ controller.stub(current_store: store1)
18
+ controller.mine
19
+
20
+ expect(assigns(:orders).length).to eq(1)
21
+ expect(assigns(:orders).first.store_id).to eq(store1.id)
22
+
23
+ controller.stub(current_store: store2)
24
+ controller.mine
25
+
26
+ expect(assigns(:orders).length).to eq(1)
27
+ expect(assigns(:orders).first.store_id).to eq(store2.id)
28
+ end
29
+ end
30
+
31
+ describe '#find_current_order' do
32
+
33
+ it 'should return the latest incomplete order from the correct store' do
34
+ order1 = FactoryGirl.create(:order, store: store1, state: :cart, user: user)
35
+ order2 = FactoryGirl.create(:order, store: store2, state: :cart, user: user)
36
+
37
+ controller.stub(current_store: store1)
38
+ expect(controller.send(:find_current_order)).to eql(order1)
39
+
40
+ controller.stub(current_store: store2)
41
+ expect(controller.send(:find_current_order)).to eql(order2)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Api::ProductsController do
4
+
5
+ let!(:product) { FactoryGirl.create(:product) }
6
+
7
+ let(:user) { create(:user) }
8
+ before { allow(controller).to receive(:current_spree_user) { user } }
9
+
10
+ describe 'on :show to a product without any stores' do
11
+ let!(:store) { FactoryGirl.create(:store) }
12
+
13
+ it 'should return 404' do
14
+ spree_get :show, :id => product.to_param, format: :json
15
+
16
+ expect(response.response_code) == 404
17
+ end
18
+ end
19
+
20
+ # Regression test for #75
21
+ describe 'on :show to a product in the wrong store' do
22
+ let!(:store_1) { FactoryGirl.create(:store) }
23
+ let!(:store_2) { FactoryGirl.create(:store) }
24
+
25
+ before(:each) do
26
+ product.stores << store_1
27
+ end
28
+
29
+ it 'should return 404' do
30
+ controller.stub(:current_store => store_2)
31
+ spree_get :show, :id => product.to_param, format: :json
32
+
33
+ expect(response.response_code) == 404
34
+ end
35
+ end
36
+
37
+ describe 'on :show to a product w/ store' do
38
+ let!(:store) { FactoryGirl.create(:store) }
39
+
40
+ before(:each) do
41
+ product.stores << store
42
+ end
43
+
44
+ it 'should return 200' do
45
+ controller.stub(:current_store => store)
46
+ spree_get :show, :id => product.to_param, format: :json
47
+
48
+ expect(response.response_code) == 200
49
+ end
50
+ end
51
+
52
+ end
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Api::ShipmentsController do
4
+ describe '#mine' do
5
+ let!(:user) { FactoryGirl.create(:user) }
6
+ let!(:store1) { FactoryGirl.create(:store) }
7
+ let!(:store2) { FactoryGirl.create(:store) }
8
+ let!(:order_from_store1) { FactoryGirl.create(:order, store: store1, user: user) }
9
+ let!(:order_from_store2) { FactoryGirl.create(:order, store: store2, user: user) }
10
+
11
+ before(:each) do
12
+ controller.stub(current_api_user: user)
13
+ end
14
+
15
+ it 'should return only shipments from the correct store' do
16
+ FactoryGirl.create(:shipment, order: order_from_store1)
17
+ FactoryGirl.create(:shipment, order: order_from_store2)
18
+
19
+ controller.stub(current_store: store1)
20
+ controller.mine
21
+
22
+ expect(assigns(:shipments).length).to eq(1)
23
+ expect(assigns(:shipments).first.order.store_id).to eq(store1.id)
24
+
25
+ controller.stub(current_store: store2)
26
+ controller.mine
27
+
28
+ expect(assigns(:shipments).length).to eq(1)
29
+ expect(assigns(:shipments).first.order.store_id).to eq(store2.id)
30
+ end
31
+ end
32
+
33
+ describe "PUT add" do
34
+
35
+ let(:current_api_user) { create(:admin_user) }
36
+ let(:shipment) { create(:shipment) }
37
+ let(:variant) { create(:variant) }
38
+
39
+ subject { spree_put :add, variant_id: variant.id, id: shipment.number, quantity: 1 }
40
+
41
+ before(:each) do
42
+ stub_authentication!
43
+ end
44
+
45
+ context "A SpreeMultiDomain::LineItemDecorator::ProductDoesNotBelongToStoreError is raised" do
46
+ before(:each) do
47
+ def controller.add
48
+ raise SpreeMultiDomain::LineItemDecorator::ProductDoesNotBelongToStoreError
49
+ end
50
+ end
51
+
52
+ it "sets the correct status" do
53
+ subject
54
+ expect(response.status).to eq 422
55
+ end
56
+
57
+ it "contains the correct error message" do
58
+ subject
59
+ expect(JSON.parse(response.body)["message"]).to eq "Products from different stores may not be added to this order."
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::ProductsController do
4
+
5
+ let!(:product) { FactoryGirl.create(:product) }
6
+
7
+ describe 'on :show to a product without any stores' do
8
+ let!(:store) { FactoryGirl.create(:store) }
9
+
10
+ it 'returns 404' do
11
+ spree_get :show, :id => product.to_param
12
+
13
+ expect(response.response_code).to eq 404
14
+ end
15
+ end
16
+
17
+ # Regression test for #75
18
+ describe 'on :show to a product in the wrong store' do
19
+ let!(:store_1) { FactoryGirl.create(:store) }
20
+ let!(:store_2) { FactoryGirl.create(:store) }
21
+
22
+ before(:each) do
23
+ product.stores << store_1
24
+ end
25
+
26
+ it 'returns 404' do
27
+ allow(controller).to receive_messages(:current_store => store_2)
28
+ spree_get :show, :id => product.to_param
29
+
30
+ expect(response.response_code).to eq 404
31
+ end
32
+ end
33
+
34
+ describe 'on :show to a product w/ store' do
35
+ let!(:store) { FactoryGirl.create(:store) }
36
+
37
+ before(:each) do
38
+ product.stores << store
39
+ end
40
+
41
+ it 'returns 200' do
42
+ allow(controller).to receive_messages(:current_store => store)
43
+ spree_get :show, :id => product.to_param
44
+
45
+ expect(response.response_code).to eq 200
46
+ end
47
+ end
48
+
49
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ describe ProductsHelper do
5
+ before(:each) do
6
+ @store = FactoryGirl.create(:store)
7
+ @taxonomy = FactoryGirl.create(:taxonomy, :store => @store)
8
+ @taxonomy2 = FactoryGirl.create(:taxonomy)
9
+
10
+ allow(helper).to receive(:current_store) { @store }
11
+ end
12
+
13
+ describe "#get_taxonomies" do
14
+ it "only show taxonomies on current_store" do
15
+ taxonomies = helper.get_taxonomies
16
+
17
+ expect(taxonomies).to include(@taxonomy)
18
+ expect(taxonomies).to_not include(@taxonomy2)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::CartonMailer do
4
+ let(:mail) { Spree::CartonMailer.shipped_email(carton.id) }
5
+
6
+ let(:carton) do
7
+ FactoryGirl.create(:carton, inventory_units: order.inventory_units)
8
+ end
9
+
10
+ let(:order) do
11
+ FactoryGirl.create(:order_ready_to_ship, line_items_count: 1)
12
+ end
13
+
14
+ describe 'from address' do
15
+ subject do
16
+ mail.from
17
+ end
18
+
19
+ context 'the order does not have a store' do
20
+ let(:order) do
21
+ FactoryGirl.create(:order_ready_to_ship, line_items_count: 1, store: nil)
22
+ end
23
+
24
+ it { is_expected.to eq [Spree::Config[:mails_from]] }
25
+ end
26
+
27
+ context 'the order has a store' do
28
+ let(:order) do
29
+ FactoryGirl.create(
30
+ :order_ready_to_ship,
31
+ line_items_count: 1,
32
+ store: store,
33
+ )
34
+ end
35
+
36
+ let(:store) { FactoryGirl.create(:store, mail_from_address: 'store@example.com') }
37
+ it { is_expected.to eq ['store@example.com'] }
38
+ end
39
+ end
40
+
41
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::LineItem do
4
+ describe "before create" do
5
+
6
+ let(:order_store) { create(:store) }
7
+ let(:other_store) { create(:store) }
8
+ let(:order) { create(:order, store: order_store) }
9
+ let(:variant) { create(:variant, product: product) }
10
+ let(:line_item) { build(:line_item, order: order, product: product) }
11
+
12
+ subject { line_item.save! }
13
+
14
+ context "the order does not have a store" do
15
+ before(:each) { order.update_attributes(store_id: nil) }
16
+ let(:product) { create(:product, stores: [order_store])}
17
+
18
+ it 'does not raise an error' do
19
+ expect{ subject }.to_not raise_error
20
+ end
21
+ end
22
+
23
+ context "the line item's product does not belong to the order's store" do
24
+ let(:product) { create(:product, stores: [other_store]) }
25
+
26
+ it 'raises the correct error' do
27
+ expect{ subject }.to raise_error(SpreeMultiDomain::LineItemDecorator::ProductDoesNotBelongToStoreError)
28
+ end
29
+ end
30
+
31
+ context "the line item's product belongs to the order's store" do
32
+ let(:product) { create(:product, stores: [order_store])}
33
+
34
+ it "does not raise an error" do
35
+ expect{ subject }.to_not raise_error
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Order do
4
+
5
+ before(:each) do
6
+ @store = FactoryGirl.create(:store)
7
+ @order = FactoryGirl.create(:order, :store => @store)
8
+
9
+ @order2 = FactoryGirl.create(:order)
10
+ end
11
+
12
+ it 'should correctly find products by store' do
13
+ by_store = Spree::Order.by_store(@store)
14
+
15
+ expect(by_store).to include(@order)
16
+ expect(by_store).to_not include(@order2)
17
+ end
18
+ end