allow importing custom fields for product option values
[bse.git] / t / 130-importer / 030-product.t
1 #!perl -w
2 use strict;
3 use BSE::Test qw(base_url);
4 use File::Spec;
5 use File::Temp;
6 use Test::More;
7
8 BEGIN {
9   eval "require Text::CSV;"
10     or plan skip_all => "Text::CSV not available";
11 }
12
13 BEGIN {
14   unshift @INC, File::Spec->catdir(BSE::Test::base_dir(), "cgi-bin", "modules");
15 }
16
17 use BSE::Importer;
18 use BSE::API qw(bse_init bse_make_product);
19
20 my $base_cgi = File::Spec->catdir(BSE::Test::base_dir(), "cgi-bin");
21 ok(bse_init($base_cgi), "initialize api")
22   or print "# failed to bse_init in $base_cgi\n";
23
24 my $when = time;
25
26 my $cfg = BSE::Cfg->new(path => $base_cgi, extra_text => <<CFG);
27 [import profile simple$when]
28 map_title=1
29 map_retailPrice=2
30 source=CSV
31 price_dollar=1
32
33 [import profile simpleupdate$when]
34 map_linkAlias=1
35 map_body=2
36 source=CSV
37 target=Product
38 update_only=1
39 sep_char=\\t
40 code_field=linkAlias
41
42 [import profile newdup$when]
43 map_product_code=1
44 map_title=2
45 map_retailPrice=3
46 skiplines=0
47 source=CSV
48 target=Product
49
50 [import profile avoidcorrupt$when]
51 map_id=1
52 map_articleId=2
53 map_title=3
54 map_product_code=4
55 source=CSV
56 target=Product
57 sep_char=\\t
58 codes=1
59 code_field=product_code
60 update_only=1
61
62 [import profile withoption$when]
63 map_linkAlias=1
64 map_title=2
65 map_prodopt1_name=3
66 map_prodopt1_values=4
67 map_prodopt1_custom.value_price=5
68 map_retailPrice=6
69 source=CSV
70 skiplines=0
71 CFG
72
73 {
74   my @added;
75
76   my $imp = BSE::Importer->new(cfg => $cfg, profile => "simple$when",
77                                callback => sub { note @_ });
78   $imp->process("t/data/importer/product-simple.csv");
79   @added = sort { $a->title cmp $b->title } $imp->leaves;
80
81   is(@added, 2, "imported two products");
82   is($added[0]->title, "test1", "check title of first import");
83   is($added[0]->retailPrice, 1000, "check price of first import");
84   is($added[1]->title, "test2", "check title of second import");
85   is($added[1]->retailPrice, 800, "check price of second import");
86
87   END {
88     $_->remove($cfg) for @added;
89   }
90 }
91
92 {
93   my $testa = bse_make_product
94     (
95      cfg => $cfg,
96      title => "test updates",
97      linkAlias => "P$when",
98      retailPrice => 500,
99      product_code => "C$when",
100     );
101
102   $testa->set_prices({ 1 => 400 });
103
104   {
105     my $fh = File::Temp->new;
106     my $filename = $fh->filename;
107     print $fh <<EOS;
108 linkAlias\tbody
109 "P$when"\t"This is the body text with multiple lines
110
111 Yes, multiple lines with CSV!"
112 EOS
113     close $fh;
114     my $imp = BSE::Importer->new(cfg => $cfg, profile => "simpleupdate$when",
115                                  callback => sub { note @_ });
116     $imp->process($filename);
117     my $testb = BSE::TB::Articles->getByPkey($testa->id);
118     like($testb->body, qr/This is the body/, "check the body is updated");
119   }
120
121   { # fail to duplicate a product code
122     my $fh = File::Temp->new;
123     my $filename = $fh->filename;
124     my $id = $testa->id;
125     print $fh <<EOS;
126 "C$when",A new title,100
127 EOS
128     close $fh;
129     my $imp = BSE::Importer->new(cfg => $cfg, profile => "newdup$when", callback => sub { note @_ });
130     $imp->process($filename);
131     is_deeply([ $imp->leaves ], [], "should be no updated articles");
132   }
133
134  SKIP:
135   {
136     my @prices = $testa->prices;
137     is(@prices, 1, "should still be a tier price")
138       or skip "No prices found", 2;
139     is($prices[0]->tier_id, 1, "check tier id");
140     is($prices[0]->retailPrice, 400, "check tier price");
141   }
142
143   END {
144     $testa->remove($cfg) if $testa;
145   }
146 }
147
148 {
149   my $code = "D$when";
150   my $testa = bse_make_product
151     (
152      cfg => $cfg,
153      title => "test updates",
154      linkAlias => "P$when",
155      retailPrice => 500,
156      product_code => $code,
157     );
158   diag "Product id ".$testa->id;
159   {
160     my $fh = File::Temp->new;
161     my $filename = $fh->filename;
162
163     print $fh <<EOS;
164 id\tarticleId\ttitle\tproduct_code
165 1\t2\tTesting\t$code
166 EOS
167     close $fh;
168     my $imp = BSE::Importer->new(cfg => $cfg, profile => "avoidcorrupt$when",
169                                  callback => sub { note @_ });
170     $imp->process($filename);
171     my $testb = BSE::TB::Products->getByPkey($testa->id);
172     ok($testb, "managed to fully load the product");
173     is($testb->title, "Testing", "check the title is updated");
174     my $top = BSE::TB::Articles->getByPkey(1);
175     isnt($top->generator, "BSE::Generate::Product",
176          "make sure we didn't scribble over article 1");
177   }
178
179   END {
180     $testa->remove($cfg) if $testa;
181   }
182 }
183
184 {
185   my @added;
186
187   my $fh = File::Temp->new;
188   my $filename = $fh->filename;
189
190   print $fh <<EOS;
191 test$when,"Test product option import $when","Colour","Red|Green|Blue","0|100|0",100
192 EOS
193   close $fh;
194   my $imp = BSE::Importer->new(cfg => $cfg, profile => "withoption$when",
195                                callback => sub { note @_ });
196   $imp->process($filename);
197
198   is_deeply([ $imp->errors ], [], "check no errors");
199
200   @added = sort { $a->title cmp $b->title } $imp->leaves;
201   is(@added, 1, "Only added one");
202   my $one = $added[0];
203   is($one->title, "Test product option import $when", "check the title is set");
204   my @options = $one->db_options;
205   is(@options, 1, "should be one option");
206   is($options[0]->name, "Colour", "name of option");
207   my @values = $options[0]->values;
208   is(@values, 3, "should be three options");
209   is($values[0]->value, "Red", "first value text correct");
210   is($values[1]->get_custom("value_price"), "100", "second custom field correct");
211
212   END {
213     $_->remove($cfg) for @added;
214   }
215 }
216
217 done_testing();