OSDN Git Service

t#31566:add mylist sb
authoryasushiito <yas@pen-chan.jp>
Fri, 14 Jun 2013 02:15:49 +0000 (11:15 +0900)
committeryasushiito <yas@pen-chan.jp>
Fri, 14 Jun 2013 02:15:49 +0000 (11:15 +0900)
20 files changed:
app/controllers/authors_controller.rb
app/controllers/home_controller.rb
app/controllers/speech_balloons_controller.rb
app/models/author.rb
app/models/speech_balloon.rb
app/views/authors/show.html.erb
app/views/authors/speech_balloons.html.erb [new file with mode: 0644]
app/views/home/index.html.erb
app/views/home/speech_balloons.html.erb [new file with mode: 0644]
app/views/speech_balloons/_list_item.html.erb [new file with mode: 0644]
app/views/speech_balloons/_standard.html.erb [new file with mode: 0644]
app/views/speech_balloons/index.html.erb
app/views/top/index.html.erb
config/locales/pettanr.ja.yml
config/routes.rb
spec/controllers/authors_controller_spec.rb
spec/controllers/home_controller_spec.rb
spec/controllers/speech_balloons_controller_spec.rb
spec/models/author_spec.rb
spec/models/speech_balloon_spec.rb

index dbd4778..4773984 100644 (file)
@@ -4,7 +4,7 @@ class AuthorsController < ApplicationController
     before_filter :authenticate_user, :only => [:new, :create, :edit, :update]
     before_filter :authenticate_author, :only => [:edit, :update]
   else
-    before_filter :authenticate_reader, :only => [:index, :show, :comics, :stories, :panels, :panel_pictures, :ground_pictures, :ground_colors, :panel_colors]
+    before_filter :authenticate_reader, :only => [:index, :show, :comics, :stories, :panels, :panel_pictures, :speech_balloons, :ground_pictures, :ground_colors]
     before_filter :authenticate_user, :only => [:new, :create, :edit, :update]
     before_filter :authenticate_author, :only => [:edit, :update]
   end
@@ -92,6 +92,21 @@ class AuthorsController < ApplicationController
     end
   end
   
+  def speech_balloons
+    @au = Author.show(params[:id], [@user, @admin])
+
+    @page = Author.page params[:page]
+    @page_size = Author.panel_picture_page_size params[:page_size]
+    @speech_balloons = SpeechBalloon.himlist(@au, @page, @page_size)
+
+    respond_to do |format|
+      format.html {
+        @paginate = SpeechBalloon.himlist_paginate(@au, @page, @page_size)
+      }
+      format.json { render json: @speech_balloons.to_json(SpeechBalloon.list_json_opt) }
+    end
+  end
+  
   def ground_pictures
     @au = Author.show(params[:id], [@user, @admin])
 
index 1458a2c..8cdaa99 100644 (file)
@@ -2,9 +2,9 @@ class HomeController < ApplicationController
   layout 'test' if MagicNumber['test_layout']
   before_filter :authenticate_user, :only => [
     :index, :show, :profile, :configure, :create_token, :delete_token, 
-    :comics, :stories, :panels, :resource_pictures, :panel_pictures, :panel_colors, :ground_pictures, :ground_colors
+    :comics, :stories, :panels, :resource_pictures, :panel_pictures, :speech_balloons, :ground_pictures, :ground_colors
   ]
-  before_filter :authenticate_author, :only => [:comics, :stories, :panels, :panel_pictures, :panel_colors, :ground_pictures, :ground_colors]
+  before_filter :authenticate_author, :only => [:comics, :stories, :panels, :panel_pictures, :speech_balloons, :ground_pictures, :ground_colors]
   before_filter :authenticate_artist, :only => [:resource_pictures]
   
   def index
@@ -92,6 +92,19 @@ class HomeController < ApplicationController
     end
   end
   
+  def speech_balloons
+    @page = Author.page params[:page]
+    @page_size = Author.speech_balloon_page_size params[:page_size]
+    @speech_balloons = SpeechBalloon.mylist(@author, @page, @page_size)
+
+    respond_to do |format|
+      format.html {
+        @paginate = SpeechBalloon.mylist_paginate(@author, @page, @page_size)
+      }
+      format.json { render json: @speech_balloons.to_json(SpeechBalloon.list_json_opt) }
+    end
+  end
+  
   def ground_pictures
     @page = Author.page params[:page]
     @page_size = Author.ground_picture_page_size params[:page_size]
index c34dd27..048f722 100644 (file)
@@ -16,7 +16,9 @@ class SpeechBalloonsController < ApplicationController
     @speech_balloons = SpeechBalloon.list(@page, @page_size)
 
     respond_to do |format|
-      format.html # index.html.erb
+      format.html {
+        @paginate = SpeechBalloon.list_paginate(@page, @page_size)
+      }
       format.json { render json: @speech_balloons.to_json(SpeechBalloon.list_json_opt) }
     end
   end
index b3f96f6..2afb344 100644 (file)
@@ -176,6 +176,21 @@ class Author < ActiveRecord::Base
     page_size
   end
   
+  def self.default_speech_balloon_page_size
+    25
+  end
+  
+  def self.speech_balloon_max_page_size
+    100
+  end
+  
+  def self.speech_balloon_page_size prm = self.default_speech_balloon_page_size
+    page_size = prm.to_i
+    page_size = self.speech_balloon_max_page_size if page_size > self.speech_balloon_max_page_size
+    page_size = self.default_speech_balloon_page_size if page_size < 1
+    page_size
+  end
+  
   def self.default_ground_picture_page_size
     25
   end
index 4ff7934..b8ae4e6 100644 (file)
@@ -64,16 +64,44 @@ class SpeechBalloon < ActiveRecord::Base
     page_size
   end
   
+  def self.list_where
+    'panels.publish > 0'
+  end
+  
+  def self.mylist_where au
+    ['panels.author_id = ?', au.id]
+  end
+  
+  def self.himlist_where au
+    ['panels.author_id = ? and panels.publish > 0', au.id]
+  end
+  
   def self.list page = 1, page_size = self.default_page_size
-    opt = {}
-    opt.merge!(SpeechBalloon.list_opt)
-    opt.merge!({:limit => page_size, :offset => (page -1) * page_size}) if page_size > 0
-    opt.merge!({:conditions => 'panels.publish > 0', :order => 'speech_balloons.updated_at desc'})
-    SpeechBalloon.find(:all, opt)
+    SpeechBalloon.where(self.list_where()).includes(SpeechBalloon.list_opt).order('speech_balloons.updated_at desc').offset((page -1) * page_size).limit(page_size)
+  end
+  
+  def self.mylist au, page = 1, page_size = Author.default_speech_balloon_page_size
+    SpeechBalloon.where(self.mylist_where(au)).includes(SpeechBalloon.list_opt).order('speech_balloons.updated_at desc').offset((page -1) * page_size).limit(page_size)
+  end
+  
+  def self.himlist au, page = 1, page_size = Author.default_speech_balloon_page_size
+    SpeechBalloon.where(self.himlist_where(au)).includes(SpeechBalloon.list_opt).order('speech_balloons.updated_at desc').offset((page -1) * page_size).limit(page_size)
+  end
+  
+  def self.list_paginate page = 1, page_size = self.default_page_size
+    Kaminari.paginate_array(Array.new(SpeechBalloon.where(self.list_where()).includes(SpeechBalloon.list_opt).count, nil)).page(page).per(page_size)
+  end
+  
+  def self.mylist_paginate au, page = 1, page_size = Author.default_speech_balloon_page_size
+    Kaminari.paginate_array(Array.new(SpeechBalloon.where(self.mylist_where(au)).includes(SpeechBalloon.list_opt).count, nil)).page(page).per(page_size)
+  end
+  
+  def self.himlist_paginate au, page = 1, page_size = Author.default_speech_balloon_page_size
+    Kaminari.paginate_array(Array.new(SpeechBalloon.where(self.himlist_where(au)).includes(SpeechBalloon.list_opt).count, nil)).page(page).per(page_size)
   end
   
   def self.list_opt
-    {:include => {:panel => {:author => {}}, :balloon => {}, :speech => {}, :speech_balloon_template => {} }}
+    {:panel => {:author => {}}, :balloon => {}, :speech => {}, :speech_balloon_template => {} }
   end
   
   def self.list_json_opt
index 47f4c65..aea2597 100644 (file)
 </p>
 
 <p>
+  <%= link_to t('authors.show.to_speech_balloons'), speech_balloons_author_path(@au) %>
+</p>
+
+<p>
   <%= link_to t('authors.show.to_ground_pictures'), ground_pictures_author_path(@au) %>
 </p>
 
diff --git a/app/views/authors/speech_balloons.html.erb b/app/views/authors/speech_balloons.html.erb
new file mode 100644 (file)
index 0000000..796c880
--- /dev/null
@@ -0,0 +1,15 @@
+<h1><%= t '.title' -%></h1>
+
+<table>
+  <tr>
+    <th><%= t_m 'SpeechBalloon.id' -%></th>
+    <th><%= t_m 'SpeechBalloon.caption' -%></th>
+    <th><%= t_m 'SpeechBalloon.z' -%></th>
+    <th><%= t_m 'SpeechBalloon.updated_at' -%></th>
+  </tr>
+
+  <% @speech_balloons.each do |speech_balloon| %>
+    <%= render 'speech_balloons/list_item', :speech_balloon => speech_balloon %>
+  <% end %>
+</table>
+<%= paginate(@paginate) %>
index c599990..c7d8a61 100644 (file)
@@ -24,6 +24,9 @@
       <%= link_to t_m('PanelPicture'), '/home/panel_pictures' %>
     </td>
     <td width="200px" align="center" valign="middle">
+      <%= link_to t_m('SpeechBalloon'), '/home/speech_balloons' %>
+    </td>
+    <td width="200px" align="center" valign="middle">
       <%= link_to t_m('GroundPicture'), '/home/ground_pictures' %>
     </td>
     <td width="200px" align="center" valign="middle">
diff --git a/app/views/home/speech_balloons.html.erb b/app/views/home/speech_balloons.html.erb
new file mode 100644 (file)
index 0000000..796c880
--- /dev/null
@@ -0,0 +1,15 @@
+<h1><%= t '.title' -%></h1>
+
+<table>
+  <tr>
+    <th><%= t_m 'SpeechBalloon.id' -%></th>
+    <th><%= t_m 'SpeechBalloon.caption' -%></th>
+    <th><%= t_m 'SpeechBalloon.z' -%></th>
+    <th><%= t_m 'SpeechBalloon.updated_at' -%></th>
+  </tr>
+
+  <% @speech_balloons.each do |speech_balloon| %>
+    <%= render 'speech_balloons/list_item', :speech_balloon => speech_balloon %>
+  <% end %>
+</table>
+<%= paginate(@paginate) %>
diff --git a/app/views/speech_balloons/_list_item.html.erb b/app/views/speech_balloons/_list_item.html.erb
new file mode 100644 (file)
index 0000000..f964dd3
--- /dev/null
@@ -0,0 +1,20 @@
+<tr>
+  <td>
+    <%= link_to(h(speech_balloon.id.to_s), speech_balloon_path(speech_balloon)) %>
+  </td>
+  <td>
+    <%= link_to(h(truncate(speech_balloon.caption, :length => 12)), speech_balloon_path(speech_balloon)) %>
+  </td>
+  <td>
+    <%= h(truncate(speech_balloon.speech.content, :length => 12)) %>
+  </td>
+  <td>
+    <%= speech_balloon.balloon.system_picture_id %>
+  </td>
+  <td>
+    <%= speech_balloon.z %>
+  </td>
+  <td>
+    <%= distance_of_time_in_words_to_now speech_balloon.updated_at %>
+  </td>
+</tr>
diff --git a/app/views/speech_balloons/_standard.html.erb b/app/views/speech_balloons/_standard.html.erb
new file mode 100644 (file)
index 0000000..35f438f
--- /dev/null
@@ -0,0 +1,6 @@
+<b><%= t_m 'Panel.caption' -%>:</b>
+<%= h(panel.caption) %>
+<%= render 'panels/body', :panel => panel, :author => author, :spot => spot %>
+<%= render 'panels/footer', :panel => panel, :author => author %>
+<%= render 'panels/licensed_pictures', :licensed_pictures => panel.licensed_pictures %>
+
index 52ef612..f216172 100644 (file)
@@ -1,2 +1,15 @@
 <h1><%= t '.title' -%></h1>
 
+<table>
+  <tr>
+    <th><%= t_m 'SpeechBalloon.id' -%></th>
+    <th><%= t_m 'SpeechBalloon.caption' -%></th>
+    <th><%= t_m 'SpeechBalloon.z' -%></th>
+    <th><%= t_m 'SpeechBalloon.updated_at' -%></th>
+  </tr>
+
+  <% @speech_balloons.each do |speech_balloon| %>
+    <%= render 'list_item', :speech_balloon => speech_balloon %>
+  <% end %>
+</table>
+<%= paginate(@paginate) %>
index c907d03..d6f27d6 100644 (file)
@@ -22,6 +22,9 @@
       <%= link_to t_m('PanelPicture'), main_app.panel_pictures_path %>\r
     </td>\r
     <td width="200px" align="center" valign="middle">\r
+      <%= link_to t_m('SpeechBalloon'), main_app.speech_balloons_path %>\r
+    </td>\r
+    <td width="200px" align="center" valign="middle">\r
       <%= link_to t_m('GroundPicture'), main_app.ground_pictures_path %>\r
     </td>\r
     <td width="200px" align="center" valign="middle">\r
index cc406b1..af7535d 100644 (file)
@@ -109,6 +109,7 @@ ja:
         classname: クラス名
         z: 重なり
         t: 話順
+        caption: 様子
         settings: 拡張データ
         created_at: 作成
         updated_at: 更新
@@ -130,7 +131,6 @@ ja:
         width: 幅
         height: 高さ
         r: 角度
-        caption: 様子
         settings: 拡張データ
         created_at: 作成
         updated_at: 更新
@@ -389,6 +389,8 @@ ja:
       title: 最近更新した素材
     panel_pictures:
       title: 最近使ったコマ絵
+    speech_balloons:
+      title: 最近使ったフキダシ
     ground_pictures:
       title: 最近使った絵地
     ground_colors:
@@ -703,6 +705,7 @@ ja:
       to_stories: 最近更新したストーリー
       to_panels: 最近更新したコマ
       to_panel_pictures: 最近コマで使ったコマ絵
+      to_speech_balloons: 最近更新したフキダシ
       to_ground_pictures: 最近コマで使った絵地
       to_ground_colors: 最近コマで使った色地
     comics:
@@ -713,6 +716,8 @@ ja:
       title: 最近更新したコマ
     panel_pictures:
       title: 最近更新したコマ絵
+    speech_balloons:
+      title: 最近更新したフキダシ
     ground_pictures:
       title: 最近更新した絵地
     ground_colors:
index 3c949d9..1f452aa 100644 (file)
@@ -28,9 +28,9 @@ Pettanr::Application.routes.draw do
       get :stories
       get :panels
       get :panel_pictures
+      get :speech_balloons
       get :ground_pictures
       get :ground_colors
-      get :panel_colors
     end
   end
   resources :artists do
index a1dabb8..87587c2 100644 (file)
@@ -8,6 +8,7 @@ describe AuthorsController do
     @sp = FactoryGirl.create :system_picture
     @lg = FactoryGirl.create :license_group
     @license = FactoryGirl.create :license, :license_group_id => @lg.id, :system_picture_id => @sp.id
+    @speech_balloon_template = FactoryGirl.create :speech_balloon_template
     @user = FactoryGirl.create( :user_yas)
     @author = FactoryGirl.create :author, :user_id => @user.id
     @artist = FactoryGirl.create :artist_yas, :author_id => @author.id
@@ -773,6 +774,139 @@ if MagicNumber['run_mode'] == 1
     end
   end
   
+  describe '対象作家のフキダシ一覧表示に於いて' do
+    before do
+      @other_user = FactoryGirl.create( :user_yas)
+      @other_author = FactoryGirl.create :author, :user_id => @other_user.id
+      @other_artist = FactoryGirl.create :artist_yas, :author_id => @other_author.id
+      @panel = FactoryGirl.create :panel, :author_id => @other_author.id
+      @sb = FactoryGirl.create :speech_balloon, :panel_id => @panel.id, :speech_balloon_template_id => @speech_balloon_template.id
+      Author.stub(:show).and_return(@other_author)
+      SpeechBalloon.stub(:himlist).and_return([@sb, @sb, @sb])
+      sign_in @user
+    end
+    context 'パラメータpageについて' do
+      it '@pageに値が入る' do
+        get :speech_balloons, :id => @other_author.id, :page => 5
+        assigns(:page).should eq 5
+      end
+      it '省略されると@pageに1値が入る' do
+        get :speech_balloons, :id => @other_author.id
+        assigns(:page).should eq 1
+      end
+      it '与えられたpage_sizeがセットされている' do
+        get :speech_balloons, :id => @other_author.id, :page_size => 15
+        assigns(:page_size).should eq 15
+      end
+      it '省略されると@page_sizeにデフォルト値が入る' do
+        get :speech_balloons, :id => @other_author.id
+        assigns(:page_size).should eq Author.default_speech_balloon_page_size
+      end
+      it '最大を超えると@page_sizeにデフォルト最大値が入る' do
+        get :speech_balloons, :id => @other_author.id, :page_size => 1500
+        assigns(:page_size).should eq Author.speech_balloon_max_page_size
+      end
+      it '不正な値が入ると@page_sizeにデフォルト最大値が入る' do
+        get :speech_balloons, :id => @other_author.id, :page_size => 0
+        assigns(:page_size).should eq Author.default_speech_balloon_page_size
+      end
+    end
+    context 'つつがなく終わるとき' do
+      it 'ステータスコード200 OKを返す' do
+        get :speech_balloons, :id => @other_author.id
+        response.should be_success 
+      end
+      it '作家モデルに単体取得を問い合わせている' do
+        Author.should_receive(:show).exactly(1)
+        get :speech_balloons, :id => @other_author.id
+      end
+      it 'フキダシモデルに他作家のフキダシ一覧を問い合わせている' do
+        SpeechBalloon.should_receive(:himlist).exactly(1)
+        get :speech_balloons, :id => @other_author.id
+      end
+      it '@speech_balloonsにリストを取得している' do
+        get :speech_balloons, :id => @other_author.id
+        assigns(:speech_balloons).should have_at_least(3).items
+      end
+      context 'html形式' do
+        it '@paginateにページ制御を取得している' do
+          get :speech_balloons, :id => @other_author.id
+          assigns(:paginate).is_a?(Kaminari::PaginatableArray).should be_true
+        end
+        it 'speech_balloonsテンプレートを描画する' do
+          get :speech_balloons, :id => @other_author.id
+          response.should render_template("speech_balloons")
+        end
+      end
+      context 'json形式' do
+        it 'jsonデータを返す' do
+          get :speech_balloons, :id => @other_author.id, :format => :json
+          lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError)
+        end
+        it 'フキダシモデルにjson一覧出力オプションを問い合わせている' do
+          SpeechBalloon.should_receive(:list_json_opt).exactly(1)
+          get :speech_balloons, :id => @other_author.id, :format => :json
+        end
+        it 'データがリスト構造になっている' do
+          get :speech_balloons, :id => @other_author.id, :format => :json
+          json = JSON.parse response.body
+          json.should have_at_least(3).items
+        end
+        it 'リストの先頭くらいはフキダシっぽいものであって欲しい' do
+          get :speech_balloons, :id => @other_author.id, :format => :json
+          json = JSON.parse response.body
+          json.first.has_key?("speech_balloon_template_id").should be_true
+          json.first.has_key?("z").should be_true
+          json.first.has_key?("t").should be_true
+        end
+      end
+    end
+    context 'ユーザ権限がないとき' do
+      before do
+        sign_out @user
+      end
+      context 'html形式' do
+        it 'ステータスコード302 Foundを返す' do
+          get :speech_balloons, :id => @other_author.id
+          response.status.should eq 302
+        end
+        it 'サインインページへ遷移する' do
+          get :speech_balloons, :id => @other_author.id
+          response.should redirect_to '/users/sign_in'
+        end
+      end
+      context 'json形式' do
+        it 'ステータスコード401 Unauthorizedを返す' do
+          get :speech_balloons, :id => @other_author.id, :format => :json
+          response.status.should eq 401
+        end
+        it '応答メッセージにUnauthorizedを返す' do
+          get :speech_balloons, :id => @other_author.id, :format => :json
+          response.message.should match(/Unauthorized/)
+        end
+      end
+    end
+    context 'ユーザ権限はないが管理者権限があるとき' do
+      before do
+        sign_out @user
+        sign_in @admin
+      end
+      it 'ステータスコード200 OKを返す' do
+        get :speech_balloons, :id => @other_author.id
+        response.should be_success 
+      end
+    end
+    context 'ユーザだが作家登録していないとき' do
+      before do
+        @author.destroy
+      end
+      it 'ステータスコード200 OKを返す' do
+        get :speech_balloons, :id => @other_author.id
+        response.should be_success 
+      end
+    end
+  end
+  
   describe '対象作家の絵地一覧表示に於いて' do
     before do
       @other_user = FactoryGirl.create( :user_yas)
index cf5c3a1..85cac71 100644 (file)
@@ -8,6 +8,7 @@ describe HomeController do
     @sp = FactoryGirl.create :system_picture
     @lg = FactoryGirl.create :license_group
     @license = FactoryGirl.create :license, :license_group_id => @lg.id, :system_picture_id => @sp.id
+    @speech_balloon_template = FactoryGirl.create :speech_balloon_template
     @user = FactoryGirl.create( :user_yas)
     @author = FactoryGirl.create :author, :user_id => @user.id
     @artist = FactoryGirl.create :artist_yas, :author_id => @author.id
@@ -334,6 +335,112 @@ if MagicNumber['run_mode'] == 1
     end
   end
   
+  describe '自分のフキダシ一覧表示に於いて' do
+    before do
+      @sb = FactoryGirl.create :speech_balloon, :panel_id => @panel.id, :speech_balloon_template_id => @speech_balloon_template.id
+      @balloon = FactoryGirl.create :balloon, :speech_balloon_id => @sb.id, :system_picture_id => @sp.id
+      @speech = FactoryGirl.create :speech, :speech_balloon_id => @sb.id
+      sign_in @user
+      SpeechBalloon.stub(:mylist).and_return([@sb, @sb, @sb])
+    end
+    context 'パラメータpageについて' do
+      it '@pageに値が入る' do
+        get :speech_balloons, :page => 5
+        assigns(:page).should eq 5
+      end
+      it '省略されると@pageに1値が入る' do
+        get :speech_balloons
+        assigns(:page).should eq 1
+      end
+      it '与えられたpage_sizeがセットされている' do
+        get :speech_balloons, :page_size => 15
+        assigns(:page_size).should eq 15
+      end
+      it '省略されると@page_sizeにデフォルト値が入る' do
+        get :speech_balloons
+        assigns(:page_size).should eq Author.default_speech_balloon_page_size
+      end
+      it '最大を超えると@page_sizeにデフォルト最大値が入る' do
+        get :speech_balloons, :page_size => 1500
+        assigns(:page_size).should eq Author.speech_balloon_max_page_size
+      end
+      it '不正な値が入ると@page_sizeにデフォルト最大値が入る' do
+        get :speech_balloons, :page_size => 0
+        assigns(:page_size).should eq Author.default_speech_balloon_page_size
+      end
+    end
+    context 'つつがなく終わるとき' do
+      it 'ステータスコード200 OKを返す' do
+        response.should be_success 
+      end
+      it 'フキダシモデルに一覧を問い合わせている' do
+        SpeechBalloon.should_receive(:mylist).exactly(1)
+        get :speech_balloons
+      end
+      it '@speech_balloonsにリストを取得している' do
+        get :speech_balloons
+        assigns(:speech_balloons).should have_at_least(3).items
+      end
+      context 'html形式' do
+        it '@paginateにページ制御を取得している' do
+          get :speech_balloons
+          assigns(:paginate).is_a?(Kaminari::PaginatableArray).should be_true
+        end
+        it 'speech_balloonsテンプレートを描画する' do
+          get :speech_balloons
+          response.should render_template("speech_balloons")
+        end
+      end
+      context 'json形式' do
+        it 'jsonデータを返す' do
+          get :speech_balloons, :format => :json
+          lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError)
+        end
+        it 'フキダシモデルにjson一覧出力オプションを問い合わせている' do
+          SpeechBalloon.should_receive(:list_json_opt).exactly(1)
+          get :speech_balloons, :format => :json
+        end
+        it 'データがリスト構造になっている' do
+          get :speech_balloons, :format => :json
+          json = JSON.parse response.body
+          json.should have_at_least(3).items
+        end
+        it 'リストの先頭くらいはフキダシっぽいものであって欲しい' do
+          get :speech_balloons, :format => :json
+          json = JSON.parse response.body
+          json.first.has_key?("speech_balloon_template_id").should be_true
+          json.first.has_key?("z").should be_true
+          json.first.has_key?("t").should be_true
+        end
+      end
+    end
+    context '作家権限がないとき' do
+      before do
+        sign_out @user
+      end
+      context 'html形式' do
+        it 'ステータスコード302 Foundを返す' do
+          get :speech_balloons
+          response.status.should eq 302
+        end
+        it 'サインインページへ遷移する' do
+          get :speech_balloons
+          response.should redirect_to '/users/sign_in'
+        end
+      end
+      context 'json形式' do
+        it 'ステータスコード401 Unauthorizedを返す' do
+          get :speech_balloons, :format => :json
+          response.status.should eq 401
+        end
+        it '応答メッセージにUnauthorizedを返す' do
+          get :speech_balloons, :format => :json
+          response.message.should match(/Unauthorized/)
+        end
+      end
+    end
+  end
+  
   describe '自分のコマの絵地一覧表示に於いて' do
     before do
       @gp = FactoryGirl.create :ground_picture, :panel_id => @panel.id, :picture_id => @p.id
index 3c555a0..f204513 100644 (file)
@@ -62,6 +62,10 @@ if MagicNumber['run_mode'] == 1
         assigns(:speech_balloons).should have_at_least(3).items
       end
       context 'html形式' do
+        it '@paginateにページ制御を取得している' do
+          get :index
+          assigns(:paginate).is_a?(Kaminari::PaginatableArray).should be_true
+        end
         it 'indexテンプレートを描画する' do
           get :index
           response.should render_template("index")
index 1504797..eedb870 100644 (file)
@@ -438,7 +438,7 @@ describe Author do
         Author.story_page_size('1000').should eq Author.story_max_page_size
       end
     end
-    context 'コマpage_size補正について' do
+    context 'コマpage_size補正について' do
       it '文字列から数値に変換される' do
         Author.panel_page_size('7').should eq 7
       end
@@ -452,7 +452,7 @@ describe Author do
         Author.panel_page_size('1000').should eq Author.panel_max_page_size
       end
     end
-    context '景色素材page_size補正について' do
+    context 'コマ素材page_size補正について' do
       it '文字列から数値に変換される' do
         Author.panel_picture_page_size('7').should eq 7
       end
@@ -466,6 +466,20 @@ describe Author do
         Author.panel_picture_page_size('1000').should eq Author.panel_picture_max_page_size
       end
     end
+    context 'フキダシpage_size補正について' do
+      it '文字列から数値に変換される' do
+        Author.speech_balloon_page_size('7').should eq 7
+      end
+      it 'nilの場合はAuthor.default_speech_balloon_page_sizeになる' do
+        Author.speech_balloon_page_size().should eq Author.default_speech_balloon_page_size
+      end
+      it '0以下の場合はAuthor.default_speech_balloon_page_sizeになる' do
+        Author.speech_balloon_page_size('0').should eq Author.default_speech_balloon_page_size
+      end
+      it 'Author.speech_balloon_max_page_sizeを超えた場合はAuthor.speech_balloon_max_page_sizeになる' do
+        Author.speech_balloon_page_size('1000').should eq Author.speech_balloon_max_page_size
+      end
+    end
     context '景色カラーpage_size補正について' do
       it '文字列から数値に変換される' do
         Author.ground_picture_page_size('7').should eq 7
index 618dbd3..650975c 100644 (file)
@@ -280,47 +280,203 @@ describe SpeechBalloon do
         pl.should eq [@sb]
       end
     end
-    context 'DBに5件あって1ページの件数を0件に変えたとして' do
+  end
+  
+  describe '自分のフキダシ一覧取得に於いて' do
+    before do
+      @sb = FactoryGirl.create :speech_balloon, :panel_id => @panel.id, :speech_balloon_template_id => @speech_balloon_template.id
+      @balloon = FactoryGirl.create :balloon, :speech_balloon_id => @sb.id, :system_picture_id => @sp.id
+      @speech = FactoryGirl.create :speech, :speech_balloon_id => @sb.id
+    end
+    context 'つつがなく終わるとき' do
+      it '一覧取得オプションを利用している' do
+        SpeechBalloon.stub(:list_opt).with(any_args).and_return({:include => :panel})
+        SpeechBalloon.should_receive(:list_opt).with(any_args).exactly(1)
+        r = SpeechBalloon.mylist @author
+      end
+    end
+    it 'リストを返す' do
+      pl = SpeechBalloon.mylist @author
+      pl.should eq [@sb]
+    end
+    it '時系列で並んでいる' do
+      npl = FactoryGirl.create :speech_balloon, :panel_id => @panel.id, :t => 1, :speech_balloon_template_id => @speech_balloon_template.id, :updated_at => Time.now + 100
+      pl = SpeechBalloon.mylist @author
+      pl.should eq [npl, @sb]
+    end
+    it '他人のコマのフキダシは公開コマでも含まない' do
+      hpl = FactoryGirl.create :panel, :author_id => @other_author.id, :publish => 1
+      npl = FactoryGirl.create :speech_balloon, :panel_id => hpl.id, :t => 1, :speech_balloon_template_id => @speech_balloon_template.id, :updated_at => Time.now + 100
+      pl = SpeechBalloon.mylist @author
+      pl.should eq [@sb]
+    end
+    it '自分のコマのフキダシは非公開コマでも含んでいる' do
+      pl = FactoryGirl.create :panel, :author_id => @author.id, :publish => 0
+      ni = FactoryGirl.create :speech_balloon, :panel_id => pl.id, :t => 1, :speech_balloon_template_id => @speech_balloon_template.id, :updated_at => Time.now + 100
+      r = SpeechBalloon.mylist @author
+      r.should eq [ni, @sb]
+    end
+    context 'DBに5件あって1ページの件数を2件に変えたとして' do
       before do
-        @sb2 = FactoryGirl.create :speech_balloon, :panel_id => @panel.id, :speech_balloon_template_id => @speech_balloon_template.id, :t => 1, :updated_at => Time.now + 100
-        @sb3 = FactoryGirl.create :speech_balloon, :panel_id => @panel.id, :speech_balloon_template_id => @speech_balloon_template.id, :t => 2, :updated_at => Time.now + 200
-        @sb4 = FactoryGirl.create :speech_balloon, :panel_id => @panel.id, :speech_balloon_template_id => @speech_balloon_template.id, :t => 3, :updated_at => Time.now + 300
-        @sb5 = FactoryGirl.create :speech_balloon, :panel_id => @panel.id, :speech_balloon_template_id => @speech_balloon_template.id, :t => 4, :updated_at => Time.now + 400
-        SpeechBalloon.stub(:default_page_size).and_return(2)
+        @npl2 = FactoryGirl.create :speech_balloon, :panel_id => @panel.id, :t => 1, :speech_balloon_template_id => @speech_balloon_template.id, :updated_at => Time.now + 100
+        @npl3 = FactoryGirl.create :speech_balloon, :panel_id => @panel.id, :t => 2, :speech_balloon_template_id => @speech_balloon_template.id, :updated_at => Time.now + 200
+        @npl4 = FactoryGirl.create :speech_balloon, :panel_id => @panel.id, :t => 3, :speech_balloon_template_id => @speech_balloon_template.id, :updated_at => Time.now + 300
+        @npl5 = FactoryGirl.create :speech_balloon, :panel_id => @panel.id, :t => 4, :speech_balloon_template_id => @speech_balloon_template.id, :updated_at => Time.now + 400
       end
-      it '通常は全件(5件)を返す' do
-        r = SpeechBalloon.list 5, 0
-        r.should have(5).items 
+      it '通常は2件を返す' do
+        r = SpeechBalloon.mylist @author, 1, 2
+        r.should have(2).items 
+      end
+      it 'page=1なら末尾2件を返す' do
+        #時系列で並んでいる
+        r = SpeechBalloon.mylist(@author, 1, 2)
+        r.should eq [@npl5, @npl4]
+      end
+      it 'page=2なら中間2件を返す' do
+        r = SpeechBalloon.mylist(@author, 2, 2)
+        r.should eq [@npl3, @npl2]
+      end
+      it 'page=3なら先頭1件を返す' do
+        r = SpeechBalloon.mylist(@author, 3, 2)
+        r.should eq [@sb]
       end
     end
   end
-  describe '一覧取得オプションに於いて' do
-    it 'includeキーを含んでいる' do
-      r = SpeechBalloon.list_opt
-      r.has_key?(:include).should be_true
+  
+  describe '他作家のフキダシ一覧取得に於いて' do
+    before do
+      @sb = FactoryGirl.create :speech_balloon, :panel_id => @panel.id, :speech_balloon_template_id => @speech_balloon_template.id
+      @balloon = FactoryGirl.create :balloon, :speech_balloon_id => @sb.id, :system_picture_id => @sp.id
+      @speech = FactoryGirl.create :speech, :speech_balloon_id => @sb.id
+      @other_panel = FactoryGirl.create :panel, :author_id => @other_author.id, :publish => 1
+      @other_sb = FactoryGirl.create :speech_balloon, :panel_id => @other_panel.id, :speech_balloon_template_id => @speech_balloon_template.id
+    end
+    it 'リストを返す' do
+      r = SpeechBalloon.himlist @other_author
+      r.should eq [@other_sb]
     end
+    it '時系列で並んでいる' do
+      new_panel = FactoryGirl.create :panel, :author_id => @other_author.id, :updated_at => Time.now + 100
+      new_sb = FactoryGirl.create :speech_balloon, :panel_id => new_panel.id, :speech_balloon_template_id => @speech_balloon_template.id, :updated_at => Time.now + 100
+      r = SpeechBalloon.himlist @other_author
+      r.should eq [new_sb, @other_sb]
+    end
+    it '公開コマに限る' do
+      hidden_panel = FactoryGirl.create :panel, :author_id => @other_author.id, :publish => 0
+      hidden_sb = FactoryGirl.create :speech_balloon, :panel_id => hidden_panel.id, :speech_balloon_template_id => @speech_balloon_template.id
+      r = SpeechBalloon.himlist @other_author
+      r.should eq [@other_sb]
+    end
+    context 'DBに5件あって1ページの件数を2件に変えたとして' do
+      before do
+        @other_sb2 = FactoryGirl.create :speech_balloon, :panel_id => @other_panel.id, :t => 1, :speech_balloon_template_id => @speech_balloon_template.id, :updated_at => Time.now + 100
+        @other_sb3 = FactoryGirl.create :speech_balloon, :panel_id => @other_panel.id, :t => 2, :speech_balloon_template_id => @speech_balloon_template.id, :updated_at => Time.now + 200
+        @other_sb4 = FactoryGirl.create :speech_balloon, :panel_id => @other_panel.id, :t => 3, :speech_balloon_template_id => @speech_balloon_template.id, :updated_at => Time.now + 300
+        @other_sb5 = FactoryGirl.create :speech_balloon, :panel_id => @other_panel.id, :t => 4, :speech_balloon_template_id => @speech_balloon_template.id, :updated_at => Time.now + 400
+      end
+      it '通常は2件を返す' do
+        r = SpeechBalloon.himlist @other_author, 1, 2
+        r.should have(2).items 
+      end
+      it 'page=1なら末尾2件を返す' do
+        #時系列で並んでいる
+        r = SpeechBalloon.himlist @other_author, 1, 2
+        r.should eq [@other_sb5, @other_sb4]
+      end
+      it 'page=2なら中間2件を返す' do
+        r = SpeechBalloon.himlist @other_author, 2, 2
+        r.should eq [@other_sb3, @other_sb2]
+      end
+      it 'page=3なら先頭1件を返す' do
+        r = SpeechBalloon.himlist @other_author, 3, 2
+        r.should eq [@other_sb]
+      end
+    end
+  end
+  
+  describe 'フキダシ一覧ページ制御に於いて' do
+    before do
+      SpeechBalloon.stub(:count).with(any_args).and_return(100)
+    end
+    it 'ページ制御を返す' do
+      r = SpeechBalloon.list_paginate 
+      r.is_a?(Kaminari::PaginatableArray).should be_true
+    end
+    it 'フキダシ一覧の取得条件を利用している' do
+      SpeechBalloon.stub(:list_where).with(any_args).and_return('')
+      SpeechBalloon.should_receive(:list_where).with(any_args).exactly(1)
+      r = SpeechBalloon.list_paginate 
+    end
+    it 'ページ件数10のとき、3ページ目のオフセットは20から始まる' do
+      r = SpeechBalloon.list_paginate 3, 10
+      r.limit_value.should eq 10
+      r.offset_value.should eq 20
+    end
+  end
+  
+  describe '自分のフキダシ一覧ページ制御に於いて' do
+    before do
+      SpeechBalloon.stub(:count).with(any_args).and_return(100)
+    end
+    it 'ページ制御を返す' do
+      r = SpeechBalloon.mylist_paginate @author
+      r.is_a?(Kaminari::PaginatableArray).should be_true
+    end
+    it '自分のフキダシ一覧の取得条件を利用している' do
+      SpeechBalloon.stub(:mylist_where).with(any_args).and_return('')
+      SpeechBalloon.should_receive(:mylist_where).with(any_args).exactly(1)
+      r = SpeechBalloon.mylist_paginate @author
+    end
+    it 'ページ件数10のとき、3ページ目のオフセットは20から始まる' do
+      r = SpeechBalloon.mylist_paginate @author, 3, 10
+      r.limit_value.should eq 10
+      r.offset_value.should eq 20
+    end
+  end
+  
+  describe '他作家のフキダシ一覧ページ制御に於いて' do
+    before do
+      SpeechBalloon.stub(:count).with(any_args).and_return(100)
+    end
+    it 'ページ制御を返す' do
+      r = SpeechBalloon.himlist_paginate @other_author
+      r.is_a?(Kaminari::PaginatableArray).should be_true
+    end
+    it '他作家のフキダシ一覧の取得条件を利用している' do
+      SpeechBalloon.stub(:himlist_where).with(any_args).and_return('')
+      SpeechBalloon.should_receive(:himlist_where).with(any_args).exactly(1)
+      r = SpeechBalloon.himlist_paginate @other_author
+    end
+    it 'ページ件数10のとき、3ページ目のオフセットは20から始まる' do
+      r = SpeechBalloon.himlist_paginate @other_author, 3, 10
+      r.limit_value.should eq 10
+      r.offset_value.should eq 20
+    end
+  end
+  
+  describe '一覧取得オプションに於いて' do
     it '4つの項目を含んでいる' do
-      r = SpeechBalloon.list_opt[:include]
+      r = SpeechBalloon.list_opt
       r.should have(4).items
     end
     it 'コマを含んでいる' do
-      r = SpeechBalloon.list_opt[:include]
+      r = SpeechBalloon.list_opt
       r.has_key?(:panel).should be_true
     end
       it 'コマは作家を含んでいる' do
-        r = SpeechBalloon.list_opt[:include]
+        r = SpeechBalloon.list_opt
         r[:panel].has_key?(:author).should be_true
       end
     it 'フキダシ枠を含んでいる' do
-      r = SpeechBalloon.list_opt[:include]
+      r = SpeechBalloon.list_opt
       r.has_key?(:balloon).should be_true
     end
     it 'セリフを含んでいる' do
-      r = SpeechBalloon.list_opt[:include]
+      r = SpeechBalloon.list_opt
       r.has_key?(:speech).should be_true
     end
     it 'フキダシテンプレートを含んでいる' do
-      r = SpeechBalloon.list_opt[:include]
+      r = SpeechBalloon.list_opt
       r.has_key?(:speech_balloon_template).should be_true
     end
   end