From: yasushiito Date: Tue, 10 Sep 2013 01:45:40 +0000 (+0900) Subject: t#32025:comic rename X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=000b5d5ef4f3cf02793ae6a06855b7bd3cd9a78f;p=pettanr%2Fpettanr.git t#32025:comic rename --- diff --git a/app/assets/javascripts/scroll_panels.js.coffee b/app/assets/javascripts/scroll_panels.js.coffee new file mode 100644 index 00000000..76156794 --- /dev/null +++ b/app/assets/javascripts/scroll_panels.js.coffee @@ -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/scrolls.js.coffee b/app/assets/javascripts/scrolls.js.coffee new file mode 100644 index 00000000..76156794 --- /dev/null +++ b/app/assets/javascripts/scrolls.js.coffee @@ -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/scroll_panels.css.scss b/app/assets/stylesheets/scroll_panels.css.scss new file mode 100644 index 00000000..011af688 --- /dev/null +++ b/app/assets/stylesheets/scroll_panels.css.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the scroll_panels 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/scrolls.css.scss b/app/assets/stylesheets/scrolls.css.scss new file mode 100644 index 00000000..050e6399 --- /dev/null +++ b/app/assets/stylesheets/scrolls.css.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the scrolls controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/scroll_panels_controller.rb b/app/controllers/scroll_panels_controller.rb new file mode 100644 index 00000000..5e0b7398 --- /dev/null +++ b/app/controllers/scroll_panels_controller.rb @@ -0,0 +1,157 @@ +class ScrollPanelsController < ApplicationController + layout 'test' if MagicNumber['test_layout'] + if MagicNumber['run_mode'] == 0 + before_filter :authenticate_user, :only => [:new, :create, :edit, :update, :destroy] + before_filter :authenticate_author, :only => [:new, :create, :edit, :update, :destroy] + else + before_filter :authenticate_reader, :only => [:index, :show, :scroll] + before_filter :authenticate_user, :only => [:new, :create, :edit, :update, :destroy] + before_filter :authenticate_author, :only => [:new, :create, :edit, :update, :destroy] + end + before_filter :authenticate_admin!, :only => [:list, :browse] + + def index + @page = ScrollPanel.page params[:page] + @page_size = ScrollPanel.page_size params[:page_size] + @scroll_panels = ScrollPanel.list(@page, @page_size) + + respond_to do |format| + format.html { + @paginate = ScrollPanel.list_paginate(@page, @page_size) + } + format.json { render :json => @scroll_panels.to_json(ScrollPanel.list_json_opt) } + end + end + + def show + @scroll_panel = ScrollPanel.show(params[:id], [@user, @admin]) + + respond_to do |format| + format.html # show.html.erb + format.json { render json: @scroll_panel.scroll_panel_as_json(@author) } + end + end + + def scroll + @scroll = Scroll.show(params[:id], [@user, @admin]) + cnt = ScrollPanel.count(:conditions => ['scroll_id = ?', @scroll.id]).to_i + @offset = ScrollPanel.offset cnt, params[:offset] + @panel_count = ScrollPanel.panel_count cnt, params[:count] + @scroll_panels = ScrollPanel.play_list(@scroll, @author, @offset, @panel_count) + respond_to do |format| + format.html { + @prev_offset = if @offset > 0 + if @offset - @panel_count < 0 + 0 + else + @offset - @panel_count + end + else + nil + end + @next_offset = if @offset + @panel_count > cnt + nil + else + @offset + @panel_count + end + if @author + @new_panels = Panel.mylist(@author, 1, 5) + end + } + format.json {render text: ScrollPanel.list_as_json_text(@scroll_panels, @author)} + format.jsonp { + render :json => "callback(" + @scroll_panels.to_json_list + ");" + } + end + end + + def list + @scroll_panels = ScrollPanel.all + + respond_to do |format| + format.html { render layout: 'system' }# index.html.erb + format.json { render json: @scroll_panels } + end + end + + def browse + @scroll_panel = ScrollPanel.find(params[:id]) + + respond_to do |format| + format.html { render layout: 'system' } # show.html.erb + format.json { render json: @scroll_panel } + end + end + + def new + @scroll_panel = ScrollPanel.new + @scroll_panel.supply_default + respond_to do |format| + format.html # new.html.erb + format.js + format.json { render json: @scroll_panel.scroll_panel_as_json(@author) } + end + end + + def edit + @scroll_panel = ScrollPanel.edit(params[:id], @author) + respond_to do |format| + format.html + format.js + end + end + + def create + @scroll_panel = ScrollPanel.new + @scroll_panel.supply_default + @scroll_panel.attributes = params[:scroll_panel] + @scroll_panel.overwrite @author + @scroll = Scroll.edit(@scroll_panel.scroll_id, @author) if @scroll_panel.scroll_id + @panel = Panel.show(@scroll_panel.panel_id, @author) if @scroll_panel.panel_id + + respond_to do |format| + if @scroll_panel.store + flash[:notice] = I18n.t('flash.notice.created', :model => ScrollPanel.model_name.human) + format.html { redirect_to action: :scroll, id: @scroll_panel.scroll_id } + format.json { render json: @scroll_panel.scroll_panel_as_json(@author) } + else + flash[:notice] = I18n.t('flash.notice.not_created', :model => ScrollPanel.model_name.human) + format.html { render action: "new" } + format.json { render json: @scroll_panel.errors, status: :unprocessable_entity } + end + end + end + + def update + @scroll_panel = ScrollPanel.edit(params[:id], @author) + ot = @scroll_panel.t + @scroll_panel.attributes = params[:scroll_panel] + @scroll_panel.overwrite @author + respond_to do |format| + if @scroll_panel.store ot + flash[:notice] = I18n.t('flash.notice.updated', :model => ScrollPanel.model_name.human) + format.html { redirect_to action: :scroll, id: @scroll_panel.scroll_id } + format.json { head :ok } + else + flash[:notice] = I18n.t('flash.notice.not_updated', :model => ScrollPanel.model_name.human) + format.html { render action: "edit" } + format.json { render json: @scroll_panel.errors, status: :unprocessable_entity } + end + end + end + + def destroy + @scroll_panel = ScrollPanel.edit(params[:id], @author) + respond_to do |format| + if @scroll_panel.destroy_and_shorten + flash[:notice] = I18n.t('flash.notice.destroyed', :model => ScrollPanel.model_name.human) + format.html { redirect_to :controller => 'scroll_panels', :action => :scroll, :id => @scroll_panel.scroll_id } + format.json { head :ok } + else + flash[:notice] = I18n.t('flash.notice.not_destroyed', :model => ScrollPanel.model_name.human) + format.html { redirect_to scroll_panel_path(@scroll_panel) } + format.json { render json: @scroll_panel.errors, status: :unprocessable_entity } + end + end + end +end diff --git a/app/controllers/scrolls_controller.rb b/app/controllers/scrolls_controller.rb new file mode 100644 index 00000000..38fa9faf --- /dev/null +++ b/app/controllers/scrolls_controller.rb @@ -0,0 +1,131 @@ +class ScrollsController < ApplicationController + layout 'test' if MagicNumber['test_layout'] + if MagicNumber['run_mode'] == 0 + before_filter :authenticate_user, :only => [:new, :create, :edit, :update, :destroy] + before_filter :authenticate_author, :only => [:new, :create, :edit, :update, :destroy] + else + before_filter :authenticate_reader, :only => [:top, :index, :show] + before_filter :authenticate_user, :only => [:new, :create, :edit, :update, :destroy] + before_filter :authenticate_author, :only => [:new, :create, :edit, :update, :destroy] + end + before_filter :authenticate_admin!, :only => [:list, :browse] + + def index + @page = Scroll.page params[:page] + @page_size = Scroll.page_size params[:page_size] + @scrolls = Scroll.list(@page, @page_size) + respond_to do |format| + format.html { + @paginate = Scroll.list_paginate(@page, @page_size) + } + format.json { render json: @scrolls.to_json(Scroll.list_json_opt) } + format.atom + format.rss + end + end + + def show + @scroll = Scroll.show(params[:id], [@user, @admin]) + + respond_to do |format| + format.html # show.html.erb + format.json { render json: @scroll.to_json(Scroll.show_json_opt) } + format.atom + format.rss + end + end + + def count + @scroll = {:count => Scroll.visible_count} + respond_to do |format| + format.json { render json: @scroll.to_json } + end + end + + def list + @scrolls = Scroll.all + + respond_to do |format| + format.html { render layout: 'system' }# index.html.erb + format.json { render json: @scrolls } + end + end + + def browse + @scroll = Scroll.find(params[:id]) + + respond_to do |format| + format.html { render layout: 'system' } # show.html.erb + format.json { render json: @scroll } + end + end + + def new + @scroll = Scroll.new + @scroll.supply_default + respond_to do |format| + format.html # new.html.erb + format.js + format.json { render json: @scroll.to_json(Scroll.show_json_opt) } + end + end + + def edit + @scroll = Scroll.edit(params[:id], @author) + respond_to do |format| + format.html + format.js + end + end + + def create + @scroll = Scroll.new + @scroll.supply_default + @scroll.attributes = params[:scroll] + @scroll.overwrite @author + + respond_to do |format| + if @scroll.save + flash[:notice] = I18n.t('flash.notice.created', :model => Scroll.model_name.human) + format.html { redirect_to @scroll } + format.json { render json: @scroll.to_json(Scroll.show_json_opt), status: :created, location: @scroll } + else + flash[:notice] = I18n.t('flash.notice.not_created', :model => Scroll.model_name.human) + format.html { render action: "new" } + format.json { render json: @scroll.errors, status: :unprocessable_entity } + end + end + end + + def update + @scroll = Scroll.edit(params[:id], @author) + @scroll.attributes = params[:scroll] + @scroll.overwrite @author + respond_to do |format| + if @scroll.save + flash[:notice] = I18n.t('flash.notice.updated', :model => Scroll.model_name.human) + format.html { redirect_to @scroll } + format.json { head :ok } + else + flash[:notice] = I18n.t('flash.notice.not_updated', :model => Scroll.model_name.human) + format.html { render action: "edit" } + format.json { render json: @scroll.errors, status: :unprocessable_entity } + end + end + end + + def destroy + @scroll = Scroll.edit(params[:id], @author) + respond_to do |format| + if @scroll.destroy_with_scroll_panel + flash[:notice] = I18n.t('flash.notice.destroyed', :model => Scroll.model_name.human) + format.html { redirect_to '/home/scrolls' } + format.json { head :ok } + else + flash[:notice] = I18n.t('flash.notice.not_destroyed', :model => Scroll.model_name.human) + format.html { redirect_to @scroll } + format.json { render json: @scroll.errors, status: :unprocessable_entity } + end + end + end +end diff --git a/app/helpers/scroll_panels_helper.rb b/app/helpers/scroll_panels_helper.rb new file mode 100644 index 00000000..186f7bb8 --- /dev/null +++ b/app/helpers/scroll_panels_helper.rb @@ -0,0 +1,2 @@ +module ScrollPanelsHelper +end diff --git a/app/helpers/scrolls_helper.rb b/app/helpers/scrolls_helper.rb new file mode 100644 index 00000000..b06e20f1 --- /dev/null +++ b/app/helpers/scrolls_helper.rb @@ -0,0 +1,2 @@ +module ScrollsHelper +end diff --git a/app/models/scroll.rb b/app/models/scroll.rb new file mode 100644 index 00000000..5588f43f --- /dev/null +++ b/app/models/scroll.rb @@ -0,0 +1,167 @@ +class Scroll < ActiveRecord::Base + has_many :scroll_panels + belongs_to :author + + validates :title, :presence => true, :length => {:maximum => 100} + validates :visible, :presence => true, :numericality => true, :inclusion => {:in => 0..1} + before_validation :valid_encode + + def valid_encode + ['title', 'description'].each do |a| + next if attributes[a] == nil + raise Pettanr::BadRequest unless attributes[a].valid_encoding? + end + end + + def supply_default + self.visible = 0 if self.visible.blank? + end + + def overwrite au + return false unless au + self.author_id = au.id + end + + def own? roles + roles = [roles] unless roles.respond_to?(:each) + au = Scroll.get_author_from_roles roles + return false unless au + self.author_id == au.id + end + + def visible? roles + if MagicNumber['run_mode'] == 0 + return false unless guest_role_check(roles) + else + return false unless reader_role_check(roles) + end + return true if self.own?(roles) + self.visible > 0 + 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_where + 'scrolls.visible > 0' + end + + def self.mylist_where au + ['scrolls.author_id = ?', au.id] + end + + def self.himlist_where au + ['scrolls.author_id = ? and scrolls.visible > 0', au.id] + end + + def self.list page = 1, page_size = self.default_page_size + Scroll.where(self.list_where()).includes(Scroll.list_opt).order('scrolls.updated_at desc').offset((page -1) * page_size).limit(page_size) + end + + def self.mylist au, page = 1, page_size = Author.default_scroll_page_size + Scroll.where(self.mylist_where(au)).includes(Scroll.list_opt).order('scrolls.updated_at desc').offset((page -1) * page_size).limit(page_size) + end + + def self.himlist au, page = 1, page_size = Author.default_scroll_page_size + Scroll.where(self.himlist_where(au)).includes(Scroll.list_opt).order('scrolls.updated_at desc').offset((page -1) * page_size).limit(page_size) + end + + def self.list_paginate page = 1, page_size = self.default_page_size + Kaminari.paginate_array(Array.new(Scroll.where(self.list_where()).count, nil)).page(page).per(page_size) + end + + def self.mylist_paginate au, page = 1, page_size = Author.default_scroll_page_size + Kaminari.paginate_array(Array.new(Scroll.where(self.mylist_where(au)).count, nil)).page(page).per(page_size) + end + + def self.himlist_paginate au, page = 1, page_size = Author.default_scroll_page_size + Kaminari.paginate_array(Array.new(Scroll.where(self.himlist_where(au)).count, nil)).page(page).per(page_size) + end + + def self.list_opt + {:scroll_panels => {:panel => {}}, :author => {} } + end + + def self.list_json_opt + {:include => {:scroll_panels => {:include => {:panel => {}}}, :author => {}}} + end + + def self.show sid, roles + opt = {} + opt.merge!(Scroll.show_opt) + res = Scroll.find(sid, opt) + raise ActiveRecord::Forbidden unless res.visible?(roles) + res + end + + def self.edit sid, au + opt = {} + opt.merge!(Scroll.show_opt) + res = Scroll.find(sid, opt) + raise ActiveRecord::Forbidden unless res.own?(au) + res + end + + def self.show_opt + {:include => {:scroll_panels => {:panel => {}}, :author => {}}} + end + + def self.show_json_opt + {:include => {:scroll_panels => {:include => {:panel => {}}}, :author => {}}} + end + + def self.visible_count + Scroll.count 'visible > 0' + end + + def destroy_with_scroll_panel + res = false + Scroll.transaction do + self.scroll_panels.each do |scroll_panel| + raise ActiveRecord::Rollback unless scroll_panel.destroy + end + raise ActiveRecord::Rollback unless self.destroy + res = true + end + res + end + + def scenario + panels.map {|panel| + panel.scenario + }.join + end + + def plain_scenario + panels.map {|panel| + panel.plain_scenario + }.join + end + +end diff --git a/app/models/scroll_panel.rb b/app/models/scroll_panel.rb new file mode 100644 index 00000000..798a0c9f --- /dev/null +++ b/app/models/scroll_panel.rb @@ -0,0 +1,316 @@ +class ScrollPanel < ActiveRecord::Base + belongs_to :author + belongs_to :panel + belongs_to :scroll + + validates :scroll_id, :presence => true, :numericality => true, :existence => {:both => false} + validates :panel_id, :presence => true, :numericality => true, :existence => {:both => false} + validates :author_id, :presence => true, :numericality => true, :existence => {:both => false} + validates :t, :presence => true, :numericality => {:greater_than_or_equal_to => 0} + + def supply_default + self.scroll_id = nil + self.panel_id = nil + self.t = nil + end + + def overwrite au + return false unless au + self.author_id = au.id + end + + def own? roles + roles = [roles] unless roles.respond_to?(:each) + au = ScrollPanel.get_author_from_roles roles + return false unless au + self.author_id == au.id + end + + def visible? roles + if MagicNumber['run_mode'] == 0 + return false unless guest_role_check(roles) + else + return false unless reader_role_check(roles) + end + return true if self.scroll.own?(roles) + self.scroll.visible? roles + end + + def self.default_panel_size + 30 + end + + def self.max_panel_size + 200 + end + + def self.offset cnt, prm = nil + offset = prm.to_i + offset = cnt - 1 if offset >= cnt + offset = cnt - offset.abs if offset < 0 + offset = 0 if offset < 0 + offset + end + + def self.panel_count cnt, prm = self.default_panel_size + count = prm.to_i + count = self.max_panel_size if count > self.max_panel_size + count = self.default_panel_size if count < 1 + count + end + + def self.default_page_size + 25 + end + + def self.max_page_size + 100 + 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.play_list_where cid + ['scroll_panels.scroll_id = ?', cid] + end + + def self.list_where + 'scrolls.visible > 0' + end + + def self.mylist_where au + ['scroll_panels.author_id = ?', au.id] + end + + def self.himlist_where au + ['scroll_panels.author_id = ? and scrolls.visible > 0', au.id] + end + + def self.play_list scroll, author, offset = 0, limit = ScrollPanel.default_panel_size + ScrollPanel.where(self.play_list_where(scroll.id)).includes(ScrollPanel.list_opt).order('scroll_panels.t').offset(offset).limit(limit) + end + + def self.list page = 1, page_size = self.default_page_size + ScrollPanel.where(self.list_where()).includes(ScrollPanel.list_opt).order('scroll_panels.updated_at desc').offset((page -1) * page_size).limit(page_size) + end + + def self.mylist au, page = 1, page_size = Author.default_scroll_panel_page_size + ScrollPanel.where(self.mylist_where(au)).includes(ScrollPanel.list_opt).order('scroll_panels.updated_at desc').offset((page -1) * page_size).limit(page_size) + end + + def self.himlist au, page = 1, page_size = Author.default_scroll_panel_page_size + ScrollPanel.where(self.himlist_where(au)).includes(ScrollPanel.list_opt).order('scroll_panels.updated_at desc').offset((page -1) * page_size).limit(page_size) + end + + def self.list_paginate page = 1, page_size = self.default_page_size + Kaminari.paginate_array(Array.new(ScrollPanel.where(self.list_where()).includes(ScrollPanel.list_opt).count, nil)).page(page).per(page_size) + end + + def self.mylist_paginate au, page = 1, page_size = Author.default_scroll_panel_page_size + Kaminari.paginate_array(Array.new(ScrollPanel.where(self.mylist_where(au)).includes(ScrollPanel.list_opt).count, nil)).page(page).per(page_size) + end + + def self.himlist_paginate au, page = 1, page_size = Author.default_scroll_panel_page_size + Kaminari.paginate_array(Array.new(ScrollPanel.where(self.himlist_where(au)).includes(ScrollPanel.list_opt).count, nil)).page(page).per(page_size) + end + + def self.list_opt + { + :author => {}, + :scroll => { + :author => {} + }, + :panel => { + :author => {}, + :panel_pictures => {:picture => {:artist => {}, :license => {}}}, + :speech_balloons =>{:balloon => {}, :speech => {}} + } + } + end + + def self.list_json_opt + {:include => { + :author => {}, + :scroll => { + :author => {} + }, + :panel => { + :author => {}, + :panel_pictures => {:picture => {:artist => {}, :license => {}}}, + :speech_balloons =>{:balloon => {}, :speech => {}} + } + }} + end + + def self.show spid, roles + opt = {} + opt.merge!(ScrollPanel.show_opt) + res = ScrollPanel.find spid, opt + raise ActiveRecord::Forbidden unless res.visible?(roles) + res + end + + def self.edit spid, au + opt = {} + opt.merge!(ScrollPanel.show_opt) + res = ScrollPanel.find spid, opt + raise ActiveRecord::Forbidden unless res.own?(au) + res + end + + def self.show_opt + {:include => { + :author => {}, + :scroll => { + :author => {} + }, + :panel => { + :author => {}, + :panel_pictures => {:picture => {:artist => {}, :license => {}}}, + :speech_balloons =>{:balloon => {}, :speech => {}} + } + }} + end + + def elements + self.panel.elements + end + + def scroll_panel_as_json au + panel_include = if self.panel and self.panel.visible?(au) + {:include => {:author => {}}, :methods => :elements} + else + {:include => {:author => {}}} + end + self.to_json({:include => {:scroll => {:include => {:author => {}}}, :author => {}, :panel => panel_include}}) + end + + def self.list_as_json_text ary, au + '[' + ary.map {|i| i.scroll_panel_as_json(au) }.join(',') + ']' + end + + def self.licensed_pictures scroll_panels + r = {} + scroll_panels.each do |scroll_panel| + r.merge!(scroll_panel.panel.licensed_pictures) if scroll_panel.panel + end + r + end + + def self.new_t scroll_id + r = ScrollPanel.max_t(scroll_id) + r.blank? ? 0 : r.to_i + 1 + end + + def self.max_t scroll_id + ScrollPanel.maximum(:t, :conditions => ['scroll_id = ?', scroll_id]) + end + + def self.find_t scroll_id, t + ScrollPanel.find(:first, :conditions => ['scroll_id = ? and t = ?', scroll_id, t]) + end + + def self.collect_t scroll_panel + r = ScrollPanel.find(:all, :conditions => ['scroll_id = ?', scroll_panel.scroll_id], :order => 't') + r.map {|sp| sp.t} + end + + def self.serial? ary + i = 0 + ary.compact.sort.each do |t| + break false unless t == i + i += 1 + end + ary.compact.size == i + end + + def self.validate_t scroll_panel + ScrollPanel.serial?(ScrollPanel.collect_t(scroll_panel)) + end + + def insert_shift + ScrollPanel.update_all('t = t + 1', ['scroll_id = ? and t >= ?', self.scroll_id, self.t]) + end + + def lesser_shift old_t + self.t = 0 if self.t < 0 + ScrollPanel.update_all('t = t + 1', ['scroll_id = ? and (t >= ? and t < ?)', self.scroll_id, self.t, old_t]) + end + + def higher_shift old_t + nf = ScrollPanel.find_t(self.scroll_id, self.t) + max_t = ScrollPanel.max_t(self.scroll_id).to_i + self.t = max_t if self.t > max_t + ScrollPanel.update_all('t = t - 1', ['scroll_id = ? and (t > ? and t <= ?)', self.scroll_id, old_t, self.t]) + end + + def update_shift old_t + if self.t > old_t + higher_shift old_t + else + lesser_shift old_t + end + end + + def rotate old_t = nil + if self.new_record? + if self.t.blank? + self.t = ScrollPanel.new_t self.scroll_id + else + self.insert_shift + end + else + if self.t.blank? + else + self.update_shift old_t + end + end + end + + def allow? + return nil if self.scroll_id == nil or self.panel_id == nil + self.scroll.own?(self.author) and self.panel.usable?(self.author) + end + + def store old_t = nil + res = false + ScrollPanel.transaction do + case self.allow? + when true + self.rotate old_t + when false + raise ActiveRecord::Forbidden + else + end + res = self.save + raise ActiveRecord::Rollback unless res + res = ScrollPanel.validate_t(self) + unless res + self.errors.add :t, 'unserialized' + raise ActiveRecord::Rollback + end + end + res + end + + def destroy_and_shorten + res = false + ScrollPanel.transaction do + ScrollPanel.update_all('t = t - 1', ['scroll_id = ? and (t > ?)', self.scroll_id, self.t]) + raise ActiveRecord::Rollback unless self.destroy + res = true + end + res + end + +end diff --git a/app/views/home/scroll_panels.html.erb b/app/views/home/scroll_panels.html.erb new file mode 100644 index 00000000..a99f490f --- /dev/null +++ b/app/views/home/scroll_panels.html.erb @@ -0,0 +1,9 @@ +

<%= t '.title' -%>

+ + + <% @stories.each do |story| %> + <%= render 'stories/list_item', :story => story, :author => @author %> + <% end %> +
+<%= paginate(@paginate) %> +<%= link_to t('stories.new.title'), new_story_path %> diff --git a/app/views/home/scrolls.html.erb b/app/views/home/scrolls.html.erb new file mode 100644 index 00000000..9d0287d7 --- /dev/null +++ b/app/views/home/scrolls.html.erb @@ -0,0 +1,10 @@ +

<%= t '.title' -%>

+

<%= notice %>

+ + + <% @comics.each do |comic| %> + <%= render 'comics/list_item', :comic => comic, :author => @author %> + <% end %> +
+<%= paginate(@paginate) %> +<%= link_to t('comics.new.title'), new_comic_path %> diff --git a/app/views/scroll_panels/_append_panel.html.erb b/app/views/scroll_panels/_append_panel.html.erb new file mode 100644 index 00000000..241bcf84 --- /dev/null +++ b/app/views/scroll_panels/_append_panel.html.erb @@ -0,0 +1,21 @@ + + + <%= link_to panel_icon(:object => panel, :size => 25), panel_path(panel) %> + <%= link_to author_icon(:object => panel.author, :size => 17), author_path(panel.author) %> + + + <%= link_to h(truncate(h(panel.caption), :length => 40)), :controller => 'stories', :action => :comic, :id => comic.id %> + + + <%= l panel.updated_at %> + + + <% @story = Story.new :comic_id => comic.id, :panel_id => panel.id -%> + <%= form_for(@story) do |f| %> + <%= f.hidden_field :comic_id %> + <%= f.hidden_field :t %> + <%= f.hidden_field :panel_id %> + <%= f.submit t('stories.comic.append') %> + <% end %> + + diff --git a/app/views/scroll_panels/_footer.html.erb b/app/views/scroll_panels/_footer.html.erb new file mode 100644 index 00000000..56e93674 --- /dev/null +++ b/app/views/scroll_panels/_footer.html.erb @@ -0,0 +1,23 @@ + + + + + + +
+ <% if story.panel -%> + <%= link_to panel_icon(:object => story.panel, :size => 25), panel_path(story.panel) %> + <%= link_to author_icon(:object => story.panel.author, :size => 17), author_path(story.panel.author) %> + <%= distance_of_time_in_words_to_now story.panel.updated_at %> + <% end %> + + <%= link_to story_icon(:object => story, :size => 25), story_path(story) %> + <%= link_to author_icon(:object => story.author, :size => 17), author_path(story.author) %> + <%= l story.updated_at %> + + <% if story.own? author %> + <%= render 'order', :story => story %> + <% else %> + No.<%= story.t %> + <% end %> +
diff --git a/app/views/scroll_panels/_form.html.erb b/app/views/scroll_panels/_form.html.erb new file mode 100644 index 00000000..8d705f58 --- /dev/null +++ b/app/views/scroll_panels/_form.html.erb @@ -0,0 +1,20 @@ +<%= form_for(@story) do |f| %> + <%= render 'system/error_explanation', :obj => @story %> + +
+ <%= f.label :comic_id %>
+ <%= f.number_field :comic_id %> +
+
+ <%= f.label :t %>
+ <%= f.number_field :t %> +
+
+ <%= f.label :panel_id %>
+ <%= f.number_field :panel_id %> +
+ +
+ <%= f.submit %> +
+<% end %> diff --git a/app/views/scroll_panels/_licensed_pictures.html.erb b/app/views/scroll_panels/_licensed_pictures.html.erb new file mode 100644 index 00000000..1c10cc72 --- /dev/null +++ b/app/views/scroll_panels/_licensed_pictures.html.erb @@ -0,0 +1,14 @@ +
+ <% licensed_pictures.each do |pid, picture| %> + + + + + +
+ <%= link_to(tag(:img, picture.tmb_opt_img_tag), picture_path(picture.id)) -%> + + <%= render picture.credit_template, :picture => picture %> +
+ <% end %> +
diff --git a/app/views/scroll_panels/_list_item.html.erb b/app/views/scroll_panels/_list_item.html.erb new file mode 100644 index 00000000..1b18f0fc --- /dev/null +++ b/app/views/scroll_panels/_list_item.html.erb @@ -0,0 +1,28 @@ + + + <%= link_to comic_icon(:object => story.comic, :size => 25), comic_path(story.comic) %> + + + <%= link_to h(story.comic.title), :controller => 'stories', :action => :comic, :id => story.comic.id %> + + + <%= link_to author_icon(:object => story.comic.author, :size => 17), author_path(story.comic.author) %> + + + <%= link_to story_icon(:object => story, :size => 25), story_path(story) %> + + + <%= link_to author_icon(:object => story.author, :size => 17), author_path(story.author) %> + + + No.<%= story.t %> + + + <%= l story.updated_at %> + + + <% if story.panel %> + <%= h story.panel.caption %> + <% end %> + + diff --git a/app/views/scroll_panels/_order.html.erb b/app/views/scroll_panels/_order.html.erb new file mode 100644 index 00000000..e0ceadfe --- /dev/null +++ b/app/views/scroll_panels/_order.html.erb @@ -0,0 +1,15 @@ +<%= form_for(story) do |f| %> + + + + + +
+ No. + <%= f.number_field :t, :size => 3 %> + <%= f.hidden_field :panel_id %> + <%= f.hidden_field :comic_id %> + + <%= f.submit t 'stories.move' %> +
+<% end %> diff --git a/app/views/scroll_panels/_scroll_header.html.erb b/app/views/scroll_panels/_scroll_header.html.erb new file mode 100644 index 00000000..d1eb9e77 --- /dev/null +++ b/app/views/scroll_panels/_scroll_header.html.erb @@ -0,0 +1,40 @@ +

+ <%= link_to comic_icon, comic_path(comic) %> + <%= link_to h(comic.title), :controller => 'stories', :action => :comic, :id => comic.id %> +

+<% if comic.own? author -%> + <%= form_for(comic) do |f| %> +
+ <%= f.label :title %>
+ <%= f.text_field :title %> +
+
+ <%= f.label :visible %>
+ <%= f.collection_select :visible, t_select_items(MagicNumber['comic_visible_items']), :last, :first, :html => {:selected => @comic.visible} %> +
+
+ <%= f.submit %> +
+ <% end %> +<% else %> +

+ <%= t_m 'Comic.visible' -%>: + <%= t_selected_item('comic_visible_items', @comic.visible) %> +

+<% end %> + +

+ <%= t_m 'Comic.author_id' -%>: + <%= link_to h(@comic.author.name), author_path(@comic.author) %> +

+ +

+ <%= t_m 'Comic.created_at' -%>: + <%= l @comic.created_at %> +

+ +

+ <%= t_m 'Comic.updated_at' -%>: + <%= l @comic.updated_at %> +

+ diff --git a/app/views/scroll_panels/browse.html.erb b/app/views/scroll_panels/browse.html.erb new file mode 100644 index 00000000..24a7a6ca --- /dev/null +++ b/app/views/scroll_panels/browse.html.erb @@ -0,0 +1,28 @@ +

<%= notice %>

+ +

+ comic_id: + <%= @story.comic_id %> +

+ +

+ panel_id: + <%= @story.panel_id %> +

+ +

+ t: + <%= @story.t %> +

+ +

+ author_id: + <%= @story.author_id %> +

+ +

+ updated_at: + <%= @story.updated_at %> +

+ +<%= link_to 'Back', :action => :list %> diff --git a/app/views/scroll_panels/edit.html.erb b/app/views/scroll_panels/edit.html.erb new file mode 100644 index 00000000..cee9463d --- /dev/null +++ b/app/views/scroll_panels/edit.html.erb @@ -0,0 +1,5 @@ +

<%= t('.title') %>

+

<%= notice %>

+ +<%= render 'form' %> +<%= button_to 'Destroy', @story.panel, confirm: 'Are you sure?', method: :delete %> diff --git a/app/views/scroll_panels/edit.js.erb b/app/views/scroll_panels/edit.js.erb new file mode 100644 index 00000000..29c687f7 --- /dev/null +++ b/app/views/scroll_panels/edit.js.erb @@ -0,0 +1 @@ +$("#story-update-<%= @story.id -%>").html("<%= escape_javascript(render('editform')) -%>"); diff --git a/app/views/scroll_panels/index.html.erb b/app/views/scroll_panels/index.html.erb new file mode 100644 index 00000000..7b61ab84 --- /dev/null +++ b/app/views/scroll_panels/index.html.erb @@ -0,0 +1,8 @@ +

<%= t '.title' -%>

+ + <% @stories.each do |story| %> + <%= render 'list_item', :story => story, :author => @author %> + <% end %> +
+<%= paginate(@paginate) %> +<%= link_to t('stories.new.title'), new_story_path %> diff --git a/app/views/scroll_panels/list.html.erb b/app/views/scroll_panels/list.html.erb new file mode 100644 index 00000000..6fae81c5 --- /dev/null +++ b/app/views/scroll_panels/list.html.erb @@ -0,0 +1,29 @@ +

Listing Story

+ + + + + + + + + + + + + +<% @stories.each do |story| %> + + + + + + + + + + +<% end %> +
idcomic_idpanel_idtauthor_idcreated_atupdated_at
<%= link_to story.id, :action => :browse, :id => story.id %><%= story.comic_id %><%= story.panel_id %><%= story.t %><%= link_to story.author_id, :controller => '/authors', :action => :browse, :id => story.author_id %><%= story.created_at %><%= story.updated_at %> +
+ diff --git a/app/views/scroll_panels/new.html.erb b/app/views/scroll_panels/new.html.erb new file mode 100644 index 00000000..f33a2f89 --- /dev/null +++ b/app/views/scroll_panels/new.html.erb @@ -0,0 +1,3 @@ +

<%= t('.title') %>

+ +<%= render 'form' %> diff --git a/app/views/scroll_panels/scroll.html.erb b/app/views/scroll_panels/scroll.html.erb new file mode 100644 index 00000000..631f6f03 --- /dev/null +++ b/app/views/scroll_panels/scroll.html.erb @@ -0,0 +1,33 @@ +<% @page_title = @comic.title %> +

<%= t '.title' -%>

+

<%= notice %>

+<%= render 'comic_header', :comic => @comic, :author => @author %> + +<% if @stories.empty? -%> +

<%= t('stories.comic.empty') %>

+<% else %> + <% @stories.each do |story| %> + <% if story.panel -%> + <%= render 'panels/body', :panel => story.panel, :author => @author, :spot => nil %> + <% end %> + <%= render 'footer', :story => story, :author => @author %> + <% end %> + <%= render 'licensed_pictures', :licensed_pictures => Story.licensed_pictures(@stories) %> + + <% if @prev_offset -%> + <%= link_to h('< @prev_offset, :count => @panel_count}) %> + <% end %> + + <% if @next_offset -%> + <%= link_to h('next>>'), comic_story_path(@comic, {:offset => @next_offset, :count => @panel_count}) %> + <% end %> + +<% end %> +<% if @comic.own? @author -%> +

<%= t('stories.comic.new_panels') -%>

+ + <% @new_panels.each do |panel| %> + <%= render 'append_panel', :comic => @comic, :panel => panel, :author => @author %> + <% end %> +
+<% end %> diff --git a/app/views/scroll_panels/show.html.erb b/app/views/scroll_panels/show.html.erb new file mode 100644 index 00000000..fa0c3a0b --- /dev/null +++ b/app/views/scroll_panels/show.html.erb @@ -0,0 +1,41 @@ +

<%= t('.title') %>

+

<%= notice %>

+ +

+ <%= t_m 'Story.comic_id' -%>: + <%= link_to comic_icon(:object => @story.comic), comic_path(@story.comic) %> + <%= link_to h(@story.comic.title), :controller => 'stories', :action => :comic, :id => @story.comic.id %> +

+ +

+ <%= t_m 'Story.panel_id' -%>: + <%= link_to panel_icon(:object => @story.panel), panel_path(@story.panel) %> +

+ +

+ <%= t_m 'Story.t' -%>: + <%= @story.t %> +

+ +

+ <%= t_m 'Story.author_id' -%>: + <%= link_to author_icon(:object => @story.author), author_path(@story.author) %> + <%= link_to h(@story.author.name), author_path(@story.author) %> +

+ +

+ <%= t_m 'Story.created_at' -%>: + <%= l @story.created_at %> +

+ +

+ <%= t_m 'Story.updated_at' -%>: + <%= l @story.updated_at %> +

+<% if @story.own? @author -%> + <%= link_to t('link.edit'), edit_story_path(@story) %> + <%= link_to t('link.destroy'), story_path(@story), :method => :delete %> +<% end %> + +
+<%= render 'panels/standard', :panel => @story.panel, :author => @author %> diff --git a/app/views/scrolls/_form.html.erb b/app/views/scrolls/_form.html.erb new file mode 100644 index 00000000..84b983cc --- /dev/null +++ b/app/views/scrolls/_form.html.erb @@ -0,0 +1,23 @@ +<%= form_for(@comic) do |f| %> + <%= render 'system/error_explanation', :obj => @comic %> + +
+ <%= f.label :title %>
+ <%= f.text_field :title %> +
+
+ <%= f.label :description %>
+ <%= f.text_area :description %> +
+
+ <%= f.label :visible %>
+ <%= f.collection_select :visible, t_select_items(MagicNumber['comic_visible_items']), :last, :first, :html => {:selected => @comic.visible} %> +
+
+ <%= f.label :author_id %>
+ <%= h @author.name %> +
+
+ <%= f.submit %> +
+<% end %> diff --git a/app/views/scrolls/_list_item.html.erb b/app/views/scrolls/_list_item.html.erb new file mode 100644 index 00000000..2e9d719a --- /dev/null +++ b/app/views/scrolls/_list_item.html.erb @@ -0,0 +1,25 @@ + + + <%= link_to comic_icon(:object => comic, :size => 25), comic_path(comic) %> + <%= link_to h(truncate(comic.title, :length => 40)), :controller => 'stories', :action => :comic, :id => comic.id %> + (<%= comic.stories.size -%>) + + + <%= distance_of_time_in_words_to_now comic.updated_at %> + + + <%= link_to author_icon(:object => comic.author, :size => 25), comic_path(comic.author) %> + <%= link_to h(truncate(comic.author.name, :length => 12)), author_path(comic.author) %> + + + <% if comic.own? author %> + <%= link_to t('link.edit'), edit_comic_path(comic) %> + <%= link_to t('link.destroy'), comic_path(comic), :method => :delete %> + <% end %> + + + + + <%= h(truncate(comic.description, :length => 40)) %> + + diff --git a/app/views/scrolls/browse.html.erb b/app/views/scrolls/browse.html.erb new file mode 100644 index 00000000..c93e6224 --- /dev/null +++ b/app/views/scrolls/browse.html.erb @@ -0,0 +1,34 @@ +

<%= t '.title' -%>

+

+ <%= t_m 'Comic.id' -%>: + <%= h @comic.id %> +

+ +

+ <%= t_m 'Comic.title' -%>: + <%= h @comic.title %> +

+ +

+ <%= t_m 'Comic.visible' -%>: + <%= @comic.visible %> + <%= t_selected_item('comic_visible_items', @comic.visible) %> +

+ +

+ <%= t_m 'Comic.author_id' -%>: + <%= @comic.author_id %> + <%= link_to h(@comic.author.name), browse_author_path(@comic.author) %> +

+ +

+ <%= t_m 'Comic.created_at' -%>: + <%= l @comic.created_at %> +

+ +

+ <%= t_m 'Comic.updated_at' -%>: + <%= l @comic.updated_at %> +

+ +<%= link_to t('link.back'), :action => :list %> diff --git a/app/views/scrolls/edit.html.erb b/app/views/scrolls/edit.html.erb new file mode 100644 index 00000000..1d67f75e --- /dev/null +++ b/app/views/scrolls/edit.html.erb @@ -0,0 +1,4 @@ +

<%= t('.title') %>

+

<%= notice %>

+ +<%= render 'form' %> diff --git a/app/views/scrolls/edit.js.erb b/app/views/scrolls/edit.js.erb new file mode 100644 index 00000000..ab2a7d24 --- /dev/null +++ b/app/views/scrolls/edit.js.erb @@ -0,0 +1 @@ +$("#newcomic").html("<%= escape_javascript(render('form')) -%>"); diff --git a/app/views/scrolls/index.atom.builder b/app/views/scrolls/index.atom.builder new file mode 100644 index 00000000..a1e9b0c0 --- /dev/null +++ b/app/views/scrolls/index.atom.builder @@ -0,0 +1,25 @@ +atom_feed( + :language => 'ja-JP', + :root_url => root_url, + :url => root_url(:format => :atom), + :id => root_url +) do |feed| + feed.title MagicNumber['profile']['users']['caption'] + feed.subtitle sanitize(MagicNumber['profile']['users']['description'], :tags => %w(a p img br)) + feed.updated Time.now + feed.author {|author| author.name(MagicNumber['profile']['web_master'])} + + @comics.each do |comic| + feed.entry( + comic, + :url => comic_url(comic), + :id => comic_url(comic), + :published => comic.updated_at, + :updated => comic.updated_at + ) do |item| + item.title(comic.title) + item.content(comic.description, :type => 'html') + item.author {|author| author.name(comic.author.name)} + end + end +end diff --git a/app/views/scrolls/index.html.erb b/app/views/scrolls/index.html.erb new file mode 100644 index 00000000..cef2ab93 --- /dev/null +++ b/app/views/scrolls/index.html.erb @@ -0,0 +1,9 @@ +

<%= t '.title' -%>

+ + + <% @comics.each do |comic| %> + <%= render 'list_item', :comic => comic, :author => @author %> + <% end %> +
+<%= paginate(@paginate) %> +<%= link_to t('comics.new.title'), new_comic_path %> diff --git a/app/views/scrolls/index.rss.builder b/app/views/scrolls/index.rss.builder new file mode 100644 index 00000000..b319a9d0 --- /dev/null +++ b/app/views/scrolls/index.rss.builder @@ -0,0 +1,24 @@ +xml.instruct! + +xml.rss("version" => "2.0", + "xmlns:dc" => "http://purl.org/dc/elements/1.1/", + "xmlns:atom" => "http://www.w3.org/2005/Atom") do + xml.channel do + xml.title MagicNumber['profile']['users']['caption'] + xml.link root_url + xml.pubDate Time.now.rfc822 + xml.description sanitize(MagicNumber['profile']['users']['description'], :tags => %w(a p img br)) + xml.atom :link, "href" => @rss_url, "rel" => "self", "type" => "application/rss+xml" + + @comics.each do |comic| + xml.item do + xml.title comic.title + xml.link comic_url(comic) + xml.guid comic_url(comic) + xml.description comic.description + xml.pubDate comic.updated_at.to_formatted_s(:rfc822) + xml.dc :creator, comic.author.name + end + end + end +end diff --git a/app/views/scrolls/list.html.erb b/app/views/scrolls/list.html.erb new file mode 100644 index 00000000..43fdf7e5 --- /dev/null +++ b/app/views/scrolls/list.html.erb @@ -0,0 +1,24 @@ +

<%= t '.title' -%>

+ + + + + + + + + + + +<% @comics.each do |comic| %> + + + + + + + + +<% end %> +
<%= t_m 'Comic.id' -%><%= t_m 'Comic.title' -%><%= t_m 'Comic.visible' -%><%= t_m 'Comic.author_id' -%><%= t_m 'Comic.created_at' -%><%= t_m 'Comic.updated_at' -%>
<%= link_to comic.id, browse_comic_path(comic) %><%= h(truncate(comic.title, :length => 12)) %><%= comic.visible %><%= link_to comic.author_id, browse_author_path(comic.author) %><%= l comic.created_at %><%= l comic.updated_at %>
+ diff --git a/app/views/scrolls/new.html.erb b/app/views/scrolls/new.html.erb new file mode 100644 index 00000000..7142b57d --- /dev/null +++ b/app/views/scrolls/new.html.erb @@ -0,0 +1,5 @@ +

<%= t('.title') %>

+ +<%= render 'form' %> + +<%= link_to t('link.back'), comics_path %> diff --git a/app/views/scrolls/new.js.erb b/app/views/scrolls/new.js.erb new file mode 100644 index 00000000..ab2a7d24 --- /dev/null +++ b/app/views/scrolls/new.js.erb @@ -0,0 +1 @@ +$("#newcomic").html("<%= escape_javascript(render('form')) -%>"); diff --git a/app/views/scrolls/show.atom.builder b/app/views/scrolls/show.atom.builder new file mode 100644 index 00000000..6f5c967f --- /dev/null +++ b/app/views/scrolls/show.atom.builder @@ -0,0 +1,25 @@ +atom_feed( + :language => 'ja-JP', + :root_url => root_url, + :url => root_url(:format => :atom), + :id => root_url +) do |feed| + feed.title MagicNumber['profile']['users']['caption'] + feed.subtitle sanitize(MagicNumber['profile']['users']['description'], :tags => %w(a p img br)) + feed.updated Time.now + feed.author {|author| author.name(MagicNumber['profile']['web_master'])} + + @comic.stories.each do |story| + feed.entry( + story.panel, + :url => panel_url(story.panel), + :id => panel_url(story.panel), + :published => story.panel.updated_at, + :updated => story.panel.updated_at + ) do |item| + item.title(story.panel.caption) + item.content(story.panel.scenario, :type => 'html') + item.author {|author| author.name(story.panel.author.name)} + end + end +end diff --git a/app/views/scrolls/show.html.erb b/app/views/scrolls/show.html.erb new file mode 100644 index 00000000..81a1bbf3 --- /dev/null +++ b/app/views/scrolls/show.html.erb @@ -0,0 +1,35 @@ +<% @page_title = t('.title') + ':' + @comic.title %> +

<%= t('.title') %>

+

<%= notice %>

+ +

+ <%= t_m 'Comic.title' -%>: + <%= link_to h(@comic.title), :controller => 'stories', :action => :comic, :id => @comic.id %> +

+ +

+ <%= t_m 'Comic.description' -%>: + <%= h(@comic.description) %> +

+ +

+ <%= t_m 'Comic.visible' -%>: + <%= t_selected_item('comic_visible_items', @comic.visible) %> +

+ +

+ <%= t_m 'Comic.author_id' -%>: + <%= link_to h(@comic.author.name), author_path(@comic.author) %> +

+ +

+ <%= t_m 'Comic.created_at' -%>: + <%= l @comic.created_at %> +

+ +

+ <%= t_m 'Comic.updated_at' -%>: + <%= l @comic.updated_at %> +

+ +<%= link_to t('link.edit'), edit_comic_path(@comic) %> diff --git a/app/views/scrolls/show.rss.builder b/app/views/scrolls/show.rss.builder new file mode 100644 index 00000000..553f344f --- /dev/null +++ b/app/views/scrolls/show.rss.builder @@ -0,0 +1,24 @@ +xml.instruct! + +xml.rss("version" => "2.0", + "xmlns:dc" => "http://purl.org/dc/elements/1.1/", + "xmlns:atom" => "http://www.w3.org/2005/Atom") do + xml.channel do + xml.title MagicNumber['profile']['users']['caption'] + xml.link root_url + xml.pubDate Time.now.rfc822 + xml.description sanitize(MagicNumber['profile']['users']['description'], :tags => %w(a p img br)) + xml.atom :link, "href" => @rss_url, "rel" => "self", "type" => "application/rss+xml" + + @comic.stories.each do |story| + xml.item do + xml.title story.panel.caption + xml.link panel_url(story.panel) + xml.guid panel_url(story.panel) + xml.description story.panel.plain_scenario + xml.pubDate story.panel.updated_at.to_formatted_s(:rfc822) + xml.dc :creator, story.panel.author.name + end + end + end +end diff --git a/db/migrate/20130906044356_create_scrolls.rb b/db/migrate/20130906044356_create_scrolls.rb new file mode 100644 index 00000000..acce49d0 --- /dev/null +++ b/db/migrate/20130906044356_create_scrolls.rb @@ -0,0 +1,12 @@ +class CreateScrolls < ActiveRecord::Migration + def change + create_table :scrolls do |t| + t.string :title, :null => false, :limit => 100 + t.integer :visible, :null => false, :default => 0 + t.text :description + t.integer :author_id, :null => false + + t.timestamps + end + end +end diff --git a/db/migrate/20130906044457_create_scroll_panels.rb b/db/migrate/20130906044457_create_scroll_panels.rb new file mode 100644 index 00000000..d260b870 --- /dev/null +++ b/db/migrate/20130906044457_create_scroll_panels.rb @@ -0,0 +1,12 @@ +class CreateScrollPanels < ActiveRecord::Migration + def change + create_table :scroll_panels do |t| + t.integer :scroll_id, :null => false, :default => 0 + t.integer :panel_id, :null => false, :default => 0 + t.integer :author_id, :null => false, :default => 0 + t.integer :t, :null => false, :default => 0 + + t.timestamps + end + end +end diff --git a/spec/controllers/scroll_panels_controller_spec.rb b/spec/controllers/scroll_panels_controller_spec.rb new file mode 100644 index 00000000..2a4db41f --- /dev/null +++ b/spec/controllers/scroll_panels_controller_spec.rb @@ -0,0 +1,1456 @@ +# -*- encoding: utf-8 -*- +require 'spec_helper' +#ストーリー +describe ScrollPanelsController 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 = FactoryGirl.create :author, :user_id => @user.id + @scroll = FactoryGirl.create :scroll, :author_id => @user.author.id + @panel = FactoryGirl.create :panel, :author_id => @author.id + end + +if MagicNumber['run_mode'] == 1 + describe '一覧表示に於いて' do + before do + sign_in @user + @scroll_panel = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + ScrollPanel.stub(:list).and_return([@scroll_panel, @scroll_panel, @scroll_panel]) + end + context 'パラメータpageについて' 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 ScrollPanel.default_page_size + end + it '最大を超えると@page_sizeにデフォルト最大値が入る' do + get :index, :page_size => 1500 + assigns(:page_size).should eq ScrollPanel.max_page_size + end + it '不正な値が入ると@page_sizeにデフォルト最大値が入る' do + get :index, :page_size => 0 + assigns(:page_size).should eq ScrollPanel.default_page_size + end + end + context 'つつがなく終わるとき' do + it 'ステータスコード200 OKを返す' do + get :index + response.should be_success + end + it 'ストーリーモデルに一覧を問い合わせている' do + ScrollPanel.should_receive(:list).exactly(1) + get :index + end + it '@scroll_panelsにリストを取得している' do + get :index + assigns(:scroll_panels).should have_at_least(3).items + end + context 'html形式' do + it '@paginateにページ制御を取得している' do + get :index + assigns(:paginate).is_a?(Kaminari::PaginatableArray).should be_true + end + it 'indexテンプレートを描画する' do + get :index + response.should render_template("index") + 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 + ScrollPanel.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?("panel_id").should be_true + json.first.has_key?("scroll_id").should be_true + json.first.has_key?("t").should be_true + end + end + end + context 'ユーザ権限がないとき' do + before do + sign_out @user + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + get :index + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + get :index + response.should redirect_to '/users/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 + context 'ユーザ権限はないが管理者権限があるとき' do + before do + sign_out @user + sign_in @admin + end + it 'ステータスコード200 OKを返す' do + get :index + response.should be_success + end + end + context 'ユーザだが作家登録していないとき' do + before do + @author.destroy + end + it 'ステータスコード200 OKを返す' do + get :index + response.should be_success + end + end + end + + describe '単体表示に於いて' do + before do + sign_in @user + @scroll_panel = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + Scroll.stub(:show).with(@scroll.id.to_s, [@user, nil]).and_return(@scroll) + Scroll.stub(:show).with(@scroll.id.to_s, [nil, @admin]).and_return(@scroll) + ScrollPanel.stub(:show).with(@scroll_panel.id.to_s, [@user, nil]).and_return(@scroll_panel) + ScrollPanel.stub(:show).with(@scroll_panel.id.to_s, [nil, @admin]).and_return(@scroll_panel) + end + context 'つつがなく終わるとき' do + it 'ストーリーモデルに単体取得を問い合わせている' do + ScrollPanel.should_receive(:show).with(@scroll_panel.id.to_s, [@user, nil]).exactly(1) + get :show, :id => @scroll_panel.id + end + it '@scroll_panelにアレを取得している' do + get :show, :id => @scroll_panel.id + assigns(:scroll_panel).should eq @scroll_panel + end + context 'html形式' do + it 'ステータスコード200 OKを返す' do + get :show, :id => @scroll_panel.id + response.should be_success + end + it 'showテンプレートを描画する' do + get :show, :id => @scroll_panel.id + response.should render_template("show") + end + end + context 'json形式' do + it 'ステータスコード200 OKを返す' do + get :show, :id => @scroll_panel.id, :format => :json + response.should be_success + end + it 'jsonデータを返す' do + get :show, :id => @scroll_panel.id, :format => :json + lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError) + end + it 'ストーリーモデルにストーリーjson出力を問い合わせている' do + ScrollPanel.any_instance.should_receive(:scroll_panel_as_json).exactly(1) + get :show, :id => @scroll_panel.id, :format => :json + end + it 'データがアレになっている' do + get :show, :id => @scroll_panel.id, :format => :json + json = JSON.parse response.body + json.has_key?("panel_id").should be_true + json.has_key?("scroll_id").should be_true + json.has_key?("author_id").should be_true + end + end + end + context 'ユーザ権限がないとき' do + before do + sign_out @user + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + get :show, :id => @scroll_panel.id + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + get :show, :id => @scroll_panel.id + response.body.should redirect_to '/users/sign_in' + end + end + context 'json形式' do + it 'ステータスコード401 Unauthorizedを返す' do + get :show, :id => @scroll_panel.id, :format => :json + response.status.should eq 401 + end + it '応答メッセージにUnauthorizedを返す' do + get :show, :id => @scroll_panel.id, :format => :json + response.message.should match(/Unauthorized/) + end + end + end + context 'ユーザ権限はないが管理者権限があるとき' do + before do + sign_out @user + sign_in @admin + end + it 'ステータスコード200 OKを返す' do + get :show, :id => @scroll_panel.id + response.should be_success + end + end + context 'ユーザだが作家登録していないとき' do + before do + @author.destroy + end + it 'ステータスコード200 OKを返す' do + get :show, :id => @scroll_panel.id + response.should be_success + end + end + end + + describe '閲覧に於いて' do + before do + @scroll_panel = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + Scroll.stub(:show).with(@scroll.id.to_s, [@user, nil]).and_return(@scroll) + Scroll.stub(:show).with(@scroll.id.to_s, [nil, @admin]).and_return(@scroll) + ScrollPanel.stub(:count).and_return(10) + ScrollPanel.stub(:play_list).with(any_args).and_return([@scroll_panel, @scroll_panel, @scroll_panel]) + sign_in @user + end + context 'パラメータチェックする' do + it '与えられたoffsetがセットされている' do + get :scroll, :id => @scroll.id, :offset => 5 + assigns(:offset).should eq 5 + end + it '省略されると@offsetに0値が入る' do + get :scroll, :id => @scroll.id + assigns(:offset).should eq 0 + end + it '与えられたcountがセットされている' do + get :scroll, :id => @scroll.id, :count => 4 + assigns(:panel_count).should eq 4 + end + it '省略されると@panel_countにデフォルト値が入る' do + get :scroll, :id => @scroll.id + assigns(:panel_count).should eq ScrollPanel.default_panel_size + end + it '最大を超えると@panel_countにデフォルト最大値が入る' do + get :scroll, :id => @scroll.id, :count => 1500 + assigns(:panel_count).should eq ScrollPanel.max_panel_size + end + it '不正な値が入ると@panel_countにデフォルト最大値が入る' do + get :scroll, :id => @scroll.id, :count => -1 + assigns(:panel_count).should eq ScrollPanel.default_panel_size + end + end + context '事前チェックする' do + it 'コミックモデルに単体取得を問い合わせている' do + Scroll.should_receive(:show).with(@scroll.id.to_s, [@user, nil]).exactly(1) + get :scroll, :id => @scroll.id + end + it 'ストーリーモデルにプレイリスト取得を問い合わせている' do + ScrollPanel.should_receive(:play_list).with(@scroll, @author, 0, 30).exactly(1) + get :scroll, :id => @scroll.id + end + end + context 'つつがなく終わるとき' do + it '@scroll_panelsにリストを取得している' do + get :scroll, :id => @scroll.id + assigns(:scroll_panels).should have_at_least(3).items + end + context 'html形式' do + it 'ステータスコード200 OKを返す' do + get :scroll, :id => @scroll.id + response.should be_success + end + it 'scrollテンプレートを描画する' do + get :scroll, :id => @scroll.id + response.should render_template("scroll") + end + end + context 'json形式' do + it 'ステータスコード200 OKを返す' do + get :scroll, :id => @scroll.id, :format => :json + response.should be_success + end + it 'jsonデータを返す' do + get :scroll, :id => @scroll.id, :format => :json + lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError) + end + it 'ストーリーモデルにストーリーリストのjson出力を問い合わせている' do + ScrollPanel.should_receive(:list_as_json_text).exactly(1) + get :scroll, :id => @scroll.id, :format => :json + end + it 'データがリスト構造になっている' do + get :scroll, :id => @scroll.id, :format => :json + json = JSON.parse response.body + json.should have_at_least(3).items + end + it 'リストの先頭くらいはストーリーっぽいものであって欲しい' do + get :scroll, :id => @scroll.id, :format => :json + json = JSON.parse response.body + json.first.has_key?("panel_id").should be_true + json.first.has_key?("scroll_id").should be_true + json.first.has_key?("author_id").should be_true + end + end + end + context 'ユーザ権限がないとき' do + before do + sign_out @user + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + get :scroll, :id => @scroll.id + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + get :scroll, :id => @scroll.id + response.should redirect_to '/users/sign_in' + end + end + context 'json形式' do + it 'ステータスコード401 Unauthorizedを返す' do + get :scroll, :id => @scroll.id, :format => :json + response.status.should eq 401 + end + it '応答メッセージにUnauthorizedを返す' do + get :scroll, :id => @scroll.id, :format => :json + response.message.should match(/Unauthorized/) + end + end + end + context 'ユーザ権限はないが管理者権限があるとき' do + before do + sign_out @user + sign_in @admin + end + it 'ステータスコード200 OKを返す' do + get :scroll, :id => @scroll.id + response.should be_success + end + end + context 'ユーザだが作家登録していないとき' do + before do + @author.destroy + end + it 'ステータスコード200 OKを返す' do + get :scroll, :id => @scroll.id + response.should be_success + end + end + end + + describe '新規作成フォーム表示に於いて' do + before do + sign_in @user + end + context 'つつがなく終わるとき' do + it '@scroll_panelに新規データを用意している' do + get :new + assigns(:scroll_panel).should be_a_new(ScrollPanel) + end + it 'モデルにデフォルト値補充を依頼している' do + ScrollPanel.any_instance.should_receive(:supply_default).exactly(1) + get :new + end + context 'html形式' do + it 'ステータスコード200 OKを返す' do + get :new + response.should be_success + end + it 'newテンプレートを描画する' do + get :new + response.should render_template("new") + end + end + context 'js形式' do + it 'ステータスコード200 OKを返す' do + get :new, :format => :js + response.should be_success + end + it 'new.jsテンプレートを描画する' do + get :new, :format => :js + response.should render_template("new") + end + end + context 'json形式' do + it 'ステータスコード200 OKを返す' do + get :new, :format => :json + response.should be_success + end + it 'jsonデータを返す' do + get :new, :format => :json + lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError) + end + it 'ストーリーモデルのストーリーのjson出力を問い合わせている' do + ScrollPanel.any_instance.should_receive(:scroll_panel_as_json).exactly(1) + get :new, :format => :json + end + it 'データがアレになっている' do + get :new, :format => :json + json = JSON.parse response.body + json.has_key?("panel_id").should be_true + json.has_key?("scroll_id").should be_true + json.has_key?("author_id").should be_true + end + end + end + context 'ユーザ権限がないとき' do + before do + sign_out @user + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + get :new + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + get :new + response.body.should redirect_to '/users/sign_in' + end + end + context 'json形式' do + it 'ステータスコード401 Unauthorizedを返す' do + get :new, :format => :json + response.status.should eq 401 + end + it '応答メッセージにUnauthorizedを返す' do + get :new, :format => :json + response.message.should match(/Unauthorized/) + end + end + end + context 'ユーザ権限はないが管理者権限があるとき' do + before do + sign_out @user + sign_in @admin + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + get :new + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + get :new + response.body.should redirect_to '/users/sign_in' + end + end + end + context 'ユーザだが作家登録していないとき' do + before do + @author.destroy + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + get :new + response.status.should eq 302 + end + it '作家登録ページへ遷移する' do + get :new + response.body.should redirect_to new_author_path + end + end + end + end + + describe '新規作成に於いて' do + before do + @attr = FactoryGirl.attributes_for(:scroll_panel, :t => nil, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id) + sign_in @user + end + context 'つつがなく終わるとき' do + it 'デフォルト値補充を依頼する' do + ScrollPanel.any_instance.should_receive(:supply_default).exactly(1) + post :create, :scroll_panel => @attr + end + it 'POSTデータから、カラム値を復元している' do + ScrollPanel.any_instance.stub(:store).and_return(true) + post :create, :scroll_panel => @attr + assigns(:scroll_panel).scroll_id.should eq @scroll.id + assigns(:scroll_panel).panel_id.should eq @panel.id + end + it '上書き補充を依頼する' do + ScrollPanel.any_instance.should_receive(:overwrite).exactly(1) + post :create, :scroll_panel => @attr + end + it 'コミックモデルに編集取得を依頼している' do + Scroll.should_receive(:edit).with(@scroll.id, @author).exactly(1) + post :create, :scroll_panel => @attr + end + it 'コマモデルに単体取得を依頼している' do + Panel.should_receive(:show).with(@panel.id, @author).exactly(1) + post :create, :scroll_panel => @attr + end + it 'モデルに保存依頼する' do + ScrollPanel.any_instance.should_receive(:store).exactly(1) + post :create, :scroll_panel => @attr + end + it "@scroll_panelに作成されたコマを保持していて、それがDBにある" do + post :create, :scroll_panel => @attr + assigns(:scroll_panel).should be_a(ScrollPanel) + assigns(:scroll_panel).should be_persisted + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + ScrollPanel.any_instance.stub(:store).and_return(true) + post :create, :scroll_panel => @attr + response.status.should eq 302 + end + it 'コミックのストーリー表示へ遷移する' do +# ScrollPanel.any_instance.stub(:store).and_return(true) + post :create, :scroll_panel => @attr + response.should redirect_to(:action => :scroll, :id => @attr[:scroll_id]) + end + end + context 'json形式' do + it 'ステータスコード200 OKを返す' do +# ScrollPanel.any_instance.stub(:store).and_return(true) + post :create, :scroll_panel => @attr, :format => :json + response.should be_success + end + it '作成されたコマをjsonデータで返す' do + post :create, :scroll_panel => @attr, :format => :json + lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError) + end + it 'ストーリーモデルのストーリーのjson出力を問い合わせている' do + ScrollPanel.any_instance.should_receive(:scroll_panel_as_json).exactly(1) + post :create, :scroll_panel => @attr, :format => :json + end + it 'データがアレになっている' do + post :create, :scroll_panel => @attr, :format => :json + json = JSON.parse response.body + json["t"].should eq 0 + end + end + end + context 'ユーザ権限がないとき' do + before do + sign_out @user + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + post :create, :scroll_panel => @attr + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + post :create, :scroll_panel => @attr + response.body.should redirect_to '/users/sign_in' + end + end + context 'json形式' do + it 'ステータスコード401 Unauthorizedを返す' do + post :create, :scroll_panel => @attr, :format => :json + response.status.should eq 401 + end + it '応答メッセージにUnauthorizedを返す' do + post :create, :scroll_panel => @attr, :format => :json + response.message.should match(/Unauthorized/) + end + end + end + context 'ユーザ権限はないが管理者権限があるとき' do + before do + sign_out @user + sign_in @admin + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + post :create, :scroll_panel => @attr + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + post :create, :scroll_panel => @attr + response.body.should redirect_to '/users/sign_in' + end + end + end + context 'ユーザだが作家登録していないとき' do + before do + @author.destroy + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + post :create, :scroll_panel => @attr + response.status.should eq 302 + end + it '作家登録ページへ遷移する' do + post :create, :scroll_panel => @attr + response.body.should redirect_to new_author_path + end + end + end + context '検証、保存に失敗した' do + before do + ScrollPanel.any_instance.stub(:store).and_return(false) + end + it "未保存のコマを保持している" do + post :create, :scroll_panel => @attr + assigns(:scroll_panel).should be_a_new(ScrollPanel) + end + context 'html形式' do + it 'ステータスコード200 OKを返す' do + post :create, :scroll_panel => @attr + response.status.should eq 200 + end + it '新規ページを描画する' do + post :create, :scroll_panel => @attr + response.should render_template("new") + end + end + context 'json形式' do + it 'ステータスコード422 unprocessable_entity を返す' do + post :create, :scroll_panel => @attr, :format => :json + response.status.should eq 422 + end + it '応答メッセージUnprocessable Entityを返す' do + post :create, :scroll_panel => @attr, :format => :json + response.message.should match(/Unprocessable/) + end + end + end + end + + describe '編集フォーム表示に於いて' do + before do + @scroll_panel = FactoryGirl.create :scroll_panel, :author_id => @author.id + sign_in @user + ScrollPanel.stub(:show).and_return(@scroll_panel) + end + context 'つつがなく終わるとき' do + it 'ストーリーモデルに編集取得を問い合わせている' do + ScrollPanel.should_receive(:edit).exactly(1) + get :edit, :id => @scroll_panel.id + end + it '@scroll_panelにデータを用意している' do + get :edit, :id => @scroll_panel.id + assigns(:scroll_panel).should eq @scroll_panel + end + context 'html形式' do + it 'ステータスコード200 OKを返す' do + get :edit, :id => @scroll_panel.id + response.should be_success + end + it 'editテンプレートを描画する' do + get :edit, :id => @scroll_panel.id + response.should render_template("edit") + end + end + context 'js形式' do + it 'ステータスコード200 OKを返す' do + get :edit, :id => @scroll_panel.id, :format => :js + response.should be_success + end + it 'edit.jsテンプレートを描画する' do + get :edit, :id => @scroll_panel.id, :format => :js + response.should render_template("edit") + end + end + end + context 'ユーザ権限がないとき' do + before do + sign_out @user + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + get :edit, :id => @scroll_panel.id + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + get :edit, :id => @scroll_panel.id + response.body.should redirect_to '/users/sign_in' + end + end + context 'js形式' do + it 'ステータスコード401 Unauthorizedを返す' do + get :edit, :id => @scroll_panel.id, :format => :js + response.status.should eq 401 + end + it '応答メッセージにUnauthorizedを返す' do + get :edit, :id => @scroll_panel.id, :format => :js + response.message.should match(/Unauthorized/) + end + end + end + context 'ユーザ権限はないが管理者権限があるとき' do + before do + sign_out @user + sign_in @admin + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + get :edit, :id => @scroll_panel.id + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + get :edit, :id => @scroll_panel.id + response.body.should redirect_to '/users/sign_in' + end + end + end + context 'ユーザだが作家登録していないとき' do + before do + @author.destroy + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + get :edit, :id => @scroll_panel.id + response.status.should eq 302 + end + it '作家登録ページへ遷移する' do + get :edit, :id => @scroll_panel.id + response.body.should redirect_to new_author_path + end + end + end + end + + describe '更新に於いて' do + before do + @scroll_panel = FactoryGirl.create :scroll_panel, :author_id => @user.author.id + @attr = FactoryGirl.attributes_for(:scroll_panel, :author_id => @author.id) + sign_in @user + end + context 'つつがなく終わるとき' do + it 'モデルに編集取得依頼する' do + ScrollPanel.stub(:edit).with(any_args).and_return(@scroll_panel) + ScrollPanel.should_receive(:edit).exactly(1) + put :update, :id => @scroll_panel.id, :scroll_panel => @attr + end + it 'POSTデータから、カラム値を復元している' do + ScrollPanel.any_instance.stub(:store).and_return(true) + ScrollPanel.any_instance.should_receive(:attributes=).exactly(1) + put :update, :id => @scroll_panel.id, :scroll_panel => @attr + end + it '上書き補充を依頼する' do + ScrollPanel.any_instance.should_receive(:overwrite).exactly(1) + put :update, :id => @scroll_panel.id, :scroll_panel => @attr + end + it 'モデルに保存依頼する' do + ScrollPanel.any_instance.should_receive(:store).exactly(1) + put :update, :id => @scroll_panel.id, :scroll_panel => @attr + end + it "@scroll_panelに作成されたストーリーを保持していて、それがDBにある" do + put :update, :id => @scroll_panel.id, :scroll_panel => @attr + assigns(:scroll_panel).should be_a(ScrollPanel) + assigns(:scroll_panel).should be_persisted + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + ScrollPanel.any_instance.stub(:store).and_return(true) + put :update, :id => @scroll_panel.id, :scroll_panel => @attr + response.status.should eq 302 + end + it 'ストーリー表示へ遷移する' do +# ScrollPanel.any_instance.stub(:store).and_return(true) + put :update, :id => @scroll_panel.id, :scroll_panel => @attr + response.should redirect_to(:action => :scroll, :id => @attr[:scroll_id]) + end + end + context 'json形式' do + it 'ステータスコード200 OKを返す' do +# ScrollPanel.any_instance.stub(:store).and_return(true) + put :update, :id => @scroll_panel.id, :scroll_panel => @attr, :format => :json + response.should be_success + end + end + end + context 'ユーザ権限がないとき' do + before do + sign_out @user + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + put :update, :id => @scroll_panel.id, :scroll_panel => @attr + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + put :update, :id => @scroll_panel.id, :scroll_panel => @attr + response.body.should redirect_to '/users/sign_in' + end + end + context 'json形式' do + it 'ステータスコード401 Unauthorizedを返す' do + put :update, :id => @scroll_panel.id, :scroll_panel => @attr, :format => :json + response.status.should eq 401 + end + it '応答メッセージにUnauthorizedを返す' do + put :update, :id => @scroll_panel.id, :scroll_panel => @attr, :format => :json + response.message.should match(/Unauthorized/) + end + end + end + context 'ユーザ権限はないが管理者権限があるとき' do + before do + sign_out @user + sign_in @admin + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + put :update, :id => @scroll_panel.id, :scroll_panel => @attr + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + put :update, :id => @scroll_panel.id, :scroll_panel => @attr + response.body.should redirect_to '/users/sign_in' + end + end + end + context 'ユーザだが作家登録していないとき' do + before do + @author.destroy + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + put :update, :id => @scroll_panel.id, :scroll_panel => @attr + response.status.should eq 302 + end + it '作家登録ページへ遷移する' do + put :update, :id => @scroll_panel.id, :scroll_panel => @attr + response.body.should redirect_to new_author_path + end + end + end + context '検証、保存に失敗した' do + before do + ScrollPanel.any_instance.stub(:store).and_return(false) + end + it "指定のコマを保持している" do + put :update, :id => @scroll_panel.id, :scroll_panel => @attr + assigns(:scroll_panel).should eq @scroll_panel + end + context 'html形式' do + it 'ステータスコード200 OKを返す' do + put :update, :id => @scroll_panel.id, :scroll_panel => @attr + response.status.should eq 200 + end + it '編集ページを描画する' do + put :update, :id => @scroll_panel.id, :scroll_panel => @attr + response.should render_template("edit") + end + end + context 'json形式' do + it 'ステータスコード422 unprocessable_entity を返す' do + put :update, :id => @scroll_panel.id, :scroll_panel => @attr, :format => :json + response.status.should eq 422 + end + it '応答メッセージUnprocessable Entityを返す' do + put :update, :id => @scroll_panel.id, :scroll_panel => @attr, :format => :json + response.message.should match(/Unprocessable/) + end + end + end + end + + describe '削除に於いて' do + before do + @scroll_panel = FactoryGirl.create :scroll_panel, :author_id => @author.id + sign_in @user + ScrollPanel.stub(:edit).and_return(@scroll_panel) + end + context '事前チェックしておく' do + before do + ScrollPanel.stub(:edit).with(any_args()).and_return @scroll_panel + ScrollPanel.any_instance.stub(:destroy_and_shorten).with(any_args()).and_return(true) + end + it 'ストーリーモデルに編集取得を問い合わせている' do + ScrollPanel.should_receive(:edit).exactly(1) + delete :destroy, :id => @scroll_panel.id + end + it 'モデルに削除を依頼する' do + ScrollPanel.any_instance.should_receive(:destroy_and_shorten).exactly(1) + delete :destroy, :id => @scroll_panel.id + end + it '@scroll_panelにアレを取得している' do + delete :destroy, :id => @scroll_panel.id + assigns(:scroll_panel).id.should eq(@scroll_panel.id) + end + end + context 'つつがなく終わるとき' do + before do + ScrollPanel.any_instance.stub(:destroy_and_shorten).with(any_args()).and_return(true) + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + delete :destroy, :id => @scroll_panel.id + response.status.should eq 302 + end + it '閲覧ページへ遷移する' do + delete :destroy, :id => @scroll_panel.id + response.should redirect_to(:controller => 'scroll_panels', :action => :scroll, :id => @scroll_panel.scroll_id) + end + end + context 'json形式' do + it 'ステータスコード200 OKを返す' do + delete :destroy, :id => @scroll_panel.id, :format => :json + response.should be_success + end + end + end + context 'ユーザ権限がないとき' do + before do + sign_out @user + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + delete :destroy, :id => @scroll_panel.id + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + delete :destroy, :id => @scroll_panel.id + response.body.should redirect_to '/users/sign_in' + end + end + context 'json形式' do + it 'ステータスコード401 Unauthorizedを返す' do + delete :destroy, :id => @scroll_panel.id, :format => :json + response.status.should eq 401 + end + it '応答メッセージにUnauthorizedを返す' do + delete :destroy, :id => @scroll_panel.id, :format => :json + response.message.should match(/Unauthorized/) + end + end + end + context 'ユーザ権限はないが管理者権限があるとき' do + before do + sign_out @user + sign_in @admin + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + delete :destroy, :id => @scroll_panel.id + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + delete :destroy, :id => @scroll_panel.id + response.body.should redirect_to '/users/sign_in' + end + end + end + context 'ユーザだが作家登録していないとき' do + before do + @author.destroy + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + delete :destroy, :id => @scroll_panel.id + response.status.should eq 302 + end + it '作家登録ページへ遷移する' do + delete :destroy, :id => @scroll_panel.id + response.body.should redirect_to new_author_path + end + end + end + context '削除に失敗したとき' do + before do + ScrollPanel.any_instance.stub(:destroy_and_shorten).with(any_args()).and_return(false) + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + delete :destroy, :id => @scroll_panel.id + response.status.should eq 302 + end + it 'そのコミックの詳細ページへ遷移する' do + delete :destroy, :id => @scroll_panel.id + response.should redirect_to(scroll_panel_path(@scroll_panel)) + end + end + context 'json形式' do + it 'ステータスコード422 unprocessable_entity を返す' do + delete :destroy, :id => @scroll_panel.id, :format => :json + response.status.should eq 422 + end + it '応答メッセージUnprocessable Entityを返す' do + delete :destroy, :id => @scroll_panel.id, :format => :json + response.message.should match(/Unprocessable/) + end + end + end +=begin + context '対象ストーリーがないとき' do + end + context '他人のストーリーだったとき' do + end +=end + end + +else + describe '一覧表示に於いて' do + before do + sign_in @user + @scroll_panel = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + ScrollPanel.stub(:list).and_return([@scroll_panel, @scroll_panel, @scroll_panel]) + end + context 'つつがなく終わるとき' do + it 'ステータスコード200 OKを返す' do + get :index + response.should be_success + 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 + end + end + context 'ユーザ権限がないとき' do + before do + sign_out @user + end + it 'ステータスコード200 OKを返す' do + get :index + response.should be_success + 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 + end + end + end + + describe '単体表示に於いて' do + before do + sign_in @user + @scroll_panel = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + Scroll.stub(:show).with(@scroll.id.to_s, [nil, nil]).and_return(@scroll) + Scroll.stub(:show).with(@scroll.id.to_s, [@user, nil]).and_return(@scroll) + Scroll.stub(:show).with(@scroll.id.to_s, [nil, @admin]).and_return(@scroll) + ScrollPanel.stub(:show).with(@scroll_panel.id.to_s, [nil, nil]).and_return(@scroll_panel) + ScrollPanel.stub(:show).with(@scroll_panel.id.to_s, [@user, nil]).and_return(@scroll_panel) + ScrollPanel.stub(:show).with(@scroll_panel.id.to_s, [nil, @admin]).and_return(@scroll_panel) + end + context 'つつがなく終わるとき' do + context 'html形式' do + it 'ステータスコード200 OKを返す' do + get :show, :id => @scroll_panel.id + response.should be_success + end + it 'showテンプレートを描画する' do + get :show, :id => @scroll_panel.id + response.should render_template("show") + end + end + context 'json形式' do + it 'ステータスコード200 OKを返す' do + get :show, :id => @scroll_panel.id, :format => :json + response.should be_success + end + it 'jsonデータを返す' do + get :show, :id => @scroll_panel.id, :format => :json + lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError) + end + end + end + context 'ユーザ権限がないとき' do + before do + sign_out @user + end + context 'html形式' do + it 'ステータスコード200 OKを返す' do + get :show, :id => @scroll_panel.id + response.should be_success + end + it 'showテンプレートを描画する' do + get :show, :id => @scroll_panel.id + response.should render_template("show") + end + end + context 'json形式' do + it 'ステータスコード200 OKを返す' do + get :show, :id => @scroll_panel.id, :format => :json + response.should be_success + end + it 'jsonデータを返す' do + get :show, :id => @scroll_panel.id, :format => :json + lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError) + end + end + end + end + + describe '閲覧に於いて' do + before do + @scroll_panel = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + Scroll.stub(:show).with(@scroll.id.to_s, [nil, nil]).and_return(@scroll) + Scroll.stub(:show).with(@scroll.id.to_s, [@user, nil]).and_return(@scroll) + Scroll.stub(:show).with(@scroll.id.to_s, [nil, @admin]).and_return(@scroll) + ScrollPanel.stub(:count).and_return(10) + ScrollPanel.stub(:play_list).with(any_args).and_return([@scroll_panel, @scroll_panel, @scroll_panel]) + sign_in @user + end + context 'つつがなく終わるとき' do + context 'html形式' do + it 'ステータスコード200 OKを返す' do + get :scroll, :id => @scroll.id + response.should be_success + end + it 'scrollテンプレートを描画する' do + get :scroll, :id => @scroll.id + response.should render_template("scroll") + end + end + context 'json形式' do + it 'ステータスコード200 OKを返す' do + get :scroll, :id => @scroll.id, :format => :json + response.should be_success + end + it 'jsonデータを返す' do + get :scroll, :id => @scroll.id, :format => :json + lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError) + end + end + end + context 'ユーザ権限がないとき' do + before do + sign_out @user + end + context 'html形式' do + it 'ステータスコード200 OKを返す' do + get :scroll, :id => @scroll.id + response.should be_success + end + it 'scrollテンプレートを描画する' do + get :scroll, :id => @scroll.id + response.should render_template("scroll") + end + end + context 'json形式' do + it 'ステータスコード200 OKを返す' do + get :scroll, :id => @scroll.id, :format => :json + response.should be_success + end + it 'jsonデータを返す' do + get :scroll, :id => @scroll.id, :format => :json + lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError) + end + end + end + end + + describe '新規作成フォーム表示に於いて' do + before do + sign_in @user + end + context 'つつがなく終わるとき' do + context 'html形式' do + it 'ステータスコード200 OKを返す' do + get :new + response.should be_success + end + it 'newテンプレートを描画する' do + get :new + response.should render_template("new") + end + end + context 'js形式' do + it 'ステータスコード200 OKを返す' do + get :new, :format => :js + response.should be_success + end + it 'new.jsテンプレートを描画する' do + get :new, :format => :js + response.should render_template("new") + end + end + context 'json形式' do + it 'ステータスコード200 OKを返す' do + get :new, :format => :json + response.should be_success + end + it 'jsonデータを返す' do + get :new, :format => :json + lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError) + end + end + end + context 'ユーザ権限がないとき' do + before do + sign_out @user + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + get :new + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + get :new + response.body.should redirect_to '/users/sign_in' + end + end + context 'json形式' do + it 'ステータスコード401 Unauthorizedを返す' do + get :new, :format => :json + response.status.should eq 401 + end + it '応答メッセージにUnauthorizedを返す' do + get :new, :format => :json + response.message.should match(/Unauthorized/) + end + end + end + end + + describe '新規作成に於いて' do + before do + @attr = FactoryGirl.attributes_for(:scroll_panel, :t => nil, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id) + sign_in @user + end + context 'つつがなく終わるとき' do + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + ScrollPanel.any_instance.stub(:store).and_return(true) + post :create, :scroll_panel => @attr + response.status.should eq 302 + end + it 'コミックのストーリー表示へ遷移する' do +# ScrollPanel.any_instance.stub(:store).and_return(true) + post :create, :scroll_panel => @attr + response.should redirect_to(:action => :scroll, :id => @attr[:scroll_id]) + end + end + context 'json形式' do + it 'ステータスコード200 OKを返す' do +# ScrollPanel.any_instance.stub(:store).and_return(true) + post :create, :scroll_panel => @attr, :format => :json + response.should be_success + end + it '作成されたコマをjsonデータで返す' do + post :create, :scroll_panel => @attr, :format => :json + lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError) + end + end + end + context 'ユーザ権限がないとき' do + before do + sign_out @user + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + post :create, :scroll_panel => @attr + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + post :create, :scroll_panel => @attr + response.body.should redirect_to '/users/sign_in' + end + end + context 'json形式' do + it 'ステータスコード401 Unauthorizedを返す' do + post :create, :scroll_panel => @attr, :format => :json + response.status.should eq 401 + end + it '応答メッセージにUnauthorizedを返す' do + post :create, :scroll_panel => @attr, :format => :json + response.message.should match(/Unauthorized/) + end + end + end + end + + describe '編集フォーム表示に於いて' do + before do + @scroll_panel = FactoryGirl.create :scroll_panel, :author_id => @author.id + sign_in @user + ScrollPanel.stub(:show).and_return(@scroll_panel) + end + context 'つつがなく終わるとき' do + context 'html形式' do + it 'ステータスコード200 OKを返す' do + get :edit, :id => @scroll_panel.id + response.should be_success + end + it 'editテンプレートを描画する' do + get :edit, :id => @scroll_panel.id + response.should render_template("edit") + end + end + context 'js形式' do + it 'ステータスコード200 OKを返す' do + get :edit, :id => @scroll_panel.id, :format => :js + response.should be_success + end + it 'edit.jsテンプレートを描画する' do + get :edit, :id => @scroll_panel.id, :format => :js + response.should render_template("edit") + end + end + end + context 'ユーザ権限がないとき' do + before do + sign_out @user + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + get :edit, :id => @scroll_panel.id + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + get :edit, :id => @scroll_panel.id + response.body.should redirect_to '/users/sign_in' + end + end + context 'js形式' do + it 'ステータスコード401 Unauthorizedを返す' do + get :edit, :id => @scroll_panel.id, :format => :js + response.status.should eq 401 + end + it '応答メッセージにUnauthorizedを返す' do + get :edit, :id => @scroll_panel.id, :format => :js + response.message.should match(/Unauthorized/) + end + end + end + end + + describe '更新に於いて' do + before do + @scroll_panel = FactoryGirl.create :scroll_panel, :author_id => @user.author.id + @attr = FactoryGirl.attributes_for(:scroll_panel, :author_id => @author.id) + sign_in @user + end + context 'つつがなく終わるとき' do + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + ScrollPanel.any_instance.stub(:store).and_return(true) + put :update, :id => @scroll_panel.id, :scroll_panel => @attr + response.status.should eq 302 + end + it 'ストーリー表示へ遷移する' do +# ScrollPanel.any_instance.stub(:store).and_return(true) + put :update, :id => @scroll_panel.id, :scroll_panel => @attr + response.should redirect_to(:action => :scroll, :id => @attr[:scroll_id]) + end + end + context 'json形式' do + it 'ステータスコード200 OKを返す' do +# ScrollPanel.any_instance.stub(:store).and_return(true) + put :update, :id => @scroll_panel.id, :scroll_panel => @attr, :format => :json + response.should be_success + end + end + end + context 'ユーザ権限がないとき' do + before do + sign_out @user + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + put :update, :id => @scroll_panel.id, :scroll_panel => @attr + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + put :update, :id => @scroll_panel.id, :scroll_panel => @attr + response.body.should redirect_to '/users/sign_in' + end + end + context 'json形式' do + it 'ステータスコード401 Unauthorizedを返す' do + put :update, :id => @scroll_panel.id, :scroll_panel => @attr, :format => :json + response.status.should eq 401 + end + it '応答メッセージにUnauthorizedを返す' do + put :update, :id => @scroll_panel.id, :scroll_panel => @attr, :format => :json + response.message.should match(/Unauthorized/) + end + end + end + end + + describe '削除に於いて' do + before do + @scroll_panel = FactoryGirl.create :scroll_panel, :author_id => @author.id + sign_in @user + ScrollPanel.stub(:edit).and_return(@scroll_panel) + end + context 'つつがなく終わるとき' do + before do + ScrollPanel.any_instance.stub(:destroy_and_shorten).with(any_args()).and_return(true) + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + delete :destroy, :id => @scroll_panel.id + response.status.should eq 302 + end + it '閲覧ページへ遷移する' do + delete :destroy, :id => @scroll_panel.id + response.should redirect_to(:controller => 'scroll_panels', :action => :scroll, :id => @scroll_panel.scroll_id) + end + end + context 'json形式' do + it 'ステータスコード200 OKを返す' do + delete :destroy, :id => @scroll_panel.id, :format => :json + response.should be_success + end + end + end + context 'ユーザ権限がないとき' do + before do + sign_out @user + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + delete :destroy, :id => @scroll_panel.id + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + delete :destroy, :id => @scroll_panel.id + response.body.should redirect_to '/users/sign_in' + end + end + context 'json形式' do + it 'ステータスコード401 Unauthorizedを返す' do + delete :destroy, :id => @scroll_panel.id, :format => :json + response.status.should eq 401 + end + it '応答メッセージにUnauthorizedを返す' do + delete :destroy, :id => @scroll_panel.id, :format => :json + response.message.should match(/Unauthorized/) + end + end + end + end + +end +end diff --git a/spec/controllers/scrolls_controller_spec.rb b/spec/controllers/scrolls_controller_spec.rb new file mode 100644 index 00000000..8ebf574e --- /dev/null +++ b/spec/controllers/scrolls_controller_spec.rb @@ -0,0 +1,1301 @@ +# -*- encoding: utf-8 -*- +require 'spec_helper' +#コミック +describe ScrollsController 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 = FactoryGirl.create :author, :user_id => @user.id + end + +if MagicNumber['run_mode'] == 1 + describe '一覧表示に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @user.author.id + Scroll.stub(:list).and_return([@scroll, @scroll, @scroll]) + sign_in @user + 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 Scroll.default_page_size + end + it '最大を超えると@page_sizeにデフォルト最大値が入る' do + get :index, :page_size => 1500 + assigns(:page_size).should eq Scroll.max_page_size + end + it '不正な値が入ると@page_sizeにデフォルト最大値が入る' do + get :index, :page_size => 0 + assigns(:page_size).should eq Scroll.default_page_size + end + end + context 'つつがなく終わるとき' do + it 'ステータスコード200 OKを返す' do + get :index + response.should be_success + end + it 'コミックモデルに一覧を問い合わせている' do + Scroll.should_receive(:list).exactly(1) + get :index + end + it '@scrollsにリストを取得している' do + get :index + assigns(:scrolls).should have_at_least(3).items + end + context 'html形式' do + it '@paginateにページ制御を取得している' do + get :index + assigns(:paginate).is_a?(Kaminari::PaginatableArray).should be_true + end + it 'indexテンプレートを描画する' do + get :index + response.should render_template("index") + 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 + Scroll.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?("title").should be_true + json.first.has_key?("visible").should be_true + end + end + end + context 'ユーザ権限がないとき' do + before do + sign_out @user + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + get :index + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + get :index + response.should redirect_to '/users/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 + context 'ユーザ権限はないが管理者権限があるとき' do + before do + sign_out @user + sign_in @admin + end + it 'ステータスコード200 OKを返す' do + get :index + response.should be_success + end + end + context 'ユーザだが作家登録していないとき' do + before do + @author.destroy + end + context 'html形式' do + it 'ステータスコード200 OKを返す' do + get :index + response.should be_success + end + end + end + end + + describe '単体表示に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @user.author.id, :title => 'normal' + Scroll.stub(:show).and_return(@scroll) + sign_in @user + end + context 'つつがなく終わるとき' do + it 'ステータスコード200 OKを返す' do + get :show, :id => @scroll.id + response.should be_success + end + it 'コミックモデルに単体取得を問い合わせている' do + Scroll.should_receive(:show).exactly(1) + get :show + end + it '@scrollにアレを取得している' do + get :show, :id => @scroll.id + assigns(:scroll).id.should eq(@scroll.id) + end + context 'html形式' do + it 'showテンプレートを描画する' do + get :show, :id => @scroll.id + response.should render_template("show") + end + end + context 'json形式' do + it 'jsonデータを返す' do + get :show, :id => @scroll.id, :format => :json + lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError) + end + it 'コミックモデルにjson単体出力オプションを問い合わせている' do + Scroll.should_receive(:show_json_opt).exactly(1) + get :show, :id => @scroll.id, :format => :json + end + it 'データがアレになっている' do + get :show, :id => @scroll.id, :format => :json + json = JSON.parse response.body + json["title"].should match(/normal/) + json["visible"].should_not be_nil + end + end + end + context 'ユーザ権限がないとき' do + before do + sign_out @user + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + get :show, :id => @scroll.id + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + get :show, :id => @scroll.id + response.body.should redirect_to '/users/sign_in' + end + end + context 'json形式' do + it 'ステータスコード401 Unauthorizedを返す' do + get :show, :id => @scroll.id, :format => :json + response.status.should eq 401 + end + it '応答メッセージにUnauthorizedを返す' do + get :show, :id => @scroll.id, :format => :json + response.message.should match(/Unauthorized/) + end + end + end + context 'ユーザ権限はないが管理者権限があるとき' do + before do + sign_out @user + sign_in @admin + end + it 'ステータスコード200 OKを返す' do + get :show, :id => @scroll.id + response.should be_success + end + end + context 'ユーザだが作家登録していないとき' do + before do + @author.destroy + end + context 'html形式' do + it 'ステータスコード200 OKを返す' do + get :show, :id => @scroll.id + response.should be_success + end + end + end +=begin + context '対象コミックがないとき' do + context 'html形式' do + it '例外404 not_foundを返す' do + lambda{ + get :show, :id => 0 + }.should raise_error(ActiveRecord::RecordNotFound) + end + end + context 'json形式' do + it '例外404 not_foundを返す' do + lambda{ + get :show, :id => 0, :format => :json + }.should raise_error(ActiveRecord::RecordNotFound) + end + end + end + context '非公開コミックを見ようとしたとき' do + context 'html形式' do + it '例外403 forbiddenを返す' do + Scroll.any_instance.stub(:visible?).with(any_args()).and_return(false) + hidden = FactoryGirl.create :hidden_scroll, :author_id => @author.id + lambda{ + get :show, :id => hidden + }.should raise_error(ActiveRecord::Forbidden) + end + end + context 'json形式' do + it '例外403 forbiddenを返す' do + Scroll.any_instance.stub(:visible?).with(any_args()).and_return(false) + hidden = FactoryGirl.create :hidden_scroll, :author_id => @author.id + lambda{ + get :show, :id => hidden, :format => :json + }.should raise_error(ActiveRecord::Forbidden) + end + end + end +=end + end + describe 'コミック数取得に於いて' do + before do + Scroll.should_receive(:visible_count).and_return(3) +# sign_in @user + end + context 'つつがなく終わるとき' do + it 'ステータスコード200 OKを返す' do + get :count, :format => :json + response.should be_success + end + context 'json形式' do + it 'jsonデータを返す' do + get :count, :format => :json + lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError) + end + it 'データがHash構造になっていてコミック数が1である' do + get :count, :format => :json + json = JSON.parse response.body + json["count"].should == 3 + end + end + end + end + + describe '新規作成フォーム表示に於いて' do + before do + sign_in @user + end + context 'つつがなく終わるとき' do + it 'ステータスコード200 OKを返す' do + get :new + response.should be_success + end + it '@scrollに新規データを用意している' do + get :new + assigns(:scroll).should be_a_new(Scroll) + end + it 'コミックモデルにデフォルト値補充を依頼している' do + Scroll.any_instance.should_receive(:supply_default).exactly(1) + get :new + end + context 'html形式' do + it 'newテンプレートを描画する' do + get :new + response.should render_template("new") + end + end + context 'js形式' do + it 'new.jsテンプレートを描画する' do + get :new, :format => :js + response.should render_template("new") + end + end + context 'json形式' do + it 'jsonデータを返す' do + get :new, :format => :json + lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError) + end + it 'コミックモデルにjson単体出力オプションを問い合わせている' do + Scroll.should_receive(:show_json_opt).exactly(1) + get :new, :format => :json + end + end + end + context 'ユーザ権限がないとき' do + before do + sign_out @user + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + get :new + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + get :new + response.body.should redirect_to '/users/sign_in' + end + end + context 'js形式' do + it 'ステータスコード401 Unauthorizedを返す' do + get :new, :format => :js + response.status.should eq 401 + end + it '応答メッセージにUnauthorizedを返す' do + get :new, :format => :js + response.message.should match(/Unauthorized/) + end + end + context 'json形式' do + it 'ステータスコード401 Unauthorizedを返す' do + get :new, :format => :json + response.status.should eq 401 + end + it '応答メッセージにUnauthorizedを返す' do + get :new, :format => :json + response.message.should match(/Unauthorized/) + end + end + end + context 'ユーザ権限はないが管理者権限があるとき' do + before do + sign_out @user + sign_in @admin + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + get :new + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + get :new + response.body.should redirect_to '/users/sign_in' + end + end + end + context 'ユーザだが作家登録していないとき' do + before do + @author.destroy + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + get :new, @attr + response.status.should eq 302 + end + it '作家登録ページへ遷移する' do + get :new, @attr + response.body.should redirect_to new_author_path + end + end + end + end + + describe '新規作成に於いて' do + before do + sign_in @user + @attr = FactoryGirl.attributes_for(:scroll, :author_id => @author.id, :title => 'normal') + end + context '事前チェックしておく' do + it 'コミックモデルにデフォルト値補充を依頼している' do + Scroll.any_instance.should_receive(:supply_default).exactly(1) + post :create, :scroll => @attr + end + it 'コミックモデルにカラム値復元を依頼している' do + Scroll.any_instance.should_receive(:attributes=).exactly(1) + post :create, :scroll => @attr + end + it 'コミックモデルに上書き補充を依頼している' do + Scroll.any_instance.should_receive(:overwrite).exactly(1) + post :create, :scroll => @attr + end + it 'モデルに保存依頼する' do + Scroll.any_instance.should_receive(:save).exactly(1) + post :create, :scroll => @attr + end + end + context 'つつがなく終わるとき' do + it "@scrollに作成されたコミックを保持していて、それがDBにある" do + post :create, :scroll => @attr + assigns(:scroll).should be_a(Scroll) + assigns(:scroll).should be_persisted + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + Scroll.any_instance.stub(:save).and_return(true) + post :create, :scroll => @attr + response.status.should eq 302 + end + it '作成されたコミックの表示ページへ遷移する' do +# Scroll.any_instance.stub(:save).and_return(true) + post :create, :scroll => @attr + response.should redirect_to(Scroll.last) + end + end + context 'json形式' do + it 'ステータスコード200 OKを返す' do +# Scroll.any_instance.stub(:save).and_return(true) + post :create, :scroll => @attr, :format => :json + response.should be_success + end + it '作成されたコミックをjsonデータで返す' do + post :create, :scroll => @attr, :format => :json + lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError) + end + it 'データがアレになっている' do + post :create, :scroll => @attr, :format => :json + json = JSON.parse response.body + json["title"].should match(/normal/) + json["visible"].should_not be_nil + end + end + end + context 'ユーザ権限がないとき' do + before do + sign_out @user + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + post :create, :scroll => @attr + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + post :create, :scroll => @attr + response.body.should redirect_to '/users/sign_in' + end + end + context 'json形式' do + it 'ステータスコード401 Unauthorizedを返す' do + post :create, :scroll => @attr, :format => :json + response.status.should eq 401 + end + it '応答メッセージにUnauthorizedを返す' do + post :create, :scroll => @attr, :format => :json + response.message.should match(/Unauthorized/) + end + end + end + context 'ユーザ権限はないが管理者権限があるとき' do + before do + sign_out @user + sign_in @admin + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + post :create, :scroll => @attr + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + post :create, :scroll => @attr + response.body.should redirect_to '/users/sign_in' + end + end + end + context 'ユーザだが作家登録していないとき' do + before do + @author.destroy + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + post :create, :scroll => @attr + response.status.should eq 302 + end + it '作家登録ページへ遷移する' do + post :create, :scroll => @attr + response.body.should redirect_to new_author_path + end + end + end + context '検証、保存に失敗した' do + before do + Scroll.any_instance.stub(:save).and_return(false) + end + it "未保存のコミックを保持している" do + post :create, :scroll => @attr + assigns(:scroll).should be_a_new(Scroll) + end + context 'html形式' do + it 'ステータスコード200 OKを返す' do + post :create, :scroll => @attr + response.status.should eq 200 + end + it '新規ページを描画する' do + post :create, :scroll => @attr + response.should render_template("new") + end + end + context 'json形式' do + it 'ステータスコード422 unprocessable_entity を返す' do + post :create, :scroll => @attr, :format => :json + response.status.should eq 422 + end + it '応答メッセージUnprocessable Entityを返す' do + post :create, :scroll => @attr, :format => :json + response.message.should match(/Unprocessable/) + end + end + end + end + + describe '編集フォーム表示に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @user.author.id + sign_in @user + Scroll.stub(:edit).and_return(@scroll) + end + context 'つつがなく終わるとき' do + it 'ステータスコード200 OKを返す' do + get :edit, :id => @scroll.id + response.should be_success + end + it 'コミックモデルに編集取得を問い合わせている' do + Scroll.should_receive(:edit).exactly(1) + get :edit, :id => @scroll.id + end + it '@scrollにデータを用意している' do + get :edit, :id => @scroll.id + assigns(:scroll).should eq @scroll + end + context 'html形式' do + it 'editテンプレートを描画する' do + get :edit, :id => @scroll.id + response.should render_template("edit") + end + end + context 'js形式' do + it 'edit.jsテンプレートを描画する' do + get :edit, :id => @scroll.id, :format => :js + response.should render_template("edit") + end + end + end + context 'ユーザ権限がないとき' do + before do + sign_out @user + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + get :edit, :id => @scroll.id + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + get :edit, :id => @scroll.id + response.body.should redirect_to '/users/sign_in' + end + end + context 'js形式' do + it 'ステータスコード401 Unauthorizedを返す' do + get :edit, :id => @scroll.id, :format => :js + response.status.should eq 401 + end + it '応答メッセージにUnauthorizedを返す' do + get :edit, :id => @scroll.id, :format => :js + response.message.should match(/Unauthorized/) + end + end + end + context 'ユーザ権限はないが管理者権限があるとき' do + before do + sign_out @user + sign_in @admin + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + get :edit, :id => @scroll.id + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + get :edit, :id => @scroll.id + response.body.should redirect_to '/users/sign_in' + end + end + end + context 'ユーザだが作家登録していないとき' do + before do + @author.destroy + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + get :edit, :id => @scroll.id + response.status.should eq 302 + end + it '作家登録ページへ遷移する' do + get :edit, :id => @scroll.id + response.body.should redirect_to new_author_path + end + end + end + end + + describe '更新に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author => @author + @attr = FactoryGirl.attributes_for(:scroll, :author_id => @author.id, :title => 'updated title', :visible => 0) + sign_in @user + end + context '事前チェックしておく' do + it 'コミックモデルに編集取得を問い合わせている' do + Scroll.stub(:edit).with(any_args()).and_return @scroll + Scroll.should_receive(:edit).exactly(1) + put :update, :id => @scroll.id, :scroll => @attr + end + it 'コミックモデルにカラム値復元を依頼している' do + Scroll.any_instance.should_receive(:attributes=).exactly(1) + put :update, :id => @scroll.id, :scroll => @attr + end + it 'コミックモデルに上書き補充を依頼している' do + Scroll.any_instance.should_receive(:overwrite).exactly(1) + put :update, :id => @scroll.id, :scroll => @attr + end + it 'モデルに更新を依頼する' do + Scroll.any_instance.stub(:save).with(any_args).and_return true + Scroll.any_instance.should_receive(:save).exactly(1) + put :update, :id => @scroll.id, :scroll => @attr + end + it '@scrollにアレを取得している' do + put :update, :id => @scroll.id, :scroll => @attr + assigns(:scroll).id.should eq(@scroll.id) + end + end + context 'つつがなく終わるとき' do + it '更新される' do + put :update, :id => @scroll.id, :scroll => @attr + Scroll.find(@scroll.id).visible.should eq 0 + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + Scroll.any_instance.stub(:save).with(any_args()).and_return(true) + put :update, :id => @scroll.id, :scroll => @attr + response.status.should eq 302 + end + it '更新されたコミックの表示ページへ遷移する' do + put :update, :id => @scroll.id, :scroll => @attr + response.should redirect_to(@scroll) + end + end + context 'json形式' do + it 'ステータスコード200 OKを返す' do + Scroll.any_instance.stub(:save).with(any_args()).and_return(true) + put :update, :id => @scroll.id, :scroll => @attr, :format => :json + response.should be_success + end + it 'ページ本体は特に返さない' do + Scroll.any_instance.stub(:save).with(any_args()).and_return(true) + put :update, :id => @scroll.id, :scroll => @attr, :format => :json + response.body.should match /./ + end + end + end + context 'ユーザ権限がないとき' do + before do + sign_out @user + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + put :update, :id => @scroll.id, :scroll => @attr + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + put :update, :id => @scroll.id, :scroll => @attr + response.body.should redirect_to '/users/sign_in' + end + end + context 'json形式' do + it '応答メッセージにUnauthorizedを返す' do + put :update, :id => @scroll.id, :scroll => @attr, :format => :json + response.message.should match(/Unauthorized/) + end + end + end + context 'ユーザ権限はないが管理者権限があるとき' do + before do + sign_out @user + sign_in @admin + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + put :update, :id => @scroll.id, :scroll => @attr + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + put :update, :id => @scroll.id, :scroll => @attr + response.body.should redirect_to '/users/sign_in' + end + end + end + context 'ユーザだが作家登録していないとき' do + before do + @author.destroy + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + put :update, :id => @scroll.id, :scroll => @attr + response.status.should eq 302 + end + it '作家登録ページへ遷移する' do + put :update, :id => @scroll.id, :scroll => @attr + response.body.should redirect_to new_author_path + end + end + end + context '検証、保存に失敗したとき' do + before do + Scroll.any_instance.stub(:save).and_return(false) + end + context 'html形式' do + it 'ステータスコード200 Okを返す' do + put :update, :id => @scroll.id, :scroll => @attr + response.status.should eq 200 + end + it '編集ページを描画する' do + put :update, :id => @scroll.id, :scroll => @attr + response.should render_template("edit") + end + end + context 'json形式' do + it 'ステータスコード422 unprocessable_entity を返す' do + Scroll.any_instance.stub(:save).and_return(false) + put :update, :id => @scroll.id, :scroll => @attr, :format => :json + response.status.should eq 422 + end + it '応答メッセージUnprocessable Entityを返す' do + put :update, :id => @scroll.id, :scroll => @attr, :format => :json + response.message.should match(/Unprocessable/) + end + end + end + end + + describe '削除に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author => @author + sign_in @user + end + context '事前チェックしておく' do + before do + Scroll.stub(:edit).with(any_args()).and_return @scroll + Scroll.any_instance.stub(:destroy_with_scroll_panel).with(any_args()).and_return(true) + end + it 'コミックモデルに編集取得を問い合わせている' do + Scroll.should_receive(:edit).exactly(1) + delete :destroy, :id => @scroll.id + end + it 'モデルに削除を依頼する' do + Scroll.any_instance.should_receive(:destroy_with_scroll_panel).exactly(1) + delete :destroy, :id => @scroll.id + end + it '@scrollにアレを取得している' do + delete :destroy, :id => @scroll.id + assigns(:scroll).id.should eq(@scroll.id) + end + end + context 'つつがなく終わるとき' do + it '削除される' do + lambda { + delete :destroy, :id => @scroll.id + }.should change Scroll, :count + end + context 'html形式' do + before do + Scroll.any_instance.stub(:destroy_with_scroll_panel).with(any_args()).and_return(true) + end + it 'ステータスコード302 Foundを返す' do + delete :destroy, :id => @scroll.id + response.status.should eq 302 + end + it 'マイコミックの一覧ページへ遷移する' do + delete :destroy, :id => @scroll.id + response.should redirect_to('/home/scrolls') + end + end + context 'json形式' do + before do + Scroll.any_instance.stub(:destroy_with_scroll_panel).with(any_args()).and_return(true) + end + it 'ステータスコード200 OKを返す' do + delete :destroy, :id => @scroll.id, :format => :json + response.should be_success + end + it 'ページ本体は特に返さない' do + delete :destroy, :id => @scroll.id, :format => :json + response.body.should match /./ + end + end + end + context 'ユーザ権限がないとき' do + before do + sign_out @user + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + delete :destroy, :id => @scroll.id + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + delete :destroy, :id => @scroll.id + response.body.should redirect_to '/users/sign_in' + end + end + context 'json形式' do + it '応答メッセージにUnauthorizedを返す' do + delete :destroy, :id => @scroll.id, :format => :json + response.message.should match(/Unauthorized/) + end + end + end + context 'ユーザ権限はないが管理者権限があるとき' do + before do + sign_out @user + sign_in @admin + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + delete :destroy, :id => @scroll.id + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + delete :destroy, :id => @scroll.id + response.body.should redirect_to '/users/sign_in' + end + end + end + context 'ユーザだが作家登録していないとき' do + before do + @author.destroy + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + delete :destroy, :id => @scroll.id + response.status.should eq 302 + end + it '作家登録ページへ遷移する' do + delete :destroy, :id => @scroll.id + response.body.should redirect_to new_author_path + end + end + end + context '削除に失敗したとき' do + before do + Scroll.any_instance.stub(:destroy_with_scroll_panel).and_return(false) + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + delete :destroy, :id => @scroll.id + response.status.should eq 302 + end + it 'そのコミックの詳細ページへ遷移する' do + delete :destroy, :id => @scroll.id + response.should redirect_to(scroll_path(@scroll)) + end + end + context 'json形式' do + it 'ステータスコード422 unprocessable_entity を返す' do + delete :destroy, :id => @scroll.id, :format => :json + response.status.should eq 422 + end + it '応答メッセージUnprocessable Entityを返す' do + delete :destroy, :id => @scroll.id, :format => :json + response.message.should match(/Unprocessable/) + end + end + end + end + +else + describe '一覧表示に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @user.author.id + Scroll.stub(:list).and_return([@scroll, @scroll, @scroll]) + sign_in @user + end + context 'つつがなく終わるとき' do + it 'ステータスコード200 OKを返す' do + get :index + response.should be_success + 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 + end + end + context 'ユーザ権限がないとき' do + before do + sign_out @user + end + it 'ステータスコード200 OKを返す' do + get :index + response.should be_success + 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 + end + end + end + + describe '単体表示に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @user.author.id, :title => 'normal' + Scroll.stub(:show).and_return(@scroll) + sign_in @user + end + context 'つつがなく終わるとき' do + it 'ステータスコード200 OKを返す' do + get :show, :id => @scroll.id + response.should be_success + end + context 'html形式' do + it 'showテンプレートを描画する' do + get :show, :id => @scroll.id + response.should render_template("show") + end + end + context 'json形式' do + it 'jsonデータを返す' do + get :show, :id => @scroll.id, :format => :json + lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError) + end + end + end + context 'ユーザ権限がないとき' do + before do + sign_out @user + end + it 'ステータスコード200 OKを返す' do + get :show, :id => @scroll.id + response.should be_success + end + context 'html形式' do + it 'showテンプレートを描画する' do + get :show, :id => @scroll.id + response.should render_template("show") + end + end + context 'json形式' do + it 'jsonデータを返す' do + get :show, :id => @scroll.id, :format => :json + lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError) + end + end + end + end + describe 'コミック数取得に於いて' do + before do + Scroll.should_receive(:visible_count).and_return(3) + sign_out @user + end + context 'つつがなく終わるとき' do + it 'ステータスコード200 OKを返す' do + get :count, :format => :json + response.should be_success + end + context 'json形式' do + it 'jsonデータを返す' do + get :count, :format => :json + lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError) + end + end + end + end + + describe '新規作成フォーム表示に於いて' do + before do + sign_in @user + end + context 'つつがなく終わるとき' do + it 'ステータスコード200 OKを返す' do + get :new + response.should be_success + end + context 'html形式' do + it 'newテンプレートを描画する' do + get :new + response.should render_template("new") + end + end + context 'js形式' do + it 'new.jsテンプレートを描画する' do + get :new, :format => :js + response.should render_template("new") + end + end + context 'json形式' do + it 'jsonデータを返す' do + get :new, :format => :json + lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError) + end + end + end + context 'ユーザ権限がないとき' do + before do + sign_out @user + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + get :new + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + get :new + response.body.should redirect_to '/users/sign_in' + end + end + context 'js形式' do + it 'ステータスコード401 Unauthorizedを返す' do + get :new, :format => :js + response.status.should eq 401 + end + it '応答メッセージにUnauthorizedを返す' do + get :new, :format => :js + response.message.should match(/Unauthorized/) + end + end + context 'json形式' do + it 'ステータスコード401 Unauthorizedを返す' do + get :new, :format => :json + response.status.should eq 401 + end + it '応答メッセージにUnauthorizedを返す' do + get :new, :format => :json + response.message.should match(/Unauthorized/) + end + end + end + end + + describe '新規作成に於いて' do + before do + sign_in @user + @attr = FactoryGirl.attributes_for(:scroll, :author_id => @author.id, :title => 'normal') + end + context 'つつがなく終わるとき' do + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + Scroll.any_instance.stub(:save).and_return(true) + post :create, :scroll => @attr + response.status.should eq 302 + end + it '作成されたコミックの表示ページへ遷移する' do +# Scroll.any_instance.stub(:save).and_return(true) + post :create, :scroll => @attr + response.should redirect_to(Scroll.last) + end + end + context 'json形式' do + it 'ステータスコード200 OKを返す' do +# Scroll.any_instance.stub(:save).and_return(true) + post :create, :scroll => @attr, :format => :json + response.should be_success + end + it '作成されたコミックをjsonデータで返す' do + post :create, :scroll => @attr, :format => :json + lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError) + end + end + end + context 'ユーザ権限がないとき' do + before do + sign_out @user + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + post :create, :scroll => @attr + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + post :create, :scroll => @attr + response.body.should redirect_to '/users/sign_in' + end + end + context 'json形式' do + it 'ステータスコード401 Unauthorizedを返す' do + post :create, :scroll => @attr, :format => :json + response.status.should eq 401 + end + it '応答メッセージにUnauthorizedを返す' do + post :create, :scroll => @attr, :format => :json + response.message.should match(/Unauthorized/) + end + end + end + end + + describe '編集フォーム表示に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @user.author.id + sign_in @user + Scroll.stub(:edit).and_return(@scroll) + end + context 'つつがなく終わるとき' do + it 'ステータスコード200 OKを返す' do + get :edit, :id => @scroll.id + response.should be_success + end + context 'html形式' do + it 'editテンプレートを描画する' do + get :edit, :id => @scroll.id + response.should render_template("edit") + end + end + context 'js形式' do + it 'edit.jsテンプレートを描画する' do + get :edit, :id => @scroll.id, :format => :js + response.should render_template("edit") + end + end + end + context 'ユーザ権限がないとき' do + before do + sign_out @user + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + get :edit, :id => @scroll.id + response.status.should eq 302 + end + it 'サインインページへ遷移する' do + get :edit, :id => @scroll.id + response.body.should redirect_to '/users/sign_in' + end + end + context 'js形式' do + it 'ステータスコード401 Unauthorizedを返す' do + get :edit, :id => @scroll.id, :format => :js + response.status.should eq 401 + end + it '応答メッセージにUnauthorizedを返す' do + get :edit, :id => @scroll.id, :format => :js + response.message.should match(/Unauthorized/) + end + end + end + end + + describe '更新に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author => @author + @attr = FactoryGirl.attributes_for(:scroll, :author_id => @author.id, :title => 'updated title', :visible => 0) + sign_in @user + end + context 'つつがなく終わるとき' do + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + Scroll.any_instance.stub(:save).with(any_args()).and_return(true) + put :update, :id => @scroll.id, :scroll => @attr + response.status.should eq 302 + end + it '更新されたコミックの表示ページへ遷移する' do + put :update, :id => @scroll.id, :scroll => @attr + response.should redirect_to(@scroll) + end + end + context 'json形式' do + it 'ステータスコード200 OKを返す' do + Scroll.any_instance.stub(:save).with(any_args()).and_return(true) + put :update, :id => @scroll.id, :scroll => @attr, :format => :json + response.should be_success + end + it 'ページ本体は特に返さない' do + Scroll.any_instance.stub(:save).with(any_args()).and_return(true) + put :update, :id => @scroll.id, :scroll => @attr, :format => :json + response.body.should match /./ + end + end + end + context 'ユーザ権限がないとき' do + before do + sign_out @user + end + it 'ステータスコード302 Foundを返す' do + put :update, :id => @scroll.id, :scroll => @attr + response.status.should eq 302 + end + context 'html形式' do + it 'サインインページへ遷移する' do + put :update, :id => @scroll.id, :scroll => @attr + response.body.should redirect_to '/users/sign_in' + end + end + end + end + + describe '削除に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author => @author + sign_in @user + end + context 'つつがなく終わるとき' do + context 'html形式' do + before do + Scroll.any_instance.stub(:destroy_with_scroll_panel).with(any_args()).and_return(true) + end + it 'ステータスコード302 Foundを返す' do + delete :destroy, :id => @scroll.id + response.status.should eq 302 + end + it 'マイコミックの一覧ページへ遷移する' do + delete :destroy, :id => @scroll.id + response.should redirect_to('/home/scroll') + end + end + context 'json形式' do + before do + Scroll.any_instance.stub(:destroy_with_scroll_panel).with(any_args()).and_return(true) + end + it 'ステータスコード200 OKを返す' do + delete :destroy, :id => @scroll.id, :format => :json + response.should be_success + end + it 'ページ本体は特に返さない' do + delete :destroy, :id => @scroll.id, :format => :json + response.body.should match /./ + end + end + end + context 'ユーザ権限がないとき' do + before do + sign_out @user + end + it 'ステータスコード302 Foundを返す' do + delete :destroy, :id => @scroll.id + response.status.should eq 302 + end + context 'html形式' do + it 'サインインページへ遷移する' do + delete :destroy, :id => @scroll.id + response.body.should redirect_to '/users/sign_in' + end + end + context 'json形式' do + it '応答メッセージにUnauthorizedを返す' do + delete :destroy, :id => @scroll.id, :format => :json + response.message.should match(/Unauthorized/) + end + end + end + end + +end + +end diff --git a/spec/helpers/scroll_panels_helper_spec.rb b/spec/helpers/scroll_panels_helper_spec.rb new file mode 100644 index 00000000..90a74e81 --- /dev/null +++ b/spec/helpers/scroll_panels_helper_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +# Specs in this file have access to a helper object that includes +# the ScrollPanelsHelper. For example: +# +# describe ScrollPanelsHelper do +# describe "string concat" do +# it "concats two strings with spaces" do +# helper.concat_strings("this","that").should == "this that" +# end +# end +# end +describe ScrollPanelsHelper do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/helpers/scrolls_helper_spec.rb b/spec/helpers/scrolls_helper_spec.rb new file mode 100644 index 00000000..b575131f --- /dev/null +++ b/spec/helpers/scrolls_helper_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +# Specs in this file have access to a helper object that includes +# the ScrollsHelper. For example: +# +# describe ScrollsHelper do +# describe "string concat" do +# it "concats two strings with spaces" do +# helper.concat_strings("this","that").should == "this that" +# end +# end +# end +describe ScrollsHelper do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/scroll_panel_spec.rb b/spec/models/scroll_panel_spec.rb new file mode 100644 index 00000000..bc3fcb2d --- /dev/null +++ b/spec/models/scroll_panel_spec.rb @@ -0,0 +1,1940 @@ +# -*- encoding: utf-8 -*- +require 'spec_helper' +#ストーリー +describe ScrollPanel 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 + @speech_balloon_template = FactoryGirl.create :speech_balloon_template, "name" => "circle@pettan.com", "classname" => "CircleSpeechBalloon", "caption" => "cc", "system_picture_id" => @sp.id, "settings" => '{}' + @writing_format = FactoryGirl.create :writing_format + @user = FactoryGirl.create( :user_yas) + @author = FactoryGirl.create :author, :user_id => @user.id + @artist = FactoryGirl.create :artist_yas, :author_id => @author.id + @other_user = FactoryGirl.create( :user_yas) + @other_author = FactoryGirl.create :author, :user_id => @other_user.id + @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 + end + + describe '検証に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @author.id + @panel = FactoryGirl.create :panel, :author_id => @author.id + @scroll_panel = FactoryGirl.build :scroll_panel, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + end + + context 'オーソドックスなデータのとき' do + it '下限データが通る' do + @scroll_panel.t = 0 + @scroll_panel.should be_valid + end + it '上限データが通る' do + @scroll_panel.t = 99999 + @scroll_panel.should be_valid + end + end + + context 'scroll_idを検証するとき' do + it 'nullなら失敗する' do + @scroll_panel.scroll_id = nil + @scroll_panel.should_not be_valid + end + it '数値でなければ失敗する' do + @scroll_panel.scroll_id = 'a' + @scroll_panel.should_not be_valid + end + it '存在するコミックでなければ失敗する' do + @scroll_panel.scroll_id = 0 + @scroll_panel.should_not be_valid + end + end + + context 'panel_idを検証するとき' do + it 'nullなら失敗する' do + @scroll_panel.panel_id = nil + @scroll_panel.should_not be_valid + end + it '数値でなければ失敗する' do + @scroll_panel.panel_id = 'a' + @scroll_panel.should_not be_valid + end + it '存在するコマでなければ失敗する' do + @scroll_panel.panel_id = 0 + @scroll_panel.should_not be_valid + end + end + + context 'tを検証するとき' do + it 'nullなら失敗する' do + @scroll_panel.t = nil + @scroll_panel.should_not be_valid + end + it '数値でなければ失敗する' do + @scroll_panel.t = 'a' + @scroll_panel.should_not be_valid + end + it '負なら失敗する' do + @scroll_panel.t = -1 + @scroll_panel.should_not be_valid + end + end + + context 'author_idを検証するとき' do + it 'nullなら失敗する' do + @scroll_panel.author_id = nil + @scroll_panel.should_not be_valid + end + it '数値でなければ失敗する' do + @scroll_panel.author_id = 'a' + @scroll_panel.should_not be_valid + end + it '存在する作家でなければ失敗する' do + @scroll_panel.author_id = 0 + @scroll_panel.should_not be_valid + end + end + context '全体を検証するとき' do + end + end + + describe 'デフォルト値補充に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @author.id + @panel = FactoryGirl.create :panel, :author_id => @author.id + end + + #dbのデフォルト値が0だから明示的にnilにしないと追加ができない + it 'tをnilにする' do + @scroll_panel = FactoryGirl.build :scroll_panel, :scroll_id => @scroll.id, :panel_id => @panel.id + @scroll_panel.supply_default + @scroll_panel.t.should be_nil + end + + end + + describe '上書き補充に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @author.id + @panel = FactoryGirl.create :panel, :author_id => @author.id + end + + context 'author_idを補充' do + it '問答無用でauthor_idを補充する' do + @scroll_panel = FactoryGirl.build :scroll_panel, :scroll_id => @scroll.id, :panel_id => @panel.id + @scroll_panel.author_id = nil + @scroll_panel.overwrite @author + @scroll_panel.author_id.should eq @author.id + end + end + + end + + describe '所持判定に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @author.id + @panel = FactoryGirl.create :panel, :author_id => @author.id + @scroll_panel = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id + @scrollo = FactoryGirl.create :scroll, :author_id => @other_author.id + @panelo = FactoryGirl.create :panel, :author_id => @other_author.id + @scroll_panelo = FactoryGirl.create :scroll_panel, :author_id => @other_author.id, :scroll_id => @scrollo.id, :panel_id => @panelo.id + end + context '事前チェックする' do + it '自身にロールリストからの作家取得を依頼している' do + ScrollPanel.should_receive(:get_author_from_roles).with(any_args).exactly(1) + r = @scroll_panel.own?([@author]) + end + end + context 'ロール内作家が取得できるとき' do + before do + end + it 'ロール内作家のidが自身の作家idと一致するなら許可する' do + ScrollPanel.stub(:get_author_from_roles).with(any_args).and_return(@author) + r = @scroll_panel.own?([@author]) + r.should be_true + end + it 'ロール内作家のidが自身の作家idと一致しないならno' do + ScrollPanel.stub(:get_author_from_roles).with(any_args).and_return(@other_author) + @scroll_panel.own?(@other_author).should be_false + end + end + context 'ロール内作家が取得できないとき' do + before do + ScrollPanel.stub(:get_author_from_roles).with(any_args).and_return(nil) + end + it 'Falseを返す' do + r = @scroll_panel.own?([@author]) + r.should be_false + end + end + end + + describe '閲覧許可に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @author.id + @panel = FactoryGirl.create :panel, :author_id => @author.id + @scroll_panel = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id + end + context 'オープンモードのとき' do + before do + MagicNumber['run_mode'] = 0 + end + it '自身にゲスト用ロールチェックを問い合わせしている' do + ScrollPanel.any_instance.stub(:guest_role_check).and_return(true) + ScrollPanel.any_instance.should_receive(:guest_role_check).with(any_args).exactly(1) + r = @scroll_panel.visible?([@author]) + end + it 'ゲスト用ロールチェックが失敗したとき、falseを返す' do + ScrollPanel.any_instance.stub(:guest_role_check).and_return(false) + r = @scroll_panel.visible?([@author]) + r.should be_false + end + end + context 'クローズドモードのとき' do + before do + MagicNumber['run_mode'] = 1 + end + it '自身に読者用ロールチェックを問い合わせしている' do + ScrollPanel.any_instance.stub(:reader_role_check).and_return(true) + ScrollPanel.any_instance.should_receive(:reader_role_check).with(any_args).exactly(1) + r = @scroll_panel.visible?([@author]) + end + it '読者用ロールチェックが失敗したとき、falseを返す' do + ScrollPanel.any_instance.stub(:reader_role_check).and_return(false) + r = @scroll_panel.visible?([@author]) + r.should be_false + end + end + context '事前チェックする' do + before do + MagicNumber['run_mode'] = 1 + ScrollPanel.any_instance.stub(:reader_role_check).and_return(true) + end + it '自身のコミックに所持判定を問い合わせしている' do + Scroll.any_instance.stub(:own?).and_return(true) + Scroll.any_instance.should_receive(:own?).with(any_args).exactly(1) + r = @scroll_panel.visible?([@author]) + end + it '自身のコミックに閲覧許可を問い合わせしている' do + Scroll.any_instance.stub(:own?).and_return(false) + Scroll.any_instance.stub(:visible?).and_return(true) + Scroll.any_instance.should_receive(:visible?).with(any_args).exactly(1) + r = @scroll_panel.visible?([@author]) + end + end + context 'つつがなく終わるとき' do + before do + MagicNumber['run_mode'] = 1 + ScrollPanel.any_instance.stub(:reader_role_check).and_return(true) + end + it '自分のコミックのストーリーなら許可する' do + Scroll.any_instance.stub(:own?).and_return(true) + Scroll.any_instance.stub(:visible).and_return(0) + r = @scroll_panel.visible?([@author]) + r.should be_true + end + it '他人の非公開コミックのストーリーなら許可しない' do + Scroll.any_instance.stub(:own?).and_return(false) + Scroll.any_instance.stub(:visible).and_return(0) + r = @scroll_panel.visible?([@author]) + r.should be_false + end + it '他人のコミックのストーリーでも公開なら許可する' do + Scroll.any_instance.stub(:own?).and_return(false) + Scroll.any_instance.stub(:visible).and_return(1) + r = @scroll_panel.visible?([@author]) + r.should be_true + end + end + end + + describe 'プレイリスト取得に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @author.id + @panel = FactoryGirl.create :panel, :author_id => @author.id + @scroll_panel = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id + @panel2 = FactoryGirl.create :panel, :author_id => @author.id, :publish => 0 + @other_scroll = FactoryGirl.create :scroll, :author_id => @other_author.id, :visible => 1 + @other_panel = FactoryGirl.create :panel, :author_id => @other_author.id, :publish => 1 + end + context 'offset補正について' do + it '文字列から数値に変換される' do + ScrollPanel.offset(100, '8').should eq 8 + end + it 'nilの場合は0になる' do + ScrollPanel.offset(100).should eq 0 + end + #投稿されたコマ数以上の値が指定されたときは、最後のコマだけになる + #最後のコマとは、コマ数‐1. + it '1件のときオフセット1なら0になる' do + ScrollPanel.offset(1, '1').should eq 0 + end + it '5件のときオフセット5なら4になる' do + ScrollPanel.offset(5, '5').should eq 4 + end + # 負の値が指定されたときは、最後のコマから数えてコマを飛ばして表示する。 + #-4のときは、最後から4つのコマを表示する。 + it '2件のときオフセット-1なら1になる' do + ScrollPanel.offset(2, '-1').should eq 1 + end + it '5件のときオフセット-2なら3になる' do + ScrollPanel.offset(5, '-2').should eq 3 + end + # 最終的なが負になるなど、不正な値が入ったときは0となる。 + it '2件のときオフセット-5なら0になる' do + ScrollPanel.offset(2, '-5').should eq 0 + end + end + context 'panel_count補正について' do + it '文字列から数値に変換される' do + ScrollPanel.panel_count(100, '7').should eq 7 + end + it 'nilの場合はScrollPanel.default_panel_sizeになる' do + ScrollPanel.panel_count(100).should eq ScrollPanel.default_panel_size + end + it '0以下の場合はScrollPanel.default_panel_sizeになる' do + ScrollPanel.panel_count(100, '0').should eq ScrollPanel.default_panel_size + end + it 'ScrollPanel.max_panel_sizeを超えた場合はScrollPanel.max_panel_sizeになる' do + ScrollPanel.panel_count(100, '1000').should eq ScrollPanel.max_panel_size + end + end + it 'リストを返す' do + c = ScrollPanel.play_list @scroll, @author + c.should eq [@scroll_panel] + end + it 't順で並んでいる' do + #公開コミックの公開コマは(他人のコミックであっても)含んでいる + v = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id, :t => 1 + c = ScrollPanel.play_list @scroll, @author + c.should eq [ @scroll_panel, v] + end + it '非公開のコマは含んでいる' do + h = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel2.id, :t => 1 + c = ScrollPanel.play_list @scroll, @author + c.should eq [ @scroll_panel, h] + end + context 'DBに5件あって1ページの件数を2件に変えたとして' do + before do + @scroll_panel2 = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id, :t => 1 + @scroll_panel3 = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id, :t => 2 + @scroll_panel4 = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id, :t => 3 + @scroll_panel5 = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id, :t => 4 + end + it 'offset=0なら末尾2件を返す' do + #時系列で並んでいる + c = ScrollPanel.play_list( @scroll, @author, 0, 2) + c.should eq [@scroll_panel, @scroll_panel2] + end + it 'offset=2なら中間2件を返す' do + c = ScrollPanel.play_list(@scroll, @author, 2, 2) + c.should eq [@scroll_panel3, @scroll_panel4] + end + it 'offset=4なら先頭1件を返す' do + c = ScrollPanel.play_list(@scroll, @author, 4, 2) + c.should eq [@scroll_panel5] + end + end + end + + describe '一覧取得に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @author.id, :visible => 1 + @panel = FactoryGirl.create :panel, :author_id => @author.id + @scroll_panel = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id + @other_scroll = FactoryGirl.create :scroll, :author_id => @other_author.id, :visible => 1 + @other_panel = FactoryGirl.create :panel, :author_id => @other_author.id, :publish => 1 + @hidden_scroll = FactoryGirl.create :scroll, :author_id => @author.id, :visible => 0 + end + context 'page補正について' do + it '文字列から数値に変換される' do + ScrollPanel.page('8').should eq 8 + end + it 'nilの場合は1になる' do + ScrollPanel.page().should eq 1 + end + it '0以下の場合は1になる' do + ScrollPanel.page('0').should eq 1 + end + end + context 'page_size補正について' do + it '文字列から数値に変換される' do + ScrollPanel.page_size('7').should eq 7 + end + it 'nilの場合はScrollPanel.default_page_sizeになる' do + ScrollPanel.page_size().should eq ScrollPanel.default_page_size + end + it '0以下の場合はScrollPanel.default_page_sizeになる' do + ScrollPanel.page_size('0').should eq ScrollPanel.default_page_size + end + it 'ScrollPanel.max_page_sizeを超えた場合はScrollPanel.max_page_sizeになる' do + ScrollPanel.page_size('1000').should eq ScrollPanel.max_page_size + end + end + it 'リストを返す' do + c = ScrollPanel.list + c.should eq [@scroll_panel] + end + it '時系列で並んでいる' do + #公開コミックのScrollPanelは(他人のScrollPanelであっても)含んでいる + v = FactoryGirl.create :scroll_panel, :author_id => @other_author.id, :scroll_id => @other_scroll.id, :panel_id => @other_panel.id, :t => 0, :updated_at => Time.now + 100 + c = ScrollPanel.list + c.should eq [ v, @scroll_panel] + end + it '非公開のストーリーは(自分のストーリーであっても)含まない' do + h = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @hidden_scroll.id, :panel_id => @panel.id, :t => 0 + c = ScrollPanel.list + c.should eq [ @scroll_panel] + end + context 'DBに5件あって1ページの件数を2件に変えたとして' do + before do + @scroll_panel2 = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id, :t => 1, :updated_at => Time.now + 100 + @scroll_panel3 = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id, :t => 2, :updated_at => Time.now + 200 + @scroll_panel4 = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id, :t => 3, :updated_at => Time.now + 300 + @scroll_panel5 = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id, :t => 4, :updated_at => Time.now + 400 + end + it '通常は2件を返す' do + l = ScrollPanel.list 1, 2 + l.should have(2).items + end + it 'page=1なら末尾2件を返す' do + #時系列で並んでいる + l = ScrollPanel.list 1, 2 + l.should eq [@scroll_panel5, @scroll_panel4] + end + it 'page=2なら中間2件を返す' do + l = ScrollPanel.list 2, 2 + l.should eq [@scroll_panel3, @scroll_panel2] + end + it 'page=3なら先頭1件を返す' do + l = ScrollPanel.list 3, 2 + l.should eq [@scroll_panel] + end + end + end + + describe '自分のストーリー一覧取得に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @author.id, :visible => 1 + @panel = FactoryGirl.create :panel, :author_id => @author.id, :publish => 1 + @scroll_panel = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id + @other_scroll = FactoryGirl.create :scroll, :author_id => @other_author.id, :visible => 1 + @other_panel = FactoryGirl.create :panel, :author_id => @other_author.id, :publish => 1 + @hscroll = FactoryGirl.create :scroll, :author_id => @author.id, :visible => 0 + @hpanel = FactoryGirl.create :panel, :author_id => @author.id, :publish => 0 + end + context 'つつがなく終わるとき' do + it '一覧取得オプションを利用している' do + ScrollPanel.stub(:list_opt).with(any_args).and_return({}) + ScrollPanel.should_receive(:list_opt).with(any_args).exactly(1) + r = ScrollPanel.mylist @author + end + end + it 'リストを返す' do + s = ScrollPanel.mylist @author + s.should eq [@scroll_panel] + end + it '時系列で並んでいる' do + ns = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id, :t => 1, :updated_at => Time.now + 100 + sl = ScrollPanel.mylist @author + sl.should eq [ns, @scroll_panel] + end + it '他人のストーリーはコマコミックともに公開でも含まない' do + so = FactoryGirl.create :scroll_panel, :author_id => @other_author.id, :scroll_id => @other_scroll.id, :panel_id => @other_panel.id + sl = ScrollPanel.mylist @author + sl.should eq [@scroll_panel] + end + it '自分のストーリーはコマコミックともに非公開でも含んでいる' do + hs = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @hscroll.id, :panel_id => @hpanel.id, :updated_at => Time.now + 100 + sl = ScrollPanel.mylist @author + sl.should eq [hs, @scroll_panel] + end + context 'DBに5件あって1ページの件数を2件に変えたとして' do + before do + @scroll_panel2 = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id, :t => 1, :updated_at => Time.now + 100 + @scroll_panel3 = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id, :t => 2, :updated_at => Time.now + 200 + @scroll_panel4 = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id, :t => 3, :updated_at => Time.now + 300 + @scroll_panel5 = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id, :t => 4, :updated_at => Time.now + 400 + ScrollPanel.stub(:default_page_size).and_return(2) + end + it '通常は2件を返す' do + l = ScrollPanel.mylist @author, 1, 2 + l.should have(2).items + end + it 'page=1なら末尾2件を返す' do + #時系列で並んでいる + l = ScrollPanel.mylist @author, 1, 2 + l.should eq [@scroll_panel5, @scroll_panel4] + end + it 'page=2なら中間2件を返す' do + l = ScrollPanel.mylist @author, 2, 2 + l.should eq [@scroll_panel3, @scroll_panel2] + end + it 'page=3なら先頭1件を返す' do + l = ScrollPanel.mylist @author, 3, 2 + l.should eq [@scroll_panel] + end + end + end + + describe '他作家のストーリー一覧取得に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @author.id, :visible => 1 + @panel = FactoryGirl.create :panel, :author_id => @author.id, :publish => 1 + @scroll_panel = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id + @other_scroll = FactoryGirl.create :scroll, :author_id => @other_author.id, :visible => 1 + @other_panel = FactoryGirl.create :panel, :author_id => @other_author.id, :publish => 1 + @other_scroll_panel = FactoryGirl.create :scroll_panel, :author_id => @other_author.id, :scroll_id => @other_scroll.id, :panel_id => @other_panel.id + end + it 'リストを返す' do + r = ScrollPanel.himlist @other_author + r.should eq [@other_scroll_panel] + end + it '時系列で並んでいる' do + ns = FactoryGirl.create :scroll_panel, :author_id => @other_author.id, :scroll_id => @other_scroll.id, :panel_id => @other_panel.id, :t => 1, :updated_at => Time.now + 100 + r = ScrollPanel.himlist @other_author + r.should eq [ns, @other_scroll_panel] + end + it '公開コミックのストーリー' do + @hscroll = FactoryGirl.create :scroll, :author_id => @other_author.id, :visible => 0 + ns = FactoryGirl.create :scroll_panel, :author_id => @other_author.id, :scroll_id => @hscroll.id, :panel_id => @other_panel.id, :t => 1, :updated_at => Time.now + 100 + r = ScrollPanel.himlist @other_author + r.should eq [@other_scroll_panel] + end + context 'DBに5件あって1ページの件数を2件に変えたとして' do + before do + @other_scroll_panel2 = FactoryGirl.create :scroll_panel, :author_id => @other_author.id, :scroll_id => @other_scroll.id, :panel_id => @other_panel.id, :t => 1, :updated_at => Time.now + 100 + @other_scroll_panel3 = FactoryGirl.create :scroll_panel, :author_id => @other_author.id, :scroll_id => @other_scroll.id, :panel_id => @other_panel.id, :t => 2, :updated_at => Time.now + 200 + @other_scroll_panel4 = FactoryGirl.create :scroll_panel, :author_id => @other_author.id, :scroll_id => @other_scroll.id, :panel_id => @other_panel.id, :t => 3, :updated_at => Time.now + 300 + @other_scroll_panel5 = FactoryGirl.create :scroll_panel, :author_id => @other_author.id, :scroll_id => @other_scroll.id, :panel_id => @other_panel.id, :t => 4, :updated_at => Time.now + 400 + ScrollPanel.stub(:default_page_size).and_return(2) + end + it '通常は2件を返す' do + l = ScrollPanel.himlist @other_author, 1, 2 + l.should have(2).items + end + it 'page=1なら末尾2件を返す' do + #時系列で並んでいる + l = ScrollPanel.himlist @other_author, 1, 2 + l.should eq [@other_scroll_panel5, @other_scroll_panel4] + end + it 'page=2なら中間2件を返す' do + l = ScrollPanel.himlist @other_author, 2, 2 + l.should eq [@other_scroll_panel3, @other_scroll_panel2] + end + it 'page=3なら先頭1件を返す' do + l = ScrollPanel.himlist @other_author, 3, 2 + l.should eq [@other_scroll_panel] + end + end + end + + describe 'ストーリー一覧ページ制御に於いて' do + before do + ScrollPanel.stub(:count).with(any_args).and_return(100) + end + it 'ページ制御を返す' do + r = ScrollPanel.list_paginate + r.is_a?(Kaminari::PaginatableArray).should be_true + end + it 'ストーリー一覧の取得条件を利用している' do + ScrollPanel.stub(:list_where).with(any_args).and_return('') + ScrollPanel.should_receive(:list_where).with(any_args).exactly(1) + r = ScrollPanel.list_paginate + end + it 'ページ件数10のとき、3ページ目のオフセットは20から始まる' do + r = ScrollPanel.list_paginate 3, 10 + r.limit_value.should eq 10 + r.offset_value.should eq 20 + end + end + + describe '自分のストーリー一覧ページ制御に於いて' do + before do + ScrollPanel.stub(:count).with(any_args).and_return(100) + end + it 'ページ制御を返す' do + r = ScrollPanel.mylist_paginate @author + r.is_a?(Kaminari::PaginatableArray).should be_true + end + it '自分のストーリー一覧の取得条件を利用している' do + ScrollPanel.stub(:mylist_where).with(any_args).and_return('') + ScrollPanel.should_receive(:mylist_where).with(any_args).exactly(1) + r = ScrollPanel.mylist_paginate @author + end + it 'ページ件数10のとき、3ページ目のオフセットは20から始まる' do + r = ScrollPanel.mylist_paginate @author, 3, 10 + r.limit_value.should eq 10 + r.offset_value.should eq 20 + end + end + + describe '他作家のストーリー一覧ページ制御に於いて' do + before do + ScrollPanel.stub(:count).with(any_args).and_return(100) + end + it 'ページ制御を返す' do + r = ScrollPanel.himlist_paginate @other_author + r.is_a?(Kaminari::PaginatableArray).should be_true + end + it '他作家のストーリー一覧の取得条件を利用している' do + ScrollPanel.stub(:himlist_where).with(any_args).and_return('') + ScrollPanel.should_receive(:himlist_where).with(any_args).exactly(1) + r = ScrollPanel.himlist_paginate @other_author + end + it 'ページ件数10のとき、3ページ目のオフセットは20から始まる' do + r = ScrollPanel.himlist_paginate @other_author, 3, 10 + r.limit_value.should eq 10 + r.offset_value.should eq 20 + end + end + + describe 'list関連テーブルプションに於いて' do + it '3つの項目を含んでいる' do + r = ScrollPanel.list_opt + r.should have(3).items + end + it 'コミックを含んでいる' do + r = ScrollPanel.list_opt + r.has_key?(:scroll).should be_true + end + it 'コミックは作家を含んでいる' do + r = ScrollPanel.list_opt + r[:scroll].has_key?(:author).should be_true + end + it '作家を含んでいる' do + r = ScrollPanel.list_opt + r.has_key?(:author).should be_true + end + it 'コマを含んでいる' do + r = ScrollPanel.list_opt + r.has_key?(:panel).should be_true + end + it 'コマは作家を含んでいる' do + r = ScrollPanel.list_opt + r[:panel].has_key?(:author).should be_true + end + it 'コマはコマ絵を含んでいる' do + r = ScrollPanel.list_opt + r[:panel].has_key?(:panel_pictures).should be_true + end + it 'コマ絵は実素材を含んでいる' do + r = ScrollPanel.list_opt + r[:panel][:panel_pictures].has_key?(:picture).should be_true + end + it '実素材は絵師を含んでいる' do + r = ScrollPanel.list_opt + r[:panel][:panel_pictures][:picture].has_key?(:artist).should be_true + end + it '実素材はライセンスを含んでいる' do + r = ScrollPanel.list_opt + r[:panel][:panel_pictures][:picture].has_key?(:license).should be_true + end + it 'コマはフキダシを含んでいる' do + r = ScrollPanel.list_opt + r[:panel].has_key?(:speech_balloons).should be_true + end + it 'フキダシはフキダシ枠を含んでいる' do + r = ScrollPanel.list_opt + r[:panel][:speech_balloons].has_key?(:balloon).should be_true + end + it 'フキダシはセリフを含んでいる' do + r = ScrollPanel.list_opt + r[:panel][:speech_balloons].has_key?(:speech).should be_true + end + end + describe 'json一覧出力オプションに於いて' do + end + + describe '単体取得に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @author.id + @panel = FactoryGirl.create :panel, :author_id => @author.id + @scroll_panel = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id + end + context 'つつがなく終わるとき' do + it '単体取得オプションを利用している' do + ScrollPanel.stub(:show_opt).with(any_args).and_return({}) + ScrollPanel.should_receive(:show_opt).with(any_args).exactly(1) + r = ScrollPanel.show @scroll_panel.id, @author + end + it '閲覧許可を問い合わせている' do + ScrollPanel.any_instance.stub(:visible?).with(@author).and_return(true) + ScrollPanel.any_instance.should_receive(:visible?).with(@author).exactly(1) + r = ScrollPanel.show @scroll_panel.id, @author + end + end + it '指定のストーリーを返す' do + l = ScrollPanel.show @scroll_panel.id, @author + l.should eq @scroll_panel + end + context '他人のストーリーを開こうとしたとき' do + it '403Forbidden例外を返す' do + ScrollPanel.any_instance.stub(:visible?).with(@other_author).and_return(false) + lambda{ + ScrollPanel.show @scroll_panel.id, @other_author + }.should raise_error(ActiveRecord::Forbidden) + end + end + context '存在しないストーリーを開こうとしたとき' do + it '404RecordNotFound例外を返す' do + lambda{ + ScrollPanel.show 110, @author + }.should raise_error(ActiveRecord::RecordNotFound) + end + end + end + + describe '編集取得に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @author.id + @panel = FactoryGirl.create :panel, :author_id => @author.id + @scroll_panel = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id + end + context 'つつがなく終わるとき' do + it '単体取得オプションを利用している' do + ScrollPanel.stub(:show_opt).with(any_args).and_return({}) + ScrollPanel.should_receive(:show_opt).with(any_args).exactly(1) + r = ScrollPanel.edit @scroll_panel.id, @author + end + it '所持判定を問い合わせている' do + ScrollPanel.any_instance.stub(:own?).with(any_args).and_return(true) + ScrollPanel.any_instance.should_receive(:own?).with(any_args).exactly(1) + r = ScrollPanel.edit @scroll_panel.id, @author + end + end + it '指定のストーリーを返す' do + l = ScrollPanel.edit @scroll_panel.id, @author + l.should eq @scroll_panel + end + context '他人のストーリーを開こうとしたとき' do + it '403Forbidden例外を返す' do + ScrollPanel.any_instance.stub(:own?).and_return(false) + lambda{ + ScrollPanel.edit @scroll_panel.id, @author + }.should raise_error(ActiveRecord::Forbidden) + end + end + context '存在しないストーリーを開こうとしたとき' do + it '404RecordNotFound例外を返す' do + lambda{ + ScrollPanel.edit 110, @author + }.should raise_error(ActiveRecord::RecordNotFound) + end + end + end + + describe '単体取得オプションに於いて' do + it 'includeキーを含んでいる' do + r = ScrollPanel.show_opt + r.has_key?(:include).should be_true + end + it '3つの項目を含んでいる' do + r = ScrollPanel.show_opt[:include] + r.should have(3).items + end + it 'コミックを含んでいる' do + r = ScrollPanel.show_opt[:include] + r.has_key?(:scroll).should be_true + end + it 'コミックは作家を含んでいる' do + r = ScrollPanel.show_opt[:include] + r[:scroll].has_key?(:author).should be_true + end + it '作家を含んでいる' do + r = ScrollPanel.show_opt[:include] + r.has_key?(:author).should be_true + end + it 'コマを含んでいる' do + r = ScrollPanel.show_opt[:include] + r.has_key?(:panel).should be_true + end + it 'コマは作家を含んでいる' do + r = ScrollPanel.show_opt[:include] + r[:panel].has_key?(:author).should be_true + end + it 'コマはコマ絵を含んでいる' do + r = ScrollPanel.show_opt[:include] + r[:panel].has_key?(:panel_pictures).should be_true + end + it 'コマ絵は実素材を含んでいる' do + r = ScrollPanel.show_opt[:include] + r[:panel][:panel_pictures].has_key?(:picture).should be_true + end + it '実素材は絵師を含んでいる' do + r = ScrollPanel.show_opt[:include] + r[:panel][:panel_pictures][:picture].has_key?(:artist).should be_true + end + it '実素材はライセンスを含んでいる' do + r = ScrollPanel.show_opt[:include] + r[:panel][:panel_pictures][:picture].has_key?(:license).should be_true + end + it 'コマはフキダシを含んでいる' do + r = ScrollPanel.show_opt[:include] + r[:panel].has_key?(:speech_balloons).should be_true + end + it 'フキダシはフキダシ枠を含んでいる' do + r = ScrollPanel.show_opt[:include] + r[:panel][:speech_balloons].has_key?(:balloon).should be_true + end + it 'フキダシはセリフを含んでいる' do + r = ScrollPanel.show_opt[:include] + r[:panel][:speech_balloons].has_key?(:speech).should be_true + end + end + describe 'json単体取得オプションに於いて' do + end + + describe 'ストーリーのjson出力に於いて' do + before do + #コマを作成しておく。 + @panel = FactoryGirl.create :panel, :author_id => @author.id + @pp = FactoryGirl.create :panel_picture, :panel_id => @panel.id, :t => 1, :width => @p.width, :height => @p.height + @sb = FactoryGirl.build :speech_balloon, :panel_id => @panel.id, :speech_balloon_template_id => @speech_balloon_template.id + @speech = @sb.build_speech( + FactoryGirl.attributes_for(:speech, :writing_format_id => @writing_format.id) + ) + @balloon = @sb.build_balloon( + FactoryGirl.attributes_for(:balloon, :system_picture_id => @sp.id) + ) + @sb.boost + @sb.save! + @gc = @panel.ground_colors.create( + FactoryGirl.attributes_for(:ground_color, :panel_id => @panel.id) + ) + @gp = @panel.ground_pictures.create( + FactoryGirl.attributes_for(:ground_picture, :panel_id => @panel.id, :picture_id => @p.id) + ) + @panel.reload + @scroll = FactoryGirl.create :scroll, :author_id => @author.id + @scroll_panel = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id + end + context '事前チェックする' do + before do + Panel.any_instance.stub(:elements).and_return('{}') + end + it 'コマ要素のjson出力を依頼している' do + Panel.any_instance.stub(:visible?).with(any_args).and_return(true) + Panel.any_instance.should_receive(:elements).with(any_args).exactly(1) + r = @scroll_panel.scroll_panel_as_json @author + end + end + it 'json textを返している' do + r = JSON.parse @scroll_panel.scroll_panel_as_json(@author) + r.is_a?(Hash).should be_true + end + it 'scroll,author,panel,コマ要素を含んでいる' do + r = JSON.parse @scroll_panel.scroll_panel_as_json(@author) + r.has_key?('scroll').should be_true + r['scroll'].has_key?('author').should be_true + r.has_key?('author').should be_true + r.has_key?('panel').should be_true + r['panel'].has_key?('author').should be_true + end + context 'コマ閲覧許可のとき' do + before do + Panel.any_instance.stub(:visible?).with(any_args).and_return(true) + end + it 'コマ要素にコマ要素を追加している' do + r = JSON.parse @scroll_panel.scroll_panel_as_json(@author) + r['panel'].has_key?('elements').should be_true + r['panel']['elements'].should_not be_empty + end + end + context 'コマ閲覧不許可のとき' do + before do + Panel.any_instance.stub(:visible?).with(any_args).and_return(false) + end + it 'コマ要素にデータを含ませない' do + r = JSON.parse @scroll_panel.scroll_panel_as_json(@author) + r['panel'].has_key?('elements').should be_false + end + end + end + + describe 'ストーリーリストのjson出力に於いて' do + before do + @panel = FactoryGirl.create :panel, :author_id => @author.id + @scroll = FactoryGirl.create :scroll, :author_id => @author.id + @scroll_panel = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id + ScrollPanel.any_instance.stub(:scroll_panel_as_json).with(@author).and_return('{"s": 5}') + end + context 'つつがなく終わるとき' do + it 'ストーリーのjson出力を依頼している' do + ScrollPanel.any_instance.should_receive(:scroll_panel_as_json).with(@author).exactly(1) + r = ScrollPanel.list_as_json_text [@scroll_panel], @author + end + end + it 'json textを返している' do + r = ScrollPanel.list_as_json_text [@scroll_panel], @author + j = JSON.parse r + j.is_a?(Array).should be_true + end + it 'ストーリーを含んでいる' do + r = ScrollPanel.list_as_json_text [@scroll_panel], @author + j = JSON.parse r + j.first.has_key?('s').should be_true + end + end + + describe 'ライセンス素材に於いて' do + before do + #コマを作成しておく。 + @op2 = FactoryGirl.create :original_picture, :artist_id => @artist.id + @p2 = FactoryGirl.create :picture, :original_picture_id => @op2.id, :license_id => @license.id, :artist_id => @artist.id + @rp2 = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :license_id => @license.id, :original_picture_id => @op2.id, :picture_id => @p2.id + @panel = FactoryGirl.create :panel, :author_id => @author.id + @pp = FactoryGirl.create :panel_picture, :panel_id => @panel.id, :t => 0, :width => @p.width, :height => @p.height, :picture_id => @p.id + @panel.reload + @panel2 = FactoryGirl.create :panel, :author_id => @author.id + @pp2= FactoryGirl.create :panel_picture, :panel_id => @panel2.id, :t => 0, :width => @p2.width, :height => @p2.height, :picture_id => @p2.id + @panel2.reload + + @scroll = FactoryGirl.create :scroll, :author_id => @author.id + @scroll_panel = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id + @scroll_panel2 = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel2.id + end + context '事前チェック' do + end + context 'つつがなく終わるとき' do + end + it '連想配列(値は実素材、キーは実素材id)を返している' do + r = ScrollPanel.licensed_pictures [@scroll_panel, @scroll_panel2] + r.is_a?(Hash).should be_true + r.should have(2).items + r[@pp.picture_id].should eq @p + r[@pp2.picture_id].should eq @p2 + end + context 'コマが削除されているときき' do + before do + @panel2.destroy + end + it '削除されているコマは無視する' do + r = ScrollPanel.licensed_pictures [@scroll_panel, @scroll_panel2] + r.is_a?(Hash).should be_true + r.should have(1).items + r[@pp.picture_id].should eq @p + r[@pp2.picture_id].should be_nil + end + end + end + + describe 't補充値に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @author.id + @panel = FactoryGirl.create :panel, :author_id => @author.id + end + + context 'コミック初のコマなら' do + it '0を補充値とする' do + @scroll_panel = FactoryGirl.build :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id + @scroll_panel.t = nil + r = ScrollPanel.new_t @scroll_panel.scroll_id + r.should eq 0 + end + end + context 'コミックに一個コマがあるとき' do + it '1を補充値とする' do + FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id, :t => 0 + @scroll_panel = FactoryGirl.build :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id + @scroll_panel.t = nil + r = ScrollPanel.new_t @scroll_panel.scroll_id + r.should eq 1 + end + end + context 'コミックに2個コマがあるとき' do + it '2を補充値とする' do + FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id, :t => 0 + FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id, :t => 1 + @scroll_panel = FactoryGirl.build :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id + @scroll_panel.t = nil + r = ScrollPanel.new_t @scroll_panel.scroll_id + r.should eq 2 + end + end + end + describe 'シリアライズチェックに於いて' do + context 'つつがなく終わるとき' do + it '0からシリアライズされているならTrueを返す' do + r = ScrollPanel.serial? [0, 1, 2] + r.should be_true + end + it '見た目はシリアライズされてなくてもソート結果が無事ならtrueを返す' do + r = ScrollPanel.serial? [0, 2, 1] + r.should be_true + end + it '見た目はシリアライズされてなくてもソート結果が無事ならtrueを返す' do + r = ScrollPanel.serial? [ 2, 1, 4, 3, 0] + r.should be_true + end + end + context '異常なとき' do + it '0から始まらないならFalseを返す' do + r = ScrollPanel.serial? [1, 2, 3] + r.should be_false + end + it '連続していないならFalseを返す' do + r = ScrollPanel.serial? [0, 1, 2, 4] + r.should be_false + end + it '連続していないならFalseを返す' do + r = ScrollPanel.serial? [0, 1, 2, 4, 5] + r.should be_false + end + end + end + describe 't収集に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @author.id + @panel = FactoryGirl.create :panel, :author_id => @author.id + @scroll_panel = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll2 = FactoryGirl.create :scroll, :author_id => @author.id + @c2scroll_panel = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll2.id, :panel_id => @panel.id, :author_id => @author.id + end + context 'つつがなく終わるとき' do + it 'ストーリーから同一コミックのtだけを収集している' do + r = ScrollPanel.collect_t @scroll_panel + r.should eq [0] + end + end + context '複数コマのとき' do + it 'ストーリーから同一コミックのtだけを収集している' do + @scroll_panel2 = FactoryGirl.create :scroll_panel, :t => 1, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + r = ScrollPanel.collect_t @scroll_panel + r.sort.should eq [0, 1] + end + end + context '複数コマでヨソのコミックも混じっているとき' do + it 'ストーリーから同一コミックのtだけを収集している' do + @scroll_panel2 = FactoryGirl.create :scroll_panel, :t => 1, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + r = ScrollPanel.collect_t @scroll_panel + r.sort.should eq [0, 1] + end + end + end + describe 'tチェックに於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @author.id + @panel = FactoryGirl.create :panel, :author_id => @author.id + @scroll_panel = FactoryGirl.build :scroll_panel, :t => 1, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + end + context 'つつがなく終わるとき' do + it 't収集を依頼している' do + ScrollPanel.should_receive(:collect_t).with(any_args).exactly(1) + ScrollPanel.stub(:collect_t).with(any_args).and_return([]) + ScrollPanel.stub(:serial?).with(any_args).and_return(true) + r = ScrollPanel.validate_t @scroll_panel + end + it '収集したtをシリアライズチェック依頼している' do + ScrollPanel.stub(:collect_t).with(any_args).and_return([]) + ScrollPanel.should_receive(:serial?).with(any_args).exactly(1) + ScrollPanel.stub(:serial?).with(any_args).and_return(true) + r = ScrollPanel.validate_t @scroll_panel + end + end + #実データでチェック + #依頼チェックだけでは不安なので最低限のチェックを + context '新規のとき' do + it '一件だけで正常通過している' do + @scroll_panel = FactoryGirl.build :scroll_panel, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id, :t => 0 + r = ScrollPanel.validate_t @scroll_panel + r.should be_true + end + end + context '既存のとき' do + it '2件目を作っても正常通過している' do + @scroll_panel = FactoryGirl.create :scroll_panel, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id, :t => 0 + @scroll_panel2 = FactoryGirl.build :scroll_panel, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id, :t => 1 + r = ScrollPanel.validate_t @scroll_panel2 + r.should be_true + end + end + end + describe '挿入シフトに於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @author.id + @panel = FactoryGirl.create :panel, :author_id => @author.id + end + context '依頼チェック' do + #テーブルが空で0に挿入 + it 'Updateを依頼している' do + ScrollPanel.stub(:update_all).with(any_args) + ScrollPanel.should_receive(:update_all).with(any_args).exactly(1) + @scroll_panel = FactoryGirl.build :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel.insert_shift + end + end + context 'テーブルに1件(t:0)で0に挿入したとき' do + before do + @scroll_panel = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel2 = FactoryGirl.build :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + end + it '既存の行を1にシフトしている' do + @scroll_panel2.insert_shift + l = ScrollPanel.find :all + l.first.t.should eq 1 + end + it 'これから挿入するt(0)が欠番になっている' do + @scroll_panel2.insert_shift + l = ScrollPanel.find(:all).map {|s| s.t } + l.include?(0).should_not be_true + end + end + context 'テーブルに2件(t:0,1)で1に挿入したとき' do + before do + @scroll_panel = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel2 = FactoryGirl.create :scroll_panel, :t => 1, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel3 = FactoryGirl.build :scroll_panel, :t => 1, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + end + it '既存のt1を2にシフトしてこれから挿入するt(1)が欠番になっている' do + @scroll_panel3.insert_shift + l = ScrollPanel.find(:all).map {|s| s.t } + l.sort.should eq [0, 2] + end + end + context 'テーブルに5件(t:0,1,2,3,4)で2に挿入したとき' do + before do + @scroll_panel = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel2 = FactoryGirl.create :scroll_panel, :t => 1, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel3 = FactoryGirl.create :scroll_panel, :t => 2, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel4 = FactoryGirl.create :scroll_panel, :t => 3, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel5 = FactoryGirl.create :scroll_panel, :t => 4, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel6 = FactoryGirl.build :scroll_panel, :t => 2, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + end + it '既存のt1を2にシフトしてこれから挿入するt(1)が欠番になっている' do + @scroll_panel6.insert_shift + l = ScrollPanel.find(:all).map {|s| s.t } + l.sort.should eq [0, 1, 3, 4, 5] + end + end + context '先ほどのケース+他のコミック1件で挿入したとき' do + before do + @scroll2 = FactoryGirl.create :scroll, :author_id => @author.id + @scroll_panelc2 = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll2.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel2 = FactoryGirl.create :scroll_panel, :t => 1, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel3 = FactoryGirl.create :scroll_panel, :t => 2, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel4 = FactoryGirl.create :scroll_panel, :t => 3, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel5 = FactoryGirl.create :scroll_panel, :t => 4, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel6 = FactoryGirl.build :scroll_panel, :t => 2, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + end + it '既存のt1を2にシフトしてこれから挿入するt(1)が欠番になっている' do + @scroll_panel6.insert_shift + l = ScrollPanel.find(:all, :conditions => ['scroll_id = ?', @scroll.id]).map {|s| s.t } + l.sort.should eq [0, 1, 3, 4, 5] + end + it '他のコミックに影響がない' do + ot = @scroll_panelc2.t + @scroll_panel6.insert_shift + @scroll_panelc2.reload + @scroll_panelc2.t.should eq ot + end + end + end + describe '少ない方に移動に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @author.id + @panel = FactoryGirl.create :panel, :author_id => @author.id + end + context '依頼チェック' do + it 'Updateを依頼している' do + @scroll_panel = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel2 = FactoryGirl.create :scroll_panel, :t => 1, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + ScrollPanel.stub(:update_all).with(any_args) + ScrollPanel.should_receive(:update_all).with(any_args).exactly(1) + ot = @scroll_panel2.t + @scroll_panel2.t = 0 + @scroll_panel2.lesser_shift ot + end + end + context 'テーブルに2件(t:0,1)で1を0に移動したとき' do + before do + @scroll_panel = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel2 = FactoryGirl.create :scroll_panel, :t => 1, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @ot = @scroll_panel2.t + @scroll_panel2.t = 0 + end + it '既存のt0を1にシフトしてこれから挿入するt(0)が欠番になっている' do + #移動させたい行はそのまま残る + @scroll_panel2.lesser_shift @ot + l = ScrollPanel.find(:all).map {|s| s.t } + l.sort.should eq [1, 1] + end + it '既存のt0を1にシフトしている' do + @scroll_panel2.lesser_shift @ot + @scroll_panel.reload + @scroll_panel.t.should eq 1 + end + end + context 'テーブルに3件(t:0,1,2)で2を1に移動したとき' do + before do + @scroll_panel = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel2 = FactoryGirl.create :scroll_panel, :t => 1, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel3 = FactoryGirl.create :scroll_panel, :t => 2, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @ot = @scroll_panel3.t + @scroll_panel3.t = 1 + end + it '既存のt1を2にシフトしてこれから挿入するt(1)が欠番になっている' do + #移動させたい行はそのまま残る + @scroll_panel3.lesser_shift @ot + l = ScrollPanel.find(:all).map {|s| s.t } + l.sort.should eq [0, 2, 2] + end + it '既存のt1を2にシフトしている' do + @scroll_panel3.lesser_shift @ot + @scroll_panel2.reload + @scroll_panel2.t.should eq 2 + end + end + context 'テーブルに5件(t:0,1,2,3,4)で3を1に移動したとき' do + before do + @scroll_panel = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel2 = FactoryGirl.create :scroll_panel, :t => 1, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel3 = FactoryGirl.create :scroll_panel, :t => 2, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel4 = FactoryGirl.create :scroll_panel, :t => 3, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel5 = FactoryGirl.create :scroll_panel, :t => 4, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @ot = @scroll_panel4.t + @scroll_panel4.t = 1 + end + it 'これから挿入するt(1)が欠番になっている' do + #移動させたい行はそのまま残る + @scroll_panel4.lesser_shift @ot + l = ScrollPanel.find(:all).map {|s| s.t } + l.sort.should eq [0, 2, 3, 3, 4] + end + it '既存のt0には変化がない' do + @scroll_panel4.lesser_shift @ot + @scroll_panel.reload + @scroll_panel.t.should eq 0 + end + it '既存のt4には変化がない' do + @scroll_panel4.lesser_shift @ot + @scroll_panel5.reload + @scroll_panel5.t.should eq 4 + end + it '既存のt1を2にシフトしている' do + @scroll_panel4.lesser_shift @ot + @scroll_panel2.reload + @scroll_panel2.t.should eq 2 + end + it '既存のt2を3にシフトしている' do + @scroll_panel4.lesser_shift @ot + @scroll_panel3.reload + @scroll_panel3.t.should eq 3 + end + end + context '先ほどのケース+他のコミック1件で挿入したとき' do + before do + @scroll2 = FactoryGirl.create :scroll, :author_id => @author.id + @scroll_panelc2 = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll2.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel2 = FactoryGirl.create :scroll_panel, :t => 1, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel3 = FactoryGirl.create :scroll_panel, :t => 2, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel4 = FactoryGirl.create :scroll_panel, :t => 3, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel5 = FactoryGirl.create :scroll_panel, :t => 4, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @ot = @scroll_panel4.t + @scroll_panel4.t = 1 + end + it 'これから挿入するt(1)が欠番になっている' do + @scroll_panel4.lesser_shift @ot + l = ScrollPanel.find(:all).map {|s| s.t } + l.sort.should eq [0, 0, 2, 3, 3, 4] + end + it '既存のt0には変化がない' do + @scroll_panel4.lesser_shift @ot + @scroll_panel.reload + @scroll_panel.t.should eq 0 + end + it '既存のt4には変化がない' do + @scroll_panel4.lesser_shift @ot + @scroll_panel5.reload + @scroll_panel5.t.should eq 4 + end + it '既存のt1を2にシフトしている' do + @scroll_panel4.lesser_shift @ot + @scroll_panel2.reload + @scroll_panel2.t.should eq 2 + end + it '既存のt2を3にシフトしている' do + @scroll_panel4.lesser_shift @ot + @scroll_panel3.reload + @scroll_panel3.t.should eq 3 + end + it '他のコミックに影響がない' do + @scroll_panel4.lesser_shift @ot + @scroll_panelc2.reload + @scroll_panelc2.t.should eq 0 + end + end + #例外ケース。 + #負のときは0として正常扱い + context 'テーブルに2件(t:0,1)で1を-1に移動したとき' do + before do + @scroll_panel = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel2 = FactoryGirl.create :scroll_panel, :t => 1, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @ot = @scroll_panel2.t + @scroll_panel2.t = -1 + end + it '既存のt0を1にシフトしてこれから挿入するt(0)が欠番になっている' do + #移動させたい行はそのまま残る + @scroll_panel2.lesser_shift @ot + l = ScrollPanel.find(:all).map {|s| s.t } + l.sort.should eq [1, 1] + end + it '既存のt0を1にシフトしている' do + @scroll_panel2.lesser_shift @ot + @scroll_panel.reload + @scroll_panel.t.should eq 1 + end + it '既存のt1は0に補正されている' do + @scroll_panel2.lesser_shift @ot + @scroll_panel2.t.should eq 0 + end + end + end + describe '大きい方に移動に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @author.id + @panel = FactoryGirl.create :panel, :author_id => @author.id + end + context '依頼チェック' do + it 'Updateを依頼している' do + @scroll_panel = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel2 = FactoryGirl.create :scroll_panel, :t => 1, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + ScrollPanel.stub(:update_all).with(any_args) + ScrollPanel.should_receive(:update_all).with(any_args).exactly(1) + ot = @scroll_panel.t + @scroll_panel.t = 1 + @scroll_panel.higher_shift ot + end + end + context 'テーブルに2件(t:0,1)で0を1に移動したとき' do + before do + @scroll_panel = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel2 = FactoryGirl.create :scroll_panel, :t => 1, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @ot = @scroll_panel.t + @scroll_panel.t = 1 + end + it '既存のt1を0にシフトしてこれから挿入するt(1)が欠番になっている' do + #移動させたい行はそのまま残る + @scroll_panel.higher_shift @ot + l = ScrollPanel.find(:all).map {|s| s.t } + l.sort.should eq [0, 0] + end + it '既存のt1を0にシフトしている' do + @scroll_panel.higher_shift @ot + @scroll_panel2.reload + @scroll_panel2.t.should eq 0 + end + end + context 'テーブルに3件(t:0,1,2)で0を1に移動したとき' do + before do + @scroll_panel = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel2 = FactoryGirl.create :scroll_panel, :t => 1, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel3 = FactoryGirl.create :scroll_panel, :t => 2, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @ot = @scroll_panel.t + @scroll_panel.t = 1 + end + it '既存のt1を0にシフトしてこれから挿入するt(1)が欠番になっている' do + #移動させたい行はそのまま残る + @scroll_panel.higher_shift @ot + l = ScrollPanel.find(:all).map {|s| s.t } + l.sort.should eq [0, 0, 2] + end + it '既存のt1を0にシフトしている' do + @scroll_panel.higher_shift @ot + @scroll_panel2.reload + @scroll_panel2.t.should eq 0 + end + end + context 'テーブルに5件(t:0,1,2,3,4)で1を3に移動したとき' do + before do + @scroll_panel = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel2 = FactoryGirl.create :scroll_panel, :t => 1, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel3 = FactoryGirl.create :scroll_panel, :t => 2, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel4 = FactoryGirl.create :scroll_panel, :t => 3, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel5 = FactoryGirl.create :scroll_panel, :t => 4, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @ot = @scroll_panel2.t + @scroll_panel2.t = 3 + end + it 'これから挿入するt(3)が欠番になっている' do + #移動させたい行はそのまま残る + @scroll_panel2.higher_shift @ot + l = ScrollPanel.find(:all).map {|s| s.t } + l.sort.should eq [0, 1, 1, 2, 4] + end + it '既存のt0には変化がない' do + @scroll_panel2.higher_shift @ot + @scroll_panel.reload + @scroll_panel.t.should eq 0 + end + it '既存のt4には変化がない' do + @scroll_panel2.higher_shift @ot + @scroll_panel5.reload + @scroll_panel5.t.should eq 4 + end + it '既存のt2を1にシフトしている' do + @scroll_panel2.higher_shift @ot + @scroll_panel3.reload + @scroll_panel3.t.should eq 1 + end + it '既存のt3を2にシフトしている' do + @scroll_panel2.higher_shift @ot + @scroll_panel4.reload + @scroll_panel4.t.should eq 2 + end + end + context '先ほどのケース+他のコミック1件で挿入したとき' do + before do + @scroll2 = FactoryGirl.create :scroll, :author_id => @author.id + @scroll_panelc2 = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll2.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel2 = FactoryGirl.create :scroll_panel, :t => 1, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel3 = FactoryGirl.create :scroll_panel, :t => 2, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel4 = FactoryGirl.create :scroll_panel, :t => 3, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel5 = FactoryGirl.create :scroll_panel, :t => 4, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @ot = @scroll_panel2.t + @scroll_panel2.t = 3 + end + it 'これから挿入するt(3)が欠番になっている' do + #移動させたい行はそのまま残る + @scroll_panel2.higher_shift @ot + l = ScrollPanel.find(:all).map {|s| s.t } + l.sort.should eq [0, 0, 1, 1, 2, 4] + end + it '既存のt0には変化がない' do + @scroll_panel2.higher_shift @ot + @scroll_panel.reload + @scroll_panel.t.should eq 0 + end + it '既存のt4には変化がない' do + @scroll_panel2.higher_shift @ot + @scroll_panel5.reload + @scroll_panel5.t.should eq 4 + end + it '既存のt2を1にシフトしている' do + @scroll_panel2.higher_shift @ot + @scroll_panel3.reload + @scroll_panel3.t.should eq 1 + end + it '既存のt3を2にシフトしている' do + @scroll_panel2.higher_shift @ot + @scroll_panel4.reload + @scroll_panel4.t.should eq 2 + end + it '他のコミックに影響がない' do + @scroll_panel2.higher_shift @ot + @scroll_panelc2.reload + @scroll_panelc2.t.should eq 0 + end + end + #例外ケース。 + #max超えたときはmaxとして正常扱い + context 'テーブルに2件(t:0,1)で0を2に移動したとき' do + before do + @scroll_panel = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel2 = FactoryGirl.create :scroll_panel, :t => 1, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @ot = @scroll_panel.t + @scroll_panel.t = 2 + end + it '既存のt1を0にシフトしてこれから挿入するt(1)が欠番になっている' do + #移動させたい行はそのまま残る + @scroll_panel.higher_shift @ot + l = ScrollPanel.find(:all).map {|s| s.t } + l.sort.should eq [0, 0] + end + it '既存のt1を0にシフトしている' do + @scroll_panel.higher_shift @ot + @scroll_panel2.reload + @scroll_panel2.t.should eq 0 + end + it '既存のt0は1に補正されている' do + @scroll_panel.higher_shift @ot + @scroll_panel.t.should eq 1 + end + end + end + describe '入れ替えに於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @author.id + @panel = FactoryGirl.create :panel, :author_id => @author.id + @scroll_panel = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel2 = FactoryGirl.create :scroll_panel, :t => 1, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + end + context '新tが旧tより小さいとき' do + it '少ない方に移動を依頼している' do + ScrollPanel.any_instance.stub(:lesser_shift).with(any_args) + ScrollPanel.any_instance.should_receive(:lesser_shift).with(any_args).exactly(1) + ot = @scroll_panel2.t + @scroll_panel2.t = 0 + @scroll_panel2.update_shift ot + end + end + context '新tが旧tより大きいとき' do + it '大きい方に移動を依頼している' do + ScrollPanel.any_instance.stub(:higher_shift).with(any_args) + ScrollPanel.any_instance.should_receive(:higher_shift).with(any_args).exactly(1) + ot = @scroll_panel.t + @scroll_panel.t = 1 + @scroll_panel.update_shift ot + end + end + end + describe '順序入れ替えに於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @author.id + @panel = FactoryGirl.create :panel, :author_id => @author.id + end + context 'オブジェクトが新規でtが空のとき' do + it '末尾追加としてtを補充依頼している' do + @scroll_panel = FactoryGirl.build :scroll_panel, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + ScrollPanel.stub(:new_t).with(any_args).and_return(0) + ScrollPanel.should_receive(:new_t).with(any_args).exactly(1) + @scroll_panel.t = nil + r = @scroll_panel.rotate + end + end + context 'オブジェクトが新規でtが設定されているとき' do + it '挿入追加として挿入シフトを依頼している' do + @scroll_panel = FactoryGirl.build :scroll_panel, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + ScrollPanel.any_instance.stub(:insert_shift).with(any_args) + ScrollPanel.any_instance.should_receive(:insert_shift).with(any_args).exactly(1) + @scroll_panel.t = 0 + r = @scroll_panel.rotate + end + end + context 'オブジェクトが新規でなくtが設定されているとき' do + it 'コマ移動として入れ替えを依頼している' do + @scroll_panel = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel2 = FactoryGirl.create :scroll_panel, :t => 1, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + ScrollPanel.any_instance.stub(:update_shift).with(any_args) + ScrollPanel.any_instance.should_receive(:update_shift).with(1).exactly(1) + @scroll_panel2.t = 0 + r = @scroll_panel.rotate 1 + end + end + context 'オブジェクトが新規でなくtが空のとき' do + it '入れ替えもシフトもせず、tを空のままにしている' do + #結果、tに欠番が生じてシリアライズチェックでひっかかる + end + end + end + describe '編集許可に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @author.id + @panel = FactoryGirl.create :panel, :author_id => @author.id + @scroll_panel = FactoryGirl.build :scroll_panel, :t => nil, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + end + context 'つつがなく終わるとき' do + it 'trueを返す' do + r = @scroll_panel.allow? + r.should be_true + end + end + context 'コミックで引っかかるとき' do + it 'falseを返す' do + Panel.any_instance.stub(:usable?).with(any_args).and_return(true) + Scroll.any_instance.stub(:own?).with(any_args).and_return(false) + r = @scroll_panel.allow? + r.should be_false + end + end + context 'コマで引っかかるとき' do + it 'falseを返す' do + Scroll.any_instance.stub(:own?).with(any_args).and_return(true) + Panel.any_instance.stub(:usable?).with(any_args).and_return(false) + r = @scroll_panel.allow? + r.should be_false + end + end + context 'コミックまたはコマが指定されていなかったとき' do + it 'nilを返す' do + Scroll.any_instance.stub(:own?).with(any_args).and_return(true) + @scroll_panel.panel_id = nil + r = @scroll_panel.allow? + r.should eq nil + end + it 'nilを返す' do + Panel.any_instance.stub(:usable?).with(any_args).and_return(true) + @scroll_panel.scroll_id = nil + r = @scroll_panel.allow? + r.should eq nil + end + end + end + describe '保存に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @author.id + @panel = FactoryGirl.create :panel, :author_id => @author.id + @scroll_panel = FactoryGirl.build :scroll_panel, :t => nil, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + end + context 'つつがなく終わるとき' do + it '編集許可チェックを依頼している' do + ScrollPanel.any_instance.stub(:allow?).with(any_args).and_return(true) + ScrollPanel.any_instance.should_receive(:allow?).with(any_args).exactly(1) + r = @scroll_panel.store + end + it '順序入れ替えを依頼している' do + ScrollPanel.any_instance.stub(:rotate).with(any_args).and_return(0) + ScrollPanel.any_instance.should_receive(:rotate).with(any_args).exactly(1) + ScrollPanel.any_instance.stub(:save).with(any_args).and_return(true) + ScrollPanel.stub(:validate_t).with(any_args).and_return(true) + r = @scroll_panel.store + end + it '保存を依頼している' do + ScrollPanel.stub(:new_t).with(any_args).and_return(0) + ScrollPanel.any_instance.stub(:save).with(any_args).and_return(true) + ScrollPanel.any_instance.should_receive(:save).with(any_args).exactly(1) + ScrollPanel.stub(:validate_t).with(any_args).and_return(true) + r = @scroll_panel.store + end + it 'tのシリアライズチェックを依頼している' do + ScrollPanel.stub(:new_t).with(any_args).and_return(0) + ScrollPanel.any_instance.stub(:save).with(any_args).and_return(true) + ScrollPanel.stub(:validate_t).with(any_args).and_return(true) + ScrollPanel.should_receive(:validate_t).with(any_args).exactly(1) + r = @scroll_panel.store + end + end + #入れ替えテストと同じテストを実施。こちらはシフトだけでなく本尊も更新されている + context 'テーブルに5件(t:0,1,2,3,4)+他のコミック1件で2に挿入したとき' do + before do + @scroll2 = FactoryGirl.create :scroll, :author_id => @author.id + @scroll_panelc2 = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll2.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel2 = FactoryGirl.create :scroll_panel, :t => 1, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel3 = FactoryGirl.create :scroll_panel, :t => 2, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel4 = FactoryGirl.create :scroll_panel, :t => 3, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel5 = FactoryGirl.create :scroll_panel, :t => 4, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel6 = FactoryGirl.build :scroll_panel, :t => 2, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + end + it '既存のt0には変化がない' do + @scroll_panel6.store + @scroll_panel.reload + @scroll_panel.t.should eq 0 + end + it '既存のt1には変化がない' do + @scroll_panel6.store + @scroll_panel2.reload + @scroll_panel2.t.should eq 1 + end + it '既存のt2を3にシフトしている' do + @scroll_panel6.store + @scroll_panel3.reload + @scroll_panel3.t.should eq 3 + end + it '既存のt3を4にシフトしている' do + @scroll_panel6.store + @scroll_panel4.reload + @scroll_panel4.t.should eq 4 + end + it '既存のt5を5にシフトしている' do + @scroll_panel6.store + @scroll_panel5.reload + @scroll_panel5.t.should eq 5 + end + it '新規のt2が作成されている' do + @scroll_panel6.store + @scroll_panel6.reload + @scroll_panel6.t.should eq 2 + end + it '他のコミックに影響がない' do + @ot = @scroll_panelc2.t + @scroll_panel6.store + @scroll_panelc2.reload + @scroll_panelc2.t.should eq @ot + end + end + context 'テーブルに5件(t:0,1,2,3,4)+他のコミック1件で3を1に移動したとき' do + before do + @scroll2 = FactoryGirl.create :scroll, :author_id => @author.id + @scroll_panelc2 = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll2.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel2 = FactoryGirl.create :scroll_panel, :t => 1, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel3 = FactoryGirl.create :scroll_panel, :t => 2, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel4 = FactoryGirl.create :scroll_panel, :t => 3, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel5 = FactoryGirl.create :scroll_panel, :t => 4, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @ot = @scroll_panel4.t + @scroll_panel4.t = 1 + end + it '既存のt0には変化がない' do + @scroll_panel4.store @ot + @scroll_panel.reload + @scroll_panel.t.should eq 0 + end + it '既存のt4には変化がない' do + @scroll_panel4.store @ot + @scroll_panel5.reload + @scroll_panel5.t.should eq 4 + end + it '既存のt1を2にシフトしている' do + @scroll_panel4.store @ot + @scroll_panel2.reload + @scroll_panel2.t.should eq 2 + end + it '既存のt2を3にシフトしている' do + @scroll_panel4.store @ot + @scroll_panel3.reload + @scroll_panel3.t.should eq 3 + end + it '既存のt3を1にシフトしている' do + @scroll_panel4.store @ot + @scroll_panel4.reload + @scroll_panel4.t.should eq 1 + end + it '他のコミックに影響がない' do + @scroll_panel4.store @ot + @scroll_panelc2.reload + @scroll_panelc2.t.should eq 0 + end + end + context 'テーブルに5件(t:0,1,2,3,4)+他のコミック1件で1を3に移動したとき' do + before do + @scroll2 = FactoryGirl.create :scroll, :author_id => @author.id + @scroll_panelc2 = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll2.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel2 = FactoryGirl.create :scroll_panel, :t => 1, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel3 = FactoryGirl.create :scroll_panel, :t => 2, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel4 = FactoryGirl.create :scroll_panel, :t => 3, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel5 = FactoryGirl.create :scroll_panel, :t => 4, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @ot = @scroll_panel2.t + @scroll_panel2.t = 3 + end + it '既存のt0には変化がない' do + @scroll_panel2.store @ot + @scroll_panel.reload + @scroll_panel.t.should eq 0 + end + it '既存のt4には変化がない' do + @scroll_panel2.store @ot + @scroll_panel5.reload + @scroll_panel5.t.should eq 4 + end + it '既存のt1を3にシフトしている' do + @scroll_panel2.store @ot + @scroll_panel2.reload + @scroll_panel2.t.should eq 3 + end + it '既存のt2を1にシフトしている' do + @scroll_panel2.store @ot + @scroll_panel3.reload + @scroll_panel3.t.should eq 1 + end + it '既存のt3を2にシフトしている' do + @scroll_panel2.store @ot + @scroll_panel4.reload + @scroll_panel4.t.should eq 2 + end + it '他のコミックに影響がない' do + @scroll_panel2.store @ot + @scroll_panelc2.reload + @scroll_panelc2.t.should eq 0 + end + end + #ロールバックテスト。入れ替えが直接DBをいじるので、すべてのケースで確実にロールバックを確認する + context 'テーブルに5件(t:0,1,2,3,4)+他のコミック1件で2に挿入したが保存に失敗したとき' do + before do + ScrollPanel.any_instance.stub(:save).with(any_args).and_return(false) + @scroll2 = FactoryGirl.create :scroll, :author_id => @author.id + @scroll_panelc2 = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll2.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel2 = FactoryGirl.create :scroll_panel, :t => 1, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel3 = FactoryGirl.create :scroll_panel, :t => 2, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel4 = FactoryGirl.create :scroll_panel, :t => 3, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel5 = FactoryGirl.create :scroll_panel, :t => 4, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel6 = FactoryGirl.build :scroll_panel, :t => 2, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + end + it '既存のtに変化がない' do + @scroll_panel6.store + @scroll_panel.reload + @scroll_panel.t.should eq 0 + @scroll_panel2.reload + @scroll_panel2.t.should eq 1 + @scroll_panel3.reload + @scroll_panel3.t.should eq 2 + @scroll_panel4.reload + @scroll_panel4.t.should eq 3 + @scroll_panel5.reload + @scroll_panel5.t.should eq 4 + @scroll_panelc2.reload + @scroll_panelc2.t.should eq 0 + end + it 'falseを返す' do + r = @scroll_panel6.store + r.should be_false + end + end + context 'テーブルに5件(t:0,1,2,3,4)+他のコミック1件で3を1に移動したがシリアルチェックに失敗したとき' do + before do + ScrollPanel.stub(:validate_t).with(any_args).and_return(false) + @scroll2 = FactoryGirl.create :scroll, :author_id => @author.id + @scroll_panelc2 = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll2.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel2 = FactoryGirl.create :scroll_panel, :t => 1, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel3 = FactoryGirl.create :scroll_panel, :t => 2, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel4 = FactoryGirl.create :scroll_panel, :t => 3, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel5 = FactoryGirl.create :scroll_panel, :t => 4, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @ot = @scroll_panel4.t + @scroll_panel4.t = 1 + end + it '既存のtに変化がない' do + @scroll_panel4.store @ot + @scroll_panel.reload + @scroll_panel.t.should eq 0 + @scroll_panel2.reload + @scroll_panel2.t.should eq 1 + @scroll_panel3.reload + @scroll_panel3.t.should eq 2 + @scroll_panel4.reload + @scroll_panel4.t.should eq 3 + @scroll_panel5.reload + @scroll_panel5.t.should eq 4 + @scroll_panelc2.reload + @scroll_panelc2.t.should eq 0 + end + it 'falseを返す' do + r = @scroll_panel4.store @ot + r.should be_false + end + it 'tにエラーメッセージが入っている' do + @scroll_panel4.store @ot + @scroll_panel4.errors[:t].should_not be_empty + @scroll_panel4.valid?.should be_true + end + end + context '編集不可だったとき' do + before do + @scroll_panel = FactoryGirl.build :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + ScrollPanel.any_instance.stub(:allow?).and_return(false) + end + it '403Forbidden例外を返す' do + lambda{ + @scroll_panel.store + }.should raise_error(ActiveRecord::Forbidden) + end + end + end + describe '切り詰め処理つき削除に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @author.id + @panel = FactoryGirl.create :panel, :author_id => @author.id + @scroll_panel = FactoryGirl.create :scroll_panel, :t => 0, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + end + context 'つつがなく終わるとき' do + it '削除される' do + lambda{ + @scroll_panel.destroy_and_shorten + }.should change(ScrollPanel, :count ).by(-1) + end + it 'Trueを返す' do + r = @scroll_panel.destroy_and_shorten + r.should be_true + end + end + context '削除に失敗したとき' do + before do + ScrollPanel.any_instance.stub(:destroy).and_return(false) + end + it 'ロールバックされる' do + lambda{ + @scroll_panel.destroy_and_shorten + }.should_not change(ScrollPanel, :count ) + end + it 'Falseを返す' do + r = @scroll_panel.destroy_and_shorten + r.should be_false + end + end + #連携テスト。切り詰めが直接DBをいじる + context '2件で先頭を削除したとき' do + before do + @scroll_panel2 = FactoryGirl.create :scroll_panel, :t => 1, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + end + it '行が削除される' do + lambda{ + @scroll_panel.destroy_and_shorten + }.should change(ScrollPanel, :count ).by(-1) + end + it '先頭は削除される' do + @scroll_panel.destroy_and_shorten + lambda{ + ScrollPanel.find @scroll_panel.id + }.should raise_error(ActiveRecord::RecordNotFound) + end + it '2件目は前に詰められる' do + @scroll_panel.destroy_and_shorten + @scroll_panel2.reload + @scroll_panel2.t.should eq 0 + end + end + context '3件で先頭を削除したとき' do + before do + @scroll_panel2 = FactoryGirl.create :scroll_panel, :t => 1, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel3 = FactoryGirl.create :scroll_panel, :t => 2, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + end + it '行が削除される' do + lambda{ + @scroll_panel.destroy_and_shorten + }.should change(ScrollPanel, :count ).by(-1) + end + it '先頭は削除される' do + @scroll_panel.destroy_and_shorten + lambda{ + ScrollPanel.find @scroll_panel.id + }.should raise_error(ActiveRecord::RecordNotFound) + end + it '2件目は前に詰められる' do + @scroll_panel.destroy_and_shorten + @scroll_panel2.reload + @scroll_panel2.t.should eq 0 + end + it '3件目は前に詰められる' do + @scroll_panel.destroy_and_shorten + @scroll_panel3.reload + @scroll_panel3.t.should eq 1 + end + end + context '5件で3件目を削除したとき' do + before do + @scroll_panel2 = FactoryGirl.create :scroll_panel, :t => 1, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel3 = FactoryGirl.create :scroll_panel, :t => 2, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel4 = FactoryGirl.create :scroll_panel, :t => 3, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + @scroll_panel5 = FactoryGirl.create :scroll_panel, :t => 4, :scroll_id => @scroll.id, :panel_id => @panel.id, :author_id => @author.id + end + it '行が削除される' do + lambda{ + @scroll_panel3.destroy_and_shorten + }.should change(ScrollPanel, :count ).by(-1) + end + it '1件目は変化がない' do + @scroll_panel3.destroy_and_shorten + @scroll_panel.reload + @scroll_panel.t.should eq 0 + end + it '2件目は変化がない' do + @scroll_panel3.destroy_and_shorten + @scroll_panel2.reload + @scroll_panel2.t.should eq 1 + end + it '3件目は削除される' do + @scroll_panel3.destroy_and_shorten + lambda{ + ScrollPanel.find @scroll_panel3.id + }.should raise_error(ActiveRecord::RecordNotFound) + end + it '4件目は前に詰められる' do + @scroll_panel3.destroy_and_shorten + @scroll_panel4.reload + @scroll_panel4.t.should eq 2 + end + it '5件目は前に詰められる' do + @scroll_panel3.destroy_and_shorten + @scroll_panel5.reload + @scroll_panel5.t.should eq 3 + end + end + #ロールバックテスト。切り詰めが直接DBをいじるので、すべてのケースで確実にロールバックを確認する + end +end diff --git a/spec/models/scroll_spec.rb b/spec/models/scroll_spec.rb new file mode 100644 index 00000000..3b76b142 --- /dev/null +++ b/spec/models/scroll_spec.rb @@ -0,0 +1,840 @@ +# -*- encoding: utf-8 -*- +require 'spec_helper' +#コミック + +describe Scroll do + before do + @admin = FactoryGirl.create :admin + @demand_user = FactoryGirl.create :demand_user + @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 = FactoryGirl.create :author, :user_id => @user.id + @artist = FactoryGirl.create :artist_yas, :author_id => @author.id + @other_user = FactoryGirl.create( :user_yas) + @other_author = FactoryGirl.create :author, :user_id => @other_user.id + @other_artist = FactoryGirl.create :artist_yas, :author_id => @other_author.id + end + + describe '検証に於いて' do + before do + @scroll = FactoryGirl.build :scroll, :author_id => @author.id + end + + context 'オーソドックスなデータのとき' do + it '下限データが通る' do + @scroll.title = 'a' + @scroll.visible = 0 + @scroll.should be_valid + end + it '上限データが通る' do + @scroll.title = 'a'*100 + @scroll.visible = 1 + @scroll.should be_valid + end + end + + context 'titleを検証するとき' do + it 'nullなら失敗する' do + @scroll.title = nil + @scroll.should_not be_valid + end + it '100文字以上なら失敗する' do + @scroll.title = 'a'*101 + @scroll.should_not be_valid + end + end + context 'visibleを検証するとき' do + it 'nullなら失敗する' do + @scroll.visible = nil + @scroll.should_not be_valid + end + it '負なら失敗する' do + @scroll.visible = -1 + @scroll.should_not be_valid + end + it '2以上なら失敗する' do + @scroll.visible = 2 + @scroll.should_not be_valid + end + end + end + + describe '文字コード検証に於いて' do + before do + @scroll = FactoryGirl.build :scroll, :author_id => @author.id + end + + context 'titleを検証するとき' do + it 'Shift JISなら失敗する' do + @scroll.title = "\x83G\x83r\x83]\x83D" + lambda{ + @scroll.valid_encode + }.should raise_error(Pettanr::BadRequest) + end + end + + context 'descriptionを検証するとき' do + it 'Shift JISなら失敗する' do + @scroll.description = "\x83G\x83r\x83]\x83D" + lambda{ + @scroll.valid_encode + }.should raise_error(Pettanr::BadRequest) + end + end + end + + describe 'デフォルト値補充に於いて' do + it 'visibleが0になっている' do + @scroll = FactoryGirl.build :scroll, :visible => nil + @scroll.supply_default + @scroll.visible.should eq 0 + end + end + + describe '上書き補充に於いて' do + it '作家idが設定されている' do + @scroll = FactoryGirl.build :scroll, :author_id => nil + @scroll.overwrite @author + @scroll.author_id.should eq @author.id + end + end + + describe 'ロールリストからの作家取得に於いて' do + context 'ロールがユーザのとき' do + it 'ユーザから作家を取得して、それを返す' do + r = Scroll.get_author_from_roles([@user]) + r.should eq @author + end + end + context 'ロールが作家のとき' do + it '作家を返す' do + r = Scroll.get_author_from_roles([@author]) + r.should eq @author + end + end + context 'ロールが絵師のとき' do + it '絵師から作家を取得できれば、それをを返す' do + r = Scroll.get_author_from_roles([@artist]) + r.should eq @author + end + it '絵師から作家を取得できないときnilを返す' do + @artist.author_id = nil + @artist.save! + r = Scroll.get_author_from_roles([@artist]) + r.should be_nil + end + end + context 'ロールが管理者のとき' do + it 'nilを返す' do + r = Scroll.get_author_from_roles([@admin]) + r.should be_nil + end + end + end + + describe 'ロールリストからの絵師取得に於いて' do + context 'ロールがユーザのとき' do + it 'ユーザから作家を取得して、そこから絵師を取得できれば、それを返す' do + r = Scroll.get_artist_from_roles([@user]) + r.should eq @artist + end + it '作家から絵師を取得できないときnilを返す' do + @artist.author_id = nil + @artist.save! + r = Scroll.get_artist_from_roles([@user]) + r.should be_nil + end + end + context 'ロールが作家のとき' do + it 'そこから絵師を取得できれば、それを返す' do + r = Scroll.get_artist_from_roles([@author]) + r.should eq @artist + end + it '作家から絵師を取得できないときnilを返す' do + @artist.author_id = nil + @artist.save! + r = Scroll.get_artist_from_roles([@author]) + r.should be_nil + end + end + context 'ロールが絵師のとき' do + it 'それを返す' do + r = Scroll.get_artist_from_roles([@artist]) + r.should eq @artist + end + end + context 'ロールが管理者のとき' do + it 'nilを返す' do + r = Scroll.get_artist_from_roles([@admin]) + r.should be_nil + end + end + end + + describe '所持判定に於いて' do + before do + @scroll = FactoryGirl.build :scroll, :author_id => @author.id + end + context '事前チェックする' do + it '自身にロールリストからの作家取得を依頼している' do + Scroll.should_receive(:get_author_from_roles).with(any_args).exactly(1) + r = @scroll.own?([@author]) + end + end + context 'ロール内作家が取得できるとき' do + before do + end + it 'ロール内作家のidが自身の作家idと一致するなら許可する' do + Scroll.stub(:get_author_from_roles).with(any_args).and_return(@author) + r = @scroll.own?([@author]) + r.should be_true + end + it 'ロール内作家のidが自身の作家idと一致しないならno' do + Scroll.stub(:get_author_from_roles).with(any_args).and_return(@other_author) + @scroll.own?(@other_author).should be_false + end + end + context 'ロール内作家が取得できないとき' do + before do + Scroll.stub(:get_author_from_roles).with(any_args).and_return(nil) + end + it 'Falseを返す' do + r = @scroll.own?([@author]) + r.should be_false + end + end + end + + describe '読者用ロールチェックに於いて' do + before do + @scroll = FactoryGirl.build :scroll, :author_id => @author.id + end + context 'ロールリストに作家が含まれるとき' do + it 'ロールリストがリストではないとき、リストにする trueを返す' do + r = @scroll.reader_role_check(@author) + r.should be_true + end + it 'trueを返す' do + r = @scroll.reader_role_check([@author]) + r.should be_true + end + end + context 'ロールリストに絵師が含まれるとき' do + it 'trueを返す' do + r = @scroll.reader_role_check([@artist]) + r.should be_true + end + end + context 'ロールリストにユーザが含まれるとき' do + it 'trueを返す' do + r = @scroll.reader_role_check([@user]) + r.should be_true + end + end + context 'ロールリストに管理者が含まれるとき' do + it 'trueを返す' do + r = @scroll.reader_role_check([@admin]) + r.should be_true + end + end + context 'ロールリストにユーザ、管理者、作家、絵師が含まれないとき' do + it 'falseを返す' do + r = @scroll.reader_role_check([nil]) + r.should be_false + end + end + end + + describe '素材読者用ロールチェックに於いて' do + before do + @scroll = FactoryGirl.build :scroll, :author_id => @author.id + end + context 'ロールリストに作家が含まれるとき' do + it 'ロールリストがリストではないとき、リストにする trueを返す' do + r = @scroll.resource_reader_role_check(@author) + r.should be_true + end + it 'trueを返す' do + r = @scroll.resource_reader_role_check([@author]) + r.should be_true + end + end + context 'ロールリストに絵師が含まれるとき' do + it 'trueを返す' do + r = @scroll.resource_reader_role_check([@artist]) + r.should be_true + end + end + context 'ロールリストにユーザが含まれるとき' do + it 'trueを返す' do + r = @scroll.resource_reader_role_check([@user]) + r.should be_true + end + end + context 'ロールリストに管理者が含まれるとき' do + it 'trueを返す' do + r = @scroll.resource_reader_role_check([@admin]) + r.should be_true + end + end + context 'ロールリストに借手が含まれるとき' do + it 'trueを返す' do + r = @scroll.resource_reader_role_check([@demand_user]) + r.should be_true + end + end + context 'ロールリストにユーザ、管理者、作家、絵師、借手が含まれないとき' do + it 'falseを返す' do + r = @scroll.resource_reader_role_check([nil]) + r.should be_false + end + end + end + + describe '閲覧許可に於いて' do + before do + @scroll = FactoryGirl.build :scroll, :author_id => @author.id + end + context 'オープンモードのとき' do + before do + MagicNumber['run_mode'] = 0 + end + it '自身にゲスト用ロールチェックを問い合わせしている' do + Scroll.any_instance.stub(:guest_role_check).and_return(true) + Scroll.any_instance.should_receive(:guest_role_check).with(any_args).exactly(1) + r = @scroll.visible?([@author]) + end + it 'ゲスト用ロールチェックが失敗したとき、falseを返す' do + Scroll.any_instance.stub(:guest_role_check).and_return(false) + r = @scroll.visible?([@author]) + r.should be_false + end + end + context 'クローズドモードのとき' do + before do + MagicNumber['run_mode'] = 1 + end + it '自身に読者用ロールチェックを問い合わせしている' do + Scroll.any_instance.stub(:reader_role_check).and_return(true) + Scroll.any_instance.should_receive(:reader_role_check).with(any_args).exactly(1) + r = @scroll.visible?([@author]) + end + it '読者用ロールチェックが失敗したとき、falseを返す' do + Scroll.any_instance.stub(:reader_role_check).and_return(false) + r = @scroll.visible?([@author]) + r.should be_false + end + end + context '事前チェックする' do + before do + MagicNumber['run_mode'] = 1 + Scroll.any_instance.stub(:reader_role_check).and_return(true) + Scroll.any_instance.stub(:own?).and_return(true) + end + it '自身に所持判定を問い合わせしている' do + Scroll.any_instance.should_receive(:own?).with(any_args).exactly(1) + r = @scroll.visible?([@author]) + end + end + context 'つつがなく終わるとき' do + before do + MagicNumber['run_mode'] = 1 + Scroll.any_instance.stub(:reader_role_check).and_return(true) + end + it '自分のコミックなら許可する' do + Scroll.any_instance.stub(:own?).and_return(true) + Scroll.any_instance.stub(:visible).and_return(0) + r = @scroll.visible?([@author]) + r.should be_true + end + it '他人の非公開コミックなら許可しない' do + Scroll.any_instance.stub(:own?).and_return(false) + Scroll.any_instance.stub(:visible).and_return(0) + r = @scroll.visible?([@author]) + r.should be_false + end + it '他人のコミックでも公開なら許可する' do + Scroll.any_instance.stub(:own?).and_return(false) + Scroll.any_instance.stub(:visible).and_return(1) + r = @scroll.visible?([@author]) + r.should be_true + end + end + end + + describe '一覧取得に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @author.id + end + context 'page補正について' do + it '文字列から数値に変換される' do + Scroll.page('8').should eq 8 + end + it 'nilの場合は1になる' do + Scroll.page().should eq 1 + end + it '0以下の場合は1になる' do + Scroll.page('0').should eq 1 + end + end + context 'page_size補正について' do + it '文字列から数値に変換される' do + Scroll.page_size('7').should eq 7 + end + it 'nilの場合はScroll.default_page_sizeになる' do + Scroll.page_size().should eq Scroll.default_page_size + end + it '0以下の場合はScroll.default_page_sizeになる' do + Scroll.page_size('0').should eq Scroll.default_page_size + end + it 'Scroll.max_page_sizeを超えた場合はScroll.max_page_sizeになる' do + Scroll.page_size('1000').should eq Scroll.max_page_size + end + end + context 'つつがなく終わるとき' do + it '一覧取得オプションを利用している' do + Scroll.stub(:list_opt).with(any_args).and_return({}) + Scroll.should_receive(:list_opt).with(any_args).exactly(1) + r = Scroll.list + end + end + it 'リストを返す' do + c = Scroll.list + c.should eq [@scroll] + end + it '非公開コミックは(自分のコミックであっても)含んでいない' do + FactoryGirl.create :scroll, :author_id => @author.id, :visible => 0 + c = Scroll.list + c.should eq [@scroll] + end + it '時系列で並んでいる' do + #公開コミックは(他人のコミックであっても)含んでいる + v = FactoryGirl.create :scroll, :author_id => @other_author.id, :updated_at => Time.now + 100 + c = Scroll.list + c.should eq [v, @scroll] + end + context 'DBに5件あって1ページの件数を2件に変えたとして' do + before do + @scroll2 = FactoryGirl.create :scroll, :author_id => @author.id, :updated_at => Time.now + 100 + @scroll3 = FactoryGirl.create :scroll, :author_id => @author.id, :updated_at => Time.now + 200 + @scroll4 = FactoryGirl.create :scroll, :author_id => @author.id, :updated_at => Time.now + 300 + @scroll5 = FactoryGirl.create :scroll, :author_id => @author.id, :updated_at => Time.now + 400 + Scroll.stub(:default_page_size).and_return(2) + end + it '通常は2件を返す' do + c = Scroll.list + c.should have(2).items + end + it 'page=1なら末尾2件を返す' do + #時系列で並んでいる + c = Scroll.list(1) + c.should eq [@scroll5, @scroll4] + end + it 'page=2なら中間2件を返す' do + c = Scroll.list(2) + c.should eq [@scroll3, @scroll2] + end + it 'page=3なら先頭1件を返す' do + c = Scroll.list(3) + c.should eq [@scroll] + end + end + end + + describe '自分のコミック一覧取得に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @author.id + end + context 'つつがなく終わるとき' do + it '一覧取得オプションを利用している' do + Scroll.stub(:list_opt).with(any_args).and_return({}) + Scroll.should_receive(:list_opt).with(any_args).exactly(1) + r = Scroll.mylist @author + end + end + it 'リストを返す' do + c = Scroll.mylist @author + c.should eq [@scroll] + end + it '時系列で並んでいる' do + nc = FactoryGirl.create :scroll, :author_id => @author.id, :updated_at => Time.now + 100 + cl = Scroll.mylist @author + cl.should eq [nc, @scroll] + end + it '他人のコミックは公開でも含まない' do + nc = FactoryGirl.create :scroll, :author_id => @other_author.id, :visible => 1 + cl = Scroll.mylist @author + cl.should eq [@scroll] + end + it '自分のコミックは非公開でも含んでいる' do + nc = FactoryGirl.create :scroll, :author_id => @author.id, :visible => 0, :updated_at => Time.now + 100 + cl = Scroll.mylist @author + cl.should eq [nc, @scroll] + end + context 'DBに5件あって1ページの件数を2件に変えたとして' do + before do + @scroll2 = FactoryGirl.create :scroll, :author_id => @author.id, :updated_at => Time.now + 100 + @scroll3 = FactoryGirl.create :scroll, :author_id => @author.id, :updated_at => Time.now + 200 + @scroll4 = FactoryGirl.create :scroll, :author_id => @author.id, :updated_at => Time.now + 300 + @scroll5 = FactoryGirl.create :scroll, :author_id => @author.id, :updated_at => Time.now + 400 + end + it '通常は2件を返す' do + c = Scroll.mylist @author, 1, 2 + c.should have(2).items + end + it 'page=1なら末尾2件を返す' do + #時系列で並んでいる + c = Scroll.mylist(@author, 1, 2) + c.should eq [@scroll5, @scroll4] + end + it 'page=2なら中間2件を返す' do + c = Scroll.mylist(@author, 2, 2) + c.should eq [@scroll3, @scroll2] + end + it 'page=3なら先頭1件を返す' do + c = Scroll.mylist(@author, 3, 2) + c.should eq [@scroll] + end + end + end + + describe '他作家のコミック一覧取得に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @author.id + @other_scroll = FactoryGirl.create :scroll, :author_id => @other_author.id, :visible => 1 + end + context 'つつがなく終わるとき' do + it '一覧取得オプションを利用している' do + Scroll.stub(:list_opt).with(any_args).and_return({}) + Scroll.should_receive(:list_opt).with(any_args).exactly(1) + r = Scroll.himlist @other_author + end + end + it '指定した作家のリストを返す' do + r = Scroll.himlist @other_author + r.should eq [@other_scroll] + end + it '時系列で並んでいる' do + nc = FactoryGirl.create :scroll, :author_id => @other_author.id, :updated_at => Time.now + 100 + r = Scroll.himlist @other_author + r.should eq [nc, @other_scroll] + end + it '公開コミックに限る ' do + hidden = FactoryGirl.create :scroll, :author_id => @other_author.id, :visible => 0 + r = Scroll.himlist @other_author + r.should eq [@other_scroll] + end + context 'DBに5件あって1ページの件数を2件に変えたとして' do + before do + @other_scroll2 = FactoryGirl.create :scroll, :author_id => @other_author.id, :updated_at => Time.now + 100 + @other_scroll3 = FactoryGirl.create :scroll, :author_id => @other_author.id, :updated_at => Time.now + 200 + @other_scroll4 = FactoryGirl.create :scroll, :author_id => @other_author.id, :updated_at => Time.now + 300 + @other_scroll5 = FactoryGirl.create :scroll, :author_id => @other_author.id, :updated_at => Time.now + 400 + end + it '通常は2件を返す' do + c = Scroll.himlist @other_author, 1, 2 + c.should have(2).items + end + it 'page=1なら末尾2件を返す' do + #時系列で並んでいる + c = Scroll.himlist(@other_author, 1, 2) + c.should eq [@other_scroll5, @other_scroll4] + end + it 'page=2なら中間2件を返す' do + c = Scroll.himlist(@other_author, 2, 2) + c.should eq [@other_scroll3, @other_scroll2] + end + it 'page=3なら先頭1件を返す' do + c = Scroll.himlist(@other_author, 3, 2) + c.should eq [@other_scroll] + end + end + end + + describe 'コミック一覧ページ制御に於いて' do + before do + Scroll.stub(:count).with(any_args).and_return(100) + end + it 'ページ制御を返す' do + r = Scroll.list_paginate + r.is_a?(Kaminari::PaginatableArray).should be_true + end + it 'コミック一覧の取得条件を利用している' do + Scroll.stub(:list_where).with(any_args).and_return('') + Scroll.should_receive(:list_where).with(any_args).exactly(1) + r = Scroll.list_paginate + end + it 'ページ件数10のとき、3ページ目のオフセットは20から始まる' do + r = Scroll.list_paginate 3, 10 + r.limit_value.should eq 10 + r.offset_value.should eq 20 + end + end + + describe '自分のコミック一覧ページ制御に於いて' do + before do + Scroll.stub(:count).with(any_args).and_return(100) + end + it 'ページ制御を返す' do + r = Scroll.mylist_paginate @author + r.is_a?(Kaminari::PaginatableArray).should be_true + end + it '自分のコミック一覧の取得条件を利用している' do + Scroll.stub(:mylist_where).with(any_args).and_return('') + Scroll.should_receive(:mylist_where).with(any_args).exactly(1) + r = Scroll.mylist_paginate @author + end + it 'ページ件数10のとき、3ページ目のオフセットは20から始まる' do + r = Scroll.mylist_paginate @author, 3, 10 + r.limit_value.should eq 10 + r.offset_value.should eq 20 + end + end + + describe '他作家のコミック一覧ページ制御に於いて' do + before do + Scroll.stub(:count).with(any_args).and_return(100) + end + it 'ページ制御を返す' do + r = Scroll.himlist_paginate @other_author + r.is_a?(Kaminari::PaginatableArray).should be_true + end + it '他作家のコミック一覧の取得条件を利用している' do + Scroll.stub(:himlist_where).with(any_args).and_return('') + Scroll.should_receive(:himlist_where).with(any_args).exactly(1) + r = Scroll.himlist_paginate @other_author + end + it 'ページ件数10のとき、3ページ目のオフセットは20から始まる' do + r = Scroll.himlist_paginate @other_author, 3, 10 + r.limit_value.should eq 10 + r.offset_value.should eq 20 + end + end + + describe '一覧取得オプションに於いて' do + it '2つの項目を含んでいる' do + r = Scroll.list_opt + r.should have(2).items + end + it 'ストーリーを含んでいる' do + r = Scroll.list_opt + r.has_key?(:scroll_panels).should be_true + end + it 'ストーリーはコマを含んでいる' do + r = Scroll.list_opt + r[:scroll_panels].has_key?(:panel).should be_true + end + it '作家を含んでいる' do + r = Scroll.list_opt + r.has_key?(:author).should be_true + end + end + describe 'json一覧出力オプションに於いて' do + before do + @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 + @scroll = FactoryGirl.create :scroll, :author_id => @author.id, :visible => 1 + @panel = FactoryGirl.create :panel, :author_id => @author.id, :publish => 1 + @scroll_panel = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id + end + it 'ストーリーを含んでいる' do + r = Scroll.list.to_json Scroll.list_json_opt + j = JSON.parse r + i = j.first + i.has_key?('scroll_panels').should be_true + end + it 'ストーリーはコマを含んでいる' do + r = Scroll.list.to_json Scroll.list_json_opt + j = JSON.parse r + i = j.first + s = i['scroll_panels'].first + s.has_key?('panel').should be_true + end + it '作家を含んでいる' do + r = Scroll.list.to_json Scroll.list_json_opt + j = JSON.parse r + i = j.first + i.has_key?('author').should be_true + end + end + + describe '単体取得に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @author.id + end + context 'つつがなく終わるとき' do + it '単体取得オプションを利用している' do + Scroll.stub(:show_opt).with(any_args).and_return({}) + Scroll.should_receive(:show_opt).with(any_args).exactly(1) + r = Scroll.show @scroll.id, @author + end + it '閲覧許可を問い合わせている' do + Scroll.any_instance.stub(:visible?).with(any_args).and_return(true) + Scroll.any_instance.should_receive(:visible?).with(any_args).exactly(1) + r = Scroll.show @scroll.id, @author + end + end + it '指定のコミックを返す' do + c = Scroll.show @scroll.id, @author + c.should eq @scroll + end + context '閲覧許可が出なかったとき' do + it '403Forbidden例外を返す' do + Scroll.any_instance.stub(:visible?).and_return(false) + lambda{ + Scroll.show @scroll.id, @author + }.should raise_error(ActiveRecord::Forbidden) + end + end + context '存在しないコミックを開こうとしたとき' do + it '404RecordNotFound例外を返す' do + lambda{ + Scroll.show 110, @author + }.should raise_error(ActiveRecord::RecordNotFound) + end + end + end + + describe '編集取得に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @author.id + end + context 'つつがなく終わるとき' do + it '単体取得オプションを利用している' do + Scroll.stub(:show_opt).with(any_args).and_return({}) + Scroll.should_receive(:show_opt).with(any_args).exactly(1) + r = Scroll.edit @scroll.id, @author + end + it '所持判定を問い合わせている' do + Scroll.any_instance.stub(:own?).with(any_args).and_return(true) + Scroll.any_instance.should_receive(:own?).with(any_args).exactly(1) + r = Scroll.edit @scroll.id, @author + end + end + it '指定のコミックを返す' do + Scroll.any_instance.stub(:own?).and_return(true) + c = Scroll.edit @scroll.id, @author.id + c.should eq @scroll + end + context '他人のコミックを開こうとしたとき' do + it '403Forbidden例外を返す' do + Scroll.any_instance.stub(:own?).and_return(false) + lambda{ + Scroll.edit @scroll.id, @author + }.should raise_error(ActiveRecord::Forbidden) + end + end + context '存在しないコミックを開こうとしたとき' do + it '404RecordNotFound例外を返す' do + lambda{ + Scroll.edit 110, @author + }.should raise_error(ActiveRecord::RecordNotFound) + end + end + end + describe '単体取得オプションに於いて' do + it 'includeキーを含んでいる' do + r = Scroll.show_opt + r.has_key?(:include).should be_true + end + it '2つの項目を含んでいる' do + r = Scroll.show_opt[:include] + r.should have(2).items + end + it '作家を含んでいる' do + r = Scroll.show_opt[:include] + r.has_key?(:author).should be_true + end + it 'ストーリーを含んでいる' do + r = Scroll.show_opt[:include] + r.has_key?(:scroll_panels).should be_true + end + it 'ストーリーはコマを含んでいる' do + r = Scroll.show_opt[:include] + r[:scroll_panels].has_key?(:panel).should be_true + end + end + describe 'json単体出力オプションに於いて' do + before do + @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 + @scroll = FactoryGirl.create :scroll, :author_id => @author.id, :visible => 1 + @panel = FactoryGirl.create :panel, :author_id => @author.id, :publish => 1 + @scroll_panel = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id + end + it 'ストーリーを含んでいる' do + r = Scroll.show(@scroll.id, @author).to_json Scroll.show_json_opt + j = JSON.parse r + i = j + i.has_key?('scroll_panels').should be_true + end + it 'ストーリーはコマを含んでいる' do + r = Scroll.show(@scroll.id, @author).to_json Scroll.show_json_opt + j = JSON.parse r + i = j + s = i['scroll_panels'].first + s.has_key?('panel').should be_true + end + it '作家を含んでいる' do + r = Scroll.show(@scroll.id, @author).to_json Scroll.show_json_opt + j = JSON.parse r + i = j + i.has_key?('author').should be_true + end + end + + describe '削除に於いて' do + before do + @scroll = FactoryGirl.create :scroll, :author_id => @author.id + @panel = FactoryGirl.create :panel, :author_id => @author.id, :publish => 1 + @scroll_panel = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @scroll.id, :panel_id => @panel.id + @other_scroll = FactoryGirl.create :scroll, :author_id => @author.id + @other_scroll_panel = FactoryGirl.create :scroll_panel, :author_id => @author.id, :scroll_id => @other_scroll.id, :panel_id => @panel.id + end + context 'つつがなく終わるとき' do + it '自身を削除する' do + lambda { + r = @scroll.destroy_with_scroll_panel + }.should change(Scroll, :count).by(-1) + lambda { + r = Scroll.find @scroll.id + }.should raise_error + end + it '自身にリンクしているストーリーをすべて削除する' do + lambda { + r = @scroll.destroy_with_scroll_panel + }.should change(ScrollPanel, :count).by(-1) + lambda { + r = ScrollPanel.find @scroll_panel.id + }.should raise_error + end + it 'Trueを返す' do + r = @scroll.destroy_with_scroll_panel + r.should be_true + end + end + context '削除に失敗したとき' do + before do + ScrollPanel.any_instance.stub(:destroy).with(any_args).and_return(false) + end + it 'Falseを返す' do + r = @scroll.destroy_with_scroll_panel + r.should be_false + end + it 'ロールバックしている' do + lambda { + r = @scroll.destroy_with_scroll_panel + }.should_not change(Scroll, :count) + lambda { + r = @scroll.destroy_with_scroll_panel + }.should_not change(ScrollPanel, :count) + end + end + end +end