solidus_related_products 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.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.hound.yml +25 -0
- data/.rspec +3 -0
- data/.rubocop.yml +8 -0
- data/.travis.yml +15 -0
- data/CONTRIBUTING.md +81 -0
- data/Gemfile +6 -0
- data/Guardfile +10 -0
- data/LICENSE.md +26 -0
- data/README.md +80 -0
- data/Rakefile +15 -0
- data/app/assets/javascripts/spree/backend/solidus_related_products.js +1 -0
- data/app/assets/javascripts/spree/frontend/solidus_related_products.js +1 -0
- data/app/assets/stylesheets/spree/backend/solidus_related_products.css +3 -0
- data/app/assets/stylesheets/spree/frontend/solidus_related_products.css +3 -0
- data/app/controllers/spree/admin/products_controller_decorator.rb +10 -0
- data/app/controllers/spree/admin/relation_types_controller.rb +6 -0
- data/app/controllers/spree/admin/relations_controller.rb +80 -0
- data/app/controllers/spree/api/relations_controller.rb +78 -0
- data/app/models/spree/calculator/related_product_discount.rb +50 -0
- data/app/models/spree/product_decorator.rb +106 -0
- data/app/models/spree/relation.rb +7 -0
- data/app/models/spree/relation_type.rb +6 -0
- data/app/overrides/add_product_relation_admin_sub_menu_tab.rb +6 -0
- data/app/overrides/add_related_product_admin_tabs.rb +6 -0
- data/app/views/spree/admin/products/_related_products.html.erb +3 -0
- data/app/views/spree/admin/products/_related_products_table.html.erb +42 -0
- data/app/views/spree/admin/products/related.html.erb +70 -0
- data/app/views/spree/admin/relation_types/_form.html.erb +19 -0
- data/app/views/spree/admin/relation_types/edit.html.erb +14 -0
- data/app/views/spree/admin/relation_types/index.html.erb +44 -0
- data/app/views/spree/admin/relation_types/new.html.erb +14 -0
- data/app/views/spree/admin/relations/create.js.erb +5 -0
- data/app/views/spree/admin/relations/destroy.js.erb +1 -0
- data/app/views/spree/api/relations/show.v1.rabl +2 -0
- data/bin/rails +7 -0
- data/config/locales/cs.yml +18 -0
- data/config/locales/de.yml +18 -0
- data/config/locales/en.yml +18 -0
- data/config/locales/es.yml +18 -0
- data/config/locales/fr.yml +18 -0
- data/config/locales/it.yml +18 -0
- data/config/locales/nl.yml +18 -0
- data/config/locales/pl.yml +18 -0
- data/config/locales/pt-BR.yml +18 -0
- data/config/locales/ru.yml +18 -0
- data/config/locales/sv.yml +18 -0
- data/config/routes.rb +24 -0
- data/db/migrate/20100308090631_create_relation_types.rb +14 -0
- data/db/migrate/20100308092101_create_relations.rb +14 -0
- data/db/migrate/20100324123835_add_discount_to_relation.rb +9 -0
- data/db/migrate/20111129044813_prefixing_tables_with_spree.rb +6 -0
- data/db/migrate/20120208144454_update_relation_types.rb +9 -0
- data/db/migrate/20120623014337_update_relations.rb +11 -0
- data/db/migrate/20130727004612_add_position_to_spree_relations.rb +5 -0
- data/lib/generators/solidus_related_products/install/install_generator.rb +20 -0
- data/lib/solidus_related_products.rb +7 -0
- data/lib/solidus_related_products/engine.rb +24 -0
- data/lib/solidus_related_products/version.rb +18 -0
- data/solidus_related_products.gemspec +45 -0
- data/spec/controllers/spree/admin/products_controller_decorator_spec.rb +20 -0
- data/spec/controllers/spree/admin/relations_controller_spec.rb +96 -0
- data/spec/controllers/spree/api/relations_controller_spec.rb +98 -0
- data/spec/factories/relation_factory.rb +7 -0
- data/spec/factories/relation_type_factory.rb +6 -0
- data/spec/features/spree/admin/product_relation_spec.rb +86 -0
- data/spec/features/spree/admin/relation_types_spec.rb +97 -0
- data/spec/models/spree/calculator/related_product_discount_spec.rb +48 -0
- data/spec/models/spree/product_spec.rb +129 -0
- data/spec/models/spree/relation_spec.rb +13 -0
- data/spec/models/spree/relation_type_spec.rb +18 -0
- data/spec/spec_helper.rb +48 -0
- data/spec/support/capybara.rb +20 -0
- data/spec/support/database_cleaner.rb +23 -0
- data/spec/support/factory_girl.rb +7 -0
- data/spec/support/spree.rb +18 -0
- metadata +388 -0
@@ -0,0 +1,96 @@
|
|
1
|
+
RSpec.describe Spree::Admin::RelationsController, type: :controller do
|
2
|
+
stub_authorization!
|
3
|
+
|
4
|
+
let(:user) { create(:user) }
|
5
|
+
let!(:product) { create(:product) }
|
6
|
+
let!(:other1) { create(:product) }
|
7
|
+
|
8
|
+
let!(:relation_type) { create(:relation_type) }
|
9
|
+
let!(:relation) do
|
10
|
+
create(
|
11
|
+
:relation,
|
12
|
+
relatable: product,
|
13
|
+
related_to: other1,
|
14
|
+
relation_type: relation_type,
|
15
|
+
position: 0
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
before { stub_authentication! }
|
20
|
+
after { Spree::Admin::ProductsController.clear_overrides! }
|
21
|
+
|
22
|
+
context '.model_class' do
|
23
|
+
it 'responds to model_class as Spree::Relation' do
|
24
|
+
expect(controller.send(:model_class)).to eq Spree::Relation
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe 'with JS' do
|
29
|
+
sign_in_as_admin!
|
30
|
+
|
31
|
+
let(:valid_params) do
|
32
|
+
{
|
33
|
+
format: :js,
|
34
|
+
product_id: product.id,
|
35
|
+
relation: {
|
36
|
+
related_to_id: other1.id,
|
37
|
+
relation_type_id: relation_type.id
|
38
|
+
}
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
context '#create' do
|
43
|
+
it 'is not routable' do
|
44
|
+
spree_post :create, valid_params
|
45
|
+
expect(response.status).to be(200)
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'returns success with valid params' do
|
49
|
+
expect {
|
50
|
+
spree_post :create, valid_params
|
51
|
+
}.to change(Spree::Relation, :count).by(1)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'raises error with invalid params' do
|
55
|
+
expect {
|
56
|
+
spree_post :create, format: :js
|
57
|
+
}.to raise_error
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context '#update' do
|
62
|
+
it 'redirects to product/related url' do
|
63
|
+
spree_put :update, product_id: product.id, id: 1, relation: { discount_amount: 2.0 }
|
64
|
+
expect(response).to redirect_to(spree.admin_product_path(relation.relatable) + '/related')
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context '#destroy' do
|
69
|
+
it 'records successfully' do
|
70
|
+
expect {
|
71
|
+
spree_delete :destroy, id: 1, product_id: product.id, format: :js
|
72
|
+
}.to change(Spree::Relation, :count).by(-1)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context '#update_positions' do
|
77
|
+
it 'returns the correct position of the related products' do
|
78
|
+
other2 = create(:product)
|
79
|
+
relation2 = create(
|
80
|
+
:relation, relatable: product, related_to: other2, relation_type: relation_type, position: 1
|
81
|
+
)
|
82
|
+
|
83
|
+
expect {
|
84
|
+
params = {
|
85
|
+
product_id: product.id,
|
86
|
+
id: relation.id,
|
87
|
+
positions: { relation.id => '1', relation2.id => '0' },
|
88
|
+
format: :js
|
89
|
+
}
|
90
|
+
spree_post :update_positions, params
|
91
|
+
relation.reload
|
92
|
+
}.to change(relation, :position).from(0).to(1)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
RSpec.describe Spree::Api::RelationsController, type: :controller do
|
2
|
+
stub_authorization!
|
3
|
+
render_views
|
4
|
+
|
5
|
+
let(:user) { create(:user) }
|
6
|
+
let!(:product) { create(:product) }
|
7
|
+
let!(:other1) { create(:product) }
|
8
|
+
|
9
|
+
let!(:relation_type) { create(:relation_type) }
|
10
|
+
let!(:relation) do
|
11
|
+
create(
|
12
|
+
:relation,
|
13
|
+
relatable: product,
|
14
|
+
related_to: other1,
|
15
|
+
relation_type: relation_type,
|
16
|
+
position: 0
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
before { stub_authentication! }
|
21
|
+
after { Spree::Admin::ProductsController.clear_overrides! }
|
22
|
+
|
23
|
+
context 'model_class' do
|
24
|
+
it 'responds to model_class as Spree::Relation' do
|
25
|
+
expect(controller.send(:model_class)).to eq Spree::Relation
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe 'with JSON' do
|
30
|
+
sign_in_as_admin!
|
31
|
+
|
32
|
+
let(:valid_params) do
|
33
|
+
{
|
34
|
+
format: :json,
|
35
|
+
product_id: product.id,
|
36
|
+
relation: {
|
37
|
+
related_to_id: other1.id,
|
38
|
+
relation_type_id: relation_type.id
|
39
|
+
},
|
40
|
+
token: user.spree_api_key
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
context '#create' do
|
45
|
+
it 'creates the relation' do
|
46
|
+
spree_post :create, valid_params
|
47
|
+
expect(response.status).to eq(201)
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'responds 422 error with invalid params' do
|
51
|
+
spree_post :create, format: :json, product_id: product.id, token: user.spree_api_key
|
52
|
+
expect(response.status).to eq(422)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context '#update' do
|
57
|
+
it 'succesfully updates the relation ' do
|
58
|
+
params = {
|
59
|
+
format: :json,
|
60
|
+
product_id: product.id,
|
61
|
+
id: relation.id,
|
62
|
+
relation: { discount_amount: 2.0 }
|
63
|
+
}
|
64
|
+
expect {
|
65
|
+
spree_put :update, params
|
66
|
+
}.to change { relation.reload.discount_amount.to_s }.from('0.0').to('2.0')
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context '#destroy with' do
|
71
|
+
it 'records successfully' do
|
72
|
+
expect {
|
73
|
+
spree_delete :destroy, id: 1, product_id: product.id, format: :json, token: user.spree_api_key
|
74
|
+
}.to change(Spree::Relation, :count).by(-1)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context '#update_positions' do
|
79
|
+
it 'returns the correct position of the related products' do
|
80
|
+
other2 = create(:product)
|
81
|
+
relation2 = create(
|
82
|
+
:relation, relatable: product, related_to: other2, relation_type: relation_type, position: 1
|
83
|
+
)
|
84
|
+
|
85
|
+
expect {
|
86
|
+
params = {
|
87
|
+
product_id: product.id,
|
88
|
+
id: relation.id,
|
89
|
+
positions: { relation.id => '1', relation2.id => '0' },
|
90
|
+
format: :json
|
91
|
+
}
|
92
|
+
spree_post :update_positions, params
|
93
|
+
relation.reload
|
94
|
+
}.to change(relation, :position).from(0).to(1)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
RSpec.feature 'Admin Product Relation', :js do
|
2
|
+
stub_authorization!
|
3
|
+
|
4
|
+
given!(:product) { create(:product) }
|
5
|
+
given!(:other) { create(:product) }
|
6
|
+
|
7
|
+
given!(:relation_type) { create(:relation_type, name: 'Gears') }
|
8
|
+
|
9
|
+
background do
|
10
|
+
visit spree.edit_admin_product_path(product)
|
11
|
+
click_link 'Related Products'
|
12
|
+
end
|
13
|
+
|
14
|
+
scenario 'create relation' do
|
15
|
+
expect(page).to have_text 'ADD RELATED PRODUCT'
|
16
|
+
expect(page).to have_text product.name
|
17
|
+
|
18
|
+
within('#add-line-item') do
|
19
|
+
select2_search other.name, from: 'Name or SKU'
|
20
|
+
select2_search relation_type.name, from: 'Type'
|
21
|
+
fill_in 'add_discount', with: '0.8'
|
22
|
+
click_link 'Add'
|
23
|
+
end
|
24
|
+
|
25
|
+
wait_for_ajax
|
26
|
+
|
27
|
+
within_row(1) do
|
28
|
+
expect(page).to have_field('relation_discount_amount', with: '0.8')
|
29
|
+
expect(column_text(2)).to eq other.name
|
30
|
+
expect(column_text(3)).to eq relation_type.name
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'with relations' do
|
35
|
+
given!(:relation) do
|
36
|
+
create(
|
37
|
+
:relation,
|
38
|
+
relatable: product,
|
39
|
+
related_to: other,
|
40
|
+
relation_type: relation_type,
|
41
|
+
discount_amount: 0.5
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
background do
|
46
|
+
visit spree.edit_admin_product_path(product)
|
47
|
+
click_link 'Related Products'
|
48
|
+
end
|
49
|
+
|
50
|
+
scenario 'ensure content exist' do
|
51
|
+
expect(page).to have_text 'ADD RELATED PRODUCT'
|
52
|
+
expect(page).to have_text product.name
|
53
|
+
expect(page).to have_text other.name
|
54
|
+
|
55
|
+
within_row(1) do
|
56
|
+
expect(page).to have_field('relation_discount_amount', with: '0.5')
|
57
|
+
expect(column_text(2)).to eq other.name
|
58
|
+
expect(column_text(3)).to eq relation_type.name
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
scenario 'update discount' do
|
63
|
+
within_row(1) do
|
64
|
+
fill_in 'relation_discount_amount', with: '0.9'
|
65
|
+
click_on 'Update'
|
66
|
+
end
|
67
|
+
wait_for_ajax
|
68
|
+
within_row(1) do
|
69
|
+
expect(page).to have_field('relation_discount_amount', with: '0.9')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'delete' do
|
74
|
+
scenario 'can remove records' do
|
75
|
+
expect(page).to have_text other.name
|
76
|
+
within_row(1) do
|
77
|
+
expect(column_text(2)).to eq other.name
|
78
|
+
click_icon :trash
|
79
|
+
end
|
80
|
+
page.driver.browser.switch_to.alert.accept unless Capybara.javascript_driver == :poltergeist
|
81
|
+
wait_for_ajax
|
82
|
+
expect(page).not_to have_text other.name
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
RSpec.feature 'Admin Relation Types', :js do
|
2
|
+
stub_authorization!
|
3
|
+
|
4
|
+
background do
|
5
|
+
visit spree.admin_relation_types_path
|
6
|
+
end
|
7
|
+
|
8
|
+
scenario 'when no relation types exists' do
|
9
|
+
expect(page).to have_text 'NO RELATION TYPES FOUND, ADD ONE!'
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'create' do
|
13
|
+
scenario 'can create a new relation type' do
|
14
|
+
click_link 'New Relation Type'
|
15
|
+
expect(current_path).to eq spree.new_admin_relation_type_path
|
16
|
+
|
17
|
+
fill_in 'Name', with: 'Gears'
|
18
|
+
fill_in 'Applies To', with: 'Spree:Products'
|
19
|
+
|
20
|
+
click_button 'Create'
|
21
|
+
|
22
|
+
expect(page).to have_text 'successfully created!'
|
23
|
+
expect(current_path).to eq spree.admin_relation_types_path
|
24
|
+
end
|
25
|
+
|
26
|
+
scenario 'shows validation errors with blank :name' do
|
27
|
+
click_link 'New Relation Type'
|
28
|
+
expect(current_path).to eq spree.new_admin_relation_type_path
|
29
|
+
|
30
|
+
fill_in 'Name', with: ''
|
31
|
+
click_button 'Create'
|
32
|
+
|
33
|
+
expect(page).to have_text 'Name can\'t be blank'
|
34
|
+
end
|
35
|
+
|
36
|
+
scenario 'shows validation errors with blank :applies_to' do
|
37
|
+
click_link 'New Relation Type'
|
38
|
+
expect(current_path).to eq spree.new_admin_relation_type_path
|
39
|
+
|
40
|
+
fill_in 'Name', with: 'Gears'
|
41
|
+
fill_in 'Applies To', with: ''
|
42
|
+
click_button 'Create'
|
43
|
+
|
44
|
+
expect(page).to have_text 'Applies to can\'t be blank'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'with records' do
|
49
|
+
background do
|
50
|
+
%w(Gears Equipments).each do |name|
|
51
|
+
create(:relation_type, name: name)
|
52
|
+
end
|
53
|
+
visit spree.admin_relation_types_path
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'show' do
|
57
|
+
scenario 'displays existing relation types' do
|
58
|
+
within_row(1) do
|
59
|
+
expect(column_text(1)).to eq 'Gears'
|
60
|
+
expect(column_text(2)).to eq 'Spree::Product'
|
61
|
+
expect(column_text(3)).to eq ''
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'edit' do
|
67
|
+
background do
|
68
|
+
within_row(1) { click_icon :edit }
|
69
|
+
expect(current_path).to eq spree.edit_admin_relation_type_path(1)
|
70
|
+
end
|
71
|
+
|
72
|
+
scenario 'can update an existing relation type' do
|
73
|
+
fill_in 'Name', with: 'Gadgets'
|
74
|
+
click_button 'Update'
|
75
|
+
expect(page).to have_text 'successfully updated!'
|
76
|
+
expect(page).to have_text 'Gadgets'
|
77
|
+
end
|
78
|
+
|
79
|
+
scenario 'shows validation errors with blank :name' do
|
80
|
+
fill_in 'Name', with: ''
|
81
|
+
click_button 'Update'
|
82
|
+
expect(page).to have_text 'Name can\'t be blank'
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'delete' do
|
87
|
+
scenario 'can remove records' do
|
88
|
+
within_row(1) do
|
89
|
+
expect(column_text(1)).to eq 'Gears'
|
90
|
+
click_icon :trash
|
91
|
+
end
|
92
|
+
page.driver.browser.switch_to.alert.accept unless Capybara.javascript_driver == :poltergeist
|
93
|
+
expect(page).to have_text 'successfully removed!'
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
RSpec.describe Spree::Calculator::RelatedProductDiscount, type: :model do
|
2
|
+
subject { described_class.new }
|
3
|
+
|
4
|
+
context '.description' do
|
5
|
+
it 'outputs relation product discount' do
|
6
|
+
expect(subject.description).to eq Spree.t(:related_product_discount)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '.compute(object)' do
|
11
|
+
it 'returns nil with empty Array' do
|
12
|
+
expect(subject.compute([])).to be_nil
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'returns nil unless order is eligible' do
|
16
|
+
empty_order = double('Spree::Order')
|
17
|
+
allow(empty_order).to receive(:line_items).and_return([])
|
18
|
+
expect(subject.compute(empty_order)).to be_nil
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'with order' do
|
22
|
+
before do
|
23
|
+
@order = double('Spree::Order')
|
24
|
+
product = build_stubbed(:product)
|
25
|
+
variant = double('Spree::Variant', product: product)
|
26
|
+
price = double('Spree::Price', variant: variant, amount: 5.00)
|
27
|
+
line_item = double('Spree::LineItem', variant: variant, order: @order, quantity: 1, price: 4.99)
|
28
|
+
|
29
|
+
allow(variant).to receive(:default_price).and_return(price)
|
30
|
+
allow(@order).to receive(:line_items).and_return([line_item])
|
31
|
+
|
32
|
+
related_product = create(:product)
|
33
|
+
relation_type = create(:relation_type)
|
34
|
+
|
35
|
+
create(:relation, relatable: product, related_to: related_product, relation_type: relation_type, discount_amount: 1.0)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'returns total count of Array' do
|
39
|
+
objects = Array.new { @order }
|
40
|
+
expect(subject.compute(objects)).to be_nil
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'returns total count' do
|
44
|
+
expect(subject.compute(@order)).to be_zero
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
RSpec.describe Spree::Product, type: :model do
|
2
|
+
context 'class' do
|
3
|
+
describe '.relation_types' do
|
4
|
+
it 'returns all the RelationTypes in use for this Product' do
|
5
|
+
relation_type = create(:relation_type)
|
6
|
+
expect(described_class.relation_types).to include(relation_type)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
context 'relations' do
|
12
|
+
it { is_expected.to have_many(:relations) }
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'instance' do
|
16
|
+
let(:other1) { create(:product) }
|
17
|
+
let(:other2) { create(:product) }
|
18
|
+
|
19
|
+
before do
|
20
|
+
@product = create(:product)
|
21
|
+
@relation_type = create(:relation_type, name: 'Related Products')
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '.relations' do
|
25
|
+
it 'has many relations' do
|
26
|
+
relation1 = create(:relation, relatable: @product, related_to: other1, relation_type: @relation_type)
|
27
|
+
relation2 = create(:relation, relatable: @product, related_to: other2, relation_type: @relation_type)
|
28
|
+
|
29
|
+
@product.reload
|
30
|
+
expect(@product.relations).to include(relation1)
|
31
|
+
expect(@product.relations).to include(relation2)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'has many relations for different RelationTypes' do
|
35
|
+
other_relation_type = Spree::RelationType.new(name: 'Recommended Products')
|
36
|
+
|
37
|
+
relation1 = create(:relation, relatable: @product, related_to: other1, relation_type: @relation_type)
|
38
|
+
relation2 = create(:relation, relatable: @product, related_to: other1, relation_type: other_relation_type)
|
39
|
+
|
40
|
+
@product.reload
|
41
|
+
expect(@product.relations).to include(relation1)
|
42
|
+
expect(@product.relations).to include(relation2)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe 'RelationType finders' do
|
47
|
+
before do
|
48
|
+
@relation = create(:relation, relatable: @product, related_to: other1, relation_type: @relation_type)
|
49
|
+
@product.reload
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'returns the relevant relations' do
|
53
|
+
expect(@product.related_products).to include(other1)
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'recognizes the method with has_related_products?(method)' do
|
57
|
+
expect(@product.has_related_products?('related_products')).to be_truthy
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'does not recognize non-existent methods with has_related_products?(method)' do
|
61
|
+
expect(@product.has_related_products?('unrelated_products')).not_to be_truthy
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'is the pluralised form of the RelationType name' do
|
65
|
+
@relation_type.update_attributes(name: 'Related Product')
|
66
|
+
expect(@product.related_products).to include(other1)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'does not return relations for another RelationType' do
|
70
|
+
other_relation_type = Spree::RelationType.new(name: 'Recommended Products')
|
71
|
+
|
72
|
+
create(:relation, relatable: @product, related_to: other1, relation_type: @relation_type)
|
73
|
+
create(:relation, relatable: @product, related_to: other2, relation_type: other_relation_type)
|
74
|
+
|
75
|
+
@product.reload
|
76
|
+
expect(@product.related_products).to include(other1)
|
77
|
+
expect(@product.related_products).not_to include(other2)
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'does not return Products that are deleted' do
|
81
|
+
other1.update_attributes(deleted_at: Time.now)
|
82
|
+
expect(@product.related_products).to be_blank
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'does not return Products that are not yet available' do
|
86
|
+
other1.update_attributes(available_on: Time.now + 1.hour)
|
87
|
+
expect(@product.related_products).to be_blank
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'does not return Products where available_on are blank' do
|
91
|
+
other1.update_attributes(available_on: nil)
|
92
|
+
expect(@product.related_products).to be_blank
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'returns all results when .relation_filter is nil' do
|
96
|
+
expect(described_class).to receive(:relation_filter).and_return(nil)
|
97
|
+
other1.update_attributes(available_on: Time.now + 1.hour)
|
98
|
+
expect(@product.related_products).to include(other1)
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'with an enhanced Product.relation_filter' do
|
102
|
+
it 'restricts the filter' do
|
103
|
+
relation_filter = described_class.relation_filter
|
104
|
+
expect(described_class).to receive(:relation_filter).at_least(:once).and_return(relation_filter.includes(:master).where('spree_variants.cost_price > 20'))
|
105
|
+
|
106
|
+
other1.master.update_attributes(cost_price: 10)
|
107
|
+
other2.master.update_attributes(cost_price: 30)
|
108
|
+
|
109
|
+
create(:relation, relatable: @product, related_to: other2, relation_type: @relation_type)
|
110
|
+
results = @product.related_products
|
111
|
+
expect(results).not_to include(other1)
|
112
|
+
expect(results).to include(other2)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
context 'instance when relation_types table is missing' do
|
119
|
+
it 'method missing should not throw ActiveRecord::StatementInvalid when the spree_relation_types table is missing' do
|
120
|
+
described_class.connection.rename_table('spree_relation_types', 'missing_relation_types')
|
121
|
+
begin
|
122
|
+
product = described_class.new
|
123
|
+
expect { product.foo }.to raise_error(NameError)
|
124
|
+
ensure
|
125
|
+
described_class.connection.rename_table('missing_relation_types', 'spree_relation_types')
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|