OSDN Git Service

t#31471:add panel catch
[pettanr/pettanr.git] / spec / models / original_picture_spec.rb
1 # -*- encoding: utf-8 -*-
2 #原画
3 require 'spec_helper'
4
5 describe OriginalPicture 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   end
18   
19   describe '検証に於いて' do
20     before do
21       @op = FactoryGirl.build :original_picture, :artist_id => @artist.id
22     end
23     
24     context 'オーソドックスなデータのとき' do
25       it '下限データが通る' do
26         @op.ext = 'png' #リストにない拡張子は通らないし
27         @op.width = 1
28         @op.height = 1
29         @op.filesize = 1
30         @op.md5 = 'a'*32
31         @op.should be_valid
32       end
33       it '上限データが通る' do
34         @op.ext = 'jpeg'
35         @op.width = 99999
36         @op.height = 99999
37         @op.filesize = 2000000
38         @op.md5 = 'a'*32
39         @op.should be_valid
40       end
41     end
42     
43     context 'extを検証するとき' do
44       it 'nullなら失敗する' do
45         @op.ext = ''
46         @op.should_not be_valid
47       end
48       it '5文字以上なら失敗する' do
49         @op.ext = 'a'*5
50         @op.should_not be_valid
51       end
52       it 'png,gif,jpeg以外なら失敗する' do
53         @op.ext = 'bmp'
54         @op.should_not be_valid
55       end
56     end
57     context 'widthを検証するとき' do
58       it 'nullなら失敗する' do
59         @op.width = nil
60         @op.should_not be_valid
61       end
62       it '数値でなければ失敗する' do
63         @op.width = 'a'
64         @op.should_not be_valid
65       end
66       it '0なら失敗する' do
67         @op.width = '0'
68         @op.should_not be_valid
69       end
70       it '負でも失敗する' do
71         @op.width = -1
72         @op.should_not be_valid
73       end
74     end
75     context 'heightを検証するとき' do
76       it 'nullなら失敗する' do
77         @op.height = nil
78         @op.should_not be_valid
79       end
80       it '数値でなければ失敗する' do
81         @op.height = 'a'
82         @op.should_not be_valid
83       end
84       it '0なら失敗する' do
85         @op.height = '0'
86         @op.should_not be_valid
87       end
88       it '負でも失敗する' do
89         @op.height = -1
90         @op.should_not be_valid
91       end
92     end
93     context 'filesizeを検証するとき' do
94       it 'nullなら失敗する' do
95         @op.filesize = nil
96         @op.should_not be_valid
97       end
98       it '数値でなければ失敗する' do
99         @op.filesize = 'a'
100         @op.should_not be_valid
101       end
102       it '負なら失敗する' do
103         @op.filesize = '-1'
104         @op.should_not be_valid
105       end
106       it '2MB以上なら失敗する' do
107         @op.filesize = 2000000+1
108         @op.should_not be_valid
109       end
110     end
111     context 'artist_idを検証するとき' do
112       it 'nullなら失敗する' do
113         @op.artist_id = nil
114         @op.should_not be_valid
115       end
116       it '数値でなければ失敗する' do
117         @op.artist_id = 'a'
118         @op.should_not be_valid
119       end
120       it '存在する絵師でなければ失敗する' do
121         @op.artist_id = 0
122         @op.should_not be_valid
123       end
124     end
125     context 'md5を検証するとき' do
126       it 'nullなら失敗する' do
127         @op.md5 = ''
128         @op.should_not be_valid
129       end
130       it '31文字なら失敗する' do
131         @op.md5 = 'a'*31
132         @op.should_not be_valid
133       end
134       it '33文字なら失敗する' do
135         @op.md5 = 'a'*33
136         @op.should_not be_valid
137       end
138     end
139   end
140   
141   describe 'デフォルト値補充に於いて' do
142     it 'defined' do
143       @op = FactoryGirl.build :original_picture, :artist_id => @artist.id
144       @op.supply_default
145     end
146   end
147   
148   describe '上書き補充に於いて' do
149     it '投稿日時が設定されている' do
150       @op = FactoryGirl.build :original_picture, :uploaded_at => nil
151       @op.overwrite @artist
152       @op.uploaded_at.should_not be_nil
153     end
154     it '絵師idが設定されている' do
155       @op = FactoryGirl.build :original_picture, :artist_id => nil
156       @op.overwrite @artist
157       @op.artist_id.should eq @artist.id
158     end
159   end
160   
161   describe '所持判定に於いて' do
162     before do
163       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
164     end
165     context '事前チェックする' do
166       it '自身にロールリストからの絵師取得を依頼している' do
167         OriginalPicture.should_receive(:get_artist_from_roles).with(any_args).exactly(1)
168         r = @op.own?([@artist])
169       end
170     end
171     context 'ロール内絵師が取得できるとき' do
172       before do
173       end
174       it 'ロール内絵師のidが自身の絵師idと一致するなら許可する' do
175         OriginalPicture.stub(:get_artist_from_roles).with(any_args).and_return(@artist)
176         r = @op.own?([@artist])
177         r.should be_true
178       end
179       it 'ロール内絵師のidが自身の絵師idと一致しないならno' do
180         OriginalPicture.stub(:get_artist_from_roles).with(any_args).and_return(@other_artist)
181         @op.own?(@other_artist).should be_false
182       end
183     end
184     context 'ロール内絵師が取得できないとき' do
185       before do
186         OriginalPicture.stub(:get_artist_from_roles).with(any_args).and_return(nil)
187       end
188       it 'Falseを返す' do
189         r = @op.own?([@artist])
190         r.should be_false
191       end
192     end
193   end
194   
195   describe '閲覧許可に於いて' do
196     before do
197       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
198     end
199     context '事前チェックする' do
200       before do
201         MagicNumber['run_mode'] = 1
202       end
203       it '自身の原画に所持判定を問い合わせしている' do
204         OriginalPicture.any_instance.stub(:own?).and_return(true)
205         OriginalPicture.any_instance.should_receive(:own?).with(any_args).exactly(1)
206         r = @op.visible?([@artist])
207       end
208     end
209     context 'つつがなく終わるとき' do
210       before do
211         MagicNumber['run_mode'] = 1
212       end
213       it '自分の原画なら許可する' do
214         OriginalPicture.any_instance.stub(:own?).and_return(true)
215         r = @op.visible?([@artist])
216         r.should be_true
217       end
218       it '他人の原画なら許可しない' do
219         OriginalPicture.any_instance.stub(:own?).and_return(false)
220         r = @op.visible?([@artist])
221         r.should be_false
222       end
223     end
224   end
225   
226   describe 'ファイル名に於いて' do
227     before do
228       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
229     end
230     it 'id+拡張子のフォーマットで返す' do
231       r = @op.filename
232       r.should eq "#{@op.id}.png"
233     end
234   end
235   
236   describe 'MimeTypeに於いて' do
237     before do
238       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
239     end
240     it 'image/拡張子のフォーマットで返す' do
241       r = @op.mime_type
242       r.should eq "image/png"
243     end
244   end
245   
246   describe 'ファイルのurlに於いて' do
247     before do
248       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
249       OriginalPicture.any_instance.stub(:filename).and_return('3.gif')
250     end
251     it 'ファイル名取得を依頼している' do
252       OriginalPicture.any_instance.should_receive(:filename).exactly(1)
253       @op.url
254     end
255     it '/original_pictures/3.gifのフォーマットで返す' do
256       r = @op.url
257       r.should eq "/original_pictures/3.gif"
258     end
259   end
260   
261   describe 'サムネイル画像タグオプションに於いて' do
262     before do
263       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
264       OriginalPicture.any_instance.stub(:url).and_return('/original_pictures/3.gif')
265       PettanImager.stub(:thumbnail_size).with(any_args).and_return([40, 30])
266     end
267     it 'サムネイル画像の幅高さ取得を依頼している' do
268       PettanImager.should_receive(:thumbnail_size).with(any_args).exactly(1)
269       @op.tmb_opt_img_tag
270     end
271     it '戻り値はHashで返す' do
272       r = @op.tmb_opt_img_tag
273       r.is_a?(Hash).should be_true
274     end
275     it 'srcキーを含んでいる' do
276       r = @op.tmb_opt_img_tag
277       r.has_key?(:src).should be_true
278       r[:src].should eq '/original_pictures/3.gif'
279     end
280     it 'widthキーを含んでいる' do
281       r = @op.tmb_opt_img_tag
282       r.has_key?(:width).should be_true
283       r[:width].should eq 40
284     end
285     it 'heightキーを含んでいる' do
286       r = @op.tmb_opt_img_tag
287       r.has_key?(:height).should be_true
288       r[:height].should eq 30
289     end
290   end
291   
292   describe '画像タグオプションに於いて' do
293     before do
294       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
295       OriginalPicture.any_instance.stub(:url).and_return('/original_pictures/3.gif')
296     end
297     it '戻り値はHashで返す' do
298       r = @op.opt_img_tag
299       r.is_a?(Hash).should be_true
300     end
301     it 'srcキーを含んでいる' do
302       r = @op.opt_img_tag
303       r.has_key?(:src).should be_true
304       r[:src].should eq '/original_pictures/3.gif'
305     end
306     it 'widthキーを含んでいる' do
307       r = @op.opt_img_tag
308       r.has_key?(:width).should be_true
309       r[:width].should eq @op.width
310     end
311     it 'heightキーを含んでいる' do
312       r = @op.opt_img_tag
313       r.has_key?(:height).should be_true
314       r[:height].should eq @op.height
315     end
316   end
317   
318   describe '未公開に於いて' do
319     before do
320       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
321     end
322     context '公開日時と停止日時がともに空のとき' do
323       it 'Trueを返す' do
324         r = @op.unpublished?
325         r.should be_true
326       end
327     end
328     context '公開日時と停止日時がともに空ではないとき' do
329       it 'Falseを返す' do
330         @op.stopped_at =Time.now
331         r = @op.unpublished?
332         r.should be_false
333       end
334       it 'Falseを返す' do
335         @op.published_at =Time.now
336         r = @op.unpublished?
337         r.should be_false
338       end
339     end
340   end
341
342   describe '停止中に於いて' do
343     before do
344       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
345     end
346     context '停止日時が空でないとき' do
347       it 'Trueを返す' do
348         @op.stopped_at =Time.now
349         r = @op.stopped?
350         r.should be_true
351       end
352     end
353     context '停止日時が空のとき' do
354       it 'Falseを返す' do
355         @op.stopped_at = nil
356         r = @op.stopped?
357         r.should be_false
358       end
359     end
360   end
361
362   describe 'ライセンス待ちに於いて' do
363     before do
364       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
365     end
366     context '公開日時と停止日時のうち、空でない方を取得して、投稿日時がそれより後のとき' do
367       it 'Trueを返す' do
368         @op.uploaded_at = Time.now
369         @op.stopped_at = Time.now - 400
370         r = @op.unlicensed?
371         r.should be_true
372       end
373       it 'Trueを返す' do
374         @op.uploaded_at = Time.now
375         @op.published_at =Time.now - 400
376         r = @op.unlicensed?
377         r.should be_true
378       end
379     end
380     context '公開日時と停止日時のうち、空でない方を取得して、投稿日時がそれより後ではないとき' do
381       it 'Falseを返す' do
382         @op.published_at = nil
383         @op.stopped_at = nil
384         r = @op.unlicensed?
385         r.should be_false
386       end
387       it 'Falseを返す' do
388         @op.uploaded_at = Time.now
389         @op.published_at =Time.now + 400
390         r = @op.unlicensed?
391         r.should be_false
392       end
393       it 'Falseを返す' do
394         @op.uploaded_at = Time.now
395         @op.stopped_at =Time.now + 400
396         r = @op.unlicensed?
397         r.should be_false
398       end
399     end
400   end
401
402   describe '公開中に於いて' do
403     before do
404       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
405     end
406     context '公開日時が空ではないとき' do
407       it 'Trueを返す' do
408         @op.published_at =Time.now
409         r = @op.published?
410         r.should be_true
411       end
412     end
413     context '公開日時が空のとき' do
414       it 'Falseを返す' do
415         @op.published_at = nil
416         r = @op.published?
417         r.should be_false
418       end
419     end
420   end
421
422   describe '一覧取得に於いて' do
423     before do
424       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
425     end
426     context 'page補正について' do
427       it '文字列から数値に変換される' do
428         OriginalPicture.page('8').should eq 8
429       end
430       it 'nilの場合は1になる' do
431         OriginalPicture.page().should eq 1
432       end
433       it '0以下の場合は1になる' do
434         OriginalPicture.page('0').should eq 1
435       end
436     end
437     context 'page_size補正について' do
438       it '文字列から数値に変換される' do
439         OriginalPicture.page_size('7').should eq 7
440       end
441       it 'nilの場合はOriginalPicture.default_page_sizeになる' do
442         OriginalPicture.page_size().should eq OriginalPicture.default_page_size
443       end
444       it '0以下の場合はOriginalPicture.default_page_sizeになる' do
445         OriginalPicture.page_size('0').should eq OriginalPicture.default_page_size
446       end
447       it 'OriginalPicture.max_page_sizeを超えた場合はOriginalPicture.max_page_sizeになる' do
448         OriginalPicture.page_size('1000').should eq OriginalPicture.max_page_size
449       end
450     end
451   end
452   describe '一覧取得オプションに於いて' do
453     it 'includeキーを含んでいる' do
454       r = OriginalPicture.list_opt
455       r.has_key?(:include).should be_true
456     end
457     it '2つの項目を含んでいる' do
458       r = OriginalPicture.list_opt[:include]
459       r.should have(2).items
460     end
461     it '素材を含んでいる' do
462       r = OriginalPicture.list_opt[:include]
463       r.has_key?(:resource_picture).should be_true
464     end
465     it '実素材を含んでいる' do
466       r = OriginalPicture.list_opt[:include]
467       r.has_key?(:pictures).should be_true
468     end
469   end
470   describe 'json一覧出力オプションに於いて' do
471     before do
472       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
473       @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id
474       @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :license_id => @license.id, :original_picture_id => @op.id, :picture_id => @p.id
475       @sbt = FactoryGirl.create :speech_balloon_template
476       @comic = FactoryGirl.create :comic, :author_id => @author.id, :visible => 1
477       @panel = FactoryGirl.create :panel, :author_id => @author.id, :publish => 1
478       @story = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id
479     end
480     it '素材を含んでいる' do
481       r = OriginalPicture.mylist(@artist).to_json OriginalPicture.list_json_opt
482       j = JSON.parse r
483       i = j.first
484       i.has_key?('resource_picture').should be_true
485     end
486     it '実素材を含んでいる' do
487       r = OriginalPicture.mylist(@artist).to_json OriginalPicture.list_json_opt
488       j = JSON.parse r
489       i = j.first
490       i.has_key?('pictures').should be_true
491     end
492   end
493   
494   describe '自分の原画一覧取得に於いて' do
495     before do
496       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
497     end
498     context 'つつがなく終わるとき' do
499       it '一覧取得オプションを利用している' do
500         OriginalPicture.stub(:list_opt).with(any_args).and_return({})
501         OriginalPicture.should_receive(:list_opt).with(any_args).exactly(1)
502         r = OriginalPicture.mylist @artist
503       end
504     end
505     it 'リストを返す' do
506       r = OriginalPicture.mylist @artist
507       r.should eq [@op]
508     end
509     it '時系列で並んでいる' do
510       nc = FactoryGirl.create :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 100
511       r = OriginalPicture.mylist @artist
512       r.should eq [nc, @op]
513     end
514     it '他人の原画は含まない' do
515       nc = FactoryGirl.create :original_picture, :artist_id => @other_artist.id
516       r = OriginalPicture.mylist @artist
517       r.should eq [@op]
518     end
519     context 'DBに5件あって1ページの件数を2件に変えたとして' do
520       before do
521         @op2 = FactoryGirl.create :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 100
522         @op3 = FactoryGirl.create :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 200
523         @op4 = FactoryGirl.create :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 300
524         @op5 = FactoryGirl.create :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 400
525       end
526       it '通常は2件を返す' do
527         r = OriginalPicture.mylist @artist, 1, 2
528         r.should have(2).items 
529       end
530       it 'page=1なら末尾2件を返す' do
531         #時系列で並んでいる
532         r = OriginalPicture.mylist @artist, 1, 2
533         r.should eq [@op5, @op4]
534       end
535       it 'page=2なら中間2件を返す' do
536         r = OriginalPicture.mylist @artist, 2, 2
537         r.should eq [@op3, @op2]
538       end
539       it 'page=3なら先頭1件を返す' do
540         r = OriginalPicture.mylist @artist, 3, 2
541         r.should eq [@op]
542       end
543     end
544     context 'DBに5件あって1ページの件数を0件に変えたとして' do
545       before do
546         @op2 = FactoryGirl.create :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 100
547         @op3 = FactoryGirl.create :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 200
548         @op4 = FactoryGirl.create :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 300
549         @op5 = FactoryGirl.create :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 400
550         OriginalPicture.stub(:default_page_size).and_return(2)
551       end
552       it '通常は全件(5件)を返す' do
553         r = OriginalPicture.mylist @artist, 5, 0
554         r.should have(5).items 
555       end
556     end
557   end
558   
559   describe '更新履歴一覧取得に於いて' do
560     before do
561       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
562       @p = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 0,
563         :original_picture_id => @op.id
564       @op2 = FactoryGirl.create :original_picture, :artist_id => @artist.id
565     end
566     it 'リストを返す' do
567       r = @op.history
568       r.should eq [@p]
569     end
570     it '他の原画の実素材は含んでいない' do
571       @p2 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 0,
572         :original_picture_id => @op2.id
573       r = @op.history
574       r.should eq [@p]
575     end
576     it 'revisionで並んでいる' do
577       @p2 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
578         :original_picture_id => @op.id
579       r = @op.history
580       r.should eq [@p2, @p]
581     end
582   end
583   
584   describe '単体取得に於いて' do
585     before do
586       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
587     end
588     context 'つつがなく終わるとき' do
589       it '単体取得オプションを利用している' do
590         OriginalPicture.stub(:show_opt).with(any_args).and_return({})
591         OriginalPicture.should_receive(:show_opt).with(any_args).exactly(1)
592         r = OriginalPicture.show @op.id, @artist
593       end
594       it '閲覧許可を問い合わせている' do
595         OriginalPicture.any_instance.stub(:visible?).with(any_args).and_return(true)
596         OriginalPicture.any_instance.should_receive(:visible?).with(any_args).exactly(1)
597         r = OriginalPicture.show @op.id, @artist
598       end
599     end
600     it '指定の原画を返す' do
601       pic = OriginalPicture.show @op.id, @artist
602       pic.should eq @op
603     end
604     context '他人の原画を開こうとしたとき' do
605       it '403Forbidden例外を返す' do
606         OriginalPicture.any_instance.stub(:visible?).and_return(false)
607         lambda{
608           pic = OriginalPicture.show @op.id, @other_artist
609         }.should raise_error(ActiveRecord::Forbidden)
610       end
611     end
612     context '存在しない原画を開こうとしたとき' do
613       it '404RecordNotFound例外を返す' do
614         lambda{
615           pic = OriginalPicture.show 0, @artist
616         }.should raise_error(ActiveRecord::RecordNotFound)
617       end
618     end
619   end
620   describe '編集取得に於いて' do
621     before do
622       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
623     end
624     context 'つつがなく終わるとき' do
625       it '単体取得オプションを利用している' do
626         OriginalPicture.stub(:show_opt).with(any_args).and_return({})
627         OriginalPicture.should_receive(:show_opt).with(any_args).exactly(1)
628         r = OriginalPicture.edit @op.id, @artist
629       end
630       it '所持判定を問い合わせている' do
631         OriginalPicture.any_instance.stub(:own?).with(any_args).and_return(true)
632         OriginalPicture.any_instance.should_receive(:own?).with(any_args).exactly(1)
633         r = OriginalPicture.edit @op.id, @artist
634       end
635     end
636     it '指定の原画を返す' do
637       pic = OriginalPicture.edit @op.id, @artist
638       pic.should eq @op
639     end
640     context '他人の原画を開こうとしたとき' do
641       it '403Forbidden例外を返す' do
642         OriginalPicture.any_instance.stub(:own?).and_return(false)
643         lambda{
644           r = OriginalPicture.edit @op.id, @other_artist
645         }.should raise_error(ActiveRecord::Forbidden)
646       end
647     end
648     context '存在しない原画を開こうとしたとき' do
649       it '404RecordNotFound例外を返す' do
650         lambda{
651           r = OriginalPicture.edit 0, @artist
652         }.should raise_error(ActiveRecord::RecordNotFound)
653       end
654     end
655   end
656   describe '単体取得オプションに於いて' do
657     it 'includeキーを含んでいる' do
658       r = OriginalPicture.show_opt
659       r.has_key?(:include).should be_true
660     end
661     it '2つの項目を含んでいる' do
662       r = OriginalPicture.show_opt[:include]
663       r.should have(2).items
664     end
665     it '素材を含んでいる' do
666       r = OriginalPicture.show_opt[:include]
667       r.has_key?(:resource_picture).should be_true
668     end
669     it '実素材を含んでいる' do
670       r = OriginalPicture.show_opt[:include]
671       r.has_key?(:pictures).should be_true
672     end
673   end
674   describe 'json単体出力オプションに於いて' do
675     before do
676       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
677       @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id
678       @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :license_id => @license.id, :original_picture_id => @op.id, :picture_id => @p.id
679       @sbt = FactoryGirl.create :speech_balloon_template
680       @comic = FactoryGirl.create :comic, :author_id => @author.id, :visible => 1
681       @panel = FactoryGirl.create :panel, :author_id => @author.id, :publish => 1
682       @story = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id
683     end
684     it '素材を含んでいる' do
685       r = OriginalPicture.show(@op.id, @artist).to_json OriginalPicture.show_json_opt
686       j = JSON.parse r
687       i = j
688       i.has_key?('resource_picture').should be_true
689     end
690     it '実素材を含んでいる' do
691       r = OriginalPicture.show(@op.id, @artist).to_json OriginalPicture.show_json_opt
692       j = JSON.parse r
693       i = j
694       i.has_key?('pictures').should be_true
695     end
696   end
697   describe '作成・更新に於いて' do
698     before do
699       @op = FactoryGirl.build :original_picture, :artist_id => @artist.id
700       @imager = ImagerTest.load "abc\ndef\nghi"
701     end
702     context '事前チェック' do
703       before do
704         #すべての処理が正常パターンで通過すれば、一番深い分岐まで通る。
705         #それで外部のメソッド呼び出しだけに着目してテストする。
706         OriginalPicture.any_instance.stub(:save).with(any_args).and_return(true)
707         PictureIO.original_picture_io.stub(:put).with(any_args).and_return(true)
708       end
709       it '自身に属性をセットしている' do
710         OriginalPicture.any_instance.should_receive(:attributes=).exactly(1)
711         @op.store @imager
712       end
713       it '自身が保存されている' do
714         OriginalPicture.any_instance.should_receive(:save).exactly(1)
715         @op.store @imager
716       end
717       it 'PictureIoに画像データの保存を依頼している' do
718         PictureIO.original_picture_io.should_receive(:put).with(any_args).exactly(1)
719         @op.store @imager
720       end
721     end
722     context 'つつがなく終わるとき' do
723       before do
724       end
725       it '自身に属性をセットしている' do
726         @op.store @imager
727         @op.width.should eq 3
728         @op.height.should eq 3
729         @op.filesize.should eq 9
730       end
731       it '原画モデルが作成されている' do
732         lambda {
733           @op.store @imager
734         }.should change OriginalPicture, :count
735       end
736       it '原画が保存されている' do
737         @op.store @imager
738         OriginalPicture.find(@op).should_not be_nil
739       end
740       it 'Trueを返す' do
741         @op.store(@imager).should eq true
742       end
743     end
744     #以下から例外ケース。処理先頭から失敗させていく
745     context 'imagerが初期化に失敗したとき' do
746       before do
747       end
748       it 'falseを返す' do
749         @op.store(false).should be_false
750       end
751       it '自身の保存は呼ばれていない' do
752         OriginalPicture.any_instance.should_not_receive(:save)
753         @op.store(false)
754       end
755       it '全体エラーメッセージがセットされている' do
756         lambda {
757           @op.store(false)
758         }.should change(@op.errors[:base], :count)
759       end
760     end
761     context '自身の保存に失敗したとき' do
762       before do
763         OriginalPicture.any_instance.stub(:save).with(any_args).and_return(false)
764       end
765       it 'falseを返す' do
766         @op.store(@imager).should be_false
767       end
768       it '更新されていない' do
769         @op.store(@imager)
770         @op.should be_a_new OriginalPicture
771       end
772       it '原画の保存は呼ばれていない' do
773         PictureIO::LocalPicture.any_instance.should_not_receive(:put)
774       end
775     end
776     context '原画の保存に失敗したとき' do
777       before do
778         OriginalPicture.any_instance.stub(:save).with(any_args).and_return(true)
779         PictureIO.original_picture_io.stub(:put).with(any_args).and_raise(PictureIO::Error)
780       end
781       it 'falseを返す' do
782         @op.store(@imager).should be_false
783       end
784       it '更新されていない' do
785         @op.store(@imager)
786         @op.should be_a_new OriginalPicture
787       end
788       it '全体エラーメッセージがセットされている' do
789         lambda {
790           @op.store(@imager)
791         }.should change(@op.errors[:base], :count)
792       end
793     end
794   end
795   
796   describe '削除に於いて' do
797     before do
798       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
799     end
800     context '事前チェックしておく' do
801       before do
802         OriginalPicture.any_instance.stub(:destroy).and_return(true)
803         ResourcePicture.any_instance.stub(:unpublish).and_return(true)
804         Picture.any_instance.stub(:unpublish).with(any_args).and_return(true)
805         PictureIO.original_picture_io.stub(:delete).with(any_args).and_return(true)
806       end
807       it '原画モデルに削除を依頼している' do
808         OriginalPicture.any_instance.should_receive(:destroy).exactly(1)
809         r = @op.destroy_with_resource_picture
810       end
811       it '保管庫に原画の画像データ削除を依頼している' do
812         PictureIO.original_picture_io.should_receive(:delete).with(@op.filename).exactly(1)
813         r = @op.destroy_with_resource_picture
814       end
815       context '自身にリンクされた素材があるとき' do
816         it '素材モデルに削除を依頼している' do
817           @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :revision => 0
818           @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :license_id => @license.id, :original_picture_id => @op.id, :picture_id => @p.id
819           ResourcePicture.any_instance.should_receive(:unpublish).exactly(1)
820           r = @op.destroy_with_resource_picture
821         end
822       end
823       context '自身にリンクされた素材がないとき' do
824         it '素材モデルに削除を依頼しない' do
825           ResourcePicture.any_instance.should_not_receive(:unpublish)
826           r = @op.destroy_with_resource_picture
827         end
828       end
829       context '自身にリンクされた実素材があるとき' do
830         it 'すべての実素材に墨塗を依頼している' do
831           @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :revision => 0
832           Picture.any_instance.should_receive(:unpublish).with(any_args).exactly(1)
833           r = @op.destroy_with_resource_picture
834         end
835       end
836       context '自身にリンクされた実素材がないとき' do
837         it '実素材に墨塗を依頼しない' do
838           Picture.any_instance.should_not_receive(:unpublish)
839           r = @op.destroy_with_resource_picture
840         end
841       end
842     end
843     context 'つつがなく終わるとき' do
844       before do
845         PictureIO.original_picture_io.stub(:delete).with(any_args).and_return(true)
846         @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :revision => 0
847         @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :license_id => @license.id, :original_picture_id => @op.id, :picture_id => @p.id
848       end
849       it '自身を削除する' do
850         lambda {
851           r = @op.destroy_with_resource_picture
852         }.should change(OriginalPicture, :count).by(-1)
853         lambda {
854           r = OriginalPicture.find @op.id
855         }.should raise_error
856       end
857       it 'Trueを返す' do
858         r = @op.destroy_with_resource_picture
859         r.should be_true
860       end
861     end
862     context '自身の削除に失敗したとき' do
863       before do
864         OriginalPicture.any_instance.stub(:destroy).with(any_args).and_return(false)
865       end
866       it 'Falseを返す' do
867         r = @op.destroy_with_resource_picture
868         r.should be_false
869       end
870       it 'ロールバックしている' do
871         lambda {
872           r = @op.destroy_with_resource_picture
873         }.should_not change(OriginalPicture, :count)
874       end
875     end
876     context '画像の削除に失敗したとき' do
877       before do
878         PictureIO.original_picture_io.stub(:exist?).with(@op.filename).and_return(true)
879         PictureIO.original_picture_io.stub(:delete).with(@op.filename).and_raise(PictureIO::Error)
880       end
881       it 'Falseを返す' do
882         r = @op.destroy_with_resource_picture
883         r.should be_false
884       end
885       it 'ロールバックしている' do
886         lambda {
887           r = @op.destroy_with_resource_picture
888         }.should_not change(OriginalPicture, :count)
889       end
890     end
891     context '素材の削除に失敗とき' do
892       before do
893         @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :revision => 0
894         @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :license_id => @license.id, :original_picture_id => @op.id, :picture_id => @p.id
895         ResourcePicture.any_instance.stub(:unpublish).with(any_args).and_return(false)
896       end
897       it 'Falseを返す' do
898         r = @op.destroy_with_resource_picture
899         r.should be_false
900       end
901       it 'ロールバックしている' do
902         lambda {
903           r = @op.destroy_with_resource_picture
904         }.should_not change(OriginalPicture, :count)
905         lambda {
906           r = @op.destroy_with_resource_picture
907         }.should_not change(ResourcePicture, :count)
908       end
909     end
910     context '実素材の墨塗に失敗とき' do
911       before do
912         @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :revision => 0
913         @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :license_id => @license.id, :original_picture_id => @op.id, :picture_id => @p.id
914         Picture.any_instance.stub(:unpublish).with(any_args).and_return(false)
915       end
916       it 'Falseを返す' do
917         r = @op.destroy_with_resource_picture
918         r.should be_false
919       end
920       it 'ロールバックしている' do
921         lambda {
922           r = @op.destroy_with_resource_picture
923         }.should_not change(OriginalPicture, :count)
924         lambda {
925           r = @op.destroy_with_resource_picture
926         }.should_not change(ResourcePicture, :count)
927       end
928     end
929   end
930   
931   describe 'エクスポートに於いて' do
932     before do
933       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
934       @p = FactoryGirl.create :picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :revision => 0
935       @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :picture_id => @p.id
936       #開始日時以前の原画
937       @old_op = FactoryGirl.create :original_picture, :artist_id => @artist.id, :updated_at => Time.now - 1000
938       #素材がライセンスされていない原画
939       @stopped_op = FactoryGirl.create :original_picture, :artist_id => @artist.id
940       #他人の原画
941       @other_op = FactoryGirl.create :original_picture, :artist_id => @other_artist.id
942       #貸手からの原画排除
943       @outer_artist = FactoryGirl.create :artist_yas, :author_id => nil
944       @outer_op = FactoryGirl.create :original_picture, :artist_id => @outer_artist.id
945     end
946     context 'つつがなく終わるとき' do
947       it '開始日時が省略された場合はすべての内原画を返す' do
948         r = OriginalPicture.export 
949         r.should eq [@op, @old_op, @stopped_op, @other_op]
950       end
951       it '開始日時以降に更新された内原画を返す' do
952         r = OriginalPicture.export @op.updated_at - 100
953         r.should eq [@op, @stopped_op, @other_op]
954       end
955       it '素材を含んでいる' do
956         r = OriginalPicture.export 
957         r.first.resource_picture.should_not be_nil
958       end
959       #素材がライセンスされていないケースもある
960       it '停止中の原画は素材を含んでいない' do
961         r = OriginalPicture.export
962         r[2].resource_picture.should be_nil
963       end
964     end
965   end
966   
967   describe 'リストのjson化に於いて' do
968     before do
969       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
970       @p = FactoryGirl.create :picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :revision => 0
971       @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :picture_id => @p.id
972       @other_op = FactoryGirl.create :original_picture, :artist_id => @other_artist.id
973       @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
974       @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
975       ResourcePicture.any_instance.stub(:restore).with(any_args).and_return('picture binary data')
976     end
977     context 'つつがなく終わるとき' do
978       it 'json文字列を返す' do
979         r = OriginalPicture.list_as_json_text OriginalPicture.all 
980         lambda {
981           j = JSON.parse r
982         }.should_not raise_error(JSON::ParserError)
983       end
984       it '原画リストを返す' do
985         r = OriginalPicture.list_as_json_text OriginalPicture.all 
986         j = JSON.parse r
987         j.size.should eq 2
988       end
989       it '素材を含んでいる' do
990         r = OriginalPicture.list_as_json_text OriginalPicture.all 
991         j = JSON.parse r
992         j.first['resource_picture'].should_not be_nil
993       end
994       it '各素材に画像データを添えて返す' do
995         r = OriginalPicture.list_as_json_text OriginalPicture.all 
996         j = JSON.parse r
997         j.first['resource_picture']['picture_data'].should_not be_nil
998         j.last['resource_picture']['picture_data'].should_not be_nil
999       end
1000     end
1001   end
1002   
1003   describe 'インポートに於いて' do
1004     before do
1005       @imports = {:licenses => {}, :artist_id => @artist.id}
1006     end
1007     context '事前チェックしておく' do
1008     end
1009   end
1010   
1011 end