OSDN Git Service

仕入先マスタ管理機能追加
[elecoma/elecoma.git] / spec / models / product_spec.rb
1 require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
3 describe Product do
4   fixtures :products, :image_resources, :product_statuses,:categories,:product_styles,:statuses,:suppliers
5   
6   include ActionView::Helpers::NumberHelper
7   
8   before(:each) do
9     @product = products(:valid_product)
10   end
11   describe "validateチェック" do
12     before(:each) do
13       @product.small_resource = image_resources(:resource_00001)
14       @product.medium_resource = image_resources(:resource_00001)    
15     end
16     it "データが正しい" do
17       @product.should be_valid
18     end
19     it "商品名" do
20       #必須
21       @product.name = nil
22       @product.should_not be_valid
23       #文字数(1-50文字)
24       @product.name = ""
25       @product.should_not be_valid
26       @product.name = "あ" * 50
27       @product.should be_valid
28       @product.name = "あ" * 51
29       @product.should_not be_valid
30     end
31     it "参照URL" do
32       #非必須
33       @product.url = nil
34       @product.should be_valid
35       #文字数(300以下)
36       @product.url = "a" * 300
37       @product.should be_valid
38       @product.url = "a" * 301
39       @product.should_not be_valid
40     end
41     it "検索ワード" do
42       #非必須
43       @product.key_word = nil
44       @product.should be_valid
45       #文字数(99999以下)
46       @product.key_word = "あ" * 99999
47       @product.should be_valid
48       @product.key_word = "a" * 100000
49       @product.should_not be_valid
50     end
51     it "カテゴリID" do
52       #必須
53       @product.category_id = nil
54       @product.should_not be_valid
55     end
56     
57     it "一覧コメント" do
58       #必須
59       @product.description = nil
60       @product.should_not be_valid
61     end
62     it "詳細コメント" do
63       #必須
64       @product.introduction = nil
65       @product.should_not be_valid      
66     end
67     it "販売期間" do
68       date = DateTime.now
69       @product.sale_start_at = date
70       @product.sale_end_at = date
71       @product.should_not be_valid
72       @product.sale_end_at = DateTime.new(2008,1,1)
73       @product.should_not be_valid
74     end
75     it "公開期間" do
76       date = DateTime.now
77       @product.public_start_at = date
78       @product.public_end_at = date
79       @product.should_not be_valid
80       @product.public_end_at = DateTime.new(2008,1,1)
81       @product.should_not be_valid
82     end
83   end
84   
85   describe "表示系" do
86     it "配送日" do
87       product = Product.new(:delivery_dates =>1)
88       product.delivery_dates_label.should == Product::DELIVERY_DATE.keys.sort{|a, b| Product::DELIVERY_DATE[a] <=> Product::DELIVERY_DATE[b]}[1]
89     end
90     it "公開かどうか" do
91       product = Product.new(:permit =>false)
92       product.permit_label.should == "非公開"
93     end
94     it "1番目の商品スタイル" do
95       product = Product.new
96       product.first_product_style.should be_nil
97       @product.first_product_style.should == product_styles(:valid_product)
98     end
99     it "最安値と最高値および価格表示" do
100       product = products(:multi_styles_product)
101       min = product_styles(:multi_styles_product_2).sell_price
102       max = product_styles(:multi_styles_product_3).sell_price
103       product.price_range.should == [min,max]
104       product.price_label.should == number_with_delimiter(min) + "~" + number_with_delimiter(max)
105       
106       @product.price_label.should == number_with_delimiter(product_styles(:valid_product).sell_price)      
107     end
108     it "カテゴリ名" do
109       product = Product.new(:category_id =>categories(:dai_category).id)
110       product.category_name.should == categories(:dai_category).name
111     end
112     it "仕入先名" do
113       product = Product.new(:supplier_id =>suppliers(:one).id)
114       product.supplier_name.should == suppliers(:one).name
115     end
116   end
117   describe "その他" do
118     it "送料無料判断" do
119       @product.free_delivery?.should be_false
120       product = products(:campaign_product)
121       product.free_delivery?.should be_true
122     end
123     it "販売期間内/公開期間内か判断" do
124       product = products(:sell_stop_product)
125       product.in_sale_term?.should be_false
126       product.in_public_term?.should be_false
127       @product.in_sale_term?.should be_true
128       @product.in_public_term?.should be_true
129     end
130     it "在庫がある判断" do
131       product = Product.new
132       product.have_zaiko?.should be_false
133       product = products(:multi_styles_product)
134       product.have_zaiko?.should be_true
135     end
136     it "CSVダウンロード" do
137       search_list = [["products.name like ?", "%スカート%"]]
138       actual_titles,actual_product,act_file_name = getCsv(Product.csv(search_list))
139       
140       #タイトル
141       act = actual_titles.sort
142       ext = Product.set_field_names.values.sort
143       act.should == ext
144       #データ数
145       columns = Product.csv_columns_name
146       actual_product.size.should == 3
147       #ファイル名
148       #ファイル名に「現在時間秒まで」を含めるので、プログラム実行により秒の相違があるのでここで分まで取り切り
149       ext_file_name = "product_#{Time.now.strftime('%Y%m%d%H%M%S')}.csv" 
150       act_file_name.slice(0,act_file_name.length-8).should == ext_file_name.slice(0,ext_file_name.length-8)
151       
152     end
153     it "商品在庫数CSVダウンロード" do
154       search_list = [["products.name like ?", "%スカート%"]]
155       actual_titles,actual_product,act_file_name = getCsv(Product.actual_count_list_csv(search_list))
156       
157       #タイトル
158       act = actual_titles.sort
159       ext = ["商品名", "商品コード", "登録更新日", "実在個数"].sort
160       act.should == ext
161       #データ内容
162       columns = [:name,:code,:updated_at,:actual_count]
163       actual_product.should == [
164       convert(products(:campaign_product),product_styles(:campaign_product),columns) ,
165       convert(products(:sell_stop_product),product_styles(:sell_stop_product),columns),
166       convert(products(:multi_styles_product),product_styles(:multi_styles_product_1),columns),
167       convert(products(:multi_styles_product),product_styles(:multi_styles_product_2),columns),
168       convert(products(:multi_styles_product),product_styles(:multi_styles_product_3),columns)
169       ]
170       #ファイル名
171       #ファイル名に「現在時間秒まで」を含めるので、プログラム実行により秒の相違があるのでここで分まで取り切り
172       ext_file_name = "actual_count_list_#{Time.now.strftime('%Y%m%d%H%M%S')}.csv" 
173       act_file_name.slice(0,act_file_name.length-8).should == ext_file_name.slice(0,ext_file_name.length-8)
174     end
175     it "CSVアップロード" do
176       max_id = Product.maximum(:id)
177       Product.add_by_csv(File.read("#{RAILS_ROOT}/spec/product_csv_upload_for_spec.csv"))
178       max_id.should < Product.maximum(:id)
179       
180       #=========================================
181       #CSVアップロードするときの画像処理が複雑なので、単独テスト
182       #仕様としてCSVファイルに画像Pathが存在、かつ、画像が指定のパスに存在するとき、画像をアップロード
183       #画像パスが空白、あるいは画像が存在しない時、画像IDが指定されれば、その画像IDを使う
184       
185       #CSVデータが2件あり、そのうち
186       #1件:小画像パスあり、IDあり、中画像パスなし、IDあり、大画像パスなし、IDなし
187       #1件:小画像パスなし、IDあり、中画像パスあり、IDあり、大画像パスありが画像存在しない、IDあり
188       #画像IDがすべて18
189       
190       #元データ
191       cnt_image_b = ImageResource.count
192       cnt_image_data_b = ResourceData.count
193       cnt_product_b = Product.count
194       #CSVアップロード
195       Product.add_by_csv(File.read("#{RAILS_ROOT}/spec/product_csv_upload_image_for_spec.csv"))
196       
197       #期待結果
198       #商品データが1件更新、1件増加、
199       #1件:小画像ID=18、中画像IDが新規作成、大画像ID=18
200       #1件:小画像IDが新規作成、中画像ID=18、大画像ID=nil
201       #image_resourceのデータ数が2件増やす
202       #resource_dataのデータ数が2件増やす
203       cnt_image_a = ImageResource.count
204       cnt_image_data_a = ResourceData.count
205       cnt_product_a = Product.count
206
207        (cnt_product_a - cnt_product_b).should == 1
208       #1件目更新
209       product = Product.find_by_id(17)
210       product.small_resource_id.should == 18
211       product.large_resource_id.should == 18
212       #2件目追加
213       product2 = Product.find(:last)
214       product.medium_resource_id.should == 18
215       product2.large_resource_id.should be_nil
216       #CSV画像アップテストは環境により結果が異なるので、ここでテストコードをコメントアウトする
217       pending("CSV画像アップテストは環境により結果が異なるので、ここで関連テストコードをコメントアウトする") do
218       #   (cnt_image_a - cnt_image_b).should == 2
219       #   (cnt_image_data_a - cnt_image_data_b).should == 2
220       #  max_img_id += 1
221       #  product.small_resource_id.should == max_img_id       
222       #  max_img_id += 1
223       #  product2.medium_resource_id.should == max_img_id
224         true.should be_false # 保留したい評価
225       end
226     end    
227   end
228   
229   describe "データ変換" do
230     it "公開かどうか(ハッシュを配列へ)" do
231       arr = Product::PERMIT_LABEL.to_a
232       Product.permit_select.should == arr
233     end
234     it "配送日(ハッシュを配列へ)" do
235       arr = Product::DELIVERY_DATE.to_a
236       Product.delivery_dates_select.should == arr
237     end
238   end
239   
240   #=====================================================
241   private
242   #fixturesデータをCSV形式に変換(比較用)
243   def convert(product,p_style, columns)
244     arr = []
245     columns.map do |c|
246       if p_style
247         #実際在庫ダウンロード
248         if [:name].include?(c)
249           arr << (product.name.nil? ? "" : product.name.to_s)
250         else
251           #更新時間について、
252           #p_style.updated_atとp_style[:updated_at]の結果が違うので特別処理
253           if [:updated_at].include?(c)
254             arr << (p_style[c].nil? ? "" : p_style.updated_at.to_s)
255           else
256             arr << (p_style[c].nil? ? "" : p_style[c].to_s)
257           end        
258         end
259       else
260         #商品ダウンロード
261         if [:permit].include?(c)
262           arr <<   (product[c] ? "公開" : "非公開")
263         elsif [:category_name].include?(c)
264           arr << (product.category_name.nil? ? "" : product.category_name)
265         else  
266           arr <<   (product[c].nil? ? "" : product[c].to_s)
267         end
268       end      
269     end
270     arr.join(",").split(",")
271   end
272   #CSVダウンロードデータを比較用データに変換
273   def getCsv(datas)
274     
275     #CSVファイル内容
276     data = datas[0]
277     #タイトル
278     actual_titles = []
279     #データ
280     actual_product = []
281     data.split("\n").each_with_index do |d,i|
282       if i == 0
283         actual_titles = d.split(/\s*,\s*/)
284       else
285         actual_product << d.split(/\s*,\s*/)
286       end
287     end
288     #CSVファイル名
289     fileName = datas[1]
290     return actual_titles ,actual_product, fileName
291   end
292   #product同士の比較
293   #結果が同じである場合、1を戻る、結果が違う場合、0を戻る
294   def compare(act,ext)
295     ret = 1
296     keys = act.attributes.keys
297     keys.each do |key|
298       #値がnil ""の場合、および id,created_at,updated_atが比較の対象から外し      
299       unless ((act[key].blank? && ext[key].blank?) or ["id","created_at","updated_at"].include?(key))
300         #時間系カラムは国際時間、日本時間の原因で特殊処理
301         if ["sale_start_at","sale_end_at","public_start_at","public_end_at","arrival_expected_date","deleted_at"].include?(key)
302           if !act[key].blank? && !ext[key].blank?
303             if (act.send(key) != ext.send(key)) && (act.send(key) != ext.send(key)- 9.hour)
304               ret = 0
305               break
306             end
307           else  
308             ret = 0
309             break
310           end
311         else
312           if act.send(key)!= ext.send(key)
313             ret = 0
314             break
315           end
316         end
317       end      
318     end
319     ret
320   end
321 end