OSDN Git Service

t#29400:update artist, author:itr1
authoryasushiito <yas@pen-chan.jp>
Wed, 29 Aug 2012 23:06:35 +0000 (08:06 +0900)
committeryasushiito <yas@pen-chan.jp>
Wed, 29 Aug 2012 23:06:35 +0000 (08:06 +0900)
13 files changed:
Gemfile.lock
app/controllers/artists_controller.rb
app/controllers/authors_controller.rb
app/models/artist.rb
app/models/author.rb
app/views/authors/_form.html.erb [new file with mode: 0644]
app/views/authors/edit.html.erb [new file with mode: 0644]
app/views/authors/edit.js.erb [new file with mode: 0644]
app/views/authors/show.html.erb
spec/controllers/artists_controller_spec.rb
spec/controllers/authors_controller_spec.rb
spec/models/artist_spec.rb
spec/models/author_spec.rb

index 34911c7..e100987 100644 (file)
@@ -1,7 +1,7 @@
 GEM
   remote: http://rubygems.org/
   specs:
-    ZenTest (4.8.1)
+    ZenTest (4.8.2)
     actionmailer (3.1.1)
       actionpack (= 3.1.1)
       mail (~> 2.3.0)
@@ -30,7 +30,7 @@ GEM
       activesupport (= 3.1.1)
     activesupport (3.1.1)
       multi_json (~> 1.0)
-    addressable (2.2.8)
+    addressable (2.3.2)
     arel (2.2.3)
     autotest (4.4.6)
       ZenTest (>= 4.4.1)
@@ -47,7 +47,7 @@ GEM
       rack-test (>= 0.5.4)
       selenium-webdriver (~> 2.0)
       xpath (~> 0.1.4)
-    childprocess (0.3.4)
+    childprocess (0.3.5)
       ffi (~> 1.0, >= 1.0.6)
     choice (0.1.6)
     coffee-rails (3.1.1)
@@ -57,7 +57,7 @@ GEM
       coffee-script-source
       execjs
     coffee-script-source (1.3.3)
-    creative_commons_v30_licenses (0.0.4)
+    creative_commons_v30_licenses (0.0.9)
       rails (~> 3.1.1)
     cucumber (1.2.1)
       builder (>= 2.1.2)
@@ -77,18 +77,18 @@ GEM
     erubis (2.7.0)
     execjs (1.4.0)
       multi_json (~> 1.0)
-    factory_girl (3.5.0)
+    factory_girl (4.0.0)
       activesupport (>= 3.0.0)
-    ffi (1.1.0-x86-mingw32)
-    gherkin (2.11.1-x86-mingw32)
+    ffi (1.1.5)
+    gherkin (2.11.2-x86-mingw32)
       json (>= 1.4.6)
     hike (1.2.1)
     i18n (0.6.0)
-    jquery-rails (1.0.19)
-      railties (~> 3.0)
+    jquery-rails (2.1.1)
+      railties (>= 3.1.0, < 5.0)
       thor (~> 0.14)
-    json (1.7.3)
-    libwebsocket (0.1.4)
+    json (1.7.5)
+    libwebsocket (0.1.5)
       addressable
     mail (2.3.3)
       i18n (>= 0.4.0)
@@ -99,15 +99,15 @@ GEM
     multi_json (1.3.6)
     nokogiri (1.5.5-x86-mingw32)
     orm_adapter (0.0.7)
-    pettan_commons_v01_licenses (0.0.5)
+    pettan_commons_v01_licenses (0.0.6)
       rails (~> 3.1.1)
-    pettan_protected_v01_licenses (0.0.5)
+    pettan_protected_v01_licenses (0.0.6)
       rails (~> 3.1.1)
-    pettan_public_v01_licenses (0.0.5)
+    pettan_public_v01_licenses (0.0.6)
       rails (~> 3.1.1)
     pg (0.14.0-x86-mingw32)
     polyglot (0.3.3)
-    public_domain_v01_licenses (0.0.5)
+    public_domain_v01_licenses (0.0.6)
       rails (~> 3.1.1)
     rack (1.3.6)
     rack-cache (1.2)
@@ -147,9 +147,9 @@ GEM
       rspec-expectations (~> 2.11.0)
       rspec-mocks (~> 2.11.0)
     rspec-core (2.11.1)
-    rspec-expectations (2.11.1)
+    rspec-expectations (2.11.2)
       diff-lcs (~> 1.1.3)
-    rspec-mocks (2.11.1)
+    rspec-mocks (2.11.2)
     rspec-rails (2.11.0)
       actionpack (>= 3.0)
       activesupport (>= 3.0)
@@ -157,7 +157,7 @@ GEM
       rspec (~> 2.11.0)
     ruby-graphviz (1.0.8)
     rubyzip (0.9.9)
-    sass (3.1.20)
+    sass (3.2.1)
     sass-rails (3.1.6)
       actionpack (~> 3.1.0)
       railties (~> 3.1.0)
@@ -182,10 +182,10 @@ GEM
       polyglot
       polyglot (>= 0.3.1)
     tzinfo (0.3.33)
-    uglifier (1.2.6)
+    uglifier (1.2.7)
       execjs (>= 0.3.0)
       multi_json (~> 1.3)
-    unknown_v01_licenses (0.0.5)
+    unknown_v01_licenses (0.0.6)
       rails (~> 3.1.1)
     validate_url (0.2.0)
       activemodel (>= 3.0.0)
index dec44ed..52c4f24 100644 (file)
@@ -1,6 +1,6 @@
 class ArtistsController < ApplicationController
 layout 'test'
-  before_filter :authenticate_user!, :only => [:index, :show, :create, :update, :destroy]
+  before_filter :authenticate_user!, :only => [:index, :show, :new, :create, :edit, :update, :destroy]
   before_filter :authenticate_admin!, :only => [:list, :browse]
 
   # GET /artists
@@ -8,7 +8,7 @@ layout 'test'
   def index
     @page = Artist.page params[:page]
     @page_size = Artist.page_size params[:page_size]
-    @artists = Artist.list({}, @page, @page_size)
+    @artists = Artist.list(@page, @page_size)
 
     respond_to do |format|
       format.html # index.html.erb
@@ -19,11 +19,11 @@ layout 'test'
   # GET /artists/1
   # GET /artists/1.json
   def show
-    @artist = Artist.show(params[:id])
+    @artist = Artist.show(params[:id], @author)
 
     respond_to do |format|
       format.html # show.html.erb
-      format.json { render :json => @artist.to_json(Artist.list_json_opt) }
+      format.json { render :json => @artist.to_json(Artist.show_json_opt) }
     end
   end
 
index fa3003d..da74488 100644 (file)
@@ -1,11 +1,11 @@
 class AuthorsController < ApplicationController
-  before_filter :authenticate_user!, :only => [:index, :show]
+  before_filter :authenticate_user!, :only => [:index, :show, :edit, :update]
   before_filter :authenticate_admin!, :only => [:list, :browse]
 
   def index
     @page = Author.page params[:page]
     @page_size = Author.page_size params[:page_size]
-    @authors = Author.list({}, @page, @page_size)
+    @authors = Author.list(@page, @page_size)
 
     respond_to do |format|
       format.html # index.html.erb
@@ -14,18 +14,18 @@ class AuthorsController < ApplicationController
   end
 
   def show
-    @author = Author.show(params[:id])
+    @au = Author.show(params[:id], @author)
 
     respond_to do |format|
       format.html
-      format.json { render :json => @author.to_json(Author.list_json_opt) }
+      format.json { render :json => @au.to_json(Author.show_json_opt) }
     end
   end
 
   def count
-    @author = {:count => Author.visible_count}
+    @au = {:count => Author.visible_count}
     respond_to do |format|
-      format.json { render json: @author.to_json }
+      format.json { render json: @au.to_json }
     end
   end
   
@@ -45,4 +45,23 @@ class AuthorsController < ApplicationController
     end
   end
   
+  def edit
+    @au = Author.edit(params[:id], @author)
+  end
+
+  def update
+    @au = Author.edit(params[:id], @author)
+    @au.attributes = params[:author]
+    @au.overwrite
+
+    respond_to do |format|
+      if @au.save
+        format.html { redirect_to @au, notice: 'Author was successfully updated.' }
+        format.json { head :ok }
+      else
+        format.html { render action: "edit" }
+        format.json { render json: @au.errors, status: :unprocessable_entity }
+      end
+    end
+  end
 end
index 093983a..63a1f20 100644 (file)
@@ -1,9 +1,11 @@
 class Artist < ActiveRecord::Base
   belongs_to :author
   has_many :original_pictures
+  has_many :pictures
+  has_many :resource_pictures
   
   validates :name, :presence => true, :length => {:maximum => 30}
-#  validates :default_license_id, :presence => true, :numericality => true, :existence => true
+  validates :author_id, :numericality => {:allow_blank => true}
   
   def supply_default
     self.name = 'no name' if self.name.blank?
@@ -19,10 +21,8 @@ class Artist < ActiveRecord::Base
     self.author_id == author.id
   end
   
-  def self.edit sid, au
-    res = Artist.find sid
-    raise ActiveRecord::Forbidden unless res.own?(au)
-    res
+  def visible? author
+    true
   end
   
   def self.find_by_author author
@@ -37,14 +37,6 @@ class Artist < ActiveRecord::Base
     100
   end
   
-  def self.default_panel_size
-    30
-  end
-  
-  def self.max_panel_size
-    200
-  end
-  
   def self.page prm = nil
     page = prm.to_i
     page = 1 if page < 1
@@ -66,34 +58,44 @@ class Artist < ActiveRecord::Base
     offset
   end
   
-  def self.list opt = {}, page = 1, page_size = self.default_page_size
-    opt.merge!(self.list_opt) unless opt[:include]
-    opt.merge!({:order => 'updated_at desc', :limit => page_size, :offset => (page -1) * page_size})
+  def self.list page = 1, page_size = self.default_page_size
+    opt = {}
+    opt.merge!(Artist.list_opt)
+    opt.merge!({:limit => page_size, :offset => (page -1) * page_size}) if page_size > 0
+    opt.merge!({:order => 'created_at desc'})
     Artist.find(:all, opt)
   end
   
   def self.list_opt
-    {:include => :author}
+    {:include => {:author => {}, :original_pictures => {}, :pictures => {}, :resource_pictures => {}} }
   end
   
   def self.list_json_opt
-    {:include => :author}
+    {:include => {:author => {}, :original_pictures => {}, :pictures => {}, :resource_pictures => {}} }
   end
   
-  def self.show aid, opt = {}
-    a = Artist.find(aid, :include => self.show_include_opt(opt))
-#    raise ActiveRecord::Forbidden unless c.visible?(au)
-    a
+  def self.show aid, au
+    opt = {}
+    opt.merge!(Artist.show_opt)
+    res = Artist.find(aid, opt)
+    raise ActiveRecord::Forbidden unless res.visible?(au)
+    res
   end
   
-  def self.show_include_opt opt = {}
-    res = [:author]
-    res.push(opt[:include]) if opt[:include]
+  def self.edit sid, au
+    opt = {}
+    opt.merge!(Artist.show_opt)
+    res = Artist.find sid, opt
+    raise ActiveRecord::Forbidden unless res.own?(au)
     res
   end
   
-  def self.show_json_include_opt
-    {:include => :author}
+  def self.show_opt
+    {:include => {:author => {}, :original_pictures => {}, :pictures => {}, :resource_pictures => {}} }
+  end
+  
+  def self.show_json_opt
+    {:include => {:author => {}, :original_pictures => {}, :pictures => {}, :resource_pictures => {}} }
   end
   
   def self.visible_count
index a6db5c2..e9fca20 100644 (file)
@@ -2,10 +2,23 @@ class Author < ActiveRecord::Base
   has_one :artist
   belongs_to :user
   
-  validates :name, :length => {:maximum => 30}
+  validates :name, :presence => true, :length => {:maximum => 30}
+  validates :user_id, :numericality => true, :existence => true
   
-  before_save do |r|
-    r.name = 'no name' if r.name.blank?
+  def supply_default
+    self.name = 'no name' if self.name.blank?
+  end
+  
+  def overwrite 
+  end
+  
+  def own? author
+    return false unless author
+    self.id == author.id
+  end
+  
+  def visible? author
+    true
   end
   
   def artist?
@@ -38,18 +51,44 @@ class Author < ActiveRecord::Base
     page_size
   end
   
-  def self.list opt = {}, page = 1, page_size = self.default_page_size
-    opt.merge!(self.list_opt) unless opt[:include]
-    opt.merge!({:order => 'updated_at desc', :limit => page_size, :offset => (page -1) * page_size})
+  def self.list page = 1, page_size = self.default_page_size
+    opt = {}
+    opt.merge!(Author.list_opt)
+    opt.merge!({:limit => page_size, :offset => (page -1) * page_size}) if page_size > 0
+    opt.merge!({:order => 'created_at desc'})
     Author.find(:all, opt)
   end
   
   def self.list_opt
-    {:include => :artist}
+    {:include => {:artist => {}} }
   end
   
   def self.list_json_opt
-    {:include => :artist}
+    {:include => {:artist => {}} }
+  end
+  
+  def self.show aid, au
+    opt = {}
+    opt.merge!(Author.show_opt)
+    res = Author.find(aid, opt)
+    raise ActiveRecord::Forbidden unless res.visible?(au)
+    res
+  end
+  
+  def self.show_opt
+    {:include => {:artist => {}} }
+  end
+  
+  def self.show_json_opt
+    {:include => {:artist => {}} }
+  end
+  
+  def self.edit aid, au
+    opt = {}
+    opt.merge!(Author.show_opt)
+    res = Author.find aid, opt
+    raise ActiveRecord::Forbidden unless res.own?(au)
+    res
   end
   
   def self.default_comic_page_size
@@ -157,22 +196,6 @@ class Author < ActiveRecord::Base
     page_size
   end
   
-  def self.show aid, opt = {}
-    a = Author.find(aid, :include => self.show_include_opt(opt))
-#    raise ActiveRecord::Forbidden unless c.visible?(au)
-    a
-  end
-  
-  def self.show_include_opt opt = {}
-    res = [:artist]
-    res.push(opt[:include]) if opt[:include]
-    res
-  end
-  
-  def self.show_json_include_opt
-    {:include => :artist}
-  end
-  
   def self.visible_count
     Author.count
   end
diff --git a/app/views/authors/_form.html.erb b/app/views/authors/_form.html.erb
new file mode 100644 (file)
index 0000000..d15a03d
--- /dev/null
@@ -0,0 +1,23 @@
+<%= form_for(@au) do |f| %>
+  <% if @au.errors.any? %>
+    <div id="error_explanation">
+      <h2><%= pluralize(@au.errors.count, "error") %> prohibited this author from being saved:</h2>
+
+      <ul>
+      <% @au.errors.full_messages.each do |msg| %>
+        <li><%= msg %></li>
+      <% end %>
+      </ul>
+    </div>
+  <% end %>
+
+  <div class="field">
+    <%= f.label :name %><br />
+    <%= f.text_field :name %><br />
+
+  </div>
+  <div class="actions">
+    <%= f.submit %>
+  </div>
+<% end %>
+
diff --git a/app/views/authors/edit.html.erb b/app/views/authors/edit.html.erb
new file mode 100644 (file)
index 0000000..8520571
--- /dev/null
@@ -0,0 +1,6 @@
+<h1>Editing author</h1>
+
+<%= render 'form' %>
+
+<%= link_to 'Show', @au %> |
+<%= link_to 'Back', authors_path %>
diff --git a/app/views/authors/edit.js.erb b/app/views/authors/edit.js.erb
new file mode 100644 (file)
index 0000000..b363b59
--- /dev/null
@@ -0,0 +1 @@
+$("#newauthor").html("<%= escape_javascript(render('form')) -%>");
index 464be42..bbaf084 100644 (file)
@@ -2,7 +2,7 @@
 
 <p>
   <b>name:</b>
-  <%= h(@author.name) %>
+  <%= h(@au.name) %>
 </p>
 
 <%= link_to 'Back', :controller => 'authors' %>
index c8c05d8..88babc0 100644 (file)
@@ -68,6 +68,10 @@ describe ArtistsController do
           get :index, :format => :json
           lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError)
         end
+        it '絵師モデルにjson一覧出力オプションを問い合わせている' do
+          Artist.should_receive(:list_json_opt).exactly(1)
+          get :index, :format => :json
+        end
         it 'データがリスト構造になっている' do
           get :index, :format => :json
           json = JSON.parse response.body
@@ -136,6 +140,10 @@ describe ArtistsController do
           get :show, :id => @artist.id, :format => :json
           lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError)
         end
+        it '絵師モデルにjson単体出力オプションを問い合わせている' do
+          Artist.should_receive(:show_json_opt).exactly(1)
+          get :show, :id => @artist.id, :format => :json
+        end
         it 'データがアレになっている' do
           get :show, :id => @artist.id, :format => :json
           json = JSON.parse response.body
@@ -203,7 +211,7 @@ describe ArtistsController do
           get :count, :format => :json
           lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError)
         end
-        it 'データがHash構造になっていてコミック数が1である' do
+        it 'データがHash構造になっていて絵師数が3である' do
           get :count, :format => :json
           json = JSON.parse response.body
           json["count"].should == 3
@@ -212,4 +220,334 @@ describe ArtistsController do
     end
   end
 
+  describe '新規作成フォーム表示に於いて' do\r
+    before do\r
+      sign_in @user\r
+    end\r
+    context 'つつがなく終わるとき' do\r
+      it 'ステータスコード200 OKを返す' do\r
+        get :new\r
+        response.should be_success \r
+      end\r
+      it '@artistに新規データを用意している' do\r
+        get :new\r
+        assigns(:artist).should be_a_new(Artist)\r
+      end\r
+      it '絵師モデルにデフォルト値補充を依頼している' do\r
+        Artist.any_instance.should_receive(:supply_default).exactly(1)\r
+        get :new\r
+      end\r
+      context 'html形式' do\r
+        it 'newテンプレートを描画する' do\r
+          get :new\r
+          response.should render_template("new")\r
+        end\r
+      end\r
+      context 'js形式' do\r
+        it 'new.jsテンプレートを描画する' do\r
+          get :new, :format => :js\r
+          response.should render_template("new")\r
+        end\r
+      end\r
+      context 'json形式' do
+        it 'jsonデータを返す' do
+          get :new, :format => :json
+          lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError)
+        end
+      end
+    end\r
+    context '作家権限がないとき' do\r
+      before do\r
+        sign_out @user\r
+      end\r
+      context 'html形式' do\r
+        it 'ステータスコード302 Foundを返す' do\r
+          get :new\r
+          response.status.should eq 302\r
+        end\r
+        it 'サインインページへ遷移する' do\r
+          get :new\r
+          response.body.should redirect_to '/users/sign_in'\r
+        end\r
+      end\r
+      context 'js形式' do\r
+        it 'ステータスコード401 Unauthorizedを返す' do\r
+          get :new, :format => :js\r
+          response.status.should eq 401\r
+        end\r
+        it '応答メッセージにUnauthorizedを返す' do\r
+          get :new, :format => :js\r
+          response.message.should match(/Unauthorized/)\r
+        end\r
+      end\r
+      context 'json形式' do
+        it 'ステータスコード401 Unauthorizedを返す' do
+          get :new, :format => :json
+          response.status.should eq 401
+        end
+        it '応答メッセージにUnauthorizedを返す' do
+          get :new, :format => :json
+          response.message.should match(/Unauthorized/)
+        end
+      end
+    end\r
+  end\r
+\r
+  describe '新規作成に於いて' do\r
+    before do\r
+      sign_in @user\r
+      @attr = FactoryGirl.attributes_for(:artist, :author_id => @author.id, :name => 'ken')\r
+    end\r
+    context 'つつがなく終わるとき' do\r
+      it 'モデルに保存依頼する' do\r
+        Artist.any_instance.should_receive(:save).exactly(1)\r
+        post :create, :artist => @attr\r
+      end\r
+      it "@artistに作成された絵師を保持していて、それがDBにある" do\r
+        post :create, :artist => @attr\r
+        assigns(:artist).should be_a(Artist)\r
+        assigns(:artist).should be_persisted\r
+      end\r
+      context 'html形式' do\r
+        it 'ステータスコード302 Foundを返す' do\r
+          Artist.any_instance.stub(:save).and_return(true)\r
+          post :create, :artist => @attr\r
+          response.status.should eq 302\r
+        end\r
+        it '作成された絵師の表示ページへ遷移する' do\r
+#          Artist.any_instance.stub(:save).and_return(true)\r
+          post :create, :artist => @attr\r
+          response.should redirect_to(Artist.last)\r
+        end\r
+      end\r
+      context 'json形式' do\r
+        it 'ステータスコード200 OKを返す' do\r
+#          Artist.any_instance.stub(:save).and_return(true)\r
+          post :create, :artist => @attr, :format => :json\r
+          response.should be_success \r
+        end\r
+        it '作成された絵師をjsonデータで返す' do\r
+          post :create, :artist => @attr, :format => :json\r
+          lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError)\r
+        end\r
+        it 'データがアレになっている' do\r
+          post :create, :artist => @attr, :format => :json\r
+          json = JSON.parse response.body\r
+          json["name"].should match(/ken/)\r
+        end\r
+      end\r
+    end\r
+    context '作家権限がないとき' do\r
+      before do\r
+        sign_out @user\r
+      end\r
+      context 'html形式' do\r
+        it 'ステータスコード302 Foundを返す' do\r
+          post :create, :artist => @attr\r
+          response.status.should eq 302\r
+        end\r
+        it 'サインインページへ遷移する' do\r
+          post :create, :artist => @attr\r
+          response.body.should redirect_to '/users/sign_in'\r
+        end\r
+      end\r
+      context 'json形式' do\r
+        it 'ステータスコード401 Unauthorizedを返す' do\r
+          post :create, :artist => @attr, :format => :json\r
+          response.status.should eq 401\r
+        end\r
+        it '応答メッセージにUnauthorizedを返す' do\r
+          post :create, :artist => @attr, :format => :json\r
+          response.message.should match(/Unauthorized/)\r
+        end\r
+      end\r
+    end\r
+    context '検証、保存に失敗した' do\r
+      before do\r
+        Artist.any_instance.stub(:save).and_return(false)\r
+      end\r
+      it "未保存の絵師を保持している" do\r
+        post :create, :artist => @attr\r
+        assigns(:artist).should be_a_new(Artist)\r
+      end\r
+      context 'html形式' do\r
+        it 'ステータスコード200 OKを返す' do\r
+          post :create, :artist => @attr\r
+          response.status.should eq 200\r
+        end\r
+        it '新規ページを描画する' do\r
+          post :create, :artist => @attr\r
+          response.should render_template("new")\r
+        end\r
+      end\r
+      context 'json形式' do\r
+        it 'ステータスコード422 unprocessable_entity を返す' do\r
+          post :create, :artist => @attr, :format => :json\r
+          response.status.should eq 422\r
+        end\r
+        it '応答メッセージUnprocessable Entityを返す' do\r
+          post :create, :artist => @attr, :format => :json\r
+          response.message.should match(/Unprocessable/)\r
+        end\r
+      end\r
+    end\r
+  end\r
+\r
+  describe '編集フォーム表示に於いて' do\r
+    before do\r
+      sign_in @user\r
+      Artist.stub(:edit).and_return(@artist)\r
+    end\r
+    context 'つつがなく終わるとき' do\r
+      it 'ステータスコード200 OKを返す' do\r
+        get :edit, :id => @artist.id\r
+        response.should be_success \r
+      end\r
+      it '絵師モデルに編集取得を問い合わせている' do\r
+        Artist.should_receive(:edit).exactly(1)\r
+        get :edit, :id => @artist.id\r
+      end\r
+      it '@artistにデータを用意している' do\r
+        get :edit, :id => @artist.id\r
+        assigns(:artist).should eq @artist\r
+      end\r
+      context 'html形式' do\r
+        it 'editテンプレートを描画する' do\r
+          get :edit, :id => @artist.id\r
+          response.should render_template("edit")\r
+        end\r
+      end\r
+      context 'js形式' do\r
+        it 'edit.jsテンプレートを描画する' do\r
+          get :edit, :id => @artist.id, :format => :js\r
+          response.should render_template("edit")\r
+        end\r
+      end\r
+    end\r
+    context '作家権限がないとき' do\r
+      before do\r
+        sign_out @user\r
+      end\r
+      context 'html形式' do\r
+        it 'ステータスコード302 Foundを返す' do\r
+          get :edit, :id => @artist.id\r
+          response.status.should eq 302\r
+        end\r
+        it 'サインインページへ遷移する' do\r
+          get :edit, :id => @artist.id\r
+          response.body.should redirect_to '/users/sign_in'\r
+        end\r
+      end\r
+      context 'js形式' do\r
+        it 'ステータスコード401 Unauthorizedを返す' do\r
+          get :edit, :id => @artist.id, :format => :js\r
+          response.status.should eq 401\r
+        end\r
+        it '応答メッセージにUnauthorizedを返す' do\r
+          get :edit, :id => @artist.id, :format => :js\r
+          response.message.should match(/Unauthorized/)\r
+        end\r
+      end\r
+    end\r
+  end\r
+\r
+  describe '更新に於いて' do\r
+    before do\r
+      @attr = FactoryGirl.attributes_for(:artist, :author_id => @author.id, :name => 'ryu')\r
+      sign_in @user\r
+    end\r
+    context '事前チェックしておく' do\r
+      it '絵師モデルに編集取得を問い合わせている' do\r
+        Artist.stub(:edit).with(any_args()).and_return @artist\r
+        Artist.should_receive(:edit).exactly(1)\r
+        put :update, :id => @artist.id, :artist => @attr\r
+      end\r
+      it 'モデルに更新を依頼する' do\r
+        Artist.any_instance.stub(:save).with(any_args).and_return true\r
+        Artist.any_instance.should_receive(:save).exactly(1)\r
+        put :update, :id => @artist.id, :artist => @attr\r
+      end\r
+      it '@artistにアレを取得している' do\r
+        put :update, :id => @artist.id, :artist => @attr\r
+        assigns(:artist).should eq @artist\r
+      end\r
+    end\r
+    context 'つつがなく終わるとき' do\r
+      it '更新される' do\r
+        put :update, :id => @artist.id, :artist => @attr\r
+        Artist.find(@artist.id).name.should eq 'ryu'\r
+      end\r
+      context 'html形式' do\r
+        it 'ステータスコード302 Foundを返す' do\r
+          Artist.any_instance.stub(:save).with(any_args()).and_return(true)\r
+          put :update, :id => @artist.id, :artist => @attr\r
+          response.status.should eq 302\r
+        end\r
+        it '更新された絵師の表示ページへ遷移する' do\r
+          put :update, :id => @artist.id, :artist => @attr\r
+          response.should redirect_to(@artist)\r
+        end\r
+      end\r
+      context 'json形式' do\r
+        it 'ステータスコード200 OKを返す' do\r
+          Artist.any_instance.stub(:save).with(any_args()).and_return(true)\r
+          put :update, :id => @artist.id, :artist => @attr, :format => :json\r
+          response.should be_success \r
+        end\r
+        it 'ページ本体は特に返さない' do\r
+          Artist.any_instance.stub(:save).with(any_args()).and_return(true)\r
+          put :update, :id => @artist.id, :artist => @attr, :format => :json\r
+          response.body.should match /./\r
+        end\r
+      end\r
+    end\r
+    context '作家権限がないとき' do\r
+      before do\r
+        sign_out @user\r
+      end\r
+      it 'ステータスコード302 Foundを返す' do\r
+        put :update, :id => @artist.id, :artist => @attr\r
+        response.status.should eq 302\r
+      end\r
+      context 'html形式' do\r
+        it 'サインインページへ遷移する' do\r
+          put :update, :id => @artist.id, :artist => @attr\r
+          response.body.should redirect_to '/users/sign_in'\r
+        end\r
+      end\r
+      context 'json形式' do\r
+        it '応答メッセージにUnauthorizedを返す' do\r
+          put :update, :id => @artist.id, :artist => @attr, :format => :json\r
+          response.message.should match(/Unauthorized/)\r
+        end\r
+      end\r
+    end\r
+    context '検証、保存に失敗したとき' do\r
+      before do\r
+        Artist.any_instance.stub(:save).and_return(false)\r
+      end\r
+      context 'html形式' do\r
+        it 'ステータスコード200 Okを返す' do\r
+          put :update, :id => @artist.id, :artist => @attr\r
+          response.status.should eq 200\r
+        end\r
+        it '編集ページを描画する' do\r
+          put :update, :id => @artist.id, :artist => @attr\r
+          response.should render_template("edit")\r
+        end\r
+      end\r
+      context 'json形式' do\r
+        it 'ステータスコード422 unprocessable_entity を返す' do\r
+          Artist.any_instance.stub(:save).and_return(false)\r
+          put :update, :id => @artist.id, :artist => @attr, :format => :json\r
+          response.status.should eq 422\r
+        end\r
+        it '応答メッセージUnprocessable Entityを返す' do\r
+          put :update, :id => @artist.id, :artist => @attr, :format => :json\r
+          response.message.should match(/Unprocessable/)\r
+        end\r
+      end\r
+    end\r
+  end\r
+\r
 end
index d7067da..d13828e 100644 (file)
@@ -68,6 +68,10 @@ describe AuthorsController do
           get :index, :format => :json
           lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError)
         end
+        it '作家モデルにjson一覧出力オプションを問い合わせている' do
+          Author.should_receive(:list_json_opt).exactly(1)
+          get :index, :format => :json
+        end
         it 'データがリスト構造になっている' do
           get :index, :format => :json
           json = JSON.parse response.body
@@ -77,6 +81,7 @@ describe AuthorsController do
           get :index, :format => :json
           json = JSON.parse response.body
           json.first.has_key?("name").should be_true
+          json.first.has_key?("user_id").should be_true
         end
       end
     end
@@ -121,9 +126,10 @@ describe AuthorsController do
         Author.should_receive(:show).exactly(1)
         get :show
       end
-      it '@authorにアレを取得している' do
+      #@authorだとログイン中のアカウントと干渉してしまう。
+      it '@auにアレを取得している' do
         get :show, :id => @author.id
-        assigns(:author).should eq(@author)
+        assigns(:au).should eq(@author)
       end
       context 'html形式' do
         it 'showテンプレートを描画する' do
@@ -136,10 +142,15 @@ describe AuthorsController do
           get :show, :id => @author.id, :format => :json
           lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError)
         end
+        it '作家モデルにjson単体出力オプションを問い合わせている' do
+          Author.should_receive(:show_json_opt).exactly(1)
+          get :show, :id => @author.id, :format => :json
+        end
         it 'データがアレになっている' do
           get :show, :id => @author.id, :format => :json
           json = JSON.parse response.body
           json["name"].should match(/name/)
+          json["user_id"].should eq @author.user_id
         end
       end
     end
@@ -203,7 +214,7 @@ describe AuthorsController do
           get :count, :format => :json
           lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError)
         end
-        it 'データがHash構造になっていてコミック数が1である' do
+        it 'データがHash構造になっていて作家数が3である' do
           get :count, :format => :json
           json = JSON.parse response.body
           json["count"].should == 3
@@ -211,5 +222,174 @@ describe AuthorsController do
       end
     end
   end
+  
+  describe '編集フォーム表示に於いて' do\r
+    before do\r
+      sign_in @user\r
+      Author.stub(:edit).and_return(@author)\r
+    end\r
+    context 'つつがなく終わるとき' do\r
+      it 'ステータスコード200 OKを返す' do\r
+        get :edit, :id => @author.id\r
+        response.should be_success \r
+      end\r
+      it '作家モデルに編集取得を問い合わせている' do\r
+        Author.should_receive(:edit).exactly(1)\r
+        get :edit, :id => @author.id\r
+      end\r
+      #@authorだとログイン中のアカウントと干渉してしまう。
+      it '@auにデータを用意している' do\r
+        get :edit, :id => @author.id\r
+        assigns(:au).should eq @author\r
+      end\r
+      context 'html形式' do\r
+        it 'editテンプレートを描画する' do\r
+          get :edit, :id => @author.id\r
+          response.should render_template("edit")\r
+        end\r
+      end\r
+      context 'js形式' do\r
+        it 'edit.jsテンプレートを描画する' do\r
+          get :edit, :id => @author.id, :format => :js\r
+          response.should render_template("edit")\r
+        end\r
+      end\r
+    end\r
+    context '作家権限がないとき' do\r
+      before do\r
+        sign_out @user\r
+      end\r
+      context 'html形式' do\r
+        it 'ステータスコード302 Foundを返す' do\r
+          get :edit, :id => @author.id\r
+          response.status.should eq 302\r
+        end\r
+        it 'サインインページへ遷移する' do\r
+          get :edit, :id => @author.id\r
+          response.body.should redirect_to '/users/sign_in'\r
+        end\r
+      end\r
+      context 'js形式' do\r
+        it 'ステータスコード401 Unauthorizedを返す' do\r
+          get :edit, :id => @author.id, :format => :js\r
+          response.status.should eq 401\r
+        end\r
+        it '応答メッセージにUnauthorizedを返す' do\r
+          get :edit, :id => @author.id, :format => :js\r
+          response.message.should match(/Unauthorized/)\r
+        end\r
+      end\r
+    end\r
+  end\r
+\r
+  describe '更新に於いて' do\r
+    before do\r
+      @attr = @author.attributes
+      @attr['name'] = 'ryu'\r
+      sign_in @user\r
+    end\r
+    context '事前チェックしておく' do\r
+      it '作家モデルに編集取得を問い合わせている' do\r
+        Author.stub(:edit).with(any_args()).and_return @author\r
+        Author.should_receive(:edit).exactly(1)\r
+        put :update, :id => @author.id, :author => @attr\r
+      end\r
+      it 'モデルにpostデータ転送を依頼する' do\r
+        Author.any_instance.stub(:attributes=).with(any_args)\r
+        Author.any_instance.should_receive(:attributes=).exactly(1)\r
+        put :update, :id => @author.id, :author => @attr\r
+      end\r
+      it 'モデルに上書き補充を依頼する' do\r
+        Author.any_instance.stub(:overwrite).with(any_args)\r
+        Author.any_instance.should_receive(:overwrite).exactly(1)\r
+        put :update, :id => @author.id, :author => @attr\r
+      end\r
+      it 'モデルに更新を依頼する' do\r
+        Author.any_instance.stub(:save).with(any_args).and_return true\r
+        Author.any_instance.should_receive(:save).exactly(1)\r
+        put :update, :id => @author.id, :author => @attr\r
+      end\r
+      it '@auにアレを取得している' do\r
+        put :update, :id => @author.id, :author => @attr\r
+        assigns(:au).should eq @author\r
+      end\r
+    end\r
+    context 'つつがなく終わるとき' do\r
+      it '更新される' do\r
+        put :update, :id => @author.id, :author => @attr\r
+        Author.find(@author.id).name.should eq 'ryu'\r
+      end\r
+      context 'html形式' do\r
+        it 'ステータスコード302 Foundを返す' do\r
+          Author.any_instance.stub(:save).with(any_args()).and_return(true)\r
+          put :update, :id => @author.id, :author => @attr\r
+          response.status.should eq 302\r
+        end\r
+        it '更新された作家の表示ページへ遷移する' do\r
+          put :update, :id => @author.id, :author => @attr\r
+          response.should redirect_to(@author)\r
+        end\r
+      end\r
+      context 'json形式' do\r
+        it 'ステータスコード200 OKを返す' do\r
+          Author.any_instance.stub(:save).with(any_args()).and_return(true)\r
+          put :update, :id => @author.id, :author => @attr, :format => :json\r
+          response.should be_success \r
+        end\r
+        it 'ページ本体は特に返さない' do\r
+          Author.any_instance.stub(:save).with(any_args()).and_return(true)\r
+          put :update, :id => @author.id, :author => @attr, :format => :json\r
+          response.body.should match /./\r
+        end\r
+      end\r
+    end\r
+    context '作家権限がないとき' do\r
+      before do\r
+        sign_out @user\r
+      end\r
+      it 'ステータスコード302 Foundを返す' do\r
+        put :update, :id => @author.id, :author => @attr\r
+        response.status.should eq 302\r
+      end\r
+      context 'html形式' do\r
+        it 'サインインページへ遷移する' do\r
+          put :update, :id => @author.id, :author => @attr\r
+          response.body.should redirect_to '/users/sign_in'\r
+        end\r
+      end\r
+      context 'json形式' do\r
+        it '応答メッセージにUnauthorizedを返す' do\r
+          put :update, :id => @author.id, :author => @attr, :format => :json\r
+          response.message.should match(/Unauthorized/)\r
+        end\r
+      end\r
+    end\r
+    context '検証、保存に失敗したとき' do\r
+      before do\r
+        Author.any_instance.stub(:save).and_return(false)\r
+      end\r
+      context 'html形式' do\r
+        it 'ステータスコード200 Okを返す' do\r
+          put :update, :id => @author.id, :author => @attr\r
+          response.status.should eq 200\r
+        end\r
+        it '編集ページを描画する' do\r
+          put :update, :id => @author.id, :author => @attr\r
+          response.should render_template("edit")\r
+        end\r
+      end\r
+      context 'json形式' do\r
+        it 'ステータスコード422 unprocessable_entity を返す' do\r
+          Author.any_instance.stub(:save).and_return(false)\r
+          put :update, :id => @author.id, :author => @attr, :format => :json\r
+          response.status.should eq 422\r
+        end\r
+        it '応答メッセージUnprocessable Entityを返す' do\r
+          put :update, :id => @author.id, :author => @attr, :format => :json\r
+          response.message.should match(/Unprocessable/)\r
+        end\r
+      end\r
+    end\r
+  end\r
 
 end
index f7797cf..815edbc 100644 (file)
@@ -7,6 +7,8 @@ describe Artist do
     FactoryGirl.create :admin
     @user = FactoryGirl.create( :user_yas)
     @author = @user.author
+    @other_user = FactoryGirl.create( :user_yas)\r
+    @other_author = @other_user.author\r
     @sp = FactoryGirl.create :system_picture
     @lg = FactoryGirl.create :license_group
     @license = FactoryGirl.create :license, :license_group_id => @lg.id, :system_picture_id => @sp.id
@@ -14,26 +16,40 @@ describe Artist do
 
   describe '検証に於いて' do
     before do
+      @artist = FactoryGirl.build :artist, :author_id => @author.id
     end
     
-    it 'オーソドックスなデータなら通る' do
-      @artist = FactoryGirl.build :artist, :author_id => @author.id
-      @artist.should be_valid
+    context 'オーソドックスなデータのとき' do
+      it '下限データが通る' do
+        @artist.name = 'a'
+        @artist.should be_valid
+      end
+      it '上限データが通る' do
+        @artist.name = 'a'*30
+        @artist.should be_valid
+      end
     end
     
     context 'nameを検証するとき' do
       it 'nullなら失敗する' do
-        @artist = FactoryGirl.build :artist, :author_id => @author.id, :name => nil
+        @artist.name = nil
         @artist.should_not be_valid
       end
       it '30文字以上なら失敗する' do
-        @artist = FactoryGirl.build :artist, :author_id => @author.id, :name => 'a'*31
+        @artist.name = 'a'*31
+        @artist.should_not be_valid
+      end
+    end
+    context 'author_idを検証するとき' do
+      #絵師は独立絵師があるので数値チェックだけ
+      it '数値でなければ失敗する' do
+        @artist.author_id = 'a'
         @artist.should_not be_valid
       end
     end
   end
   
-  describe '自動補充に於いて' do
+  describe 'デフォルト値補充に於いて' do
     it '名前がno nameになっている' do
       @artist = FactoryGirl.build :artist, :name => nil
       @artist.supply_default
@@ -41,52 +57,44 @@ describe Artist do
     end
   end
   
-  describe '単体取得に於いて' do
+  describe '上書き補充に於いて' do
+    it '作家idが設定されている' do
+      @artist = FactoryGirl.build :artist
+      @artist.overwrite @author
+      @artist.author_id.should eq @author.id
+    end
+  end
+  
+  describe '所持判定に於いて' do
     before do
       @artist = FactoryGirl.create :artist, :author_id => @author.id
+      @other_artist = FactoryGirl.create :artist_yas, :author_id => @other_author.id\r
     end
-    it '指定の絵師を返す' do
-      a = Artist.show @artist.id
-      a.should eq @artist
+    it '自分の絵師ならyes' do
+      @artist.own?(@author).should == true
     end
-    context '関連テーブルオプションがないとき' do
-      it '作家データだけを含んでいる' do
-        r = Artist.show_include_opt
-        r.should eq [:author]
-      end
+    it '他人の絵師ならno' do
+      @artist.own?(@other_author).should == false
     end
-    context '関連テーブルオプションで素材を含ませたとき' do
-      it '作家データと素材データを含んでいる' do
-        r = Artist.show_include_opt(:include => :resource_pictures)
-        r.should eq [:author, :resource_pictures]
-      end
+    it '作家が不明ならno' do
+      @artist.own?(nil).should == false
     end
   end
-  describe '編集取得に於いて' do
+  
+  describe '閲覧許可に於いて' do
     before do
       @artist = FactoryGirl.create :artist, :author_id => @author.id
     end
-    it '指定の絵師を返す' do
-      Artist.any_instance.stub(:own?).and_return(true)
-      r = Artist.edit @artist.id, @author.id
-      r.should eq @artist
-    end
-    context '他人の絵師を開こうとしたとき' do
-      it '403Forbidden例外を返す' do
-        Artist.any_instance.stub(:own?).and_return(false)
-        lambda{
-          Artist.edit @artist.id, @author
-        }.should raise_error(ActiveRecord::Forbidden)
-      end
-    end
-    context '存在しない絵師を開こうとしたとき' do
-      it '404RecordNotFound例外を返す' do
-        lambda{
-          Artist.edit 110, @author
-        }.should raise_error(ActiveRecord::RecordNotFound)
-      end
-    end
+    it '自分の絵師を見るときは許可する' do\r
+      Artist.any_instance.stub(:own?).and_return(true)\r
+      @artist.visible?(@author).should == true
+    end\r
+    it '他人の絵師でも許可する' do\r
+      Artist.any_instance.stub(:own?).and_return(false)\r
+      @artist.visible?(@author).should == true
+    end\r
   end
+  
   describe '一覧取得に於いて' do
     before do
       @artist = FactoryGirl.create :artist, :author_id => @author.id
@@ -116,40 +124,238 @@ describe Artist do
         Artist.page_size('1000').should eq Artist.max_page_size
       end
     end
+    context 'つつがなく終わるとき' do\r
+      it '一覧取得オプションを利用している' do\r
+        Artist.stub(:list_opt).with(any_args).and_return({})\r
+        Artist.should_receive(:list_opt).with(any_args).exactly(1)\r
+        r = Artist.list
+      end\r
+    end\r
     it 'リストを返す' do
-      c = Artist.list
-      c.should eq [@artist]
+      r = Artist.list
+      r.should eq [@artist]
     end
-    it '時系列で並んでいる' do
-      n = FactoryGirl.create :artist, :author_id => @author.id, :name => 'artist', :updated_at => Time.now + 100
+    it '作成時系列で並んでいる' do
+      n = FactoryGirl.create :artist, :author_id => @author.id, :name => 'artist', :created_at => Time.now + 100
       l = Artist.list
       l.should eq [n, @artist]
     end
     context 'DBに5件あって1ページの件数を2件に変えたとして' do
       before do
-        @artist2 = FactoryGirl.create :artist, :author_id => @author.id, :name => 'artist2', :updated_at => Time.now + 100
-        @artist3 = FactoryGirl.create :artist, :author_id => @author.id, :name => 'artist3', :updated_at => Time.now + 200
-        @artist4 = FactoryGirl.create :artist, :author_id => @author.id, :name => 'artist4', :updated_at => Time.now + 300
-        @artist5 = FactoryGirl.create :artist, :author_id => @author.id, :name => 'artist5', :updated_at => Time.now + 400
+        @artist2 = FactoryGirl.create :artist, :author_id => @author.id, :name => 'artist2', :created_at => Time.now + 100
+        @artist3 = FactoryGirl.create :artist, :author_id => @author.id, :name => 'artist3', :created_at => Time.now + 200
+        @artist4 = FactoryGirl.create :artist, :author_id => @author.id, :name => 'artist4', :created_at => Time.now + 300
+        @artist5 = FactoryGirl.create :artist, :author_id => @author.id, :name => 'artist5', :created_at => Time.now + 400
         Artist.stub(:default_page_size).and_return(2)
       end
       it '通常は2件を返す' do
-        c = Artist.list
-        c.should have(2).items 
+        r = Artist.list
+        r.should have(2).items 
       end
       it 'page=1なら末尾2件を返す' do
         #時系列で並んでいる
-        c = Artist.list({}, 1)
-        c.should eq [@artist5, @artist4]
+        r = Artist.list(1)
+        r.should eq [@artist5, @artist4]
       end
       it 'page=2なら中間2件を返す' do
-        c = Artist.list({}, 2)
-        c.should eq [@artist3, @artist2]
+        r = Artist.list(2)
+        r.should eq [@artist3, @artist2]
       end
       it 'page=3なら先頭1件を返す' do
-        c = Artist.list({}, 3)
-        c.should eq [@artist]
+        r = Artist.list(3)
+        r.should eq [@artist]
+      end
+    end
+    context 'DBに5件あって1ページの件数を0件に変えたとして' do
+      before do
+        @artist2 = FactoryGirl.create :artist, :author_id => @author.id, :name => 'artist2', :created_at => Time.now + 100
+        @artist3 = FactoryGirl.create :artist, :author_id => @author.id, :name => 'artist3', :created_at => Time.now + 200
+        @artist4 = FactoryGirl.create :artist, :author_id => @author.id, :name => 'artist4', :created_at => Time.now + 300
+        @artist5 = FactoryGirl.create :artist, :author_id => @author.id, :name => 'artist5', :created_at => Time.now + 400
+        Artist.stub(:default_page_size).and_return(0)
+      end
+      it '通常は全件(5件)を返す' do
+        r = Artist.list
+        r.should have(5).items 
+      end
+    end
+  end
+  describe '一覧取得オプションに於いて' do
+    it 'includeキーを含んでいる' do
+      r = Artist.list_opt
+      r.has_key?(:include).should be_true
+    end
+    it '4つの項目を含んでいる' do
+      r = Artist.list_opt[:include]
+      r.should have(4).items
+    end
+    it '作家を含んでいる' do
+      r = Artist.list_opt[:include]
+      r.has_key?(:author).should be_true
+    end
+    it '原画を含んでいる' do
+      r = Artist.list_opt[:include]
+      r.has_key?(:original_pictures).should be_true
+    end
+    it '実素材を含んでいる' do
+      r = Artist.list_opt[:include]
+      r.has_key?(:pictures).should be_true
+    end
+    it '素材を含んでいる' do
+      r = Artist.list_opt[:include]
+      r.has_key?(:resource_pictures).should be_true
+    end
+  end
+  describe 'json一覧出力オプションに於いて' do
+    it 'includeキーを含んでいる' do
+      r = Artist.list_json_opt
+      r.has_key?(:include).should be_true
+    end
+    it '4つの項目を含んでいる' do
+      r = Artist.list_json_opt[:include]
+      r.should have(4).items
+    end
+    it '作家を含んでいる' do
+      r = Artist.list_json_opt[:include]
+      r.has_key?(:author).should be_true
+    end
+    it '原画を含んでいる' do
+      r = Artist.list_json_opt[:include]
+      r.has_key?(:original_pictures).should be_true
+    end
+    it '実素材を含んでいる' do
+      r = Artist.list_json_opt[:include]
+      r.has_key?(:pictures).should be_true
+    end
+    it '素材を含んでいる' do
+      r = Artist.list_json_opt[:include]
+      r.has_key?(:resource_pictures).should be_true
+    end
+  end
+  
+  describe '単体取得に於いて' do
+    before do
+      @artist = FactoryGirl.create :artist, :author_id => @author.id
+    end
+    context 'つつがなく終わるとき' do\r
+      it '単体取得オプションを利用している' do\r
+        Artist.stub(:show_opt).with(any_args).and_return({})\r
+        Artist.should_receive(:show_opt).with(any_args).exactly(1)\r
+        r = Artist.show @artist.id, @author
+      end\r
+      it '閲覧許可を問い合わせている' do\r
+        Artist.any_instance.stub(:visible?).with(any_args).and_return(true)\r
+        Artist.any_instance.should_receive(:visible?).with(any_args).exactly(1)\r
+        r = Artist.show @artist.id, @author
+      end\r
+    end\r
+    it '指定の絵師を返す' do
+      a = Artist.show @artist.id, @author
+      a.should eq @artist
+    end
+    context '閲覧許可が出なかったとき' do\r
+      it '403Forbidden例外を返す' do\r
+        Artist.any_instance.stub(:visible?).and_return(false)\r
+        lambda{\r
+          Artist.show @artist.id, @author\r
+        }.should raise_error(ActiveRecord::Forbidden)\r
+      end\r
+    end\r
+    context '存在しない絵師を開こうとしたとき' do\r
+      it '404RecordNotFound例外を返す' do\r
+        lambda{\r
+          Artist.show 110, @author\r
+        }.should raise_error(ActiveRecord::RecordNotFound)\r
+      end\r
+    end\r
+  end
+  describe '編集取得に於いて' do
+    before do
+      @artist = FactoryGirl.create :artist, :author_id => @author.id
+    end
+    context 'つつがなく終わるとき' do\r
+      it '単体取得オプションを利用している' do\r
+        Artist.stub(:show_opt).with(any_args).and_return({})\r
+        Artist.should_receive(:show_opt).with(any_args).exactly(1)\r
+        r = Artist.edit @artist.id, @author
+      end\r
+      it '所持判定を問い合わせている' do\r
+        Artist.any_instance.stub(:own?).with(any_args).and_return(true)\r
+        Artist.any_instance.should_receive(:own?).with(any_args).exactly(1)\r
+        r = Artist.edit @artist.id, @author
+      end\r
+    end\r
+    it '指定の絵師を返す' do
+      Artist.any_instance.stub(:own?).and_return(true)
+      r = Artist.edit @artist.id, @author.id
+      r.should eq @artist
+    end
+    context '他人の絵師を開こうとしたとき' do
+      it '403Forbidden例外を返す' do
+        Artist.any_instance.stub(:own?).and_return(false)
+        lambda{
+          Artist.edit @artist.id, @author
+        }.should raise_error(ActiveRecord::Forbidden)
       end
     end
+    context '存在しない絵師を開こうとしたとき' do
+      it '404RecordNotFound例外を返す' do
+        lambda{
+          Artist.edit 110, @author
+        }.should raise_error(ActiveRecord::RecordNotFound)
+      end
+    end
+  end
+  describe '単体取得オプションに於いて' do
+    it 'includeキーを含んでいる' do
+      r = Artist.show_opt
+      r.has_key?(:include).should be_true
+    end
+    it '4つの項目を含んでいる' do
+      r = Artist.show_opt[:include]
+      r.should have(4).items
+    end
+    it '作家を含んでいる' do
+      r = Artist.show_opt[:include]
+      r.has_key?(:author).should be_true
+    end
+    it '原画を含んでいる' do
+      r = Artist.show_opt[:include]
+      r.has_key?(:original_pictures).should be_true
+    end
+    it '実素材を含んでいる' do
+      r = Artist.show_opt[:include]
+      r.has_key?(:pictures).should be_true
+    end
+    it '素材を含んでいる' do
+      r = Artist.show_opt[:include]
+      r.has_key?(:resource_pictures).should be_true
+    end
+  end
+  describe 'json単体出力オプションに於いて' do
+    it 'includeキーを含んでいる' do
+      r = Artist.show_json_opt
+      r.has_key?(:include).should be_true
+    end
+    it '4つの項目を含んでいる' do
+      r = Artist.show_json_opt[:include]
+      r.should have(4).items
+    end
+    it '作家を含んでいる' do
+      r = Artist.show_json_opt[:include]
+      r.has_key?(:author).should be_true
+    end
+    it '原画を含んでいる' do
+      r = Artist.show_json_opt[:include]
+      r.has_key?(:original_pictures).should be_true
+    end
+    it '実素材を含んでいる' do
+      r = Artist.show_json_opt[:include]
+      r.has_key?(:pictures).should be_true
+    end
+    it '素材を含んでいる' do
+      r = Artist.show_json_opt[:include]
+      r.has_key?(:resource_pictures).should be_true
+    end
   end
 end
index 414b161..4557d51 100644 (file)
@@ -9,13 +9,83 @@ describe Author do
     @author = @user.author
   end
 
-  describe '自動補充に於いて' do
-    #作家はユーザ作成で自動作成されちゃってる
+  describe '検証に於いて' do
+    before do
+    end
+    
+    context 'オーソドックスなデータのとき' do
+      it '下限データが通る' do
+        @author.name = 'a'
+        @author.should be_valid
+      end
+      it '上限データが通る' do
+        @author.name = 'a'*30
+        @author.save!
+        @author.should be_valid
+      end
+    end
+    
+    context 'nameを検証するとき' do
+      it 'nullなら失敗する' do
+        @author.name = nil
+        @author.should_not be_valid
+      end
+      it '30文字以上なら失敗する' do
+        @author.name = 'a'*31
+        @author.should_not be_valid
+      end
+    end
+    context 'user_idを検証するとき' do
+      it 'nullなら失敗する' do
+        @author.user_id = nil
+        @author.should_not be_valid
+      end
+      it '数値でなければ失敗する' do
+        @author.user_id = 'a'
+        @author.should_not be_valid
+      end
+      it '存在するアカウントでなければ失敗する' do
+        @author.user_id = 0
+        @author.should_not be_valid
+      end
+    end
+  end
+  
+  describe 'デフォルト値補充に於いて' do
     it '名前がno nameになっている' do
+      @author = FactoryGirl.build :author, :name => nil
+      @author.supply_default
       @author.name.should eq 'no name'
     end
   end
   
+  describe '上書き補充に於いて' do
+  end
+  
+  describe '所持判定に於いて' do
+    before do
+      @other_user = FactoryGirl.create :user_yas
+#アカウントを作ると連動して作家ができる      @other_author = FactoryGirl.create :author_yas, :user_id => @other_user.id\r
+    end
+    it '作家自身ならyes' do
+      @author.own?(@author).should == true
+    end
+    it '作家自身でなければno' do
+      @author.own?(@other_author).should == false
+    end
+    it '作家が不明ならno' do
+      @author.own?(nil).should == false
+    end
+  end
+  
+  describe '閲覧許可に於いて' do
+    before do
+    end
+    it '許可する' do\r
+      @author.visible?(@author).should == true
+    end\r
+  end
+  
   describe '絵師作家判定に於いて' do
     before do
     end
@@ -32,4 +102,333 @@ describe Author do
     end
   end
   
+  describe '一覧取得に於いて' do
+    before do
+    end
+    context 'page補正について' do
+      it '文字列から数値に変換される' do
+        Author.page('8').should eq 8
+      end
+      it 'nilの場合は1になる' do
+        Author.page().should eq 1
+      end
+      it '0以下の場合は1になる' do
+        Author.page('0').should eq 1
+      end
+    end
+    context 'page_size補正について' do
+      it '文字列から数値に変換される' do
+        Author.page_size('7').should eq 7
+      end
+      it 'nilの場合はAuthor.default_page_sizeになる' do
+        Author.page_size().should eq Author.default_page_size
+      end
+      it '0以下の場合はAuthor.default_page_sizeになる' do
+        Author.page_size('0').should eq Author.default_page_size
+      end
+      it 'Author.max_page_sizeを超えた場合はAuthor.max_page_sizeになる' do
+        Author.page_size('1000').should eq Author.max_page_size
+      end
+    end
+    context 'つつがなく終わるとき' do\r
+      it '一覧取得オプションを利用している' do\r
+        Author.stub(:list_opt).with(any_args).and_return({})\r
+        Author.should_receive(:list_opt).with(any_args).exactly(1)\r
+        r = Author.list
+      end\r
+    end\r
+    it 'リストを返す' do
+      r = Author.list
+      r.should eq [@author]
+    end
+    it '作成時系列で並んでいる' do
+      @other_user = FactoryGirl.create :user_yas
+      #アカウントを作ると連動して作家ができる
+      n = @other_user.author
+      n.created_at = Time.now + 100
+      n.save
+      l = Author.list
+      l.should eq [n, @author]
+    end
+    context 'DBに5件あって1ページの件数を2件に変えたとして' do
+      before do
+        @other_user2 = FactoryGirl.create :user_yas
+        @author2 = @other_user2.author
+        @author2.created_at = Time.now + 100
+        @author2.save
+        @other_user3 = FactoryGirl.create :user_yas
+        @author3 = @other_user3.author
+        @author3.created_at = Time.now + 200
+        @author3.save
+        @other_user4 = FactoryGirl.create :user_yas
+        @author4 = @other_user4.author
+        @author4.created_at = Time.now + 300
+        @author4.save
+        @other_user5 = FactoryGirl.create :user_yas
+        @author5 = @other_user5.author
+        @author5.created_at = Time.now + 400
+        @author5.save
+        Author.stub(:default_page_size).and_return(2)
+      end
+      it '通常は2件を返す' do
+        r = Author.list
+        r.should have(2).items 
+      end
+      it 'page=1なら末尾2件を返す' do
+        #時系列で並んでいる
+        r = Author.list(1)
+        r.should eq [@author5, @author4]
+      end
+      it 'page=2なら中間2件を返す' do
+        r = Author.list(2)
+        r.should eq [@author3, @author2]
+      end
+      it 'page=3なら先頭1件を返す' do
+        r = Author.list(3)
+        r.should eq [@author]
+      end
+    end
+    context 'DBに5件あって1ページの件数を0件に変えたとして' do
+      before do
+        @other_user2 = FactoryGirl.create :user_yas
+        @author2 = @other_user2.author
+        @author2.created_at = Time.now + 100
+        @author2.save
+        @other_user3 = FactoryGirl.create :user_yas
+        @author3 = @other_user3.author
+        @author3.created_at = Time.now + 200
+        @author3.save
+        @other_user4 = FactoryGirl.create :user_yas
+        @author4 = @other_user4.author
+        @author4.created_at = Time.now + 300
+        @author4.save
+        @other_user5 = FactoryGirl.create :user_yas
+        @author5 = @other_user5.author
+        @author5.created_at = Time.now + 400
+        @author5.save
+        Author.stub(:default_page_size).and_return(0)
+      end
+      it '通常は全件(5件)を返す' do
+        r = Author.list
+        r.should have(5).items 
+      end
+    end
+  end
+  describe '一覧取得オプションに於いて' do
+    it 'includeキーを含んでいる' do
+      r = Author.list_opt
+      r.has_key?(:include).should be_true
+    end
+    it '1つの項目を含んでいる' do
+      r = Author.list_opt[:include]
+      r.should have(1).items
+    end
+    it '絵師を含んでいる' do
+      r = Author.list_opt[:include]
+      r.has_key?(:artist).should be_true
+    end
+  end
+  describe 'json一覧出力オプションに於いて' do
+    it 'includeキーを含んでいる' do
+      r = Author.list_json_opt
+      r.has_key?(:include).should be_true
+    end
+    it '1つの項目を含んでいる' do
+      r = Author.list_json_opt[:include]
+      r.should have(1).items
+    end
+    it '絵師を含んでいる' do
+      r = Author.list_json_opt[:include]
+      r.has_key?(:artist).should be_true
+    end
+  end
+  
+  describe '単体取得に於いて' do
+    before do
+    end
+    context 'つつがなく終わるとき' do\r
+      it '単体取得オプションを利用している' do\r
+        Author.stub(:show_opt).with(any_args).and_return({})\r
+        Author.should_receive(:show_opt).with(any_args).exactly(1)\r
+        r = Author.show @author.id, @author
+      end\r
+      it '閲覧許可を問い合わせている' do\r
+        Author.any_instance.stub(:visible?).with(any_args).and_return(true)\r
+        Author.any_instance.should_receive(:visible?).with(any_args).exactly(1)\r
+        r = Author.show @author.id, @author
+      end\r
+    end\r
+    it '指定の作家を返す' do
+      r = Author.show @author.id, @author
+      r.should eq @author
+    end
+    context '閲覧許可が出なかったとき' do\r
+      it '403Forbidden例外を返す' do\r
+        Author.any_instance.stub(:visible?).and_return(false)\r
+        lambda{\r
+          Author.show @author.id, @author\r
+        }.should raise_error(ActiveRecord::Forbidden)\r
+      end\r
+    end\r
+    context '存在しない作家を開こうとしたとき' do\r
+      it '404RecordNotFound例外を返す' do\r
+        lambda{\r
+          Author.show 110, @author\r
+        }.should raise_error(ActiveRecord::RecordNotFound)\r
+      end\r
+    end\r
+  end
+  describe '編集取得に於いて' do
+    before do
+    end
+    context 'つつがなく終わるとき' do\r
+      it '単体取得オプションを利用している' do\r
+        Author.stub(:show_opt).with(any_args).and_return({})\r
+        Author.should_receive(:show_opt).with(any_args).exactly(1)\r
+        r = Author.edit @author.id, @author
+      end\r
+      it '所持判定を問い合わせている' do\r
+        Author.any_instance.stub(:own?).with(any_args).and_return(true)\r
+        Author.any_instance.should_receive(:own?).with(any_args).exactly(1)\r
+        r = Author.edit @author.id, @author
+      end\r
+    end\r
+    it '指定の作家を返す' do
+      Author.any_instance.stub(:own?).and_return(true)
+      r = Author.edit @author.id, @author.id
+      r.should eq @author
+    end
+    context '他人の作家を開こうとしたとき' do
+      it '403Forbidden例外を返す' do
+        Author.any_instance.stub(:own?).and_return(false)
+        lambda{
+          Author.edit @author.id, @author
+        }.should raise_error(ActiveRecord::Forbidden)
+      end
+    end
+    context '存在しない作家を開こうとしたとき' do
+      it '404RecordNotFound例外を返す' do
+        lambda{
+          Author.edit 110, @author
+        }.should raise_error(ActiveRecord::RecordNotFound)
+      end
+    end
+  end
+  describe '単体取得オプションに於いて' do
+    it 'includeキーを含んでいる' do
+      r = Author.show_opt
+      r.has_key?(:include).should be_true
+    end
+    it '1つの項目を含んでいる' do
+      r = Author.show_opt[:include]
+      r.should have(1).items
+    end
+    it '絵師を含んでいる' do
+      r = Author.show_opt[:include]
+      r.has_key?(:artist).should be_true
+    end
+  end
+  describe 'json単体出力オプションに於いて' do
+    it 'includeキーを含んでいる' do
+      r = Author.show_json_opt
+      r.has_key?(:include).should be_true
+    end
+    it '1つの項目を含んでいる' do
+      r = Author.show_json_opt[:include]
+      r.should have(1).items
+    end
+    it '絵師を含んでいる' do
+      r = Author.show_json_opt[:include]
+      r.has_key?(:artist).should be_true
+    end
+  end
+  
+  describe 'マイリストページ制御パラメータに於いて' do
+    before do
+    end
+    context 'コミックpage_size補正について' do
+      it '文字列から数値に変換される' do
+        Author.comic_page_size('7').should eq 7
+      end
+      it 'nilの場合はAuthor.default_comic_page_sizeになる' do
+        Author.comic_page_size().should eq Author.default_comic_page_size
+      end
+      it '0以下の場合はAuthor.default_comic_page_sizeになる' do
+        Author.comic_page_size('0').should eq Author.default_comic_page_size
+      end
+      it 'Author.comic_max_page_sizeを超えた場合はAuthor.comic_max_page_sizeになる' do
+        Author.comic_page_size('1000').should eq Author.comic_max_page_size
+      end
+    end
+    context 'ストーリーpage_size補正について' do
+      it '文字列から数値に変換される' do
+        Author.story_page_size('7').should eq 7
+      end
+      it 'nilの場合はAuthor.default_story_page_sizeになる' do
+        Author.story_page_size().should eq Author.default_story_page_size
+      end
+      it '0以下の場合はAuthor.default_story_page_sizeになる' do
+        Author.story_page_size('0').should eq Author.default_story_page_size
+      end
+      it 'Author.story_max_page_sizeを超えた場合はAuthor.story_max_page_sizeになる' do
+        Author.story_page_size('1000').should eq Author.story_max_page_size
+      end
+    end
+    context 'コマ絵page_size補正について' do
+      it '文字列から数値に変換される' do
+        Author.panel_page_size('7').should eq 7
+      end
+      it 'nilの場合はAuthor.default_panel_page_sizeになる' do
+        Author.panel_page_size().should eq Author.default_panel_page_size
+      end
+      it '0以下の場合はAuthor.default_panel_page_sizeになる' do
+        Author.panel_page_size('0').should eq Author.default_panel_page_size
+      end
+      it 'Author.panel_max_page_sizeを超えた場合はAuthor.panel_max_page_sizeになる' do
+        Author.panel_page_size('1000').should eq Author.panel_max_page_size
+      end
+    end
+    context '景色素材page_size補正について' do
+      it '文字列から数値に変換される' do
+        Author.panel_picture_page_size('7').should eq 7
+      end
+      it 'nilの場合はAuthor.default_panel_picture_page_sizeになる' do
+        Author.panel_picture_page_size().should eq Author.default_panel_picture_page_size
+      end
+      it '0以下の場合はAuthor.default_panel_picture_page_sizeになる' do
+        Author.panel_picture_page_size('0').should eq Author.default_panel_picture_page_size
+      end
+      it 'Author.panel_picture_max_page_sizeを超えた場合はAuthor.panel_picture_max_page_sizeになる' do
+        Author.panel_picture_page_size('1000').should eq Author.panel_picture_max_page_size
+      end
+    end
+    context '景色カラーpage_size補正について' do
+      it '文字列から数値に変換される' do
+        Author.ground_picture_page_size('7').should eq 7
+      end
+      it 'nilの場合はAuthor.default_ground_picture_page_sizeになる' do
+        Author.ground_picture_page_size().should eq Author.default_ground_picture_page_size
+      end
+      it '0以下の場合はAuthor.default_ground_picture_page_sizeになる' do
+        Author.ground_picture_page_size('0').should eq Author.default_ground_picture_page_size
+      end
+      it 'Author.ground_picture_max_page_sizeを超えた場合はAuthor.ground_picture_max_page_sizeになる' do
+        Author.ground_picture_page_size('1000').should eq Author.ground_picture_max_page_size
+      end
+    end
+    context '景色カラーコードpage_size補正について' do
+      it '文字列から数値に変換される' do
+        Author.ground_color_page_size('7').should eq 7
+      end
+      it 'nilの場合はAuthor.default_ground_color_page_sizeになる' do
+        Author.ground_color_page_size().should eq Author.default_ground_color_page_size
+      end
+      it '0以下の場合はAuthor.default_ground_color_page_sizeになる' do
+        Author.ground_color_page_size('0').should eq Author.default_ground_color_page_size
+      end
+      it 'Author.ground_color_max_page_sizeを超えた場合はAuthor.ground_color_max_page_sizeになる' do
+        Author.ground_color_page_size('1000').should eq Author.ground_color_max_page_size
+      end
+    end
+  end
 end