solidus_importer 0.1.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/.circleci/config.yml +35 -0
- data/.gem_release.yml +5 -0
- data/.github/stale.yml +17 -0
- data/.gitignore +20 -0
- data/.hound.yml +8 -0
- data/.rspec +2 -0
- data/.rubocop.yml +2 -0
- data/Gemfile +33 -0
- data/LICENSE +26 -0
- data/README.md +170 -0
- data/Rakefile +6 -0
- data/app/assets/javascripts/spree/backend/solidus_importer.js +2 -0
- data/app/assets/javascripts/spree/frontend/solidus_importer.js +2 -0
- data/app/assets/stylesheets/spree/backend/solidus_importer.css +16 -0
- data/app/assets/stylesheets/spree/frontend/solidus_importer.css +4 -0
- data/app/controllers/spree/admin/solidus_importer/import_rows_controller.rb +24 -0
- data/app/controllers/spree/admin/solidus_importer/imports_controller.rb +44 -0
- data/app/jobs/solidus_importer/import_job.rb +30 -0
- data/app/models/solidus_importer/import.rb +48 -0
- data/app/models/solidus_importer/row.rb +26 -0
- data/app/views/spree/admin/solidus_importer/import_rows/show.html.erb +46 -0
- data/app/views/spree/admin/solidus_importer/imports/_form.html.erb +14 -0
- data/app/views/spree/admin/solidus_importer/imports/index.html.erb +80 -0
- data/app/views/spree/admin/solidus_importer/imports/new.html.erb +13 -0
- data/app/views/spree/admin/solidus_importer/imports/show.html.erb +87 -0
- data/bin/console +17 -0
- data/bin/rails +7 -0
- data/bin/rails-engine +13 -0
- data/bin/rails-sandbox +16 -0
- data/bin/rake +7 -0
- data/bin/sandbox +84 -0
- data/bin/setup +8 -0
- data/config/initializers/spree.rb +11 -0
- data/config/locales/en.yml +28 -0
- data/config/routes.rb +11 -0
- data/db/migrate/20191216101011_create_solidus_importer_imports.rb +19 -0
- data/db/migrate/20191216101012_create_solidus_importer_rows.rb +14 -0
- data/examples/importers/custom_importer.rb +20 -0
- data/examples/processors/notify_on_failure.rb +22 -0
- data/lib/generators/solidus_importer/install/install_generator.rb +22 -0
- data/lib/solidus_importer.rb +25 -0
- data/lib/solidus_importer/base_importer.rb +26 -0
- data/lib/solidus_importer/configuration.rb +39 -0
- data/lib/solidus_importer/engine.rb +23 -0
- data/lib/solidus_importer/exception.rb +5 -0
- data/lib/solidus_importer/factories.rb +4 -0
- data/lib/solidus_importer/process_import.rb +88 -0
- data/lib/solidus_importer/process_row.rb +46 -0
- data/lib/solidus_importer/processors/address.rb +47 -0
- data/lib/solidus_importer/processors/base.rb +15 -0
- data/lib/solidus_importer/processors/customer.rb +41 -0
- data/lib/solidus_importer/processors/log.rb +15 -0
- data/lib/solidus_importer/processors/option_types.rb +43 -0
- data/lib/solidus_importer/processors/option_values.rb +49 -0
- data/lib/solidus_importer/processors/order.rb +40 -0
- data/lib/solidus_importer/processors/product.rb +51 -0
- data/lib/solidus_importer/processors/product_images.rb +30 -0
- data/lib/solidus_importer/processors/taxon.rb +52 -0
- data/lib/solidus_importer/processors/variant.rb +51 -0
- data/lib/solidus_importer/processors/variant_images.rb +30 -0
- data/lib/solidus_importer/version.rb +5 -0
- data/solidus_importer.gemspec +36 -0
- data/spec/factories/solidus_importer_imports.rb +27 -0
- data/spec/factories/solidus_importer_rows.rb +82 -0
- data/spec/features/admin/solidus_importer/import_rows_spec.rb +30 -0
- data/spec/features/admin/solidus_importer/imports_spec.rb +121 -0
- data/spec/features/solidus_importer/import_spec.rb +138 -0
- data/spec/features/solidus_importer/processors_spec.rb +53 -0
- data/spec/fixtures/solidus_importer/apparel.csv +23 -0
- data/spec/fixtures/solidus_importer/customers.csv +3 -0
- data/spec/fixtures/solidus_importer/home-and-garden.csv +22 -0
- data/spec/fixtures/solidus_importer/invalid_headers.csv +3 -0
- data/spec/fixtures/solidus_importer/invalid_product.csv +2 -0
- data/spec/fixtures/solidus_importer/jewelery.csv +55 -0
- data/spec/fixtures/solidus_importer/orders.csv +5 -0
- data/spec/fixtures/solidus_importer/products.csv +8 -0
- data/spec/fixtures/solidus_importer/thinking-cat.jpg +0 -0
- data/spec/jobs/solidus_importer/import_job_spec.rb +54 -0
- data/spec/lib/solidus_importer/base_importer_spec.rb +23 -0
- data/spec/lib/solidus_importer/process_import_spec.rb +74 -0
- data/spec/lib/solidus_importer/process_row_spec.rb +24 -0
- data/spec/lib/solidus_importer/processors/address_spec.rb +18 -0
- data/spec/lib/solidus_importer/processors/base_spec.rb +9 -0
- data/spec/lib/solidus_importer/processors/customer_spec.rb +65 -0
- data/spec/lib/solidus_importer/processors/log_spec.rb +18 -0
- data/spec/lib/solidus_importer/processors/option_types_spec.rb +38 -0
- data/spec/lib/solidus_importer/processors/option_values_spec.rb +43 -0
- data/spec/lib/solidus_importer/processors/order_spec.rb +56 -0
- data/spec/lib/solidus_importer/processors/product_images_spec.rb +42 -0
- data/spec/lib/solidus_importer/processors/product_spec.rb +66 -0
- data/spec/lib/solidus_importer/processors/taxon_spec.rb +33 -0
- data/spec/lib/solidus_importer/processors/variant_images_spec.rb +44 -0
- data/spec/lib/solidus_importer/processors/variant_spec.rb +86 -0
- data/spec/lib/solidus_importer_spec.rb +14 -0
- data/spec/models/solidus_importer/import_spec.rb +60 -0
- data/spec/models/solidus_importer/row_spec.rb +18 -0
- data/spec/spec_helper.rb +27 -0
- data/spec/support/solidus_importer_helpers.rb +13 -0
- metadata +227 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe SolidusImporter::Processors::OptionValues do
|
|
6
|
+
describe '#call' do
|
|
7
|
+
subject(:described_method) { described_class.call(context) }
|
|
8
|
+
|
|
9
|
+
let(:context) { { data: data, variant: variant } }
|
|
10
|
+
let(:variant) { create :base_variant }
|
|
11
|
+
let(:product) { variant.product }
|
|
12
|
+
let(:color) { create :option_type, presentation: 'Color' }
|
|
13
|
+
let(:size) { create :option_type, presentation: 'Size' }
|
|
14
|
+
let(:data) do
|
|
15
|
+
{
|
|
16
|
+
'Option1 Name' => 'Size',
|
|
17
|
+
'Option1 Value' => 'L',
|
|
18
|
+
'Option2 Name' => 'Color',
|
|
19
|
+
'Option2 Value' => 'Black'
|
|
20
|
+
}
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
before { product.option_types << size << color }
|
|
24
|
+
|
|
25
|
+
context 'when "Option(1,2,3) Value" are present' do
|
|
26
|
+
it 'create option values for variant in row' do
|
|
27
|
+
expect { described_method }.to change(variant.option_values, :count).from(0).to(2)
|
|
28
|
+
expect(variant.option_values.first.presentation).to eq 'L'
|
|
29
|
+
expect(variant.option_values.first.name).to eq 'L'
|
|
30
|
+
expect(variant.option_values.last.presentation).to eq 'Black'
|
|
31
|
+
expect(variant.option_values.last.name).to eq 'Black'
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'creates "Black" option value for related "Color" option type' do
|
|
35
|
+
described_method
|
|
36
|
+
black = variant.option_values.find_by(presentation: 'Black')
|
|
37
|
+
l = variant.option_values.find_by(presentation: 'L')
|
|
38
|
+
expect(black.option_type).to eq color
|
|
39
|
+
expect(l.option_type).to eq size
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe SolidusImporter::Processors::Order do
|
|
6
|
+
describe '#call' do
|
|
7
|
+
subject(:described_method) { described_class.call(context) }
|
|
8
|
+
|
|
9
|
+
let(:context) { {} }
|
|
10
|
+
|
|
11
|
+
context 'without order number in row data' do
|
|
12
|
+
let(:context) do
|
|
13
|
+
{ data: 'Some data' }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'raises an exception' do
|
|
17
|
+
expect { described_method }.to raise_error(SolidusImporter::Exception, 'Missing required key: "Name"')
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context 'with an order row with a file entity' do
|
|
22
|
+
let(:context) do
|
|
23
|
+
{ data: data }
|
|
24
|
+
end
|
|
25
|
+
let(:data) { build(:solidus_importer_row_order, :with_import).data }
|
|
26
|
+
let(:result) { context.merge(order: Spree::Order.last) }
|
|
27
|
+
|
|
28
|
+
before { allow(Spree::Store).to receive(:default).and_return(build_stubbed(:store)) }
|
|
29
|
+
|
|
30
|
+
it 'creates a new order' do
|
|
31
|
+
expect { described_method }.to change { Spree::Order.count }.by(1)
|
|
32
|
+
expect(described_method).to eq(result)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
context 'with an existing valid order' do
|
|
36
|
+
let!(:order) { create(:order, number: data['Name'], email: data['Email']) }
|
|
37
|
+
|
|
38
|
+
it 'updates the order' do
|
|
39
|
+
expect { described_method }.not_to(change{ Spree::Order.count })
|
|
40
|
+
expect(described_method).to eq(result)
|
|
41
|
+
expect(order.reload.email).to eq('an_email@example.com')
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
context 'with an existing invalid order' do
|
|
46
|
+
let!(:order) { create(:order, number: data['Name'], email: data['Email']) }
|
|
47
|
+
|
|
48
|
+
before { order.update_column(:state, 'an invalid state') }
|
|
49
|
+
|
|
50
|
+
it 'raises an exception' do
|
|
51
|
+
expect { described_method }.to raise_error(ActiveRecord::RecordInvalid, /State is invalid/)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe SolidusImporter::Processors::ProductImages do
|
|
6
|
+
describe '#call' do
|
|
7
|
+
subject(:described_method) { described_class.call(context) }
|
|
8
|
+
|
|
9
|
+
let(:context) { {} }
|
|
10
|
+
|
|
11
|
+
context 'without "Image Src" attribute in row data' do
|
|
12
|
+
let(:context) do
|
|
13
|
+
{ data: { 'Some attr' => 'some value' }, product: build_stubbed(:product) }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'returns nothing' do
|
|
17
|
+
expect(described_method).to be_nil
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context 'with a product and a invalid image in row data' do
|
|
22
|
+
let(:context) do
|
|
23
|
+
{ data: { 'Image Src' => 'some missing image' }, product: build_stubbed(:product) }
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'raises an exception' do
|
|
27
|
+
expect { described_method }.to raise_error(Errno::ENOENT, /No such file or directory/)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
context 'with a product and a valid image in row data' do
|
|
32
|
+
let(:image_path) { solidus_importer_fixture_path('thinking-cat.jpg') }
|
|
33
|
+
let(:context) do
|
|
34
|
+
{ data: { 'Image Src' => image_path }, product: build_stubbed(:product) }
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'adds images to the product' do
|
|
38
|
+
expect { described_method }.to change(context[:product].images, :any?).from(false).to(true)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe SolidusImporter::Processors::Product do
|
|
6
|
+
describe '#call' do
|
|
7
|
+
subject(:described_method) { described_class.call(context) }
|
|
8
|
+
|
|
9
|
+
let(:context) { {} }
|
|
10
|
+
|
|
11
|
+
context 'without product slug in row data' do
|
|
12
|
+
let(:context) do
|
|
13
|
+
{ data: 'Some data' }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'raises an exception' do
|
|
17
|
+
expect { described_method }.to raise_error(SolidusImporter::Exception, 'Missing required key: "Handle"')
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context 'with a product row with a file entity' do
|
|
22
|
+
let(:context) do
|
|
23
|
+
{ data: data }
|
|
24
|
+
end
|
|
25
|
+
let(:data) { build(:solidus_importer_row_product, :with_import).data }
|
|
26
|
+
let(:product) { Spree::Product.last }
|
|
27
|
+
let(:result) { context.merge(product: product) }
|
|
28
|
+
let!(:shipping_category) { create(:shipping_category) }
|
|
29
|
+
|
|
30
|
+
it 'creates a new product' do
|
|
31
|
+
expect { described_method }.to change { Spree::Product.count }.by(1)
|
|
32
|
+
expect(described_method).to eq(result)
|
|
33
|
+
expect(product).not_to be_available
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
context 'when "Published" is "true"' do
|
|
37
|
+
before { data.merge! 'Published' => 'true' }
|
|
38
|
+
|
|
39
|
+
it 'creates an available product' do
|
|
40
|
+
described_method
|
|
41
|
+
expect(product).to be_available
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
context 'when "Published" is false' do
|
|
46
|
+
before { data.merge! 'Published' => 'false' }
|
|
47
|
+
|
|
48
|
+
it 'creates an available product' do
|
|
49
|
+
described_method
|
|
50
|
+
expect(product).not_to be_available
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
context 'with an existing valid product' do
|
|
55
|
+
let(:result) { { data: data, product: product } }
|
|
56
|
+
let!(:product) { create(:product, slug: data['Handle']) }
|
|
57
|
+
|
|
58
|
+
it 'updates the product' do
|
|
59
|
+
expect { described_method }.not_to(change { Spree::Product.count })
|
|
60
|
+
expect(described_method).to eq(result)
|
|
61
|
+
expect(product.reload.name).to eq('A product name')
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe SolidusImporter::Processors::Taxon do
|
|
6
|
+
describe '#call' do
|
|
7
|
+
subject(:described_method) { described_class.call(context) }
|
|
8
|
+
|
|
9
|
+
let!(:shipping_category) { create :shipping_category }
|
|
10
|
+
let(:context) { { data: data, product: product } }
|
|
11
|
+
let(:product) { create :product }
|
|
12
|
+
let(:data) { build(:solidus_importer_row_product, :with_import, :with_type, :with_tags).data }
|
|
13
|
+
let(:tags_taxonomy) { Spree::Taxonomy.find_by(name: 'Tags') }
|
|
14
|
+
let(:type_taxonomy) { Spree::Taxonomy.find_by(name: 'Type') }
|
|
15
|
+
|
|
16
|
+
it 'create a taxon for each tag, related to the given taxonomy' do
|
|
17
|
+
expect { described_method }.to change(product.taxons, :count).by(4)
|
|
18
|
+
|
|
19
|
+
%w[Type1 Tag1 Tag2 Tag3].each do |taxon_name|
|
|
20
|
+
expect(product.taxons.map(&:name)).to include(taxon_name)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
expect(Spree::Taxon.find_by(name: 'Tag1').taxonomy).to eq tags_taxonomy
|
|
24
|
+
expect(Spree::Taxon.find_by(name: 'Type1').taxonomy).to eq type_taxonomy
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'creates "Type" and "Tags" taxonomies' do
|
|
28
|
+
described_method
|
|
29
|
+
expect(type_taxonomy).to be_present
|
|
30
|
+
expect(tags_taxonomy).to be_present
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe SolidusImporter::Processors::VariantImages do
|
|
6
|
+
describe '#call' do
|
|
7
|
+
subject(:described_method) { described_class.call(context) }
|
|
8
|
+
|
|
9
|
+
let(:context) { {} }
|
|
10
|
+
|
|
11
|
+
context 'without "Variant Image" attribute in row data' do
|
|
12
|
+
let(:context) do
|
|
13
|
+
{ data: { 'Some attr' => 'some value' }, product: build_stubbed(:product) }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'returns nothing' do
|
|
17
|
+
expect(described_method).to be_nil
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context 'with a variant and a invalid image in row data' do
|
|
22
|
+
let(:context) do
|
|
23
|
+
{ data: { 'Variant Image' => 'some missing image' }, variant: build_stubbed(:variant) }
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'raises an exception' do
|
|
27
|
+
expect { described_method }.to raise_error(Errno::ENOENT, /No such file or directory/)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
context 'with a variant and a valid image in row data' do
|
|
32
|
+
let(:context) do
|
|
33
|
+
{
|
|
34
|
+
data: { 'Variant Image' => solidus_importer_fixture_path('thinking-cat.jpg') },
|
|
35
|
+
variant: build_stubbed(:variant)
|
|
36
|
+
}
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'adds images to the variant' do
|
|
40
|
+
expect { described_method }.to change(context[:variant].images, :any?).from(false).to(true)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe SolidusImporter::Processors::Variant do
|
|
6
|
+
describe '#call' do
|
|
7
|
+
subject(:described_method) { described_class.call(context) }
|
|
8
|
+
|
|
9
|
+
let(:context) { {} }
|
|
10
|
+
|
|
11
|
+
context 'without a target product' do
|
|
12
|
+
let(:context) do
|
|
13
|
+
{ data: { 'Variant SKU' => 'some SKU' }, product: nil }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'raises an exception' do
|
|
17
|
+
expect { described_method }.to raise_error(ArgumentError, 'missing :product in context')
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context 'with a variant row, a product and a source file' do
|
|
22
|
+
let(:context) do
|
|
23
|
+
{ data: data, product: product }
|
|
24
|
+
end
|
|
25
|
+
let(:data) { build(:solidus_importer_row_variant, :with_import).data }
|
|
26
|
+
let!(:product) { create(:product, slug: data['Handle']) }
|
|
27
|
+
|
|
28
|
+
before do
|
|
29
|
+
allow(Spree::ShippingCategory).to receive(:last).and_return(build_stubbed(:shipping_category))
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
context 'when "Option1 Value" is "Some value"' do
|
|
33
|
+
let(:result) { context.merge(variant: product.variants.first) }
|
|
34
|
+
|
|
35
|
+
before { data.merge! 'Option1 Value' => 'Some value' }
|
|
36
|
+
|
|
37
|
+
it 'creates a new variant' do
|
|
38
|
+
expect { described_method }.to change { Spree::Variant.count }.by(1)
|
|
39
|
+
expect(described_method).to eq(result)
|
|
40
|
+
expect(product.variants.first.weight).to eq 20.0
|
|
41
|
+
expect(product.variants.first.price).to eq 60.5
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
context 'when "Option1 Value" is "Default Title"' do
|
|
46
|
+
let(:result) { context.merge(variant: product.master) }
|
|
47
|
+
|
|
48
|
+
before { data.merge! 'Option1 Value' => 'Default Title' }
|
|
49
|
+
|
|
50
|
+
it 'updates master variant' do
|
|
51
|
+
expect { described_method }.not_to(change { Spree::Variant.count })
|
|
52
|
+
expect(described_method).to eq(result)
|
|
53
|
+
expect(product.master.weight).to eq 20.0
|
|
54
|
+
expect(product.master.price).to eq 60.5
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
context 'when "Option1 Value" is blank' do
|
|
59
|
+
let(:result) { context.merge(variant: product.master) }
|
|
60
|
+
|
|
61
|
+
before { data.merge! 'Option1 Value' => nil }
|
|
62
|
+
|
|
63
|
+
it 'updates master variant' do
|
|
64
|
+
expect { described_method }.not_to(change { Spree::Variant.count })
|
|
65
|
+
expect(described_method).to eq(result)
|
|
66
|
+
expect(product.master.weight).to eq 20.0
|
|
67
|
+
expect(product.master.price).to eq 60.5
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
context 'with an existing valid variant' do
|
|
72
|
+
let(:result) { context.merge(variant: variant) }
|
|
73
|
+
let!(:variant) { create(:variant, sku: data['Variant SKU'], price: 0, weight: 10.0) }
|
|
74
|
+
|
|
75
|
+
before { data.merge! 'Option1 Value' => 'Some value' }
|
|
76
|
+
|
|
77
|
+
it 'updates the variant' do
|
|
78
|
+
expect { described_method }.not_to(change { Spree::Variant.count })
|
|
79
|
+
expect(described_method).to eq(result)
|
|
80
|
+
expect(variant.reload.weight.to_f).to eq(data['Variant Weight'])
|
|
81
|
+
expect(variant.reload.price).to eq(data['Variant Price'])
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe SolidusImporter do
|
|
6
|
+
describe '.import!' do
|
|
7
|
+
subject(:described_method) { described_class.import!('target-import.csv', type: 'customers') }
|
|
8
|
+
|
|
9
|
+
it 'invokes ProcessImport#import_from_file' do
|
|
10
|
+
expect(SolidusImporter::ProcessImport).to receive(:import_from_file).with('target-import.csv', :customers)
|
|
11
|
+
subject
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe SolidusImporter::Import do
|
|
6
|
+
subject(:described_instance) { described_class.new }
|
|
7
|
+
|
|
8
|
+
it { expect(described_instance).not_to be_valid }
|
|
9
|
+
|
|
10
|
+
context 'with an import file and type' do
|
|
11
|
+
before do
|
|
12
|
+
described_instance.import_type = :customers
|
|
13
|
+
described_instance.import_file = solidus_importer_fixture_path('customers.csv')
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it { expect(described_instance).to be_valid }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe '#import_file=' do
|
|
20
|
+
subject(:described_method) { described_instance.import_file = some_file }
|
|
21
|
+
|
|
22
|
+
let(:some_file) { nil }
|
|
23
|
+
|
|
24
|
+
it { expect { described_method }.to raise_error(SolidusImporter::Exception) }
|
|
25
|
+
|
|
26
|
+
context 'with a file' do
|
|
27
|
+
let(:some_file) { __FILE__ }
|
|
28
|
+
|
|
29
|
+
it { expect { described_method }.to change { described_instance.file.present? }.from(false).to(true) }
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
describe '#finished?' do
|
|
34
|
+
subject(:described_method) { described_instance.finished? }
|
|
35
|
+
|
|
36
|
+
let(:rows) { OpenStruct.new }
|
|
37
|
+
let(:finished_rows) { [] }
|
|
38
|
+
let(:size) { 0 }
|
|
39
|
+
|
|
40
|
+
before do
|
|
41
|
+
allow(rows).to receive_messages(failed_or_completed: finished_rows, size: size)
|
|
42
|
+
allow(described_instance).to receive_messages(rows: rows)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it { is_expected.to be_truthy }
|
|
46
|
+
|
|
47
|
+
context 'with some rows' do
|
|
48
|
+
let(:finished_rows) { [1, 2] }
|
|
49
|
+
let(:size) { 3 }
|
|
50
|
+
|
|
51
|
+
it { is_expected.to be_falsey }
|
|
52
|
+
|
|
53
|
+
context 'with the size equals to the number of failed or completed rows' do
|
|
54
|
+
let(:size) { finished_rows.size }
|
|
55
|
+
|
|
56
|
+
it { is_expected.to be_truthy }
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|