OSDN Git Service

t#31470:create pager
[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   
453   describe '自分の原画一覧取得に於いて' do
454     before do
455       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
456     end
457     context 'つつがなく終わるとき' do
458       it '一覧取得オプションを利用している' do
459         OriginalPicture.stub(:list_opt).with(any_args).and_return({})
460         OriginalPicture.should_receive(:list_opt).with(any_args).exactly(1)
461         r = OriginalPicture.mylist @artist
462       end
463     end
464     it 'リストを返す' do
465       r = OriginalPicture.mylist @artist
466       r.should eq [@op]
467     end
468     it '時系列で並んでいる' do
469       nc = FactoryGirl.create :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 100
470       r = OriginalPicture.mylist @artist
471       r.should eq [nc, @op]
472     end
473     it '他人の原画は含まない' do
474       nc = FactoryGirl.create :original_picture, :artist_id => @other_artist.id
475       r = OriginalPicture.mylist @artist
476       r.should eq [@op]
477     end
478     context 'DBに5件あって1ページの件数を2件に変えたとして' do
479       before do
480         @op2 = FactoryGirl.create :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 100
481         @op3 = FactoryGirl.create :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 200
482         @op4 = FactoryGirl.create :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 300
483         @op5 = FactoryGirl.create :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 400
484       end
485       it '通常は2件を返す' do
486         r = OriginalPicture.mylist @artist, 1, 2
487         r.should have(2).items 
488       end
489       it 'page=1なら末尾2件を返す' do
490         #時系列で並んでいる
491         r = OriginalPicture.mylist @artist, 1, 2
492         r.should eq [@op5, @op4]
493       end
494       it 'page=2なら中間2件を返す' do
495         r = OriginalPicture.mylist @artist, 2, 2
496         r.should eq [@op3, @op2]
497       end
498       it 'page=3なら先頭1件を返す' do
499         r = OriginalPicture.mylist @artist, 3, 2
500         r.should eq [@op]
501       end
502     end
503   end
504   
505   describe '自分の原画一覧ページ制御に於いて' do
506     before do
507       OriginalPicture.stub(:count).with(any_args).and_return(100)
508     end
509     it 'ページ制御を返す' do
510       r = OriginalPicture.mylist_paginate @author
511       r.is_a?(Kaminari::PaginatableArray).should be_true
512     end
513     it '自分の原画一覧の取得条件を利用している' do
514       OriginalPicture.stub(:mylist_where).with(any_args).and_return('')
515       OriginalPicture.should_receive(:mylist_where).with(any_args).exactly(1)
516       r = OriginalPicture.mylist_paginate @author
517     end
518     it 'ページ件数10のとき、3ページ目のオフセットは20から始まる' do
519       r = OriginalPicture.mylist_paginate @author, 3, 10
520       r.limit_value.should eq 10
521       r.offset_value.should eq 20
522     end
523   end
524   
525   describe '一覧取得オプションに於いて' do
526     it '2つの項目を含んでいる' do
527       r = OriginalPicture.list_opt
528       r.should have(2).items
529     end
530     it '素材を含んでいる' do
531       r = OriginalPicture.list_opt
532       r.has_key?(:resource_picture).should be_true
533     end
534     it '実素材を含んでいる' do
535       r = OriginalPicture.list_opt
536       r.has_key?(:pictures).should be_true
537     end
538   end
539   describe 'json一覧出力オプションに於いて' do
540     before do
541       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
542       @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id
543       @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :license_id => @license.id, :original_picture_id => @op.id, :picture_id => @p.id
544       @sbt = FactoryGirl.create :speech_balloon_template
545       @comic = FactoryGirl.create :comic, :author_id => @author.id, :visible => 1
546       @panel = FactoryGirl.create :panel, :author_id => @author.id, :publish => 1
547       @story = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id
548     end
549     it '素材を含んでいる' do
550       r = OriginalPicture.mylist(@artist).to_json OriginalPicture.list_json_opt
551       j = JSON.parse r
552       i = j.first
553       i.has_key?('resource_picture').should be_true
554     end
555     it '実素材を含んでいる' do
556       r = OriginalPicture.mylist(@artist).to_json OriginalPicture.list_json_opt
557       j = JSON.parse r
558       i = j.first
559       i.has_key?('pictures').should be_true
560     end
561   end
562   
563   describe '更新履歴一覧取得に於いて' do
564     before do
565       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
566       @p = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 0,
567         :original_picture_id => @op.id
568       @op2 = FactoryGirl.create :original_picture, :artist_id => @artist.id
569     end
570     it 'リストを返す' do
571       r = @op.history
572       r.should eq [@p]
573     end
574     it '他の原画の実素材は含んでいない' do
575       @p2 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 0,
576         :original_picture_id => @op2.id
577       r = @op.history
578       r.should eq [@p]
579     end
580     it 'revisionで並んでいる' do
581       @p2 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
582         :original_picture_id => @op.id
583       r = @op.history
584       r.should eq [@p2, @p]
585     end
586   end
587   
588   describe '単体取得に於いて' do
589     before do
590       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
591     end
592     context 'つつがなく終わるとき' do
593       it '単体取得オプションを利用している' do
594         OriginalPicture.stub(:show_opt).with(any_args).and_return({})
595         OriginalPicture.should_receive(:show_opt).with(any_args).exactly(1)
596         r = OriginalPicture.show @op.id, @artist
597       end
598       it '閲覧許可を問い合わせている' do
599         OriginalPicture.any_instance.stub(:visible?).with(any_args).and_return(true)
600         OriginalPicture.any_instance.should_receive(:visible?).with(any_args).exactly(1)
601         r = OriginalPicture.show @op.id, @artist
602       end
603     end
604     it '指定の原画を返す' do
605       pic = OriginalPicture.show @op.id, @artist
606       pic.should eq @op
607     end
608     context '他人の原画を開こうとしたとき' do
609       it '403Forbidden例外を返す' do
610         OriginalPicture.any_instance.stub(:visible?).and_return(false)
611         lambda{
612           pic = OriginalPicture.show @op.id, @other_artist
613         }.should raise_error(ActiveRecord::Forbidden)
614       end
615     end
616     context '存在しない原画を開こうとしたとき' do
617       it '404RecordNotFound例外を返す' do
618         lambda{
619           pic = OriginalPicture.show 0, @artist
620         }.should raise_error(ActiveRecord::RecordNotFound)
621       end
622     end
623   end
624   describe '編集取得に於いて' do
625     before do
626       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
627     end
628     context 'つつがなく終わるとき' do
629       it '単体取得オプションを利用している' do
630         OriginalPicture.stub(:show_opt).with(any_args).and_return({})
631         OriginalPicture.should_receive(:show_opt).with(any_args).exactly(1)
632         r = OriginalPicture.edit @op.id, @artist
633       end
634       it '所持判定を問い合わせている' do
635         OriginalPicture.any_instance.stub(:own?).with(any_args).and_return(true)
636         OriginalPicture.any_instance.should_receive(:own?).with(any_args).exactly(1)
637         r = OriginalPicture.edit @op.id, @artist
638       end
639     end
640     it '指定の原画を返す' do
641       pic = OriginalPicture.edit @op.id, @artist
642       pic.should eq @op
643     end
644     context '他人の原画を開こうとしたとき' do
645       it '403Forbidden例外を返す' do
646         OriginalPicture.any_instance.stub(:own?).and_return(false)
647         lambda{
648           r = OriginalPicture.edit @op.id, @other_artist
649         }.should raise_error(ActiveRecord::Forbidden)
650       end
651     end
652     context '存在しない原画を開こうとしたとき' do
653       it '404RecordNotFound例外を返す' do
654         lambda{
655           r = OriginalPicture.edit 0, @artist
656         }.should raise_error(ActiveRecord::RecordNotFound)
657       end
658     end
659   end
660   describe '単体取得オプションに於いて' do
661     it 'includeキーを含んでいる' do
662       r = OriginalPicture.show_opt
663       r.has_key?(:include).should be_true
664     end
665     it '2つの項目を含んでいる' do
666       r = OriginalPicture.show_opt[:include]
667       r.should have(2).items
668     end
669     it '素材を含んでいる' do
670       r = OriginalPicture.show_opt[:include]
671       r.has_key?(:resource_picture).should be_true
672     end
673     it '実素材を含んでいる' do
674       r = OriginalPicture.show_opt[:include]
675       r.has_key?(:pictures).should be_true
676     end
677   end
678   describe 'json単体出力オプションに於いて' do
679     before do
680       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
681       @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id
682       @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :license_id => @license.id, :original_picture_id => @op.id, :picture_id => @p.id
683       @sbt = FactoryGirl.create :speech_balloon_template
684       @comic = FactoryGirl.create :comic, :author_id => @author.id, :visible => 1
685       @panel = FactoryGirl.create :panel, :author_id => @author.id, :publish => 1
686       @story = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id
687     end
688     it '素材を含んでいる' do
689       r = OriginalPicture.show(@op.id, @artist).to_json OriginalPicture.show_json_opt
690       j = JSON.parse r
691       i = j
692       i.has_key?('resource_picture').should be_true
693     end
694     it '実素材を含んでいる' do
695       r = OriginalPicture.show(@op.id, @artist).to_json OriginalPicture.show_json_opt
696       j = JSON.parse r
697       i = j
698       i.has_key?('pictures').should be_true
699     end
700   end
701   describe '作成・更新に於いて' do
702     before do
703       @op = FactoryGirl.build :original_picture, :artist_id => @artist.id
704       @imager = ImagerTest.load "abc\ndef\nghi"
705     end
706     context '事前チェック' do
707       before do
708         #すべての処理が正常パターンで通過すれば、一番深い分岐まで通る。
709         #それで外部のメソッド呼び出しだけに着目してテストする。
710         OriginalPicture.any_instance.stub(:save).with(any_args).and_return(true)
711         PictureIO.original_picture_io.stub(:put).with(any_args).and_return(true)
712       end
713       it '自身に属性をセットしている' do
714         OriginalPicture.any_instance.should_receive(:attributes=).exactly(1)
715         @op.store @imager
716       end
717       it '自身が保存されている' do
718         OriginalPicture.any_instance.should_receive(:save).exactly(1)
719         @op.store @imager
720       end
721       it 'PictureIoに画像データの保存を依頼している' do
722         PictureIO.original_picture_io.should_receive(:put).with(any_args).exactly(1)
723         @op.store @imager
724       end
725     end
726     context 'つつがなく終わるとき' do
727       before do
728       end
729       it '自身に属性をセットしている' do
730         @op.store @imager
731         @op.width.should eq 3
732         @op.height.should eq 3
733         @op.filesize.should eq 9
734       end
735       it '原画モデルが作成されている' do
736         lambda {
737           @op.store @imager
738         }.should change OriginalPicture, :count
739       end
740       it '原画が保存されている' do
741         @op.store @imager
742         OriginalPicture.find(@op).should_not be_nil
743       end
744       it 'Trueを返す' do
745         @op.store(@imager).should eq true
746       end
747     end
748     #以下から例外ケース。処理先頭から失敗させていく
749     context 'imagerが初期化に失敗したとき' do
750       before do
751       end
752       it 'falseを返す' do
753         @op.store(false).should be_false
754       end
755       it '自身の保存は呼ばれていない' do
756         OriginalPicture.any_instance.should_not_receive(:save)
757         @op.store(false)
758       end
759       it '全体エラーメッセージがセットされている' do
760         lambda {
761           @op.store(false)
762         }.should change(@op.errors[:base], :count)
763       end
764     end
765     context '自身の保存に失敗したとき' do
766       before do
767         OriginalPicture.any_instance.stub(:save).with(any_args).and_return(false)
768       end
769       it 'falseを返す' do
770         @op.store(@imager).should be_false
771       end
772       it '更新されていない' do
773         @op.store(@imager)
774         @op.should be_a_new OriginalPicture
775       end
776       it '原画の保存は呼ばれていない' do
777         PictureIO::LocalPicture.any_instance.should_not_receive(:put)
778       end
779     end
780     context '原画の保存に失敗したとき' do
781       before do
782         OriginalPicture.any_instance.stub(:save).with(any_args).and_return(true)
783         PictureIO.original_picture_io.stub(:put).with(any_args).and_raise(PictureIO::Error)
784       end
785       it 'falseを返す' do
786         @op.store(@imager).should be_false
787       end
788       it '更新されていない' do
789         @op.store(@imager)
790         @op.should be_a_new OriginalPicture
791       end
792       it '全体エラーメッセージがセットされている' do
793         lambda {
794           @op.store(@imager)
795         }.should change(@op.errors[:base], :count)
796       end
797     end
798   end
799   
800   describe '削除に於いて' do
801     before do
802       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
803     end
804     context '事前チェックしておく' do
805       before do
806         OriginalPicture.any_instance.stub(:destroy).and_return(true)
807         ResourcePicture.any_instance.stub(:unpublish).and_return(true)
808         Picture.any_instance.stub(:unpublish).with(any_args).and_return(true)
809         PictureIO.original_picture_io.stub(:delete).with(any_args).and_return(true)
810       end
811       it '原画モデルに削除を依頼している' do
812         OriginalPicture.any_instance.should_receive(:destroy).exactly(1)
813         r = @op.destroy_with_resource_picture
814       end
815       it '保管庫に原画の画像データ削除を依頼している' do
816         PictureIO.original_picture_io.should_receive(:delete).with(@op.filename).exactly(1)
817         r = @op.destroy_with_resource_picture
818       end
819       context '自身にリンクされた素材があるとき' do
820         it '素材モデルに削除を依頼している' do
821           @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :revision => 0
822           @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :license_id => @license.id, :original_picture_id => @op.id, :picture_id => @p.id
823           ResourcePicture.any_instance.should_receive(:unpublish).exactly(1)
824           r = @op.destroy_with_resource_picture
825         end
826       end
827       context '自身にリンクされた素材がないとき' do
828         it '素材モデルに削除を依頼しない' do
829           ResourcePicture.any_instance.should_not_receive(:unpublish)
830           r = @op.destroy_with_resource_picture
831         end
832       end
833       context '自身にリンクされた実素材があるとき' do
834         it 'すべての実素材に墨塗を依頼している' do
835           @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :revision => 0
836           Picture.any_instance.should_receive(:unpublish).with(any_args).exactly(1)
837           r = @op.destroy_with_resource_picture
838         end
839       end
840       context '自身にリンクされた実素材がないとき' do
841         it '実素材に墨塗を依頼しない' do
842           Picture.any_instance.should_not_receive(:unpublish)
843           r = @op.destroy_with_resource_picture
844         end
845       end
846     end
847     context 'つつがなく終わるとき' do
848       before do
849         PictureIO.original_picture_io.stub(:delete).with(any_args).and_return(true)
850         @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :revision => 0
851         @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :license_id => @license.id, :original_picture_id => @op.id, :picture_id => @p.id
852       end
853       it '自身を削除する' do
854         lambda {
855           r = @op.destroy_with_resource_picture
856         }.should change(OriginalPicture, :count).by(-1)
857         lambda {
858           r = OriginalPicture.find @op.id
859         }.should raise_error
860       end
861       it 'Trueを返す' do
862         r = @op.destroy_with_resource_picture
863         r.should be_true
864       end
865     end
866     context '自身の削除に失敗したとき' do
867       before do
868         OriginalPicture.any_instance.stub(:destroy).with(any_args).and_return(false)
869       end
870       it 'Falseを返す' do
871         r = @op.destroy_with_resource_picture
872         r.should be_false
873       end
874       it 'ロールバックしている' do
875         lambda {
876           r = @op.destroy_with_resource_picture
877         }.should_not change(OriginalPicture, :count)
878       end
879     end
880     context '画像の削除に失敗したとき' do
881       before do
882         PictureIO.original_picture_io.stub(:exist?).with(@op.filename).and_return(true)
883         PictureIO.original_picture_io.stub(:delete).with(@op.filename).and_raise(PictureIO::Error)
884       end
885       it 'Falseを返す' do
886         r = @op.destroy_with_resource_picture
887         r.should be_false
888       end
889       it 'ロールバックしている' do
890         lambda {
891           r = @op.destroy_with_resource_picture
892         }.should_not change(OriginalPicture, :count)
893       end
894     end
895     context '素材の削除に失敗とき' do
896       before do
897         @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :revision => 0
898         @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :license_id => @license.id, :original_picture_id => @op.id, :picture_id => @p.id
899         ResourcePicture.any_instance.stub(:unpublish).with(any_args).and_return(false)
900       end
901       it 'Falseを返す' do
902         r = @op.destroy_with_resource_picture
903         r.should be_false
904       end
905       it 'ロールバックしている' do
906         lambda {
907           r = @op.destroy_with_resource_picture
908         }.should_not change(OriginalPicture, :count)
909         lambda {
910           r = @op.destroy_with_resource_picture
911         }.should_not change(ResourcePicture, :count)
912       end
913     end
914     context '実素材の墨塗に失敗とき' do
915       before do
916         @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :revision => 0
917         @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :license_id => @license.id, :original_picture_id => @op.id, :picture_id => @p.id
918         Picture.any_instance.stub(:unpublish).with(any_args).and_return(false)
919       end
920       it 'Falseを返す' do
921         r = @op.destroy_with_resource_picture
922         r.should be_false
923       end
924       it 'ロールバックしている' do
925         lambda {
926           r = @op.destroy_with_resource_picture
927         }.should_not change(OriginalPicture, :count)
928         lambda {
929           r = @op.destroy_with_resource_picture
930         }.should_not change(ResourcePicture, :count)
931       end
932     end
933   end
934   
935   describe 'エクスポートに於いて' do
936     before do
937       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
938       @p = FactoryGirl.create :picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :revision => 0
939       @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :picture_id => @p.id
940       #開始日時以前の原画
941       @old_op = FactoryGirl.create :original_picture, :artist_id => @artist.id, :updated_at => Time.now - 1000
942       #素材がライセンスされていない原画
943       @stopped_op = FactoryGirl.create :original_picture, :artist_id => @artist.id
944       #他人の原画
945       @other_op = FactoryGirl.create :original_picture, :artist_id => @other_artist.id
946       #貸手からの原画排除
947       @outer_artist = FactoryGirl.create :artist_yas, :author_id => nil
948       @outer_op = FactoryGirl.create :original_picture, :artist_id => @outer_artist.id
949     end
950     context 'つつがなく終わるとき' do
951       it '開始日時が省略された場合はすべての内原画を返す' do
952         r = OriginalPicture.export 
953         r.should eq [@op, @old_op, @stopped_op, @other_op]
954       end
955       it '開始日時以降に更新された内原画を返す' do
956         r = OriginalPicture.export @op.updated_at - 100
957         r.should eq [@op, @stopped_op, @other_op]
958       end
959       it '素材を含んでいる' do
960         r = OriginalPicture.export 
961         r.first.resource_picture.should_not be_nil
962       end
963       #素材がライセンスされていないケースもある
964       it '停止中の原画は素材を含んでいない' do
965         r = OriginalPicture.export
966         r[2].resource_picture.should be_nil
967       end
968     end
969   end
970   
971   describe 'リストのjson化に於いて' do
972     before do
973       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
974       @p = FactoryGirl.create :picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :revision => 0
975       @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :picture_id => @p.id
976       @other_op = FactoryGirl.create :original_picture, :artist_id => @other_artist.id
977       @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
978       @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
979       ResourcePicture.any_instance.stub(:restore).with(any_args).and_return('picture binary data')
980     end
981     context 'つつがなく終わるとき' do
982       it 'json文字列を返す' do
983         r = OriginalPicture.list_as_json_text OriginalPicture.all 
984         lambda {
985           j = JSON.parse r
986         }.should_not raise_error(JSON::ParserError)
987       end
988       it '原画リストを返す' do
989         r = OriginalPicture.list_as_json_text OriginalPicture.all 
990         j = JSON.parse r
991         j.size.should eq 2
992       end
993       it '素材を含んでいる' do
994         r = OriginalPicture.list_as_json_text OriginalPicture.all 
995         j = JSON.parse r
996         j.first['resource_picture'].should_not be_nil
997       end
998       it '各素材に画像データを添えて返す' do
999         r = OriginalPicture.list_as_json_text OriginalPicture.all 
1000         j = JSON.parse r
1001         j.first['resource_picture']['picture_data'].should_not be_nil
1002         j.last['resource_picture']['picture_data'].should_not be_nil
1003       end
1004     end
1005   end
1006   
1007   describe 'インポートに於いて' do
1008     before do
1009       @imports = {:licenses => {}, :artist_id => @artist.id}
1010     end
1011     context '事前チェックしておく' do
1012     end
1013   end
1014   
1015 end