datashift 0.2.1 → 0.2.2

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 (84) hide show
  1. data/.document +5 -5
  2. data/LICENSE.txt +26 -26
  3. data/README.markdown +326 -305
  4. data/README.rdoc +19 -19
  5. data/Rakefile +86 -93
  6. data/VERSION +1 -1
  7. data/datashift.gemspec +163 -152
  8. data/lib/applications/jruby/jexcel_file.rb +410 -408
  9. data/lib/applications/jruby/word.rb +79 -79
  10. data/lib/datashift.rb +183 -152
  11. data/lib/datashift/exceptions.rb +11 -11
  12. data/lib/datashift/file_definitions.rb +353 -353
  13. data/lib/datashift/mapping_file_definitions.rb +87 -87
  14. data/lib/datashift/method_detail.rb +293 -275
  15. data/lib/datashift/method_dictionary.rb +208 -209
  16. data/lib/datashift/method_mapper.rb +90 -90
  17. data/lib/datashift/model_mapper.rb +27 -0
  18. data/lib/exporters/csv_exporter.rb +36 -0
  19. data/lib/exporters/excel_exporter.rb +116 -0
  20. data/lib/exporters/exporter_base.rb +15 -0
  21. data/lib/generators/csv_generator.rb +36 -36
  22. data/lib/generators/excel_generator.rb +106 -122
  23. data/lib/generators/generator_base.rb +13 -13
  24. data/lib/helpers/core_ext/to_b.rb +24 -24
  25. data/lib/helpers/rake_utils.rb +42 -0
  26. data/lib/helpers/spree_helper.rb +194 -153
  27. data/lib/java/poi-3.7/LICENSE +507 -507
  28. data/lib/java/poi-3.7/NOTICE +21 -21
  29. data/lib/java/poi-3.7/RELEASE_NOTES.txt +115 -115
  30. data/lib/loaders/csv_loader.rb +98 -98
  31. data/lib/loaders/excel_loader.rb +155 -155
  32. data/lib/loaders/loader_base.rb +420 -420
  33. data/lib/loaders/spreadsheet_loader.rb +136 -136
  34. data/lib/loaders/spree/image_loader.rb +67 -63
  35. data/lib/loaders/spree/product_loader.rb +289 -248
  36. data/lib/thor/generate_excel.thor +54 -0
  37. data/sandbox/app/controllers/application_controller.rb +3 -0
  38. data/sandbox/config/application.rb +43 -0
  39. data/sandbox/config/database.yml +34 -0
  40. data/sandbox/config/environment.rb +7 -0
  41. data/sandbox/config/environments/development.rb +30 -0
  42. data/spec/csv_loader_spec.rb +30 -30
  43. data/spec/datashift_spec.rb +26 -26
  44. data/spec/db/migrate/20110803201325_create_test_bed.rb +85 -85
  45. data/spec/excel_exporter_spec.rb +78 -78
  46. data/spec/excel_generator_spec.rb +78 -78
  47. data/spec/excel_loader_spec.rb +223 -223
  48. data/spec/file_definitions.rb +141 -141
  49. data/spec/fixtures/ProjectsDefaults.yml +29 -29
  50. data/spec/fixtures/config/database.yml +27 -27
  51. data/spec/fixtures/datashift_Spree_db.sqlite +0 -0
  52. data/spec/fixtures/datashift_test_models_db.sqlite +0 -0
  53. data/spec/fixtures/negative/SpreeProdMiss1Mandatory.csv +4 -4
  54. data/spec/fixtures/negative/SpreeProdMissManyMandatory.csv +4 -4
  55. data/spec/fixtures/spree/SpreeProducts.csv +4 -4
  56. data/spec/fixtures/spree/SpreeProducts.xls +0 -0
  57. data/spec/fixtures/spree/SpreeProductsMultiColumn.csv +4 -4
  58. data/spec/fixtures/spree/SpreeProductsMultiColumn.xls +0 -0
  59. data/spec/fixtures/spree/SpreeProductsSimple.csv +4 -4
  60. data/spec/fixtures/spree/SpreeProductsWithImages.csv +4 -4
  61. data/spec/fixtures/spree/SpreeZoneExample.csv +5 -5
  62. data/spec/fixtures/test_model_defs.rb +57 -57
  63. data/spec/loader_spec.rb +120 -120
  64. data/spec/method_dictionary_spec.rb +242 -242
  65. data/spec/method_mapper_spec.rb +41 -41
  66. data/spec/spec_helper.rb +154 -116
  67. data/spec/spree_exporter_spec.rb +67 -0
  68. data/spec/spree_generator_spec.rb +77 -64
  69. data/spec/spree_loader_spec.rb +363 -324
  70. data/spec/spree_method_mapping_spec.rb +218 -214
  71. data/tasks/config/seed_fu_product_template.erb +15 -15
  72. data/tasks/config/tidy_config.txt +12 -12
  73. data/tasks/{excel_generator.rake → export/excel_generator.rake} +101 -78
  74. data/tasks/file_tasks.rake +36 -36
  75. data/tasks/import/csv.rake +50 -49
  76. data/tasks/import/excel.rake +74 -71
  77. data/tasks/spree/image_load.rake +108 -108
  78. data/tasks/spree/product_loader.rake +43 -43
  79. data/tasks/word_to_seedfu.rake +166 -166
  80. data/test/helper.rb +18 -18
  81. data/test/test_interact.rb +7 -7
  82. metadata +16 -8
  83. data/datashift-0.1.0.gem +0 -0
  84. data/tasks/db_tasks.rake +0 -66
@@ -1,325 +1,364 @@
1
- # Copyright:: (c) Autotelik Media Ltd 2011
2
- # Author :: Tom Statter
3
- # Date :: Summer 2011
4
- #
5
- # License:: MIT - Free, OpenSource
6
- #
7
- # Details:: Specification for Spree aspect of datashift gem.
8
- #
9
- # Provides Loaders and rake tasks specifically tailored for uploading or exporting
10
- # Spree Products, associations and Images
11
- #
12
- require File.dirname(__FILE__) + '/spec_helper'
13
-
14
- require 'spree_helper'
15
- require 'product_loader'
16
-
17
- include DataShift
18
-
19
- describe 'SpreeLoader' do
20
-
21
- before(:all) do
22
-
23
- # key to YAML db e.g test_memory, test_mysql
24
- db_connect( 'test_spree_standalone' )
25
-
26
- # See errors #<NameError: uninitialized constant RAILS_CACHE> when doing save (AR without Rails)
27
- # so copied this from ... Rails::Initializer.initialize_cache
28
- Object.const_set "RAILS_CACHE", ActiveSupport::Cache.lookup_store( :memory_store )
29
-
30
- RAILS_CACHE = ActiveSupport::Cache.lookup_store( :memory_store )
31
-
32
- # we are not a Spree project, nor is it practical to externally generate
33
- # a complete Spree application for testing so we implement a mini migrate/boot of our own
34
- Spree.load() # require Spree gems
35
- Spree.boot # create a sort-of Spree app
36
-
37
- Spree.migrate_up # create an sqlite Spree database on the fly
38
-
39
- $SpreeFixturePath = File.join($DataShiftFixturePath, 'spree')
40
-
41
- $SpreeNegativeFixturePath = File.join($DataShiftFixturePath, 'negative')
42
- end
43
-
44
- def spree_fix( source)
45
- File.join($SpreeFixturePath, source)
46
- end
47
-
48
- before(:each) do
49
-
50
- MethodDictionary.clear
51
- MethodDictionary.find_operators( Product )
52
-
53
- # Reset main tables - TODO should really purge properly, or roll back a transaction
54
- [OptionType, OptionValue, Product, Property, Variant, Taxonomy, Taxon, Zone].each { |x| x.delete_all }
55
-
56
- Product.count.should == 0
57
-
58
- Taxon.count.should == 0
59
-
60
- # want to test both lookup and dynamic creation - this Taxonomy should be found, rest created
61
- root = Taxonomy.create( :name => 'Paintings' )
62
- Taxon.create( :name => 'Landscape', :taxonomy => root )
63
-
64
- Taxon.count.should == 2
65
-
66
-
67
- @product_loader = DataShift::Spree::ProductLoader.new
68
- end
69
-
70
-
71
- it "should process a simple .xls spreadsheet" do
72
-
73
- Zone.delete_all
74
-
75
- loader = ExcelLoader.new(Zone)
76
-
77
- loader.perform_load( spree_fix('SpreeZoneExample.xls') )
78
-
79
- loader.loaded_count.should == Zone.count
80
- end
81
-
82
- it "should process a simple csv file" do
83
-
84
- Zone.delete_all
85
-
86
- loader = CsvLoader.new(Zone)
87
-
88
- loader.perform_load( spree_fix('SpreeZoneExample.csv') )
89
-
90
- loader.loaded_count.should == Zone.count
91
- end
92
-
93
-
94
- # Loader should perform identically regardless of source, whether csv, .xls etc
95
-
96
- it "should load basic Products .xls via Spree loader", :focus => true do
97
- test_basic_product('SpreeProductsSimple.xls')
98
- end
99
-
100
- it "should load basic Products from .csv via Spree loader" do
101
- test_basic_product('SpreeProductsSimple.csv')
102
- end
103
-
104
- it "should raise an error for unsupported file types" do
105
- lambda { test_basic_product('SpreeProductsSimple.xml') }.should raise_error UnsupportedFileType
106
- end
107
-
108
- def test_basic_product( source )
109
-
110
- @product_loader.perform_load( spree_fix(source), :mandatory => ['sku', 'name', 'price'] )
111
-
112
- Product.count.should == 3
113
-
114
- @product_loader.failed_objects.size.should == 0
115
- @product_loader.loaded_objects.size.should == 3
116
-
117
- @product_loader.loaded_count.should == Product.count
118
-
119
- p = Product.first
120
-
121
- p.sku.should == "SIMPLE_001"
122
- p.price.should == 345.78
123
- p.name.should == "Simple Product for AR Loader"
124
- p.description.should == "blah blah"
125
- p.cost_price.should == 320.00
126
- p.option_types.should have_exactly(1).items
127
- p.count_on_hand.should == 12
128
-
129
- Product.last.option_types.should have_exactly(2).items
130
- Product.last.count_on_hand.should == 23
131
- end
132
-
133
-
134
- # Operation and results should be identical when loading multiple associations
135
- # if using either single column embedded syntax, or one column per entry.
136
-
137
- it "should load Products and create Variants from single column" do
138
- test_variants_creation('SpreeProducts.xls')
139
- end
140
-
141
-
142
- it "should load Products and create Variants from multiple column" do
143
- test_variants_creation('SpreeProductsMultiColumn.xls')
144
- end
145
-
146
- def test_variants_creation( source )
147
- @product_loader.perform_load( spree_fix(source), :mandatory => ['sku', 'name', 'price'] )
148
-
149
- expected_multi_column_variants
150
- end
151
-
152
-
153
- def expected_multi_column_variants
154
-
155
- # 3 MASTER products, 11 VARIANTS
156
- Product.count.should == 3
157
- Variant.count.should == 14
158
-
159
- p = Product.first
160
-
161
- p.sku.should == "DEMO_001"
162
-
163
- p.sku.should == "DEMO_001"
164
- p.price.should == 399.99
165
- p.description.should == "blah blah"
166
- p.cost_price.should == 320.00
167
-
168
- Product.all.select {|m| m.is_master.should == true }
169
-
170
- p.variants.should have_exactly(3).items
171
-
172
- Variant.all[1].sku.should == "DEMO_001_0"
173
- Variant.all[1].price.should == 399.99
174
-
175
- v = p.variants[0]
176
-
177
- v.sku.should == "DEMO_001_0"
178
- v.price.should == 399.99
179
- v.count_on_hand.should == 12
180
-
181
- p.variants[1].count_on_hand.should == 6
182
- p.variants[2].count_on_hand.should == 7
183
-
184
- Variant.last.price.should == 50.34
185
- Variant.last.count_on_hand.should == 18
186
-
187
- @product_loader.failed_objects.size.should == 0
188
- end
189
-
190
-
191
- # Operation and results should be identical when loading multiple associations
192
- # if using either single column embedded syntax, or one column per entry.
193
-
194
- it "should load Products and multiple Properties from single column" do
195
- test_properties_creation( 'SpreeProducts.xls' )
196
- end
197
-
198
- it "should load Products and multiple Properties from multiple column" do
199
- test_properties_creation( 'SpreeProductsMultiColumn.xls' )
200
- end
201
-
202
- def test_properties_creation( source )
203
-
204
- # want to test both lookup and dynamic creation - this Prop should be found, rest created
205
- Property.create( :name => 'test_pp_001', :presentation => 'Test PP 001' )
206
-
207
- Property.count.should == 1
208
-
209
- @product_loader.perform_load( spree_fix(source), :mandatory => ['sku', 'name', 'price'] )
210
-
211
- expected_multi_column_properties
212
-
213
- end
214
-
215
- def expected_multi_column_properties
216
- Property.count.should == 4
217
-
218
- Product.first.properties.should have_exactly(1).items
219
-
220
- p3 = Product.all.last
221
-
222
- p3.properties.should have_exactly(3).items
223
-
224
- p3.properties.should include Property.find_by_name('test_pp_002')
225
-
226
- # Test the optional text value got set on assigned product property
227
- p3.product_properties.select {|p| p.value == 'Example free value' }.should have_exactly(1).items
228
-
229
- end
230
-
231
- # Operation and results should be identical when loading multiple associations
232
- # if using either single column embedded syntax, or one column per entry.
233
-
234
- it "should load Products and multiple Taxons from single column" do
235
- test_taxon_creation( 'SpreeProducts.xls' )
236
- end
237
-
238
- it "should load Products and multiple Taxons from multiple columns" do
239
- test_taxon_creation( 'SpreeProductsMultiColumn.xls' )
240
- end
241
-
242
- def test_taxon_creation( source )
243
-
244
- @product_loader.perform_load( spree_fix(source), :mandatory => ['sku', 'name', 'price'] )
245
-
246
- expected_multi_column_taxons
247
- end
248
-
249
- def expected_multi_column_taxons
250
-
251
- Taxonomy.count.should == 4
252
- Taxon.count.should == 5
253
-
254
- Product.first.taxons.should have_exactly(2).items
255
- Product.last.taxons.should have_exactly(1).items
256
-
257
- p2 = Product.all[1]
258
-
259
- p2.taxons.should have_exactly(3).items
260
-
261
- t = Taxon.find_by_name('Oils')
262
-
263
- t.should_not be_nil
264
-
265
- p2.taxons.collect( &:id ).should include(t.id)
266
-
267
- end
268
-
269
- it "should load Products with associated image", :img => true do
270
-
271
- @product_loader.perform_load( spree_fix('SpreeProductsWithImages.csv'), :mandatory => ['sku', 'name', 'price'] )
272
-
273
- p = Product.find_by_name("Demo Product for AR Loader")
274
-
275
- p.images.should have_exactly(1).items
276
- end
277
-
278
-
279
- # REPEAT THE WHOLE TEST SUITE VIA CSV
280
-
281
- it "should load Products from single column csv as per .xls" do
282
- test_variants_creation('SpreeProducts.csv')
283
-
284
- expected_multi_column_properties
285
-
286
- expected_multi_column_taxons
287
- end
288
-
289
-
290
- it "should load Products from multiple column csv as per .xls" do
291
- test_variants_creation('SpreeProductsMultiColumn.csv')
292
-
293
- expected_multi_column_properties
294
-
295
- expected_multi_column_taxons
296
- end
297
-
298
- it "should load Products with assoicated image" do
299
- test_variants_creation('SpreeProductsMultiColumn.csv')
300
-
301
- expected_multi_column_properties
302
-
303
- expected_multi_column_taxons
304
- end
305
-
306
-
307
- it "should raise exception when mandatory columns missing from .xls", :ex => true do
308
- expect {@product_loader.perform_load($SpreeNegativeFixturePath + '/SpreeProdMissManyMandatory.xls', :mandatory => ['sku', 'name', 'price'] )}.to raise_error(DataShift::MissingMandatoryError)
309
- end
310
-
311
-
312
- it "should raise exception when single mandatory column missing from .xls", :ex => true do
313
- expect {@product_loader.perform_load($SpreeNegativeFixturePath + '/SpreeProdMiss1Mandatory.xls', :mandatory => 'sku' )}.to raise_error(DataShift::MissingMandatoryError)
314
- end
315
-
316
- it "should raise exception when mandatory columns missing from .csv", :ex => true do
317
- expect {@product_loader.perform_load($SpreeNegativeFixturePath + '/SpreeProdMissManyMandatory.csv', :mandatory => ['sku', 'name', 'price'] )}.to raise_error(DataShift::MissingMandatoryError)
318
- end
319
-
320
-
321
- it "should raise exception when single mandatory column missing from .csv", :ex => true do
322
- expect {@product_loader.perform_load($SpreeNegativeFixturePath + '/SpreeProdMiss1Mandatory.csv', :mandatory => 'sku' )}.to raise_error(DataShift::MissingMandatoryError)
323
- end
324
-
1
+ # Copyright:: (c) Autotelik Media Ltd 2011
2
+ # Author :: Tom Statter
3
+ # Date :: Summer 2011
4
+ #
5
+ # License:: MIT - Free, OpenSource
6
+ #
7
+ # Details:: Specification for Spree aspect of datashift gem.
8
+ #
9
+ # Provides Loaders and rake tasks specifically tailored for uploading or exporting
10
+ # Spree Products, associations and Images
11
+ #
12
+ require File.dirname(__FILE__) + '/spec_helper'
13
+
14
+ require 'spree_helper'
15
+ require 'product_loader'
16
+
17
+ include DataShift
18
+
19
+ describe 'SpreeLoader' do
20
+
21
+
22
+ before(:all) do
23
+ SpecHelper::before_all_spree
24
+ end
25
+
26
+ before(:each) do
27
+
28
+ begin
29
+
30
+ include SpecHelper
31
+ extend SpecHelper
32
+
33
+ before_each_spree
34
+
35
+ @klass.count.should == 0
36
+ @Taxon_klass.count.should == 0
37
+ @Variant_klass.count.should == 0
38
+
39
+ MethodDictionary.clear
40
+ MethodDictionary.find_operators( @klass )
41
+
42
+ # want to test both lookup and dynamic creation - this Taxonomy should be found, rest created
43
+ root = @Taxonomy_klass.create( :name => 'Paintings' )
44
+
45
+ @Taxon_klass.create( :name => 'Landscape', :taxonomy => root )
46
+
47
+ @Taxon_klass.count.should == 2
48
+
49
+ @product_loader = DataShift::SpreeHelper::ProductLoader.new
50
+ rescue => e
51
+ puts e.inspect
52
+ puts e.backtrace
53
+ end
54
+ end
55
+
56
+
57
+ it "should process a simple .xls spreadsheet" do
58
+
59
+ @zone_klass.delete_all
60
+
61
+ loader = ExcelLoader.new(@zone_klass)
62
+
63
+ loader.perform_load( SpecHelper::spree_fixture('SpreeZoneExample.xls') )
64
+
65
+ loader.loaded_count.should == @zone_klass.count
66
+ end
67
+
68
+ it "should process a simple csv file" do
69
+
70
+ @zone_klass.delete_all
71
+
72
+ loader = CsvLoader.new(@zone_klass)
73
+
74
+ loader.perform_load( SpecHelper::spree_fixture('SpreeZoneExample.csv') )
75
+
76
+ loader.loaded_count.should == @zone_klass.count
77
+ end
78
+
79
+
80
+ # Loader should perform identically regardless of source, whether csv, .xls etc
81
+
82
+ it "should load basic Products .xls via Spree loader" do
83
+ test_basic_product('SpreeProductsSimple.xls')
84
+ end
85
+
86
+ it "should load basic Products from .csv via Spree loader" do
87
+ test_basic_product('SpreeProductsSimple.csv')
88
+ end
89
+
90
+ it "should raise an error for unsupported file types" do
91
+ lambda { test_basic_product('SpreeProductsSimple.xml') }.should raise_error UnsupportedFileType
92
+ end
93
+
94
+ def test_basic_product( source )
95
+
96
+ @product_loader.perform_load( SpecHelper::spree_fixture(source), :mandatory => ['sku', 'name', 'price'] )
97
+
98
+ @klass.count.should == 3
99
+
100
+ @product_loader.failed_objects.size.should == 0
101
+ @product_loader.loaded_objects.size.should == 3
102
+
103
+ @product_loader.loaded_count.should == @klass.count
104
+
105
+ p = @klass.first
106
+
107
+ p.sku.should == "SIMPLE_001"
108
+ p.price.should == 345.78
109
+ p.name.should == "Simple Product for AR Loader"
110
+ p.description.should == "blah blah"
111
+ p.cost_price.should == 320.00
112
+ p.option_types.should have_exactly(1).items
113
+ p.count_on_hand.should == 12
114
+
115
+ @klass.last.option_types.should have_exactly(2).items
116
+ @klass.last.count_on_hand.should == 23
117
+ end
118
+
119
+
120
+ # Operation and results should be identical when loading multiple associations
121
+ # if using either single column embedded syntax, or one column per entry.
122
+
123
+ it "should load Products and create Variants from single column", :fail => true do
124
+ test_variants_creation('SpreeProducts.xls')
125
+ end
126
+
127
+
128
+ it "should load Products and create Variants from multiple column" do
129
+ test_variants_creation('SpreeProductsMultiColumn.xls')
130
+ end
131
+
132
+ def test_variants_creation( source )
133
+ @klass.count.should == 0
134
+ @Variant_klass.count.should == 0
135
+
136
+ @product_loader.perform_load( SpecHelper::spree_fixture(source), :mandatory => ['sku', 'name', 'price'] )
137
+
138
+ expected_multi_column_variants
139
+ end
140
+
141
+
142
+ def expected_multi_column_variants
143
+
144
+ # 3 MASTER products, 11 VARIANTS
145
+ @klass.count.should == 3
146
+ @Variant_klass.count.should == 14
147
+
148
+ p = @klass.first
149
+
150
+ p.sku.should == "DEMO_001"
151
+
152
+ p.sku.should == "DEMO_001"
153
+ p.price.should == 399.99
154
+ p.description.should == "blah blah"
155
+ p.cost_price.should == 320.00
156
+
157
+ @klass.all.select {|m| m.is_master.should == true }
158
+
159
+ p.variants.should have_exactly(3).items # count => 12|6|7
160
+
161
+ @Variant_klass.all[1].sku.should == "DEMO_001_0"
162
+ @Variant_klass.all[1].price.should == 399.99
163
+
164
+ v = p.variants[0]
165
+
166
+ v.sku.should == "DEMO_001_0"
167
+ v.price.should == 399.99
168
+ v.count_on_hand.should == 12
169
+
170
+ p.variants[1].count_on_hand.should == 6
171
+ p.variants[2].count_on_hand.should == 7
172
+
173
+ @Variant_klass.last.price.should == 50.34
174
+ @Variant_klass.last.count_on_hand.should == 18
175
+
176
+ @product_loader.failed_objects.size.should == 0
177
+ end
178
+
179
+ ##################
180
+ ### PROPERTIES ###
181
+ ##################
182
+
183
+ # Operation and results should be identical when loading multiple associations
184
+ # if using either single column embedded syntax, or one column per entry.
185
+
186
+ it "should load Products and multiple Properties from single column", :props => true do
187
+ test_properties_creation( 'SpreeProducts.xls' )
188
+ end
189
+
190
+ it "should load Products and multiple Properties from multiple column", :props => true do
191
+ test_properties_creation( 'SpreeProductsMultiColumn.xls' )
192
+ end
193
+
194
+ def test_properties_creation( source )
195
+
196
+ # want to test both lookup and dynamic creation - this Prop should be found, rest created
197
+ @Property_klass.create( :name => 'test_pp_001', :presentation => 'Test PP 001' )
198
+
199
+ @Property_klass.count.should == 1
200
+
201
+ @product_loader.perform_load( SpecHelper::spree_fixture(source), :mandatory => ['sku', 'name', 'price'] )
202
+
203
+ expected_multi_column_properties
204
+
205
+ end
206
+
207
+ def expected_multi_column_properties
208
+ # 3 MASTER products, 11 VARIANTS
209
+ @klass.count.should == 3
210
+ @Variant_klass.count.should == 14
211
+
212
+ @klass.first.properties.should have_exactly(1).items
213
+
214
+ p3 = @klass.all.last
215
+
216
+ p3.properties.should have_exactly(3).items
217
+
218
+ p3.properties.should include @Property_klass.find_by_name('test_pp_002')
219
+
220
+ # Test the optional text value got set on assigned product property
221
+ p3.product_properties.select {|p| p.value == 'Example free value' }.should have_exactly(1).items
222
+
223
+ end
224
+
225
+ ##############
226
+ ### TAXONS ###
227
+ ##############
228
+
229
+ # Operation and results should be identical when loading multiple associations
230
+ # if using either single column embedded syntax, or one column per entry.
231
+
232
+ it "should load Products and multiple Taxons from single column", :taxon => true do
233
+ test_taxon_creation( 'SpreeProducts.xls' )
234
+ end
235
+
236
+ it "should load Products and multiple Taxons from multiple columns", :taxons => true do
237
+ test_taxon_creation( 'SpreeProductsMultiColumn.xls' )
238
+ end
239
+
240
+ def test_taxon_creation( source )
241
+
242
+ # we want to test both find and find_or_create so should already have an object
243
+ # for find
244
+ @Taxonomy_klass.count.should == 1
245
+ @Taxon_klass.count.should == 2
246
+
247
+ @product_loader.perform_load( SpecHelper::spree_fixture(source), :mandatory => ['sku', 'name', 'price'] )
248
+
249
+ expected_multi_column_taxons
250
+ end
251
+
252
+ def expected_multi_column_taxons
253
+
254
+ #puts @Taxonomy_klass.all.collect( &:name).inspect
255
+ #puts @Taxon_klass.all.collect( &:name).inspect
256
+
257
+ # Paintings alreadyexisted and had 1 child Taxon (Landscape)
258
+ # 2 nested Taxon (Paintings>Nature>Seascape) created under it so expect Taxonomy :
259
+
260
+ # WaterColour
261
+ # Oils
262
+ # Paintings >Nature>Seascape + >Landscape
263
+ # Drawings
264
+
265
+ @Taxonomy_klass.count.should == 4
266
+ @Taxon_klass.count.should == 7
267
+
268
+ @klass.first.taxons.should have_exactly(2).items
269
+ @klass.last.taxons.should have_exactly(2).items
270
+
271
+ p2 = @Variant_klass.find_by_sku("DEMO_002").product
272
+
273
+ # Paintings Oils Paintings>Nature>Seascape
274
+
275
+ #puts p2.taxons.collect(&:name).inspect
276
+
277
+ p2.taxons.should have_exactly(4).items
278
+
279
+ p2.taxons.collect(&:name).sort.should == ['Nature','Oils','Paintings','Seascape']
280
+
281
+ paint_parent = @Taxonomy_klass.find_by_name('Paintings')
282
+
283
+ paint_parent.taxons.should have_exactly(4).items # 3 children + all Taxonomies have a root Taxon
284
+
285
+ paint_parent.taxons.collect(&:name).sort.should == ['Landscape','Nature','Paintings','Seascape']
286
+
287
+ tn = @Taxon_klass.find_by_name('Nature') # child with children
288
+ ts = @Taxon_klass.find_by_name('Seascape') # last child
289
+
290
+ ts.should_not be_nil
291
+ tn.should_not be_nil
292
+
293
+ p2.taxons.collect( &:id ).should include(ts.id)
294
+ p2.taxons.collect( &:id ).should include(tn.id)
295
+
296
+ puts tn.inspect
297
+ puts ts.inspect
298
+
299
+ tn.parent.id.should == paint_parent.root.id
300
+ ts.parent.id.should == tn.id
301
+
302
+ tn.children.should have_exactly(1).items
303
+ ts.children.should have_exactly(0).items
304
+
305
+
306
+ end
307
+
308
+ it "should load Products with associated image", :img => true do
309
+ pending("embedded images")
310
+ @product_loader.perform_load( SpecHelper::spree_fixture('SpreeProductsWithImages.csv'), :mandatory => ['sku', 'name', 'price'] )
311
+
312
+ p = @klass.find_by_name("Demo Product for AR Loader")
313
+
314
+ p.images.should have_exactly(1).items
315
+ end
316
+
317
+
318
+ # REPEAT THE WHOLE TEST SUITE VIA CSV
319
+
320
+ it "should load Products from single column csv as per .xls" do
321
+ test_variants_creation('SpreeProducts.csv')
322
+
323
+ expected_multi_column_properties
324
+
325
+ expected_multi_column_taxons
326
+ end
327
+
328
+
329
+ it "should load Products from multiple column csv as per .xls" do
330
+ test_variants_creation('SpreeProductsMultiColumn.csv')
331
+
332
+ expected_multi_column_properties
333
+
334
+ expected_multi_column_taxons
335
+ end
336
+
337
+ it "should load Products with assoicated image" do
338
+ test_variants_creation('SpreeProductsMultiColumn.csv')
339
+
340
+ expected_multi_column_properties
341
+
342
+ expected_multi_column_taxons
343
+ end
344
+
345
+
346
+ it "should raise exception when mandatory columns missing from .xls", :ex => true do
347
+ expect {@product_loader.perform_load($SpreeNegativeFixturePath + '/SpreeProdMissManyMandatory.xls', :mandatory => ['sku', 'name', 'price'] )}.to raise_error(DataShift::MissingMandatoryError)
348
+ end
349
+
350
+
351
+ it "should raise exception when single mandatory column missing from .xls", :ex => true do
352
+ expect {@product_loader.perform_load($SpreeNegativeFixturePath + '/SpreeProdMiss1Mandatory.xls', :mandatory => 'sku' )}.to raise_error(DataShift::MissingMandatoryError)
353
+ end
354
+
355
+ it "should raise exception when mandatory columns missing from .csv", :ex => true do
356
+ expect {@product_loader.perform_load($SpreeNegativeFixturePath + '/SpreeProdMissManyMandatory.csv', :mandatory => ['sku', 'name', 'price'] )}.to raise_error(DataShift::MissingMandatoryError)
357
+ end
358
+
359
+
360
+ it "should raise exception when single mandatory column missing from .csv", :ex => true do
361
+ expect {@product_loader.perform_load($SpreeNegativeFixturePath + '/SpreeProdMiss1Mandatory.csv', :mandatory => 'sku' )}.to raise_error(DataShift::MissingMandatoryError)
362
+ end
363
+
325
364
  end