OSDN Git Service

t#30328:pull porting
[pettanr/pettanr.git] / spec / models / picture_spec.rb
1 # -*- encoding: utf-8 -*-
2 #実素材
3 require 'spec_helper'
4
5 describe Picture do
6   before do
7     @admin = FactoryGirl.create :admin
8     @user = FactoryGirl.create( :user_yas)
9     @author = FactoryGirl.create :author, :user_id => @user.id
10     @artist = FactoryGirl.create :artist_yas, :author_id => @author.id
11     @other_user = FactoryGirl.create( :user_yas)
12     @other_author = FactoryGirl.create :author, :user_id => @other_user.id
13     @other_artist = FactoryGirl.create :artist_yas, :author_id => @other_author.id
14     @sp = FactoryGirl.create :system_picture
15     @lg = FactoryGirl.create :license_group
16     @license = FactoryGirl.create :license, :license_group_id => @lg.id, :system_picture_id => @sp.id
17     @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
18   end
19   
20   describe '検証に於いて' do
21     before do
22       @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id
23     end
24     
25     context 'オーソドックスなデータのとき' do
26       it '下限データが通る' do
27         @p.revision = 1
28         @p.ext = 'png' #リストにない拡張子は通らないし
29         @p.width = 1
30         @p.height = 1
31         @p.filesize = 1
32         @p.md5 = 'a'*32
33         @p.classname = 'a'*1
34         @p.should be_valid
35       end
36       it '上限データが通る' do
37         @p.revision = 99999
38         @p.ext = 'jpeg'
39         @p.width = 99999
40         @p.height = 99999
41         @p.filesize = 2000000
42         @p.md5 = 'a'*32
43         @p.classname = 'a'*50
44         @p.should be_valid
45       end
46     end
47     
48     context 'original_picture_idを検証するとき' do
49       it 'nullなら失敗する' do
50         @p.original_picture_id = nil
51         @p.should_not be_valid
52       end
53       it '数値でなければ失敗する' do
54         @p.original_picture_id = 'a'
55         @p.should_not be_valid
56       end
57       it '存在する原画でなければ失敗する' do
58         @p.original_picture_id = 0
59         @p.should_not be_valid
60       end
61     end
62     context 'revisionを検証するとき' do
63       it 'nullなら失敗する' do
64         @p.revision = nil
65         @p.should_not be_valid
66       end
67       it '数値でなければ失敗する' do
68         @p.revision = 'a'
69         @p.should_not be_valid
70       end
71     end
72     context 'extを検証するとき' do
73       it 'nullなら失敗する' do
74         @p.ext = ''
75         @p.should_not be_valid
76       end
77       it '5文字以上なら失敗する' do
78         @p.ext = 'a'*5
79         @p.should_not be_valid
80       end
81       it 'png,gif,jpeg以外なら失敗する' do
82         @p.ext = 'bmp'
83         @p.should_not be_valid
84       end
85     end
86     context 'widthを検証するとき' do
87       it 'nullなら失敗する' do
88         @p.width = nil
89         @p.should_not be_valid
90       end
91       it '数値でなければ失敗する' do
92         @p.width = 'a'
93         @p.should_not be_valid
94       end
95       it '0なら失敗する' do
96         @p.width = '0'
97         @p.should_not be_valid
98       end
99       it '負でも失敗する' do
100         @p.width = -1
101         @p.should_not be_valid
102       end
103     end
104     context 'heightを検証するとき' do
105       it 'nullなら失敗する' do
106         @p.height = nil
107         @p.should_not be_valid
108       end
109       it '数値でなければ失敗する' do
110         @p.height = 'a'
111         @p.should_not be_valid
112       end
113       it '0なら失敗する' do
114         @p.height = '0'
115         @p.should_not be_valid
116       end
117       it '負でも失敗する' do
118         @p.height = -1
119         @p.should_not be_valid
120       end
121     end
122     context 'filesizeを検証するとき' do
123       it 'nullなら失敗する' do
124         @p.filesize = nil
125         @p.should_not be_valid
126       end
127       it '数値でなければ失敗する' do
128         @p.filesize = 'a'
129         @p.should_not be_valid
130       end
131       it '負なら失敗する' do
132         @p.filesize = '-1'
133         @p.should_not be_valid
134       end
135       it '2MB以上なら失敗する' do
136         @p.filesize = 2000000+1
137         @p.should_not be_valid
138       end
139     end
140     context 'md5を検証するとき' do
141       it 'nullなら失敗する' do
142         @p.md5 = ''
143         @p.should_not be_valid
144       end
145       it '31文字なら失敗する' do
146         @p.md5 = 'a'*31
147         @p.should_not be_valid
148       end
149       it '32文字以上なら失敗する' do
150         @p.md5 = 'a'*33
151         @p.should_not be_valid
152       end
153     end
154     context 'artist_idを検証するとき' do
155       it 'nullなら失敗する' do
156         @p.artist_id = nil
157         @p.should_not be_valid
158       end
159       it '数値でなければ失敗する' do
160         @p.artist_id = 'a'
161         @p.should_not be_valid
162       end
163       it '存在する絵師でなければ失敗する' do
164         @p.artist_id = 0
165         @p.should_not be_valid
166       end
167     end
168     context 'license_idを検証するとき' do
169       it 'nullなら失敗する' do
170         @p.license_id = nil
171         @p.should_not be_valid
172       end
173       it '数値でなければ失敗する' do
174         @p.license_id = 'a'
175         @p.should_not be_valid
176       end
177       it '存在するライセンスでなければ失敗する' do
178         @p.license_id = 0
179         @p.should_not be_valid
180       end
181     end
182     context 'artist_nameを検証するとき' do
183       it 'nullなら失敗する' do
184         @p.artist_name = nil
185         @p.should_not be_valid
186       end
187     end
188     context 'classnameを検証するとき' do
189       it 'nullなら失敗する' do
190         @p.classname = ''
191         @p.should_not be_valid
192       end
193       it '51文字以上なら失敗する' do
194         @p.classname = 'a'*51
195         @p.should_not be_valid
196       end
197     end
198     context 'creditを検証するとき' do
199     end
200     context 'settingsを検証するとき' do
201     end
202   end
203   
204   describe 'デフォルト値補充に於いて' do
205     it 'defined' do
206       @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id
207       @p.supply_default
208     end
209   end
210   
211   describe '上書き補充に於いて' do
212     before do
213       attr = {:ext => 'jpeg', :width => 264, :height => 265, :filesize => 266, 
214         :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, 
215         :artist_name => 'tester', :classname => 'Tester', :credit => {:title => 'cap'}.to_json.to_s, :settings => {:set => 1}.to_json.to_s}
216       @rp = FactoryGirl.build :resource_picture, attr
217       @p = FactoryGirl.build :picture, :original_picture_id => nil, :license_id => nil, :artist_id => nil, :revision => nil
218     end
219     it 'width, height, ext, filesize, md5, original_picture_idが設定されている' do
220       @p.overwrite @rp
221       @p.width.should eq 264
222       @p.height.should eq 265
223       @p.ext.should eq 'jpeg'
224       @p.filesize.should eq 266
225       @p.md5.should eq @rp.md5
226       @p.original_picture_id.should eq @op.id
227     end
228     it 'license_id, artist_id, artist_name, classname, credit, settingsが設定されている' do
229       @p.overwrite @rp
230       @p.license_id.should eq @license.id
231       @p.artist_id.should eq @artist.id
232       @p.artist_name.should eq 'tester'
233       @p.classname.should eq 'Tester'
234       @p.credit.should match /title/
235       @p.settings.should match /set/
236     end
237     it 'new_revisionに問い合わせている' do
238       Picture.any_instance.stub(:new_revision).with(any_args).and_return(3)
239       Picture.any_instance.should_receive(:new_revision).with(any_args).exactly(1)
240       @p.overwrite @rp
241     end
242     it 'revisionは、new_revisionに設定されている' do
243       Picture.any_instance.stub(:new_revision).with(any_args).and_return(3)
244       @p.overwrite @rp
245       @p.revision.should eq 3
246     end
247   end
248   
249   describe '所持判定に於いて' do
250     before do
251       @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id
252     end
253     context '事前チェックする' do
254       it '自身にロールリストからの絵師取得を依頼している' do
255         Picture.should_receive(:get_artist_from_roles).with(any_args).exactly(1)
256         r = @p.own?([@artist])
257       end
258     end
259     context 'ロール内絵師が取得できるとき' do
260       before do
261       end
262       it 'ロール内絵師のidが自身の絵師idと一致するなら許可する' do
263         Picture.stub(:get_artist_from_roles).with(any_args).and_return(@artist)
264         r = @p.own?([@artist])
265         r.should be_true
266       end
267       it 'ロール内絵師のidが自身の絵師idと一致しないならno' do
268         Picture.stub(:get_artist_from_roles).with(any_args).and_return(@other_artist)
269         @p.own?(@other_artist).should be_false
270       end
271     end
272     context 'ロール内絵師が取得できないとき' do
273       before do
274         Picture.stub(:get_artist_from_roles).with(any_args).and_return(nil)
275       end
276       it 'Falseを返す' do
277         r = @p.own?([@artist])
278         r.should be_false
279       end
280     end
281   end
282   
283   describe '閲覧許可に於いて' do
284     before do
285       @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id
286     end
287     it 'Trueを返す。' do
288       r = @p.visible?(@artist)
289       r.should be_true
290     end
291   end
292   
293   describe '詳細閲覧許可に於いて' do
294     before do
295       @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id
296     end
297     context '自身に原画がリンクしていないとき' do
298       before do
299         Picture.any_instance.stub(:original_picture).with(any_args).and_return(nil)
300       end
301       it 'Falseを返す' do
302         r = @p.showable?(@author)
303         r.should be_false
304       end
305     end
306     it '自作の実素材ならyes' do
307       Picture.any_instance.stub(:own?).with(any_args).and_return(true)
308       @p.showable?(@artist).should == true
309     end
310     context '他人の実素材のとき' do
311       before do
312         Picture.any_instance.stub(:own?).with(any_args).and_return(false)
313       end
314       it '自身にhead判定と有効性判定を問い合わせ、両者がTrueならTrueを返す。' do
315         Picture.any_instance.stub(:head?).with(any_args).and_return(true)
316         Picture.any_instance.stub(:enable?).with(any_args).and_return(true)
317         r = @p.showable?(@author)
318         r.should be_true
319       end
320       it 'head判定がFalseならFalseを返す。' do
321         Picture.any_instance.stub(:head?).with(any_args).and_return(false)
322         Picture.any_instance.stub(:enable?).with(any_args).and_return(true)
323         r = @p.showable?(@author)
324         r.should be_false
325       end
326       it '有効性判定がFalseならFalseを返す。' do
327         Picture.any_instance.stub(:enable?).with(any_args).and_return(false)
328         Picture.any_instance.stub(:head?).with(any_args).and_return(true)
329         r = @p.showable?(@author)
330         r.should be_false
331       end
332     end
333   end
334   
335   describe 'ファイル名に於いて' do
336     before do
337       @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'png'
338     end
339     it 'id+拡張子のフォーマットで返す' do
340       r = @p.filename
341       r.should eq "#{@p.id}.png"
342     end
343   end
344   
345   describe 'gifファイル名に於いて' do
346     before do
347       @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'gif'
348     end
349     it 'id.gifのフォーマットで返す' do
350       r = @p.filename
351       r.should eq "#{@p.id}.gif"
352     end
353   end
354   
355   describe 'MimeTypeに於いて' do
356     before do
357       @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'png'
358     end
359     it 'image/拡張子のフォーマットで返す' do
360       r = @p.mime_type
361       r.should eq "image/png"
362     end
363   end
364   
365   describe 'ファイルのurlに於いて' do
366     before do
367       @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id
368       Picture.any_instance.stub(:filename).and_return('3.gif')
369     end
370     it 'ファイル名取得を依頼している' do
371       Picture.any_instance.should_receive(:filename).exactly(1)
372       @p.url
373     end
374     it '/pictures/3.gifのフォーマットで返す' do
375       r = @p.url
376       r.should eq "/pictures/3.gif"
377     end
378   end
379   
380   describe '最新Revision取得に於いて' do
381     context '初めての原画を公開したとき' do
382       before do
383         @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id
384       end
385       it 'Revisionは1となる' do
386         @p.new_revision.should eq 1
387       end
388     end
389     context 'HEADが1のとき' do
390       before do
391         FactoryGirl.create :picture, :revision => 1, :original_picture_id => @op.id, :license_id => @license.id
392         @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id
393       end
394       it 'Revisionは2となる' do
395         @p.new_revision.should eq 2
396       end
397     end
398     context 'HEADが5のとき' do
399       before do
400         FactoryGirl.create :picture, :revision => 1, :original_picture_id => @op.id, :license_id => @license.id
401         FactoryGirl.create :picture, :revision => 5, :original_picture_id => @op.id, :license_id => @license.id
402         @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id
403       end
404       it 'Revisionは6となる' do
405         @p.new_revision.should eq 6
406       end
407     end
408   end
409   
410   describe '有効性判定に於いて' do
411     before do
412       @p = FactoryGirl.create :picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id 
413       @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :picture_id => @p.id
414       Picture.any_instance.stub(:head).and_return(@p)
415     end
416     context '自身のheadとリンクした素材があるとき' do
417       before do
418         Picture.any_instance.stub(:resource_picture).and_return(@rp)
419       end
420       it 'trueを返す' do
421         res = @p.enable?
422         res.should be_true
423       end
424     end
425     context '自身のheadとリンクした素材がないとき' do
426       before do
427         Picture.any_instance.stub(:resource_picture).and_return(nil)
428       end
429       it 'falseを返す' do
430         res = @p.enable?
431         res.should be_false
432       end
433     end
434   end
435   
436   describe 'head取得に於いて' do
437     before do
438       #旧版
439       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
440       @p = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 0,
441         :original_picture_id => @op.id, :md5 => 'a' * 32
442       #最新版
443       @p2 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
444         :original_picture_id => @op.id, :md5 => 'b' * 32
445       #除外すべき無関係画像
446       @op2 = FactoryGirl.create :original_picture, :artist_id => @artist.id
447       @p3 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 0,
448         :original_picture_id => @op2.id, :md5 => 'C' * 32
449     end
450     context 'つつがなく終わるとき' do
451       before do
452         #素材は有効
453         @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :picture_id => @p2.id
454       end
455       it '最新版を返す' do
456         res = @p.head
457         res.should eq @p2
458       end
459     end
460     context '無効な素材(素材とリンクしてない)とき' do
461       it '同じく最新版を返す' do
462         res = @p.head
463         res.should eq @p2
464       end
465     end
466   end
467   
468   describe 'head判定に於いて' do
469     before do
470       #旧版
471       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
472       @p = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 0,
473         :original_picture_id => @op.id, :md5 => 'a' * 32
474       #最新版
475       @p2 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
476         :original_picture_id => @op.id, :md5 => 'b' * 32
477       @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :picture_id => @p2.id
478     end
479     context '旧版のとき' do
480       it 'falseを返す' do
481         res = @p.head?
482         res.should be_false
483       end
484     end
485     context '最新版のとき' do
486       it 'trueを返す' do
487         res = @p2.head?
488         res.should be_true
489       end
490     end
491   end
492   
493   describe 'フォーマット変換対象判定に於いて' do
494     before do
495       @p = FactoryGirl.build :picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id
496     end
497     context '変換するケース' do
498       it '画像フォーマットがpngかつライセンスの変換禁止フラグが無効のときTrue' do
499         Picture.any_instance.stub(:flag_gif_convert).with(any_args).and_return(0)
500         @p.ext = 'png'
501         @p.to_gif?.should be_true
502       end
503     end
504     context '変換しないケース' do
505       it '画像フォーマットがpngでない' do
506         Picture.any_instance.stub(:flag_gif_convert).with(any_args).and_return(0)
507         @p.ext = 'gif'
508         @p.to_gif?.should be_false
509       end
510       it '変換禁止フラグが無効' do
511         Picture.any_instance.stub(:flag_gif_convert).with(any_args).and_return(-1)
512         @p.ext = 'png'
513         @p.to_gif?.should be_false
514       end
515     end
516   end
517   
518   describe 'サブディレクトリリストに於いて' do
519     before do
520       @p = FactoryGirl.build :picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id
521     end
522     it '配列で返す' do
523       Picture.any_instance.stub(:flag_gif_convert).with(any_args).and_return(0)
524       r = @p.subdirs
525       r.is_a?(Array).should be_true
526     end
527     it '本画像(ベースディレクトリ)を含んでいる' do
528       Picture.any_instance.stub(:flag_reverse).with(any_args).and_return(0)
529       r = @p.subdirs
530       r.include?('').should be_true
531     end
532     context '反転が許可されているとき' do
533       it '垂直・水平・垂直水平反転ディレクトリも返す' do
534         Picture.any_instance.stub(:flag_reverse).with(any_args).and_return(0)
535         r = @p.subdirs
536         r.include?('v').should be_true
537         r.include?('h').should be_true
538         r.include?('vh').should be_true
539       end
540     end
541     context '反転が許可されていないとき' do
542       it '本画像(ベースディレクトリ)だけを返す' do
543         Picture.any_instance.stub(:flag_reverse).with(any_args).and_return(-1)
544         r = @p.subdirs
545         r.size.should eq 1
546       end
547     end
548   end
549   
550   describe 'md5重複リストに於いて' do
551     before do
552       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
553       @p = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 0,
554         :original_picture_id => @op.id, :md5 => 'a' * 32
555       @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :picture_id => @p.id
556       @op2 = FactoryGirl.create :original_picture, :artist_id => @artist.id
557       @p2 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 0,
558         :original_picture_id => @op2.id, :md5 => 'b' * 32
559       @op3 = FactoryGirl.create :original_picture, :artist_id => @artist.id
560     end
561     context '除外する原画idで指定されていないとき' do
562       it 'リストを返す' do
563         res = Picture.list_by_md5(@p.md5)
564         res.is_a?(Array).should be_true
565       end
566       it 'md5が違えば含まない' do
567         res = Picture.list_by_md5(@p.md5)
568         res.include?(@p2).should be_false
569       end
570       it '更新日時順' do
571         @p3 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
572           :original_picture_id => @op2.id, :md5 => 'C' * 32
573         @p4 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
574           :original_picture_id => @op3.id, :md5 => @p3.md5, :updated_at => Time.now + 100
575         res = Picture.find_by_md5(@p3.md5)
576         res.should eq [@p4, @p3]
577       end
578     end
579     context '除外する原画idで指定されたとき' do
580       it 'リストを返す' do
581         res = Picture.list_by_md5(@p.md5, @p.original_picture_id)
582         res.is_a?(Array).should be_true
583       end
584       it 'md5が違えば含まない' do
585         res = Picture.list_by_md5(@p.md5, @p.original_picture_id)
586         res.include?(@p2).should be_false
587       end
588       it '同一原画は含まない' do
589         res = Picture.list_by_md5(@p.md5, @p.original_picture_id)
590         res.empty?.should be_true
591       end
592       it '同一原画は旧版でも含まない' do
593         @p3 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
594           :original_picture_id => @op.id, :md5 => 'a' * 32
595         res = Picture.list_by_md5(@p.md5, @p.original_picture_id)
596         res.empty?.should be_true
597       end
598       it '他所の原画なら含む' do
599         @p3 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
600           :original_picture_id => @op2.id, :md5 => 'a' * 32
601         res = Picture.list_by_md5(@p.md5, @p.original_picture_id)
602         res.should eq [@p3]
603       end
604       it '他所の原画でもmd5が違えば含まない' do
605         @p3 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
606           :original_picture_id => @op2.id, :md5 => 'c' * 32
607         res = Picture.list_by_md5(@p.md5, @p.original_picture_id)
608         res.empty?.should be_true
609       end
610       it '更新日時順' do
611         @p3 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
612           :original_picture_id => @op2.id, :md5 => 'a' * 32
613         @p4 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
614           :original_picture_id => @op3.id, :md5 => 'a' * 32, :updated_at => Time.now + 100
615         res = Picture.list_by_md5(@p.md5, @p.original_picture_id)
616         res.should eq [@p4, @p3]
617       end
618     end
619   end
620   
621   describe 'md5重複判定に於いて' do
622     before do
623       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
624       @op2 = FactoryGirl.create :original_picture, :artist_id => @artist.id
625       @p = FactoryGirl.create :picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :revision => 0
626       @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :picture_id => @p.id
627     end
628     context '同一原画以外に同じ値があるとき' do
629       before do
630         @p2 = FactoryGirl.create :picture, :artist_id => @artist.id, :original_picture_id => @op2.id, :license_id => @license.id
631       end
632       it 'trueを返す' do
633         res = Picture.exist_by_md5(@p.md5, @p.original_picture_id)
634         res.should be_true
635       end
636     end
637     context '同一原画以外に同じ値がないとき' do
638       it 'falseを返す' do
639         res = Picture.exist_by_md5(@p.md5, @p.original_picture_id)
640         res.should be_false
641       end
642     end
643     context '同一原画に同じ値があるとき' do
644       before do
645         @p2 = FactoryGirl.create :picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :revision => 1
646       end
647       it 'falseを返す' do
648         res = Picture.exist_by_md5(@p.md5, @p.original_picture_id)
649         res.should be_false
650       end
651     end
652   end
653   
654   describe '単体取得に於いて' do
655     before do
656       @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id
657     end
658     context 'つつがなく終わるとき' do
659       it '閲覧許可を問い合わせている' do
660         Picture.any_instance.stub(:visible?).with(any_args).and_return(true)
661         Picture.any_instance.should_receive(:visible?).with(any_args).exactly(1)
662         r = Picture.show @p.id, @author
663       end
664     end
665     it '指定の実素材を返す' do
666       r = Picture.show @p.id, @author
667       r.should eq @p
668     end
669     context '他人の実素材を開こうとしたとき' do
670       it '403Forbidden例外を返す' do
671         Picture.any_instance.stub(:visible?).and_return(false)
672         lambda{
673           r = Picture.show @p.id, @other_author
674         }.should raise_error(ActiveRecord::Forbidden)
675       end
676     end
677     context '存在しない実素材を開こうとしたとき' do
678       it '404RecordNotFound例外を返す' do
679         lambda{
680           r = Picture.show 0, @author
681         }.should raise_error(ActiveRecord::RecordNotFound)
682       end
683     end
684   end
685   
686   describe '作成に於いて' do
687     before do
688       @imager = ImagerTest.load "abc\ndef\nghi"
689       #原画ファイル削除だけは必ず成功するものとしておく
690       PictureIO::LocalPicture.any_instance.stub(:delete).with(any_args).and_return(true)
691     end
692     context '事前チェック' do
693       before do
694         #すべての処理が正常パターンで通過すれば、一番深い分岐まで通る。
695         #それで外部のメソッド呼び出しだけに着目してテストする。
696         Picture.any_instance.stub(:save).with(any_args).and_return(true)
697         Picture.any_instance.stub(:store_picture).with(any_args).and_return(true)
698         Picture.any_instance.stub(:to_gif?).with(any_args).and_return(true)
699         @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'png'
700       end
701       it '自身を保存している' do
702         Picture.any_instance.should_receive(:save).with(any_args).exactly(1)
703         r = @p.store(@imager)
704       end
705       it '画像ファイルの作成機能で画像を保存している' do
706         Picture.any_instance.stub(:filename).with(any_args).and_return('1.png')
707         #二回目の保存はgif変換の結果を渡す。
708         Picture.any_instance.should_receive(:store_picture).with(any_args).exactly(2)
709         r = @p.store(@imager)
710       end
711       it '自身にgifフォーマット変換対象かを問い合わせている' do
712         Picture.any_instance.should_receive(:to_gif?).with(any_args).exactly(1)
713         r = @p.store(@imager)
714       end
715     end
716     context 'つつがなく終わるとき' do
717       before do
718         #すべての処理を正常パターンで通過させ、保存機能をチェックする。
719         Picture.any_instance.stub(:store_picture).with(any_args).and_return(true)
720         Picture.any_instance.stub(:to_gif?).with(any_args).and_return(true)
721         @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'png'
722       end
723       it 'Trueを返す' do
724         r = @p.store(@imager)
725         r.should be_true
726       end
727       it '自身が保存されている' do
728         lambda {
729           r = @p.store(@imager)
730         }.should change Picture, :count
731       end
732     end
733     context 'gif変換なしで、つつがなく終わるとき' do
734       before do
735         #すべての処理を正常パターンで通過させ、保存機能をチェックする。
736         Picture.any_instance.stub(:store_picture).with(any_args).and_return(true)
737         Picture.any_instance.stub(:to_gif?).with(any_args).and_return(false)
738         @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'png'
739       end
740       it 'Trueを返す' do
741         r = @p.store(@imager)
742         r.should be_true
743       end
744       it 'gif保存は呼ばれていない' do
745         #二回目の画像作成が呼び出されないで1回こっきりならgif保存は呼ばれていないんだろう。
746         Picture.any_instance.should_receive(:store_picture).with(any_args).exactly(1)
747         r = @p.store(@imager)
748       end
749     end
750     #以下から例外ケース。処理先頭から失敗させていく
751     context '自身の保存に失敗したとき' do
752       before do
753         Picture.any_instance.stub(:save).with(any_args).and_return(false)
754         @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'png'
755       end
756       it 'Falseを返す' do
757         r = @p.store(@imager)
758         r.should be_false
759       end
760       it '更新されていない' do
761         r = @p.store(@imager)
762         @p.should be_a_new Picture
763       end
764     end
765     context '画像の保存に失敗したとき' do
766       before do
767         Picture.any_instance.stub(:store_picture).with(any_args).and_return(false)
768         @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'png'
769       end
770       it 'Falseを返す' do
771         r = @p.store(@imager)
772         r.should be_false
773       end
774       it 'gif変換判定は呼ばれていない' do
775         Picture.any_instance.should_not_receive(:to_gif?).with(any_args).exactly(0)
776         r = @p.store(@imager)
777       end
778     end
779     context 'gif変換に失敗したとき' do
780       before do
781         Picture.any_instance.stub(:store_picture).with(any_args).and_return(true)
782         Picture.any_instance.stub(:to_gif?).with(any_args).and_return(true)
783         ImagerTest.stub(:load).with(any_args).and_return(false)
784         @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'png'
785       end
786       it 'Falseを返す' do
787         r = @p.store(@imager)
788         r.should be_false
789       end
790       it 'gif画像の保存は呼ばれていない' do
791         #本画像の保存があるので、一度は呼ばれる
792         Picture.any_instance.should_receive(:store_picture).with(any_args).exactly(1)
793         r = @p.store(@imager)
794       end
795     end
796     context 'gif画像の保存に失敗したとき' do
797       before do
798         @gifimager = @imager.to_gif
799         ImagerTest.any_instance.stub(:to_gif).with(any_args).and_return(@gifimager)
800         Picture.any_instance.stub(:filename).with(any_args).and_return('1.png')
801         Picture.any_instance.stub(:gifname).with(any_args).and_return('1.gif')
802         Picture.any_instance.stub(:store_picture).with(@imager, '1.png').and_return(true)
803         Picture.any_instance.stub(:to_gif?).with(any_args).and_return(true)
804         Picture.any_instance.stub(:store_picture).with(@gifimager, '1.gif').and_return(false)
805         @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'png'
806       end
807       it 'Falseを返す' do
808         r = @p.store(@imager)
809         r.should be_false
810       end
811     end
812   end
813   
814   describe '画像ファイルの作成に於いて' do
815     #PictureIo経由で画像を保存するための機能。ファイル名に自身のidを使うので事前に自身の保存が必要。
816     before do
817       @imager = ImagerTest.load "abc\ndef\nghi"
818       #原画ファイル削除だけは必ず成功するものとしておく
819       PictureIO::LocalPicture.any_instance.stub(:delete).with(any_args).and_return(true)
820       
821       Picture.any_instance.stub(:subdirs).with(any_args).and_return(['', 'v', 'h', 'vh'])
822       @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'png'
823     end
824     context '事前チェック' do
825       before do
826         #すべての処理を正常パターンで通過させ、保存機能をチェックする。
827         PictureIO.picture_io.stub(:put).with(any_args).and_return(true)
828       end
829       it '画像ファイルの保存が4回呼ばれる' do
830         PictureIO.picture_io.should_receive(:put).with(any_args).exactly(4)
831         r = @p.store_picture(@imager, '1.png')
832       end
833       it '画像ファイルのベースへの保存が1回呼ばれる' do
834         PictureIO.picture_io.should_receive(:put).with("abc\ndef\nghi", '1.png', '').exactly(1)
835         r = @p.store_picture(@imager, '1.png')
836       end
837       it '画像ファイルの垂直反転への保存が1回呼ばれる' do
838         PictureIO.picture_io.should_receive(:put).with("cba\nfed\nihg", '1.png', 'v').exactly(1)
839         r = @p.store_picture(@imager, '1.png')
840       end
841       it '画像ファイルの水平反転への保存が1回呼ばれる' do
842         PictureIO.picture_io.should_receive(:put).with("ghi\ndef\nabc", '1.png', 'h').exactly(1)
843         r = @p.store_picture(@imager, '1.png')
844       end
845       it '画像ファイルの垂直水平反転への保存が1回呼ばれる' do
846         PictureIO.picture_io.should_receive(:put).with("ihg\nfed\ncba", '1.png', 'vh').exactly(1)
847         r = @p.store_picture(@imager, '1.png')
848       end
849     end
850     context 'つつがなく終わるとき' do
851       before do
852         #すべての処理を正常パターンで通過させ、保存機能をチェックする。
853         PictureIO.picture_io.stub(:put).with(any_args).and_return(true)
854       end
855       it 'Trueを返す' do
856         r = @p.store_picture(@imager, '1.png')
857         r.should be_true
858       end
859     end
860     context '例外ケース' do
861       before do
862         PictureIO.picture_io.stub(:put).with(any_args).and_return(false)
863       end
864       it 'Falseを返す' do
865         r = @p.store_picture(@imager, '1.png')
866         r.should be_false
867       end
868     end
869     
870   end
871   
872   describe '墨塗に於いて' do
873     before do
874       @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'png'
875     end
876     context '事前チェック' do
877       before do
878         @imager = ImagerTest.load "abc\ndef\nghi"
879         Picture.any_instance.stub(:store).with(any_args).and_return(true)
880         PettanImager.stub(:load).with(any_args).and_return(@imager)
881       end
882       it '画像ライブラリにロードを依頼している' do
883         PettanImager.should_receive(:load).with(any_args).exactly(1)
884         r = @p.unpublish
885       end
886       it '自身に作成を依頼している' do
887         Picture.any_instance.should_receive(:store).with(any_args).exactly(1)
888         r = @p.unpublish
889       end
890     end
891     context 'つつがなく終わるとき' do
892       before do
893         Picture.any_instance.stub(:store).with(any_args).and_return(true)
894       end
895       it 'Trueを返す' do
896         r = @p.unpublish
897         r.should be_true
898       end
899     end
900     #例外ケース
901     context '画像ライブラリのロードに失敗したとき' do
902       before do
903         PettanImager.stub(:load).and_return(false)
904       end
905       it 'Falseを返す' do
906         r = @p.unpublish
907         r.should be_false
908       end
909     end
910     context '作成に失敗したとき' do
911       before do
912         Picture.any_instance.stub(:store).with(any_args).and_return(false)
913       end
914       it 'Falseを返す' do
915         r = @p.unpublish
916         r.should be_false
917       end
918     end
919   end
920   
921   describe 'フラグ展開に於いて' do
922     before do
923       @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id,
924         :settings => "{\"open\": 1, \"commercial\": 2, \"official\": 3, \"attribution\": 4, \"derive\": 5, \"thumbnail\": 6, \"gif_convert\": 7, \"reverse\": 8, \"resize\": 9, \"sync_vh\": 10, \"overlap\": 11}"
925     end
926     context 'json展開チェック' do
927       it '展開してなければ展開して@flagsに保管する' do
928         @p.flags.should_not be_nil
929       end
930       it '展開できなければ{}' do
931         @p.settings += '}'
932         @p.flags.is_a?(Hash).should be_true
933         @p.flags.empty?.should be_true
934       end
935     end
936     context 'openについて' do
937       it '@flag_openに保管する' do
938         @p.flag_open.should_not be_nil
939       end
940       it '本当にフラグHashからじゃなく、変数から取得してる?' do
941         @p.flag_open
942         @p.flags = nil
943         @p.flag_open.should_not be_nil
944       end
945       it '1を返す' do
946         @p.flag_open.should eq 1
947       end
948     end
949     context 'commercialについて' do
950       it '@flag_commercialに保管する' do
951         @p.flag_commercial.should_not be_nil
952       end
953       it '本当にフラグHashからじゃなく、変数から取得してる?' do
954         @p.flag_commercial
955         @p.flags = nil
956         @p.flag_commercial.should_not be_nil
957       end
958       it '2を返す' do
959         @p.flag_commercial.should eq 2
960       end
961     end
962     context 'officialについて' do
963       it '@flag_officialに保管する' do
964         @p.flag_official.should_not be_nil
965       end
966       it '本当にフラグHashからじゃなく、変数から取得してる?' do
967         @p.flag_official
968         @p.flags = nil
969         @p.flag_official.should_not be_nil
970       end
971       it 'を返す' do
972         @p.flag_official.should eq 3
973       end
974     end
975     context 'attributionについて' do
976       it '@flag_attributionに保管する' do
977         @p.flag_attribution.should_not be_nil
978       end
979       it '本当にフラグHashからじゃなく、変数から取得してる?' do
980         @p.flag_attribution
981         @p.flags = nil
982         @p.flag_attribution.should_not be_nil
983       end
984       it '4を返す' do
985         @p.flag_attribution.should eq 4
986       end
987     end
988     context 'deriveについて' do
989       it '@flag_deriveに保管する' do
990         @p.flag_derive.should_not be_nil
991       end
992       it '本当にフラグHashからじゃなく、変数から取得してる?' do
993         @p.flag_derive
994         @p.flags = nil
995         @p.flag_derive.should_not be_nil
996       end
997       it '5を返す' do
998         @p.flag_derive.should eq 5
999       end
1000     end
1001     context 'thumbnailについて' do
1002       it '@flag_thumbnailに保管する' do
1003         @p.flag_thumbnail.should_not be_nil
1004       end
1005       it '本当にフラグHashからじゃなく、変数から取得してる?' do
1006         @p.flag_thumbnail
1007         @p.flags = nil
1008         @p.flag_thumbnail.should_not be_nil
1009       end
1010       it '6を返す' do
1011         @p.flag_thumbnail.should eq 6
1012       end
1013     end
1014     context 'gif_convertについて' do
1015       it '@flag_gif_convertに保管する' do
1016         @p.flag_gif_convert.should_not be_nil
1017       end
1018       it '本当にフラグHashからじゃなく、変数から取得してる?' do
1019         @p.flag_gif_convert
1020         @p.flags = nil
1021         @p.flag_gif_convert.should_not be_nil
1022       end
1023       it '7を返す' do
1024         @p.flag_gif_convert.should eq 7
1025       end
1026     end
1027     context 'reverseについて' do
1028       it '@flag_reverseに保管する' do
1029         @p.flag_reverse.should_not be_nil
1030       end
1031       it '本当にフラグHashからじゃなく、変数から取得してる?' do
1032         @p.flag_reverse
1033         @p.flags = nil
1034         @p.flag_reverse.should_not be_nil
1035       end
1036       it '8を返す' do
1037         @p.flag_reverse.should eq 8
1038       end
1039     end
1040     context 'resizeについて' do
1041       it '@flag_resizeに保管する' do
1042         @p.flag_resize.should_not be_nil
1043       end
1044       it '本当にフラグHashからじゃなく、変数から取得してる?' do
1045         @p.flag_resize
1046         @p.flags = nil
1047         @p.flag_resize.should_not be_nil
1048       end
1049       it '9を返す' do
1050         @p.flag_resize.should eq 9
1051       end
1052     end
1053     context 'sync_vhについて' do
1054       it '@flag_sync_vhに保管する' do
1055         @p.flag_sync_vh.should_not be_nil
1056       end
1057       it '本当にフラグHashからじゃなく、変数から取得してる?' do
1058         @p.flag_sync_vh
1059         @p.flags = nil
1060         @p.flag_sync_vh.should_not be_nil
1061       end
1062       it '10を返す' do
1063         @p.flag_sync_vh.should eq 10
1064       end
1065     end
1066     context 'overlapについて' do
1067       it '@flag_overlapに保管する' do
1068         @p.flag_overlap.should_not be_nil
1069       end
1070       it '本当にフラグHashからじゃなく、変数から取得してる?' do
1071         @p.flag_overlap
1072         @p.flags = nil
1073         @p.flag_overlap.should_not be_nil
1074       end
1075       it '11を返す' do
1076         @p.flag_overlap.should eq 11
1077       end
1078     end
1079   end
1080
1081   describe 'クレジットデータに於いて' do
1082     before do
1083       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
1084       @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :credit => '{"system_picture_id": 2}'
1085     end
1086     it 'system_picture_idが入っている' do
1087       res = @p.credit_data
1088       res["system_picture_id"].should eq 2
1089     end
1090   end
1091   
1092   describe 'エクスポートに於いて' do
1093     before do
1094       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
1095       @p = FactoryGirl.create :picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :revision => 0
1096       @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :picture_id => @p.id
1097       @p2 = FactoryGirl.create :picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :revision => 1, :updated_at => Time.now + 1000
1098       #開始日時以前の実素材
1099       @old_op = FactoryGirl.create :original_picture, :artist_id => @artist.id
1100       @old_p = FactoryGirl.create :picture, :artist_id => @artist.id, :original_picture_id => @old_op.id, :license_id => @license.id, :revision => 0, :updated_at => Time.now - 1000
1101       @old_rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :original_picture_id => @old_op.id, :license_id => @license.id, :picture_id => @old_p.id
1102       #他人の実素材
1103       @other_op = FactoryGirl.create :original_picture, :artist_id => @other_artist.id
1104       @other_p = FactoryGirl.create :picture, :artist_id => @other_artist.id, :original_picture_id => @other_op.id, :license_id => @license.id, :revision => 0, :updated_at => Time.now + 100
1105       @other_rp = FactoryGirl.create :resource_picture, :artist_id => @other_artist.id, :original_picture_id => @other_op.id, :license_id => @license.id, :picture_id => @other_p.id
1106       #貸手からの実素材排除
1107       @outer_artist = FactoryGirl.create :artist_yas, :author_id => nil
1108       @outer_op = FactoryGirl.create :original_picture, :artist_id => @outer_artist.id
1109       @outer_p = FactoryGirl.create :picture, :artist_id => @outer_artist.id, :original_picture_id => @outer_op.id, :license_id => @license.id, :revision => 0
1110       @outer_rp = FactoryGirl.create :resource_picture, :artist_id => @outer_artist.id, :original_picture_id => @outer_op.id, :license_id => @license.id, :picture_id => @outer_p.id
1111     end
1112     context 'つつがなく終わるとき' do
1113       it '開始日時が省略された場合はすべての内実素材を返す' do
1114         r = Picture.export 
1115         r.should eq [@p2, @other_p, @p, @old_p]
1116       end
1117       it '開始日時以降に更新された内実素材を返す' do
1118         r = Picture.export @p.updated_at - 100
1119         r.should eq [@p2, @other_p, @p]
1120       end
1121     end
1122   end
1123   
1124   describe 'リストのjson化に於いて' do
1125     before do
1126       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
1127       @p = FactoryGirl.create :picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :revision => 0
1128       @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :picture_id => @p.id
1129       @other_op = FactoryGirl.create :original_picture, :artist_id => @other_artist.id
1130       @other_p = FactoryGirl.create :picture, :artist_id => @other_artist.id, :original_picture_id => @other_op.id, :license_id => @license.id, :revision => 0, :updated_at => Time.now + 100
1131       @other_rp = FactoryGirl.create :resource_picture, :artist_id => @other_artist.id, :original_picture_id => @other_op.id, :license_id => @license.id, :picture_id => @other_p.id
1132       Picture.any_instance.stub(:restore).with(any_args).and_return('picture binary data')
1133     end
1134     context 'つつがなく終わるとき' do
1135       it 'json文字列を返す' do
1136         r = Picture.list_as_json_text Picture.all 
1137         lambda {
1138           j = JSON.parse r
1139         }.should_not raise_error(JSON::ParserError)
1140       end
1141       it '実素材リストを返す' do
1142         r = Picture.list_as_json_text Picture.all 
1143         j = JSON.parse r
1144         j.size.should eq 2
1145       end
1146       it '各実素材に画像データを添えて返す' do
1147         r = Picture.list_as_json_text Picture.all 
1148         j = JSON.parse r
1149         j.first['picture_data'].should_not be_nil
1150         j.last['picture_data'].should_not be_nil
1151       end
1152     end
1153   end
1154   
1155 end