From 9618822ebe6f87ffde3376b0ab88c0be36880659 Mon Sep 17 00:00:00 2001 From: yasushiito Date: Mon, 24 Dec 2012 09:49:38 +0900 Subject: [PATCH] t30350#:fix destroy --- app/controllers/comics_controller.rb | 26 ++--- app/controllers/panels_controller.rb | 12 ++- app/controllers/resource_pictures_controller.rb | 2 +- app/controllers/stories_controller.rb | 14 ++- app/models/author.rb | 2 + app/models/comic.rb | 12 +++ app/models/panel.rb | 12 +++ app/models/resource_picture.rb | 17 +++- app/models/story.rb | 3 + app/models/user.rb | 16 ++++ app/views/home/comic.html.erb | 1 + app/views/home/panel.html.erb | 1 + app/views/stories/show.html.erb | 1 + config/routes.rb | 1 + spec/controllers/comics_controller_spec.rb | 103 ++++++++++++++++++++ spec/controllers/panels_controller_spec.rb | 31 +++++- .../resource_pictures_controller_spec.rb | 105 +++++++++++++++++++++ spec/controllers/stories_controller_spec.rb | 47 +++++++-- spec/models/comic_spec.rb | 49 ++++++++++ spec/models/panel_spec.rb | 67 +++++++++++++ spec/models/resource_picture_spec.rb | 85 +++++++++++++++++ spec/models/story_spec.rb | 18 ++++ 22 files changed, 584 insertions(+), 41 deletions(-) diff --git a/app/controllers/comics_controller.rb b/app/controllers/comics_controller.rb index b68a5780..d57a0842 100644 --- a/app/controllers/comics_controller.rb +++ b/app/controllers/comics_controller.rb @@ -15,8 +15,6 @@ class ComicsController < ApplicationController end end - # GET /comics - # GET /comics.json def index @page = Comic.page params[:page] @page_size = Comic.page_size params[:page_size] @@ -27,8 +25,6 @@ class ComicsController < ApplicationController end end - # GET /comics/1 - # GET /comics/1.json def show @comic = Comic.show(params[:id], @author) @@ -63,8 +59,6 @@ class ComicsController < ApplicationController end end - # GET /comics/new - # GET /comics/new.js def new @comic = Comic.new @comic.supply_default @@ -75,8 +69,6 @@ class ComicsController < ApplicationController end end - # GET /comics/1/edit - # GET /comics/1.js/edit def edit @comic = Comic.edit(params[:id], @author) respond_to do |format| @@ -85,8 +77,6 @@ class ComicsController < ApplicationController end end - # POST /comics - # POST /comics.json def create @comic = Comic.new @comic.supply_default @@ -105,8 +95,6 @@ class ComicsController < ApplicationController end end - # PUT /comics/1 - # PUT /comics/1.json def update @comic = Comic.edit(params[:id], @author) @comic.attributes = params[:comic] @@ -123,14 +111,18 @@ class ComicsController < ApplicationController end end - # DELETE /comics/1 - # DELETE /comics/1.json def destroy @comic = Comic.edit(params[:id], @author) - @comic.destroy respond_to do |format| - format.html { redirect_to comics_url } - format.json { head :ok } + if @comic.destroy_with_story + flash[:notice] = I18n.t('flash.notice.destroyed', :model => Comic.model_name.human) + format.html { redirect_to '/home/comic' } + format.json { head :ok } + else + flash[:notice] = I18n.t('flash.notice.not_destroyed', :model => Comic.model_name.human) + format.html { redirect_to @comic } + format.json { render json: @comic.errors, status: :unprocessable_entity } + end end end end diff --git a/app/controllers/panels_controller.rb b/app/controllers/panels_controller.rb index c2bc788e..7d5e4e60 100644 --- a/app/controllers/panels_controller.rb +++ b/app/controllers/panels_controller.rb @@ -115,9 +115,15 @@ class PanelsController < ApplicationController @panel = Panel.edit(params[:id], @author) respond_to do |format| Panel.transaction do - @panel.destroy - format.html { redirect_to panels_url } - format.json { head :ok } + if @panel.destroy_with_elements + flash[:notice] = I18n.t('flash.notice.destroyed', :model => Panel.model_name.human) + format.html { redirect_to '/home/panel' } + format.json { head :ok } + else + flash[:notice] = I18n.t('flash.notice.not_destroyed', :model => Panel.model_name.human) + format.html { redirect_to @panel } + format.json { render json: @panel.errors, status: :unprocessable_entity } + end end end end diff --git a/app/controllers/resource_pictures_controller.rb b/app/controllers/resource_pictures_controller.rb index 87ce3c72..3fd04cb7 100644 --- a/app/controllers/resource_pictures_controller.rb +++ b/app/controllers/resource_pictures_controller.rb @@ -95,7 +95,7 @@ class ResourcePicturesController < ApplicationController format.html { redirect_to resource_pictures_path } format.json { head :ok } else - format.html { render resource_picture_path(@resource_picture) } + format.html { redirect_to resource_picture_path(@resource_picture) } format.json { render json: @resource_picture.errors, status: :unprocessable_entity } end end diff --git a/app/controllers/stories_controller.rb b/app/controllers/stories_controller.rb index e13a7d33..3832ea59 100644 --- a/app/controllers/stories_controller.rb +++ b/app/controllers/stories_controller.rb @@ -119,12 +119,16 @@ class StoriesController < ApplicationController def destroy @story = Story.edit(params[:id], @author) - Story.transaction do - @story.destroy_and_shorten - end respond_to do |format| - format.html { redirect_to story_path(@story.comic) } - format.json { head :ok } + if @story.destroy_and_shorten + flash[:notice] = I18n.t('flash.notice.destroyed', :model => Story.model_name.human) + format.html { redirect_to :controller => 'stories', :action => :comic, :id => @story.comic_id } + format.json { head :ok } + else + flash[:notice] = I18n.t('flash.notice.not_destroyed', :model => Story.model_name.human) + format.html { redirect_to story_path(@story) } + format.json { render json: @story.errors, status: :unprocessable_entity } + end end end end diff --git a/app/models/author.rb b/app/models/author.rb index 83db8dc6..d574bae9 100644 --- a/app/models/author.rb +++ b/app/models/author.rb @@ -1,6 +1,8 @@ class Author < ActiveRecord::Base has_one :artist belongs_to :user + has_many :comic + has_many :panel validates :name, :presence => true, :length => {:maximum => 30} validates :user_id, :numericality => true, :existence => {:both => false} diff --git a/app/models/comic.rb b/app/models/comic.rb index f32b0bd2..e9b12982 100644 --- a/app/models/comic.rb +++ b/app/models/comic.rb @@ -112,4 +112,16 @@ class Comic < ActiveRecord::Base Comic.count 'visible > 0' end + def destroy_with_story + res = false + Comic.transaction do + self.stories.each do |story| + raise ActiveRecord::Rollback unless story.destroy + end + raise ActiveRecord::Rollback unless self.destroy + res = true + end + res + end + end diff --git a/app/models/panel.rb b/app/models/panel.rb index 3e7e93ca..1d87d741 100644 --- a/app/models/panel.rb +++ b/app/models/panel.rb @@ -266,6 +266,18 @@ class Panel < ActiveRecord::Base res end + def destroy_with_elements + res = false + Panel.transaction do + self.panel_elements.each do |element| + raise ActiveRecord::Rollback unless element.destroy + end + raise ActiveRecord::Rollback unless self.destroy + res = true + end + res + end + =begin def self.validate_id ary, pid ary.map {|v| diff --git a/app/models/resource_picture.rb b/app/models/resource_picture.rb index c8bd3f7d..757140a3 100644 --- a/app/models/resource_picture.rb +++ b/app/models/resource_picture.rb @@ -205,13 +205,20 @@ class ResourcePicture < ActiveRecord::Base end def unpublish - r = true + res = false ResourcePicture.transaction do - self.destroy - PictureIO.resource_picture_io.delete(self.filename) - PictureIO.resource_picture_io.delete(self.filename, 'full') + begin + if res = self.destroy + PictureIO.resource_picture_io.delete(self.filename) + PictureIO.resource_picture_io.delete(self.filename, 'full') + res = true + end + rescue PictureIO::Error + res = false + raise ActiveRecord::Rollback + end end - r + res end def self.visible_count diff --git a/app/models/story.rb b/app/models/story.rb index d67ac9d5..b4c609c0 100644 --- a/app/models/story.rb +++ b/app/models/story.rb @@ -280,10 +280,13 @@ class Story < ActiveRecord::Base end def destroy_and_shorten + res = false Story.transaction do Story.update_all('t = t - 1', ['comic_id = ? and (t > ?)', self.comic_id, self.t]) raise ActiveRecord::Rollback unless self.destroy + res = true end + res end diff --git a/app/models/user.rb b/app/models/user.rb index 90958af6..54ee43dd 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -19,4 +19,20 @@ class User < ActiveRecord::Base self.save end + def destroy + res = false + User.transaction do + self.author.comics.each do |comic| + raise ActiveRecord::Rollback unless comic.destroy_with_story + end + self.author.panels.each do |panel| + raise ActiveRecord::Rollback unless panel.destroy_with_elements + end + raise ActiveRecord::Rollback unless self.author.destroy + raise ActiveRecord::Rollback unless self.destroy + res = true + end + res + end + end diff --git a/app/views/home/comic.html.erb b/app/views/home/comic.html.erb index 3f90c929..c304a54d 100644 --- a/app/views/home/comic.html.erb +++ b/app/views/home/comic.html.erb @@ -1,4 +1,5 @@

<%= t '.title' -%>

+

<%= notice %>

<% @comics.each do |comic| %> diff --git a/app/views/home/panel.html.erb b/app/views/home/panel.html.erb index fb572ad9..e95104b8 100644 --- a/app/views/home/panel.html.erb +++ b/app/views/home/panel.html.erb @@ -1,4 +1,5 @@

<%= t '.title' -%>

+

<%= notice %>

<% @panels.each do |panel| %>
diff --git a/app/views/stories/show.html.erb b/app/views/stories/show.html.erb index 871fd958..fa0c3a0b 100644 --- a/app/views/stories/show.html.erb +++ b/app/views/stories/show.html.erb @@ -34,6 +34,7 @@

<% if @story.own? @author -%> <%= link_to t('link.edit'), edit_story_path(@story) %> + <%= link_to t('link.destroy'), story_path(@story), :method => :delete %> <% end %>
diff --git a/config/routes.rb b/config/routes.rb index 48a716ed..e5c5ca42 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -211,6 +211,7 @@ Pettanr::Application.routes.draw do get :list end member do + get :comic put :update delete :destroy get :browse diff --git a/spec/controllers/comics_controller_spec.rb b/spec/controllers/comics_controller_spec.rb index 9efd0e0e..80fd23e9 100644 --- a/spec/controllers/comics_controller_spec.rb +++ b/spec/controllers/comics_controller_spec.rb @@ -601,5 +601,108 @@ describe ComicsController do end end + describe '削除に於いて' do + before do + @comic = FactoryGirl.create :comic, :author => @author + sign_in @user + end + context '事前チェックしておく' do + before do + Comic.stub(:edit).with(any_args()).and_return @comic + Comic.any_instance.stub(:destroy_with_story).with(any_args()).and_return(true) + end + it 'コミックモデルに編集取得を問い合わせている' do + Comic.should_receive(:edit).exactly(1) + delete :destroy, :id => @comic.id + end + it 'モデルに削除を依頼する' do + Comic.any_instance.should_receive(:destroy_with_story).exactly(1) + delete :destroy, :id => @comic.id + end + it '@comicにアレを取得している' do + delete :destroy, :id => @comic.id + assigns(:comic).id.should eq(@comic.id) + end + end + context 'つつがなく終わるとき' do + it '削除される' do + lambda { + delete :destroy, :id => @comic.id + }.should change Comic, :count + end + context 'html形式' do + before do + Comic.any_instance.stub(:destroy_with_story).with(any_args()).and_return(true) + end + it 'ステータスコード302 Foundを返す' do + delete :destroy, :id => @comic.id + response.status.should eq 302 + end + it 'マイコミックの一覧ページへ遷移する' do + delete :destroy, :id => @comic.id + response.should redirect_to('/home/comic') + end + end + context 'json形式' do + before do + Comic.any_instance.stub(:destroy_with_story).with(any_args()).and_return(true) + end + it 'ステータスコード200 OKを返す' do + delete :destroy, :id => @comic.id, :format => :json + response.should be_success + end + it 'ページ本体は特に返さない' do + delete :destroy, :id => @comic.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 => @comic.id + response.status.should eq 302 + end + context 'html形式' do + it 'サインインページへ遷移する' do + delete :destroy, :id => @comic.id + response.body.should redirect_to '/users/sign_in' + end + end + context 'json形式' do + it '応答メッセージにUnauthorizedを返す' do + delete :destroy, :id => @comic.id, :format => :json + response.message.should match(/Unauthorized/) + end + end + end + context '削除に失敗したとき' do + before do + Comic.any_instance.stub(:destroy_with_story).and_return(false) + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + delete :destroy, :id => @comic.id + response.status.should eq 302 + end + it 'そのコミックの詳細ページへ遷移する' do + delete :destroy, :id => @comic.id + response.should redirect_to(comic_path(@comic)) + end + end + context 'json形式' do + it 'ステータスコード422 unprocessable_entity を返す' do + delete :destroy, :id => @comic.id, :format => :json + response.status.should eq 422 + end + it '応答メッセージUnprocessable Entityを返す' do + delete :destroy, :id => @comic.id, :format => :json + response.message.should match(/Unprocessable/) + end + end + end + end end diff --git a/spec/controllers/panels_controller_spec.rb b/spec/controllers/panels_controller_spec.rb index f9bfacdd..a75ad3f4 100644 --- a/spec/controllers/panels_controller_spec.rb +++ b/spec/controllers/panels_controller_spec.rb @@ -646,7 +646,7 @@ describe PanelsController do delete :destroy, :id => @panel.id assigns(:panel).id.should eq(@panel.id) end - it 'そのコマを一つのトランザクションで削除する' do + it 'そのコマを削除する' do lambda { delete :destroy, :id => @panel.id }.should change(Panel, :count) @@ -656,9 +656,9 @@ describe PanelsController do delete :destroy, :id => @panel.id response.status.should eq 302 end - it 'コマ一覧ページへ遷移する' do + it 'マイコマ一覧ページへ遷移する' do delete :destroy, :id => @panel.id - response.should redirect_to(panels_url) + response.should redirect_to('/home/panel') end end context 'json形式' do @@ -693,6 +693,31 @@ describe PanelsController do end end end + context '削除に失敗したとき' do + before do + Panel.any_instance.stub(:destroy_with_elements).and_return(false) + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + delete :destroy, :id => @panel.id + response.status.should eq 302 + end + it 'そのコマの詳細ページへ遷移する' do + delete :destroy, :id => @panel.id + response.should redirect_to(panel_path(@panel)) + end + end + context 'json形式' do + it 'ステータスコード422 unprocessable_entity を返す' do + delete :destroy, :id => @panel.id, :format => :json + response.status.should eq 422 + end + it '応答メッセージUnprocessable Entityを返す' do + delete :destroy, :id => @panel.id, :format => :json + response.message.should match(/Unprocessable/) + end + end + end =begin context '対象コマがないとき' do end diff --git a/spec/controllers/resource_pictures_controller_spec.rb b/spec/controllers/resource_pictures_controller_spec.rb index 86ce8a10..09a0e257 100644 --- a/spec/controllers/resource_pictures_controller_spec.rb +++ b/spec/controllers/resource_pictures_controller_spec.rb @@ -874,4 +874,109 @@ describe ResourcePicturesController do end end + describe '削除に於いて' do + before do + @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 + sign_in @user + end + context '事前チェックしておく' do + before do + ResourcePicture.stub(:edit).with(any_args()).and_return @rp + ResourcePicture.any_instance.stub(:unpublish).with(any_args()).and_return(true) + end + it '素材モデルに編集取得を問い合わせている' do + ResourcePicture.should_receive(:edit).exactly(1) + delete :destroy, :id => @rp.id + end + it 'モデルに削除を依頼する' do + ResourcePicture.any_instance.should_receive(:unpublish).exactly(1) + delete :destroy, :id => @rp.id + end + it '@resource_pictureにアレを取得している' do + delete :destroy, :id => @rp.id + assigns(:resource_picture).id.should eq(@rp.id) + end + end + context 'つつがなく終わるとき' do + it '削除される' do + lambda { + delete :destroy, :id => @rp.id + }.should change ResourcePicture, :count + end + context 'html形式' do + before do + ResourcePicture.any_instance.stub(:unpublish).with(any_args()).and_return(true) + end + it 'ステータスコード302 Foundを返す' do + delete :destroy, :id => @rp.id + response.status.should eq 302 + end + it 'マイ素材の一覧ページへ遷移する' do + delete :destroy, :id => @rp.id + response.should redirect_to('/home/resource_picture') + end + end + context 'json形式' do + before do + ResourcePicture.any_instance.stub(:unpublish).with(any_args()).and_return(true) + end + it 'ステータスコード200 OKを返す' do + delete :destroy, :id => @rp.id, :format => :json + response.should be_success + end + it 'ページ本体は特に返さない' do + delete :destroy, :id => @rp.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 => @rp.id + response.status.should eq 302 + end + context 'html形式' do + it 'サインインページへ遷移する' do + delete :destroy, :id => @rp.id + response.body.should redirect_to '/users/sign_in' + end + end + context 'json形式' do + it '応答メッセージにUnauthorizedを返す' do + delete :destroy, :id => @rp.id, :format => :json + response.message.should match(/Unauthorized/) + end + end + end + context '削除に失敗したとき' do + before do + ResourcePicture.any_instance.stub(:unpublish).and_return(false) + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + delete :destroy, :id => @rp.id + response.status.should eq 302 + end + it 'その素材の詳細ページへ遷移する' do + delete :destroy, :id => @rp.id + response.should redirect_to(resource_picture_path(@rp)) + end + end + context 'json形式' do + it 'ステータスコード422 unprocessable_entity を返す' do + delete :destroy, :id => @rp.id, :format => :json + response.status.should eq 422 + end + it '応答メッセージUnprocessable Entityを返す' do + delete :destroy, :id => @rp.id, :format => :json + response.message.should match(/Unprocessable/) + end + end + end + end + end diff --git a/spec/controllers/stories_controller_spec.rb b/spec/controllers/stories_controller_spec.rb index 2b325edd..974e0f90 100644 --- a/spec/controllers/stories_controller_spec.rb +++ b/spec/controllers/stories_controller_spec.rb @@ -685,28 +685,36 @@ describe StoriesController do sign_in @user Story.stub(:edit).and_return(@story) end - context 'つつがなく終わるとき' do + context '事前チェックしておく' do + before do + Story.stub(:edit).with(any_args()).and_return @story + Story.any_instance.stub(:destroy_and_shorten).with(any_args()).and_return(true) + end it 'ストーリーモデルに編集取得を問い合わせている' do Story.should_receive(:edit).exactly(1) delete :destroy, :id => @story.id end + it 'モデルに削除を依頼する' do + Story.any_instance.should_receive(:destroy_and_shorten).exactly(1) + delete :destroy, :id => @story.id + end it '@storyにアレを取得している' do delete :destroy, :id => @story.id assigns(:story).id.should eq(@story.id) end - it 'そのストーリーを一つのトランザクションで削除する' do - lambda { - delete :destroy, :id => @story.id - }.should change(Story, :count) + end + context 'つつがなく終わるとき' do + before do + Story.any_instance.stub(:destroy_and_shorten).with(any_args()).and_return(true) end context 'html形式' do it 'ステータスコード302 Foundを返す' do delete :destroy, :id => @story.id response.status.should eq 302 end - it 'ストーリー一覧ページへ遷移する' do + it '閲覧ページへ遷移する' do delete :destroy, :id => @story.id - response.should redirect_to(story_path(@story.comic_id)) + response.should redirect_to(:controller => 'stories', :action => :comic, :id => @story.comic_id) end end context 'json形式' do @@ -741,6 +749,31 @@ describe StoriesController do end end end + context '削除に失敗したとき' do + before do + Story.any_instance.stub(:destroy_and_shorten).with(any_args()).and_return(false) + end + context 'html形式' do + it 'ステータスコード302 Foundを返す' do + delete :destroy, :id => @story.id + response.status.should eq 302 + end + it 'そのコミックの詳細ページへ遷移する' do + delete :destroy, :id => @story.id + response.should redirect_to(story_path(@story)) + end + end + context 'json形式' do + it 'ステータスコード422 unprocessable_entity を返す' do + delete :destroy, :id => @story.id, :format => :json + response.status.should eq 422 + end + it '応答メッセージUnprocessable Entityを返す' do + delete :destroy, :id => @story.id, :format => :json + response.message.should match(/Unprocessable/) + end + end + end =begin context '対象ストーリーがないとき' do end diff --git a/spec/models/comic_spec.rb b/spec/models/comic_spec.rb index b0c740e4..78a6f7a2 100644 --- a/spec/models/comic_spec.rb +++ b/spec/models/comic_spec.rb @@ -489,4 +489,53 @@ describe Comic do i.has_key?('author').should be_true end end + + describe '削除に於いて' do + before do + @comic = FactoryGirl.create :comic, :author_id => @author.id + @panel = FactoryGirl.create :panel, :author_id => @author.id, :publish => 1 + @story = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id + @other_comic = FactoryGirl.create :comic, :author_id => @author.id + @other_story = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @other_comic.id, :panel_id => @panel.id + end + context 'つつがなく終わるとき' do + it '自身を削除する' do + lambda { + r = @comic.destroy_with_story + }.should change(Comic, :count).by(-1) + lambda { + r = Comic.find @comic.id + }.should raise_error + end + it '自身にリンクしているストーリーをすべて削除する' do + lambda { + r = @comic.destroy_with_story + }.should change(Story, :count).by(-1) + lambda { + r = Story.find @story.id + }.should raise_error + end + it 'Trueを返す' do + r = @comic.destroy_with_story + r.should be_true + end + end + context '削除に失敗したとき' do + before do + Story.any_instance.stub(:destroy).with(any_args).and_return(false) + end + it 'Falseを返す' do + r = @comic.destroy_with_story + r.should be_false + end + it 'ロールバックしている' do + lambda { + r = @comic.destroy_with_story + }.should_not change(Comic, :count) + lambda { + r = @comic.destroy_with_story + }.should_not change(Story, :count) + end + end + end end diff --git a/spec/models/panel_spec.rb b/spec/models/panel_spec.rb index ea6374ba..b319970c 100644 --- a/spec/models/panel_spec.rb +++ b/spec/models/panel_spec.rb @@ -1163,6 +1163,73 @@ describe Panel do end end end + + describe '削除に於いて' do + before do + @comic = FactoryGirl.create :comic, :author_id => @author.id + @panel = FactoryGirl.create :panel, :author_id => @author.id, :publish => 1 + @pp = FactoryGirl.create :panel_picture, :panel_id => @panel.id, :t => 1, :width => @p.width, :height => @p.height + @sb = @panel.speech_balloons.create( + FactoryGirl.attributes_for(:speech_balloon, :panel_id => @panel.id, :speech_balloon_template_id => @sbt.id, :t => 0) + ) + @gc = @panel.ground_colors.create( + FactoryGirl.attributes_for(:ground_color, :panel_id => @panel.id, :color_id => @color.id) + ) + @gp = @panel.ground_pictures.create( + FactoryGirl.attributes_for(:ground_picture, :panel_id => @panel.id, :picture_id => @p.id) + ) + @pc = @panel.panel_colors.create( + FactoryGirl.attributes_for(:panel_color, :panel_id => @panel.id, :code => 0xff0000) + ) + end + context 'つつがなく終わるとき' do + it '自身を削除する' do + lambda { + r = @panel.destroy_with_elements + }.should change(Panel, :count).by(-1) + lambda { + r = Panel.find @panel.id + }.should raise_error + end + it '自身にリンクしているコマ要素をすべて削除する' do + lambda { + r = @panel.destroy_with_elements + }.should change(PanelPicture, :count).by(-1) + lambda { + r = PanelPicture.find @pp.id + }.should raise_error + end + it '自身にリンクしているコマ要素をすべて削除する' do + lambda { + r = @panel.destroy_with_elements + }.should change(GroundPicture, :count).by(-1) + lambda { + r = GroundPicture.find @gp.id + }.should raise_error + end + it 'Trueを返す' do + r = @panel.destroy_with_elements + r.should be_true + end + end + context '削除に失敗したとき' do + before do + PanelPicture.any_instance.stub(:destroy).with(any_args).and_return(false) + end + it 'Falseを返す' do + r = @panel.destroy_with_elements + r.should be_false + end + it 'ロールバックしている' do + lambda { + r = @panel.destroy_with_elements + }.should_not change(Panel, :count) + lambda { + r = @panel.destroy_with_elements + }.should_not change(PanelPicture, :count) + end + end + end =begin describe 'id挿げ替え防止確認に於いて' do before do diff --git a/spec/models/resource_picture_spec.rb b/spec/models/resource_picture_spec.rb index f6143482..2dd12d77 100644 --- a/spec/models/resource_picture_spec.rb +++ b/spec/models/resource_picture_spec.rb @@ -968,6 +968,91 @@ describe ResourcePicture do end + describe '公開停止に於いて' 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 + end + context '事前チェックしておく' do + before do + ResourcePicture.any_instance.stub(:destroy).and_return(true) + PictureIO.resource_picture_io.stub(:delete).with(@rp.filename).and_return(true) + PictureIO.resource_picture_io.stub(:delete).with(@rp.filename, 'full').and_return(true) + end + it '素材モデルに削除を依頼している' do + ResourcePicture.any_instance.should_receive(:destroy).exactly(1) + r = @rp.unpublish + end + it '保管庫にサムネイルの画像データ削除を依頼している' do + PictureIO.resource_picture_io.should_receive(:delete).with(@rp.filename).exactly(1) + r = @rp.unpublish + end + it '保管庫にフルサイズの画像データ削除を依頼している' do + PictureIO.resource_picture_io.should_receive(:delete).with(@rp.filename, 'full').exactly(1) + r = @rp.unpublish + end + end + context 'つつがなく終わるとき' do + it '自身を削除する' do + lambda { + r = @rp.unpublish + }.should change(ResourcePicture, :count).by(-1) + lambda { + r = ResourcePicture.find @rp.id + }.should raise_error + end + it 'Trueを返す' do + r = @rp.unpublish + r.should be_true + end + end + context '自身の削除に失敗したとき' do + before do + ResourcePicture.any_instance.stub(:destroy).with(any_args).and_return(false) + end + it 'Falseを返す' do + r = @rp.unpublish + r.should be_false + end + it 'ロールバックしている' do + lambda { + r = @rp.unpublish + }.should_not change(ResourcePicture, :count) + end + end + context 'サムネイル画像の削除に失敗したとき' do + before do + PictureIO.resource_picture_io.stub(:delete).with(@rp.filename).and_raise(PictureIO::Error) + PictureIO.resource_picture_io.stub(:delete).with(@rp.filename, 'full').and_return(true) + end + it 'Falseを返す' do + r = @rp.unpublish + r.should be_false + end + it 'ロールバックしている' do + lambda { + r = @rp.unpublish + }.should_not change(ResourcePicture, :count) + end + end + context 'フルサイズ画像の削除に失敗したとき' do + before do + PictureIO.resource_picture_io.stub(:delete).with(@rp.filename).and_return(true) + PictureIO.resource_picture_io.stub(:delete).with(@rp.filename, 'full').and_raise(PictureIO::Error) + end + it 'Falseを返す' do + r = @rp.unpublish + r.should be_false + end + it 'ロールバックしている' do + lambda { + r = @rp.unpublish + }.should_not change(ResourcePicture, :count) + end + end + end + describe 'クレジットデータに於いて' do before do @op = FactoryGirl.create :original_picture, :artist_id => @artist.id diff --git a/spec/models/story_spec.rb b/spec/models/story_spec.rb index f1a16460..06a8f845 100644 --- a/spec/models/story_spec.rb +++ b/spec/models/story_spec.rb @@ -1697,6 +1697,24 @@ describe Story do @story.destroy_and_shorten }.should change(Story, :count ).by(-1) end + it 'Trueを返す' do + r = @story.destroy_and_shorten + r.should be_true + end + end + context '削除に失敗したとき' do + before do + Story.any_instance.stub(:destroy).and_return(false) + end + it 'ロールバックされる' do + lambda{ + @story.destroy_and_shorten + }.should_not change(Story, :count ) + end + it 'Falseを返す' do + r = @story.destroy_and_shorten + r.should be_false + end end #連携テスト。切り詰めが直接DBをいじる context '2件で先頭を削除したとき' do -- 2.11.0