OSDN Git Service

t#29312:any update
authoryasushiito <yas@pen-chan.jp>
Mon, 20 Aug 2012 10:07:52 +0000 (19:07 +0900)
committeryasushiito <yas@pen-chan.jp>
Mon, 20 Aug 2012 10:07:52 +0000 (19:07 +0900)
127 files changed:
.gitignore
.rspec
Gemfile
Gemfile.lock
app/assets/javascripts/ie5.js [new file with mode: 0644]
app/controllers/application_controller.rb
app/controllers/artists_controller.rb
app/controllers/colors_controller.rb [new file with mode: 0644]
app/controllers/comics_controller.rb
app/controllers/ground_colors_controller.rb [new file with mode: 0644]
app/controllers/ground_pictures_controller.rb [new file with mode: 0644]
app/controllers/original_pictures_controller.rb
app/controllers/panel_colors_controller.rb [new file with mode: 0644]
app/controllers/panels_controller.rb
app/controllers/pictures_controller.rb
app/controllers/stories_controller.rb
app/helpers/colors_helper.rb [new file with mode: 0644]
app/helpers/ground_colors_helper.rb [new file with mode: 0644]
app/helpers/ground_pictures_helper.rb [new file with mode: 0644]
app/helpers/panel_colors_helper.rb [new file with mode: 0644]
app/models/artist.rb
app/models/author.rb
app/models/color.rb [new file with mode: 0644]
app/models/comic.rb
app/models/ground_color.rb [new file with mode: 0644]
app/models/ground_picture.rb [new file with mode: 0644]
app/models/license_group.rb
app/models/original_picture.rb
app/models/panel.rb
app/models/panel_color.rb [new file with mode: 0644]
app/models/panel_picture.rb
app/models/picture.rb
app/models/resource_picture.rb
app/models/system_picture.rb
app/views/artists/_form.html.erb
app/views/artists/list.html.erb
app/views/colors/index.html.erb [new file with mode: 0644]
app/views/comics/_form.html.erb
app/views/comics/browse.html.erb
app/views/comics/list.html.erb
app/views/comics/show.html.erb
app/views/ground_colors/index.html.erb [new file with mode: 0644]
app/views/ground_pictures/index.html.erb [new file with mode: 0644]
app/views/home/step3.html.erb
app/views/layouts/system.html.erb
app/views/layouts/test.html.erb
app/views/original_pictures/_artist_register.html.erb
app/views/original_pictures/_exist.html.erb [new file with mode: 0644]
app/views/original_pictures/_history_list.html.erb [new file with mode: 0644]
app/views/original_pictures/browse.html.erb
app/views/original_pictures/history.html.erb [new file with mode: 0644]
app/views/original_pictures/index.html.erb
app/views/original_pictures/list.html.erb
app/views/original_pictures/show.html.erb
app/views/panel_colors/index.html.erb [new file with mode: 0644]
app/views/pictures/_head.html.erb [new file with mode: 0644]
app/views/pictures/_tail.html.erb [new file with mode: 0644]
app/views/pictures/show.html.erb [new file with mode: 0644]
app/views/resource_pictures/index.html.erb
app/views/resource_pictures/show.html.erb
app/views/system/browse.html.erb
config/environment.rb
config/routes.rb
db/colors.json [new file with mode: 0644]
db/migrate/20120815021444_add_md5.rb [new file with mode: 0644]
db/migrate/20120815043236_rm_default_ls_on_artist.rb [new file with mode: 0644]
db/migrate/20120815045014_rm_default_size_on_comic.rb [new file with mode: 0644]
db/migrate/20120816022713_create_colors.rb [new file with mode: 0644]
db/migrate/20120816024744_create_ground_colors.rb [new file with mode: 0644]
db/migrate/20120816024915_create_panel_colors.rb [new file with mode: 0644]
db/migrate/20120816025308_create_ground_pictures.rb [new file with mode: 0644]
lib/tasks/licenses.rake [new file with mode: 0644]
lib/validators/resize_validator.rb
lib/validators/reverse_validator.rb
lib/validators/sync_vh_validator.rb
script/gem_builder.rb [new file with mode: 0644]
script/ls_helper.rb [new file with mode: 0644]
spec/cli/u/panels/create.json
spec/controllers/colors_controller_spec.rb [new file with mode: 0644]
spec/controllers/comics_controller_spec.rb
spec/controllers/ground_colors_controller_spec.rb [new file with mode: 0644]
spec/controllers/ground_pictures_controller_spec.rb [new file with mode: 0644]
spec/controllers/original_pictures_controller_spec.rb
spec/controllers/panel_colors_controller_spec.rb [new file with mode: 0644]
spec/controllers/panels_controller_spec.rb
spec/controllers/pictures_controller_spec.rb
spec/controllers/stories_controller_spec.rb
spec/factories.rb
spec/helpers/artists_helper_spec.rb
spec/helpers/authors_helper_spec.rb
spec/helpers/balloons_helper_spec.rb
spec/helpers/colors_helper_spec.rb [new file with mode: 0644]
spec/helpers/comics_helper_spec.rb
spec/helpers/ground_colors_helper_spec.rb [new file with mode: 0644]
spec/helpers/ground_pictures_helper_spec.rb [new file with mode: 0644]
spec/helpers/home_helper_spec.rb
spec/helpers/license_groups_helper_spec.rb
spec/helpers/licenses_helper_spec.rb
spec/helpers/original_picture_license_groups_helper_spec.rb
spec/helpers/original_pictures_helper_spec.rb
spec/helpers/panel_colors_helper_spec.rb [new file with mode: 0644]
spec/helpers/panel_pictures_helper_spec.rb
spec/helpers/panels_helper_spec.rb
spec/helpers/pictures_helper_spec.rb
spec/helpers/resource_pictures_helper_spec.rb
spec/helpers/speech_balloon_templates_helper_spec.rb
spec/helpers/speech_balloons_helper_spec.rb
spec/helpers/speeches_helper_spec.rb
spec/helpers/system_helper_spec.rb
spec/helpers/system_pictures_helper_spec.rb
spec/json/color.json [new file with mode: 0644]
spec/json/colors.json [new file with mode: 0644]
spec/json/license_group.json
spec/json/license_groups.json
spec/models/admin_spec.rb
spec/models/artist_spec.rb
spec/models/color_spec.rb [new file with mode: 0644]
spec/models/comic_spec.rb
spec/models/ground_color_spec.rb [new file with mode: 0644]
spec/models/ground_picture_spec.rb [new file with mode: 0644]
spec/models/original_picture_spec.rb
spec/models/panel_color_spec.rb [new file with mode: 0644]
spec/models/panel_picture_spec.rb
spec/models/panel_spec.rb
spec/models/picture_spec.rb
spec/models/resource_picture_spec.rb
spec/models/story_spec.rb

index 012febf..7d019e6 100644 (file)
@@ -10,3 +10,9 @@ config/picture_io.yml
 config/license.yml
 config/test_layout
 lib/test/temp/
+db/migrate/*_creative_commons_v??_licenses_attributes.rb
+db/migrate/*_pettan_commons_v??_licenses_attributes.rb
+db/migrate/*_pettan_protected_v??_licenses_attributes.rb
+db/migrate/*_pettan_public_v??_licenses_attributes.rb
+db/migrate/*_public_domain_v??_licenses_attributes.rb
+db/migrate/*_unknown_v??_licenses_attributes.rb
diff --git a/.rspec b/.rspec
index 53607ea..38dcdb5 100644 (file)
--- a/.rspec
+++ b/.rspec
@@ -1 +1 @@
---colour
+--no-colour
diff --git a/Gemfile b/Gemfile
index b44c1f7..258ae6d 100644 (file)
--- a/Gemfile
+++ b/Gemfile
@@ -6,7 +6,12 @@ gem 'aws-s3'
 gem 'validates_existence'
 gem "validate_url"
 gem "standard_licenses"
-gem "creative_commons_v30_licenses", '>= 0.0.4'
+gem "creative_commons_v30_licenses"
+gem 'pettan_commons_v01_licenses'
+gem 'pettan_protected_v01_licenses'
+gem 'pettan_public_v01_licenses'
+gem 'public_domain_v01_licenses'
+gem 'unknown_v01_licenses'
 
 # Bundle edge Rails instead:
 # gem 'rails',     :git => 'git://github.com/rails/rails.git'
index 5158c6c..34911c7 100644 (file)
@@ -99,8 +99,16 @@ GEM
     multi_json (1.3.6)
     nokogiri (1.5.5-x86-mingw32)
     orm_adapter (0.0.7)
+    pettan_commons_v01_licenses (0.0.5)
+      rails (~> 3.1.1)
+    pettan_protected_v01_licenses (0.0.5)
+      rails (~> 3.1.1)
+    pettan_public_v01_licenses (0.0.5)
+      rails (~> 3.1.1)
     pg (0.14.0-x86-mingw32)
     polyglot (0.3.3)
+    public_domain_v01_licenses (0.0.5)
+      rails (~> 3.1.1)
     rack (1.3.6)
     rack-cache (1.2)
       rack (>= 0.4)
@@ -177,6 +185,8 @@ GEM
     uglifier (1.2.6)
       execjs (>= 0.3.0)
       multi_json (~> 1.3)
+    unknown_v01_licenses (0.0.5)
+      rails (~> 3.1.1)
     validate_url (0.2.0)
       activemodel (>= 3.0.0)
     validates_existence (0.7.1)
@@ -197,7 +207,7 @@ DEPENDENCIES
   autotest
   aws-s3
   coffee-rails (~> 3.1.1)
-  creative_commons_v30_licenses (>= 0.0.4)
+  creative_commons_v30_licenses
   cucumber
   cucumber-rails
   database_cleaner
@@ -205,7 +215,11 @@ DEPENDENCIES
   factory_girl
   jquery-rails
   moro-miso
+  pettan_commons_v01_licenses
+  pettan_protected_v01_licenses
+  pettan_public_v01_licenses
   pg
+  public_domain_v01_licenses
   rails (= 3.1.1)
   rails-erd
   rmagick
@@ -216,6 +230,7 @@ DEPENDENCIES
   standard_licenses
   therubyracer-heroku
   uglifier (>= 1.0.3)
+  unknown_v01_licenses
   validate_url
   validates_existence
   webrat
diff --git a/app/assets/javascripts/ie5.js b/app/assets/javascripts/ie5.js
new file mode 100644 (file)
index 0000000..c404f21
--- /dev/null
@@ -0,0 +1,78 @@
+/**
+ * http://d.hatena.ne.jp/ofk/20080904/1220485969
+ * @author ofk
+ */
+
+Function.prototype.apply || (Function.prototype.apply = function (x, y) {
+       x = x || window;
+       y = y ||[];
+       x.__apply = this;
+       if (!x.__apply) x.constructor.prototype.__apply = this;
+       var r, j = y.length;
+       switch (j) {
+               case 0: r = x.__apply(); break;
+               case 1: r = x.__apply(y[0]); break;
+               case 2: r = x.__apply(y[0], y[1]); break;
+               case 3: r = x.__apply(y[0], y[1], y[2]); break;
+               case 4: r = x.__apply(y[0], y[1], y[2], y[3]); break;
+               case 5: r = x.__apply(y[0], y[1], y[2], y[3], y[4]); break;
+               case 6: r = x.__apply(y[0], y[1], y[2], y[3], y[4], y[5]); break;
+               case 7: r = x.__apply(y[0], y[1], y[2], y[3], y[4], y[5], y[6]); break;
+               case 8: r = x.__apply(y[0], y[1], y[2], y[3], y[4], y[5], y[6], y[7]); break;
+               case 9: r = x.__apply(y[0], y[1], y[2], y[3], y[4], y[5], y[6], y[7], y[8]); break;
+               default:
+                       var a = [];
+                       for (var i = 0; i < j; ++i)
+                               a[i] = 'y[' + i + ']';
+                       r = eval('x.__apply(' + a.join(',') + ')');
+                       break;
+       }
+       delete x.__apply ? x.__apply : x.constructor.prototype.__apply;
+       return r;
+});
+Function.prototype.call || (Function.prototype.call = function () {
+       var a = arguments, x = a[0], y = [];
+       for (var i = 1, j = a.length; i < j; ++i)
+               y[i - 1] = a[i]
+       return this.apply(x, y);
+});
+Array.prototype.pop || (Array.prototype.pop = function () {
+       var r = this[this.length - 1];
+       --this.length;
+       return r;
+});
+Array.prototype.push || (Array.prototype.push = function () {
+       for (var a = arguments, i = 0, j = a.length, l = this.length; i < j; ++i)
+               this[l + i] = a[i];
+       return this.length;
+});
+Array.prototype.shift || (Array.prototype.shift = function () {
+       var r = this[0];
+       for(var i = 1, j = this.length; i < j; ++i)
+               this[i - 1] = this[i];
+       --this.length;
+       return r;
+});
+Array.prototype.unshift || (Array.prototype.unshift = function () {
+       var a = arguments, l = a.length, j = this.length += l - 1;
+       for (var i = j; i >= l; --i)
+               this[i] = this[i - l];
+       for (var i = 0; i < l; ++i)
+               this[i] = a[i];
+       return j;
+});
+Array.prototype.splice || (Array.prototype.splice = function (x, y) {
+       var a = arguments, s = a.length - 2 - y, r = this.slice(x, x + y);
+       if (s > 0) {
+               for (var i = this.length - 1, j = x + y; i >= j; --i)
+                       this[i + s] = this[i];
+       }
+       else if (s < 0) {
+               for (var i = x + y, j = this.length; i < j; ++i)
+                       this[i + s] = this[i];
+               this.length += s;
+       }
+       for (var i = 2, j = a.length; i < j; ++i)
+               this[i - 2 + x] = a[i];
+       return r;
+});
index f108ef9..125b159 100644 (file)
@@ -15,7 +15,7 @@ class ApplicationController < ActionController::Base
         @artist = if @author and @author.artist?
           @author.artist
         else
-          Artist.new author_id: @author.id, email: @user.email, name: @author.name, default_license_id: 1
+          Artist.new author_id: @author.id, email: @user.email, name: @author.name
         end
       end
     end
@@ -26,7 +26,7 @@ class ApplicationController < ActionController::Base
       true
     else
       respond_to do |format|
-        format.html { redirect_to new_artist_path, :status => :found }
+        format.html { redirect_to main_app.new_artist_path, :status => :found }
         format.js { render "artists/new" }
         format.json { 
           raise ActiveRecord::Forbidden
index ae96dd9..dec44ed 100644 (file)
@@ -56,6 +56,7 @@ layout 'test'
   # GET /artists/new.json
   def new
     @artist = Artist.new
+    @artist.supply_default 
 
     respond_to do |format|
       format.html # new.html.erb
@@ -66,14 +67,16 @@ layout 'test'
 
   # GET /artists/1/edit
   def edit
-    @artist = Artist.find(params[:id])
+    @artist = Artist.edit(params[:id], @author)
   end
 
   # POST /artists
   # POST /artists.json
   def create
-    @artist = Artist.new(params[:artist])
-    @artist.author_id = @author.id
+    @artist = Artist.new()
+    @artist.supply_default 
+    @artist.attributes = params[:artist]
+    @artist.overwrite @author
     respond_to do |format|
       if @artist.save
         format.html { redirect_to @artist, notice: 'Artist was successfully created.' }
@@ -88,10 +91,12 @@ layout 'test'
   # PUT /artists/1
   # PUT /artists/1.json
   def update
-    @artist = Artist.find(params[:id])
+    @artist = Artist.edit(params[:id], @author)
+    @artist.attributes = params[:artist]
+    @artist.overwrite @author
 
     respond_to do |format|
-      if @artist.update_attributes(params[:artist])
+      if @artist.save
         format.html { redirect_to @artist, notice: 'Artist was successfully updated.' }
         format.json { head :ok }
       else
@@ -104,7 +109,7 @@ layout 'test'
   # DELETE /artists/1
   # DELETE /artists/1.json
   def destroy
-    @artist = Artist.find(params[:id])
+    @artist = Artist.edit(params[:id], @author)
     @artist.destroy
 
     respond_to do |format|
diff --git a/app/controllers/colors_controller.rb b/app/controllers/colors_controller.rb
new file mode 100644 (file)
index 0000000..9a936ff
--- /dev/null
@@ -0,0 +1,16 @@
+class ColorsController < ApplicationController
+  layout 'test' if Pettanr::TestLayout
+  
+  # GET /colors
+  # GET /colors.json
+  def index
+    @page = PanelColor.page params[:page]
+    @page_size = PanelColor.page_size params[:page_size]
+    @colors = Color.list({}, @page, @page_size)
+
+    respond_to do |format|
+      format.html # index.html.erb
+      format.json { render json: @colors.to_json(Color.list_json_opt) }
+    end
+  end
+end
index ae1459d..4444e83 100644 (file)
@@ -7,14 +7,6 @@ class ComicsController < ApplicationController
   end
   before_filter :authenticate_admin!, :only => [:list, :browse]
 
-  private
-  
-  def treat_param comic
-    comic.author_id = @author.id
-  end
-  
-  public
-  
   def top
     @new_comics = Comic.find(:all, 
       :include => :author, :conditions => ['visible > 0'], :order => 'updated_at desc', :limit => 5
@@ -88,7 +80,7 @@ class ComicsController < ApplicationController
   # GET /comics/1/edit
   # GET /comics/1.js/edit
   def edit
-    @comic = Comic.show(params[:id], @author)
+    @comic = Comic.edit(params[:id], @author)
     @comic.supply_default
     respond_to do |format|
       format.html 
@@ -100,8 +92,10 @@ class ComicsController < ApplicationController
   # POST /comics.json
   def create
     params[:comic].merge! author_id: @author.id
-    @comic = Comic.new params[:comic]
+    @comic = Comic.new
     @comic.supply_default 
+    @comic.attributes = params[:comic]
+    @comic.overwrite @author
 
     respond_to do |format|
       if @comic.save
@@ -117,10 +111,11 @@ class ComicsController < ApplicationController
   # PUT /comics/1
   # PUT /comics/1.json
   def update
-    params[:comic].merge! author_id: @author.id
-    @comic = Comic.show(params[:id], @author)
+    @comic = Comic.edit(params[:id], @author)
+    @comic.attributes = params[:comic]
+    @comic.overwrite @author
     respond_to do |format|
-      if @comic.update_attributes(params[:comic])
+      if @comic.save
         format.html { redirect_to @comic, notice: 'Comic was successfully updated.' }
         format.json { head :ok }
       else
@@ -133,16 +128,11 @@ class ComicsController < ApplicationController
   # DELETE /comics/1
   # DELETE /comics/1.json
   def destroy
-    @comic = Comic.find(params[:id])
-    if @comic.own? @author
-      @comic.destroy
-      respond_to do |format|
-        format.html { redirect_to comics_url }
-        format.json { head :ok }
-      end
-    else
-      format.html { render action: "edit" }
-      format.json { render json: @comic.errors, status: :unprocessable_entity }
+    @comic = Comic.edit(params[:id], @author)
+    @comic.destroy
+    respond_to do |format|
+      format.html { redirect_to comics_url }
+      format.json { head :ok }
     end
   end
 end
diff --git a/app/controllers/ground_colors_controller.rb b/app/controllers/ground_colors_controller.rb
new file mode 100644 (file)
index 0000000..db1f252
--- /dev/null
@@ -0,0 +1,17 @@
+class GroundColorsController < ApplicationController
+  layout 'test' if Pettanr::TestLayout
+  before_filter :authenticate_user!, :only => [:index]
+
+  # GET /ground_colors
+  # GET /ground_colors.json
+  def index
+    @page = GroundColor.page params[:page]
+    @page_size = GroundColor.page_size params[:page_size]
+    @ground_colors = GroundColor.list({}, @page, @page_size)
+
+    respond_to do |format|
+      format.html # index.html.erb
+      format.json { render :json => @ground_colors.to_json(GroundColor.list_json_opt) }
+    end
+  end
+end
diff --git a/app/controllers/ground_pictures_controller.rb b/app/controllers/ground_pictures_controller.rb
new file mode 100644 (file)
index 0000000..28de171
--- /dev/null
@@ -0,0 +1,18 @@
+class GroundPicturesController < ApplicationController
+  layout 'test' if Pettanr::TestLayout
+  before_filter :authenticate_user!, :only => [:index]
+
+  # GET /ground_pictures
+  # GET /ground_pictures.json
+  def index
+    @page = GroundPicture.page params[:page]
+    @page_size = GroundPicture.page_size params[:page_size]
+    @ground_pictures = GroundPicture.list({}, @page, @page_size)
+
+    respond_to do |format|
+      format.html # index.html.erb
+      format.json { render :json => @ground_pictures.to_json(GroundPicture.list_json_opt) }
+    end
+  end
+
+end
index c211d86..eaa3a84 100644 (file)
@@ -1,9 +1,9 @@
 #原画
 class OriginalPicturesController < ApplicationController
   layout 'test' if Pettanr::TestLayout
-  before_filter :authenticate_user!, :only => [:index, :show, :new, :edit, :create, :update, :destroy]
+  before_filter :authenticate_user!, :only => [:index, :show, :history, :new, :edit, :create, :update, :destroy]
   before_filter :authenticate_admin!, :only => [:list, :browse]
-  before_filter :authenticate_artist, :only => [:index, :show, :new, :edit, :create, :update, :destroy]
+  before_filter :authenticate_artist, :only => [:index, :show, :history, :new, :edit, :create, :update, :destroy]
   
   private
   
@@ -49,6 +49,16 @@ class OriginalPicturesController < ApplicationController
     end
   end
 
+  def history
+    @original_picture = OriginalPicture.show(params[:id], @artist)
+    @history = @original_picture.history
+    
+    respond_to do |format|
+      format.html # index.html.erb
+      format.json { render json: @history.to_json }
+    end
+  end
+  
   def list
     @original_pictures = OriginalPicture.all
 
@@ -91,7 +101,7 @@ class OriginalPicturesController < ApplicationController
 
   # GET /original_pictures/1/edit
   def edit
-    @original_picture = OriginalPicture.show(params[:id], @author)
+    @original_picture = OriginalPicture.edit(params[:id], @author)
     respond_to do |format|
       format.html
       format.js
@@ -121,7 +131,6 @@ class OriginalPicturesController < ApplicationController
   def update
     @picture_data = set_image params[:original_picture][:file]
     @original_picture = OriginalPicture.edit(params[:id], @author)
-    @original_picture.supply_default @artist
 
     respond_to do |format|
       if @original_picture.store(@picture_data, @artist)
diff --git a/app/controllers/panel_colors_controller.rb b/app/controllers/panel_colors_controller.rb
new file mode 100644 (file)
index 0000000..c701e77
--- /dev/null
@@ -0,0 +1,18 @@
+class PanelColorsController < ApplicationController
+  layout 'test' if Pettanr::TestLayout
+  before_filter :authenticate_user!, :only => [:index]
+
+  # GET /ground_pictures
+  # GET /ground_pictures.json
+  def index
+    @page = PanelColor.page params[:page]
+    @page_size = PanelColor.page_size params[:page_size]
+    @panel_colors = PanelColor.list({}, @page, @page_size)
+
+    respond_to do |format|
+      format.html # index.html.erb
+      format.json { render :json => @panel_colors.to_json(PanelColor.list_json_opt) }
+    end
+  end
+
+end
index abae3f7..29390ce 100644 (file)
@@ -68,7 +68,7 @@ class PanelsController < ApplicationController
   end
 
   def edit
-    @panel = Panel.show(params[:id], @author)
+    @panel = Panel.edit(params[:id], @author)
     respond_to do |format|
       format.html
       format.js
@@ -131,20 +131,4 @@ class PanelsController < ApplicationController
     end
   end
   
-  def move
-    @panel = Panel.find(params[:id])
-    @new_seq = params[:panel][:t].to_i
-    respond_to do |format|
-      Panel.transaction do
-        if @panel.move_to(@new_t)
-          format.html { redirect_to @panel, notice: 'Panel was successfully moved.' }
-          format.json { head :ok }
-        else
-          format.html { render action: "show" }
-          format.json { render json: @panel.errors, status: :unprocessable_entity }
-        end
-      end
-    end
-  end
-  
 end
index 4661dbf..4ebe33a 100644 (file)
@@ -10,6 +10,7 @@ class PicturesController < ApplicationController
       format.png { send_data(@picture.restore(params[:subdir]), opt ) }
       format.gif { send_data(@picture.restore(params[:subdir]), opt ) }
       format.jpeg { send_data(@picture.restore(params[:subdir]), opt ) }
+      format.html 
       format.json { render :json => @picture.to_json}
     end
   end
index f2ee082..4f41dc1 100644 (file)
@@ -58,7 +58,7 @@ class StoriesController < ApplicationController
   # GET /stories/1/edit
   # GET /stories/1.js/edit
   def edit
-    @story = Story.show(params[:id], @author)
+    @story = Story.edit(params[:id], @author)
     respond_to do |format|
       format.html 
       format.js
diff --git a/app/helpers/colors_helper.rb b/app/helpers/colors_helper.rb
new file mode 100644 (file)
index 0000000..f74a8a7
--- /dev/null
@@ -0,0 +1,2 @@
+module ColorsHelper
+end
diff --git a/app/helpers/ground_colors_helper.rb b/app/helpers/ground_colors_helper.rb
new file mode 100644 (file)
index 0000000..99eb4ee
--- /dev/null
@@ -0,0 +1,2 @@
+module GroundColorsHelper
+end
diff --git a/app/helpers/ground_pictures_helper.rb b/app/helpers/ground_pictures_helper.rb
new file mode 100644 (file)
index 0000000..76df63c
--- /dev/null
@@ -0,0 +1,2 @@
+module GroundPicturesHelper
+end
diff --git a/app/helpers/panel_colors_helper.rb b/app/helpers/panel_colors_helper.rb
new file mode 100644 (file)
index 0000000..f554e63
--- /dev/null
@@ -0,0 +1,2 @@
+module PanelColorsHelper
+end
index db85188..093983a 100644 (file)
@@ -4,11 +4,27 @@ class Artist < ActiveRecord::Base
   
   validates :name, :presence => true, :length => {:maximum => 30}
 #  validates :default_license_id, :presence => true, :numericality => true, :existence => true
-  \r
+  
   def supply_default
     self.name = 'no name' if self.name.blank?
   end
   
+  def overwrite au
+    return false unless au
+    self.author_id = au.id
+  end
+  
+  def own? author
+    return false unless author
+    self.author_id == author.id
+  end
+  
+  def self.edit sid, au
+    res = Artist.find sid
+    raise ActiveRecord::Forbidden unless res.own?(au)
+    res
+  end
+  
   def self.find_by_author author
     Artist.find( :first, :conditions => ['author_id = ?', author.id])
   end
index 980da84..a6db5c2 100644 (file)
@@ -112,6 +112,51 @@ class Author < ActiveRecord::Base
     page_size
   end
   
+  def self.default_ground_picture_page_size
+    30
+  end
+  
+  def self.ground_picture_max_page_size
+    200
+  end
+  
+  def self.ground_picture_page_size prm = self.default_ground_picture_page_size
+    page_size = prm.to_i
+    page_size = self.ground_picture_max_page_size if page_size > self.ground_picture_max_page_size
+    page_size = self.default_ground_picture_page_size if page_size < 1
+    page_size
+  end
+  
+  def self.default_ground_color_page_size
+    30
+  end
+  
+  def self.ground_color_max_page_size
+    200
+  end
+  
+  def self.ground_color_page_size prm = self.default_ground_color_page_size
+    page_size = prm.to_i
+    page_size = self.ground_color_max_page_size if page_size > self.ground_color_max_page_size
+    page_size = self.default_ground_color_page_size if page_size < 1
+    page_size
+  end
+  
+  def self.default_panel_color_page_size
+    30
+  end
+  
+  def self.panel_color_max_page_size
+    200
+  end
+  
+  def self.panel_color_page_size prm = self.default_panel_color_page_size
+    page_size = prm.to_i
+    page_size = self.panel_color_max_page_size if page_size > self.panel_color_max_page_size
+    page_size = self.default_panel_color_page_size if page_size < 1
+    page_size
+  end
+  
   def self.show aid, opt = {}
     a = Author.find(aid, :include => self.show_include_opt(opt))
 #    raise ActiveRecord::Forbidden unless c.visible?(au)
diff --git a/app/models/color.rb b/app/models/color.rb
new file mode 100644 (file)
index 0000000..d09ae2c
--- /dev/null
@@ -0,0 +1,61 @@
+class Color < ActiveRecord::Base
+  belongs_to :ground_color
+
+  validates :name, :presence => true, :length => {:maximum => 50}, :uniqueness => true
+  validates :code, :presence => true, :numericality => {:greater_than_or_equal_to => 0, :less_than => 0x1000000}
+  validates :t, :presence => true, :numericality => {:greater_than_or_equal_to => 0}
+  
+  def self.import filename
+    Color.import_file(filename) {|name, attr| Color.store(name, attr)}
+  end
+  
+  def self.store name, attr
+    r = Color.modify_object name, attr
+    r.save
+    r
+  end
+  
+  def self.default_page_size
+    25
+  end
+  
+  def self.max_page_size
+    100
+  end
+  
+  def self.default_panel_size
+    30
+  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 opt = {}, page = 1, page_size = self.default_page_size
+    opt.merge!({:order => 'colors.t', :limit => page_size, :offset => (page -1) * page_size})
+    Color.find(:all, opt)
+  end
+  
+  def self.list_opt
+    {:include => {:ground_color => {:panel => {:author => {}}} }}
+  end
+  
+  def self.list_json_opt
+    {:include => {:ground_color => {:panel => {:author => {}}} }}
+  end
+  
+  def self.show cid
+    c = Color.find(cid)
+    c
+  end
+  
+end
index 13ef9c7..6a1e92b 100644 (file)
@@ -4,8 +4,6 @@ class Comic < ActiveRecord::Base
   belongs_to :author
   
   validates :title, :presence => true, :length => {:maximum => 100}
-  validates :width, :presence => true, :numericality => true, :natural_number => true
-  validates :height, :presence => true, :numericality => true, :natural_number => true
   validates :visible, :presence => true, :numericality => true, :inclusion => {:in => 0..3}
   
   before_save do |r|
@@ -16,6 +14,11 @@ class Comic < ActiveRecord::Base
     self.visible = 0 if self.visible.blank?
   end
   
+  def overwrite au
+    return false unless au
+    self.author_id = au.id
+  end
+  
   def own? author
     return false unless author
     self.author_id == author.id
@@ -84,6 +87,12 @@ class Comic < ActiveRecord::Base
     c
   end
   
+  def self.edit cid, au, opt = {}
+    c = Comic.find(cid, :include => self.show_include_opt(opt))
+    raise ActiveRecord::Forbidden unless c.own?(au)
+    c
+  end
+  
   def self.show_include_opt opt = {}
     res = {:stories => {:panel => {}}, :author => {}}
     res.push(opt[:include]) if opt[:include]
diff --git a/app/models/ground_color.rb b/app/models/ground_color.rb
new file mode 100644 (file)
index 0000000..c8af47e
--- /dev/null
@@ -0,0 +1,58 @@
+class GroundColor < ActiveRecord::Base
+  belongs_to :panel
+  belongs_to :color
+  
+  validates :panel_id, :numericality => {:allow_blank => true}
+  validates :color_id, :numericality => true, :existence => true
+  validates :z, :presence => true, :numericality => {:greater_than => 0}
+  
+  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.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.list opt = {}, page = 1, page_size = self.default_page_size
+    opt.merge!(self.list_opt) unless opt[:include]
+    opt.merge!({:conditions => 'panels.publish > 0', :order => 'ground_colors.updated_at desc', :limit => page_size, :offset => (page -1) * page_size})
+    GroundColor.find(:all, opt)
+  end
+  
+  def self.list_opt
+    {:include => {:panel => {:author => {}}, :color => {} }}
+  end
+  
+  def self.list_json_opt
+    {:include => {:panel => {:author => {}}, :color => {} }}
+  end
+  
+  def self.mylist au, opt = {}, page = 1, ground_color_page_size = Author.default_ground_color_page_size
+    opt.merge!(self.list_opt) unless opt[:include]
+    opt.merge!({:conditions => ['panels.author_id = ?', au.id], :order => 'ground_colors.updated_at desc', :limit => page_size, :offset => (page -1) * ground_color_page_size})
+    GroundColor.find(:all, opt)
+  end
+  
+end
diff --git a/app/models/ground_picture.rb b/app/models/ground_picture.rb
new file mode 100644 (file)
index 0000000..207b208
--- /dev/null
@@ -0,0 +1,58 @@
+class GroundPicture < ActiveRecord::Base
+  belongs_to :panel
+  belongs_to :picture
+  
+  validates :panel_id, :numericality => {:allow_blank => true}
+  validates :picture_id, :numericality => true, :existence => true
+  validates :z, :presence => true, :numericality => {:greater_than => 0}
+  
+  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.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.list opt = {}, page = 1, page_size = self.default_page_size
+    opt.merge!(self.list_opt) unless opt[:include]
+    opt.merge!({:conditions => 'panels.publish > 0', :order => 'ground_pictures.updated_at desc', :limit => page_size, :offset => (page -1) * page_size})
+    GroundPicture.find(:all, opt)
+  end
+  
+  def self.list_opt
+    {:include => {:panel => {:author => {}}, :picture => {:artist => {}, :license => {}}}}
+  end
+  
+  def self.list_json_opt
+    {:include => {:panel => {:author => {}}, :picture => {:artist => {}, :license => {}}}}
+  end
+  
+  def self.mylist au, opt = {}, page = 1, ground_picture_page_size = Author.default_ground_picture_page_size
+    opt.merge!(self.list_opt) unless opt[:include]
+    opt.merge!({:conditions => ['panels.author_id = ?', au.id], :order => 'ground_pictures.updated_at desc', :limit => page_size, :offset => (page -1) * ground_picture_page_size})
+    GroundPicture.find(:all, opt)
+  end
+  
+end
index fa67c7b..7d7f13d 100644 (file)
@@ -55,4 +55,15 @@ class LicenseGroup < ActiveRecord::Base
     {:include => {:licenses => {}}}
   end
   
+  def self.disp_import_error r
+    if r == false
+      puts "json file error. file does not exist or broken"
+    else
+      unless r.empty?
+        r.each do |lg|
+          put lg.errors.full_messages
+        end
+      end
+    end
+  end
 end
index a2606bf..497fa64 100644 (file)
@@ -2,18 +2,25 @@ class OriginalPicture < ActiveRecord::Base
   belongs_to :artist
   belongs_to :original_picture_license_group
   has_one :resource_picture
+  has_many :pictures
   
-  validates :ext, :presence => true, :length => {:maximum => 4}, :inclusion => {:in => ['png', 'jpeg', 'gif']}\r
+  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 :artist_id, :presence => true, :numericality => true, :existence => true
+  validates :md5, :presence => true, :length => {:maximum => 32}
   
   before_destroy :destroy_with_file
   
   def supply_default art
   end
   
+  def overwrite art
+    return false unless art
+    self.artist_id = art.id
+  end
+  
   def self.default_page_size
     25
   end
@@ -43,34 +50,36 @@ class OriginalPicture < ActiveRecord::Base
     OriginalPicture.find(:all, opt)
   end
   
+  def history 
+    Picture.find(:all, {:conditions => ['pictures.original_picture_id = ?', self.id], :order => 'pictures.revision desc'} )
+  end
+  
   def self.list_opt
-    {:include => {:resource_picture => {}}}
+    {:include => {:resource_picture => {}, :pictures => {}}}
   end
   
   def self.list_json_opt
-    {:include => {:resource_picture => {}}}
+    {:include => {:resource_picture => {}, :pictures => {}}}
   end
   
   def self.show cid, artist, opt = {}
-    pic = OriginalPicture.find(cid, :include => self.show_include_opt(opt))
+    pic = OriginalPicture.find(cid, self.show_include_opt)
     raise ActiveRecord::Forbidden unless pic.own?(artist)
     pic
   end
   
   def self.edit cid, artist, opt = {}
-    pic = OriginalPicture.find(cid, :include => self.show_include_opt(opt))
+    pic = OriginalPicture.find(cid, self.show_include_opt)
     raise ActiveRecord::Forbidden unless pic.own?(artist)
     pic
   end
   
-  def self.show_include_opt opt = {}
-    res = {:resource_picture => {}}
-    res.merge!(opt[:include]) if opt[:include]
-    res
+  def self.show_include_opt
+    {:include => {:resource_picture => {}, :pictures => {}}}
   end
   
   def self.show_json_include_opt
-    {:include => {:resource_picture => {}}}
+    {:include => {:resource_picture => {}, :pictures => {}}}
   end
   
   def destroy_with_file
@@ -94,6 +103,11 @@ class OriginalPicture < ActiveRecord::Base
     '/original_pictures/' + filename
   end
   
+  def opt_img_tag
+    tw, th = ResourcePicture.fix_size_both(MagicNumber['thumbnail_width'], MagicNumber['thumbnail_height'], self.width, self.height)
+    {:src => self.url, :width => tw, :height => th}
+  end
+  
   def data_to_mgk picture_data
     begin
       mgk = Magick::Image.from_blob(picture_data).shift
@@ -111,6 +125,8 @@ class OriginalPicture < ActiveRecord::Base
     self.attributes = {:ext => mgk.format.downcase, :width => mgk.columns, :height => mgk.rows, 
       :filesize => mgk.filesize, :artist_id => art.id
     }
+    self.md5 = Digest::MD5.hexdigest(picture_data)
+    self.overwrite art
     OriginalPicture.transaction do
       if res = self.save
         if res = PictureIO.original_picture_io.put(picture_data, self.filename)
index 4328e91..db740ff 100644 (file)
@@ -2,12 +2,17 @@
 class Panel < ActiveRecord::Base
   belongs_to :author
   belongs_to :resource_picture
-#  belongs_to :background_picture, :class_name => 'ResourcePicture'
   has_many :stories
   has_many :panel_pictures, :dependent => :destroy
   has_many :speech_balloons, :dependent => :destroy
+  has_many :ground_pictures, :dependent => :destroy
+  has_many :ground_colors, :dependent => :destroy
+  has_many :panel_colors, :dependent => :destroy
   accepts_nested_attributes_for :panel_pictures, :allow_destroy => true
   accepts_nested_attributes_for :speech_balloons, :allow_destroy => true
+  accepts_nested_attributes_for :ground_pictures, :allow_destroy => true
+  accepts_nested_attributes_for :ground_colors, :allow_destroy => true
+  accepts_nested_attributes_for :panel_colors, :allow_destroy => true
 
   validates :width, :presence => true, :numericality => true, :natural_number => true
   validates :height, :presence => true, :numericality => true, :natural_number => true
@@ -144,6 +149,14 @@ class Panel < ActiveRecord::Base
         :picture => {:artist => {}, :license => {}}
       }, 
       :speech_balloons => {:balloons => {}, :speeches => {}},
+      :ground_pictures => {
+        :picture => {:artist => {}, :license => {}}
+      }, 
+      :ground_colors => {
+        :color => {}
+      }, 
+      :panel_colors => {
+      }, 
       :author => {}
     }}
   end
@@ -154,6 +167,14 @@ class Panel < ActiveRecord::Base
         :picture => {:artist => {}, :license => {}}
       }, 
       :speech_balloons => {:balloons => {}, :speeches => {}},
+      :ground_pictures => {
+        :picture => {:artist => {}, :license => {}}
+      }, 
+      :ground_colors => {
+        :color => {}
+      }, 
+      :panel_colors => {
+      }, 
       :author => {}
     }}
   end
@@ -182,6 +203,14 @@ class Panel < ActiveRecord::Base
         :picture => {:artist => {}, :license => {}}
       }, 
       :speech_balloons => {:balloons => {}, :speeches => {}},
+      :ground_pictures => {
+        :picture => {:artist => {}, :license => {}}
+      }, 
+      :ground_colors => {
+        :color => {}
+      }, 
+      :panel_colors => {
+      }, 
       :author => {}
     }
     res.merge!(opt[:include]) if opt[:include]
@@ -194,6 +223,14 @@ class Panel < ActiveRecord::Base
         :picture => {:artist => {}, :license => {}}
       }, 
       :speech_balloons => {:balloons => {}, :speeches => {}},
+      :ground_pictures => {
+        :picture => {:artist => {}, :license => {}}
+      }, 
+      :ground_colors => {
+        :color => {}
+      }, 
+      :panel_colors => {
+      }, 
       :author => {}
     }}
   end
@@ -227,6 +264,12 @@ class Panel < ActiveRecord::Base
     pe
   end
   
+  def each_ground
+    (self.ground_colors || []) + (self.ground_pictures || []) + (self.panel_colors || []).each do |e|
+      yield e
+    end
+  end
+  
   def each_element
     self.sort_by_time.each do |e|
       yield e
@@ -237,12 +280,23 @@ class Panel < ActiveRecord::Base
     res = []
     self.each_element do |elm|
       if elm.kind_of?(PanelPicture)
-        res[elm.t] = elm.to_json({:include => :resource_picture})
+        res[elm.t] = elm.to_json({:include => {:picture => {:artist => {}, :license => {}}}})
       end
       if elm.kind_of?(SpeechBalloon)
         res[elm.t] = elm.to_json({:include => {:balloons => {}, :speeches => {}}})
       end
     end
+    self.each_ground do |elm|
+      if elm.kind_of?(GroundColor)
+        res <<  elm.to_json({:include => :color})
+      end
+      if elm.kind_of?(GroundPicture)
+        res << elm.to_json({:include => {:picture => {:artist => {}, :license => {}}}})
+      end
+      if elm.kind_of?(PanelColor)
+        res << elm.to_json({:include => {}})
+      end
+    end
     res
   end
   
diff --git a/app/models/panel_color.rb b/app/models/panel_color.rb
new file mode 100644 (file)
index 0000000..820a541
--- /dev/null
@@ -0,0 +1,57 @@
+class PanelColor < ActiveRecord::Base
+  belongs_to :panel
+  
+  validates :panel_id, :numericality => {:allow_blank => true}
+  validates :z, :presence => true, :numericality => {:greater_than => 0}
+  validates :code, :presence => true, :numericality => {:greater_than_or_equal_to => 0, :less_than => 0x1000000}
+  
+  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.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.list opt = {}, page = 1, page_size = self.default_page_size
+    opt.merge!(self.list_opt) unless opt[:include]
+    opt.merge!({:conditions => 'panels.publish > 0', :order => 'panel_colors.updated_at desc', :limit => page_size, :offset => (page -1) * page_size})
+    PanelColor.find(:all, opt)
+  end
+  
+  def self.list_opt
+    {:include => {:panel => {:author => {}} }}
+  end
+  
+  def self.list_json_opt
+    {:include => {:panel => {:author => {}} }}
+  end
+  
+  def self.mylist au, opt = {}, page = 1, panel_color_page_size = Author.default_panel_color_page_size
+    opt.merge!(self.list_opt) unless opt[:include]
+    opt.merge!({:conditions => ['panels.author_id = ?', au.id], :order => 'panel_colors.updated_at desc', :limit => page_size, :offset => (page -1) * panel_color_page_size})
+    PanelColor.find(:all, opt)
+  end
+  
+end
index a26e0a2..afbe97f 100644 (file)
@@ -3,6 +3,7 @@ class PanelPicture < ActiveRecord::Base
   belongs_to :picture
   
   validates :panel_id, :numericality => {:allow_blank => true}
+  validates :picture_id, :numericality => true, :existence => true
   validates :link, :length => {:maximum => 200}
   validates :x, :presence => true, :numericality => true
   validates :y, :presence => true, :numericality => true
index 1c1ff83..38305a1 100644 (file)
@@ -11,6 +11,7 @@ class Picture < ActiveRecord::Base
   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 :md5, :presence => true, :length => {:maximum => 32}
   validates :license_id, :presence => true, :numericality => true, :existence => true
   validates :artist_id, :presence => true, :numericality => true, :existence => true
   validates :artist_name, :presence => true
@@ -32,6 +33,27 @@ class Picture < ActiveRecord::Base
     "image/#{self.dext}"
   end
   
+  def dext
+    self.ext.downcase
+  end
+  
+  def url
+    '/pictures/' + filename
+  end
+  
+  def self.list_by_md5 md5, opid
+    r = Picture.find :all, :conditions => ['pictures.md5 = ? and pictures.original_picture_id <> ?', md5, opid], :order => 'pictures.updated_at desc'
+  end
+  
+  def self.exist_by_md5 md5, opid
+    Picture.list_by_md5(md5, opid).empty? ? false : true
+  end
+  
+  def head?
+    r = self.resource_picture
+    r ? true : false
+  end
+  
   def new_revision
     Picture.maximum(:revision, :conditions => ['original_picture_id = ?', self.original_picture_id]).to_i + 1
   end
@@ -71,7 +93,7 @@ class Picture < ActiveRecord::Base
   def copy_data(rp)
     attr = {:width => rp.width, :height => rp.height, :ext => rp.ext, :filesize => rp.filesize, 
       :original_picture_id => rp.original_picture_id, :license_id => rp.license_id, :artist_id => rp.artist_id, 
-      :artist_name => rp.artist_name, :classname => rp.classname, :credit => rp.credit, :settings => rp.settings
+      :md5 => rp.md5, :artist_name => rp.artist_name, :classname => rp.classname, :credit => rp.credit, :settings => rp.settings
     }
     self.attributes = attr
   end
@@ -104,7 +126,7 @@ class Picture < ActiveRecord::Base
   end
   
   def restore(subdir = nil)
-    PictureIO.resource_picture_io.get self.filename, subdir
+    PictureIO.picture_io.get self.filename, subdir
   end
   
   def self.show pid
index 5e1b4f7..9c1514f 100644 (file)
@@ -78,9 +78,14 @@ class ResourcePicture < ActiveRecord::Base
     ResourcePicture.resize(rimg.to_blob, tw, th).to_blob
   end
   
+  def opt_img_tag
+    tw, th = ResourcePicture.fix_size_both(MagicNumber['thumbnail_width'], MagicNumber['thumbnail_height'], self.width, self.height)
+    {:src => self.url, :width => tw, :height => th}
+  end
+  
   def copy_data(op)
     attr = {:width => op.width, :height => op.height, :ext => op.ext, :filesize => op.filesize, 
-      :original_picture_id => op.id, :artist_id => op.artist_id
+      :original_picture_id => op.id, :artist_id => op.artist_id, :md5 => op.md5
     }
     self.attributes = attr
   end
index a2dea47..ccfe6af 100644 (file)
@@ -48,7 +48,7 @@ class SystemPicture < ActiveRecord::Base
     self.attributes = {:ext => mgk.format.downcase, :width => mgk.columns, :height => mgk.rows, 
       :filesize => mgk.filesize
     }
-    self.md5 = Digest::MD5.hexdigest(picture_data) unless self.md5
+    self.md5 = Digest::MD5.hexdigest(picture_data)
     SystemPicture.transaction do
       if res = self.save
         res = PictureIO.system_picture_io.put(picture_data, self.filename)
index 5a0690b..b91ef8a 100644 (file)
@@ -18,8 +18,6 @@
     <%= f.label :name %><br />
     <%= f.text_field :name %><br />
 
-    <%= f.label :default_license_id %><br />
-    <%= f.number_field :default_license_id %>
   </div>
   <div class="actions">
     <%= f.submit %>
index dcb90be..de4e1df 100644 (file)
@@ -7,7 +7,6 @@
     <th>name</th>
     <th>homepage_url</th>
     <th>api_url</th>
-    <th>default_license</th>
     <th>crowled_at</th>
     <th>author_id</th>
     <th>created_at</th>
@@ -21,7 +20,6 @@
     <td><%= h artist.name %></td>
     <td><%= h artist.homepage_url %></td>
     <td><%= h artist.api_url %></td>
-    <td><%= link_to artist.default_license_id, :controller => 'licenses', :action => :browse, :id => artist.default_license_id %></td>
     <td><%= artist.crowled_at %></td>
     <td><%= link_to artist.author_id, :controller => 'authors', :action => :browse, :id => artist.author_id %></td>
     <td><%= artist.created_at %></td>
diff --git a/app/views/colors/index.html.erb b/app/views/colors/index.html.erb
new file mode 100644 (file)
index 0000000..907e97f
--- /dev/null
@@ -0,0 +1,19 @@
+<h1>Listing Colors</h1>
+
+<table>
+  <tr>
+    <th>id</th>
+    <th>name</th>
+    <th>code</th>
+    <th>t</th>
+  </tr>
+
+<% @colors.each do |c| %>
+  <tr>
+    <td><%= c.id %></td>
+    <td><%= h c.name %></td>
+    <td><%= c.code %><font color="<%= c.code %>">*****</font></td>
+    <td><%= c.t %></td>
+  </tr>
+<% end -%>
+</table>
index c8e1fb6..21a7d4f 100644 (file)
     <%= f.text_field :title %>
   </div>
   <div class="field">
-    <%= f.label :width %><br />
-    <%= f.number_field :width %>
-  </div>
-  <div class="field">
-    <%= f.label :height %><br />
-    <%= f.number_field :height %>
-  </div>
-  <div class="field">
     <%= f.label :visible %><br />
     <%= f.collection_select :visible, [['only me', 0], ['everyone', 3]], :last, :first, :html => {:selected => @comic.visible} %>
   </div>
index c9861b9..6e781df 100644 (file)
@@ -6,16 +6,6 @@
 </p>
 
 <p>
-  <b>width:</b>
-  <%= @comic.width %>
-</p>
-
-<p>
-  <b>height:</b>
-  <%= @comic.height %>
-</p>
-
-<p>
   <b>visible:</b>
   <%= @comic.visible %>
 </p>
index 189ada4..f7b7e62 100644 (file)
@@ -4,8 +4,6 @@
   <tr>
     <th>id</th>
     <th>Title</th>
-    <th>width</th>
-    <th>height</th>
     <th>visible</th>
     <th>author_id</th>
     <th>created_at</th>
@@ -17,8 +15,6 @@
   <tr>
     <td><%= link_to comic.id, :action => :browse, :id => comic.id %></td>
     <td><%= h comic.title %></td>
-    <td><%= comic.width %></td>
-    <td><%= comic.height %></td>
     <td><%= comic.visible %></td>
     <td><%= link_to comic.author_id, :controller => '/authors', :action => :browse, :id => comic.author_id %></td>
     <td><%= comic.created_at %></td>
index f77abc2..1515429 100644 (file)
@@ -6,16 +6,6 @@
 </p>
 
 <p>
-  <b>width:</b>
-  <%= @comic.width %>
-</p>
-
-<p>
-  <b>height:</b>
-  <%= @comic.height %>
-</p>
-
-<p>
   <b>visible:</b>
   <%= @comic.visible %>
 </p>
diff --git a/app/views/ground_colors/index.html.erb b/app/views/ground_colors/index.html.erb
new file mode 100644 (file)
index 0000000..fed3158
--- /dev/null
@@ -0,0 +1,19 @@
+<h1>Listing Ground Colors</h1>
+
+<table>
+  <tr>
+    <th>id</th>
+    <th>panel_id</th>
+    <th>color_id</th>
+    <th>z</th>
+  </tr>
+
+<% @ground_colors.each do |gc| %>
+  <tr>
+    <td><%= gc.id %></td>
+    <td><%= link_to gc.panel_id, panel_path(gc.panel_id) %></td>
+    <td><%= link_to gc.color_id, color_path(gc.color_id) %></td>
+    <td><%= gc.z %></td>
+  </tr>
+<% end -%>
+</table>
diff --git a/app/views/ground_pictures/index.html.erb b/app/views/ground_pictures/index.html.erb
new file mode 100644 (file)
index 0000000..32f741c
--- /dev/null
@@ -0,0 +1,19 @@
+<h1>Listing Ground Pictures</h1>
+
+<table>
+  <tr>
+    <th>id</th>
+    <th>panel_id</th>
+    <th>picture_id</th>
+    <th>z</th>
+  </tr>
+
+<% @ground_pictures.each do |gp| %>
+  <tr>
+    <td><%= gp.id %></td>
+    <td><%= link_to gp.panel_id, panel_path(gp.panel_id) %></td>
+    <td><%= link_to gp.picture_id, color_path(gp.picture_id) %></td>
+    <td><%= gp.z %></td>
+  </tr>
+<% end -%>
+</table>
index 9c1941c..bc604f0 100644 (file)
@@ -19,9 +19,6 @@
       <%= f.label :name %><br />
       <%= f.text_field :name %><br />
 
-      <p>素材をアップロードするときのデフォルトライセンスを選択します。</p>
-      <%= f.label :default_license_id %><br />
-      <%= f.select :default_license_id, License.all.map {|l| [l.name, l.id] }, :html => {:selected => @artist.default_license_id} %>
       <%= f.hidden_field :author_id, :value => @artist.author_id %>
     </div>
     <div class="actions">
index 9cb2930..97ced9d 100644 (file)
@@ -3,7 +3,7 @@
 <head>
   <title>Pettanr</title>
   <%= stylesheet_link_tag    "application" %>
-  <%# javascript_include_tag "application" %>
+  <%= javascript_include_tag "application" %>
   <%= csrf_meta_tags %>
 </head>
 <body>
index 0c1a06e..ff14561 100644 (file)
@@ -3,6 +3,7 @@
 <head>\r
   <title>Pettanr</title>\r
   <%= stylesheet_link_tag    "application" %>\r
+  <%= javascript_include_tag "application" %>\r
   <%= csrf_meta_tags %>\r
 </head>\r
 <body>\r
@@ -36,6 +37,7 @@
 <%= link_to 'speeches', main_app.speeches_path %>\r
  : \r
 <%= link_to 'speech_balloon_templates', main_app.speech_balloon_templates_path %>\r
+<%= link_to 'colors', main_app.colors_path %>\r
  : \r
 <%= link_to 'artists', main_app.artists_path %>\r
 <%= link_to 'system_pictures', main_app.system_pictures_path %>\r
index c07140c..4fc4445 100644 (file)
@@ -18,8 +18,6 @@
     <%= f.label :name %><br />
     <%= f.text_field :name %><br />
 
-    <%= f.label :default_license_id %><br />
-    <%= f.number_field :default_license_id %>
     <%= f.hidden_field :author_id, :value => @artist.author_id %>
   </div>
   <div class="actions">
diff --git a/app/views/original_pictures/_exist.html.erb b/app/views/original_pictures/_exist.html.erb
new file mode 100644 (file)
index 0000000..8129f4f
--- /dev/null
@@ -0,0 +1,4 @@
+<% case exist -%>
+<% when true -%>
+  この画像は既に公開されています
+<% end -%>
diff --git a/app/views/original_pictures/_history_list.html.erb b/app/views/original_pictures/_history_list.html.erb
new file mode 100644 (file)
index 0000000..8fd4c22
--- /dev/null
@@ -0,0 +1,6 @@
+<% history.each do |picture| -%>
+  <h3>revision:<%= picture.revision %></h3>
+  <div>licensed at <%= picture.created_at %></div>
+  <img src="<%= picture.url -%>">
+  <%= render picture.credit_template, :picture => picture %>
+<% end -%>
index 9142c7d..03ea484 100644 (file)
   <%= @original_picture.artist_id %>
 </p>
 
+<p>
+  <b>md5:</b>
+  <%= @original_picture.md5 %>
+</p>
+
 <img src="<%= @original_picture.url -%>">
 
 <p>
 <a href="<%= @original_picture.url %>">browse picture</a> 
 </p>
-<p>
-<%= link_to '再生成', :action => :refresh, :id => @original_picture.id %>
-</p>
 <% if @original_picture.own? @author -%>
 <p>
 Replace picture
diff --git a/app/views/original_pictures/history.html.erb b/app/views/original_pictures/history.html.erb
new file mode 100644 (file)
index 0000000..4a1396a
--- /dev/null
@@ -0,0 +1,2 @@
+History of Original Picture <%= @original_picture.id %>
+<%= render 'history_list', :history => @history %>
index 8411ea1..0089f09 100644 (file)
@@ -4,22 +4,28 @@
 <table>
   <tr>
     <th>picture</th>
+    <th>revisions</th>
     <th>filename</th>
     <th>Width</th>
     <th>Height</th>
     <th>filesize</th>
+    <th>md5</th>
+    <th>history</th>
   </tr>
 <% @original_pictures.each do |original_picture| %>
   <div>
   </div>
   <tr>
     <td>
-      <%= link_to tag(:img, :src => original_picture.url, :width => 50, :height => 50), original_picture %>
+      <%= link_to tag(:img, original_picture.opt_img_tag), original_picture %>
     </td>
+    <td><%= original_picture.pictures.empty? ? '' : original_picture.history.first.revision %></td>
     <td><%= original_picture.filename %></td>
     <td><%= original_picture.width %></td>
     <td><%= original_picture.height %></td>
     <td><%= original_picture.filesize %></td>
+    <td><%= original_picture.md5 %></td>
+    <td><%= link_to '...', :controller => 'original_pictures', :action => :history, :id => original_picture.id %></td>
   </tr>
 <% end %>
 </table>
index 0727ed1..f9a69df 100644 (file)
@@ -9,6 +9,7 @@
     <th>Height</th>
     <th>filesize</th>
     <th>artist</th>
+    <th>md5</th>
     <th>created_at</th>
     <th>updated_at</th>
     <th></th>
@@ -22,6 +23,7 @@
     <td><%= original_picture.height %></td>
     <td><%= original_picture.filesize %></td>
     <td><%= link_to original_picture.artist_id, :controller => 'artists', :action => :browse, :id => original_picture.artist_id %></td>
+    <td><%= original_picture.md5 %></td>
     <td><%= original_picture.created_at %></td>
     <td><%= original_picture.updated_at %></td>
     <td>
index 5d32979..89ce57c 100644 (file)
@@ -1,3 +1,4 @@
+<%= render 'exist', :exist => Picture.exist_by_md5(@original_picture.md5, @original_picture.id) %>
 <p id="notice"><%= notice %></p>
 
 <p>
 </p>
 
 <p>
+  <b>md5:</b>
+  <%= @original_picture.md5 %>
+</p>
+
+<p>
   <b>artist:</b>
   <%= @original_picture.artist_id %>
 </p>
@@ -45,5 +51,11 @@ Replace picture
     <%= f.submit 'replace' %>
   </div>
 <% end %>
+<div>
+  <p>
+    History
+  </p>
+  <%= render 'history_list', :history => @original_picture.history %>
+</div>
 
 <%= link_to 'Back', original_pictures_path %>
diff --git a/app/views/panel_colors/index.html.erb b/app/views/panel_colors/index.html.erb
new file mode 100644 (file)
index 0000000..e6a9fa2
--- /dev/null
@@ -0,0 +1,19 @@
+<h1>Listing Panel Colors</h1>
+
+<table>
+  <tr>
+    <th>id</th>
+    <th>panel_id</th>
+    <th>code</th>
+    <th>z</th>
+  </tr>
+
+<% @panel_colors.each do |pc| %>
+  <tr>
+    <td><%= pc.id %></td>
+    <td><%= link_to pc.panel_id, panel_path(pc.panel_id) %></td>
+    <td><%= pc.code %><font color="<%= pc.code %>">*****</font></td>
+    <td><%= pc.z %></td>
+  </tr>
+<% end -%>
+</table>
diff --git a/app/views/pictures/_head.html.erb b/app/views/pictures/_head.html.erb
new file mode 100644 (file)
index 0000000..ac14f8f
--- /dev/null
@@ -0,0 +1,3 @@
+<img src="<%= picture.url -%>">
+<%= render picture.credit_template, :picture => picture %>
+<div>revision:<%= picture.revision %></div>
diff --git a/app/views/pictures/_tail.html.erb b/app/views/pictures/_tail.html.erb
new file mode 100644 (file)
index 0000000..d080031
--- /dev/null
@@ -0,0 +1,2 @@
+この画像は既に改訂されています <%= link_to 'Head', resource_picture_path(picture.resource_picture ) %>
+<div>revision:<%= picture.revision %></div>
diff --git a/app/views/pictures/show.html.erb b/app/views/pictures/show.html.erb
new file mode 100644 (file)
index 0000000..952542a
--- /dev/null
@@ -0,0 +1,36 @@
+<p>
+  <b>Ext:</b>
+  <%= @original_picture.ext %>
+</p>
+
+<p>
+  <b>Width:</b>
+  <%= @original_picture.width %>
+</p>
+
+<p>
+  <b>Height:</b>
+  <%= @original_picture.height %>
+</p>
+
+<p>
+  <b>filesize:</b>
+  <%= @original_picture.filesize %>
+</p>
+
+<p>
+  <b>md5:</b>
+  <%= @original_picture.md5 %>
+</p>
+
+<p>
+  <b>artist:</b>
+  <%= @original_picture.artist_id %>
+</p>
+
+<% if @picture.head? %>
+  <%= render 'head', :picture => @picture %>
+<% else %>
+  <%= render 'tail', :picture => @picture %>
+<% end %>
+
index 76defae..71e7566 100644 (file)
@@ -3,7 +3,7 @@
   <% @resource_picture = resource_picture %>
   <div>
     <%= link_to resource_picture.filename, resource_picture_path(resource_picture) %>
-    <%= tag :img, :src => resource_picture.url, :width => MagicNumber['thumbnail_width'], :height => MagicNumber['thumbnail_height'] %>
+    <%= tag :img, resource_picture.opt_img_tag %>
     <%= resource_picture.width %>x<%= resource_picture.height %>
     <%= resource_picture.filesize %>bytes
     <%= render resource_picture.credit_template, :picture => resource_picture %>
index 0839b2d..6827972 100644 (file)
@@ -1,11 +1,3 @@
 <p id="notice"><%= notice %></p>
-<%= render @resource_picture.credit_template, :picture => @resource_picture %>
-<p>
-  <a href="<%= @resource_picture.url %>">ノーマル</a> 
-  <img src="<%= @resource_picture.url -%>">
-</p>
-<p>
-  <a href="<%= @resource_picture.url :thumbnail%>">サムネ</a> 
-  <img src="<%= @resource_picture.url :full -%>">
-</p>
+  <%= render 'pictures/head', :picture => @resource_picture.picture %>
 <%= link_to 'Back', resource_pictures_path %>
index d8c3075..e857e0d 100644 (file)
       <%= link_to 'speeches', :controller => 'speeches', :action => :list %>
     </td>
   </tr>
+  <tr>
+    <td>
+      <%= link_to 'colors', :controller => 'colors' %>
+    </td>
+  </tr>
 </table>
 フキダシテンプレート関連
 <table>
index a32bd2f..aa0ff2e 100644 (file)
@@ -1,10 +1,6 @@
 # Load the rails application
 require File.expand_path('../application', __FILE__)
-begin
-  require 'RMagick'
-rescue LoadError
-  require 'DMagick'
-end
+require 'RMagick'
 
 # Initialize the rails application
 Pettanr::Application.initialize!
index bcdc270..6a1e38c 100644 (file)
@@ -109,6 +109,7 @@ Pettanr::Application.routes.draw do
     collection do
       get :index
       get :show
+      get :history
       post :create
       get :list
       get :browse
@@ -127,6 +128,34 @@ Pettanr::Application.routes.draw do
       post :create
     end
   end
+  resources :colors do
+    collection do
+      get :index
+    end
+    member do
+    end
+  end
+  resources :panel_colors do
+    collection do
+      get :index
+    end
+    member do
+    end
+  end
+  resources :ground_colors do
+    collection do
+      get :index
+    end
+    member do
+    end
+  end
+  resources :ground_pictures do
+    collection do
+      get :index
+    end
+    member do
+    end
+  end
   resources :panels do
     new do
       get :new
diff --git a/db/colors.json b/db/colors.json
new file mode 100644 (file)
index 0000000..fba582f
--- /dev/null
@@ -0,0 +1,10 @@
+{\r
+  "white": {\r
+    "code": 255,\r
+    "t": 0\r
+  },\r
+  "black": {\r
+    "code": 0,\r
+    "t": 1\r
+  }\r
+}\r
diff --git a/db/migrate/20120815021444_add_md5.rb b/db/migrate/20120815021444_add_md5.rb
new file mode 100644 (file)
index 0000000..51c2684
--- /dev/null
@@ -0,0 +1,13 @@
+class AddMd5 < ActiveRecord::Migration
+  def up
+    add_column :original_pictures, :md5, :string, :null => false, :limit => 32, :default => '00000000000000000000000000000000'
+    add_column :pictures, :md5, :string, :null => false, :limit => 32, :default => '00000000000000000000000000000000'
+    add_column :resource_pictures, :md5, :string, :null => false, :limit => 32, :default => '00000000000000000000000000000000'
+  end
+
+  def down
+    remove_column :original_pictures, :md5
+    remove_column :pictures, :md5
+    remove_column :resource_pictures, :md5
+  end
+end
diff --git a/db/migrate/20120815043236_rm_default_ls_on_artist.rb b/db/migrate/20120815043236_rm_default_ls_on_artist.rb
new file mode 100644 (file)
index 0000000..9b01e60
--- /dev/null
@@ -0,0 +1,9 @@
+class RmDefaultLsOnArtist < ActiveRecord::Migration
+  def up
+    remove_column :artists, :default_license_id
+  end
+
+  def down
+    remove_column :artists, :default_license_id, :integer , :null => false, :default => 0
+  end
+end
diff --git a/db/migrate/20120815045014_rm_default_size_on_comic.rb b/db/migrate/20120815045014_rm_default_size_on_comic.rb
new file mode 100644 (file)
index 0000000..0aca16a
--- /dev/null
@@ -0,0 +1,11 @@
+class RmDefaultSizeOnComic < ActiveRecord::Migration
+  def up
+    remove_column :comics, :width
+    remove_column :comics, :height
+  end
+
+  def down
+    add_column :comics, :width, :integer , :null => false, :default => 0
+    add_column :comics, :height, :integer , :null => false, :default => 0
+  end
+end
diff --git a/db/migrate/20120816022713_create_colors.rb b/db/migrate/20120816022713_create_colors.rb
new file mode 100644 (file)
index 0000000..6b4a706
--- /dev/null
@@ -0,0 +1,11 @@
+class CreateColors < ActiveRecord::Migration
+  def change
+    create_table :colors do |t|
+      t.string :name, :null => false, :limit => 50, :default => 'no name'
+      t.integer :code, :null => false, :default => 0
+      t.integer :t, :null => false, :default => 0
+
+      t.timestamps
+    end
+  end
+end
diff --git a/db/migrate/20120816024744_create_ground_colors.rb b/db/migrate/20120816024744_create_ground_colors.rb
new file mode 100644 (file)
index 0000000..b6294ae
--- /dev/null
@@ -0,0 +1,12 @@
+class CreateGroundColors < ActiveRecord::Migration
+  def change
+    create_table :ground_colors do |t|
+      t.integer :panel_id, :null => false, :default => 0
+      t.integer :color_id, :null => false, :default => 0
+      t.integer :author_id, :null => false, :default => 0
+      t.integer :z, :null => false, :default => 0
+
+      t.timestamps
+    end
+  end
+end
diff --git a/db/migrate/20120816024915_create_panel_colors.rb b/db/migrate/20120816024915_create_panel_colors.rb
new file mode 100644 (file)
index 0000000..32433c0
--- /dev/null
@@ -0,0 +1,11 @@
+class CreatePanelColors < ActiveRecord::Migration
+  def change
+    create_table :panel_colors do |t|
+      t.integer :panel_id, :null => false, :default => 0
+      t.integer :z, :null => false, :default => 0
+      t.integer :code, :null => false, :default => 0
+
+      t.timestamps
+    end
+  end
+end
diff --git a/db/migrate/20120816025308_create_ground_pictures.rb b/db/migrate/20120816025308_create_ground_pictures.rb
new file mode 100644 (file)
index 0000000..27852f3
--- /dev/null
@@ -0,0 +1,11 @@
+class CreateGroundPictures < ActiveRecord::Migration
+  def change
+    create_table :ground_pictures do |t|
+      t.integer :panel_id, :null => false, :default => 0
+      t.integer :picture_id, :null => false, :default => 0
+      t.integer :z, :null => false, :default => 0
+
+      t.timestamps
+    end
+  end
+end
diff --git a/lib/tasks/licenses.rake b/lib/tasks/licenses.rake
new file mode 100644 (file)
index 0000000..8caed78
--- /dev/null
@@ -0,0 +1,20 @@
+namespace :licenses do
+  desc "Import json format license data in license engine"
+  task :import => :environment do
+    licenses = YAML.load(open(Rails.root + 'config/license.yml').read)
+    licenses.each do |name, klass|
+      puts name + "\n"
+      system 'rake ' + name + ':import'
+    end
+  end
+  
+  desc "Copy migration file for license "
+  task :install => :environment do
+    licenses = YAML.load(open(Rails.root + 'config/license.yml').read)
+    licenses.each do |name, klass|
+      puts name + "\n"
+      system 'rake ' + name + ':install:migrations'
+    end
+    puts "run 'rake db:migrate' if you can migrate database\n"
+  end
+end
index 59b6265..be01eeb 100644 (file)
@@ -1,6 +1,6 @@
 class ResizeValidator < ActiveModel::EachValidator\r
   def validate_each(record, attribute, value)\r
-    if record.picture.flag_resize < 0\r
+    if record.picture and record.picture.flag_resize < 0\r
       record.errors[attribute] << (options[:message] || "no resize") unless value == record.picture[attribute]\r
     end\r
   end\r
index 638e5b9..b52f697 100644 (file)
@@ -1,6 +1,6 @@
 class ReverseValidator < ActiveModel::EachValidator\r
   def validate_each(record, attribute, value)\r
-    if record.picture.flag_reverse < 0\r
+    if record.picture and record.picture.flag_reverse < 0\r
       record.errors[attribute] << (options[:message] || "no reverse") if value < 0\r
     end\r
   end\r
index 928d957..04425fd 100644 (file)
@@ -1,6 +1,6 @@
 class SyncVhValidator < ActiveModel::EachValidator\r
   def validate_each(record, attribute, value)\r
-    if record.picture.flag_sync_vh < 0\r
+    if record.picture and record.picture.flag_sync_vh < 0\r
       record.errors[attribute] << (options[:message] || "sync_vh") unless sync?(record)\r
     end\r
   end\r
diff --git a/script/gem_builder.rb b/script/gem_builder.rb
new file mode 100644 (file)
index 0000000..6866ae6
--- /dev/null
@@ -0,0 +1,23 @@
+#ライセンスのgemファイルを作るサポートツール\r
+#Yamlファイルからコンバートする\r
+if ARGV.size < 1\r
+  puts "gem_builder.rb dir"\r
+  puts "build to gem on child dirs"\r
+  exit\r
+end\r
+\r
+dirname = File.expand_path ARGV[0]\r
+Dir.glob dirname + '/*' do |filename|\r
+  if File.directory?(filename)\r
+    fn = Dir.glob(filename + '/*.gemspec').first\r
+    c = "gem build " + fn\r
+    Dir.chdir filename do\r
+      puts c\r
+      system c\r
+    end\r
+    gem = Dir.glob(filename + '/*.gem').sort.last\r
+    c = "gem install " + gem\r
+      puts c\r
+      system c\r
+  end\r
+end\r
diff --git a/script/ls_helper.rb b/script/ls_helper.rb
new file mode 100644 (file)
index 0000000..4ea1a66
--- /dev/null
@@ -0,0 +1,40 @@
+#ライセンスのjsonファイルを作るサポートツール\r
+#Yamlファイルからコンバートする\r
+if ARGV.size < 1\r
+  puts "ls_helper.rb ls.yml [work dir=current dir]"\r
+  puts "generate to ls.json"\r
+  exit\r
+end\r
+\r
+require 'yaml'\r
+require 'json'\r
+require 'base64'\r
+\r
+filename = ARGV[0]\r
+lg = YAML.load(open(filename).read)\r
+fn = File.basename filename, ".*"\r
+wd = ARGV[1] ? File.expand_path(ARGV[1]) : File.dirname(filename)\r
+o = wd + '/' + fn + '.json'\r
+\r
+lg.each do |k, g|\r
+  puts k\r
+  g['licenses_attributes'].each do |lk, l|\r
+    puts lk\r
+    if l['settings']\r
+      puts 'settings to json'\r
+      l['settings'] = l['settings'].to_json.to_s\r
+    end\r
+    if l['system_picture_file']\r
+      fn = File.expand_path(wd + '/' + l['system_picture_file'])\r
+      puts 'open system picture file ' + fn\r
+      d = File.open(fn, 'rb').read\r
+      b = Base64.encode64(d).gsub(/\r/, '').gsub(/\n/, '')\r
+      l['system_picture'] = b\r
+      l.delete 'system_picture_file'\r
+    end\r
+  end\r
+end\r
+puts "generating " + o\r
+File.open(o, 'wb') do |f|\r
+  f.write lg.to_json.to_s\r
+end\r
index 9b610c9..5301454 100644 (file)
@@ -9,7 +9,7 @@
     "publish": 1,\r
     "panel_pictures_attributes": {\r
       "new1": {\r
-        "resource_picture_id": 3,\r
+        "picture_id": 3,\r
         "x": 10,\r
         "y": 135,\r
         "z": 3,\r
         "width": 100,\r
         "height": 103\r
       }\r
+    },\r
+    "ground_pictures_attributes": {\r
+      "new1": {\r
+        "picture_id": 1,\r
+        "z": 1\r
+      }\r
+    },\r
+    "ground_colors_attributes": {\r
+      "new1": {\r
+        "color_id": 1,\r
+        "z": 1\r
+      }\r
+    },\r
+    "panel_colors_attributes": {\r
+      "new1": {\r
+        "code": 1,\r
+        "z": 1\r
+      }\r
     }\r
   },\r
-  "auth_token": "vX7rc33zxVJSQPKjp2vc"\r
+  "auth_token": "3d3Fvz9RafTPcpzLrYSW"\r
 }
\ No newline at end of file
diff --git a/spec/controllers/colors_controller_spec.rb b/spec/controllers/colors_controller_spec.rb
new file mode 100644 (file)
index 0000000..c0a301e
--- /dev/null
@@ -0,0 +1,95 @@
+# -*- encoding: utf-8 -*-
+require 'spec_helper'
+#色マスター
+
+describe ColorsController do
+  before do
+    @admin = FactoryGirl.create :admin
+    @user = FactoryGirl.create( :user_yas)
+    @sp = FactoryGirl.create :system_picture
+    @lg = FactoryGirl.create :license_group, :name => 'peta'
+    @license = FactoryGirl.create :license, :license_group_id => @lg.id, :system_picture_id => @sp.id
+  end
+
+  describe '一覧表示に於いて' do
+    before do
+      sign_in @user
+      @color = FactoryGirl.create :color
+      Color.stub(:list).and_return([@color, @color, @color])
+    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 Color.default_page_size
+      end
+      it '最大を超えると@page_sizeにデフォルト最大値が入る' do
+        get :index, :page_size => 1500
+        assigns(:page_size).should eq Color.max_page_size
+      end
+      it '不正な値が入ると@page_sizeにデフォルト最大値が入る' do
+        get :index, :page_size => 0
+        assigns(:page_size).should eq Color.default_page_size
+      end
+    end
+    context 'つつがなく終わるとき' do
+      it 'ステータスコード200 OKを返す' do
+        get :index
+        response.should be_success 
+      end
+      it '色モデルに一覧を問い合わせている' do
+        Color.should_receive(:list).exactly(1)
+        get :index
+      end
+      it '@colorsにリストを取得している' do
+        get :index
+        assigns(:colors).should have_at_least(3).items
+      end
+      context 'html形式' do
+        it 'indexテンプレートを描画する' do
+          get :index
+          response.should render_template("index")
+        end
+      end
+      context 'json形式' do
+        it 'jsonデータを返す' do
+          get :index, :format => :json
+          lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError)
+        end
+        it 'データがリスト構造になっている' do
+          get :index, :format => :json
+          json = JSON.parse response.body
+          json.should have_at_least(3).items
+        end
+        it 'リストの先頭くらいは色っぽいものであって欲しい' do
+          get :index, :format => :json
+          json = JSON.parse response.body
+          json.first.has_key?("name").should be_true
+          json.first.has_key?("code").should be_true
+          json.first.has_key?("t").should be_true
+        end
+      end
+    end
+    context '作家権限がないとき' do
+      before do
+        sign_out @user
+      end
+      it 'ステータスコード200 okを返す' do
+        get :index
+        response.status.should eq 200
+      end
+    end
+  end
+  
+end
index 4f937d8..5d2f639 100644 (file)
@@ -1,12 +1,12 @@
 # -*- encoding: utf-8 -*-\r
-require 'spec_helper'
-
-describe ComicsController do
-  before do
-    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
+require 'spec_helper'\r
+\r
+describe ComicsController do\r
+  before do\r
+    FactoryGirl.create :admin\r
+    @sp = FactoryGirl.create :system_picture\r
+    @lg = FactoryGirl.create :license_group\r
+    @license = FactoryGirl.create :license, :license_group_id => @lg.id, :system_picture_id => @sp.id\r
     @user = FactoryGirl.create :user_yas\r
     @author = @user.author    #ユーザ作成時に連動して作成される\r
   end\r
@@ -392,15 +392,15 @@ describe ComicsController do
     before do\r
       @comic = FactoryGirl.create :comic, :author_id => @user.author.id\r
       sign_in @user\r
-      Comic.stub(:show).and_return(@comic)\r
+      Comic.stub(:edit).and_return(@comic)\r
     end\r
     context 'つつがなく終わるとき' do\r
       it 'ステータスコード200 OKを返す' do\r
         get :edit, :id => @comic.id\r
         response.should be_success \r
       end\r
-      it 'コミックモデルに単体取得を問い合わせている' do\r
-        Comic.should_receive(:show).exactly(1)\r
+      it 'コミックモデルに編集取得を問い合わせている' do\r
+        Comic.should_receive(:edit).exactly(1)\r
         get :edit, :id => @comic.id\r
       end\r
       it '@comicにデータを用意している' do\r
@@ -454,13 +454,14 @@ describe ComicsController do
       sign_in @user\r
     end\r
     context '事前チェックしておく' do\r
-      it 'コミックモデルに単体取得を問い合わせている' do\r
-        Comic.stub(:show).with(any_args()).and_return @comic\r
-        Comic.should_receive(:show).exactly(1)\r
+      it 'コミックモデルに編集取得を問い合わせている' do\r
+        Comic.stub(:edit).with(any_args()).and_return @comic\r
+        Comic.should_receive(:edit).exactly(1)\r
         put :update, :id => @comic.id, :comic => @attr\r
       end\r
       it 'モデルに更新を依頼する' do\r
-        Comic.any_instance.should_receive(:update_attributes).with(any_args)\r
+        Comic.any_instance.stub(:save).with(any_args).and_return true\r
+        Comic.any_instance.should_receive(:save).exactly(1)\r
         put :update, :id => @comic.id, :comic => @attr\r
       end\r
       it '@comicにアレを取得している' do\r
@@ -475,7 +476,7 @@ describe ComicsController do
       end\r
       context 'html形式' do\r
         it 'ステータスコード302 Foundを返す' do\r
-          Comic.any_instance.stub(:update_attributes).with(any_args()).and_return(true)\r
+          Comic.any_instance.stub(:save).with(any_args()).and_return(true)\r
           put :update, :id => @comic.id, :comic => @attr\r
           response.status.should eq 302\r
         end\r
@@ -486,12 +487,12 @@ describe ComicsController do
       end\r
       context 'json形式' do\r
         it 'ステータスコード200 OKを返す' do\r
-          Comic.any_instance.stub(:update_attributes).with(any_args()).and_return(true)\r
+          Comic.any_instance.stub(:save).with(any_args()).and_return(true)\r
           put :update, :id => @comic.id, :comic => @attr, :format => :json\r
           response.should be_success \r
         end\r
         it 'ページ本体は特に返さない' do\r
-          Comic.any_instance.stub(:update_attributes).with(any_args()).and_return(true)\r
+          Comic.any_instance.stub(:save).with(any_args()).and_return(true)\r
           put :update, :id => @comic.id, :comic => @attr, :format => :json\r
           response.body.should match /./\r
         end\r
@@ -520,7 +521,7 @@ describe ComicsController do
     end\r
     context '検証、保存に失敗したとき' do\r
       before do\r
-        Comic.any_instance.stub(:update_attributes).and_return(false)\r
+        Comic.any_instance.stub(:save).and_return(false)\r
       end\r
       context 'html形式' do\r
         it 'ステータスコード200 Okを返す' do\r
@@ -534,7 +535,7 @@ describe ComicsController do
       end\r
       context 'json形式' do\r
         it 'ステータスコード422 unprocessable_entity を返す' do\r
-          Comic.any_instance.stub(:update_attributes).and_return(false)\r
+          Comic.any_instance.stub(:save).and_return(false)\r
           put :update, :id => @comic.id, :comic => @attr, :format => :json\r
           response.status.should eq 422\r
         end\r
diff --git a/spec/controllers/ground_colors_controller_spec.rb b/spec/controllers/ground_colors_controller_spec.rb
new file mode 100644 (file)
index 0000000..8d40002
--- /dev/null
@@ -0,0 +1,115 @@
+# -*- encoding: utf-8 -*-
+require 'spec_helper'
+#コマの間接背景
+
+describe GroundColorsController do
+  before do
+    @admin = FactoryGirl.create :admin
+    @user = FactoryGirl.create( :user_yas)
+    @sp = FactoryGirl.create :system_picture
+    @lg = FactoryGirl.create :license_group, :name => 'peta'
+    @license = FactoryGirl.create :license, :license_group_id => @lg.id, :system_picture_id => @sp.id
+    @author = @user.author
+    @artist = FactoryGirl.create :artist_yas, :author_id => @author.id
+    @panel = FactoryGirl.create :panel, :author_id => @author.id
+    @color = FactoryGirl.create :color
+  end
+
+  describe '一覧表示に於いて' do
+    before do
+      sign_in @user
+      @gc = FactoryGirl.create :ground_color
+      GroundColor.stub(:list).and_return([@gc, @gc, @gc])
+    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 GroundColor.default_page_size
+      end
+      it '最大を超えると@page_sizeにデフォルト最大値が入る' do
+        get :index, :page_size => 1500
+        assigns(:page_size).should eq GroundColor.max_page_size
+      end
+      it '不正な値が入ると@page_sizeにデフォルト最大値が入る' do
+        get :index, :page_size => 0
+        assigns(:page_size).should eq GroundColor.default_page_size
+      end
+    end
+    context 'つつがなく終わるとき' do
+      it 'ステータスコード200 OKを返す' do
+        get :index
+        response.should be_success 
+      end
+      it '間接背景モデルに一覧を問い合わせている' do
+        GroundColor.should_receive(:list).exactly(1)
+        get :index
+      end
+      it '@ground_colorsにリストを取得している' do
+        get :index
+        assigns(:ground_colors).should have_at_least(3).items
+      end
+      context 'html形式' do
+        it 'indexテンプレートを描画する' do
+          get :index
+          response.should render_template("index")
+        end
+      end
+      context 'json形式' do
+        it 'jsonデータを返す' do
+          get :index, :format => :json
+          lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError)
+        end
+        it 'データがリスト構造になっている' 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").should be_true
+          json.first.has_key?("color_id").should be_true
+          json.first.has_key?("z").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
+  end
+  
+end
diff --git a/spec/controllers/ground_pictures_controller_spec.rb b/spec/controllers/ground_pictures_controller_spec.rb
new file mode 100644 (file)
index 0000000..e150928
--- /dev/null
@@ -0,0 +1,117 @@
+# -*- encoding: utf-8 -*-
+require 'spec_helper'
+#コマの画像背景
+
+describe GroundPicturesController do
+  before do
+    @admin = FactoryGirl.create :admin
+    @user = FactoryGirl.create( :user_yas)
+    @sp = FactoryGirl.create :system_picture
+    @lg = FactoryGirl.create :license_group, :name => 'peta'
+    @license = FactoryGirl.create :license, :license_group_id => @lg.id, :system_picture_id => @sp.id
+    @author = @user.author
+    @artist = FactoryGirl.create :artist_yas, :author_id => @author.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
+    @panel = FactoryGirl.create :panel, :author_id => @author.id
+  end
+
+  describe '一覧表示に於いて' do
+    before do
+      sign_in @user
+      @gp = FactoryGirl.create :ground_picture, :panel_id => @panel.id, :picture_id => @p.id
+      GroundPicture.stub(:list).and_return([@gp, @gp, @gp])
+    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 GroundPicture.default_page_size
+      end
+      it '最大を超えると@page_sizeにデフォルト最大値が入る' do
+        get :index, :page_size => 1500
+        assigns(:page_size).should eq GroundPicture.max_page_size
+      end
+      it '不正な値が入ると@page_sizeにデフォルト最大値が入る' do
+        get :index, :page_size => 0
+        assigns(:page_size).should eq GroundPicture.default_page_size
+      end
+    end
+    context 'つつがなく終わるとき' do
+      it 'ステータスコード200 OKを返す' do
+        get :index
+        response.should be_success 
+      end
+      it 'コマの画像背景モデルに一覧を問い合わせている' do
+        GroundPicture.should_receive(:list).exactly(1)
+        get :index
+      end
+      it '@ground_picturesにリストを取得している' do
+        get :index
+        assigns(:ground_pictures).should have_at_least(3).items
+      end
+      context 'html形式' do
+        it 'indexテンプレートを描画する' do
+          get :index
+          response.should render_template("index")
+        end
+      end
+      context 'json形式' do
+        it 'jsonデータを返す' do
+          get :index, :format => :json
+          lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError)
+        end
+        it 'データがリスト構造になっている' 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?("picture_id").should be_true
+          json.first.has_key?("z").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
+  end
+  
+end
index a81df82..351ffd9 100644 (file)
@@ -34,7 +34,7 @@ describe OriginalPicturesController do
       end
       it '省略されると@page_sizeにデフォルト値が入る' do
         get :index
-        assigns(:page_size).should eq OriginalPicture.default_page_size\r
+        assigns(:page_size).should eq OriginalPicture.default_page_size
       end
       it '最大を超えると@page_sizeにデフォルト最大値が入る' do
         get :index, :page_size => 1500
@@ -51,7 +51,7 @@ describe OriginalPicturesController do
         response.should be_success 
       end
       it '原画モデルに一覧を問い合わせている' do
-        OriginalPicture.should_receive(:list).exactly(1)\r
+        OriginalPicture.should_receive(:list).exactly(1)
         get :index
       end
       it '@original_picturesにリストを取得している' do
@@ -142,7 +142,7 @@ describe OriginalPicturesController do
         response.should be_success
       end
       it '原画モデルに単体取得を問い合わせている' do
-        OriginalPicture.should_receive(:show).exactly(1)\r
+        OriginalPicture.should_receive(:show).exactly(1)
         get :show
       end
       it '@original_pictureにアレを取得している' do
@@ -171,33 +171,33 @@ describe OriginalPicturesController do
       #スタブをおいてsend_dataがデータを返す体裁でテストする。
       context 'png形式' do
         it '画像モデルに画像データを問い合わせる' do
-          OriginalPicture.any_instance.should_receive(:restore).exactly(1)\r
+          OriginalPicture.any_instance.should_receive(:restore).exactly(1)
           get :show, :id => @pic.id, :format => :png
         end
         it '画像を送信する' do
-          OriginalPicture.any_instance.stub(:restore).and_return('aaa')\r
+          OriginalPicture.any_instance.stub(:restore).and_return('aaa')
           get :show, :id => @pic.id, :format => :png
           response.body.should eq 'aaa'
         end
       end
       context 'gif形式' do
         it '画像モデルに画像データを問い合わせる' do
-          OriginalPicture.any_instance.should_receive(:restore).exactly(1)\r
+          OriginalPicture.any_instance.should_receive(:restore).exactly(1)
           get :show, :id => @pic.id, :format => :gif
         end
         it '画像を送信する' do
-          OriginalPicture.any_instance.stub(:restore).and_return('bbb')\r
+          OriginalPicture.any_instance.stub(:restore).and_return('bbb')
           get :show, :id => @pic.id, :format => :gif
           response.body.should eq 'bbb'
         end
       end
       context 'jpeg形式' do
         it '画像モデルに画像データを問い合わせる' do
-          OriginalPicture.any_instance.should_receive(:restore).exactly(1)\r
+          OriginalPicture.any_instance.should_receive(:restore).exactly(1)
           get :show, :id => @pic.id, :format => :jpeg
         end
         it '画像を送信する' do
-          OriginalPicture.any_instance.stub(:restore).and_return('ccc')\r
+          OriginalPicture.any_instance.stub(:restore).and_return('ccc')
           get :show, :id => @pic.id, :format => :jpeg
           response.body.should eq 'ccc'
         end
@@ -293,6 +293,104 @@ describe OriginalPicturesController do
 =end
   end
 
+  describe '履歴一覧表示に於いて' do
+    before do
+      @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
+      @p = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 0,
+        :original_picture_id => @op.id
+      sign_in @user
+      OriginalPicture.stub(:show).and_return(@op)
+      OriginalPicture.any_instance.stub(:history).and_return([@p, @p, @p])
+    end
+    context 'つつがなく終わるとき' do
+      it 'ステータスコード200 OKを返す' do
+        get :history, :id => @op.id
+        response.should be_success 
+      end
+      it '原画モデルに単体取得を問い合わせている' do
+        OriginalPicture.should_receive(:show).exactly(1)
+        get :history, :id => @op.id
+      end
+      it '自身に履歴一覧を問い合わせている' do
+        OriginalPicture.any_instance.should_receive(:history).exactly(1)
+        get :history
+      end
+      it '@historyにリストを取得している' do
+        get :history, :id => @op.id
+        assigns(:history).should have_at_least(3).items
+      end
+      context 'html形式' do
+        it 'historyテンプレートを描画する' do
+          get :history, :id => @op.id
+          response.should render_template("history")
+        end
+      end
+      context 'json形式' do
+        it 'jsonデータを返す' do
+          get :history, :id => @op.id, :format => :json
+          lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError)
+        end
+        it 'データがリスト構造になっている' do
+          get :history, :id => @op.id, :format => :json
+          json = JSON.parse response.body
+          json.should have_at_least(3).items
+        end
+        it 'リストの先頭くらいは原画っぽいものであって欲しい' do
+          get :history, :id => @op.id, :format => :json
+          json = JSON.parse response.body
+          json.first.has_key?("ext").should be_true
+        end
+      end
+    end
+    context '作家権限がないとき' do
+      before do
+        sign_out @user
+      end
+      context 'html形式' do
+        it 'ステータスコード302 Foundを返す' do
+          get :history, :id => @op.id
+          response.status.should eq 302
+        end
+        it 'サインインページへ遷移する' do
+          get :history, :id => @op.id
+          response.should redirect_to '/users/sign_in'
+        end
+      end
+      context 'json形式' do
+        it 'ステータスコード401 Unauthorizedを返す' do
+          get :history, :id => @op.id, :format => :json
+          response.status.should eq 401
+        end
+        it '応答メッセージにUnauthorizedを返す' do
+          get :history, :id => @op.id, :format => :json
+          response.message.should match(/Unauthorized/)
+        end
+      end
+    end
+    context '作家が絵師でないとき' do
+      before do
+        Author.any_instance.stub(:artist?).and_return(false)
+      end
+      context 'html形式' do
+        it 'ステータスコード302 Foundを返す' do
+          get :history, :id => @op.id
+          response.status.should eq 302
+        end
+        it '絵師登録ページへ遷移する' do
+          get :history, :id => @op.id
+          response.should redirect_to new_artist_path
+        end
+      end
+      context 'json形式' do
+        it '例外403 forbiddenを返す' do
+          lambda{
+            get :history, :id => @op.id, :format => :json
+          }.should raise_error(ActiveRecord::Forbidden)
+        end
+      end
+    end
+  end
+  
   describe '新規作成フォーム表示に於いて' do
     before do
       sign_in @user
@@ -307,7 +405,7 @@ describe OriginalPicturesController do
         assigns(:original_picture).should be_a_new(OriginalPicture)
       end
       it '原画モデルにデフォルト値補充を依頼している' do
-        OriginalPicture.any_instance.should_receive(:supply_default).exactly(1)\r
+        OriginalPicture.any_instance.should_receive(:supply_default).exactly(1)
         get :new
       end
       context 'html形式' do
@@ -519,8 +617,8 @@ describe OriginalPicturesController do
         get :edit, :id => @pic.id
         response.should be_success 
       end
-      it '原画モデルに単体取得を問い合わせている' do
-        OriginalPicture.should_receive(:show).exactly(1)\r
+      it '原画モデルに編集取得を問い合わせている' do
+        OriginalPicture.should_receive(:edit).exactly(1)
         get :edit, :id => @pic.id
       end
       it '@original_pictureにデータを用意している' do
@@ -603,7 +701,7 @@ describe OriginalPicturesController do
         OriginalPicture.any_instance.stub(:store).with(any_args()).and_return(true)
       end
       it '原画モデルに単体取得を問い合わせている' do
-        OriginalPicture.should_receive(:edit).exactly(1)\r
+        OriginalPicture.should_receive(:edit).exactly(1)
         put :update, :id => @pic.id, :original_picture => FactoryGirl.attributes_for(:original_picture)
       end
       it 'モデルに更新を依頼する' do
diff --git a/spec/controllers/panel_colors_controller_spec.rb b/spec/controllers/panel_colors_controller_spec.rb
new file mode 100644 (file)
index 0000000..102009d
--- /dev/null
@@ -0,0 +1,114 @@
+# -*- encoding: utf-8 -*-
+require 'spec_helper'
+#コマの色背景
+
+describe PanelColorsController do
+  before do
+    @admin = FactoryGirl.create :admin
+    @user = FactoryGirl.create( :user_yas)
+    @sp = FactoryGirl.create :system_picture
+    @lg = FactoryGirl.create :license_group, :name => 'peta'
+    @license = FactoryGirl.create :license, :license_group_id => @lg.id, :system_picture_id => @sp.id
+    @author = @user.author
+    @artist = FactoryGirl.create :artist_yas, :author_id => @author.id
+    @panel = FactoryGirl.create :panel, :author_id => @author.id
+  end
+
+  describe '一覧表示に於いて' do
+    before do
+      sign_in @user
+      @pc = FactoryGirl.create :panel_color, :panel_id => @panel.id
+      PanelColor.stub(:list).and_return([@pc, @pc, @pc])
+    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 PanelColor.default_page_size
+      end
+      it '最大を超えると@page_sizeにデフォルト最大値が入る' do
+        get :index, :page_size => 1500
+        assigns(:page_size).should eq PanelColor.max_page_size
+      end
+      it '不正な値が入ると@page_sizeにデフォルト最大値が入る' do
+        get :index, :page_size => 0
+        assigns(:page_size).should eq PanelColor.default_page_size
+      end
+    end
+    context 'つつがなく終わるとき' do
+      it 'ステータスコード200 OKを返す' do
+        get :index
+        response.should be_success 
+      end
+      it '色背景モデルに一覧を問い合わせている' do
+        PanelColor.should_receive(:list).exactly(1)
+        get :index
+      end
+      it '@panel_colorsにリストを取得している' do
+        get :index
+        assigns(:panel_colors).should have_at_least(3).items
+      end
+      context 'html形式' do
+        it 'indexテンプレートを描画する' do
+          get :index
+          response.should render_template("index")
+        end
+      end
+      context 'json形式' do
+        it 'jsonデータを返す' do
+          get :index, :format => :json
+          lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError)
+        end
+        it 'データがリスト構造になっている' 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?("code").should be_true
+          json.first.has_key?("z").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
+  end
+  
+end
index 7f1770b..485b04d 100644 (file)
@@ -4,9 +4,9 @@ require 'spec_helper'
 describe PanelsController do\r
   before do\r
     FactoryGirl.create :admin\r
-    @sp = FactoryGirl.create :system_picture
-    @lg = FactoryGirl.create :license_group
-    @license = FactoryGirl.create :license, :license_group_id => @lg.id, :system_picture_id => @sp.id
+    @sp = FactoryGirl.create :system_picture\r
+    @lg = FactoryGirl.create :license_group\r
+    @license = FactoryGirl.create :license, :license_group_id => @lg.id, :system_picture_id => @sp.id\r
     @user = FactoryGirl.create :user_yas\r
     @author = @user.author    #ユーザ作成時に連動して作成される\r
   end\r
@@ -430,8 +430,8 @@ describe PanelsController do
         get :edit, :id => @panel.id\r
         response.should be_success \r
       end\r
-      it 'コマモデルに単体取得を問い合わせている' do\r
-        Panel.should_receive(:show).exactly(1)\r
+      it 'コマモデルに編集取得を問い合わせている' do\r
+        Panel.should_receive(:edit).exactly(1)\r
         get :edit, :id => @panel.id\r
       end\r
       it '@panelにデータを用意している' do\r
index b61f920..6fdc26e 100644 (file)
@@ -33,6 +33,12 @@ describe PicturesController do
         get :show, :id => @p.id, :format => :json
         assigns(:picture).id.should eq(@p.id)
       end
+      context 'html形式' do
+        it 'showテンプレートを描画する' do
+          get :show, :id => @p.id
+          response.should render_template("show")
+        end
+      end
       context 'json形式' do
         it 'jsonデータを返す' do
           get :show, :id => @p.id, :format => :json
@@ -149,89 +155,89 @@ describe PicturesController do
 =end
   end
 
-  describe 'クレジット表示に於いて' do\r
-    before do\r
+  describe 'クレジット表示に於いて' do
+    before do
       @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id
       sign_in @user
       Picture.stub(:show).and_return(@p)
-    end\r
-    context 'つつがなく終わるとき' do\r
-      it 'ステータスコード200 OKを返す' do\r
-        get :credit, :id => @p.id\r
-        response.should be_success\r
-      end\r
-      it '実素材モデルに単体取得を問い合わせている' do\r
-        Picture.should_receive(:show).exactly(1)\r
-        get :credit, :id => @p.id\r
-      end\r
-      it '@pictureにアレを取得している' do\r
-        get :credit, :id => @p.id\r
-        assigns(:picture).id.should eq(@p.id)\r
-      end\r
-      context 'html形式' do\r
-        it 'creditテンプレートを描画する' do\r
-          get :credit, :id => @p.id\r
-          response.should render_template("credit")\r
-        end\r
-      end\r
-      context 'json形式' do\r
-        it 'jsonデータを返す' do\r
-          get :credit, :id => @p.id, :format => :json\r
-          lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError)\r
-        end\r
-        it 'データがアレになっている' do\r
-          get :credit, :id => @p.id, :format => :json\r
-          json = JSON.parse response.body\r
-          json["ext"].should match(/png/)\r
-        end\r
-      end\r
-    end\r
-    context '作家権限がないとき' do\r
-      before do\r
-        sign_out @user\r
-      end\r
-      context 'html形式' do\r
-        it 'ステータスコード302 Foundを返す' do\r
-          get :credit, :id => @p.id\r
-          response.status.should eq 302\r
-        end\r
-        it 'サインインページへ遷移する' do\r
-          get :credit, :id => @p.id\r
-          response.body.should redirect_to '/users/sign_in'\r
-        end\r
-      end\r
-      context 'json形式' do\r
-        it 'ステータスコード401 Unauthorizedを返す' do\r
-          get :credit, :id => @p.id, :format => :json\r
-          response.status.should eq 401\r
-        end\r
-        it '応答メッセージにUnauthorizedを返す' do\r
-          get :credit, :id => @p.id, :format => :json\r
-          response.message.should match(/Unauthorized/)\r
-        end\r
-      end\r
-    end\r
-=begin\r
-    context '対象素材がないとき' do\r
-      before do\r
-        Picture.unstub(:show)\r
-      end\r
-      context 'html形式' do\r
-        it '例外404 not_foundを返す' do\r
-          lambda{\r
-            get :show, :id => 0\r
-          }.should raise_error(ActiveRecord::RecordNotFound)\r
-        end\r
-      end\r
-      context 'json形式' do\r
-        it '例外404 not_foundを返す' do\r
-          lambda{ \r
-            get :show, :id => 0, :format => :json\r
-          }.should raise_error(ActiveRecord::RecordNotFound)\r
-        end\r
-      end\r
-    end\r
-=end\r
-  end\r
+    end
+    context 'つつがなく終わるとき' do
+      it 'ステータスコード200 OKを返す' do
+        get :credit, :id => @p.id
+        response.should be_success
+      end
+      it '実素材モデルに単体取得を問い合わせている' do
+        Picture.should_receive(:show).exactly(1)
+        get :credit, :id => @p.id
+      end
+      it '@pictureにアレを取得している' do
+        get :credit, :id => @p.id
+        assigns(:picture).id.should eq(@p.id)
+      end
+      context 'html形式' do
+        it 'creditテンプレートを描画する' do
+          get :credit, :id => @p.id
+          response.should render_template("credit")
+        end
+      end
+      context 'json形式' do
+        it 'jsonデータを返す' do
+          get :credit, :id => @p.id, :format => :json
+          lambda{JSON.parse(response.body)}.should_not raise_error(JSON::ParserError)
+        end
+        it 'データがアレになっている' do
+          get :credit, :id => @p.id, :format => :json
+          json = JSON.parse response.body
+          json["ext"].should match(/png/)
+        end
+      end
+    end
+    context '作家権限がないとき' do
+      before do
+        sign_out @user
+      end
+      context 'html形式' do
+        it 'ステータスコード302 Foundを返す' do
+          get :credit, :id => @p.id
+          response.status.should eq 302
+        end
+        it 'サインインページへ遷移する' do
+          get :credit, :id => @p.id
+          response.body.should redirect_to '/users/sign_in'
+        end
+      end
+      context 'json形式' do
+        it 'ステータスコード401 Unauthorizedを返す' do
+          get :credit, :id => @p.id, :format => :json
+          response.status.should eq 401
+        end
+        it '応答メッセージにUnauthorizedを返す' do
+          get :credit, :id => @p.id, :format => :json
+          response.message.should match(/Unauthorized/)
+        end
+      end
+    end
+=begin
+    context '対象素材がないとき' do
+      before do
+        Picture.unstub(:show)
+      end
+      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
+=end
+  end
 
 end
index 878be3b..0ac61e4 100644 (file)
@@ -209,8 +209,8 @@ describe StoriesController do
         get :edit, :id => @story.id
         response.should be_success 
       end
-      it 'コマモデルに単体取得を問い合わせている' do
-        Story.should_receive(:show).exactly(1)
+      it 'コマモデルに編集取得を問い合わせている' do
+        Story.should_receive(:edit).exactly(1)
         get :edit, :id => @story.id
       end
       it '@storyにデータを用意している' do
@@ -363,74 +363,74 @@ describe StoriesController do
     end
   end
 
-  describe '削除に於いて' do\r
-    before do\r
+  describe '削除に於いて' do
+    before do
       @story = FactoryGirl.create :story, :author_id => @author.id
       sign_in @user
-      Story.stub(:edit).and_return(@story)\r
-    end\r
-    context 'つつがなく終わるとき' do\r
-      it 'ストーリーモデルに編集取得を問い合わせている' do\r
-        Story.should_receive(:edit).exactly(1)\r
-        delete :destroy, :id => @story.id\r
-      end\r
-      it '@storyにアレを取得している' do\r
-        delete :destroy, :id => @story.id\r
-        assigns(:story).id.should eq(@story.id)\r
-      end\r
-      it 'そのストーリーを一つのトランザクションで削除する' do\r
-        lambda {\r
-          delete :destroy, :id => @story.id\r
-        }.should change(Story, :count)\r
-      end\r
-      context 'html形式' do\r
-        it 'ステータスコード302 Foundを返す' do\r
-          delete :destroy, :id => @story.id\r
-          response.status.should eq 302\r
-        end\r
-        it 'ストーリー一覧ページへ遷移する' do\r
-          delete :destroy, :id => @story.id\r
-          response.should redirect_to(story_path(@story.comic_id))\r
-        end\r
-      end\r
-      context 'json形式' do\r
-        it 'ステータスコード200 OKを返す' do\r
-          delete :destroy, :id => @story.id, :format => :json\r
-          response.should be_success\r
-        end\r
-      end\r
-    end\r
-    context '作家権限がないとき' do\r
-      before do\r
-        sign_out @user\r
-      end\r
-      context 'html形式' do\r
-        it 'ステータスコード302 Foundを返す' do\r
-          delete :destroy, :id => @story.id\r
-          response.status.should eq 302\r
-        end\r
-        it 'サインインページへ遷移する' do\r
-          delete :destroy, :id => @story.id\r
-          response.body.should redirect_to '/users/sign_in'\r
-        end\r
-      end\r
-      context 'json形式' do\r
-        it 'ステータスコード401 Unauthorizedを返す' do\r
-          delete :destroy, :id => @story.id, :format => :json\r
-          response.status.should eq 401\r
-        end\r
-        it '応答メッセージにUnauthorizedを返す' do\r
-          delete :destroy, :id => @story.id, :format => :json\r
-          response.message.should match(/Unauthorized/)\r
-        end\r
-      end\r
-    end\r
-=begin\r
-    context '対象ストーリーがないとき' do\r
-    end\r
-    context '他人のストーリーだったとき' do\r
-    end\r
-=end\r
-  end\r
-  \r
+      Story.stub(:edit).and_return(@story)
+    end
+    context 'つつがなく終わるとき' do
+      it 'ストーリーモデルに編集取得を問い合わせている' do
+        Story.should_receive(:edit).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 '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.comic_id))
+        end
+      end
+      context 'json形式' do
+        it 'ステータスコード200 OKを返す' do
+          delete :destroy, :id => @story.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 => @story.id
+          response.status.should eq 302
+        end
+        it 'サインインページへ遷移する' do
+          delete :destroy, :id => @story.id
+          response.body.should redirect_to '/users/sign_in'
+        end
+      end
+      context 'json形式' do
+        it 'ステータスコード401 Unauthorizedを返す' do
+          delete :destroy, :id => @story.id, :format => :json
+          response.status.should eq 401
+        end
+        it '応答メッセージにUnauthorizedを返す' do
+          delete :destroy, :id => @story.id, :format => :json
+          response.message.should match(/Unauthorized/)
+        end
+      end
+    end
+=begin
+    context '対象ストーリーがないとき' do
+    end
+    context '他人のストーリーだったとき' do
+    end
+=end
+  end
+  
 end
index b8c0dfd..ff13301 100644 (file)
@@ -52,10 +52,14 @@ FactoryGirl.define do
     license.system_picture_id 1
   end
 
+  factory :color, :class => Color do |color|
+    color.name 'black'
+    color.code 0
+    color.t 0
+  end
+
   factory :comic, :class => Comic do |comic|
     comic.title "comic"
-    comic.width 100
-    comic.height 10
     comic.visible 3
   end
 
@@ -65,6 +69,7 @@ FactoryGirl.define do
     op.height 111
     op.filesize 100000
     op.artist_id 1
+    op.md5 'op8f6bcd4621d373cade4e832627b4f6'
   end
 
   factory :oplg, :class => OriginalPictureLicenseGroup do |oplg|
@@ -77,6 +82,7 @@ FactoryGirl.define do
     rp.width 222
     rp.height 111
     rp.filesize 100000
+    rp.md5 'rp8f6bcd4621d373cade4e832627b4f6'
     rp.artist_id 1
     rp.license_id 1
     rp.classname 'StandardLicense'
@@ -90,6 +96,7 @@ FactoryGirl.define do
     p.width 222
     p.height 111
     p.filesize 100000
+    p.md5 'ap8f6bcd4621d373cade4e832627b4f6'
     p.artist_id 1
     p.license_id 1
     p.artist_name 'no name'
@@ -156,6 +163,24 @@ FactoryGirl.define do
     pp.height 300
   end
 
+  factory :panel_color, :class => PanelColor do |pc|
+    pc.panel_id 1
+    pc.z 1
+    pc.code 1
+  end
+
+  factory :ground_color, :class => GroundColor do |gc|
+    gc.panel_id 1
+    gc.color_id 1
+    gc.z 1
+  end
+
+  factory :ground_picture, :class => GroundPicture do |gp|
+    gp.panel_id 1
+    gp.picture_id 1
+    gp.z 1
+  end
+
   factory :panel, :class => Panel do |panel|
     panel.border 1
     panel.x nil
index 7a1305a..f66b09f 100644 (file)
@@ -1,3 +1,5 @@
+# -*- encoding: utf-8 -*-
+# 
 require 'spec_helper'
 
 # Specs in this file have access to a helper object that includes
@@ -11,5 +13,4 @@ require 'spec_helper'
 #   end
 # end
 describe ArtistsHelper do
-  pending "add some examples to (or delete) #{__FILE__}"
 end
index 09acc33..9c0a8cb 100644 (file)
@@ -1,3 +1,5 @@
+# -*- encoding: utf-8 -*-
+# 
 require 'spec_helper'
 
 # Specs in this file have access to a helper object that includes
@@ -11,5 +13,4 @@ require 'spec_helper'
 #   end
 # end
 describe AuthorsHelper do
-  pending "add some examples to (or delete) #{__FILE__}"
 end
index c8b6605..5a4a680 100644 (file)
@@ -1,3 +1,5 @@
+# -*- encoding: utf-8 -*-
+# 
 require 'spec_helper'
 
 # Specs in this file have access to a helper object that includes
@@ -11,5 +13,4 @@ require 'spec_helper'
 #   end
 # end
 describe BalloonsHelper do
-  pending "add some examples to (or delete) #{__FILE__}"
 end
diff --git a/spec/helpers/colors_helper_spec.rb b/spec/helpers/colors_helper_spec.rb
new file mode 100644 (file)
index 0000000..9e0d6e5
--- /dev/null
@@ -0,0 +1,16 @@
+# -*- encoding: utf-8 -*-
+# 
+require 'spec_helper'
+
+# Specs in this file have access to a helper object that includes
+# the ColorsHelper. For example:
+#
+# describe ColorsHelper do
+#   describe "string concat" do
+#     it "concats two strings with spaces" do
+#       helper.concat_strings("this","that").should == "this that"
+#     end
+#   end
+# end
+describe ColorsHelper do
+end
index 30bdaaf..3ffabda 100644 (file)
@@ -1,3 +1,5 @@
+# -*- encoding: utf-8 -*-
+# 
 require 'spec_helper'
 
 # Specs in this file have access to a helper object that includes
@@ -11,5 +13,4 @@ require 'spec_helper'
 #   end
 # end
 describe ComicsHelper do
-  pending "add some examples to (or delete) #{__FILE__}"
 end
diff --git a/spec/helpers/ground_colors_helper_spec.rb b/spec/helpers/ground_colors_helper_spec.rb
new file mode 100644 (file)
index 0000000..612d280
--- /dev/null
@@ -0,0 +1,16 @@
+# -*- encoding: utf-8 -*-
+# 
+require 'spec_helper'
+
+# Specs in this file have access to a helper object that includes
+# the GroundColorsHelper. For example:
+#
+# describe GroundColorsHelper do
+#   describe "string concat" do
+#     it "concats two strings with spaces" do
+#       helper.concat_strings("this","that").should == "this that"
+#     end
+#   end
+# end
+describe GroundColorsHelper do
+end
diff --git a/spec/helpers/ground_pictures_helper_spec.rb b/spec/helpers/ground_pictures_helper_spec.rb
new file mode 100644 (file)
index 0000000..49bac83
--- /dev/null
@@ -0,0 +1,14 @@
+require 'spec_helper'
+
+# Specs in this file have access to a helper object that includes
+# the GroundPicturesHelper. For example:
+#
+# describe GroundPicturesHelper do
+#   describe "string concat" do
+#     it "concats two strings with spaces" do
+#       helper.concat_strings("this","that").should == "this that"
+#     end
+#   end
+# end
+describe GroundPicturesHelper do
+end
index 4a37633..85739de 100644 (file)
@@ -1,3 +1,5 @@
+# -*- encoding: utf-8 -*-
+# 
 require 'spec_helper'
 
 # Specs in this file have access to a helper object that includes
@@ -11,5 +13,4 @@ require 'spec_helper'
 #   end
 # end
 describe HomeHelper do
-  pending "add some examples to (or delete) #{__FILE__}"
 end
index 5b68da9..086a88c 100644 (file)
@@ -1,3 +1,5 @@
+# -*- encoding: utf-8 -*-
+# 
 require 'spec_helper'
 
 # Specs in this file have access to a helper object that includes
@@ -11,5 +13,4 @@ require 'spec_helper'
 #   end
 # end
 describe LicenseGroupsHelper do
-  pending "add some examples to (or delete) #{__FILE__}"
 end
index 832b796..727c056 100644 (file)
@@ -1,3 +1,5 @@
+# -*- encoding: utf-8 -*-
+# 
 require 'spec_helper'
 
 # Specs in this file have access to a helper object that includes
@@ -11,5 +13,4 @@ require 'spec_helper'
 #   end
 # end
 describe LicensesHelper do
-  pending "add some examples to (or delete) #{__FILE__}"
 end
index 85b259b..dcc573e 100644 (file)
@@ -1,3 +1,5 @@
+# -*- encoding: utf-8 -*-
+# 
 require 'spec_helper'
 
 # Specs in this file have access to a helper object that includes
@@ -11,5 +13,4 @@ require 'spec_helper'
 #   end
 # end
 describe OriginalPictureLicenseGroupsHelper do
-  pending "add some examples to (or delete) #{__FILE__}"
 end
index b506205..fe678c1 100644 (file)
@@ -1,3 +1,5 @@
+# -*- encoding: utf-8 -*-
+# 
 require 'spec_helper'
 
 # Specs in this file have access to a helper object that includes
@@ -11,5 +13,4 @@ require 'spec_helper'
 #   end
 # end
 describe OriginalPicturesHelper do
-  pending "add some examples to (or delete) #{__FILE__}"
 end
diff --git a/spec/helpers/panel_colors_helper_spec.rb b/spec/helpers/panel_colors_helper_spec.rb
new file mode 100644 (file)
index 0000000..2f2d817
--- /dev/null
@@ -0,0 +1,16 @@
+# -*- encoding: utf-8 -*-
+# 
+require 'spec_helper'
+
+# Specs in this file have access to a helper object that includes
+# the PanelColorsHelper. For example:
+#
+# describe PanelColorsHelper do
+#   describe "string concat" do
+#     it "concats two strings with spaces" do
+#       helper.concat_strings("this","that").should == "this that"
+#     end
+#   end
+# end
+describe PanelColorsHelper do
+end
index fb0c201..622414f 100644 (file)
@@ -1,3 +1,5 @@
+# -*- encoding: utf-8 -*-
+# 
 require 'spec_helper'
 
 # Specs in this file have access to a helper object that includes
@@ -11,5 +13,4 @@ require 'spec_helper'
 #   end
 # end
 describe PanelPicturesHelper do
-  pending "add some examples to (or delete) #{__FILE__}"
 end
index 8a38388..a3cff28 100644 (file)
@@ -1,3 +1,5 @@
+# -*- encoding: utf-8 -*-
+# 
 require 'spec_helper'
 
 # Specs in this file have access to a helper object that includes
@@ -11,5 +13,4 @@ require 'spec_helper'
 #   end
 # end
 describe PanelsHelper do
-  pending "add some examples to (or delete) #{__FILE__}"
 end
index d0a47d3..ebaaea8 100644 (file)
@@ -1,3 +1,5 @@
+# -*- encoding: utf-8 -*-
+# 
 require 'spec_helper'
 
 # Specs in this file have access to a helper object that includes
@@ -11,5 +13,4 @@ require 'spec_helper'
 #   end
 # end
 describe PicturesHelper do
-  pending "add some examples to (or delete) #{__FILE__}"
 end
index 1da5508..2ce12b2 100644 (file)
@@ -1,3 +1,5 @@
+# -*- encoding: utf-8 -*-
+# 
 require 'spec_helper'
 
 # Specs in this file have access to a helper object that includes
@@ -11,5 +13,4 @@ require 'spec_helper'
 #   end
 # end
 describe ResourcePicturesHelper do
-  pending "add some examples to (or delete) #{__FILE__}"
 end
index 6134c6d..ed083a4 100644 (file)
@@ -1,3 +1,5 @@
+# -*- encoding: utf-8 -*-
+# 
 require 'spec_helper'
 
 # Specs in this file have access to a helper object that includes
@@ -11,5 +13,4 @@ require 'spec_helper'
 #   end
 # end
 describe SpeechBalloonTemplatesHelper do
-  pending "add some examples to (or delete) #{__FILE__}"
 end
index 041cfcf..d89b38c 100644 (file)
@@ -1,3 +1,5 @@
+# -*- encoding: utf-8 -*-
+# 
 require 'spec_helper'
 
 # Specs in this file have access to a helper object that includes
@@ -11,5 +13,4 @@ require 'spec_helper'
 #   end
 # end
 describe SpeechBalloonsHelper do
-  pending "add some examples to (or delete) #{__FILE__}"
 end
index 0de28b6..e0582b8 100644 (file)
@@ -1,3 +1,5 @@
+# -*- encoding: utf-8 -*-
+# 
 require 'spec_helper'
 
 # Specs in this file have access to a helper object that includes
@@ -11,5 +13,4 @@ require 'spec_helper'
 #   end
 # end
 describe SpeechesHelper do
-  pending "add some examples to (or delete) #{__FILE__}"
 end
index 8f36345..39b804f 100644 (file)
@@ -1,3 +1,5 @@
+# -*- encoding: utf-8 -*-
+# 
 require 'spec_helper'
 
 # Specs in this file have access to a helper object that includes
@@ -11,5 +13,4 @@ require 'spec_helper'
 #   end
 # end
 describe SystemHelper do
-  pending "add some examples to (or delete) #{__FILE__}"
 end
index 839a2e7..6b0acad 100644 (file)
@@ -1,3 +1,5 @@
+# -*- encoding: utf-8 -*-
+# 
 require 'spec_helper'
 
 # Specs in this file have access to a helper object that includes
@@ -11,5 +13,4 @@ require 'spec_helper'
 #   end
 # end
 describe SystemPicturesHelper do
-  pending "add some examples to (or delete) #{__FILE__}"
 end
diff --git a/spec/json/color.json b/spec/json/color.json
new file mode 100644 (file)
index 0000000..e9b2ddc
--- /dev/null
@@ -0,0 +1,6 @@
+{\r
+  "white": {\r
+    "code": 0,\r
+    "t": 0\r
+  }\r
+}\r
diff --git a/spec/json/colors.json b/spec/json/colors.json
new file mode 100644 (file)
index 0000000..fba582f
--- /dev/null
@@ -0,0 +1,10 @@
+{\r
+  "white": {\r
+    "code": 255,\r
+    "t": 0\r
+  },\r
+  "black": {\r
+    "code": 0,\r
+    "t": 1\r
+  }\r
+}\r
index 3cfb5ab..fec9dba 100644 (file)
@@ -8,7 +8,7 @@
       "PublicDomain": {\r
         "caption": "Public Domain", \r
         "url": "http://test.com/",\r
-        "system_picture": "Data"\r
+        "system_picture": "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"\r
       }\r
     }\r
   }\r
index fe31ec7..e8b082a 100644 (file)
       "UnknownF1": {\r
         "caption": "Unknown Flag1", \r
         "url": "http://test.com/f1",\r
-        "system_picture": "Dataf1"\r
+        "system_picture": "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"\r
       },\r
       "UnknownF2": {\r
         "caption": "Unknown Flag2", \r
         "url": "http://test.com/f2",\r
-        "system_picture": "Dataf2"\r
+        "system_picture": "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"\r
       }\r
     }\r
   }\r
index ccc4624..745094e 100644 (file)
@@ -1,5 +1,6 @@
+# -*- encoding: utf-8 -*-
+#管理者
 require 'spec_helper'
 
 describe Admin do
-  pending "add some examples to (or delete) #{__FILE__}"
 end
index b1b088b..f7797cf 100644 (file)
@@ -17,17 +17,17 @@ describe Artist do
     end
     
     it 'オーソドックスなデータなら通る' do
-      @artist = FactoryGirl.build :artist, :author_id => @author.id, :default_license_id => @license.id
+      @artist = FactoryGirl.build :artist, :author_id => @author.id
       @artist.should be_valid
     end
     
     context 'nameを検証するとき' do
       it 'nullなら失敗する' do
-        @artist = FactoryGirl.build :artist, :author_id => @author.id, :default_license_id => @license.id, :name => nil
+        @artist = FactoryGirl.build :artist, :author_id => @author.id, :name => nil
         @artist.should_not be_valid
       end
       it '30文字以上なら失敗する' do
-        @artist = FactoryGirl.build :artist, :author_id => @author.id, :default_license_id => @license.id, :name => 'a'*31
+        @artist = FactoryGirl.build :artist, :author_id => @author.id, :name => 'a'*31
         @artist.should_not be_valid
       end
     end
@@ -43,7 +43,7 @@ describe Artist do
   
   describe '単体取得に於いて' do
     before do
-      @artist = FactoryGirl.create :artist, :author_id => @author.id, :default_license_id => @license.id
+      @artist = FactoryGirl.create :artist, :author_id => @author.id
     end
     it '指定の絵師を返す' do
       a = Artist.show @artist.id
@@ -62,9 +62,34 @@ describe Artist do
       end
     end
   end
+  describe '編集取得に於いて' do
+    before do
+      @artist = FactoryGirl.create :artist, :author_id => @author.id
+    end
+    it '指定の絵師を返す' do
+      Artist.any_instance.stub(:own?).and_return(true)
+      r = Artist.edit @artist.id, @author.id
+      r.should eq @artist
+    end
+    context '他人の絵師を開こうとしたとき' do
+      it '403Forbidden例外を返す' do
+        Artist.any_instance.stub(:own?).and_return(false)
+        lambda{
+          Artist.edit @artist.id, @author
+        }.should raise_error(ActiveRecord::Forbidden)
+      end
+    end
+    context '存在しない絵師を開こうとしたとき' do
+      it '404RecordNotFound例外を返す' do
+        lambda{
+          Artist.edit 110, @author
+        }.should raise_error(ActiveRecord::RecordNotFound)
+      end
+    end
+  end
   describe '一覧取得に於いて' do
     before do
-      @artist = FactoryGirl.create :artist, :author_id => @author.id, :default_license_id => @license.id
+      @artist = FactoryGirl.create :artist, :author_id => @author.id
     end
     context 'page補正について' do
       it '文字列から数値に変換される' do
diff --git a/spec/models/color_spec.rb b/spec/models/color_spec.rb
new file mode 100644 (file)
index 0000000..bbb6126
--- /dev/null
@@ -0,0 +1,224 @@
+# -*- encoding: utf-8 -*-
+require 'spec_helper'
+#色マスター
+
+describe Color do
+  before do
+    @f = Rails.root + 'spec/json/color.json'
+    @fs = Rails.root + 'spec/json/colors.json'
+    FactoryGirl.create :admin
+    @user = FactoryGirl.create( :user_yas)
+    @author = @user.author
+    @artist = FactoryGirl.create :artist_yas, :author_id => @author.id
+    @other_user = FactoryGirl.create( :user_yas)
+    @other_author = @other_user.author
+    @other_artist = FactoryGirl.create :artist_yas, :author_id => @other_author.id
+    @sp = FactoryGirl.create :system_picture
+    @lg = FactoryGirl.create :license_group
+    @license = FactoryGirl.create :license, :license_group_id => @lg.id, :system_picture_id => @sp.id
+  end
+  
+  describe '検証に於いて' do
+    before do
+    end
+    
+    it 'オーソドックスなデータなら通る' do
+      @c = FactoryGirl.build :color
+      @c.should be_valid
+    end
+    
+    context 'nameを検証するとき' do
+      before do
+        @c = FactoryGirl.build :color
+      end
+      it 'テストデータの確認' do
+        @c.name = 'a'*50
+        @c.should be_valid
+      end
+      it 'nullなら失敗する' do
+        @c.name = ''
+        @c.should_not be_valid
+      end
+      it '51文字以上なら失敗する' do
+        @c.name = 'a'*51
+        @c.should_not be_valid
+      end
+      it '重複していたら失敗する' do
+        l = FactoryGirl.create :color
+        @c.should_not be_valid
+      end
+    end
+    context 'codeを検証するとき' do
+      before do
+        @c = FactoryGirl.build :color
+      end
+      it 'テストデータの確認' do
+        @c.code = 0xffffff
+        @c.should be_valid
+      end
+      it 'nullなら失敗する' do
+        @c.code = nil
+        @c.should_not be_valid
+      end
+      it '数値でなければ失敗する' do
+        @c.code = 'a'
+        @c.should_not be_valid
+      end
+      it '負なら失敗する' do
+        @c.code = -1
+        @c.should_not be_valid
+      end
+      it '24bit colorでなければ失敗する' do
+        @c.code = 0x1000000
+        @c.should_not be_valid
+      end
+    end
+    context 'tを検証するとき' do
+      before do
+        @c = FactoryGirl.build :color
+      end
+      it 'テストデータの確認' do
+        @c.t = '1'
+        @c.should be_valid
+      end
+      it '数値でなければ失敗する' do
+        @c.t = 'a'
+        @c.should_not be_valid
+      end
+      it '0なら通る' do
+        @c.t = '0'
+        @c.should be_valid
+      end
+      it '負なら失敗する' do
+        @c.t = -1
+        @c.should_not be_valid
+      end
+    end
+  end
+  
+  describe 'インポートに於いて' do
+    before do
+    end
+    context 'つつがなく終わるとき' do
+      it 'ファイルインポートを依頼する' do
+        Color.should_receive(:import_file).with(any_args).exactly(1)
+        Color.stub(:import_file).with(any_args).and_return([])
+        Color.import(@f)
+      end
+      it '色更新を一回依頼する' do
+        Color.stub(:store).with(any_args).and_return(Color.new)
+        Color.should_receive(:store).with(any_args).exactly(1)
+        Color.import(@f)
+      end
+      it '色が追加される' do
+        lambda {
+          Color.import(@f)
+        }.should change Color, :count
+      end
+      it '[]を返す' do
+        r = Color.import(@f)
+        r.should eq []
+      end
+    end
+    context '複数データがつつがなく終わるとき' do
+      it '色更新を二回依頼する' do
+        Color.stub(:store).with(any_args).and_return(Color.new)
+        Color.should_receive(:store).with(any_args).exactly(2)
+        Color.import(@fs)
+      end
+      it '色が二個追加される' do
+        lambda {
+          r = Color.import(@fs)
+        }.should change(Color, :count).by 2
+      end
+      it '[]を返す' do
+        r = Color.import(@fs)
+        r.should eq []
+      end
+    end
+  end
+  
+  describe '単体取得に於いて' do
+    before do
+      @c = FactoryGirl.create :color
+    end
+    it '指定の色を返す' do
+      c = Color.show @c.id
+      c.should eq @c
+    end
+    context '存在しない色を開こうとしたとき' do
+      it '404RecordNotFound例外を返す' do
+        lambda{
+          Color.show 110
+        }.should raise_error(ActiveRecord::RecordNotFound)
+      end
+    end
+  end
+  
+  describe '一覧取得に於いて' do
+    before do
+      @color = FactoryGirl.create :color
+    end
+    context 'page補正について' do
+      it '文字列から数値に変換される' do
+        Color.page('8').should eq 8
+      end
+      it 'nilの場合は1になる' do
+        Color.page().should eq 1
+      end
+      it '0以下の場合は1になる' do
+        Color.page('0').should eq 1
+      end
+    end
+    context 'page_size補正について' do
+      it '文字列から数値に変換される' do
+        Color.page_size('7').should eq 7
+      end
+      it 'nilの場合はColor.default_page_sizeになる' do
+        Color.page_size().should eq Color.default_page_size
+      end
+      it '0以下の場合はColor.default_page_sizeになる' do
+        Color.page_size('0').should eq Color.default_page_size
+      end
+      it 'Color.max_page_sizeを超えた場合はColor.max_page_sizeになる' do
+        Color.page_size('1000').should eq Color.max_page_size
+      end
+    end
+    it 'リストを返す' do
+      cl = Color.list
+      cl.should eq [@color]
+    end
+    it 'tで並んでいる' do
+      ncl = FactoryGirl.create :color, :t => 1, :name => 'name a'
+      cl = Color.list
+      cl.should eq [@color, ncl]
+    end
+    context 'DBに5件あって1ページの件数を2件に変えたとして' do
+      before do
+        @nc2 = FactoryGirl.create :color, :t => 1, :name => 'name a'
+        @nc3 = FactoryGirl.create :color, :t => 3, :name => 'name b'
+        @nc4 = FactoryGirl.create :color, :t => 2, :name => 'name c'
+        @nc5 = FactoryGirl.create :color, :t => 4, :name => 'name d'
+        Color.stub(:default_page_size).and_return(2)
+      end
+      it '通常は2件を返す' do
+        cl = Color.list
+        cl.should have(2).items 
+      end
+      it 'page=1なら末尾2件を返す' do
+        #時系列で並んでいる
+        cl = Color.list( {}, 1)
+        cl.should eq [@color, @nc2]
+      end
+      it 'page=2なら中間2件を返す' do
+        cl = Color.list({}, 2)
+        cl.should eq [@nc4, @nc3]
+      end
+      it 'page=3なら先頭1件を返す' do
+        cl = Color.list({}, 3)
+        cl.should eq [@nc5]
+      end
+    end
+  end
+  
+end
index b4d9f42..c73ec3b 100644 (file)
@@ -35,42 +35,6 @@ describe Comic do
         @comic.should_not be_valid
       end
     end
-    context 'widthを検証するとき' do
-      it 'nullなら失敗する' do
-        @comic = FactoryGirl.build :comic, :author_id => @author.id, :width => nil
-        @comic.should_not be_valid
-      end
-      it '0なら失敗する' do
-        @comic = FactoryGirl.build :comic, :author_id => @author.id, :width => 0
-        @comic.should_not be_valid
-      end
-      it '負でも失敗する' do
-        @comic = FactoryGirl.build :comic, :author_id => @author.id, :width => -1
-        @comic.should_not be_valid
-      end
-      it '正なら通る' do
-        @comic = FactoryGirl.build :comic, :author_id => @author.id, :width => 1
-        @comic.should be_valid
-      end
-    end
-    context 'heightを検証するとき' do
-      it 'nullなら失敗する' do
-        @comic = FactoryGirl.build :comic, :author_id => @author.id, :height => nil
-        @comic.should_not be_valid
-      end
-      it '0なら失敗する' do
-        @comic = FactoryGirl.build :comic, :author_id => @author.id, :height => 0
-        @comic.should_not be_valid
-      end
-      it '負でも失敗する' do
-        @comic = FactoryGirl.build :comic, :author_id => @author.id, :height => -1
-        @comic.should_not be_valid
-      end
-      it '正なら通る' do
-        @comic = FactoryGirl.build :comic, :author_id => @author.id, :height => 1
-        @comic.should be_valid
-      end
-    end
     context 'visibleを検証するとき' do
       it 'nullなら失敗する' do
         @comic = FactoryGirl.build :comic, :author_id => @author.id, :visible => nil
@@ -153,6 +117,31 @@ describe Comic do
       c.should eq @comic
     end
   end
+  describe '編集取得に於いて' do
+    before do
+      @comic = FactoryGirl.create :comic, :author_id => @author.id
+    end
+    it '指定のコミックを返す' do
+      Comic.any_instance.stub(:own?).and_return(true)
+      c = Comic.edit @comic.id, @author.id
+      c.should eq @comic
+    end
+    context '他人のコミックを開こうとしたとき' do
+      it '403Forbidden例外を返す' do
+        Comic.any_instance.stub(:own?).and_return(false)
+        lambda{
+          Comic.edit @comic.id, @author
+        }.should raise_error(ActiveRecord::Forbidden)
+      end
+    end
+    context '存在しないコミックを開こうとしたとき' do
+      it '404RecordNotFound例外を返す' do
+        lambda{
+          Comic.edit 110, @author
+        }.should raise_error(ActiveRecord::RecordNotFound)
+      end
+    end
+  end
   describe '関連テーブルプションに於いて' do
     context 'オプションがないとき' do
       it '2つの項目を含んでいる' do
diff --git a/spec/models/ground_color_spec.rb b/spec/models/ground_color_spec.rb
new file mode 100644 (file)
index 0000000..556956e
--- /dev/null
@@ -0,0 +1,222 @@
+# -*- encoding: utf-8 -*-
+require 'spec_helper'
+#コマの背景間接
+
+describe GroundColor do
+  before do
+    FactoryGirl.create :admin
+    @user = FactoryGirl.create( :user_yas)
+    @author = @user.author
+    @artist = FactoryGirl.create :artist_yas, :author_id => @author.id
+    @other_user = FactoryGirl.create( :user_yas)
+    @other_author = @other_user.author
+    @other_artist = FactoryGirl.create :artist_yas, :author_id => @other_author.id
+    @sp = FactoryGirl.create :system_picture
+    @lg = FactoryGirl.create :license_group
+    @license = FactoryGirl.create :license, :license_group_id => @lg.id, :system_picture_id => @sp.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
+    @panel = FactoryGirl.create :panel, :author_id => @author.id
+    @color = FactoryGirl.create :color
+  end
+  
+  describe '検証に於いて' do
+    before do
+      @gc = FactoryGirl.build :ground_color, :panel_id => @panel.id, :color_id => @color.id
+    end
+    it 'オーソドックスなデータなら通る' do
+      @gc.save
+      @gc.should be_valid
+    end
+    
+    context 'panel_idを検証するとき' do
+      #ネストの保存はnilを許可しなければならないので数値チェックだけ
+      it 'テストデータの確認' do
+        @gc.panel_id = @panel.id
+        @gc.should be_valid
+      end
+      it '数値でなければ失敗する' do
+        @gc.panel_id = 'a'
+        @gc.should_not be_valid
+      end
+    end
+    context 'color_idを検証するとき' do
+      it 'テストデータの確認' do
+        @gc.color_id = @color.id
+        @gc.should be_valid
+      end
+      it 'nullなら失敗する' do
+        @gc.color_id = nil
+        @gc.should_not be_valid
+      end
+      it '数値でなければ失敗する' do
+        @gc.color_id = 'a'
+        @gc.should_not be_valid
+      end
+      it '存在する実素材でなければ失敗する' do
+        @gc.color_id = 0
+        @gc.should_not be_valid
+      end
+    end
+    context 'zを検証するとき' do
+      it 'テストデータの確認' do
+        @gc.z = 1
+        @gc.should be_valid
+      end
+      it 'nullなら失敗する' do
+        @gc.z = nil
+        @gc.should_not be_valid
+      end
+      it '数値でなければ失敗する' do
+        @gc.z = 'a'
+        @gc.should_not be_valid
+      end
+      it '負なら失敗する' do
+        @gc.z = -1
+        @gc.should_not be_valid
+      end
+      it '負なら失敗する' do
+        @gc.z = 0
+        @gc.should_not be_valid
+      end
+    end
+  end
+  describe '一覧取得に於いて' do
+    before do
+      @gc = FactoryGirl.create :ground_color, :panel_id => @panel.id, :color_id => @color.id
+    end
+    context 'page補正について' do
+      it '文字列から数値に変換される' do
+        GroundColor.page('8').should eq 8
+      end
+      it 'nilの場合は1になる' do
+        GroundColor.page().should eq 1
+      end
+      it '0以下の場合は1になる' do
+        GroundColor.page('0').should eq 1
+      end
+    end
+    context 'page_size補正について' do
+      it '文字列から数値に変換される' do
+        GroundColor.page_size('7').should eq 7
+      end
+      it 'nilの場合はGroundColor.default_page_sizeになる' do
+        GroundColor.page_size().should eq GroundColor.default_page_size
+      end
+      it '0以下の場合はGroundColor.default_page_sizeになる' do
+        GroundColor.page_size('0').should eq GroundColor.default_page_size
+      end
+      it 'GroundColor.max_page_sizeを超えた場合はGroundColor.max_page_sizeになる' do
+        GroundColor.page_size('1000').should eq GroundColor.max_page_size
+      end
+    end
+    it 'リストを返す' do
+      pl = GroundColor.list
+      pl.should eq [@gc]
+    end
+    it '時系列で並んでいる' do
+      npl = FactoryGirl.create :ground_color, :panel_id => @panel.id, :color_id => @color.id, :z => 2, :updated_at => Time.now + 100
+      pl = GroundColor.list
+      pl.should eq [npl, @gc]
+    end
+    it '非公開のコマの景色は含まない' do
+      hpl = FactoryGirl.create :panel, :author_id => @author.id, :publish => 0
+      npl = FactoryGirl.create :ground_color, :panel_id => hpl.id, :color_id => @color.id, :updated_at => Time.now + 100
+      pl = GroundColor.list
+      pl.should eq [@gc]
+    end
+    context 'DBに5件あって1ページの件数を2件に変えたとして' do
+      before do
+        @npl2 = FactoryGirl.create :ground_color, :panel_id => @panel.id, :z => 1, :color_id => @color.id, :updated_at => Time.now + 100
+        @npl3 = FactoryGirl.create :ground_color, :panel_id => @panel.id, :z => 2, :color_id => @color.id, :updated_at => Time.now + 200
+        @npl4 = FactoryGirl.create :ground_color, :panel_id => @panel.id, :z => 3, :color_id => @color.id, :updated_at => Time.now + 300
+        @npl5 = FactoryGirl.create :ground_color, :panel_id => @panel.id, :z => 4, :color_id => @color.id, :updated_at => Time.now + 400
+        GroundColor.stub(:default_page_size).and_return(2)
+      end
+      it '通常は2件を返す' do
+        pl = GroundColor.list
+        pl.should have(2).items 
+      end
+      it 'page=1なら末尾2件を返す' do
+        #時系列で並んでいる
+        pl = GroundColor.list( {}, 1)
+        pl.should eq [@npl5, @npl4]
+      end
+      it 'page=2なら中間2件を返す' do
+        pl = GroundColor.list({}, 2)
+        pl.should eq [@npl3, @npl2]
+      end
+      it 'page=3なら先頭1件を返す' do
+        pl = GroundColor.list({}, 3)
+        pl.should eq [@gc]
+      end
+    end
+  end
+  describe 'list関連テーブルプションに於いて' do
+    it 'includeキーを含んでいる' do
+      r = GroundColor.list_opt
+      r.has_key?(:include).should be_true
+    end
+    it '2つの項目を含んでいる' do
+      r = GroundColor.list_opt[:include]
+      r.should have(2).items
+    end
+    it 'コマを含んでいる' do
+      r = GroundColor.list_opt[:include]
+      r.has_key?(:panel).should be_true
+    end
+      it 'コマは作家を含んでいる' do
+        r = GroundColor.list_opt[:include]
+        r[:panel].has_key?(:author).should be_true
+      end
+    it '色を含んでいる' do
+      r = GroundColor.list_opt[:include]
+      r.has_key?(:color).should be_true
+    end
+  end
+  describe 'json一覧出力オプションに於いて' do
+    it 'includeキーを含んでいる' do
+      r = GroundColor.list_json_opt
+      r.has_key?(:include).should be_true
+    end
+    it '2つの項目を含んでいる' do
+      r = GroundColor.list_json_opt[:include]
+      r.should have(2).items
+    end
+    it 'コマを含んでいる' do
+      r = GroundColor.list_json_opt[:include]
+      r.has_key?(:panel).should be_true
+    end
+      it 'コマは作家を含んでいる' do
+        r = GroundColor.list_json_opt[:include]
+        r[:panel].has_key?(:author).should be_true
+      end
+    it '色を含んでいる' do
+      r = GroundColor.list_json_opt[:include]
+      r.has_key?(:color).should be_true
+    end
+  end
+  
+  describe '自分のコマで使った色一覧取得に於いて' do
+    before do
+      @gc = FactoryGirl.create :ground_color, :panel_id => @panel.id, :color_id => @color.id
+    end
+    it 'リストを返す' do
+      pl = GroundColor.mylist @author
+      pl.should eq [@gc]
+    end
+    it '時系列で並んでいる' do
+      npl = FactoryGirl.create :ground_color, :panel_id => @panel.id, :color_id => @color.id, :z => 2, :updated_at => Time.now + 100
+      pl = GroundColor.mylist @author
+      pl.should eq [npl, @gc]
+    end
+    it '他人のコマの景色は公開でも含まない' do
+      hpl = FactoryGirl.create :panel, :author_id => @other_author.id, :publish => 1
+      npl = FactoryGirl.create :ground_color, :panel_id => hpl.id, :color_id => @color.id
+      pl = GroundColor.mylist @author
+      pl.should eq [@gc]
+    end
+  end
+  
+end
diff --git a/spec/models/ground_picture_spec.rb b/spec/models/ground_picture_spec.rb
new file mode 100644 (file)
index 0000000..9a45e75
--- /dev/null
@@ -0,0 +1,237 @@
+# -*- encoding: utf-8 -*-
+require 'spec_helper'
+#コマの画像背景
+
+describe GroundPicture do
+  before do
+    FactoryGirl.create :admin
+    @user = FactoryGirl.create( :user_yas)
+    @author = @user.author
+    @artist = FactoryGirl.create :artist_yas, :author_id => @author.id
+    @other_user = FactoryGirl.create( :user_yas)
+    @other_author = @other_user.author
+    @other_artist = FactoryGirl.create :artist_yas, :author_id => @other_author.id
+    @sp = FactoryGirl.create :system_picture
+    @lg = FactoryGirl.create :license_group
+    @license = FactoryGirl.create :license, :license_group_id => @lg.id, :system_picture_id => @sp.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
+    @panel = FactoryGirl.create :panel, :author_id => @author.id
+  end
+  
+  describe '検証に於いて' do
+    before do
+      @gp = FactoryGirl.build :ground_picture, :panel_id => @panel.id, :picture_id => @p.id
+    end
+    it 'オーソドックスなデータなら通る' do
+      @gp.save
+      @gp.should be_valid
+    end
+    
+    context 'panel_idを検証するとき' do
+      #ネストの保存はnilを許可しなければならないので数値チェックだけ
+      it 'テストデータの確認' do
+        @gp.panel_id = @panel.id
+        @gp.should be_valid
+      end
+      it '数値でなければ失敗する' do
+        @gp.panel_id = 'a'
+        @gp.should_not be_valid
+      end
+    end
+    context 'picture_idを検証するとき' do
+      it 'テストデータの確認' do
+        @gp.picture_id = @panel.id
+        @gp.should be_valid
+      end
+      it 'nullなら失敗する' do
+        @gp.picture_id = nil
+        @gp.should_not be_valid
+      end
+      it '数値でなければ失敗する' do
+        @gp.picture_id = 'a'
+        @gp.should_not be_valid
+      end
+      it '存在する実素材でなければ失敗する' do
+        @gp.picture_id = 0
+        @gp.should_not be_valid
+      end
+    end
+    context 'zを検証するとき' do
+      it 'テストデータの確認' do
+        @gp.z = 1
+        @gp.should be_valid
+      end
+      it 'nullなら失敗する' do
+        @gp.z = nil
+        @gp.should_not be_valid
+      end
+      it '数値でなければ失敗する' do
+        @gp.z = 'a'
+        @gp.should_not be_valid
+      end
+      it '負なら失敗する' do
+        @gp.z = -1
+        @gp.should_not be_valid
+      end
+      it '負なら失敗する' do
+        @gp.z = 0
+        @gp.should_not be_valid
+      end
+    end
+  end
+  describe '一覧取得に於いて' do
+    before do
+      @gp = FactoryGirl.create :ground_picture, :panel_id => @panel.id, :picture_id => @p.id
+    end
+    context 'page補正について' do
+      it '文字列から数値に変換される' do
+        GroundPicture.page('8').should eq 8
+      end
+      it 'nilの場合は1になる' do
+        GroundPicture.page().should eq 1
+      end
+      it '0以下の場合は1になる' do
+        GroundPicture.page('0').should eq 1
+      end
+    end
+    context 'page_size補正について' do
+      it '文字列から数値に変換される' do
+        GroundPicture.page_size('7').should eq 7
+      end
+      it 'nilの場合はGroundPicture.default_page_sizeになる' do
+        GroundPicture.page_size().should eq GroundPicture.default_page_size
+      end
+      it '0以下の場合はGroundPicture.default_page_sizeになる' do
+        GroundPicture.page_size('0').should eq GroundPicture.default_page_size
+      end
+      it 'GroundPicture.max_page_sizeを超えた場合はGroundPicture.max_page_sizeになる' do
+        GroundPicture.page_size('1000').should eq GroundPicture.max_page_size
+      end
+    end
+    it 'リストを返す' do
+      pl = GroundPicture.list
+      pl.should eq [@gp]
+    end
+    it '時系列で並んでいる' do
+      npl = FactoryGirl.create :ground_picture, :panel_id => @panel.id, :picture_id => @p.id, :z => 2, :updated_at => Time.now + 100
+      pl = GroundPicture.list
+      pl.should eq [npl, @gp]
+    end
+    it '非公開のコマの景色は含まない' do
+      hpl = FactoryGirl.create :panel, :author_id => @author.id, :publish => 0
+      npl = FactoryGirl.create :ground_picture, :panel_id => hpl.id, :picture_id => @p.id, :updated_at => Time.now + 100
+      pl = GroundPicture.list
+      pl.should eq [@gp]
+    end
+    context 'DBに5件あって1ページの件数を2件に変えたとして' do
+      before do
+        @npl2 = FactoryGirl.create :ground_picture, :panel_id => @panel.id, :z => 1, :picture_id => @p.id, :updated_at => Time.now + 100
+        @npl3 = FactoryGirl.create :ground_picture, :panel_id => @panel.id, :z => 2, :picture_id => @p.id, :updated_at => Time.now + 200
+        @npl4 = FactoryGirl.create :ground_picture, :panel_id => @panel.id, :z => 3, :picture_id => @p.id, :updated_at => Time.now + 300
+        @npl5 = FactoryGirl.create :ground_picture, :panel_id => @panel.id, :z => 4, :picture_id => @p.id, :updated_at => Time.now + 400
+        GroundPicture.stub(:default_page_size).and_return(2)
+      end
+      it '通常は2件を返す' do
+        pl = GroundPicture.list
+        pl.should have(2).items 
+      end
+      it 'page=1なら末尾2件を返す' do
+        #時系列で並んでいる
+        pl = GroundPicture.list( {}, 1)
+        pl.should eq [@npl5, @npl4]
+      end
+      it 'page=2なら中間2件を返す' do
+        pl = GroundPicture.list({}, 2)
+        pl.should eq [@npl3, @npl2]
+      end
+      it 'page=3なら先頭1件を返す' do
+        pl = GroundPicture.list({}, 3)
+        pl.should eq [@gp]
+      end
+    end
+  end
+  describe 'list関連テーブルプションに於いて' do
+    it 'includeキーを含んでいる' do
+      r = GroundPicture.list_opt
+      r.has_key?(:include).should be_true
+    end
+    it '2つの項目を含んでいる' do
+      r = GroundPicture.list_opt[:include]
+      r.should have(2).items
+    end
+    it 'コマを含んでいる' do
+      r = GroundPicture.list_opt[:include]
+      r.has_key?(:panel).should be_true
+    end
+      it 'コマは作家を含んでいる' do
+        r = GroundPicture.list_opt[:include]
+        r[:panel].has_key?(:author).should be_true
+      end
+    it '実素材を含んでいる' do
+      r = GroundPicture.list_opt[:include]
+      r.has_key?(:picture).should be_true
+    end
+      it '実素材は絵師を含んでいる' do
+        r = GroundPicture.list_opt[:include]
+        r[:picture].has_key?(:artist).should be_true
+      end
+      it '実素材はライセンスを含んでいる' do
+        r = GroundPicture.list_opt[:include]
+        r[:picture].has_key?(:license).should be_true
+      end
+  end
+  describe 'json一覧出力オプションに於いて' do
+    it 'includeキーを含んでいる' do
+      r = GroundPicture.list_json_opt
+      r.has_key?(:include).should be_true
+    end
+    it '2つの項目を含んでいる' do
+      r = GroundPicture.list_json_opt[:include]
+      r.should have(2).items
+    end
+    it 'コマを含んでいる' do
+      r = GroundPicture.list_json_opt[:include]
+      r.has_key?(:panel).should be_true
+    end
+      it 'コマは作家を含んでいる' do
+        r = GroundPicture.list_json_opt[:include]
+        r[:panel].has_key?(:author).should be_true
+      end
+    it '実素材を含んでいる' do
+      r = GroundPicture.list_json_opt[:include]
+      r.has_key?(:picture).should be_true
+    end
+      it '実素材は絵師を含んでいる' do
+        r = GroundPicture.list_json_opt[:include]
+        r[:picture].has_key?(:artist).should be_true
+      end
+      it '実素材はライセンスを含んでいる' do
+        r = GroundPicture.list_json_opt[:include]
+        r[:picture].has_key?(:license).should be_true
+      end
+  end
+  
+  describe '自分のコマで使った景色画像一覧取得に於いて' do
+    before do
+      @gp = FactoryGirl.create :ground_picture, :panel_id => @panel.id, :picture_id => @p.id
+    end
+    it 'リストを返す' do
+      pl = GroundPicture.mylist @author
+      pl.should eq [@gp]
+    end
+    it '時系列で並んでいる' do
+      npl = FactoryGirl.create :ground_picture, :panel_id => @panel.id, :picture_id => @p.id, :z => 2, :updated_at => Time.now + 100
+      pl = GroundPicture.mylist @author
+      pl.should eq [npl, @gp]
+    end
+    it '他人のコマの景色は公開でも含まない' do
+      hpl = FactoryGirl.create :panel, :author_id => @other_author.id, :publish => 1
+      npl = FactoryGirl.create :ground_picture, :panel_id => hpl.id, :picture_id => @p.id
+      pl = GroundPicture.mylist @author
+      pl.should eq [@gp]
+    end
+  end
+  
+end
index cea37e9..4314fd3 100644 (file)
@@ -1,4 +1,5 @@
 # -*- encoding: utf-8 -*-
+#原画
 require 'spec_helper'
 
 describe OriginalPicture do
@@ -141,6 +142,23 @@ describe OriginalPicture do
         @op.should_not be_valid
       end
     end
+    context 'md5を検証するとき' do
+      before do
+        @op = FactoryGirl.build :original_picture
+      end
+      it 'テストデータの確認' do
+        @op.md5 = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+        @op.should be_valid
+      end
+      it 'nullなら失敗する' do
+        @op.md5 = ''
+        @op.should_not be_valid
+      end
+      it '32文字以上なら失敗する' do
+        @op.md5 = 'a'*33
+        @op.should_not be_valid
+      end
+    end
   end
   
   describe 'データ補充に於いて' do
@@ -216,19 +234,41 @@ describe OriginalPicture do
       end
     end
   end
+  describe '単体出力オプションに於いて' do
+    it 'includeキーを含んでいる' do
+      r = OriginalPicture.show_include_opt
+      r.has_key?(:include).should be_true
+    end
+    it '2つの項目を含んでいる' do
+      r = OriginalPicture.show_include_opt[:include]
+      r.should have(2).items
+    end
+    it '素材を含んでいる' do
+      r = OriginalPicture.show_include_opt[:include]
+      r.has_key?(:resource_picture).should be_true
+    end
+    it '実素材を含んでいる' do
+      r = OriginalPicture.show_include_opt[:include]
+      r.has_key?(:pictures).should be_true
+    end
+  end
   describe 'json単体出力オプションに於いて' do
-    it 'includeキーを含んでいる' do\r
-      r = OriginalPicture.show_json_include_opt\r
-      r.has_key?(:include).should be_true\r
-    end\r
-    it '1つの項目を含んでいる' do\r
-      r = OriginalPicture.show_json_include_opt[:include]\r
-      r.should have(1).items\r
-    end\r
-    it '素材を含んでいる' do\r
-      r = OriginalPicture.show_json_include_opt[:include]\r
-      r.has_key?(:resource_picture).should be_true\r
-    end\r
+    it 'includeキーを含んでいる' do
+      r = OriginalPicture.show_json_include_opt
+      r.has_key?(:include).should be_true
+    end
+    it '2つの項目を含んでいる' do
+      r = OriginalPicture.show_json_include_opt[:include]
+      r.should have(2).items
+    end
+    it '素材を含んでいる' do
+      r = OriginalPicture.show_json_include_opt[:include]
+      r.has_key?(:resource_picture).should be_true
+    end
+    it '実素材を含んでいる' do
+      r = OriginalPicture.show_json_include_opt[:include]
+      r.has_key?(:pictures).should be_true
+    end
   end
   describe '一覧取得に於いて' do
     before do
@@ -300,34 +340,66 @@ describe OriginalPicture do
       end
     end
   end
-  describe 'list関連テーブルプションに於いて' do\r
-    it 'includeキーを含んでいる' do\r
-      r = OriginalPicture.list_opt\r
-      r.has_key?(:include).should be_true\r
-    end\r
-    it '1つの項目を含んでいる' do\r
-      r = OriginalPicture.list_opt[:include]\r
-      r.should have(1).items\r
-    end\r
-    it '素材を含んでいる' do\r
-      r = OriginalPicture.list_opt[:include]\r
-      r.has_key?(:resource_picture).should be_true\r
-    end\r
+  describe 'list関連テーブルプションに於いて' do
+    it 'includeキーを含んでいる' do
+      r = OriginalPicture.list_opt
+      r.has_key?(:include).should be_true
+    end
+    it '2つの項目を含んでいる' do
+      r = OriginalPicture.list_opt[:include]
+      r.should have(2).items
+    end
+    it '素材を含んでいる' do
+      r = OriginalPicture.list_opt[:include]
+      r.has_key?(:resource_picture).should be_true
+    end
+    it '実素材を含んでいる' do
+      r = OriginalPicture.list_opt[:include]
+      r.has_key?(:pictures).should be_true
+    end
+  end
+  describe 'json一覧出力オプションに於いて' do
+    it 'includeキーを含んでいる' do
+      r = OriginalPicture.list_json_opt
+      r.has_key?(:include).should be_true
+    end
+    it '2つの項目を含んでいる' do
+      r = OriginalPicture.list_json_opt[:include]
+      r.should have(2).items
+    end
+    it '素材を含んでいる' do
+      r = OriginalPicture.list_json_opt[:include]
+      r.has_key?(:resource_picture).should be_true
+    end
+    it '実素材を含んでいる' do
+      r = OriginalPicture.list_json_opt[:include]
+      r.has_key?(:pictures).should be_true
+    end
+  end
+  describe '更新履歴一覧取得に於いて' do
+    before do
+      @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
+      @p = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 0,
+        :original_picture_id => @op.id
+      @op2 = FactoryGirl.create :original_picture, :artist_id => @artist.id
+    end
+    it 'リストを返す' do
+      r = @op.history
+      r.should eq [@p]
+    end
+    it '他の原画の実素材は含んでいない' do
+      @p2 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 0,
+        :original_picture_id => @op2.id
+      r = @op.history
+      r.should eq [@p]
+    end
+    it 'revisionで並んでいる' do
+      @p2 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
+        :original_picture_id => @op.id
+      r = @op.history
+      r.should eq [@p2, @p]
+    end
   end
-  describe 'json一覧出力オプションに於いて' do\r
-    it 'includeキーを含んでいる' do\r
-      r = OriginalPicture.list_json_opt\r
-      r.has_key?(:include).should be_true\r
-    end\r
-    it '1つの項目を含んでいる' do\r
-      r = OriginalPicture.list_json_opt[:include]\r
-      r.should have(1).items\r
-    end\r
-    it '素材を含んでいる' do\r
-      r = OriginalPicture.list_json_opt[:include]\r
-      r.has_key?(:resource_picture).should be_true\r
-    end\r
-  end\r
   describe 'RMagick変換に於いて' do
     before do
       @op = FactoryGirl.build :original_picture, :artist_id => @artist.id
@@ -375,36 +447,36 @@ describe OriginalPicture do
         #すべての処理が正常パターンで通過すれば、一番深い分岐まで通る。
         #それで外部のメソッド呼び出しだけに着目してテストする。
         OriginalPicture.any_instance.stub(:data_to_mgk).with(any_args).and_return(Mgk.new)
-        OriginalPicture.any_instance.stub(:save).with(any_args).and_return(true)\r
+        OriginalPicture.any_instance.stub(:save).with(any_args).and_return(true)
         PictureIO::LocalPicture.any_instance.stub(:put).with(any_args).and_return(true)
       end
       it 'RMagick変換を依頼している' do
         OriginalPicture.any_instance.should_receive(:data_to_mgk).exactly(1)
-        @op.store 'bindata', @artist\r
+        @op.store 'bindata', @artist
       end
       it '自身に属性をセットしている' do
         OriginalPicture.any_instance.should_receive(:attributes=).exactly(1)
-        @op.store 'bindata', @artist\r
+        @op.store 'bindata', @artist
       end
       it '自身が保存されている' do
-        OriginalPicture.any_instance.should_receive(:save).exactly(1)\r
-        @op.store 'bindata', @artist\r
+        OriginalPicture.any_instance.should_receive(:save).exactly(1)
+        @op.store 'bindata', @artist
       end
       it 'PictureIoに画像データの保存を依頼している' do
         PictureIO::LocalPicture.any_instance.should_receive(:put).with(any_args).exactly(1)
-        @op.store 'bindata', @artist\r
+        @op.store 'bindata', @artist
       end
     end
     context 'つつがなく終わるとき' do
       before do
         #すべての処理を正常パターンで通過させ、保存機能をチェックする。
         OriginalPicture.any_instance.stub(:data_to_mgk).with(any_args).and_return(Mgk.new)
-#        OriginalPicture.any_instance.stub(:save).with(any_args).and_return(true)\r
+#        OriginalPicture.any_instance.stub(:save).with(any_args).and_return(true)
         PictureIO::LocalPicture.any_instance.stub(:put).with(any_args).and_return(true)
       end
       it '自身に属性をセットしている' do
         lambda {
-          @op.store 'bindata', @artist\r
+          @op.store 'bindata', @artist
         }.should change @op, :filesize
       end
       it '原画モデルが作成されている' do
@@ -414,10 +486,10 @@ describe OriginalPicture do
       end
       it '原画が保存されている' do
         @op.store 'bindata', @artist
-        OriginalPicture.find(@op).should_not be_nil\r
+        OriginalPicture.find(@op).should_not be_nil
       end
       it 'Trueを返す' do
-        @op.store('bindata', @artist).should eq true\r
+        @op.store('bindata', @artist).should eq true
       end
     end
     #以下から例外ケース。処理先頭から失敗させていく
@@ -426,49 +498,49 @@ describe OriginalPicture do
         OriginalPicture.any_instance.stub(:data_to_mgk).with(any_args).and_return(false)
       end
       it 'falseを返す' do
-        @op.store('bindata', @artist).should be_false\r
+        @op.store('bindata', @artist).should be_false
       end
       it '自身の保存は呼ばれていない' do
-        OriginalPicture.any_instance.should_not_receive(:save)\r
-        @op.store('bindata', @artist)\r
+        OriginalPicture.any_instance.should_not_receive(:save)
+        @op.store('bindata', @artist)
       end
     end
     context '自身の保存に失敗したとき' do
       before do
         OriginalPicture.any_instance.stub(:data_to_mgk).with(any_args).and_return(Mgk.new)
-        OriginalPicture.any_instance.stub(:save).with(any_args).and_return(false)\r
+        OriginalPicture.any_instance.stub(:save).with(any_args).and_return(false)
       end
       it 'falseを返す' do
-        @op.store('bindata', @artist).should be_false\r
+        @op.store('bindata', @artist).should be_false
       end
       it '更新されていない' do
         @op.store('bindata', @artist)
-        @op.should be_a_new OriginalPicture\r
+        @op.should be_a_new OriginalPicture
       end
       it '原画の保存は呼ばれていない' do
-        PictureIO::LocalPicture.any_instance.should_not_receive(:put)\r
+        PictureIO::LocalPicture.any_instance.should_not_receive(:put)
       end
     end
     context '原画の保存に失敗したとき' do
       before do
         OriginalPicture.any_instance.stub(:data_to_mgk).with(any_args).and_return(Mgk.new)
-        OriginalPicture.any_instance.stub(:save).with(any_args).and_return(true)\r
+        OriginalPicture.any_instance.stub(:save).with(any_args).and_return(true)
         PictureIO::LocalPicture.any_instance.stub(:put).with(any_args).and_return(false)
       end
       it 'falseを返す' do
-        @op.store('bindata', @artist).should be_false\r
+        @op.store('bindata', @artist).should be_false
       end
       it '更新されていない' do
-        @op.store('bindata', @artist)\r
-        @op.should be_a_new OriginalPicture\r
+        @op.store('bindata', @artist)
+        @op.should be_a_new OriginalPicture
       end
       it '対象素材オブジェクトの保存は呼ばれていない' do
-        ResourcePicture.any_instance.should_not_receive(:save)\r
-        @op.store('bindata', @artist)\r
+        ResourcePicture.any_instance.should_not_receive(:save)
+        @op.store('bindata', @artist)
       end
       it '全体エラーメッセージがセットされている' do
         lambda {
-          @op.store('bindata', @artist)\r
+          @op.store('bindata', @artist)
         }.should change(@op.errors[:base], :count)
       end
     end
diff --git a/spec/models/panel_color_spec.rb b/spec/models/panel_color_spec.rb
new file mode 100644 (file)
index 0000000..7f0c5b5
--- /dev/null
@@ -0,0 +1,217 @@
+# -*- encoding: utf-8 -*-
+require 'spec_helper'
+#コマの色背景
+
+describe PanelColor do
+  before do
+    FactoryGirl.create :admin
+    @user = FactoryGirl.create( :user_yas)
+    @author = @user.author
+    @artist = FactoryGirl.create :artist_yas, :author_id => @author.id
+    @other_user = FactoryGirl.create( :user_yas)
+    @other_author = @other_user.author
+    @other_artist = FactoryGirl.create :artist_yas, :author_id => @other_author.id
+    @sp = FactoryGirl.create :system_picture
+    @lg = FactoryGirl.create :license_group
+    @license = FactoryGirl.create :license, :license_group_id => @lg.id, :system_picture_id => @sp.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
+    @panel = FactoryGirl.create :panel, :author_id => @author.id
+  end
+  
+  describe '検証に於いて' do
+    before do
+      @pc = FactoryGirl.build :panel_color, :panel_id => @panel.id
+    end
+    it 'オーソドックスなデータなら通る' do
+      @pc.save
+      @pc.should be_valid
+    end
+    
+    context 'panel_idを検証するとき' do
+      #ネストの保存はnilを許可しなければならないので数値チェックだけ
+      it 'テストデータの確認' do
+        @pc.panel_id = @panel.id
+        @pc.should be_valid
+      end
+      it '数値でなければ失敗する' do
+        @pc.panel_id = 'a'
+        @pc.should_not be_valid
+      end
+    end
+    context 'codeを検証するとき' do
+      it 'テストデータの確認' do
+        @pc.code = 0xffffff
+        @pc.should be_valid
+      end
+      it 'nullなら失敗する' do
+        @pc.code = nil
+        @pc.should_not be_valid
+      end
+      it '数値でなければ失敗する' do
+        @pc.code = 'a'
+        @pc.should_not be_valid
+      end
+      it '負なら失敗する' do
+        @pc.code = -1
+        @pc.should_not be_valid
+      end
+      it '24bit colorでなければ失敗する' do
+        @pc.code = 0x1000000
+        @pc.should_not be_valid
+      end
+    end
+    context 'zを検証するとき' do
+      it 'テストデータの確認' do
+        @pc.z = 1
+        @pc.should be_valid
+      end
+      it 'nullなら失敗する' do
+        @pc.z = nil
+        @pc.should_not be_valid
+      end
+      it '数値でなければ失敗する' do
+        @pc.z = 'a'
+        @pc.should_not be_valid
+      end
+      it '負なら失敗する' do
+        @pc.z = -1
+        @pc.should_not be_valid
+      end
+      it '負なら失敗する' do
+        @pc.z = 0
+        @pc.should_not be_valid
+      end
+    end
+  end
+  describe '一覧取得に於いて' do
+    before do
+      @pc = FactoryGirl.create :panel_color, :panel_id => @panel.id
+    end
+    context 'page補正について' do
+      it '文字列から数値に変換される' do
+        PanelColor.page('8').should eq 8
+      end
+      it 'nilの場合は1になる' do
+        PanelColor.page().should eq 1
+      end
+      it '0以下の場合は1になる' do
+        PanelColor.page('0').should eq 1
+      end
+    end
+    context 'page_size補正について' do
+      it '文字列から数値に変換される' do
+        PanelColor.page_size('7').should eq 7
+      end
+      it 'nilの場合はPanelColor.default_page_sizeになる' do
+        PanelColor.page_size().should eq PanelColor.default_page_size
+      end
+      it '0以下の場合はPanelColor.default_page_sizeになる' do
+        PanelColor.page_size('0').should eq PanelColor.default_page_size
+      end
+      it 'PanelColor.max_page_sizeを超えた場合はPanelColor.max_page_sizeになる' do
+        PanelColor.page_size('1000').should eq PanelColor.max_page_size
+      end
+    end
+    it 'リストを返す' do
+      pl = PanelColor.list
+      pl.should eq [@pc]
+    end
+    it '時系列で並んでいる' do
+      npl = FactoryGirl.create :panel_color, :panel_id => @panel.id, :z => 2, :updated_at => Time.now + 100
+      pl = PanelColor.list
+      pl.should eq [npl, @pc]
+    end
+    it '非公開のコマの景色は含まない' do
+      hpl = FactoryGirl.create :panel, :author_id => @author.id, :publish => 0
+      npl = FactoryGirl.create :panel_color, :panel_id => hpl.id, :updated_at => Time.now + 100
+      pl = PanelColor.list
+      pl.should eq [@pc]
+    end
+    context 'DBに5件あって1ページの件数を2件に変えたとして' do
+      before do
+        @npl2 = FactoryGirl.create :panel_color, :panel_id => @panel.id, :z => 1, :updated_at => Time.now + 100
+        @npl3 = FactoryGirl.create :panel_color, :panel_id => @panel.id, :z => 2, :updated_at => Time.now + 200
+        @npl4 = FactoryGirl.create :panel_color, :panel_id => @panel.id, :z => 3, :updated_at => Time.now + 300
+        @npl5 = FactoryGirl.create :panel_color, :panel_id => @panel.id, :z => 4, :updated_at => Time.now + 400
+        PanelColor.stub(:default_page_size).and_return(2)
+      end
+      it '通常は2件を返す' do
+        pl = PanelColor.list
+        pl.should have(2).items 
+      end
+      it 'page=1なら末尾2件を返す' do
+        #時系列で並んでいる
+        pl = PanelColor.list( {}, 1)
+        pl.should eq [@npl5, @npl4]
+      end
+      it 'page=2なら中間2件を返す' do
+        pl = PanelColor.list({}, 2)
+        pl.should eq [@npl3, @npl2]
+      end
+      it 'page=3なら先頭1件を返す' do
+        pl = PanelColor.list({}, 3)
+        pl.should eq [@pc]
+      end
+    end
+  end
+  describe 'list関連テーブルプションに於いて' do
+    it 'includeキーを含んでいる' do
+      r = PanelColor.list_opt
+      r.has_key?(:include).should be_true
+    end
+    it '1つの項目を含んでいる' do
+      r = PanelColor.list_opt[:include]
+      r.should have(1).items
+    end
+    it 'コマを含んでいる' do
+      r = PanelColor.list_opt[:include]
+      r.has_key?(:panel).should be_true
+    end
+      it 'コマは作家を含んでいる' do
+        r = PanelColor.list_opt[:include]
+        r[:panel].has_key?(:author).should be_true
+      end
+  end
+  describe 'json一覧出力オプションに於いて' do
+    it 'includeキーを含んでいる' do
+      r = PanelColor.list_json_opt
+      r.has_key?(:include).should be_true
+    end
+    it '1つの項目を含んでいる' do
+      r = PanelColor.list_json_opt[:include]
+      r.should have(1).items
+    end
+    it 'コマを含んでいる' do
+      r = PanelColor.list_json_opt[:include]
+      r.has_key?(:panel).should be_true
+    end
+      it 'コマは作家を含んでいる' do
+        r = PanelColor.list_json_opt[:include]
+        r[:panel].has_key?(:author).should be_true
+      end
+  end
+  
+  describe '自分のコマで使った色一覧取得に於いて' do
+    before do
+      @pc = FactoryGirl.create :panel_color, :panel_id => @panel.id
+    end
+    it 'リストを返す' do
+      pl = PanelColor.mylist @author
+      pl.should eq [@pc]
+    end
+    it '時系列で並んでいる' do
+      npl = FactoryGirl.create :panel_color, :panel_id => @panel.id, :z => 2, :updated_at => Time.now + 100
+      pl = PanelColor.mylist @author
+      pl.should eq [npl, @pc]
+    end
+    it '他人のコマの景色は公開でも含まない' do
+      hpl = FactoryGirl.create :panel, :author_id => @other_author.id, :publish => 1
+      npl = FactoryGirl.create :panel_color, :panel_id => hpl.id
+      pl = PanelColor.mylist @author
+      pl.should eq [@pc]
+    end
+  end
+  
+end
index 09a3a47..f3a70a3 100644 (file)
@@ -23,9 +23,12 @@ describe PanelPicture do
     before do
       @pp = FactoryGirl.build :panel_picture, :panel_id => @panel.id, :picture_id => @p.id,
         :width => @p.width, :height => @p.height
+      Picture.any_instance.stub(:flag_reverse).with(any_args).and_return(0)
+      Picture.any_instance.stub(:flag_resize).with(any_args).and_return(0)
+      Picture.any_instance.stub(:flag_sync_vh).with(any_args).and_return(0)
     end
     it 'オーソドックスなデータなら通る' do
-      @pp.save!
+      @pp.save
       @pp.should be_valid
     end
     
@@ -100,9 +103,6 @@ describe PanelPicture do
     end
     context 'widthを検証するとき' do
       before do
-        Picture.any_instance.stub(:flag_reverse).with(any_args).and_return(0)
-        Picture.any_instance.stub(:flag_resize).with(any_args).and_return(0)
-        Picture.any_instance.stub(:flag_sync_vh).with(any_args).and_return(0)
       end
       it 'テストデータの確認' do
         @pp.width = 1
@@ -122,7 +122,6 @@ describe PanelPicture do
       end
       context  '反転許可のとき' do
         before do
-          Picture.any_instance.stub(:flag_reverse).with(any_args).and_return(0)
         end
         it '負でも通る' do
           @pp.width = -1
@@ -140,7 +139,6 @@ describe PanelPicture do
       end
       context  'サイズ変更許可のとき' do
         before do
-          Picture.any_instance.stub(:flag_resize).with(any_args).and_return(0)
         end
         it '実素材のサイズと違っても通る' do
           @pp.width = @p.width-1
@@ -158,7 +156,6 @@ describe PanelPicture do
       end
       context  '縦横比変更許可のとき' do
         before do
-          Picture.any_instance.stub(:flag_sync_vh).with(any_args).and_return(0)
         end
         it '実素材の縦横比と違っても通る' do
           @pp.width = @p.width / 2
@@ -177,9 +174,6 @@ describe PanelPicture do
     end
     context 'heightを検証するとき' do
       before do
-        Picture.any_instance.stub(:flag_reverse).with(any_args).and_return(0)
-        Picture.any_instance.stub(:flag_resize).with(any_args).and_return(0)
-        Picture.any_instance.stub(:flag_sync_vh).with(any_args).and_return(0)
       end
       it 'テストデータの確認' do
         @pp.height = '1'
@@ -203,7 +197,6 @@ describe PanelPicture do
       end
       context  '反転許可のとき' do
         before do
-          Picture.any_instance.stub(:flag_reverse).with(any_args).and_return(0)
         end
         it '負でも通る' do
           @pp.height = -1
@@ -221,7 +214,6 @@ describe PanelPicture do
       end
       context  'サイズ変更許可のとき' do
         before do
-          Picture.any_instance.stub(:flag_resize).with(any_args).and_return(0)
         end
         it '実素材のサイズと違っても通る' do
           @pp.height = @p.height-1
@@ -239,7 +231,6 @@ describe PanelPicture do
       end
       context  '縦横比変更許可のとき' do
         before do
-          Picture.any_instance.stub(:flag_sync_vh).with(any_args).and_return(0)
         end
         it '実素材の縦横比と違っても通る' do
           @pp.height = @p.height / 2
@@ -296,6 +287,24 @@ describe PanelPicture do
         @pp.should_not be_valid
       end
     end
+    context 'picture_idを検証するとき' do
+      it 'テストデータの確認' do
+        @pp.picture_id = @p.id
+        @pp.should be_valid
+      end
+      it 'nullなら失敗する' do
+        @pp.picture_id = nil
+        @pp.should_not be_valid
+      end
+      it '数値でなければ失敗する' do
+        @pp.picture_id = 'a'
+        @pp.should_not be_valid
+      end
+      it '存在する実素材でなければ失敗する' do
+        @pp.picture_id = 0
+        @pp.should_not be_valid
+      end
+    end
   end
   describe '一覧取得に於いて' do
     before do
index ba2a386..ecf150a 100644 (file)
@@ -288,7 +288,7 @@ describe Panel do
       end\r
     end\r
   end\r
-  describe '単体取得に於いて' do\r
+  describe '編集取得に於いて' do\r
     before do\r
       @panel = FactoryGirl.create :panel, :author_id => @author.id\r
     end\r
@@ -314,53 +314,69 @@ describe Panel do
     end\r
   end\r
   describe '関連テーブルプションに於いて' do\r
-    context 'オプションがないとき' do\r
-      it '3つの項目を含んでいる' do\r
-        r = Panel.show_include_opt\r
-        r.should have(3).items\r
-      end\r
-      it 'コマ絵を含んでいる' do\r
+    it '6つの項目を含んでいる' do\r
+      r = Panel.show_include_opt\r
+      r.should have(6).items\r
+    end\r
+    it 'コマ絵を含んでいる' do\r
+      r = Panel.show_include_opt\r
+      r.has_key?(:panel_pictures).should be_true\r
+    end\r
+      it 'コマ絵は実素材を含んでいる' do\r
         r = Panel.show_include_opt\r
-        r.has_key?(:panel_pictures).should be_true\r
+        r[:panel_pictures].has_key?(:picture).should be_true\r
       end\r
-        it 'コマ絵は実素材を含んでいる' do\r
+        it '実素材は絵師を含んでいる' do\r
           r = Panel.show_include_opt\r
-          r[:panel_pictures].has_key?(:picture).should be_true\r
+          r[:panel_pictures][:picture].has_key?(:artist).should be_true\r
         end\r
-          it '実素材は絵師を含んでいる' do\r
-            r = Panel.show_include_opt\r
-            r[:panel_pictures][:picture].has_key?(:artist).should be_true\r
-          end\r
-          it '実素材はライセンスを含んでいる' do\r
-            r = Panel.show_include_opt\r
-            r[:panel_pictures][:picture].has_key?(:license).should be_true\r
-          end\r
-      it 'フキダシを含んでいる' do\r
+        it '実素材はライセンスを含んでいる' do\r
+          r = Panel.show_include_opt\r
+          r[:panel_pictures][:picture].has_key?(:license).should be_true\r
+        end\r
+    it 'フキダシを含んでいる' do\r
+      r = Panel.show_include_opt\r
+      r.has_key?(:speech_balloons).should be_true\r
+    end\r
+      it 'フキダシはフキダシ枠を含んでいる' do\r
+        r = Panel.show_include_opt\r
+        r[:speech_balloons].has_key?(:balloons).should be_true\r
+      end\r
+      it 'フキダシはセリフを含んでいる' do\r
         r = Panel.show_include_opt\r
-        r.has_key?(:speech_balloons).should be_true\r
+        r[:speech_balloons].has_key?(:speeches).should be_true\r
       end\r
-        it 'フキダシはフキダシ枠を含んでいる' do\r
+    it '景色画像を含んでいる' do\r
+      r = Panel.show_include_opt\r
+      r.has_key?(:ground_pictures).should be_true\r
+    end\r
+      it '景色画像は実素材を含んでいる' do\r
+        r = Panel.show_include_opt\r
+        r[:ground_pictures].has_key?(:picture).should be_true\r
+      end\r
+        it '実素材は絵師を含んでいる' do\r
           r = Panel.show_include_opt\r
-          r[:speech_balloons].has_key?(:balloons).should be_true\r
+          r[:ground_pictures][:picture].has_key?(:artist).should be_true\r
         end\r
-        it 'フキダシはセリフを含んでいる' do\r
+        it '実素材はライセンスを含んでいる' do\r
           r = Panel.show_include_opt\r
-          r[:speech_balloons].has_key?(:speeches).should be_true\r
+          r[:ground_pictures][:picture].has_key?(:license).should be_true\r
         end\r
-      it '作家を含んでいる' do\r
+    it '間接色を含んでいる' do\r
+      r = Panel.show_include_opt\r
+      r.has_key?(:ground_colors).should be_true\r
+    end\r
+      it '間接色は色を含んでいる' do\r
         r = Panel.show_include_opt\r
-        r.has_key?(:author).should be_true\r
+        r[:ground_colors].has_key?(:color).should be_true\r
       end\r
+    it '景色を含んでいる' do\r
+      r = Panel.show_include_opt\r
+      r.has_key?(:panel_colors).should be_true\r
     end\r
-    context 'オプションで原画を含ませたとき' do\r
-      it '4つの項目を含んでいる' do\r
-        r = Panel.show_include_opt(:include => {:test => {}})\r
-        r.should have(4).items\r
-      end\r
-      it 'testを含んでいる' do\r
-        r = Panel.show_include_opt(:include => {:test => {}})\r
-        r.has_key?(:test).should be_true\r
-      end\r
+    it '作家を含んでいる' do\r
+      r = Panel.show_include_opt\r
+      r.has_key?(:author).should be_true\r
     end\r
   end\r
   describe 'json単体出力オプションに於いて' do\r
@@ -368,9 +384,9 @@ describe Panel do
       r = Panel.show_json_include_opt\r
       r.has_key?(:include).should be_true\r
     end\r
-    it '3つの項目を含んでいる' do\r
+    it '6つの項目を含んでいる' do\r
       r = Panel.show_json_include_opt[:include]\r
-      r.should have(3).items\r
+      r.should have(6).items\r
     end\r
     it 'コマ絵を含んでいる' do\r
       r = Panel.show_json_include_opt[:include]\r
@@ -389,17 +405,45 @@ describe Panel do
           r[:panel_pictures][:picture].has_key?(:license).should be_true\r
         end\r
     it 'フキダシを含んでいる' do\r
-      r = Panel.show_include_opt\r
+      r = Panel.show_json_include_opt[:include]\r
       r.has_key?(:speech_balloons).should be_true\r
     end\r
       it 'フキダシはフキダシ枠を含んでいる' do\r
-        r = Panel.show_include_opt\r
+        r = Panel.show_json_include_opt[:include]\r
         r[:speech_balloons].has_key?(:balloons).should be_true\r
       end\r
       it 'フキダシはセリフを含んでいる' do\r
-        r = Panel.show_include_opt\r
+        r = Panel.show_json_include_opt[:include]\r
         r[:speech_balloons].has_key?(:speeches).should be_true\r
       end\r
+    it '景色画像を含んでいる' do\r
+      r = Panel.show_json_include_opt[:include]\r
+      r.has_key?(:ground_pictures).should be_true\r
+    end\r
+      it '景色画像は実素材を含んでいる' do\r
+        r = Panel.show_json_include_opt[:include]\r
+        r[:ground_pictures].has_key?(:picture).should be_true\r
+      end\r
+        it '実素材は絵師を含んでいる' do\r
+          r = Panel.show_json_include_opt[:include]\r
+          r[:ground_pictures][:picture].has_key?(:artist).should be_true\r
+        end\r
+        it '実素材はライセンスを含んでいる' do\r
+          r = Panel.show_json_include_opt[:include]\r
+          r[:ground_pictures][:picture].has_key?(:license).should be_true\r
+        end\r
+    it '間接色を含んでいる' do\r
+      r = Panel.show_json_include_opt[:include]\r
+      r.has_key?(:ground_colors).should be_true\r
+    end\r
+      it '間接色は色を含んでいる' do\r
+        r = Panel.show_json_include_opt[:include]\r
+        r[:ground_colors].has_key?(:color).should be_true\r
+      end\r
+    it '景色を含んでいる' do\r
+      r = Panel.show_json_include_opt[:include]\r
+      r.has_key?(:panel_colors).should be_true\r
+    end\r
     it '作家を含んでいる' do\r
       r = Panel.show_json_include_opt[:include]\r
       r.has_key?(:author).should be_true\r
@@ -480,9 +524,9 @@ describe Panel do
       r = Panel.list_opt\r
       r.has_key?(:include).should be_true\r
     end\r
-    it '3つの項目を含んでいる' do\r
+    it '6つの項目を含んでいる' do\r
       r = Panel.list_opt[:include]\r
-      r.should have(3).items\r
+      r.should have(6).items\r
     end\r
     it 'コマ絵を含んでいる' do\r
       r = Panel.list_opt[:include]\r
@@ -501,17 +545,45 @@ describe Panel do
           r[:panel_pictures][:picture].has_key?(:license).should be_true\r
         end\r
     it 'フキダシを含んでいる' do\r
-      r = Panel.show_include_opt\r
+      r = Panel.list_opt[:include]\r
       r.has_key?(:speech_balloons).should be_true\r
     end\r
       it 'フキダシはフキダシ枠を含んでいる' do\r
-        r = Panel.show_include_opt\r
+        r = Panel.list_opt[:include]\r
         r[:speech_balloons].has_key?(:balloons).should be_true\r
       end\r
       it 'フキダシはセリフを含んでいる' do\r
-        r = Panel.show_include_opt\r
+        r = Panel.list_opt[:include]\r
         r[:speech_balloons].has_key?(:speeches).should be_true\r
       end\r
+    it '景色画像を含んでいる' do\r
+      r = Panel.list_opt[:include]\r
+      r.has_key?(:ground_pictures).should be_true\r
+    end\r
+      it '景色画像は実素材を含んでいる' do\r
+        r = Panel.list_opt[:include]\r
+        r[:ground_pictures].has_key?(:picture).should be_true\r
+      end\r
+        it '実素材は絵師を含んでいる' do\r
+          r = Panel.list_opt[:include]\r
+          r[:ground_pictures][:picture].has_key?(:artist).should be_true\r
+        end\r
+        it '実素材はライセンスを含んでいる' do\r
+          r = Panel.list_opt[:include]\r
+          r[:ground_pictures][:picture].has_key?(:license).should be_true\r
+        end\r
+    it '間接色を含んでいる' do\r
+      r = Panel.list_opt[:include]\r
+      r.has_key?(:ground_colors).should be_true\r
+    end\r
+      it '間接色は色を含んでいる' do\r
+        r = Panel.list_opt[:include]\r
+        r[:ground_colors].has_key?(:color).should be_true\r
+      end\r
+    it '景色を含んでいる' do\r
+      r = Panel.list_opt[:include]\r
+      r.has_key?(:panel_colors).should be_true\r
+    end\r
     it '作家を含んでいる' do\r
       r = Panel.list_opt[:include]\r
       r.has_key?(:author).should be_true\r
@@ -522,9 +594,9 @@ describe Panel do
       r = Panel.list_json_opt\r
       r.has_key?(:include).should be_true\r
     end\r
-    it '3つの項目を含んでいる' do\r
+    it '6つの項目を含んでいる' do\r
       r = Panel.list_json_opt[:include]\r
-      r.should have(3).items\r
+      r.should have(6).items\r
     end\r
     it 'コマ絵を含んでいる' do\r
       r = Panel.list_json_opt[:include]\r
@@ -543,17 +615,45 @@ describe Panel do
           r[:panel_pictures][:picture].has_key?(:license).should be_true\r
         end\r
     it 'フキダシを含んでいる' do\r
-      r = Panel.show_include_opt\r
+      r = Panel.list_json_opt[:include]\r
       r.has_key?(:speech_balloons).should be_true\r
     end\r
       it 'フキダシはフキダシ枠を含んでいる' do\r
-        r = Panel.show_include_opt\r
+        r = Panel.list_json_opt[:include]\r
         r[:speech_balloons].has_key?(:balloons).should be_true\r
       end\r
       it 'フキダシはセリフを含んでいる' do\r
-        r = Panel.show_include_opt\r
+        r = Panel.list_json_opt[:include]\r
         r[:speech_balloons].has_key?(:speeches).should be_true\r
       end\r
+    it '景色画像を含んでいる' do\r
+      r = Panel.list_json_opt[:include]\r
+      r.has_key?(:ground_pictures).should be_true\r
+    end\r
+      it '景色画像は実素材を含んでいる' do\r
+        r = Panel.list_json_opt[:include]\r
+        r[:ground_pictures].has_key?(:picture).should be_true\r
+      end\r
+        it '実素材は絵師を含んでいる' do\r
+          r = Panel.list_json_opt[:include]\r
+          r[:ground_pictures][:picture].has_key?(:artist).should be_true\r
+        end\r
+        it '実素材はライセンスを含んでいる' do\r
+          r = Panel.list_json_opt[:include]\r
+          r[:ground_pictures][:picture].has_key?(:license).should be_true\r
+        end\r
+    it '間接色を含んでいる' do\r
+      r = Panel.list_json_opt[:include]\r
+      r.has_key?(:ground_colors).should be_true\r
+    end\r
+      it '間接色は色を含んでいる' do\r
+        r = Panel.list_json_opt[:include]\r
+        r[:ground_colors].has_key?(:color).should be_true\r
+      end\r
+    it '景色を含んでいる' do\r
+      r = Panel.list_json_opt[:include]\r
+      r.has_key?(:panel_colors).should be_true\r
+    end\r
     it '作家を含んでいる' do\r
       r = Panel.list_json_opt[:include]\r
       r.has_key?(:author).should be_true\r
index b1d55fa..7177bfc 100644 (file)
@@ -181,6 +181,23 @@ describe Picture do
         @p.should_not be_valid
       end
     end
+    context 'md5を検証するとき' do
+      before do
+        @p = FactoryGirl.build :picture
+      end
+      it 'テストデータの確認' do
+        @p.md5 = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+        @p.should be_valid
+      end
+      it 'nullなら失敗する' do
+        @p.md5 = ''
+        @p.should_not be_valid
+      end
+      it '32文字以上なら失敗する' do
+        @p.md5 = 'a'*33
+        @p.should_not be_valid
+      end
+    end
     context 'license_idを検証するとき' do
       before do
         @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id
@@ -298,6 +315,7 @@ describe Picture do
       @p.height.should eq 265
       @p.filesize.should eq 266
       @p.artist_id.should eq @artist.id
+      @p.md5.should eq @rp.md5
       @p.license_id.should eq @license.id
       @p.original_picture_id.should eq @op.id
       @p.artist_name.should eq 'tester'
@@ -307,6 +325,118 @@ describe Picture do
     end
   end
   
+  describe 'md5重複リストに於いて' do
+    before do
+      @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
+      @p = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 0,
+        :original_picture_id => @op.id, :md5 => 'a' * 32
+      @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :picture_id => @p.id
+      @op2 = FactoryGirl.create :original_picture, :artist_id => @artist.id
+      @p2 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 0,
+        :original_picture_id => @op2.id, :md5 => 'b' * 32
+      @op3 = FactoryGirl.create :original_picture, :artist_id => @artist.id
+    end
+    it 'リストを返す' do
+      res = Picture.list_by_md5(@p.md5, @p.original_picture_id)
+      res.is_a?(Array).should be_true
+    end
+    it 'md5が違えば含まない' do
+      res = Picture.list_by_md5(@p.md5, @p.original_picture_id)
+      res.include?(@p2).should be_false
+    end
+    it '同一原画は含まない' do
+      res = Picture.list_by_md5(@p.md5, @p.original_picture_id)
+      res.empty?.should be_true
+    end
+    it '同一原画は旧版でも含まない' do
+      @p3 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
+        :original_picture_id => @op.id, :md5 => 'a' * 32
+      res = Picture.list_by_md5(@p.md5, @p.original_picture_id)
+      res.empty?.should be_true
+    end
+    it '他所の原画なら含む' do
+      @p3 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
+        :original_picture_id => @op2.id, :md5 => 'a' * 32
+      res = Picture.list_by_md5(@p.md5, @p.original_picture_id)
+      res.should eq [@p3]
+    end
+    it '他所の原画でもmd5が違えば含まない' do
+      @p3 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
+        :original_picture_id => @op2.id, :md5 => 'c' * 32
+      res = Picture.list_by_md5(@p.md5, @p.original_picture_id)
+      res.empty?.should be_true
+    end
+    it '更新日時順' do
+      @p3 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
+        :original_picture_id => @op2.id, :md5 => 'a' * 32
+      @p4 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
+        :original_picture_id => @op3.id, :md5 => 'a' * 32, :updated_at => Time.now + 100
+      res = Picture.list_by_md5(@p.md5, @p.original_picture_id)
+      res.should eq [@p4, @p3]
+    end
+  end
+  
+  describe 'md5重複判定に於いて' do
+    before do
+      @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
+      @op2 = FactoryGirl.create :original_picture, :artist_id => @artist.id
+      @p = FactoryGirl.create :picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :revision => 0
+      @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :picture_id => @p.id
+    end
+    context '同一原画以外に同じ値があるとき' do
+      before do
+        @p2 = FactoryGirl.create :picture, :artist_id => @artist.id, :original_picture_id => @op2.id, :license_id => @license.id
+      end
+      it 'trueを返す' do
+        res = Picture.exist_by_md5(@p.md5, @p.original_picture_id)
+        res.should be_true
+      end
+    end
+    context '同一原画以外に同じ値がないとき' do
+      it 'falseを返す' do
+        res = Picture.exist_by_md5(@p.md5, @p.original_picture_id)
+        res.should be_false
+      end
+    end
+    context '同一原画に同じ値があるとき' do
+      before do
+        @p2 = FactoryGirl.create :picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :revision => 1
+      end
+      it 'falseを返す' do
+        res = Picture.exist_by_md5(@p.md5, @p.original_picture_id)
+        res.should be_false
+      end
+    end
+  end
+  
+  describe 'head判定に於いて' do
+    before do
+    end
+    context '自身とリンクした素材があるとき' do
+      before do
+        @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
+        @p = FactoryGirl.create :picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id 
+        @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :picture_id => @p.id
+      end
+      it 'trueを返す' do
+        res = @p.head?
+        res.should be_true
+      end
+    end
+    context '自身とリンクした素材がないとき' do
+      before do
+        @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
+        @p = FactoryGirl.create :picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :revision => 0
+        @p2 = FactoryGirl.create :picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :revision => 1
+        @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :picture_id => @p2.id
+      end
+      it 'falseを返す' do
+        res = @p.head?
+        res.should be_false
+      end
+    end
+  end
+  
   describe '作成に於いて' do
     before do
       #RMagickのスタブをおいておく
index 93bf195..c8d377d 100644 (file)
@@ -144,6 +144,23 @@ describe ResourcePicture do
         @rp.should_not be_valid\r
       end\r
     end\r
+    context 'md5を検証するとき' do\r
+      before do\r
+        @rp = FactoryGirl.build :picture\r
+      end\r
+      it 'テストデータの確認' do\r
+        @rp.md5 = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'\r
+        @rp.should be_valid\r
+      end\r
+      it 'nullなら失敗する' do\r
+        @rp.md5 = ''\r
+        @rp.should_not be_valid\r
+      end\r
+      it '32文字以上なら失敗する' do\r
+        @rp.md5 = 'a'*33\r
+        @rp.should_not be_valid\r
+      end\r
+    end\r
     context 'license_idを検証するとき' do\r
       it 'テストデータの確認' do\r
         @rp.license_id = @license.id\r
@@ -440,6 +457,7 @@ describe ResourcePicture do
       @rp.width.should eq 264\r
       @rp.height.should eq 265\r
       @rp.filesize.should eq 266\r
+      @rp.md5.should eq @op.md5\r
       @rp.artist_id.should eq @artist.id\r
     end\r
   end\r
@@ -682,7 +700,7 @@ describe ResourcePicture do
         ResourcePicture.stub(:png_to_gif).with(any_args).and_return(@gifmgk)\r
       end\r
       it '画像ファイルの作成・更新機能で画像を保存している' do\r
-        ResourcePicture.any_instance.stub(:filename).with(any_args).and_return('1.png')
+        ResourcePicture.any_instance.stub(:filename).with(any_args).and_return('1.png')\r
         ResourcePicture.any_instance.should_receive(:store_picture).with(@mgk, '1.png').exactly(1)\r
         res = @rp.store_picture_with_gif @mgk\r
       end\r
@@ -696,7 +714,7 @@ describe ResourcePicture do
       end\r
       it '画像ファイルの作成・更新機能でgif画像を保存している' do\r
         #二回目の保存はgif変換の結果を渡す。\r
-        ResourcePicture.any_instance.stub(:gifname).with(any_args).and_return('1.gif')
+        ResourcePicture.any_instance.stub(:gifname).with(any_args).and_return('1.gif')\r
         ResourcePicture.any_instance.should_receive(:store_picture).with(@gifmgk, '1.gif').exactly(1)\r
         res = @rp.store_picture_with_gif @mgk\r
       end\r
@@ -766,8 +784,8 @@ describe ResourcePicture do
     end\r
     context 'gif画像の保存に失敗したとき' do\r
       before do\r
-        ResourcePicture.any_instance.stub(:filename).with(any_args).and_return('1.png')
-        ResourcePicture.any_instance.stub(:gifname).with(any_args).and_return('1.gif')
+        ResourcePicture.any_instance.stub(:filename).with(any_args).and_return('1.png')\r
+        ResourcePicture.any_instance.stub(:gifname).with(any_args).and_return('1.gif')\r
         @mgk = Mgk.new\r
         ResourcePicture.any_instance.stub(:store_picture).with(@mgk, '1.png').and_return(true)\r
         ResourcePicture.any_instance.stub(:to_gif?).with(any_args).and_return(true)\r
@@ -821,20 +839,22 @@ describe ResourcePicture do
         #すべての処理を正常パターンで通過させ、保存機能をチェックする。\r
         PictureIO.resource_picture_io.stub(:put).with(any_args).and_return(true)\r
         ResourcePicture.any_instance.stub(:flag_thumbnail).with(any_args).and_return(1)\r
+        ResourcePicture.any_instance.stub(:thumbnail).with(any_args).and_return('tmbdata')\r
       end\r
       it 'Trueを返す' do\r
-#        res = @rp.store_picture(Mgk.new, '1.gif')\r
-#        res.should be_true\r
+        res = @rp.store_picture(Mgk.new, '1.gif')\r
+        res.should be_true\r
       end\r
     end\r
     context '例外ケース' do\r
       before do\r
         ResourcePicture.any_instance.stub(:flag_thumbnail).with(any_args).and_return(1)\r
+        ResourcePicture.any_instance.stub(:thumbnail).with(any_args).and_return('tmbdata')\r
         PictureIO.resource_picture_io.stub(:put).with(any_args).and_return(false)\r
       end\r
-      it 'Falseを返す' do\r
#       res = @rp.store_picture(Mgk.new, '1.gif')\r
#       res.should be_false\r
+      it '画像の保存に失敗したならFalseを返す' do\r
+        res = @rp.store_picture(Mgk.new, '1.gif')\r
+        res.should be_false\r
       end\r
     end\r
     \r
index 1ba54ce..4301a68 100644 (file)
@@ -160,7 +160,7 @@ describe Story do
       @story.own?(nil).should == false
     end
   end
-  describe '単体取得に於いて' do
+  describe '編集取得に於いて' do
     before do
       @comic = FactoryGirl.create :comic, :author_id => @author.id
       @panel = FactoryGirl.create :panel, :author_id => @author.id