From 46a24d50079a1961e3315d64526787eaefb452ab Mon Sep 17 00:00:00 2001 From: yasushiito Date: Fri, 6 Jul 2012 08:44:02 +0900 Subject: [PATCH] pass test: Picture.store --- app/models/license_group.rb | 2 +- app/models/picture.rb | 160 ++++++++++ app/models/resource_picture.rb | 12 - config/application.rb | 1 + config/picture_io.yml.org | 2 + db/standard_license.json | 6 +- lib/local_picture.rb | 4 - lib/picture_io.rb | 11 +- lib/test/local_picture_spec.rb | 15 - spec/factories.rb | 14 + spec/models/picture_spec.rb | 698 ++++++++++++++++++++++++++++++++++++++++- 11 files changed, 887 insertions(+), 38 deletions(-) diff --git a/app/models/license_group.rb b/app/models/license_group.rb index fa67c7b8..9ea51e5d 100644 --- a/app/models/license_group.rb +++ b/app/models/license_group.rb @@ -22,7 +22,7 @@ class LicenseGroup < ActiveRecord::Base end def self.import filename - LicenseGroup.import_file(filename) {|name, attr| LicenseGroup.store(name, attr)} + p LicenseGroup.import_file(filename) {|name, attr| LicenseGroup.store(name, attr)} end def self.list opt = {} diff --git a/app/models/picture.rb b/app/models/picture.rb index f62ecbe4..33d4bf4c 100644 --- a/app/models/picture.rb +++ b/app/models/picture.rb @@ -1,2 +1,162 @@ class Picture < ActiveRecord::Base + belongs_to :original_picture + belongs_to :license + belongs_to :artist + + validates :original_picture_id, :presence => true, :numericality => true, :existence => true + validates :revision, :presence => true, :numericality => true + validates :ext, :presence => true, :length => {:maximum => 4}, :inclusion => {:in => ['png', 'jpeg', 'gif']} + validates :width, :presence => true, :numericality => true, :natural_number => true + validates :height, :presence => true, :numericality => true, :natural_number => true + validates :filesize, :presence => true, :numericality => {:greater_than => 0, :less_than_or_equal_to => 2000000}, :natural_number => true + validates :license_id, :presence => true, :numericality => true, :existence => true + validates :artist_id, :presence => true, :numericality => true, :existence => true + validates :artist_name, :presence => true + + def dext + self.ext.downcase + end + + def filename + "#{self.id}.#{self.dext}" + end + + def mime_type + "image/#{self.dext}" + end + + def new_revision + Picture.maximum(:revision, :conditions => ['original_picture_id = ?', self.original_picture_id]).to_i + 1 + end + + def v(rimg) + rimg.flip.to_blob + end + + def h(rimg) + rimg.flop.to_blob + end + + def vh(rimg) + rimg.flip.flop.to_blob + end + + def to_gif? + self.dext == 'png' and self.flag_gif_convert >= 0 + end + + def self.png_to_gif(data) + res = nil + begin + mgk = Magick::Image.from_blob(data).shift + mgk.format = 'gif' + res = mgk + rescue + res = false + end + res + end + + def subdirs + flag_reverse < 0 ? [''] : ['', 'v', 'h', 'vh'] + end + + def store(mgk) + res = false + self.revision = self.new_revision + if res = self.save + if res = self.store_picture(mgk) + if self.to_gif? + if gifmgk = Picture.png_to_gif(mgk.to_blob) + res = self.store_picture(gifmgk) + else + res = false + end + end + end + end + res + end + + def store_picture(mgk) + res = false + subdirs.each do |d| + picdata = d.empty? ? mgk.to_blob : self.__send__(d, mgk) + res = PictureIO.picture_io.put(picdata, "#{self.id}.#{mgk.format}", d) + break unless res + end + res + end + + def restore(subdir = nil) + PictureIO.resource_picture_io.get self.filename, subdir + end + + def flags + begin + @flags = JSON.parse(self.settings) unless @flags + rescue + end + @flags + end + + def flags=(s) + @flags = s + end + + def flag_open + @flag_open = flags["open"] unless @flag_open + @flag_open + end + + def flag_commercial + @flag_commercial = flags["commercial"] unless @flag_commercial + @flag_commercial + end + + def flag_official + @flag_official = flags["official"] unless @flag_official + @flag_official + end + + def flag_attribution + @flag_attribution = flags["attribution"] unless @flag_attribution + @flag_attribution + end + + def flag_derive + @flag_derive = flags["derive"] unless @flag_derive + @flag_derive + end + + def flag_thumbnail + @flag_thumbnail = flags["thumbnail"] unless @flag_thumbnail + @flag_thumbnail + end + + def flag_gif_convert + @flag_gif_convert = flags["gif_convert"] unless @flag_gif_convert + @flag_gif_convert + end + + def flag_reverse + @flag_reverse = flags["reverse"] unless @flag_reverse + @flag_reverse + end + + def flag_resize + @flag_resize = flags["resize"] unless @flag_resize + @flag_resize + end + + def flag_sync_vh + @flag_sync_vh = flags["sync_vh"] unless @flag_sync_vh + @flag_sync_vh + end + + def flag_overlap + @flag_overlap = flags["overlap"] unless @flag_overlap + @flag_overlap + end + end diff --git a/app/models/resource_picture.rb b/app/models/resource_picture.rb index 7d320923..5f5c9e63 100644 --- a/app/models/resource_picture.rb +++ b/app/models/resource_picture.rb @@ -60,18 +60,6 @@ class ResourcePicture < ActiveRecord::Base "image/#{self.dext}" end - def v(rimg) - rimg.flip.to_blob - end - - def h(rimg) - rimg.flop.to_blob - end - - def vh(rimg) - rimg.flip.flop.to_blob - end - def url subdir = nil '/resource_pictures/' + (subdir.to_s.empty? ? '' : subdir.to_s + '/' ) + filename end diff --git a/config/application.rb b/config/application.rb index 00a00f71..fff4f75c 100644 --- a/config/application.rb +++ b/config/application.rb @@ -63,6 +63,7 @@ pio = PictureIO.const_get y[Rails.env]["io"] PictureIO.setup do |config| config.original_picture_io = pio.new y[Rails.env]["original_picture"] config.resource_picture_io = pio.new y[Rails.env]["resource_picture"] + config.picture_io = pio.new y[Rails.env]["picture"] config.system_picture_io = pio.new y[Rails.env]["system_picture"] end module ActiveRecord diff --git a/config/picture_io.yml.org b/config/picture_io.yml.org index d1399fe6..1a038654 100644 --- a/config/picture_io.yml.org +++ b/config/picture_io.yml.org @@ -3,6 +3,7 @@ development: io: LocalPicture original_picture: /pettanr/dev/o/ resource_picture: /pettanr/dev/r/ + picture: /temp/p/p/ system_picture: /pettanr/dev/s/ test: @@ -10,6 +11,7 @@ test: io: LocalPicture original_picture: /pettanr/test/o/ resource_picture: /pettanr/test/r/ + picture: /temp/p/tp/ system_picture: /pettanr/test/s/ production: diff --git a/db/standard_license.json b/db/standard_license.json index e8b8ae47..56e17c13 100644 --- a/db/standard_license.json +++ b/db/standard_license.json @@ -7,12 +7,14 @@ "StandardLicenseA": { "caption": "Flag A", "url": "http://test.com/standard_license/a", - "system_picture": "Data" + "system_picture": "iVBORw0KGgoAAAANSUhEUgAAAGQAAAAyCAIAAAAlV+npAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIYSURBVGhD7ZtNkoIwFIS5D+WOY7hxzw1ceQPdsfMSuvMO7ixvMseYAUMS8vJDEvLAqWrLjSUgfK+701RhdT7/4h1JoIrcDpv1BAArwViABVg8QUyV9X7+4C0I2DENWF5xAFaCbwALsHhyFsqCsqCszRsMbAgbwoawYYILAAuweCLjvyrruq/mX/t7mcvrWvFbu+Mr+oCvUy1PsL48Cg0vszp8OyzJVwA7dGXMngnLnPD9ME6xvRaaoXH8dGXRWRbS+FqwzFFXtjVulx0x9nCFEzdNv51xlhxe3chjlpniCrA8F1w1p9vojsexcSVgv0EWrIkSlcSKOJEdlgKh41mpTAhEacrQS68OSTPNhorvZ3fyW8tSghuWcoSxJMmBm9fjS5YkWBS9ye6rYalTN0EouQ3usNKKVoQUWLaQHdLORcasLJLrVjKJKHFnlnJlAiyXjtw2zykTzLDsNc7kNc1du7uNEouHFTeb6GZLgTLDesrMCjSdrqVLlbpmsRf56DfRfFVeVri4YU0sRk9UrneCxfRbIiWtl3Bd8ndjLfBFhYsdlrdYDoTM1ZAkmm4SikLwdi8kQN3XlhSuFWB9nO8KL33eVtZY98wmL0eDn8Gh15AF99VFYOWsLNkpu+GOgJUwacACrNyOHvY4lAVlQVkbroN48i/BgIDFAAt/DggQwHPweA5+nefgYUPYMMFrgAVYPMEEZZVR1h8aqGKZ0anY3gAAAABJRU5ErkJggg==", + "settings": "{\"open\": 1, \"commercial\": 1, \"official\": 0, \"attribution\": 1, \"derive\": 1, \"thumbnail\": 1, \"gif_convert\": 1, \"reverse\": 1, \"resize\": 1, \"sync_vh\": 1, \"overlap\": 1}" }, "StandardLicenseB": { "caption": "Flag B", "url": "http://test.com/standard_license/b", - "system_picture": "Data" + "system_picture": "iVBORw0KGgoAAAANSUhEUgAAAGQAAAAyCAIAAAAlV+npAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAANFSURBVGhD7ZjPaxpBFMc3/Ssq2gbBQqF4C2hyKXpqITkIgge9JocaChIk3oynGkT2klzsVQ+BBQ8K6UnpoVXBmwiFBtKWFftftLM7sz/txnm7k4DNWzyo+31vZj7z3pu3u3V29kfCi4/AEz4ZqjQCCAsQBwgLYQEIAKRbrgL/5vVvgPV/Lf30+alrfZiGgA1HWAgLQAAgxchCWAACAClGFsICEABIMbIQFoAAQIqRhbAABABSjCyEBSAAkHK9dRg1Q6X+Oqf7nfFJep2I4/6knKy0iS5e/PoxG+Uw0CWG1ao+U1+eJnjd2HWP8a1DtxJKNgd+aK3YcNWs3ZPleGh+OhnmpSBbfy7FhFXwNb2qKeas6gXmry9fLYK7vqd38CQpUiHrc9xSXVNdtA7tAvJd2/zbq+MQzUFyzS73mIdVc86FJ94a+8ppsEbGFVmQoRwLZobzajZ1YO6tqhwkC9WZy6mgzfeY6svnYcgiPLSCYanKe3muDUXKM8tclgtT+YMeX4tW7XKqKez5MqSpHc1dLMdG7lgeLo4ivlaqKnJXN4wX3+368uAyEgtr0DFAVM2DLNGQ9/VB570vpHCo31lMRWM2BOnTYS8nYvMlLYpZBcjqkyGnIeBUvZOpUFiLmxs6mAOE9Gx7R/93+oOEVuRFnGr6eVqSDpVbEbvu6UM7DVOh84mAQYTCMqPGAEFx0B1mV/ioWqTs2MUKue8q7oLgyO6lYozVrZRHgXEJhWVGzZ3TimR7pJyx3DSV82rtHkIski0ZB+K3X4G7B6GwwrEYXTzp5u0tmPFd66QnZZoRVu9mVPTZT0c+un4GDgsBDoTCktJ5GvYkDd1N8+Dc6B68Wur4tvPhpn8dPHFGzTw9ECVJQPfA9Wzo3BSybDoD0sE3Vo5k0mft0e5h5doptXs5lT36ue+SWsNaBNO/IbFueUeH97OhbqMPDTxtH+DZUO+V2jV25NlWl6nr0000zE7KvKm1VFYzRdoI84lKQO7oNQFM6p8D+4gsEQvYBB8PEFmbgMHvHMUWeL+z2BA7hAXYKISFsAAEAFKMLIQFIACQYmQBYLmbUoDp45NiZAH2HGEhLAABgBQjC2EBCACkGFkIC0AAIP0Las1F1VY+UUMAAAAASUVORK5CYII=", + "settings": "{\"open\": 1, \"commercial\": 1, \"official\": 0, \"attribution\": 1, \"derive\": 1, \"thumbnail\": 0, \"gif_convert\": 1, \"reverse\": 1, \"resize\": 1, \"sync_vh\": 1, \"overlap\": 1}" } } } diff --git a/lib/local_picture.rb b/lib/local_picture.rb index daaf8665..262b9bd8 100644 --- a/lib/local_picture.rb +++ b/lib/local_picture.rb @@ -13,10 +13,6 @@ class PictureIO @base = b end - def self.subdirs - ['', 'v', 'h', 'vh', 'thumbnail'] - end - def dir(subdir = nil) sd = if subdir.to_s.empty? self.base diff --git a/lib/picture_io.rb b/lib/picture_io.rb index df49d0e7..4b964778 100644 --- a/lib/picture_io.rb +++ b/lib/picture_io.rb @@ -1,7 +1,4 @@ class PictureIO - @@resource_picture_io #= LocalPicture.new - @@original_picture_io #= LocalPicture.new Rails.root + 'original' - @@system_picture_io #= LocalPicture.new Rails.root + 'system' def self.original_picture_io @@original_picture_io @@ -19,6 +16,14 @@ class PictureIO @@resource_picture_io = pclass end + def self.picture_io + @@picture_io + end + + def self.picture_io=(pclass) + @@picture_io = pclass + end + def self.system_picture_io @@system_picture_io end diff --git a/lib/test/local_picture_spec.rb b/lib/test/local_picture_spec.rb index 2be6b6a3..acb4733f 100644 --- a/lib/test/local_picture_spec.rb +++ b/lib/test/local_picture_spec.rb @@ -20,21 +20,6 @@ describe PictureIO::LocalPicture do @io = PictureIO::LocalPicture.new @path end - describe 'サブディレクトリに於いて' do - it '配列が返る' do - PictureIO::LocalPicture.subdirs.is_a?(Array).should be_true - end - - it 'カレント、サムネ、水平反転、垂直反転、水平垂直反転が返る' do - PictureIO::LocalPicture.subdirs.size.should eq 5 - PictureIO::LocalPicture.subdirs.include?('').should eq true - PictureIO::LocalPicture.subdirs.include?('v').should eq true - PictureIO::LocalPicture.subdirs.include?('h').should eq true - PictureIO::LocalPicture.subdirs.include?('vh').should eq true - PictureIO::LocalPicture.subdirs.include?('thumbnail').should eq true - end - end - describe 'ファイル存在確認に於いて' do before do end diff --git a/spec/factories.rb b/spec/factories.rb index 89213cdb..474d0127 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -147,6 +147,20 @@ Factory.define :resource_picture, :class => ResourcePicture do |rp| rp.original_picture_id 1 end +Factory.define :picture, :class => Picture do |p| + p.original_picture_id 1 + p.revision 1 + p.ext 'png' + p.width 222 + p.height 111 + p.filesize 100000 + p.artist_id 1 + p.license_id 1 + p.artist_name 'no name' + p.credit '' + p.settings '' +end + Factory.define :system_picture, :class => SystemPicture do |sp| sp.ext 'png' sp.width 222 diff --git a/spec/models/picture_spec.rb b/spec/models/picture_spec.rb index 5ef8eeae..465838b8 100644 --- a/spec/models/picture_spec.rb +++ b/spec/models/picture_spec.rb @@ -1,5 +1,701 @@ +# -*- encoding: utf-8 -*- +#実素材 require 'spec_helper' describe Picture do - pending "add some examples to (or delete) #{__FILE__}" + before do + Factory :admin + @user = Factory( :user_yas) + @author = @user.author + @artist = Factory :artist_yas, :author_id => @author.id + @other_user = Factory( :user_yas) + @other_author = @other_user.author + @other_artist = Factory :artist_yas, :author_id => @other_author.id + @sp = Factory :system_picture + @lg = Factory :license_group + @license = Factory :license, :license_group_id => @lg.id, :system_picture_id => @sp.id + @op = Factory :original_picture, :artist_id => @artist.id + end + + describe '検証に於いて' do + before do + end + + it 'オーソドックスなデータなら通る' do + @p = Factory.build :picture, :original_picture_id => @op.id, :license_id => @license.id + @p.should be_valid + end + + context 'original_picture_idを検証するとき' do + before do + @p = Factory.build :picture, :original_picture_id => @op.id, :license_id => @license.id + end + it 'テストデータの確認' do + @p.original_picture_id = @op.id + @p.should be_valid + end + it 'nullなら失敗する' do + @p.original_picture_id = nil + @p.should_not be_valid + end + it '数値でなければ失敗する' do + @p.original_picture_id = 'a' + @p.should_not be_valid + end + it '存在する原画でなければ失敗する' do + @p.original_picture_id = 0 + @p.should_not be_valid + end + end + context 'revisionを検証するとき' do + before do + @p = Factory.build :picture, :original_picture_id => @op.id, :license_id => @license.id + end + it 'テストデータの確認' do + @p.revision = 1 + @p.should be_valid + end + it 'nullなら失敗する' do + @p.revision = nil + @p.should_not be_valid + end + it '数値でなければ失敗する' do + @p.revision = 'a' + @p.should_not be_valid + end + end + context 'extを検証するとき' do + before do + @p = Factory.build :picture, :original_picture_id => @op.id, :license_id => @license.id + end + it 'テストデータの確認' do + @p.ext = 'jpeg' + @p.should be_valid + end + it 'nullなら失敗する' do + @p.ext = '' + @p.should_not be_valid + end + it '5文字以上なら失敗する' do + @p.ext = 'a'*5 + @p.should_not be_valid + end + it 'png,gif,jpeg以外なら失敗する' do + @p.ext = 'bmp' + @p.should_not be_valid + end + end + context 'widthを検証するとき' do + before do + @p = Factory.build :picture, :original_picture_id => @op.id, :license_id => @license.id + end + it 'テストデータの確認' do + @p.width = 1 + @p.should be_valid + end + it 'nullなら失敗する' do + @p.width = nil + @p.should_not be_valid + end + it '数値でなければ失敗する' do + @p.width = 'a' + @p.should_not be_valid + end + it '0なら失敗する' do + @p.width = '0' + @p.should_not be_valid + end + it '負でも失敗する' do + @p.width = -1 + @p.should_not be_valid + end + end + context 'heightを検証するとき' do + before do + @p = Factory.build :picture, :original_picture_id => @op.id, :license_id => @license.id + end + it 'テストデータの確認' do + @p.height = 1 + @p.should be_valid + end + it 'nullなら失敗する' do + @p.height = nil + @p.should_not be_valid + end + it '数値でなければ失敗する' do + @p.height = 'a' + @p.should_not be_valid + end + it '0なら失敗する' do + @p.height = '0' + @p.should_not be_valid + end + it '負でも失敗する' do + @p.height = -1 + @p.should_not be_valid + end + end + context 'filesizeを検証するとき' do + before do + @p = Factory.build :picture, :original_picture_id => @op.id, :license_id => @license.id + end + it 'テストデータの確認' do + @p.filesize = 1 + @p.should be_valid + end + it 'nullなら失敗する' do + @p.filesize = nil + @p.should_not be_valid + end + it '数値でなければ失敗する' do + @p.filesize = 'a' + @p.should_not be_valid + end + it '負なら失敗する' do + @p.filesize = '-1' + @p.should_not be_valid + end + it '2MB以上なら失敗する' do + @p.filesize = 2000000+1 + @p.should_not be_valid + end + end + context 'artist_idを検証するとき' do + before do + @p = Factory.build :picture, :original_picture_id => @op.id, :license_id => @license.id + end + it 'テストデータの確認' do + @p.artist_id = @artist.id + @p.should be_valid + end + it 'nullなら失敗する' do + @p.artist_id = nil + @p.should_not be_valid + end + it '数値でなければ失敗する' do + @p.artist_id = 'a' + @p.should_not be_valid + end + it '存在する絵師でなければ失敗する' do + @p.artist_id = 0 + @p.should_not be_valid + end + end + context 'license_idを検証するとき' do + before do + @p = Factory.build :picture, :original_picture_id => @op.id, :license_id => @license.id + end + it 'テストデータの確認' do + @p.license_id = @license.id + @p.should be_valid + end + it 'nullなら失敗する' do + @p.license_id = nil + @p.should_not be_valid + end + it '数値でなければ失敗する' do + @p.license_id = 'a' + @p.should_not be_valid + end + it '存在するライセンスグループでなければ失敗する' do + @p.license_id = 0 + @p.should_not be_valid + end + end + context 'artist_nameを検証するとき' do + before do + @p = Factory.build :picture, :original_picture_id => @op.id, :license_id => @license.id + end + it 'テストデータの確認' do + @p.artist_name = 'a' + @p.should be_valid + end + it 'nullなら失敗する' do + @p.artist_name = nil + @p.should_not be_valid + end + end + context 'creditを検証するとき' do + before do + @p = Factory.build :picture, :original_picture_id => @op.id, :license_id => @license.id + end + it 'テストデータの確認' do + @p.credit = 'a' + @p.should be_valid + end + end + context 'settingsを検証するとき' do + before do + @p = Factory.build :picture, :original_picture_id => @op.id, :license_id => @license.id + end + it 'テストデータの確認' do + @p.settings = 'a' + @p.should be_valid + end + end + end + describe '補充に於いて' do + end + describe '最新Revision取得に於いて' do + context '初めての原画を公開したとき' do + before do + @p = Factory.build :picture, :original_picture_id => @op.id, :license_id => @license.id + end + it 'Revisionは1となる' do + @p.new_revision.should eq 1 + end + end + context 'HEADが1のとき' do + before do + Factory :picture, :revision => 1, :original_picture_id => @op.id, :license_id => @license.id + @p = Factory.build :picture, :original_picture_id => @op.id, :license_id => @license.id + end + it 'Revisionは2となる' do + @p.new_revision.should eq 2 + end + end + context 'HEADが5のとき' do + before do + Factory :picture, :revision => 1, :original_picture_id => @op.id, :license_id => @license.id + Factory :picture, :revision => 5, :original_picture_id => @op.id, :license_id => @license.id + @p = Factory.build :picture, :original_picture_id => @op.id, :license_id => @license.id + end + it 'Revisionは6となる' do + @p.new_revision.should eq 6 + end + end + end + describe '作成に於いて' do + before do + #RMagickのスタブをおいておく + class Mgk ; class Image ; end ; end + @filesize = 76543 + Mgk::Image.stub(:from_blob).with(any_args).and_return([Mgk.new]) + Mgk.any_instance.stub(:format).with(any_args).and_return('png') + Mgk.any_instance.stub(:rows).with(any_args).and_return(200) + Mgk.any_instance.stub(:columns).with(any_args).and_return(100) + Mgk.any_instance.stub(:filesize).with(any_args).and_return(@filesize) + Mgk.any_instance.stub(:to_blob).with(any_args).and_return('data') + #原画ファイル削除だけは必ず成功するものとしておく + PictureIO::LocalPicture.any_instance.stub(:delete).with(any_args).and_return(true) + end + context '事前チェック' do + before do + #すべての処理が正常パターンで通過すれば、一番深い分岐まで通る。 + #それで外部のメソッド呼び出しだけに着目してテストする。 + Picture.any_instance.stub(:save).with(any_args).and_return(true) + Picture.any_instance.stub(:store_picture).with(any_args).and_return(true) + Picture.any_instance.stub(:to_gif?).with(any_args).and_return(true) + class GifMgk < Mgk ; end #store_pictureは二回呼び出される。区別をつけるために + @gifmgk = GifMgk.new #パラメータを二種類用意する。 + Picture.stub(:png_to_gif).with(any_args).and_return(@gifmgk) + @p = Factory.build :picture, :original_picture_id => @op.id, :license_id => @license.id + end + it '最新Revisionを取得している' do + Picture.any_instance.should_receive(:new_revision).with(any_args).exactly(1) + res = @p.store(Mgk.new) + end + it '自身を保存している' do + Picture.any_instance.should_receive(:save).with(any_args).exactly(1) + res = @p.store(Mgk.new) + end + it '画像ファイルの作成機能で画像を保存している' do + mgk = Mgk.new #一回目の本画像保存は与えたオブジェクトを使って保存する。 + Picture.any_instance.should_receive(:store_picture).with(mgk).exactly(1) + res = @p.store(mgk) + end + it '自身にgifフォーマット変換対象かを問い合わせている' do + Picture.any_instance.should_receive(:to_gif?).with(any_args).exactly(1) + res = @p.store(Mgk.new) + end + it '自身にGifフォーマット変換を依頼している' do + Picture.should_receive(:png_to_gif).with(any_args).exactly(1) + res = @p.store(Mgk.new) + end + it '画像ファイルの作成機能でgif画像を保存している' do + #二回目の保存はgif変換の結果を渡す。 + Picture.any_instance.should_receive(:store_picture).with(@gifmgk).exactly(1) + res = @p.store(Mgk.new) + end + end + context 'つつがなく終わるとき' do + before do + #すべての処理を正常パターンで通過させ、保存機能をチェックする。 +# Picture.any_instance.stub(:save).with(any_args).and_return(true) + Picture.any_instance.stub(:store_picture).with(any_args).and_return(true) + Picture.any_instance.stub(:to_gif?).with(any_args).and_return(true) + class GifMgk < Mgk ; end #store_pictureは二回呼び出される。区別をつけるために + @gifmgk = GifMgk.new #パラメータを二種類用意する。 + Picture.stub(:png_to_gif).with(any_args).and_return(@gifmgk) + @p = Factory.build :picture, :revision => nil, :original_picture_id => @op.id, :license_id => @license.id + end + it 'Trueを返す' do + res = @p.store(Mgk.new) + res.should be_true + end + it 'Revisionに最新Revisionセット' do + res = @p.store(Mgk.new) + @p.revision.should eq 1 + end + it '自身が保存されている' do + lambda { + res = @p.store(Mgk.new) + }.should change Picture, :count + end + end + context 'gif変換なしで、つつがなく終わるとき' do + before do + #すべての処理を正常パターンで通過させ、保存機能をチェックする。 + Picture.any_instance.stub(:save).with(any_args).and_return(true) + Picture.any_instance.stub(:store_picture).with(any_args).and_return(true) + Picture.any_instance.stub(:to_gif?).with(any_args).and_return(false) + @p = Factory.build :picture, :original_picture_id => @op.id, :license_id => @license.id + end + it 'Trueを返す' do + res = @p.store(Mgk.new) + res.should be_true + end + it 'gif保存は呼ばれていない' do + #二回目の画像作成が呼び出されないで1回こっきりならgif保存は呼ばれていないんだろう。 + Picture.any_instance.should_receive(:store_picture).with(any_args).exactly(1) + res = @p.store(Mgk.new) + end + end + #以下から例外ケース。処理先頭から失敗させていく + context '自身の保存に失敗したとき' do + before do + Picture.any_instance.stub(:save).with(any_args).and_return(false) + @p = Factory.build :picture, :original_picture_id => @op.id, :license_id => @license.id + end + it 'Falseを返す' do + res = @p.store(Mgk.new) + res.should be_false + end + it '更新されていない' do + @p.store(Mgk.new) + @p.should be_a_new Picture + end + end + context '画像の保存に失敗したとき' do + before do + Picture.any_instance.stub(:save).with(any_args).and_return(true) + Picture.any_instance.stub(:store_picture).with(any_args).and_return(false) + @p = Factory.build :picture, :original_picture_id => @op.id, :license_id => @license.id + end + it 'Falseを返す' do + res = @p.store(Mgk.new) + res.should be_false + end + it 'gif変換判定は呼ばれていない' do + Picture.any_instance.should_not_receive(:to_gif?).with(any_args) + res = @p.store(Mgk.new) + end + end + context 'gif変換に失敗したとき' do + before do + Picture.any_instance.stub(:save).with(any_args).and_return(true) + Picture.any_instance.stub(:store_picture).with(any_args).and_return(true) + Picture.any_instance.stub(:to_gif?).with(any_args).and_return(true) + Picture.stub(:png_to_gif).with(any_args).and_return(false) + @p = Factory.build :picture, :original_picture_id => @op.id, :license_id => @license.id + end + it 'Falseを返す' do + res = @p.store(Mgk.new) + res.should be_false + end + it 'gif画像の保存は呼ばれていない' do + #本画像の保存があるので、一度は呼ばれる + Picture.any_instance.should_receive(:store_picture).with(any_args).exactly(1) + res = @p.store(Mgk.new) + end + end + context 'gif画像の保存に失敗したとき' do + before do + @mgk = Mgk.new + Picture.any_instance.stub(:save).with(any_args).and_return(true) + Picture.any_instance.stub(:store_picture).with(@mgk).and_return(true) + Picture.any_instance.stub(:to_gif?).with(any_args).and_return(true) + class GifMgk < Mgk ; end #store_pictureは二回呼び出される。区別をつけるために + @gifmgk = GifMgk.new #パラメータを二種類用意する。 + Picture.stub(:png_to_gif).with(any_args).and_return(@gifmgk) + Picture.any_instance.stub(:store_picture).with(@gifmgk).and_return(false) + @p = Factory.build :picture, :original_picture_id => @op.id, :license_id => @license.id + end + it 'Falseを返す' do + res = @p.store(@mgk) + res.should be_false + end + end + end + + describe '反転画像の保存先に於いて' do + before do + @p = Factory.build :picture, :original_picture_id => @op.id, :license_id => @license.id + end + context '禁止のとき' do + it 'ベースディレクトリだけを返す' do + Picture.any_instance.should_receive(:flag_reverse).with(any_args).and_return(-1) + r = @p.subdirs + r.should have(1).item + end + it 'ベースディレクトリだけを返す' do + Picture.any_instance.should_receive(:flag_reverse).with(any_args).and_return(-1) + r = @p.subdirs + r.first.should eq '' + end + end + context '許可のとき' do + it 'ベースディレクトリと反転3種を返す' do + Picture.any_instance.should_receive(:flag_reverse).with(any_args).and_return(1) + r = @p.subdirs + r.should have(4).item + end + it 'ベースディレクトリと反転3種を返す' do + Picture.any_instance.should_receive(:flag_reverse).with(any_args).and_return(1) + r = @p.subdirs + r.last.should eq 'vh' + end + end + end + + describe '画像ファイルの作成に於いて' do + #PictureIo経由で画像を保存するための機能。ファイル名に自身のidを使うので事前に自身の保存が必要。 + before do + #RMagickのスタブをおいておく + class Mgk ; class Image ; end ; end + @filesize = 76543 + Mgk::Image.stub(:from_blob).with(any_args).and_return([Mgk.new]) + Mgk.any_instance.stub(:format).with(any_args).and_return('png') + Mgk.any_instance.stub(:rows).with(any_args).and_return(200) + Mgk.any_instance.stub(:columns).with(any_args).and_return(100) + Mgk.any_instance.stub(:filesize).with(any_args).and_return(@filesize) + Mgk.any_instance.stub(:to_blob).with(any_args).and_return('data') + #原画ファイル削除だけは必ず成功するものとしておく + PictureIO::LocalPicture.any_instance.stub(:delete).with(any_args).and_return(true) + + Picture.any_instance.stub(:subdirs).with(any_args).and_return(['', 'v', 'h', 'vh']) + Picture.any_instance.stub(:h).with(any_args).and_return('data') + Picture.any_instance.stub(:v).with(any_args).and_return('data') + Picture.any_instance.stub(:vh).with(any_args).and_return('data') + @p = Factory.build :picture, :original_picture_id => @op.id, :license_id => @license.id + end + context '事前チェック' do + before do + #すべての処理を正常パターンで通過させ、保存機能をチェックする。 + PictureIO.picture_io.stub(:put).with(any_args).and_return(true) + end + it '画像ファイルの保存が4回呼ばれる' do + PictureIO.picture_io.should_receive(:put).with(any_args).exactly(4) + res = @p.store_picture(Mgk.new) + end + it '画像ファイルのベースへの保存が1回呼ばれる' do + PictureIO.picture_io.should_receive(:put).with('data', @p.filename, '').exactly(1) + res = @p.store_picture(Mgk.new) + end + it '画像ファイルの垂直反転への保存が1回呼ばれる' do + PictureIO.picture_io.should_receive(:put).with('data', @p.filename, 'v').exactly(1) + res = @p.store_picture(Mgk.new) + end + it '画像ファイルの水平反転への保存が1回呼ばれる' do + PictureIO.picture_io.should_receive(:put).with('data', @p.filename, 'h').exactly(1) + res = @p.store_picture(Mgk.new) + end + it '画像ファイルの垂直水平反転への保存が1回呼ばれる' do + PictureIO.picture_io.should_receive(:put).with('data', @p.filename, 'vh').exactly(1) + res = @p.store_picture(Mgk.new) + end + it '垂直反転が1回呼ばれる' do + Picture.any_instance.should_receive(:v).with(any_args).exactly(1) + res = @p.store_picture(Mgk.new) + end + it '水平反転が1回呼ばれる' do + Picture.any_instance.should_receive(:h).with(any_args).exactly(1) + res = @p.store_picture(Mgk.new) + end + it '垂直水平反転が1回呼ばれる' do + Picture.any_instance.should_receive(:vh).with(any_args).exactly(1) + res = @p.store_picture(Mgk.new) + end + end + context 'つつがなく終わるとき' do + before do + #すべての処理を正常パターンで通過させ、保存機能をチェックする。 + PictureIO.picture_io.stub(:put).with(any_args).and_return(true) + end + it 'Trueを返す' do + res = @p.store_picture(Mgk.new) + res.should be_true + end + end + context '例外ケース' do + before do + PictureIO.picture_io.stub(:put).with(any_args).and_return(false) + end + it 'Falseを返す' do + res = @p.store_picture(Mgk.new) + res.should be_false + end + end + + end + + describe 'フラグ展開に於いて' do + before do + @p = Factory.build :picture, :original_picture_id => @op.id, :license_id => @license.id, + :settings => "{\"open\": 1, \"commercial\": 2, \"official\": 3, \"attribution\": 4, \"derive\": 5, \"thumbnail\": 6, \"gif_convert\": 7, \"reverse\": 8, \"resize\": 9, \"sync_vh\": 10, \"overlap\": 11}" + end + context 'json展開チェック' do + it '展開してなければ展開して@flagsに保管する' do + @p.flags.should_not be_nil + end + it '展開できなければnilのまま' do + @p.settings += '}' + @p.flags.should be_nil + end + end + context 'openについて' do + it '@flag_openに保管する' do + @p.flag_open.should_not be_nil + end + it '本当にフラグHashからじゃなく、変数から取得してる?' do + @p.flag_open + @p.flags = nil + @p.flag_open.should_not be_nil + end + it '1を返す' do + @p.flag_open.should eq 1 + end + end + context 'commercialについて' do + it '@flag_commercialに保管する' do + @p.flag_commercial.should_not be_nil + end + it '本当にフラグHashからじゃなく、変数から取得してる?' do + @p.flag_commercial + @p.flags = nil + @p.flag_commercial.should_not be_nil + end + it '2を返す' do + @p.flag_commercial.should eq 2 + end + end + context 'officialについて' do + it '@flag_officialに保管する' do + @p.flag_official.should_not be_nil + end + it '本当にフラグHashからじゃなく、変数から取得してる?' do + @p.flag_official + @p.flags = nil + @p.flag_official.should_not be_nil + end + it 'を返す' do + @p.flag_official.should eq 3 + end + end + context 'attributionについて' do + it '@flag_attributionに保管する' do + @p.flag_attribution.should_not be_nil + end + it '本当にフラグHashからじゃなく、変数から取得してる?' do + @p.flag_attribution + @p.flags = nil + @p.flag_attribution.should_not be_nil + end + it '4を返す' do + @p.flag_attribution.should eq 4 + end + end + context 'deriveについて' do + it '@flag_deriveに保管する' do + @p.flag_derive.should_not be_nil + end + it '本当にフラグHashからじゃなく、変数から取得してる?' do + @p.flag_derive + @p.flags = nil + @p.flag_derive.should_not be_nil + end + it '5を返す' do + @p.flag_derive.should eq 5 + end + end + context 'thumbnailについて' do + it '@flag_thumbnailに保管する' do + @p.flag_thumbnail.should_not be_nil + end + it '本当にフラグHashからじゃなく、変数から取得してる?' do + @p.flag_thumbnail + @p.flags = nil + @p.flag_thumbnail.should_not be_nil + end + it '6を返す' do + @p.flag_thumbnail.should eq 6 + end + end + context 'gif_convertについて' do + it '@flag_gif_convertに保管する' do + @p.flag_gif_convert.should_not be_nil + end + it '本当にフラグHashからじゃなく、変数から取得してる?' do + @p.flag_gif_convert + @p.flags = nil + @p.flag_gif_convert.should_not be_nil + end + it '7を返す' do + @p.flag_gif_convert.should eq 7 + end + end + context 'reverseについて' do + it '@flag_reverseに保管する' do + @p.flag_reverse.should_not be_nil + end + it '本当にフラグHashからじゃなく、変数から取得してる?' do + @p.flag_reverse + @p.flags = nil + @p.flag_reverse.should_not be_nil + end + it '8を返す' do + @p.flag_reverse.should eq 8 + end + end + context 'resizeについて' do + it '@flag_resizeに保管する' do + @p.flag_resize.should_not be_nil + end + it '本当にフラグHashからじゃなく、変数から取得してる?' do + @p.flag_resize + @p.flags = nil + @p.flag_resize.should_not be_nil + end + it '9を返す' do + @p.flag_resize.should eq 9 + end + end + context 'sync_vhについて' do + it '@flag_sync_vhに保管する' do + @p.flag_sync_vh.should_not be_nil + end + it '本当にフラグHashからじゃなく、変数から取得してる?' do + @p.flag_sync_vh + @p.flags = nil + @p.flag_sync_vh.should_not be_nil + end + it '10を返す' do + @p.flag_sync_vh.should eq 10 + end + end + context 'overlapについて' do + it '@flag_overlapに保管する' do + @p.flag_overlap.should_not be_nil + end + it '本当にフラグHashからじゃなく、変数から取得してる?' do + @p.flag_overlap + @p.flags = nil + @p.flag_overlap.should_not be_nil + end + it '11を返す' do + @p.flag_overlap.should eq 11 + end + end + end + end -- 2.11.0