OSDN Git Service

create provider
authoryasushiito <yas@pen-chan.jp>
Fri, 23 Nov 2012 05:09:40 +0000 (14:09 +0900)
committeryasushiito <yas@pen-chan.jp>
Fri, 23 Nov 2012 05:09:40 +0000 (14:09 +0900)
44 files changed:
Gemfile
app/assets/javascripts/provider_statuses.js.coffee [new file with mode: 0644]
app/assets/javascripts/providers.js.coffee [new file with mode: 0644]
app/assets/stylesheets/provider_statuses.css.scss [new file with mode: 0644]
app/assets/stylesheets/providers.css.scss [new file with mode: 0644]
app/controllers/application_controller.rb
app/controllers/provider_sources_controller.rb [new file with mode: 0644]
app/controllers/provider_statuses_controller.rb [new file with mode: 0644]
app/controllers/providers_controller.rb [new file with mode: 0644]
app/controllers/system_controller.rb
app/helpers/provider_sources_helper.rb [new file with mode: 0644]
app/helpers/provider_statuses_helper.rb [new file with mode: 0644]
app/helpers/providers_helper.rb [new file with mode: 0644]
app/models/provider.rb [new file with mode: 0644]
app/models/provider_status.rb [new file with mode: 0644]
app/views/layouts/system.html.erb
app/views/provider_sources/_ng.html.erb [new file with mode: 0644]
app/views/provider_sources/_ok.html.erb [new file with mode: 0644]
app/views/provider_sources/import.html.erb [new file with mode: 0644]
app/views/provider_sources/index.html.erb [new file with mode: 0644]
app/views/provider_statuses/_basic.html.erb [new file with mode: 0644]
app/views/provider_statuses/_form.html.erb [new file with mode: 0644]
app/views/provider_statuses/_provider.html.erb [new file with mode: 0644]
app/views/provider_statuses/edit.html.erb [new file with mode: 0644]
app/views/provider_statuses/index.html.erb [new file with mode: 0644]
app/views/provider_statuses/show.html.erb [new file with mode: 0644]
app/views/providers/index.html.erb [new file with mode: 0644]
app/views/providers/show.html.erb [new file with mode: 0644]
app/views/system/import.html.erb [new file with mode: 0644]
config/magic_number.yml
config/routes.rb
db/migrate/20121111060613_create_providers.rb [new file with mode: 0644]
db/migrate/20121116024837_create_provider_statuses.rb [new file with mode: 0644]
spec/controllers/provider_sources_controller_spec.rb [new file with mode: 0644]
spec/controllers/provider_statuses_controller_spec.rb [new file with mode: 0644]
spec/controllers/providers_controller_spec.rb [new file with mode: 0644]
spec/factories.rb
spec/helpers/provider_sources_helper_spec.rb [new file with mode: 0644]
spec/helpers/provider_statuses_helper_spec.rb [new file with mode: 0644]
spec/helpers/providers_helper_spec.rb [new file with mode: 0644]
spec/json/provider_source.json [new file with mode: 0644]
spec/models/comic_spec.rb
spec/models/provider_spec.rb [new file with mode: 0644]
spec/models/provider_status_spec.rb [new file with mode: 0644]

diff --git a/Gemfile b/Gemfile
index 82c882a..da2ec2c 100644 (file)
--- a/Gemfile
+++ b/Gemfile
@@ -63,5 +63,6 @@ end
 
 group :test do
   gem 'autotest'
+  gem 'webmock'
 end
 
diff --git a/app/assets/javascripts/provider_statuses.js.coffee b/app/assets/javascripts/provider_statuses.js.coffee
new file mode 100644 (file)
index 0000000..7615679
--- /dev/null
@@ -0,0 +1,3 @@
+# Place all the behaviors and hooks related to the matching controller here.
+# All this logic will automatically be available in application.js.
+# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
diff --git a/app/assets/javascripts/providers.js.coffee b/app/assets/javascripts/providers.js.coffee
new file mode 100644 (file)
index 0000000..7615679
--- /dev/null
@@ -0,0 +1,3 @@
+# Place all the behaviors and hooks related to the matching controller here.
+# All this logic will automatically be available in application.js.
+# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
diff --git a/app/assets/stylesheets/provider_statuses.css.scss b/app/assets/stylesheets/provider_statuses.css.scss
new file mode 100644 (file)
index 0000000..da190ba
--- /dev/null
@@ -0,0 +1,3 @@
+// Place all the styles related to the provider_statuses controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: http://sass-lang.com/
diff --git a/app/assets/stylesheets/providers.css.scss b/app/assets/stylesheets/providers.css.scss
new file mode 100644 (file)
index 0000000..298aeaf
--- /dev/null
@@ -0,0 +1,3 @@
+// Place all the styles related to the providers controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: http://sass-lang.com/
index 4ba05ae..e9fa1f2 100644 (file)
@@ -22,6 +22,11 @@ class ApplicationController < ActionController::Base
           Artist.new author_id: @author.id, email: @user.email, name: @author.name
         end
       end
+      @admin = if admin_signed_in?
+        current_admin
+      else
+        nil
+      end
     end
   end
   
diff --git a/app/controllers/provider_sources_controller.rb b/app/controllers/provider_sources_controller.rb
new file mode 100644 (file)
index 0000000..953fe2c
--- /dev/null
@@ -0,0 +1,19 @@
+class ProviderSourcesController < ApplicationController
+  layout 'test' if MagicNumber['test_layout']
+  before_filter :authenticate_admin!, :only => [:index, :import]
+  
+  def index
+    @urls = MagicNumber['provider_sources']
+    respond_to do |format|
+      format.html # index.html.erb
+    end
+  end
+
+  def import
+    @results = Provider.import MagicNumber['provider_sources']
+    respond_to do |format|
+      format.html # index.html.erb
+    end
+  end
+
+end
diff --git a/app/controllers/provider_statuses_controller.rb b/app/controllers/provider_statuses_controller.rb
new file mode 100644 (file)
index 0000000..95a60ef
--- /dev/null
@@ -0,0 +1,61 @@
+class ProviderStatusesController < ApplicationController
+  layout 'test' if MagicNumber['test_layout']
+  before_filter :authenticate_admin!, :only => [:index, :show, :edit, :update, :destroy]
+
+  def index
+    @page = ProviderStatus.page params[:page]
+    @page_size = ProviderStatus.page_size params[:page_size]
+    @hide = params[:hide]
+    @provider_statuses = if @hide.blank?
+      ProviderStatus.list(@page, @page_size)
+    else
+      ProviderStatus.available_list(@page, @page_size)
+    end
+
+    respond_to do |format|
+      format.html # index.html.erb
+      format.json { render :json => @provider_statuses.to_json(ProviderStatus.list_json_opt) }
+    end
+  end
+
+  def show
+    @provider_status = ProviderStatus.show(params[:id], @admin)
+
+    respond_to do |format|
+      format.html # show.html.erb
+      format.json { render :json => @provider_status.to_json(ProviderStatus.show_json_opt) }
+    end
+  end
+
+  def edit
+    @provider_status = ProviderStatus.edit(params[:id], @admin)
+    respond_to do |format|
+      format.html 
+      format.js
+    end
+  end
+
+  def update
+    @provider_status = ProviderStatus.edit(params[:id], @admin)
+    @provider_status.attributes = params[:provider_status]
+    @provider_status.overwrite
+    respond_to do |format|
+      if @provider_status.save
+        format.html { redirect_to @provider_status, notice: 'ProviderStatus was successfully updated.' }
+        format.json { head :ok }
+      else
+        format.html { render action: "edit" }
+        format.json { render json: @provider_status.errors, status: :unprocessable_entity }
+      end
+    end
+  end
+
+  def destroy
+    @provider_status = ProviderStatus.edit(params[:id], @admin)
+    @provider_status.destroy
+    respond_to do |format|
+      format.html { redirect_to comics_url }
+      format.json { head :ok }
+    end
+  end
+end
diff --git a/app/controllers/providers_controller.rb b/app/controllers/providers_controller.rb
new file mode 100644 (file)
index 0000000..d229d28
--- /dev/null
@@ -0,0 +1,30 @@
+class ProvidersController < ApplicationController
+  layout 'test' if MagicNumber['test_layout']
+  before_filter :authenticate_admin!, :only => [:index, :show]
+
+  def index
+    @page = Provider.page params[:page]
+    @page_size = Provider.page_size params[:page_size]
+    @hide = params[:hide]
+    @providers = if @hide.blank?
+      Provider.list(@page, @page_size)
+    else
+      Provider.available_list(@page, @page_size)
+    end
+
+    respond_to do |format|
+      format.html # index.html.erb
+      format.json { render :json => @providers.to_json(Provider.list_json_opt) }
+    end
+  end
+
+  def show
+    @provider = Provider.show(params[:id], @admin)
+
+    respond_to do |format|
+      format.html # show.html.erb
+      format.json { render :json => @provider.to_json(Provider.show_json_opt) }
+    end
+  end
+
+end
index d8cbb0b..632f7e7 100644 (file)
@@ -9,6 +9,9 @@ class SystemController < ApplicationController
   def index
   end
   
+  def import
+  end
+  
   def browse
   end
   
diff --git a/app/helpers/provider_sources_helper.rb b/app/helpers/provider_sources_helper.rb
new file mode 100644 (file)
index 0000000..04f16e9
--- /dev/null
@@ -0,0 +1,2 @@
+module ProviderSourcesHelper
+end
diff --git a/app/helpers/provider_statuses_helper.rb b/app/helpers/provider_statuses_helper.rb
new file mode 100644 (file)
index 0000000..52b7c0d
--- /dev/null
@@ -0,0 +1,2 @@
+module ProviderStatusesHelper
+end
diff --git a/app/helpers/providers_helper.rb b/app/helpers/providers_helper.rb
new file mode 100644 (file)
index 0000000..b2e719d
--- /dev/null
@@ -0,0 +1,2 @@
+module ProvidersHelper
+end
diff --git a/app/models/provider.rb b/app/models/provider.rb
new file mode 100644 (file)
index 0000000..42925c8
--- /dev/null
@@ -0,0 +1,130 @@
+class Provider < ActiveRecord::Base
+  belongs_to :provider_status
+  
+  validates :name, :presence => true, :length => {:maximum => 50}, :uniqueness => true
+  validates :caption, :presence => true, :length => {:maximum => 30}
+  validates :url, :presence => true, :length => {:maximum => 200}, :url => true
+  validates :description, :presence => true
+  validates :demander_url, :presence => true, :length => {:maximum => 200}, :url => true
+  validates :provider_status_id, :presence => true, :numericality => true, :existence => true
+
+  def supply_default
+    self.provider_status_id = nil
+  end
+  
+  def overwrite
+  end
+  
+  def own? ad
+    return false unless ad
+    ad.is_a?(Admin)
+  end
+  
+  def visible? ad
+    return false unless ad
+    ad.is_a?(Admin)
+  end
+  
+  def status
+    self.provider_status.status
+  end
+  
+  def self.default_page_size
+    25
+  end
+  
+  def self.max_page_size
+    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
+    page
+  end
+  
+  def self.page_size prm = self.default_page_size
+    page_size = prm.to_i
+    page_size = self.max_page_size if page_size > self.max_page_size
+    page_size = self.default_page_size if page_size < 1
+    page_size
+  end
+  
+  def self.list page = 1, page_size = self.default_page_size
+    opt = {}
+    opt.merge!(Provider.list_opt)
+    opt.merge!({:limit => page_size, :offset => (page -1) * page_size}) if page_size > 0
+    opt.merge!({:order => 'providers.name'})
+    Provider.find(:all, opt)
+  end
+  
+  def self.available_list page = 1, page_size = self.default_page_size
+    opt = {}
+    opt.merge!(Provider.list_opt)
+    opt.merge!({:limit => page_size, :offset => (page -1) * page_size}) if page_size > 0
+    opt.merge!({:conditions => ['provider_statuses.token is null'], :order => 'providers.name'})
+    Provider.find(:all, opt)
+  end
+  
+  def self.list_opt
+    {:include => {:provider_status => {}} }
+  end
+  
+  def self.list_json_opt
+    {:include => {:provider_status => {}} }
+  end
+  
+  def self.show pid, ad
+    opt = {}
+    opt.merge!(Provider.show_opt)
+    res = Provider.find(pid, opt)
+    raise ActiveRecord::Forbidden unless res.visible?(ad)
+    res
+  end
+  
+  def self.edit pid, ad
+    opt = {}
+    opt.merge!(Provider.show_opt)
+    res = Provider.find(pid, opt)
+    raise ActiveRecord::Forbidden unless res.own?(ad)
+    res
+  end
+  
+  def self.show_opt
+    {:include => {:provider_status => {}} }
+  end
+  
+  def self.show_json_opt
+    {:include => {:provider_status => {}} }
+  end
+  
+  def self.store name, attr
+    r = Provider.modify_object name, attr
+    Provider.transaction do
+      if r.new_record?
+        ps = ProviderStatus.new
+        ps.supply_default
+        if ps.save
+          r.provider_status_id = ps.id
+        else
+          r.provider_status_id = nil
+       end
+      end
+      r.save
+    end
+    r
+  end
+  
+  def self.import urls
+    Provider.import_urls(urls) {|name, attr| Provider.store(name, attr)}
+  end
+  
+end
diff --git a/app/models/provider_status.rb b/app/models/provider_status.rb
new file mode 100644 (file)
index 0000000..0c71768
--- /dev/null
@@ -0,0 +1,107 @@
+class ProviderStatus < ActiveRecord::Base
+  has_one :provider
+  
+#  validates :token
+  validates :receive_hour1, :numericality => {:allow_blank => true}
+  validates :receive_hour2, :numericality => {:allow_blank => true}
+#  validates :received_at
+#  validates :stopped_at
+  
+  def supply_default
+  end
+  
+  def overwrite
+  end
+  
+  def own? ad
+    return false unless ad
+    ad.is_a?(Admin)
+  end
+  
+  def visible? ad
+    return false unless ad
+    ad.is_a?(Admin)
+  end
+  
+  def status
+    self.token.blank? ? 0 : 1
+  end
+  
+  def self.default_page_size
+    25
+  end
+  
+  def self.max_page_size
+    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
+    page
+  end
+  
+  def self.page_size prm = self.default_page_size
+    page_size = prm.to_i
+    page_size = self.max_page_size if page_size > self.max_page_size
+    page_size = self.default_page_size if page_size < 1
+    page_size
+  end
+  
+  def self.list page = 1, page_size = self.default_page_size
+    opt = {}
+    opt.merge!(ProviderStatus.list_opt)
+    opt.merge!({:limit => page_size, :offset => (page -1) * page_size}) if page_size > 0
+    opt.merge!({:order => 'providers.name'})
+    ProviderStatus.find(:all, opt)
+  end
+  
+  def self.available_list page = 1, page_size = self.default_page_size
+    opt = {}
+    opt.merge!(ProviderStatus.list_opt)
+    opt.merge!({:limit => page_size, :offset => (page -1) * page_size}) if page_size > 0
+    opt.merge!({:conditions => ['provider_statuses.token is null'], :order => 'providers.name'})
+    ProviderStatus.find(:all, opt)
+  end
+  
+  def self.list_opt
+    {:include => {:provider => {}} }
+  end
+  
+  def self.list_json_opt
+    {:include => {:provider => {}} }
+  end
+  
+  def self.show pid, ad
+    opt = {}
+    opt.merge!(ProviderStatus.show_opt)
+    res = ProviderStatus.find(pid, opt)
+    raise ActiveRecord::Forbidden unless res.visible?(ad)
+    res
+  end
+  
+  def self.edit pid, ad
+    opt = {}
+    opt.merge!(ProviderStatus.show_opt)
+    res = ProviderStatus.find(pid, opt)
+    raise ActiveRecord::Forbidden unless res.own?(ad)
+    res
+  end
+  
+  def self.show_opt
+    {:include => {:provider => {}} }
+  end
+  
+  def self.show_json_opt
+    {:include => {:provider => {}} }
+  end
+  
+end
index 97ced9d..7505153 100644 (file)
@@ -32,6 +32,7 @@
 <div>
   <%= link_to "browse", '/system/browse' %>
   <%= link_to "approve", '/system/waiting_list' %>
+  <%= link_to "import", '/system/import' %>
   <%= link_to "token", '/system/auth_token' %>
 </div>
 <%= yield %>
diff --git a/app/views/provider_sources/_ng.html.erb b/app/views/provider_sources/_ng.html.erb
new file mode 100644 (file)
index 0000000..24ab5bb
--- /dev/null
@@ -0,0 +1,12 @@
+<h3>
+  貸手文献の読み込みに失敗しました
+</h3>
+<p>
+  貸手文献がない、貸手文献を管理しているサーバが応答しない、ネットに接続されていない、などの理由が考えられます。
+</p>
+<p>
+  <%= exception[:message] %>
+</p>
+<p>
+  <%= exception[:location] %>
+</p>
diff --git a/app/views/provider_sources/_ok.html.erb b/app/views/provider_sources/_ok.html.erb
new file mode 100644 (file)
index 0000000..7a986a4
--- /dev/null
@@ -0,0 +1,23 @@
+<% if validations.empty? %>
+  <h3>
+    この貸手文献は正常にインポートされました
+  </h3>
+<% else %>
+  <h3>
+    この貸手文献でインポートできなかった貸手があります
+  </h3>
+  <p>
+    貸手文献が壊れている、サーバの設定が正しくない、などの理由が考えられます。
+  </p>
+  <% validations.each do |provider| %>
+    <%= h provider.name -%>(<%= h provider.caption -%>)
+    <div id="error_explanation">
+      <h2><%= pluralize(provider.errors.count, "error") %></h2>
+      <ul>
+      <% provider.errors.full_messages.each do |msg| %>
+        <li><%= msg %></li>
+      <% end %>
+      </ul>
+    </div>
+  <% end %>
+<% end %>
diff --git a/app/views/provider_sources/import.html.erb b/app/views/provider_sources/import.html.erb
new file mode 100644 (file)
index 0000000..c7f5a7f
--- /dev/null
@@ -0,0 +1,15 @@
+<h1>Result Importing</h1>
+<%= @results.size %>件の貸手文献をインポートしました。
+
+<% @results.each do |url, result| %>
+  <h2>
+    <%= link_to h(url), url %>
+  </h2>
+  <% if result[:validations] %>
+    <%= render 'ok', :validations => result[:validations] %>
+  <% elsif result[:exception] %>
+    <%= render 'ng', :exception => result[:exception] %>
+  <% else %>
+    Undefined result
+  <% end %>
+<% end %>
diff --git a/app/views/provider_sources/index.html.erb b/app/views/provider_sources/index.html.erb
new file mode 100644 (file)
index 0000000..900b2e1
--- /dev/null
@@ -0,0 +1,15 @@
+<h1>Listing Provider Sources</h1>
+
+<table>
+  <tr>
+    <th>url</th>
+  </tr>
+  <% @urls.each do |url| %>
+    <tr>
+      <td><%= link_to h(url), url %></td>
+    </tr>
+  <% end %>
+</table>
+<%= form_tag({:controller => 'provider_sources',:action => "import"}, {:method => :post}) do %>
+  <%= submit_tag 'import' -%>
+<% end -%>
diff --git a/app/views/provider_statuses/_basic.html.erb b/app/views/provider_statuses/_basic.html.erb
new file mode 100644 (file)
index 0000000..a82e895
--- /dev/null
@@ -0,0 +1,4 @@
+<p>
+received_at
+<%= l(provider_status.received_at) if provider_status.received_at %>
+</p>
diff --git a/app/views/provider_statuses/_form.html.erb b/app/views/provider_statuses/_form.html.erb
new file mode 100644 (file)
index 0000000..fd02b24
--- /dev/null
@@ -0,0 +1,32 @@
+<%= form_for(@provider_status) do |f| %>
+  <% if @provider_status.errors.any? %>
+    <div id="error_explanation">
+      <h2><%= pluralize(@provider_status.errors.count, "error") %> prohibited this comic from being saved:</h2>
+
+      <ul>
+      <% @provider_status.errors.full_messages.each do |msg| %>
+        <li><%= msg %></li>
+      <% end %>
+      </ul>
+    </div>
+  <% end %>
+
+  <div class="field">
+    <p>
+      <%= f.label :token %><br />
+      <%= f.text_field :token %>
+    </p>
+    <p>
+      <%= f.label :receive_hour1 %><br />
+      <%= f.number_field :receive_hour1 %>
+    </p>
+    <p>
+      <%= f.label :receive_hour2 %><br />
+      <%= f.number_field :receive_hour2 %>
+    </p>
+  </div>
+
+  <div class="actions">
+    <%= f.submit %>
+  </div>
+<% end %>
diff --git a/app/views/provider_statuses/_provider.html.erb b/app/views/provider_statuses/_provider.html.erb
new file mode 100644 (file)
index 0000000..113f18c
--- /dev/null
@@ -0,0 +1,16 @@
+<p>
+caption
+<%= h(provider.caption) %>
+</p>
+<p>
+name
+<%= h(provider.name) %>
+</p>
+<p>
+description
+<%= h(provider.description) %>
+</p>
+<p>
+status
+<%= h(MagicNumber['provider_status_items'][provider.provider_status.status].first) %>
+</p>
diff --git a/app/views/provider_statuses/edit.html.erb b/app/views/provider_statuses/edit.html.erb
new file mode 100644 (file)
index 0000000..a525d00
--- /dev/null
@@ -0,0 +1,7 @@
+<h1>借受</h1>
+<p id="notice"><%= notice %></p>
+
+<%= render 'provider', :provider => @provider_status.provider %>
+<%= render 'basic', :provider_status => @provider_status %>
+<%= render 'form' %>
+
diff --git a/app/views/provider_statuses/index.html.erb b/app/views/provider_statuses/index.html.erb
new file mode 100644 (file)
index 0000000..1347e58
--- /dev/null
@@ -0,0 +1,48 @@
+<h1>借受状況一覧</h1>
+<table>
+  <tr>
+    <th>caption</th>
+    <th>name</th>
+    <th>status</th>
+    <th>received_at</th>
+    <th>receive_hour1</th>
+    <th>receive_hour2</th>
+    <th>開く</th>
+  </tr>
+  
+  <% @provider_statuses.each do |provider_status| %>
+    <tr>
+      <td>
+        <%= link_to h(truncate(provider_status.provider.caption, :length => 20)), provider_status_path(provider_status.provider) %>
+      </td>
+      <td>
+        <%= h(truncate(provider_status.provider.name, :length => 12)) %>
+      </td>
+      <td>
+        <%= h(MagicNumber['provider_status_items'][provider_status.status].first) %>
+      </td>
+      <td>
+        <%= l(provider_status.received_at) if provider_status.received_at  %>
+      </td>
+      <td>
+        <%= l(provider_status.receive_hour1) if provider_status.receive_hour1 %>
+      </td>
+      <td>
+        <%= l(provider_status.receive_hour2) if provider_status.receive_hour2 %>
+      </td>
+      <td>
+        <%= link_to '開く', provider_status.provider.demander_url %>
+      </td>
+    </tr>
+  <% end %>
+</table>
+<div>
+<% if @hide.blank? %>
+  <%= link_to '待機中の貸手の借受状況だけを表示する', provider_statuses_path(:hide => 1) %>
+<% else %>
+  <%= link_to 'すべての貸手の借受状況を表示する', provider_statuses_path %>
+<% end %>
+</div>
+<div>
+  <%= link_to '貸手に切り替える', providers_path(:page => @page, :page_size => @page_size, :hide => @hide) %>
+</div>
diff --git a/app/views/provider_statuses/show.html.erb b/app/views/provider_statuses/show.html.erb
new file mode 100644 (file)
index 0000000..8195faa
--- /dev/null
@@ -0,0 +1,38 @@
+<h1>借受状況</h1>
+<p id="notice"><%= notice %></p>
+
+<%= render 'provider', :provider => @provider_status.provider %>
+<%= render 'basic', :provider_status => @provider_status %>
+
+<p>
+token
+<%= h(@provider_status.token) %>
+</p>
+<p>
+receive_hour1
+<%= h(@provider_status.receive_hour1) if @provider_status.receive_hour1 %>
+</p>
+<p>
+receive_hour2
+<%= h(@provider_status.receive_hour2) if @provider_status.receive_hour2 %>
+</p>
+<p>
+  <%= link_to '貸手', providers_path(@provider_status.provider) %>
+</p>
+
+<p>
+  <%= link_to 'サイトの借手向けページを開く', @provider_status.provider.demander_url %>
+</p>
+
+<p>
+  借受するには借手となって借受申請する。 
+</p>
+<p>
+  <% if @provider_status.status == 0 %>
+    <%= link_to 'この貸手からの借受を開始する', edit_provider_status_path(@provider_status) %>
+  <% else %>
+    <%= link_to '借受を停止する', destroy_provider_status_path(@provider_status) %>
+  <% end %>
+</p>
+<%= link_to 'Back', provider_statuses_path %>
+
diff --git a/app/views/providers/index.html.erb b/app/views/providers/index.html.erb
new file mode 100644 (file)
index 0000000..e55ff37
--- /dev/null
@@ -0,0 +1,40 @@
+<h1>貸手一覧</h1>
+<table>
+  <tr>
+    <th>caption</th>
+    <th>name</th>
+    <th>description</th>
+    <th>status</th>
+    <th>開く</th>
+  </tr>
+  
+  <% @providers.each do |provider| %>
+    <tr>
+      <td>
+        <%= link_to h(truncate(provider.caption, :length => 20)), provider_path(provider) %>
+      </td>
+      <td>
+        <%= h(truncate(provider.name, :length => 12)) %>
+      </td>
+      <td>
+        <%= h(truncate(provider.description, :length => 30)) %>
+      </td>
+      <td>
+        <%= link_to h(MagicNumber['provider_status_items'][provider.status].first), provider_status_path(provider.provider_status) %>
+      </td>
+      <td>
+        <%= link_to '開く', provider.url %>
+      </td>
+    </tr>
+  <% end %>
+</table>
+<div>
+<% if @hide.blank? %>
+  <%= link_to '待機中の貸手だけを表示する', providers_path(:hide => 1) %>
+<% else %>
+  <%= link_to 'すべての貸手を表示する', providers_path %>
+<% end %>
+</div>
+<div>
+  <%= link_to '借受状況に切り替える', provider_statuses_path(:page => @page, :page_size => @page_size, :hide => @hide) %>
+</div>
diff --git a/app/views/providers/show.html.erb b/app/views/providers/show.html.erb
new file mode 100644 (file)
index 0000000..2d0a458
--- /dev/null
@@ -0,0 +1,42 @@
+<h1>貸手</h1>
+<p id="notice"><%= notice %></p>
+
+<p>
+caption
+<%= h(@provider.caption) %>
+</p>
+<p>
+name
+<%= h(@provider.name) %>
+</p>
+<p>
+url
+<%= @provider.url %>
+</p>
+<p>
+status
+<%= h(MagicNumber['provider_status_items'][@provider.provider_status.status].first) %>
+</p>
+<p>
+description 
+<%= h(@provider.description) %>
+</p>
+
+<p>
+  <%= link_to 'サイトを開く', @provider.url %>
+</p>
+<p>
+  <%= link_to '貸手を開く', @provider.demander_url %>
+</p>
+<p>
+  <%= link_to '借受状況', provider_status_path(@provider.provider_status) %>
+</p>
+<p>
+  <% if @provider.status == 0 %>
+    <%= link_to '貸手を削除する', providers_path %>
+  <% else %>
+  <% end %>
+</p>
+
+<%= link_to 'Back', providers_path %>
+
diff --git a/app/views/system/import.html.erb b/app/views/system/import.html.erb
new file mode 100644 (file)
index 0000000..45f72e3
--- /dev/null
@@ -0,0 +1,17 @@
+<div>
+ <p class="notice"><%= notice %></p>
+ <p class="alert"><%= alert %></p>
+<h1>貸手</h1>
+<table>
+  <tr>
+    <td>
+      <%= link_to '貸手文献', provider_sources_path %>
+    </td>
+  </tr>
+  <tr>
+    <td>
+      <%= link_to '貸手', providers_path %>
+    </td>
+  </tr>
+</table>
+</div>
index de0a7b4..fe42478 100644 (file)
@@ -3,6 +3,8 @@
   thumbnail_width: 64
   thumbnail_height: 64
 
+  provider_status_items: [['waiting', 0], ['receiving', 1]]
+  
   comic_visible_items: [['private', 0], ['public', 1]]
   ground_picture_repeat_items: ['repeat', 'repeat-x', 'repeat-y', 'no-repeat']
 
index ac3e8d8..3647ec2 100644 (file)
@@ -235,7 +235,39 @@ Pettanr::Application.routes.draw do
       delete :destroy
     end
   end
-
+  resources :provider_sources do
+    collection do
+      get :index
+      post :import
+      get :list
+      get :browse
+    end
+    member do
+    end
+  end
+  resources :providers do
+    collection do
+      get :index
+      get :show
+      get :list
+      get :browse
+    end
+    member do
+    end
+  end
+  resources :provider_statuses do
+    collection do
+      get :index
+      get :show
+      get :list
+      get :browse
+    end
+    member do
+      get :edit
+      put :update
+      delete :destroy
+    end
+  end
   # The priority is based upon order of creation:
   # first created -> highest priority.
 
diff --git a/db/migrate/20121111060613_create_providers.rb b/db/migrate/20121111060613_create_providers.rb
new file mode 100644 (file)
index 0000000..0a86e6a
--- /dev/null
@@ -0,0 +1,14 @@
+class CreateProviders < ActiveRecord::Migration
+  def change
+    create_table :providers do |t|
+      t.integer :provider_status_id, :null => false, :default => 0
+      t.string :name, :null => false, :limit => 50
+      t.string :caption, :null => false, :limit => 30
+      t.string :url, :null => false
+      t.string :description, :null => false
+      t.string :demander_url, :null => false
+
+      t.timestamps
+    end
+  end
+end
diff --git a/db/migrate/20121116024837_create_provider_statuses.rb b/db/migrate/20121116024837_create_provider_statuses.rb
new file mode 100644 (file)
index 0000000..97d64bd
--- /dev/null
@@ -0,0 +1,13 @@
+class CreateProviderStatuses < ActiveRecord::Migration
+  def change
+    create_table :provider_statuses do |t|
+      t.string :token
+      t.integer :receive_hour1
+      t.integer :receive_hour2
+      t.datetime :received_at
+      t.datetime :stopped_at
+
+      t.timestamps
+    end
+  end
+end
diff --git a/spec/controllers/provider_sources_controller_spec.rb b/spec/controllers/provider_sources_controller_spec.rb
new file mode 100644 (file)
index 0000000..6f0301c
--- /dev/null
@@ -0,0 +1,109 @@
+# -*- encoding: utf-8 -*-
+require 'spec_helper'
+#貸手文献
+
+describe ProviderSourcesController do
+  before do
+    @admin = FactoryGirl.create :admin
+    @sp = FactoryGirl.create :system_picture
+    @lg = FactoryGirl.create :license_group
+    @license = FactoryGirl.create :license, :license_group_id => @lg.id, :system_picture_id => @sp.id
+    @user = FactoryGirl.create :user_yas
+    @author = @user.author    #ユーザ作成時に連動して作成される
+  end
+  
+  describe '一覧表示に於いて' do
+    before do
+      sign_in @admin
+    end
+    context '事前チェックする' do
+    end
+    context 'つつがなく終わるとき' do
+      it 'ステータスコード200 OKを返す' do
+        get :index
+        response.should be_success 
+      end
+      it '@urlsにリストを取得している' do
+        get :index
+        assigns(:urls).should eq MagicNumber['provider_sources']
+      end
+      context 'html形式' do
+        it 'indexテンプレートを描画する' do
+          get :index
+          response.should render_template("index")
+        end
+      end
+      context 'json形式' do
+      end
+    end
+    context '管理者権限がないとき' do
+      before do
+        sign_out @admin
+      end
+      context 'html形式' do
+        it 'ステータスコード302 Foundを返す' do
+          get :index
+          response.status.should eq 302
+        end
+        it 'サインインページへ遷移する' do
+          get :index
+          response.should redirect_to '/admins/sign_in'
+        end
+      end
+      context 'json形式' do
+      end
+    end
+  end
+  
+  describe 'インポートに於いて' do
+    before do
+      sign_in @admin
+      @ps = MagicNumber['provider_sources']
+      @results = @ps.map {|u| {u => {:validations => []}}}
+      Provider.stub(:import).with(@ps).and_return @results
+    end
+    context '事前チェックする' do
+      it '貸手モデルに文献からのインポートを依頼している' do
+        Provider.should_receive(:import).with(@ps).exactly(1)
+        post :import
+      end
+    end
+    context 'つつがなく終わるとき' do
+      it 'ステータスコード200 OKを返す' do
+        post :import
+        response.should be_success 
+      end
+      it '@resultsにインポート結果を取得している' do
+        post :import
+        assigns(:results).should eq @results
+      end
+      context 'html形式' do
+        it 'importテンプレートを描画する' do
+          post :import
+          response.should render_template("import")
+        end
+      end
+      context 'json形式' do
+      end
+    end
+    context '管理者権限がないとき' do
+      before do
+        sign_out @admin
+      end
+      context 'html形式' do
+        it 'ステータスコード302 Foundを返す' do
+          post :import
+          response.status.should eq 302
+        end
+        it 'サインインページへ遷移する' do
+          post :import
+          response.should redirect_to '/admins/sign_in'
+        end
+      end
+      context 'json形式' do
+      end
+    end
+  end
+  
+
+end
diff --git a/spec/controllers/provider_statuses_controller_spec.rb b/spec/controllers/provider_statuses_controller_spec.rb
new file mode 100644 (file)
index 0000000..e13ec8e
--- /dev/null
@@ -0,0 +1,377 @@
+# -*- encoding: utf-8 -*-
+#借受状況
+require 'spec_helper'
+
+describe ProviderStatusesController do
+  before do
+    @admin = FactoryGirl.create :admin
+    @sp = FactoryGirl.create :system_picture
+    @lg = FactoryGirl.create :license_group
+    @license = FactoryGirl.create :license, :license_group_id => @lg.id, :system_picture_id => @sp.id
+    @user = FactoryGirl.create :user_yas
+    @author = @user.author    #ユーザ作成時に連動して作成される
+  end
+  
+  describe '一覧表示に於いて' do
+    before do
+      @ps = FactoryGirl.create :provider_status
+      @provider = FactoryGirl.create :provider, :provider_status_id => @ps.id
+      ProviderStatus.stub(:list).and_return([@ps, @ps, @ps])
+      ProviderStatus.stub(:available_list).and_return([@ps, @ps])
+      sign_in @admin
+    end
+    context '事前チェックする' do
+      it '与えられたpageがセットされている' do
+        get :index, :page => 5
+        assigns(:page).should eq 5
+      end
+      it '省略されると@pageに1値が入る' do
+        get :index
+        assigns(:page).should eq 1
+      end
+      it '与えられたpage_sizeがセットされている' do
+        get :index, :page_size => 15
+        assigns(:page_size).should eq 15
+      end
+      it '省略されると@page_sizeにデフォルト値が入る' do
+        get :index
+        assigns(:page_size).should eq ProviderStatus.default_page_size
+      end
+      it '最大を超えると@page_sizeにデフォルト最大値が入る' do
+        get :index, :page_size => 1500
+        assigns(:page_size).should eq ProviderStatus.max_page_size
+      end
+      it '不正な値が入ると@page_sizeにデフォルト最大値が入る' do
+        get :index, :page_size => 0
+        assigns(:page_size).should eq ProviderStatus.default_page_size
+      end
+    end
+    context 'つつがなく終わるとき' do
+      it 'ステータスコード200 OKを返す' do
+        get :index
+        response.should be_success 
+      end
+      it '@hideが空になっている' do
+        get :index
+        assigns(:hide).should be_blank
+      end
+      it '借受状況モデルに全一覧取得を問い合わせている' do
+        ProviderStatus.should_receive(:list).exactly(1)
+        get :index
+      end
+      it '@provider_statusesにリストを取得している' do
+        get :index
+        assigns(:provider_statuses).should have_at_least(3).items
+      end
+      context 'html形式' do
+        it 'indexテンプレートを描画する' do
+          get :index
+          response.should render_template("index")
+        end
+      end
+      context 'json形式' do
+        it 'jsonデータを返す' do
+          get :index, :format => :json
+          lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError)
+        end
+        it '借受状況モデルにjson一覧出力オプションを問い合わせている' do
+          ProviderStatus.should_receive(:list_json_opt).exactly(1)
+          get :index, :format => :json
+        end
+        it 'データがリスト構造になっている' do
+          get :index, :format => :json
+          json = JSON.parse response.body
+          json.should have_at_least(3).items
+        end
+        it 'リストの先頭くらいは借受状況っぽいものであって欲しい' do
+          get :index, :format => :json
+          json = JSON.parse response.body
+          json.first.has_key?("token").should be_true
+          json.first.has_key?("receive_hour1").should be_true
+          json.first.has_key?("receive_hour2").should be_true
+          json.first.has_key?("received_at").should be_true
+        end
+      end
+    end
+    context '除外フラグが除外のとき' do
+      it '@hideが設定されている' do
+        get :index, :hide => 1
+        assigns(:hide).should_not be_blank
+      end
+      it '借受状況モデルに待機中一覧取得を問い合わせている' do
+        ProviderStatus.should_receive(:available_list).exactly(1)
+        get :index, :hide => 1
+      end
+      it '@provider_statusesにリストを取得している' do
+        get :index, :hide => 1
+        assigns(:provider_statuses).should have_at_least(2).items
+      end
+    end
+    context '管理者権限がないとき' do
+      before do
+        sign_out @admin
+      end
+      context 'html形式' do
+        it 'ステータスコード302 Foundを返す' do
+          get :index
+          response.status.should eq 302
+        end
+        it 'サインインページへ遷移する' do
+          get :index
+          response.should redirect_to '/admins/sign_in'
+        end
+      end
+      context 'json形式' do
+        it 'ステータスコード401 Unauthorizedを返す' do
+          get :index, :format => :json
+          response.status.should eq 401
+        end
+        it '応答メッセージにUnauthorizedを返す' do
+          get :index, :format => :json
+          response.message.should match(/Unauthorized/)
+        end
+      end
+    end
+  end
+  
+  describe '単体表示に於いて' do
+    before do
+      @ps = FactoryGirl.create :provider_status
+      @provider = FactoryGirl.create :provider, :provider_status_id => @ps.id
+      ProviderStatus.stub(:show).and_return(@ps)
+      sign_in @admin
+    end
+    context 'つつがなく終わるとき' do
+      it 'ステータスコード200 OKを返す' do
+        get :show, :id => @ps.id
+        response.should be_success
+      end
+      it '借受状況モデルに単体取得を問い合わせている' do
+        ProviderStatus.should_receive(:show).exactly(1)
+        get :show
+      end
+      it '@provider_statusにアレを取得している' do
+        get :show, :id => @ps.id
+        assigns(:provider_status).should eq(@ps)
+      end
+      context 'html形式' do
+        it 'showテンプレートを描画する' do
+          get :show, :id => @ps.id
+          response.should render_template("show")
+        end
+      end
+      context 'json形式' do
+        it 'jsonデータを返す' do
+          get :show, :id => @ps.id, :format => :json
+          lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError)
+        end
+        it '借受状況モデルにjson単体出力オプションを問い合わせている' do
+          ProviderStatus.should_receive(:show_json_opt).exactly(1)
+          get :show, :id => @ps.id, :format => :json
+        end
+        it 'データがアレになっている' do
+          get :show, :id => @ps.id, :format => :json
+          json = JSON.parse response.body
+          json.has_key?("token").should be_true
+          json.has_key?("receive_hour1").should be_true
+          json.has_key?("receive_hour2").should be_true
+          json.has_key?("received_at").should be_true
+        end
+      end
+    end
+    context '管理者権限がないとき' do
+      before do
+        sign_out @admin
+      end
+      context 'html形式' do
+        it 'ステータスコード302 Foundを返す' do
+          get :show, :id => @ps.id
+          response.status.should eq 302
+        end
+        it 'サインインページへ遷移する' do
+          get :show, :id => @ps.id
+          response.body.should redirect_to '/admins/sign_in'
+        end
+      end
+      context 'json形式' do
+        it 'ステータスコード401 Unauthorizedを返す' do
+          get :show, :id => @ps.id, :format => :json
+          response.status.should eq 401
+        end
+        it '応答メッセージにUnauthorizedを返す' do
+          get :show, :id => @ps.id, :format => :json
+          response.message.should match(/Unauthorized/)
+        end
+      end
+    end
+  end
+  
+  describe '編集フォーム表示に於いて' do
+    before do
+      @ps = FactoryGirl.create :provider_status
+      @provider = FactoryGirl.create :provider, :provider_status_id => @ps.id
+      sign_in @admin
+      ProviderStatus.stub(:edit).with(@ps.id.to_s, @admin).and_return(@ps)
+    end
+    context 'つつがなく終わるとき' do
+      it 'ステータスコード200 OKを返す' do
+        get :edit, :id => @ps.id
+        response.should be_success 
+      end
+      it '借受状況モデルに編集取得を問い合わせている' do
+        ProviderStatus.should_receive(:edit).exactly(1)
+        get :edit, :id => @ps.id
+      end
+      it '@provider_statusにデータを用意している' do
+        get :edit, :id => @ps.id
+        assigns(:provider_status).should eq @ps
+      end
+      context 'html形式' do
+        it 'editテンプレートを描画する' do
+          get :edit, :id => @ps.id
+          response.should render_template("edit")
+        end
+      end
+      context 'js形式' do
+        it 'edit.jsテンプレートを描画する' do
+          get :edit, :id => @ps.id, :format => :js
+          response.should render_template("edit")
+        end
+      end
+    end
+    context '管理者権限がないとき' do
+      before do
+        sign_out @admin
+      end
+      context 'html形式' do
+        it 'ステータスコード302 Foundを返す' do
+          get :edit, :id => @ps.id
+          response.status.should eq 302
+        end
+        it 'サインインページへ遷移する' do
+          get :edit, :id => @ps.id
+          response.body.should redirect_to '/admins/sign_in'
+        end
+      end
+      context 'js形式' do
+        it 'ステータスコード401 Unauthorizedを返す' do
+          get :edit, :id => @ps.id, :format => :js
+          response.status.should eq 401
+        end
+        it '応答メッセージにUnauthorizedを返す' do
+          get :edit, :id => @ps.id, :format => :js
+          response.message.should match(/Unauthorized/)
+        end
+      end
+    end
+  end
+
+  describe '更新に於いて' do
+    before do
+      @ps = FactoryGirl.create :provider_status
+      @attr = FactoryGirl.attributes_for(:provider_status, :receive_hour1 => 22)
+      sign_in @admin
+    end
+    context '事前チェックしておく' do
+      it '借受状況モデルに編集取得を問い合わせている' do
+        ProviderStatus.stub(:edit).with(any_args()).and_return @ps
+        ProviderStatus.should_receive(:edit).exactly(1)
+        put :update, :id => @ps.id, :provider_status => @attr
+      end
+      it '借受状況モデルにカラム値復元を依頼している' do
+        ProviderStatus.any_instance.should_receive(:attributes=).exactly(1)
+        put :update, :id => @ps.id, :provider_status => @attr
+      end
+      it '借受状況モデルに上書き補充を依頼している' do
+        ProviderStatus.any_instance.should_receive(:overwrite).exactly(1)
+        put :update, :id => @ps.id, :provider_status => @attr
+      end
+      it 'モデルに更新を依頼する' do
+        ProviderStatus.any_instance.stub(:save).with(any_args).and_return true
+        ProviderStatus.any_instance.should_receive(:save).exactly(1)
+        put :update, :id => @ps.id, :provider_status => @attr
+      end
+      it '@provider_statusにアレを取得している' do
+        put :update, :id => @ps.id, :provider_status => @attr
+        assigns(:provider_status).id.should eq(@ps.id)
+      end
+    end
+    context 'つつがなく終わるとき' do
+      it '更新される' do
+        put :update, :id => @ps.id, :provider_status => @attr
+        ProviderStatus.find(@ps.id).receive_hour1.should eq 22
+      end
+      context 'html形式' do
+        it 'ステータスコード302 Foundを返す' do
+          ProviderStatus.any_instance.stub(:save).with(any_args()).and_return(true)
+          put :update, :id => @ps.id, :provider_status => @attr
+          response.status.should eq 302
+        end
+        it '更新された借受状況の表示ページへ遷移する' do
+          put :update, :id => @ps.id, :provider_status => @attr
+          response.should redirect_to(@ps)
+        end
+      end
+      context 'json形式' do
+        it 'ステータスコード200 OKを返す' do
+          ProviderStatus.any_instance.stub(:save).with(any_args()).and_return(true)
+          put :update, :id => @ps.id, :provider_status => @attr, :format => :json
+          response.should be_success 
+        end
+        it 'ページ本体は特に返さない' do
+          ProviderStatus.any_instance.stub(:save).with(any_args()).and_return(true)
+          put :update, :id => @ps.id, :provider_status => @attr, :format => :json
+          response.body.should match /./
+        end
+      end
+    end
+    context '管理者権限がないとき' do
+      before do
+        sign_out @admin
+      end
+      it 'ステータスコード302 Foundを返す' do
+        put :update, :id => @ps.id, :provider_status => @attr
+        response.status.should eq 302
+      end
+      context 'html形式' do
+        it 'サインインページへ遷移する' do
+          put :update, :id => @ps.id, :provider_status => @attr
+          response.body.should redirect_to '/admins/sign_in'
+        end
+      end
+      context 'json形式' do
+        it '応答メッセージにUnauthorizedを返す' do
+          put :update, :id => @ps.id, :provider_status => @attr, :format => :json
+          response.message.should match(/Unauthorized/)
+        end
+      end
+    end
+    context '検証、保存に失敗したとき' do
+      before do
+        ProviderStatus.any_instance.stub(:save).and_return(false)
+      end
+      context 'html形式' do
+        it 'ステータスコード200 Okを返す' do
+          put :update, :id => @ps.id, :provider_status => @attr
+          response.status.should eq 200
+        end
+        it '編集ページを描画する' do
+          put :update, :id => @ps.id, :provider_status => @attr
+          response.should render_template("edit")
+        end
+      end
+      context 'json形式' do
+        it 'ステータスコード422 unprocessable_entity を返す' do
+          ProviderStatus.any_instance.stub(:save).and_return(false)
+          put :update, :id => @ps.id, :provider_status => @attr, :format => :json
+          response.status.should eq 422
+        end
+        it '応答メッセージUnprocessable Entityを返す' do
+          put :update, :id => @ps.id, :provider_status => @attr, :format => :json
+          response.message.should match(/Unprocessable/)
+        end
+      end
+    end
+  end
+
+end
diff --git a/spec/controllers/providers_controller_spec.rb b/spec/controllers/providers_controller_spec.rb
new file mode 100644 (file)
index 0000000..75b4103
--- /dev/null
@@ -0,0 +1,209 @@
+# -*- encoding: utf-8 -*-
+require 'spec_helper'
+#貸手
+
+describe ProvidersController do
+  before do
+    @admin = FactoryGirl.create :admin
+    @sp = FactoryGirl.create :system_picture
+    @lg = FactoryGirl.create :license_group
+    @license = FactoryGirl.create :license, :license_group_id => @lg.id, :system_picture_id => @sp.id
+    @user = FactoryGirl.create :user_yas
+    @author = @user.author    #ユーザ作成時に連動して作成される
+  end
+  
+  describe '一覧表示に於いて' do
+    before do
+      @ps = FactoryGirl.create :provider_status
+      @provider = FactoryGirl.create :provider, :provider_status_id => @ps.id
+      Provider.stub(:list).and_return([@provider, @provider, @provider])
+      Provider.stub(:available_list).and_return([@provider, @provider])
+      sign_in @admin
+    end
+    context '事前チェックする' do
+      it '与えられたpageがセットされている' do
+        get :index, :page => 5
+        assigns(:page).should eq 5
+      end
+      it '省略されると@pageに1値が入る' do
+        get :index
+        assigns(:page).should eq 1
+      end
+      it '与えられたpage_sizeがセットされている' do
+        get :index, :page_size => 15
+        assigns(:page_size).should eq 15
+      end
+      it '省略されると@page_sizeにデフォルト値が入る' do
+        get :index
+        assigns(:page_size).should eq Provider.default_page_size
+      end
+      it '最大を超えると@page_sizeにデフォルト最大値が入る' do
+        get :index, :page_size => 1500
+        assigns(:page_size).should eq Provider.max_page_size
+      end
+      it '不正な値が入ると@page_sizeにデフォルト最大値が入る' do
+        get :index, :page_size => 0
+        assigns(:page_size).should eq Provider.default_page_size
+      end
+    end
+    context 'つつがなく終わるとき' do
+      it 'ステータスコード200 OKを返す' do
+        get :index
+        response.should be_success 
+      end
+      it '@hideが空になっている' do
+        get :index
+        assigns(:hide).should be_blank
+      end
+      it '貸手モデルに全一覧取得を問い合わせている' do
+        Provider.should_receive(:list).exactly(1)
+        get :index
+      end
+      it '@providersにリストを取得している' do
+        get :index
+        assigns(:providers).should have_at_least(3).items
+      end
+      context 'html形式' do
+        it 'indexテンプレートを描画する' do
+          get :index
+          response.should render_template("index")
+        end
+      end
+      context 'json形式' do
+        it 'jsonデータを返す' do
+          get :index, :format => :json
+          lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError)
+        end
+        it '貸手モデルにjson一覧出力オプションを問い合わせている' do
+          Provider.should_receive(:list_json_opt).exactly(1)
+          get :index, :format => :json
+        end
+        it 'データがリスト構造になっている' do
+          get :index, :format => :json
+          json = JSON.parse response.body
+          json.should have_at_least(3).items
+        end
+        it 'リストの先頭くらいは貸手っぽいものであって欲しい' do
+          get :index, :format => :json
+          json = JSON.parse response.body
+          json.first.has_key?("name").should be_true
+          json.first.has_key?("caption").should be_true
+          json.first.has_key?("url").should be_true
+          json.first.has_key?("description").should be_true
+        end
+      end
+    end
+    context '除外フラグが除外のとき' do
+      it '@hideが設定されている' do
+        get :index, :hide => 1
+        assigns(:hide).should_not be_blank
+      end
+      it '貸手モデルに待機中一覧取得を問い合わせている' do
+        Provider.should_receive(:available_list).exactly(1)
+        get :index, :hide => 1
+      end
+      it '@providersにリストを取得している' do
+        get :index, :hide => 1
+        assigns(:providers).should have_at_least(2).items
+      end
+    end
+    context '管理者権限がないとき' do
+      before do
+        sign_out @admin
+      end
+      context 'html形式' do
+        it 'ステータスコード302 Foundを返す' do
+          get :index
+          response.status.should eq 302
+        end
+        it 'サインインページへ遷移する' do
+          get :index
+          response.should redirect_to '/admins/sign_in'
+        end
+      end
+      context 'json形式' do
+        it 'ステータスコード401 Unauthorizedを返す' do
+          get :index, :format => :json
+          response.status.should eq 401
+        end
+        it '応答メッセージにUnauthorizedを返す' do
+          get :index, :format => :json
+          response.message.should match(/Unauthorized/)
+        end
+      end
+    end
+  end
+  
+  describe '単体表示に於いて' do
+    before do
+      @ps = FactoryGirl.create :provider_status
+      @provider = FactoryGirl.create :provider, :provider_status_id => @ps.id
+      Provider.stub(:show).and_return(@provider)
+      sign_in @admin
+    end
+    context 'つつがなく終わるとき' do
+      it 'ステータスコード200 OKを返す' do
+        get :show, :id => @provider.id
+        response.should be_success
+      end
+      it '貸手モデルに単体取得を問い合わせている' do
+        Provider.should_receive(:show).exactly(1)
+        get :show
+      end
+      it '@providerにアレを取得している' do
+        get :show, :id => @provider.id
+        assigns(:provider).should eq(@provider)
+      end
+      context 'html形式' do
+        it 'showテンプレートを描画する' do
+          get :show, :id => @provider.id
+          response.should render_template("show")
+        end
+      end
+      context 'json形式' do
+        it 'jsonデータを返す' do
+          get :show, :id => @provider.id, :format => :json
+          lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError)
+        end
+        it '貸手モデルにjson単体出力オプションを問い合わせている' do
+          Provider.should_receive(:show_json_opt).exactly(1)
+          get :show, :id => @provider.id, :format => :json
+        end
+        it 'データがアレになっている' do
+          get :show, :id => @provider.id, :format => :json
+          json = JSON.parse response.body
+          json.has_key?("name").should be_true
+          json.has_key?("caption").should be_true
+          json.has_key?("url").should be_true
+          json.has_key?("description").should be_true
+        end
+      end
+    end
+    context '管理者権限がないとき' do
+      before do
+        sign_out @admin
+      end
+      context 'html形式' do
+        it 'ステータスコード302 Foundを返す' do
+          get :show, :id => @provider.id
+          response.status.should eq 302
+        end
+        it 'サインインページへ遷移する' do
+          get :show, :id => @provider.id
+          response.body.should redirect_to '/admins/sign_in'
+        end
+      end
+      context 'json形式' do
+        it 'ステータスコード401 Unauthorizedを返す' do
+          get :show, :id => @provider.id, :format => :json
+          response.status.should eq 401
+        end
+        it '応答メッセージにUnauthorizedを返す' do
+          get :show, :id => @provider.id, :format => :json
+          response.message.should match(/Unauthorized/)
+        end
+      end
+    end
+  end
+
+end
index 384ef68..5f09ea3 100644 (file)
@@ -1,3 +1,5 @@
+# -*- encoding: utf-8 -*-
+#テストデータ
 FactoryGirl.define do
   factory :admin, :class => Admin do |admin|
     admin.sequence(:email) { |n| "admin#{n}@gmail.com"}
@@ -198,4 +200,22 @@ FactoryGirl.define do
     story.author_id 1
     story.t 0
   end
+
+  factory :provider, :class => Provider do |provider|
+    provider.provider_status_id 1
+    provider.name 'admin@penguinkingdom.com'
+    provider.caption 'ペンギン王国"'
+    provider.url 'http://localhost:3000/'
+    provider.description 'ペンギン王国はペンギン素材を豊富に用意したペンギンマニアのサイトです。'
+    provider.demander_url 'http://localhost:3000/demanders'
+  end
+
+  factory :provider_status, :class => ProviderStatus do |provider_status|
+    provider_status.token nil
+    provider_status.receive_hour1 nil
+    provider_status.receive_hour2 nil
+    provider_status.received_at nil
+    provider_status.stopped_at nil
+  end
+
 end
diff --git a/spec/helpers/provider_sources_helper_spec.rb b/spec/helpers/provider_sources_helper_spec.rb
new file mode 100644 (file)
index 0000000..5046480
--- /dev/null
@@ -0,0 +1,15 @@
+require 'spec_helper'
+
+# Specs in this file have access to a helper object that includes
+# the ProviderSourcesHelper. For example:
+#
+# describe ProviderSourcesHelper do
+#   describe "string concat" do
+#     it "concats two strings with spaces" do
+#       helper.concat_strings("this","that").should == "this that"
+#     end
+#   end
+# end
+describe ProviderSourcesHelper do
+  pending "add some examples to (or delete) #{__FILE__}"
+end
diff --git a/spec/helpers/provider_statuses_helper_spec.rb b/spec/helpers/provider_statuses_helper_spec.rb
new file mode 100644 (file)
index 0000000..8d0e311
--- /dev/null
@@ -0,0 +1,15 @@
+require 'spec_helper'
+
+# Specs in this file have access to a helper object that includes
+# the ProviderStatusesHelper. For example:
+#
+# describe ProviderStatusesHelper do
+#   describe "string concat" do
+#     it "concats two strings with spaces" do
+#       helper.concat_strings("this","that").should == "this that"
+#     end
+#   end
+# end
+describe ProviderStatusesHelper do
+  pending "add some examples to (or delete) #{__FILE__}"
+end
diff --git a/spec/helpers/providers_helper_spec.rb b/spec/helpers/providers_helper_spec.rb
new file mode 100644 (file)
index 0000000..cd2a9a4
--- /dev/null
@@ -0,0 +1,15 @@
+require 'spec_helper'
+
+# Specs in this file have access to a helper object that includes
+# the ProvidersHelper. For example:
+#
+# describe ProvidersHelper do
+#   describe "string concat" do
+#     it "concats two strings with spaces" do
+#       helper.concat_strings("this","that").should == "this that"
+#     end
+#   end
+# end
+describe ProvidersHelper do
+  pending "add some examples to (or delete) #{__FILE__}"
+end
diff --git a/spec/json/provider_source.json b/spec/json/provider_source.json
new file mode 100644 (file)
index 0000000..61dcaf9
--- /dev/null
@@ -0,0 +1,8 @@
+{
+  "admin@localhost": {
+    "caption": "ペンギン王国",
+    "url": "http://localhost:3000/", 
+    "description": "ペンギン王国はペンギン素材を豊富に用意したペンギンマニアのサイトです。", 
+    "demander_url": "http://localhost:3000/demanders"
+  }
+}
index 5ffdb64..908b415 100644 (file)
@@ -100,53 +100,53 @@ describe Comic do
         before do
           MagicNumber['run_mode'] = 1
         end
-        it '不許可を返す。' do\r
+        it '不許可を返す。' do
           r = @comic.visible?(nil)
           r.should be_false
-        end\r
-      end\r
+        end
+      end
       context 'オープンモードのとき' do
         before do
           MagicNumber['run_mode'] = 0
         end
-        it '公開コミックなら許可する' do\r
-          Comic.any_instance.stub(:visible).and_return(1)\r
+        it '公開コミックなら許可する' do
+          Comic.any_instance.stub(:visible).and_return(1)
           r = @comic.visible?(nil)
           r.should be_true
-        end\r
-        it '非公開コミックなら許可しない' do\r
-          Comic.any_instance.stub(:visible).and_return(0)\r
+        end
+        it '非公開コミックなら許可しない' do
+          Comic.any_instance.stub(:visible).and_return(0)
           r = @comic.visible?(nil)
           r.should be_false
-        end\r
-      end\r
-    end\r
+        end
+      end
+    end
     context '検査対象が作家のとき' do
-      it '自分のコミックなら許可する' do\r
-        Comic.any_instance.stub(:own?).and_return(true)\r
-        Comic.any_instance.stub(:visible).and_return(0)\r
+      it '自分のコミックなら許可する' do
+        Comic.any_instance.stub(:own?).and_return(true)
+        Comic.any_instance.stub(:visible).and_return(0)
         r = @comic.visible?(@author)
         r.should == true
-      end\r
-      it '他人の非公開コミックなら許可しない' do\r
-        Comic.any_instance.stub(:own?).and_return(false)\r
-        Comic.any_instance.stub(:visible).and_return(0)\r
+      end
+      it '他人の非公開コミックなら許可しない' do
+        Comic.any_instance.stub(:own?).and_return(false)
+        Comic.any_instance.stub(:visible).and_return(0)
         r = @comic.visible?(@author)
         r.should == false
-      end\r
-      it '他人のコミックでも公開なら許可する' do\r
-        Comic.any_instance.stub(:own?).and_return(false)\r
-        Comic.any_instance.stub(:visible).and_return(1)\r
+      end
+      it '他人のコミックでも公開なら許可する' do
+        Comic.any_instance.stub(:own?).and_return(false)
+        Comic.any_instance.stub(:visible).and_return(1)
         r = @comic.visible?(@author)
         r.should == true
-      end\r
-    end\r
+      end
+    end
     context '検査対象がそれ以外のとき' do
-      it '不許可を返す。' do\r
+      it '不許可を返す。' do
         r = @comic.visible?(@admin)
         r.should be_false
-      end\r
-    end\r
+      end
+    end
   end
   
   describe '一覧取得に於いて' do
@@ -178,13 +178,13 @@ describe Comic do
         Comic.page_size('1000').should eq Comic.max_page_size
       end
     end
-    context 'つつがなく終わるとき' do\r
-      it '一覧取得オプションを利用している' do\r
-        Comic.stub(:list_opt).with(any_args).and_return({})\r
-        Comic.should_receive(:list_opt).with(any_args).exactly(1)\r
+    context 'つつがなく終わるとき' do
+      it '一覧取得オプションを利用している' do
+        Comic.stub(:list_opt).with(any_args).and_return({})
+        Comic.should_receive(:list_opt).with(any_args).exactly(1)
         r = Comic.list
-      end\r
-    end\r
+      end
+    end
     it 'リストを返す' do
       c = Comic.list
       c.should eq [@comic]
@@ -264,10 +264,10 @@ describe Comic do
   end
   describe 'json一覧出力オプションに於いて' do
     before do
-      @op = FactoryGirl.create :original_picture, :artist_id => @artist.id\r
-      @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id\r
-      @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :license_id => @license.id, :original_picture_id => @op.id, :picture_id => @p.id\r
-      @sbt = FactoryGirl.create :speech_balloon_template\r
+      @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
+      @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id
+      @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :license_id => @license.id, :original_picture_id => @op.id, :picture_id => @p.id
+      @sbt = FactoryGirl.create :speech_balloon_template
       @comic = FactoryGirl.create :comic, :author_id => @author.id, :visible => 1
       @panel = FactoryGirl.create :panel, :author_id => @author.id, :publish => 1
       @story = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id
@@ -297,13 +297,13 @@ describe Comic do
     before do
       @comic = FactoryGirl.create :comic, :author_id => @author.id
     end
-    context 'つつがなく終わるとき' do\r
-      it '一覧取得オプションを利用している' do\r
-        Comic.stub(:list_opt).with(any_args).and_return({})\r
-        Comic.should_receive(:list_opt).with(any_args).exactly(1)\r
+    context 'つつがなく終わるとき' do
+      it '一覧取得オプションを利用している' do
+        Comic.stub(:list_opt).with(any_args).and_return({})
+        Comic.should_receive(:list_opt).with(any_args).exactly(1)
         r = Comic.mylist @author
-      end\r
-    end\r
+      end
+    end
     it 'リストを返す' do
       c = Comic.mylist @author
       c.should eq [@comic]
@@ -354,7 +354,7 @@ describe Comic do
         @comic3 = FactoryGirl.create :comic, :author_id => @author.id, :updated_at => Time.now + 200
         @comic4 = FactoryGirl.create :comic, :author_id => @author.id, :updated_at => Time.now + 300
         @comic5 = FactoryGirl.create :comic, :author_id => @author.id, :updated_at => Time.now + 400
-        Author.stub(:default_comic_page_size).and_return(2)\r
+        Author.stub(:default_comic_page_size).and_return(2)
       end
       it '通常は全件(5件)を返す' do
         r = Comic.mylist @author, 5, 0
@@ -367,55 +367,55 @@ describe Comic do
     before do
       @comic = FactoryGirl.create :comic, :author_id => @author.id
     end
-    context 'つつがなく終わるとき' do\r
-      it '単体取得オプションを利用している' do\r
-        Comic.stub(:show_opt).with(any_args).and_return({})\r
-        Comic.should_receive(:show_opt).with(any_args).exactly(1)\r
+    context 'つつがなく終わるとき' do
+      it '単体取得オプションを利用している' do
+        Comic.stub(:show_opt).with(any_args).and_return({})
+        Comic.should_receive(:show_opt).with(any_args).exactly(1)
         r = Comic.show @comic.id, @author
-      end\r
-      it '閲覧許可を問い合わせている' do\r
-        Comic.any_instance.stub(:visible?).with(any_args).and_return(true)\r
-        Comic.any_instance.should_receive(:visible?).with(any_args).exactly(1)\r
+      end
+      it '閲覧許可を問い合わせている' do
+        Comic.any_instance.stub(:visible?).with(any_args).and_return(true)
+        Comic.any_instance.should_receive(:visible?).with(any_args).exactly(1)
         r = Comic.show @comic.id, @author
-      end\r
-    end\r
+      end
+    end
     it '指定のコミックを返す' do
       c = Comic.show @comic.id, @author
       c.should eq @comic
     end
-    context '閲覧許可が出なかったとき' do\r
-      it '403Forbidden例外を返す' do\r
-        Comic.any_instance.stub(:visible?).and_return(false)\r
-        lambda{\r
-          Comic.show @comic.id, @author\r
-        }.should raise_error(ActiveRecord::Forbidden)\r
-      end\r
-    end\r
-    context '存在しない作家を開こうとしたとき' do\r
-      it '404RecordNotFound例外を返す' do\r
-        lambda{\r
-          Comic.show 110, @author\r
-        }.should raise_error(ActiveRecord::RecordNotFound)\r
-      end\r
-    end\r
+    context '閲覧許可が出なかったとき' do
+      it '403Forbidden例外を返す' do
+        Comic.any_instance.stub(:visible?).and_return(false)
+        lambda{
+          Comic.show @comic.id, @author
+        }.should raise_error(ActiveRecord::Forbidden)
+      end
+    end
+    context '存在しないコミックを開こうとしたとき' do
+      it '404RecordNotFound例外を返す' do
+        lambda{
+          Comic.show 110, @author
+        }.should raise_error(ActiveRecord::RecordNotFound)
+      end
+    end
   end
   
   describe '編集取得に於いて' do
     before do
       @comic = FactoryGirl.create :comic, :author_id => @author.id
     end
-    context 'つつがなく終わるとき' do\r
-      it '単体取得オプションを利用している' do\r
-        Comic.stub(:show_opt).with(any_args).and_return({})\r
-        Comic.should_receive(:show_opt).with(any_args).exactly(1)\r
+    context 'つつがなく終わるとき' do
+      it '単体取得オプションを利用している' do
+        Comic.stub(:show_opt).with(any_args).and_return({})
+        Comic.should_receive(:show_opt).with(any_args).exactly(1)
         r = Comic.edit @comic.id, @author
-      end\r
-      it '所持判定を問い合わせている' do\r
-        Comic.any_instance.stub(:own?).with(any_args).and_return(true)\r
-        Comic.any_instance.should_receive(:own?).with(any_args).exactly(1)\r
+      end
+      it '所持判定を問い合わせている' do
+        Comic.any_instance.stub(:own?).with(any_args).and_return(true)
+        Comic.any_instance.should_receive(:own?).with(any_args).exactly(1)
         r = Comic.edit @comic.id, @author
-      end\r
-    end\r
+      end
+    end
     it '指定のコミックを返す' do
       Comic.any_instance.stub(:own?).and_return(true)
       c = Comic.edit @comic.id, @author.id
@@ -461,10 +461,10 @@ describe Comic do
   end
   describe 'json単体出力オプションに於いて' do
     before do
-      @op = FactoryGirl.create :original_picture, :artist_id => @artist.id\r
-      @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id\r
-      @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :license_id => @license.id, :original_picture_id => @op.id, :picture_id => @p.id\r
-      @sbt = FactoryGirl.create :speech_balloon_template\r
+      @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
+      @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id
+      @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :license_id => @license.id, :original_picture_id => @op.id, :picture_id => @p.id
+      @sbt = FactoryGirl.create :speech_balloon_template
       @comic = FactoryGirl.create :comic, :author_id => @author.id, :visible => 1
       @panel = FactoryGirl.create :panel, :author_id => @author.id, :publish => 1
       @story = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id
diff --git a/spec/models/provider_spec.rb b/spec/models/provider_spec.rb
new file mode 100644 (file)
index 0000000..3f87421
--- /dev/null
@@ -0,0 +1,609 @@
+# -*- encoding: utf-8 -*-
+#貸手
+require 'spec_helper'
+
+describe Provider do
+  before do
+    @admin = FactoryGirl.create :admin
+    @sp = FactoryGirl.create :system_picture
+    @lg = FactoryGirl.create :license_group
+    @license = FactoryGirl.create :license, :license_group_id => @lg.id, :system_picture_id => @sp.id
+    @user = FactoryGirl.create :user_yas
+    @author = @user.author    #ユーザ作成時に連動して作成される
+    
+    #テストデータを用意してね
+    @f = Rails.root + 'spec/json/provider_source.json'
+    @t = File.open(@f, 'r').read
+    @j = JSON.parse @t
+  end
+  describe '検証に於いて' do
+    before do
+      @ps = FactoryGirl.create :provider_status
+      @pd = FactoryGirl.build :provider, :provider_status_id => @ps.id
+    end
+    
+    context 'オーソドックスなデータのとき' do
+      it '下限データが通る' do
+        @pd.name = 'a'
+        @pd.caption = 'a'
+        @pd.url = 'http://test.jp/'
+        @pd.description = 'a'
+        @pd.demander_url = 'http://test.jp/'
+        @pd.should be_valid
+      end
+      it '上限データが通る' do
+        @pd.name = 'a'*50
+        @pd.caption = 'a'*30
+        @pd.url = 'http://test.jp/aaaaa' + 'a' * 180
+        @pd.description = 'a' * 99999
+        @pd.demander_url = 'http://test.jp/aaaaa' + 'a' * 180
+        @pd.should be_valid
+      end
+    end
+    
+    context 'provider_status_idを検証するとき' do
+      it 'nullなら失敗する' do
+        @pd.provider_status_id = nil
+        @pd.should_not be_valid
+      end
+      it '数値でなければ失敗する' do
+        @pd.provider_status_id = 'a'
+        @pd.should_not be_valid
+      end
+      it '存在する借受状況でなければ失敗する' do
+        @pd.provider_status_id = 0
+        @pd.should_not be_valid
+      end
+    end
+    context 'nameを検証するとき' do
+      it 'nullなら失敗する' do
+        @pd.name = ''
+        @pd.should_not be_valid
+      end
+      it '51文字以上なら失敗する' do
+        @pd.name = 'a'*51
+        @pd.should_not be_valid
+      end
+      it '重複していたら失敗する' do
+        l = FactoryGirl.create :provider
+        @pd.should_not be_valid
+      end
+    end
+    context 'captionを検証するとき' do
+      it 'nullなら失敗する' do
+        @pd.caption = ''
+        @pd.should_not be_valid
+      end
+      it '31文字以上なら失敗する' do
+        @pd.caption = 'a'*31
+        @pd.should_not be_valid
+      end
+    end
+    context 'urlを検証するとき' do
+      it 'nullなら失敗する' do
+        @pd.url = ''
+        @pd.should_not be_valid
+      end
+      it '201文字以上なら失敗する' do
+        @pd.url = 'http://test.jp/aaaaa' + 'a' * 181
+        @pd.should_not be_valid
+      end
+      it 'url形式でないなら失敗する' do
+        @pd.url = 'aaaaaaa'
+        @pd.should_not be_valid
+      end
+    end
+    context 'descriptionを検証するとき' do
+      it 'nullなら失敗する' do
+        @pd.description= ''
+        @pd.should_not be_valid
+      end
+    end
+    context 'demander_urlを検証するとき' do
+      it 'nullなら失敗する' do
+        @pd.demander_url = ''
+        @pd.should_not be_valid
+      end
+      it '201文字以上なら失敗する' do
+        @pd.demander_url = 'http://test.jp/aaaaa' + 'a' * 181
+        @pd.should_not be_valid
+      end
+      it 'url形式でないなら失敗する' do
+        @pd.demander_url = 'aaaaaaa'
+        @pd.should_not be_valid
+      end
+    end
+  end
+  
+  describe 'デフォルト値補充に於いて' do
+    it 'defined' do
+      @ps = FactoryGirl.create :provider_status
+      @pd = FactoryGirl.build :provider, :provider_status_id => @ps.id
+      @pd.supply_default
+    end
+  end
+  
+  describe '上書き補充に於いて' do
+    it 'defined' do
+      @ps = FactoryGirl.create :provider_status
+      @pd = FactoryGirl.build :provider, :provider_status_id => @ps.id
+      @pd.overwrite
+    end
+  end
+  
+  describe '所持判定に於いて' do
+    before do
+      @ps = FactoryGirl.create :provider_status
+      @pd = FactoryGirl.build :provider, :provider_status_id => @ps.id
+    end
+    it '管理者ならyes' do
+      @pd.own?(@admin).should == true
+    end
+    it '作家ならno' do
+      @pd.own?(@author).should == false
+    end
+    it 'パラメータが管理者でないならno' do
+      @pd.own?(nil).should == false
+    end
+  end
+  
+  describe '閲覧許可に於いて' do
+    before do
+      @ps = FactoryGirl.create :provider_status
+      @pd = FactoryGirl.build :provider, :provider_status_id => @ps.id
+    end
+    it '管理者なら許可する' do
+      r = @pd.visible?(@admin)
+      r.should == true
+    end
+    it '作家なら許可しない' do
+      r = @pd.visible?(@author)
+      r.should == false
+    end
+    it 'それ以外のとき不許可を返す。' do
+      r = @pd.visible?(nil)
+      r.should be_false
+    end
+  end
+  
+  describe '状態に於いて' do
+    before do
+      @ps = FactoryGirl.create :provider_status
+      @pd = FactoryGirl.create :provider, :provider_status_id => @ps.id
+    end
+    it '借り受けしていないのとき0を返す' do
+      ProviderStatus.any_instance.stub(:token).with(any_args).and_return(nil)
+      r = @pd.status
+      r.should eq 0
+    end
+    it '借り受けしているのとき1を返す' do
+      ProviderStatus.any_instance.stub(:token).with(any_args).and_return('a')
+      r = @pd.status
+      r.should eq 1
+    end
+  end
+  
+  describe '一覧取得に於いて' do
+    before do
+      @ps = FactoryGirl.create :provider_status
+      @pd = FactoryGirl.create :provider, :provider_status_id => @ps.id, :name => "6"
+    end
+    context 'page補正について' do
+      it '文字列から数値に変換される' do
+        Provider.page('8').should eq 8
+      end
+      it 'nilの場合は1になる' do
+        Provider.page().should eq 1
+      end
+      it '0以下の場合は1になる' do
+        Provider.page('0').should eq 1
+      end
+    end
+    context 'page_size補正について' do
+      it '文字列から数値に変換される' do
+        Provider.page_size('7').should eq 7
+      end
+      it 'nilの場合はProvider.default_page_sizeになる' do
+        Provider.page_size().should eq Provider.default_page_size
+      end
+      it '0以下の場合はProvider.default_page_sizeになる' do
+        Provider.page_size('0').should eq Provider.default_page_size
+      end
+      it 'Provider.max_page_sizeを超えた場合はProvider.max_page_sizeになる' do
+        Provider.page_size('1000').should eq Provider.max_page_size
+      end
+    end
+    context 'つつがなく終わるとき' do
+      it '一覧取得オプションを利用している' do
+        Provider.stub(:list_opt).with(any_args).and_return({})
+        Provider.should_receive(:list_opt).with(any_args).exactly(1)
+        r = Provider.list
+      end
+    end
+    it 'リストを返す' do
+      r = Provider.list
+      r.should eq [@pd]
+    end
+    it '管理名で並んでいる' do
+      v = FactoryGirl.create :provider, :name => "0"
+      r = Provider.list
+      r.should eq [v, @pd]
+    end
+    context 'DBに5件あって1ページの件数を2件に変えたとして' do
+      before do
+        @ps2 = FactoryGirl.create :provider_status
+        @pd2 = FactoryGirl.create :provider, :provider_status_id => @ps2.id, :name => "5"
+        @ps3 = FactoryGirl.create :provider_status
+        @pd3 = FactoryGirl.create :provider, :provider_status_id => @ps3.id, :name => "4"
+        @ps4 = FactoryGirl.create :provider_status
+        @pd4 = FactoryGirl.create :provider, :provider_status_id => @ps4.id, :name => "3"
+        @ps5 = FactoryGirl.create :provider_status
+        @pd5 = FactoryGirl.create :provider, :provider_status_id => @ps5.id, :name => "2"
+        Provider.stub(:default_page_size).and_return(2)
+      end
+      it '通常は2件を返す' do
+        r = Provider.list
+        r.should have(2).items 
+      end
+      it 'page=1なら末尾2件を返す' do
+        #管理名で並んでいる
+        r = Provider.list(1)
+        r.should eq [@pd5, @pd4]
+      end
+      it 'page=2なら中間2件を返す' do
+        r = Provider.list(2)
+        r.should eq [@pd3, @pd2]
+      end
+      it 'page=3なら先頭1件を返す' do
+        r = Provider.list(3)
+        r.should eq [@pd]
+      end
+    end
+    context 'DBに5件あって1ページの件数を2件に変えたとして' do
+      before do
+        @ps2 = FactoryGirl.create :provider_status
+        @pd2 = FactoryGirl.create :provider, :provider_status_id => @ps2.id, :name => "5"
+        @ps3 = FactoryGirl.create :provider_status
+        @pd3 = FactoryGirl.create :provider, :provider_status_id => @ps3.id, :name => "4"
+        @ps4 = FactoryGirl.create :provider_status
+        @pd4 = FactoryGirl.create :provider, :provider_status_id => @ps4.id, :name => "3"
+        @ps5 = FactoryGirl.create :provider_status
+        @pd5 = FactoryGirl.create :provider, :provider_status_id => @ps5.id, :name => "2"
+        Provider.stub(:default_page_size).and_return(2)
+      end
+      it '件数0は全件(5件)を返す' do
+        r = Provider.list 5, 0
+        r.should have(5).items 
+      end
+    end
+  end
+  describe '待機中一覧取得に於いて' do
+    before do
+      @ps = FactoryGirl.create :provider_status
+      @pd = FactoryGirl.create :provider, :provider_status_id => @ps.id, :name => "6"
+    end
+    context 'つつがなく終わるとき' do
+      it '一覧取得オプションを利用している' do
+        Provider.stub(:list_opt).with(any_args).and_return({:include => {:provider_status => {}} })
+        Provider.should_receive(:list_opt).with(any_args).exactly(1)
+        r = Provider.available_list
+      end
+    end
+    it 'リストを返す' do
+      r = Provider.available_list
+      r.should eq [@pd]
+    end
+    it '管理名で並んでいる' do
+      @ps2 = FactoryGirl.create :provider_status
+      v = FactoryGirl.create :provider, :name => "0", :provider_status_id => @ps2.id
+      r = Provider.available_list
+      r.should eq [v, @pd]
+    end
+    it '借受状況のトークンが設定されていない貸手に限る' do
+      @ps2 = FactoryGirl.create :provider_status, :token => 'aaaaa'
+      v = FactoryGirl.create :provider, :name => "0", :provider_status_id => @ps2.id
+      r = Provider.available_list
+      r.should eq [@pd]
+    end
+    context 'DBに5件あって1ページの件数を2件に変えたとして' do
+      before do
+        @ps2 = FactoryGirl.create :provider_status
+        @pd2 = FactoryGirl.create :provider, :provider_status_id => @ps2.id, :name => "5"
+        @ps3 = FactoryGirl.create :provider_status
+        @pd3 = FactoryGirl.create :provider, :provider_status_id => @ps3.id, :name => "4"
+        @ps4 = FactoryGirl.create :provider_status
+        @pd4 = FactoryGirl.create :provider, :provider_status_id => @ps4.id, :name => "3"
+        @ps5 = FactoryGirl.create :provider_status
+        @pd5 = FactoryGirl.create :provider, :provider_status_id => @ps5.id, :name => "2"
+        Provider.stub(:default_page_size).and_return(2)
+      end
+      it '通常は2件を返す' do
+        r = Provider.available_list
+        r.should have(2).items 
+      end
+      it 'page=1なら末尾2件を返す' do
+        #管理名で並んでいる
+        r = Provider.available_list(1)
+        r.should eq [@pd5, @pd4]
+      end
+      it 'page=2なら中間2件を返す' do
+        r = Provider.available_list(2)
+        r.should eq [@pd3, @pd2]
+      end
+      it 'page=3なら先頭1件を返す' do
+        r = Provider.available_list(3)
+        r.should eq [@pd]
+      end
+    end
+    context 'DBに5件あって1ページの件数を2件に変えたとして' do
+      before do
+        @ps2 = FactoryGirl.create :provider_status
+        @pd2 = FactoryGirl.create :provider, :provider_status_id => @ps2.id, :name => "5"
+        @ps3 = FactoryGirl.create :provider_status
+        @pd3 = FactoryGirl.create :provider, :provider_status_id => @ps3.id, :name => "4"
+        @ps4 = FactoryGirl.create :provider_status
+        @pd4 = FactoryGirl.create :provider, :provider_status_id => @ps4.id, :name => "3"
+        @ps5 = FactoryGirl.create :provider_status
+        @pd5 = FactoryGirl.create :provider, :provider_status_id => @ps5.id, :name => "2"
+        Provider.stub(:default_page_size).and_return(2)
+      end
+      it '件数0は全件(5件)を返す' do
+        r = Provider.available_list 5, 0
+        r.should have(5).items 
+      end
+    end
+  end
+  describe '一覧取得オプションに於いて' do
+    it 'includeキーを含んでいる' do
+      r = Provider.list_opt
+      r.has_key?(:include).should be_true
+    end
+    it '1つの項目を含んでいる' do
+      r = Provider.list_opt[:include]
+      r.should have(1).items
+    end
+    it '借受状況を含んでいる' do
+      r = Provider.list_opt[:include]
+      r.has_key?(:provider_status).should be_true
+    end
+  end
+  describe 'json一覧出力オプションに於いて' do
+    before do
+      @ps = FactoryGirl.create :provider_status
+      @pd = FactoryGirl.create :provider, :provider_status_id => @ps.id
+    end
+    it '借受状況を含んでいる' do
+      r = Provider.list.to_json Provider.list_json_opt
+      j = JSON.parse r
+      i = j.first
+      i.has_key?('provider_status').should be_true
+    end
+  end
+  
+  describe '単体取得に於いて' do
+    before do
+      @ps = FactoryGirl.create :provider_status
+      @pd = FactoryGirl.create :provider, :provider_status_id => @ps.id
+    end
+    context 'つつがなく終わるとき' do
+      it '単体取得オプションを利用している' do
+        Provider.stub(:show_opt).with(any_args).and_return({})
+        Provider.should_receive(:show_opt).with(any_args).exactly(1)
+        r = Provider.show @pd.id, @admin
+      end
+      it '閲覧許可を問い合わせている' do
+        Provider.any_instance.stub(:visible?).with(any_args).and_return(true)
+        Provider.any_instance.should_receive(:visible?).with(any_args).exactly(1)
+        r = Provider.show @pd.id, @admin
+      end
+    end
+    it '指定の貸手を返す' do
+      r = Provider.show @pd.id, @admin
+      r.should eq @pd
+    end
+    context '閲覧許可が出なかったとき' do
+      it '403Forbidden例外を返す' do
+        Provider.any_instance.stub(:visible?).and_return(false)
+        lambda{
+          Provider.show @pd.id, @admin
+        }.should raise_error(ActiveRecord::Forbidden)
+      end
+    end
+    context '存在しない貸手を開こうとしたとき' do
+      it '404RecordNotFound例外を返す' do
+        lambda{
+          Provider.show 110, @admin
+        }.should raise_error(ActiveRecord::RecordNotFound)
+      end
+    end
+  end
+  
+  describe '編集取得に於いて' do
+    before do
+      @ps = FactoryGirl.create :provider_status
+      @pd = FactoryGirl.create :provider, :provider_status_id => @ps.id
+    end
+    context 'つつがなく終わるとき' do
+      it '単体取得オプションを利用している' do
+        Provider.stub(:show_opt).with(any_args).and_return({})
+        Provider.should_receive(:show_opt).with(any_args).exactly(1)
+        r = Provider.edit @pd.id, @admin
+      end
+      it '所持判定を問い合わせている' do
+        Provider.any_instance.stub(:own?).with(any_args).and_return(true)
+        Provider.any_instance.should_receive(:own?).with(any_args).exactly(1)
+        r = Provider.edit @pd.id, @admin
+      end
+    end
+    it '指定の貸手を返す' do
+      Provider.any_instance.stub(:own?).and_return(true)
+      r = Provider.edit @pd.id, @admin
+      r.should eq @pd
+    end
+    context '権限がなかったとき' do
+      it '403Forbidden例外を返す' do
+        Provider.any_instance.stub(:own?).and_return(false)
+        lambda{
+          Provider.edit @pd.id, @admin
+        }.should raise_error(ActiveRecord::Forbidden)
+      end
+    end
+    context '存在しない貸手を開こうとしたとき' do
+      it '404RecordNotFound例外を返す' do
+        lambda{
+          Provider.edit 110, @admin
+        }.should raise_error(ActiveRecord::RecordNotFound)
+      end
+    end
+  end
+  describe '単体取得オプションに於いて' do
+    it 'includeキーを含んでいる' do
+      r = Provider.show_opt
+      r.has_key?(:include).should be_true
+    end
+    it '1つの項目を含んでいる' do
+      r = Provider.show_opt[:include]
+      r.should have(1).items
+    end
+    it '借受状況を含んでいる' do
+      r = Provider.show_opt[:include]
+      r.has_key?(:provider_status).should be_true
+    end
+  end
+  describe 'json単体出力オプションに於いて' do
+    before do
+      @ps = FactoryGirl.create :provider_status
+      @pd = FactoryGirl.create :provider, :provider_status_id => @ps.id
+    end
+    it '借受状況を含んでいる' do
+      r = Provider.show(@pd.id, @admin).to_json Provider.show_json_opt
+      j = JSON.parse r
+      i = j
+      i.has_key?('provider_status').should be_true
+    end
+  end
+  
+  describe '更新作成に於いて' do
+    before do
+      @ps = FactoryGirl.create :provider_status
+      @pd = FactoryGirl.build :provider, :provider_status_id => @ps.id
+      @name = @pd.name
+      @attr = @pd.attributes
+    end
+    context 'つつがなく終わるとき' do
+      before do
+      end
+      it '貸手が追加される' do
+        lambda {
+          r = Provider.store(@name, @attr)
+        }.should change Provider, :count
+      end
+      it '借受状況が作成される' do
+        lambda {
+          r = Provider.store(@name, @attr)
+        }.should change ProviderStatus, :count
+      end
+      it '貸手を返す' do
+        r = Provider.store(@name, @attr)
+        r.is_a?(Provider).should be_true
+        r.valid?.should be_true
+      end
+    end
+    context '借受状況があるとき' do
+      before do
+        @pd = FactoryGirl.create :provider, :provider_status_id => @ps.id
+        @name = @pd.name
+        @attr = @pd.attributes
+      end
+      it '貸手は変化しない' do
+        lambda {
+          r = Provider.store(@name, @attr)
+        }.should_not change Provider, :count
+      end
+      it '借受状況は変化しない' do
+        lambda {
+          r = Provider.store(@name, @attr)
+        }.should_not change ProviderStatus, :count
+      end
+    end
+    context '借受状況の作成に失敗したとき' do
+      before do
+        ProviderStatus.any_instance.stub(:save).with(any_args).and_return(false)
+      end
+      it '貸手は変化しない' do
+        lambda {
+          r = Provider.store(@name, @attr)
+        }.should_not change Provider, :count
+      end
+      it '借受状況は変化しない' do
+        lambda {
+          r = Provider.store(@name, @attr)
+        }.should_not change ProviderStatus, :count
+      end
+      it '貸手の検証は失敗している' do
+        r = Provider.store(@name, @attr)
+        r.valid?.should be_false
+      end
+    end
+  end
+  
+  describe 'インポートに於いて' do
+    before do
+      @urls = ['http://pettan.net/provider_source.json']
+    end
+    context '事前チェック' do
+      before do
+        WebMock.stub_request(:get, @urls.first).to_return(:body => @t)
+      end
+      it '貸手文献インポートを依頼する' do
+        Provider.should_receive(:import_urls).with(@urls).exactly(1)
+        Provider.stub(:import_urls).with(@urls).and_return({@urls.first => {:validations => []}})
+        Provider.import(@urls)
+      end
+      it '貸手更新を一回依頼する' do
+        Provider.stub(:store).with(any_args).and_return(Provider.new)
+        Provider.should_receive(:store).with(any_args).exactly(1)
+        Provider.import(@urls)
+      end
+    end
+    context 'つつがなく終わるとき' do
+      before do
+        WebMock.stub_request(:get, @urls.first).to_return(:body => @t)
+      end
+      it '貸手が追加される' do
+        lambda {
+          Provider.import(@urls)
+        }.should change Provider, :count
+      end
+      it '借受状況がなかったら、借受状況を作成される' do
+        lambda {
+          Provider.import(@urls)
+        }.should change ProviderStatus, :count
+      end
+      it '借受状況があるなら、借受状況は作成しない' do
+        Provider.import(@urls)
+        ProviderStatus.any_instance.should_not_receive(:save).exactly(1)
+        Provider.import(@urls)
+      end
+      it 'Hashを返す' do
+        r = Provider.import(@urls)
+        r.is_a?(Hash).should be_true
+      end
+    end
+    context '貸手作成に失敗したとき' do
+      before do
+        WebMock.stub_request(:get, @urls.first).to_return(:status => 404)
+      end
+      it '貸手の数に変化がない' do
+        lambda {
+          Provider.import(@urls)
+        }.should_not change Provider, :count
+      end
+      it 'Hashを返す' do
+        r = Provider.import(@urls)
+        r.is_a?(Hash).should be_true
+      end
+    end
+  end
+  
+end
diff --git a/spec/models/provider_status_spec.rb b/spec/models/provider_status_spec.rb
new file mode 100644 (file)
index 0000000..9e7b2ff
--- /dev/null
@@ -0,0 +1,409 @@
+# -*- encoding: utf-8 -*-
+#借受状況
+require 'spec_helper'
+
+describe ProviderStatus do
+  before do
+    @admin = FactoryGirl.create :admin
+    @sp = FactoryGirl.create :system_picture
+    @lg = FactoryGirl.create :license_group
+    @license = FactoryGirl.create :license, :license_group_id => @lg.id, :system_picture_id => @sp.id
+    @user = FactoryGirl.create :user_yas
+    @author = @user.author    #ユーザ作成時に連動して作成される
+  end
+  describe '検証に於いて' do
+    before do
+      @ps = FactoryGirl.build :provider_status
+    end
+    
+    context 'オーソドックスなデータのとき' do
+      it '下限データが通る' do
+        @ps.receive_hour1 = -99999
+        @ps.receive_hour2 = -99999
+        @ps.should be_valid
+      end
+      it '上限データが通る' do
+        @ps.receive_hour1 = 99999
+        @ps.receive_hour2 = 99999
+        @ps.should be_valid
+      end
+    end
+    
+    context 'receive_hour1を検証するとき' do
+      it '数値でなければ失敗する' do
+        @ps.receive_hour1 = 'a'
+        @ps.should_not be_valid
+      end
+    end
+    context 'receive_hour2を検証するとき' do
+      it '数値でなければ失敗する' do
+        @ps.receive_hour2 = 'a'
+        @ps.should_not be_valid
+      end
+    end
+  end
+  
+  describe 'デフォルト値補充に於いて' do
+    it 'defined' do
+      @ps = FactoryGirl.build :provider_status
+      @ps.supply_default
+    end
+  end
+  
+  describe '上書き補充に於いて' do
+    it 'defined' do
+      @ps = FactoryGirl.build :provider_status
+      @ps.overwrite
+    end
+  end
+  
+  describe '所持判定に於いて' do
+    before do
+      @ps = FactoryGirl.create :provider_status
+    end
+    it '管理者ならyes' do
+      @ps.own?(@admin).should == true
+    end
+    it '作家ならno' do
+      @ps.own?(@author).should == false
+    end
+    it 'パラメータが管理者でないならno' do
+      @ps.own?(nil).should == false
+    end
+  end
+  
+  describe '閲覧許可に於いて' do
+    before do
+      @ps = FactoryGirl.create :provider_status
+    end
+    it '管理者なら許可する' do
+      r = @ps.visible?(@admin)
+      r.should == true
+    end
+    it '作家なら許可しない' do
+      r = @ps.visible?(@author)
+      r.should == false
+    end
+    it 'それ以外のとき不許可を返す。' do
+      r = @ps.visible?(nil)
+      r.should be_false
+    end
+  end
+  
+  describe '状態に於いて' do
+    before do
+    end
+    it '借り受けしていないのとき0を返す' do
+      @ps = FactoryGirl.create :provider_status, :token => nil
+      r = @ps.status
+      r.should eq 0
+    end
+    it '借り受けしているのとき1を返す' do
+      @ps = FactoryGirl.create :provider_status, :token => 'a'
+      r = @ps.status
+      r.should eq 1
+    end
+  end
+  
+  describe '一覧取得に於いて' do
+    before do
+      @ps = FactoryGirl.create :provider_status
+      @pd = FactoryGirl.create :provider, :provider_status_id => @ps.id, :name => "6"
+    end
+    context 'page補正について' do
+      it '文字列から数値に変換される' do
+        ProviderStatus.page('8').should eq 8
+      end
+      it 'nilの場合は1になる' do
+        ProviderStatus.page().should eq 1
+      end
+      it '0以下の場合は1になる' do
+        ProviderStatus.page('0').should eq 1
+      end
+    end
+    context 'page_size補正について' do
+      it '文字列から数値に変換される' do
+        ProviderStatus.page_size('7').should eq 7
+      end
+      it 'nilの場合はProviderStatus.default_page_sizeになる' do
+        ProviderStatus.page_size().should eq ProviderStatus.default_page_size
+      end
+      it '0以下の場合はProviderStatus.default_page_sizeになる' do
+        ProviderStatus.page_size('0').should eq ProviderStatus.default_page_size
+      end
+      it 'ProviderStatus.max_page_sizeを超えた場合はProviderStatus.max_page_sizeになる' do
+        ProviderStatus.page_size('1000').should eq ProviderStatus.max_page_size
+      end
+    end
+    context 'つつがなく終わるとき' do
+      it '一覧取得オプションを利用している' do
+        ProviderStatus.stub(:list_opt).with(any_args).and_return({:include => {:provider => {}} })
+        ProviderStatus.should_receive(:list_opt).with(any_args).exactly(1)
+        r = ProviderStatus.list
+      end
+    end
+    it 'リストを返す' do
+      r = ProviderStatus.list
+      r.should eq [@ps]
+    end
+    it '管理名で並んでいる' do
+      v = FactoryGirl.create :provider_status
+      vd = FactoryGirl.create :provider, :provider_status_id => v.id, :name => "0"
+      r = ProviderStatus.list
+      r.should eq [v, @ps]
+    end
+    context 'DBに5件あって1ページの件数を2件に変えたとして' do
+      before do
+        @ps2 = FactoryGirl.create :provider_status
+        @pd2 = FactoryGirl.create :provider, :provider_status_id => @ps2.id, :name => "5"
+        @ps3 = FactoryGirl.create :provider_status
+        @pd3 = FactoryGirl.create :provider, :provider_status_id => @ps3.id, :name => "4"
+        @ps4 = FactoryGirl.create :provider_status
+        @pd4 = FactoryGirl.create :provider, :provider_status_id => @ps4.id, :name => "3"
+        @ps5 = FactoryGirl.create :provider_status
+        @pd5 = FactoryGirl.create :provider, :provider_status_id => @ps5.id, :name => "2"
+        ProviderStatus.stub(:default_page_size).and_return(2)
+      end
+      it '通常は2件を返す' do
+        r = ProviderStatus.list
+        r.should have(2).items 
+      end
+      it 'page=1なら末尾2件を返す' do
+        #管理名で並んでいる
+        r = ProviderStatus.list(1)
+        r.should eq [@ps5, @ps4]
+      end
+      it 'page=2なら中間2件を返す' do
+        r = ProviderStatus.list(2)
+        r.should eq [@ps3, @ps2]
+      end
+      it 'page=3なら先頭1件を返す' do
+        r = ProviderStatus.list(3)
+        r.should eq [@ps]
+      end
+    end
+    context 'DBに5件あって1ページの件数を2件に変えたとして' do
+      before do
+        @ps2 = FactoryGirl.create :provider_status
+        @pd2 = FactoryGirl.create :provider, :provider_status_id => @ps2.id, :name => "5"
+        @ps3 = FactoryGirl.create :provider_status
+        @pd3 = FactoryGirl.create :provider, :provider_status_id => @ps3.id, :name => "4"
+        @ps4 = FactoryGirl.create :provider_status
+        @pd4 = FactoryGirl.create :provider, :provider_status_id => @ps4.id, :name => "3"
+        @ps5 = FactoryGirl.create :provider_status
+        @pd5 = FactoryGirl.create :provider, :provider_status_id => @ps5.id, :name => "2"
+        ProviderStatus.stub(:default_page_size).and_return(2)
+      end
+      it '件数0は全件(5件)を返す' do
+        r = ProviderStatus.list 5, 0
+        r.should have(5).items 
+      end
+    end
+  end
+  describe '待機中一覧取得に於いて' do
+    before do
+      @ps = FactoryGirl.create :provider_status
+      @pd = FactoryGirl.create :provider, :provider_status_id => @ps.id, :name => "6"
+    end
+    context 'つつがなく終わるとき' do
+      it '一覧取得オプションを利用している' do
+        ProviderStatus.stub(:list_opt).with(any_args).and_return({:include => {:provider => {}} })
+        ProviderStatus.should_receive(:list_opt).with(any_args).exactly(1)
+        r = ProviderStatus.available_list
+      end
+    end
+    it 'リストを返す' do
+      r = ProviderStatus.available_list
+      r.should eq [@ps]
+    end
+    it '管理名で並んでいる' do
+      @ps2 = FactoryGirl.create :provider_status
+      v = FactoryGirl.create :provider, :name => "0", :provider_status_id => @ps2.id
+      r = ProviderStatus.available_list
+      r.should eq [@ps2, @ps]
+    end
+    it '借受状況のトークンが設定されていない借受状況に限る' do
+      @ps2 = FactoryGirl.create :provider_status, :token => 'aaaaa'
+      v = FactoryGirl.create :provider, :name => "0", :provider_status_id => @ps2.id
+      r = ProviderStatus.available_list
+      r.should eq [@ps]
+    end
+    context 'DBに5件あって1ページの件数を2件に変えたとして' do
+      before do
+        @ps2 = FactoryGirl.create :provider_status
+        @pd2 = FactoryGirl.create :provider, :provider_status_id => @ps2.id, :name => "5"
+        @ps3 = FactoryGirl.create :provider_status
+        @pd3 = FactoryGirl.create :provider, :provider_status_id => @ps3.id, :name => "4"
+        @ps4 = FactoryGirl.create :provider_status
+        @pd4 = FactoryGirl.create :provider, :provider_status_id => @ps4.id, :name => "3"
+        @ps5 = FactoryGirl.create :provider_status
+        @pd5 = FactoryGirl.create :provider, :provider_status_id => @ps5.id, :name => "2"
+        ProviderStatus.stub(:default_page_size).and_return(2)
+      end
+      it '通常は2件を返す' do
+        r = ProviderStatus.available_list
+        r.should have(2).items 
+      end
+      it 'page=1なら末尾2件を返す' do
+        #管理名で並んでいる
+        r = ProviderStatus.available_list(1)
+        r.should eq [@ps5, @ps4]
+      end
+      it 'page=2なら中間2件を返す' do
+        r = ProviderStatus.available_list(2)
+        r.should eq [@ps3, @ps2]
+      end
+      it 'page=3なら先頭1件を返す' do
+        r = ProviderStatus.available_list(3)
+        r.should eq [@ps]
+      end
+    end
+    context 'DBに5件あって1ページの件数を2件に変えたとして' do
+      before do
+        @ps2 = FactoryGirl.create :provider_status
+        @pd2 = FactoryGirl.create :provider, :provider_status_id => @ps2.id, :name => "5"
+        @ps3 = FactoryGirl.create :provider_status
+        @pd3 = FactoryGirl.create :provider, :provider_status_id => @ps3.id, :name => "4"
+        @ps4 = FactoryGirl.create :provider_status
+        @pd4 = FactoryGirl.create :provider, :provider_status_id => @ps4.id, :name => "3"
+        @ps5 = FactoryGirl.create :provider_status
+        @pd5 = FactoryGirl.create :provider, :provider_status_id => @ps5.id, :name => "2"
+        ProviderStatus.stub(:default_page_size).and_return(2)
+      end
+      it '件数0は全件(5件)を返す' do
+        r = ProviderStatus.available_list 5, 0
+        r.should have(5).items 
+      end
+    end
+  end
+  describe '一覧取得オプションに於いて' do
+    it 'includeキーを含んでいる' do
+      r = ProviderStatus.list_opt
+      r.has_key?(:include).should be_true
+    end
+    it '1つの項目を含んでいる' do
+      r = ProviderStatus.list_opt[:include]
+      r.should have(1).items
+    end
+    it '貸手を含んでいる' do
+      r = ProviderStatus.list_opt[:include]
+      r.has_key?(:provider).should be_true
+    end
+  end
+  describe 'json一覧出力オプションに於いて' do
+    before do
+      @ps = FactoryGirl.create :provider_status
+      @pd = FactoryGirl.create :provider, :provider_status_id => @ps.id
+    end
+    it '貸手を含んでいる' do
+      r = ProviderStatus.list.to_json ProviderStatus.list_json_opt
+      j = JSON.parse r
+      i = j.first
+      i.has_key?('provider').should be_true
+    end
+  end
+  
+  describe '単体取得に於いて' do
+    before do
+      @ps = FactoryGirl.create :provider_status
+      @pd = FactoryGirl.create :provider, :provider_status_id => @ps.id
+    end
+    context 'つつがなく終わるとき' do
+      it '単体取得オプションを利用している' do
+        ProviderStatus.stub(:show_opt).with(any_args).and_return({})
+        ProviderStatus.should_receive(:show_opt).with(any_args).exactly(1)
+        r = ProviderStatus.show @ps.id, @admin
+      end
+      it '閲覧許可を問い合わせている' do
+        ProviderStatus.any_instance.stub(:visible?).with(any_args).and_return(true)
+        ProviderStatus.any_instance.should_receive(:visible?).with(any_args).exactly(1)
+        r = ProviderStatus.show @ps.id, @admin
+      end
+    end
+    it '指定の借受状況を返す' do
+      r = ProviderStatus.show @ps.id, @admin
+      r.should eq @ps
+    end
+    context '閲覧許可が出なかったとき' do
+      it '403Forbidden例外を返す' do
+        ProviderStatus.any_instance.stub(:visible?).and_return(false)
+        lambda{
+          ProviderStatus.show @ps.id, @admin
+        }.should raise_error(ActiveRecord::Forbidden)
+      end
+    end
+    context '存在しない借受状況を開こうとしたとき' do
+      it '404RecordNotFound例外を返す' do
+        lambda{
+          ProviderStatus.show 110, @admin
+        }.should raise_error(ActiveRecord::RecordNotFound)
+      end
+    end
+  end
+  
+  describe '編集取得に於いて' do
+    before do
+      @ps = FactoryGirl.create :provider_status
+      @pd = FactoryGirl.create :provider, :provider_status_id => @ps.id
+    end
+    context 'つつがなく終わるとき' do
+      it '単体取得オプションを利用している' do
+        ProviderStatus.stub(:show_opt).with(any_args).and_return({})
+        ProviderStatus.should_receive(:show_opt).with(any_args).exactly(1)
+        r = ProviderStatus.edit @ps.id, @admin
+      end
+      it '所持判定を問い合わせている' do
+        ProviderStatus.any_instance.stub(:own?).with(any_args).and_return(true)
+        ProviderStatus.any_instance.should_receive(:own?).with(any_args).exactly(1)
+        r = ProviderStatus.edit @ps.id, @admin
+      end
+    end
+    it '指定の借受状況を返す' do
+      ProviderStatus.any_instance.stub(:own?).and_return(true)
+      r = ProviderStatus.edit @ps.id, @admin
+      r.should eq @ps
+    end
+    context '権限がなかったとき' do
+      it '403Forbidden例外を返す' do
+        ProviderStatus.any_instance.stub(:own?).and_return(false)
+        lambda{
+          ProviderStatus.edit @ps.id, @admin
+        }.should raise_error(ActiveRecord::Forbidden)
+      end
+    end
+    context '存在しない借受状況を開こうとしたとき' do
+      it '404RecordNotFound例外を返す' do
+        lambda{
+          ProviderStatus.edit 110, @admin
+        }.should raise_error(ActiveRecord::RecordNotFound)
+      end
+    end
+  end
+  describe '単体取得オプションに於いて' do
+    it 'includeキーを含んでいる' do
+      r = ProviderStatus.show_opt
+      r.has_key?(:include).should be_true
+    end
+    it '1つの項目を含んでいる' do
+      r = ProviderStatus.show_opt[:include]
+      r.should have(1).items
+    end
+    it '貸手を含んでいる' do
+      r = ProviderStatus.show_opt[:include]
+      r.has_key?(:provider).should be_true
+    end
+  end
+  describe 'json単体出力オプションに於いて' do
+    before do
+      @ps = FactoryGirl.create :provider_status
+      @pd = FactoryGirl.create :provider, :provider_status_id => @ps.id
+    end
+    it '貸手を含んでいる' do
+      r = ProviderStatus.show(@ps.id, @admin).to_json ProviderStatus.show_json_opt
+      j = JSON.parse r
+      i = j
+      i.has_key?('provider').should be_true
+    end
+  end
+  
+end