OSDN Git Service

t#2334:add gc offset
[pettanr/pettanr.git] / spec / models / ground_color_spec.rb
1 # -*- encoding: utf-8 -*-
2 require 'spec_helper'
3 #色地
4
5 describe GroundColor do
6   before do
7     SpeechBalloonTemplate.delete_all
8     @admin = FactoryGirl.create :admin
9     @user = FactoryGirl.create( :user_yas)
10     @author = FactoryGirl.create :author, :user_id => @user.id
11     @artist = FactoryGirl.create :artist_yas, :author_id => @author.id
12     @other_user = FactoryGirl.create( :user_yas)
13     @other_author = FactoryGirl.create :author, :user_id => @other_user.id
14     @other_artist = FactoryGirl.create :artist_yas, :author_id => @other_author.id
15     @sp = FactoryGirl.create :system_picture
16     @lg = FactoryGirl.create :license_group
17     @license = FactoryGirl.create :license, :license_group_id => @lg.id, :system_picture_id => @sp.id
18     @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
19     @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id
20     @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :license_id => @license.id, :original_picture_id => @op.id, :picture_id => @p.id
21     @panel = FactoryGirl.create :panel, :author_id => @author.id
22   end
23   
24   describe '検証に於いて' do
25     before do
26       @gc = FactoryGirl.build :ground_color, :panel_id => @panel.id
27     end
28     
29     context 'オーソドックスなデータのとき' do
30       it '下限データが通る' do
31         @gc.code = 0
32         @gc.orientation = 0
33         @gc.xy = 0
34         @gc.wh = 0
35         @gc.z = 1
36         @gc.t = 0
37         @gc.should be_valid
38       end
39       it '上限データが通る' do
40         @gc.code = 99999
41         @gc.orientation = 1
42         @gc.xy = 100
43         @gc.wh = 100
44         @gc.z = 99999
45         @gc.t = 99999
46         @gc.should be_valid
47       end
48     end
49     
50     context 'panel_idを検証するとき' do
51       #ネストの保存はnilを許可しなければならないので数値チェックだけ
52       it '数値でなければ失敗する' do
53         @gc.panel_id = 'a'
54         @gc.should_not be_valid
55       end
56     end
57     context 'codeを検証するとき' do
58       it 'テストデータの確認' do
59         @gc.code = 0xffffff
60         @gc.should be_valid
61       end
62       it 'nullなら失敗する' do
63         @gc.code = nil
64         @gc.should_not be_valid
65       end
66       it '数値でなければ失敗する' do
67         @gc.code = 'a'
68         @gc.should_not be_valid
69       end
70       it '負なら失敗する' do
71         @gc.code = -1
72         @gc.should_not be_valid
73       end
74       it '24bit colorでなければ失敗する' do
75         @gc.code = 0x1000000
76         @gc.should_not be_valid
77       end
78     end
79     context 'orientationを検証するとき' do
80       it 'nullなら失敗する' do
81         @gc.orientation = nil
82         @gc.should_not be_valid
83       end
84       it '数値でなければ失敗する' do
85         @gc.orientation = 'a'
86         @gc.should_not be_valid
87       end
88       it '負なら失敗する' do
89         @gc.orientation = -1
90         @gc.should_not be_valid
91       end
92       it '2以上なら失敗する' do
93         @gc.orientation = 2
94         @gc.should_not be_valid
95       end
96     end
97     context 'xyを検証するとき' do
98       it 'nullでも通る' do
99         @gc.xy = nil
100         @gc.should be_valid
101       end
102       it '数値でなければ失敗する' do
103         @gc.xy = 'a'
104         @gc.should_not be_valid
105       end
106       it '負なら失敗する' do
107         @gc.xy = -1
108         @gc.should_not be_valid
109       end
110     end
111     context 'whを検証するとき' do
112       it 'nullでも通る' do
113         @gc.wh = nil
114         @gc.should be_valid
115       end
116       it '数値でなければ失敗する' do
117         @gc.wh = 'a'
118         @gc.should_not be_valid
119       end
120       it '負なら失敗する' do
121         @gc.wh = -1
122         @gc.should_not be_valid
123       end
124     end
125     context 'zを検証するとき' do
126       it 'nullなら失敗する' do
127         @gc.z = nil
128         @gc.should_not be_valid
129       end
130       it '数値でなければ失敗する' do
131         @gc.z = 'a'
132         @gc.should_not be_valid
133       end
134       it '負なら失敗する' do
135         @gc.z = -1
136         @gc.should_not be_valid
137       end
138       it '0なら失敗する' do
139         @gc.z = 0
140         @gc.should_not be_valid
141       end
142     end
143     context 'tを検証するとき' do
144       it 'nullなら失敗する' do
145         @gc.t = nil
146         @gc.should_not be_valid
147       end
148       it '数値でなければ失敗する' do
149         @gc.t = 'a'
150         @gc.should_not be_valid
151       end
152       it '負なら失敗する' do
153         @gc.t = -1
154         @gc.should_not be_valid
155       end
156     end
157   end
158   
159   describe '文字コード検証に於いて' do
160     before do
161       @gc = FactoryGirl.build :ground_color, :panel_id => @panel.id
162     end
163     
164     context 'captionを検証するとき' do
165       it 'Shift JISなら失敗する' do
166         @gc.caption = "\x83G\x83r\x83]\x83D"
167         lambda{
168           @gc.valid_encode
169         }.should raise_error(Pettanr::BadRequest)
170       end
171     end
172   end
173   
174   describe 'デフォルト値補充に於いて' do
175     it 'defined' do
176       @gc = FactoryGirl.build :ground_color, :panel_id => @panel.id
177       @gc.supply_default
178     end
179   end
180   
181   describe '上書き補充に於いて' do
182     it 'panel_idが設定されている' do
183       @gc = FactoryGirl.build :ground_color, :panel_id => @panel.id
184       @gc.overwrite  @panel.id
185       @gc.panel_id.should eq @panel.id
186     end
187   end
188   
189   describe '閲覧許可に於いて' do
190     before do
191       @gc = FactoryGirl.create :ground_color, :panel_id => @panel.id
192     end
193     context 'オープンモードのとき' do
194       before do
195         MagicNumber['run_mode'] = 0
196       end
197       it '自身にゲスト用ロールチェックを問い合わせしている' do
198         GroundColor.any_instance.stub(:guest_role_check).and_return(true)
199         GroundColor.any_instance.should_receive(:guest_role_check).with(any_args).exactly(1)
200         r = @gc.visible?([@author])
201       end
202       it 'ゲスト用ロールチェックが失敗したとき、falseを返す' do
203         GroundColor.any_instance.stub(:guest_role_check).and_return(false)
204         r = @gc.visible?([@author])
205         r.should be_false
206       end
207     end
208     context 'クローズドモードのとき' do
209       before do
210         MagicNumber['run_mode'] = 1
211       end
212       it '自身に読者用ロールチェックを問い合わせしている' do
213         GroundColor.any_instance.stub(:reader_role_check).and_return(true)
214         GroundColor.any_instance.should_receive(:reader_role_check).with(any_args).exactly(1)
215         r = @gc.visible?([@author])
216       end
217       it '読者用ロールチェックが失敗したとき、falseを返す' do
218         GroundColor.any_instance.stub(:reader_role_check).and_return(false)
219         r = @gc.visible?([@author])
220         r.should be_false
221       end
222     end
223     context '事前チェックする' do
224       before do
225         MagicNumber['run_mode'] = 1
226         GroundColor.any_instance.stub(:reader_role_check).and_return(true)
227       end
228       it '自身のコマに所持判定を問い合わせしている' do
229         Panel.any_instance.stub(:own?).and_return(true)
230         Panel.any_instance.should_receive(:own?).with(any_args).exactly(1)
231         r = @gc.visible?([@author])
232       end
233       it '自身のコマに閲覧許可を問い合わせしている' do
234         Panel.any_instance.stub(:own?).and_return(false)
235         Panel.any_instance.stub(:visible?).and_return(true)
236         Panel.any_instance.should_receive(:visible?).with(any_args).exactly(1)
237         r = @gc.visible?([@author])
238       end
239     end
240     context 'つつがなく終わるとき' do
241       before do
242         MagicNumber['run_mode'] = 1
243         Panel.any_instance.stub(:reader_role_check).and_return(true)
244       end
245       it '自分のコマの色地なら許可する' do
246         Panel.any_instance.stub(:own?).and_return(true)
247         Panel.any_instance.stub(:visible?).and_return(false)
248         r = @gc.visible?([@author])
249         r.should be_true
250       end
251       it '他人の非公開コマの色地なら許可しない' do
252         Panel.any_instance.stub(:own?).and_return(false)
253         Panel.any_instance.stub(:visible?).and_return(false)
254         r = @gc.visible?([@author])
255         r.should be_false
256       end
257       it '他人のコマの色地でも公開なら許可する' do
258         Panel.any_instance.stub(:own?).and_return(false)
259         Panel.any_instance.stub(:visible?).and_return(true)
260         r = @gc.visible?([@author])
261         r.should be_true
262       end
263     end
264   end
265   
266   describe '一覧取得に於いて' do
267     before do
268       @gc = FactoryGirl.create :ground_color, :panel_id => @panel.id
269     end
270     context 'page補正について' do
271       it '文字列から数値に変換される' do
272         GroundColor.page('8').should eq 8
273       end
274       it 'nilの場合は1になる' do
275         GroundColor.page().should eq 1
276       end
277       it '0以下の場合は1になる' do
278         GroundColor.page('0').should eq 1
279       end
280     end
281     context 'page_size補正について' do
282       it '文字列から数値に変換される' do
283         GroundColor.page_size('7').should eq 7
284       end
285       it 'nilの場合はGroundColor.default_page_sizeになる' do
286         GroundColor.page_size().should eq GroundColor.default_page_size
287       end
288       it '0以下の場合はGroundColor.default_page_sizeになる' do
289         GroundColor.page_size('0').should eq GroundColor.default_page_size
290       end
291       it 'GroundColor.max_page_sizeを超えた場合はGroundColor.max_page_sizeになる' do
292         GroundColor.page_size('1000').should eq GroundColor.max_page_size
293       end
294     end
295     context 'つつがなく終わるとき' do
296       it '一覧取得オプションを利用している' do
297         GroundColor.stub(:list_opt).with(any_args).and_return({:include => :panel})
298         GroundColor.should_receive(:list_opt).with(any_args).exactly(1)
299         r = GroundColor.list
300       end
301     end
302     it 'リストを返す' do
303       pl = GroundColor.list
304       pl.should eq [@gc]
305     end
306     it '時系列で並んでいる' do
307       #公開コマなら(他人のコマであっても)含んでいる
308       opl = FactoryGirl.create :panel, :author_id => @other_author.id, :publish => 1
309       npl = FactoryGirl.create :ground_color, :panel_id => opl.id, :updated_at => Time.now + 100
310       pl = GroundColor.list
311       pl.should eq [npl, @gc]
312     end
313     it '非公開のコマの色地は含まない' do
314       hpl = FactoryGirl.create :panel, :author_id => @author.id, :publish => 0
315       npl = FactoryGirl.create :ground_color, :panel_id => hpl.id, :updated_at => Time.now + 100
316       pl = GroundColor.list
317       pl.should eq [@gc]
318     end
319     context 'DBに5件あって1ページの件数を2件に変えたとして' do
320       before do
321         @gc2 = FactoryGirl.create :ground_color, :panel_id => @panel.id, :z => 1, :updated_at => Time.now + 100
322         @gc3 = FactoryGirl.create :ground_color, :panel_id => @panel.id, :z => 2, :updated_at => Time.now + 200
323         @gc4 = FactoryGirl.create :ground_color, :panel_id => @panel.id, :z => 3, :updated_at => Time.now + 300
324         @gc5 = FactoryGirl.create :ground_color, :panel_id => @panel.id, :z => 4, :updated_at => Time.now + 400
325         GroundColor.stub(:default_page_size).and_return(2)
326       end
327       it '通常は2件を返す' do
328         pl = GroundColor.list
329         pl.should have(2).items 
330       end
331       it 'page=1なら末尾2件を返す' do
332         #時系列で並んでいる
333         pl = GroundColor.list(1)
334         pl.should eq [@gc5, @gc4]
335       end
336       it 'page=2なら中間2件を返す' do
337         pl = GroundColor.list(2)
338         pl.should eq [@gc3, @gc2]
339       end
340       it 'page=3なら先頭1件を返す' do
341         pl = GroundColor.list(3)
342         pl.should eq [@gc]
343       end
344     end
345   end
346   
347   describe '自分のコマで使った色地一覧取得に於いて' do
348     before do
349       @gc = FactoryGirl.create :ground_color, :panel_id => @panel.id
350     end
351     context 'つつがなく終わるとき' do
352       it '一覧取得オプションを利用している' do
353         GroundColor.stub(:list_opt).with(any_args).and_return({:include => :panel})
354         GroundColor.should_receive(:list_opt).with(any_args).exactly(1)
355         r = GroundColor.mylist @author
356       end
357     end
358     it 'リストを返す' do
359       pl = GroundColor.mylist @author
360       pl.should eq [@gc]
361     end
362     it '時系列で並んでいる' do
363       npl = FactoryGirl.create :ground_color, :panel_id => @panel.id, :z => 2, :updated_at => Time.now + 100
364       pl = GroundColor.mylist @author
365       pl.should eq [npl, @gc]
366     end
367     it '他人のコマの色地は公開でも含まない' do
368       hpl = FactoryGirl.create :panel, :author_id => @other_author.id, :publish => 1
369       npl = FactoryGirl.create :ground_color, :panel_id => hpl.id
370       pl = GroundColor.mylist @author
371       pl.should eq [@gc]
372     end
373     it '自分のコマの色地は非公開でも含んでいる' do
374       hpl = FactoryGirl.create :panel, :author_id => @author.id, :publish => 0
375       npl = FactoryGirl.create :ground_color, :panel_id => hpl.id, :z => 2, :updated_at => Time.now + 100
376       pl = GroundColor.mylist @author
377       pl.should eq [npl, @gc]
378     end
379     context 'DBに5件あって1ページの件数を2件に変えたとして' do
380       before do
381         @gc2 = FactoryGirl.create :ground_color, :panel_id => @panel.id, :z => 1, :updated_at => Time.now + 100
382         @gc3 = FactoryGirl.create :ground_color, :panel_id => @panel.id, :z => 2, :updated_at => Time.now + 200
383         @gc4 = FactoryGirl.create :ground_color, :panel_id => @panel.id, :z => 3, :updated_at => Time.now + 300
384         @gc5 = FactoryGirl.create :ground_color, :panel_id => @panel.id, :z => 4, :updated_at => Time.now + 400
385       end
386       it '通常は2件を返す' do
387         c = GroundColor.mylist @author, 1, 2
388         c.should have(2).items 
389       end
390       it 'page=1なら末尾2件を返す' do
391         #時系列で並んでいる
392         c = GroundColor.mylist(@author, 1, 2)
393         c.should eq [@gc5, @gc4]
394       end
395       it 'page=2なら中間2件を返す' do
396         c = GroundColor.mylist(@author, 2, 2)
397         c.should eq [@gc3, @gc2]
398       end
399       it 'page=3なら先頭1件を返す' do
400         c = GroundColor.mylist(@author, 3, 2)
401         c.should eq [@gc]
402       end
403     end
404   end
405   
406   describe '他作家の色地一覧取得に於いて' do
407     before do
408       @gc = FactoryGirl.create :ground_color, :panel_id => @panel.id
409       @other_panel = FactoryGirl.create :panel, :author_id => @other_author.id, :publish => 1
410       @other_gc = FactoryGirl.create :ground_color, :panel_id => @other_panel.id
411     end
412     it 'リストを返す' do
413       r = GroundColor.himlist @other_author
414       r.should eq [@other_gc]
415     end
416     it '時系列で並んでいる' do
417       new_panel = FactoryGirl.create :panel, :author_id => @other_author.id, :updated_at => Time.now + 100
418       new_gc = FactoryGirl.create :ground_color, :panel_id => @other_panel.id, :updated_at => Time.now + 100
419       r = GroundColor.himlist @other_author
420       r.should eq [new_gc, @other_gc]
421     end
422     it '公開コマに限る' do
423       hidden_panel = FactoryGirl.create :panel, :author_id => @other_author.id, :publish => 0
424       hidden_gc = FactoryGirl.create :ground_color, :panel_id => hidden_panel.id
425       r = GroundColor.himlist @other_author
426       r.should eq [@other_gc]
427     end
428     context 'DBに5件あって1ページの件数を2件に変えたとして' do
429       before do
430         @other_gc2 = FactoryGirl.create :ground_color, :panel_id => @other_panel.id, :updated_at => Time.now + 100
431         @other_gc3 = FactoryGirl.create :ground_color, :panel_id => @other_panel.id, :updated_at => Time.now + 200
432         @other_gc4 = FactoryGirl.create :ground_color, :panel_id => @other_panel.id, :updated_at => Time.now + 300
433         @other_gc5 = FactoryGirl.create :ground_color, :panel_id => @other_panel.id, :updated_at => Time.now + 400
434       end
435       it '通常は2件を返す' do
436         pl = GroundColor.himlist @other_author, 1, 2
437         pl.should have(2).items 
438       end
439       it 'page=1なら末尾2件を返す' do
440         #時系列で並んでいる
441         pl = GroundColor.himlist @other_author, 1, 2
442         pl.should eq [@other_gc5, @other_gc4]
443       end
444       it 'page=2なら中間2件を返す' do
445         pl = GroundColor.himlist @other_author, 2, 2
446         pl.should eq [@other_gc3, @other_gc2]
447       end
448       it 'page=3なら先頭1件を返す' do
449         pl = GroundColor.himlist @other_author, 3, 2
450         pl.should eq [@other_gc]
451       end
452     end
453   end
454   
455   describe '色地一覧ページ制御に於いて' do
456     before do
457       GroundColor.stub(:count).with(any_args).and_return(100)
458     end
459     it 'ページ制御を返す' do
460       r = GroundColor.list_paginate 
461       r.is_a?(Kaminari::PaginatableArray).should be_true
462     end
463     it '色地一覧の取得条件を利用している' do
464       GroundColor.stub(:list_where).with(any_args).and_return('')
465       GroundColor.should_receive(:list_where).with(any_args).exactly(1)
466       r = GroundColor.list_paginate 
467     end
468     it 'ページ件数10のとき、3ページ目のオフセットは20から始まる' do
469       r = GroundColor.list_paginate 3, 10
470       r.limit_value.should eq 10
471       r.offset_value.should eq 20
472     end
473   end
474   
475   describe '自分の色地一覧ページ制御に於いて' do
476     before do
477       GroundColor.stub(:count).with(any_args).and_return(100)
478     end
479     it 'ページ制御を返す' do
480       r = GroundColor.mylist_paginate @author
481       r.is_a?(Kaminari::PaginatableArray).should be_true
482     end
483     it '自分の色地一覧の取得条件を利用している' do
484       GroundColor.stub(:mylist_where).with(any_args).and_return('')
485       GroundColor.should_receive(:mylist_where).with(any_args).exactly(1)
486       r = GroundColor.mylist_paginate @author
487     end
488     it 'ページ件数10のとき、3ページ目のオフセットは20から始まる' do
489       r = GroundColor.mylist_paginate @author, 3, 10
490       r.limit_value.should eq 10
491       r.offset_value.should eq 20
492     end
493   end
494   
495   describe '他作家の色地一覧ページ制御に於いて' do
496     before do
497       GroundColor.stub(:count).with(any_args).and_return(100)
498     end
499     it 'ページ制御を返す' do
500       r = GroundColor.himlist_paginate @other_author
501       r.is_a?(Kaminari::PaginatableArray).should be_true
502     end
503     it '他作家の色地一覧の取得条件を利用している' do
504       GroundColor.stub(:himlist_where).with(any_args).and_return('')
505       GroundColor.should_receive(:himlist_where).with(any_args).exactly(1)
506       r = GroundColor.himlist_paginate @other_author
507     end
508     it 'ページ件数10のとき、3ページ目のオフセットは20から始まる' do
509       r = GroundColor.himlist_paginate @other_author, 3, 10
510       r.limit_value.should eq 10
511       r.offset_value.should eq 20
512     end
513   end
514   
515   describe '一覧取得オプションに於いて' do
516     it '1つの項目を含んでいる' do
517       r = GroundColor.list_opt
518       r.should have(1).items
519     end
520     it 'コマを含んでいる' do
521       r = GroundColor.list_opt
522       r.has_key?(:panel).should be_true
523     end
524       it 'コマは作家を含んでいる' do
525         r = GroundColor.list_opt
526         r[:panel].has_key?(:author).should be_true
527       end
528   end
529   describe 'json一覧出力オプションに於いて' do
530     before do
531       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
532       @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id
533       @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :license_id => @license.id, :original_picture_id => @op.id, :picture_id => @p.id
534       @sbt = FactoryGirl.create :speech_balloon_template
535       @scroll = FactoryGirl.create :scroll, :author_id => @author.id, :visible => 1
536       @panel = FactoryGirl.create :panel, :author_id => @author.id, :publish => 1
537       @scroll_panel = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id
538       @gc = FactoryGirl.create :ground_color, :panel_id => @panel.id
539     end
540     it 'コマを含んでいる' do
541       r = GroundColor.list.to_json GroundColor.list_json_opt
542       j = JSON.parse r
543       i = j.first
544       i.has_key?('panel').should be_true
545     end
546       it 'コマは作家を含んでいる' do
547         r = GroundColor.list.to_json GroundColor.list_json_opt
548         j = JSON.parse r
549         i = j.first
550         s = i['panel']
551         s.has_key?('author').should be_true
552       end
553   end
554   
555   describe '単体取得に於いて' do
556     before do
557       @gc = FactoryGirl.create :ground_color, :panel_id => @panel.id
558     end
559     context 'つつがなく終わるとき' do
560       it '単体取得オプションを利用している' do
561         GroundColor.stub(:show_opt).with(any_args).and_return({:include => :panel})
562         GroundColor.should_receive(:show_opt).with(any_args).exactly(1)
563         r = GroundColor.show @gc.id, @author
564       end
565       it '閲覧許可を問い合わせている' do
566         GroundColor.any_instance.stub(:visible?).with(any_args).and_return(true)
567         GroundColor.any_instance.should_receive(:visible?).with(any_args).exactly(1)
568         r = GroundColor.show @gc.id, @author
569       end
570     end
571     it '指定の色地を返す' do
572       GroundColor.any_instance.stub(:visible?).and_return(true)
573       pl = GroundColor.show @gc.id, @author
574       pl.should eq @gc
575     end
576     context '閲覧許可が出なかったとき' do
577       it '403Forbidden例外を返す' do
578         GroundColor.any_instance.stub(:visible?).and_return(false)
579         lambda{
580           GroundColor.show @gc.id, @author
581         }.should raise_error(ActiveRecord::Forbidden)
582       end
583     end
584     context '存在しない色地を開こうとしたとき' do
585       it '404RecordNotFound例外を返す' do
586         lambda{
587           GroundColor.show 110, @author
588         }.should raise_error(ActiveRecord::RecordNotFound)
589       end
590     end
591   end
592   describe '単体取得オプションに於いて' do
593     it 'includeキーを含んでいる' do
594       r = GroundColor.show_opt
595       r.has_key?(:include).should be_true
596     end
597     it '1つの項目を含んでいる' do
598       r = GroundColor.show_opt[:include]
599       r.should have(1).items
600     end
601     it 'コマを含んでいる' do
602       r = GroundColor.show_opt[:include]
603       r.has_key?(:panel).should be_true
604     end
605       it 'コマは作家を含んでいる' do
606         r = GroundColor.show_opt[:include]
607         r[:panel].has_key?(:author).should be_true
608       end
609   end
610   describe 'json単体出力オプションに於いて' do
611     before do
612       @gc = FactoryGirl.create :ground_color, :panel_id => @panel.id
613     end
614     it 'コマを含んでいる' do
615       r = GroundColor.show(@gc.id, @author).to_json GroundColor.show_json_opt
616       j = JSON.parse r
617       i = j
618       i.has_key?('panel').should be_true
619     end
620       it 'コマは作家を含んでいる' do
621         r = GroundColor.show(@gc.id, @author).to_json GroundColor.show_json_opt
622         j = JSON.parse r
623         i = j
624         s = i['panel']
625         s.has_key?('author').should be_true
626       end
627   end
628   
629 end