diff --git a/Gemfile b/Gemfile index ca82d4b..f94e4d3 100644 --- a/Gemfile +++ b/Gemfile @@ -46,13 +46,14 @@ group :development, :test do gem 'hirb' gem 'hirb-unicode' gem 'awesome_print' + + gem 'rspec-rails' + gem 'factory_girl_rails' end group :test do - gem 'rspec-rails' gem 'shoulda-matchers' gem 'database_rewinder' - gem 'factory_girl_rails' gem 'forgery' gem 'capybara' diff --git a/app/assets/javascripts/upload.js.coffee b/app/assets/javascripts/upload.js.coffee new file mode 100644 index 0000000..24f83d1 --- /dev/null +++ b/app/assets/javascripts/upload.js.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/stylesheets/upload.css.scss b/app/assets/stylesheets/upload.css.scss new file mode 100644 index 0000000..663994b --- /dev/null +++ b/app/assets/stylesheets/upload.css.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the upload controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/uploads_controller.rb b/app/controllers/uploads_controller.rb new file mode 100644 index 0000000..c0ecad7 --- /dev/null +++ b/app/controllers/uploads_controller.rb @@ -0,0 +1,34 @@ +class UploadsController < ApplicationController + before_action :set_upload, only: [:destroy] + + def new + @upload = Upload.new + end + + def create + @upload = Upload.new(upload_params) + + if @upload.save + redirect_to root_url, notice: 'Upload was successfully created.' + else + render action: 'new' + end + end + + # DELETE /uploads/1 + # DELETE /uploads/1.json + def destroy + @upload.destroy + redirect_to root_url + end + + private + + def set_upload + @upload = Upload.find(params[:id]) + end + + def upload_params + params.require(:upload).permit(:file).merge(ip: request.remote_ip) + end +end diff --git a/app/helpers/uploads_helper.rb b/app/helpers/uploads_helper.rb new file mode 100644 index 0000000..f4f8250 --- /dev/null +++ b/app/helpers/uploads_helper.rb @@ -0,0 +1,2 @@ +module UploadsHelper +end diff --git a/app/models/upload.rb b/app/models/upload.rb new file mode 100644 index 0000000..c08b2fe --- /dev/null +++ b/app/models/upload.rb @@ -0,0 +1,29 @@ +class Upload < ActiveRecord::Base + attr_accessor :file + + before_validation :set_attributes_from_file, :if => Proc.new { |instance| instance.new_record? } + + validates :filename, presence: true, format: { with: /\.[A-Za-z]+\Z/ } + validates :ext, presence: true + validates :ip, presence: true + + private + + def set_attributes_from_file + set_filename + set_ext + set_data + end + + def set_data + self.data = @file.read + end + + def set_filename + self.filename = @file.original_filename + end + + def set_ext + self.ext = File.extname(@file.original_filename) + end +end diff --git a/app/views/uploads/_form.html.haml b/app/views/uploads/_form.html.haml new file mode 100644 index 0000000..3ff84b2 --- /dev/null +++ b/app/views/uploads/_form.html.haml @@ -0,0 +1,10 @@ += form_for @upload do |f| + - if @upload.errors.any? + #error_explanation + %h2= "#{pluralize(@upload.errors.count, "error")} prohibited this upload from being saved:" + %ul + - @upload.errors.full_messages.each do |msg| + %li= msg + + .actions + = f.submit 'Save' diff --git a/app/views/uploads/new.html.haml b/app/views/uploads/new.html.haml new file mode 100644 index 0000000..c056226 --- /dev/null +++ b/app/views/uploads/new.html.haml @@ -0,0 +1,5 @@ +%h1 New upload + += render 'form' + += link_to 'Back', uploads_path diff --git a/config/routes.rb b/config/routes.rb index edd0a68..255d003 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,3 +1,4 @@ PecaUploader::Application.routes.draw do root "welcome#index" + resources :upload, only: [:new, :create, :destroy] end diff --git a/db/migrate/20130928060122_create_uploads.rb b/db/migrate/20130928060122_create_uploads.rb new file mode 100644 index 0000000..93c2bea --- /dev/null +++ b/db/migrate/20130928060122_create_uploads.rb @@ -0,0 +1,14 @@ +class CreateUploads < ActiveRecord::Migration + def change + create_table :uploads do |t| + t.string :filename, presence: true + t.string :ext, presence: true + t.string :comment + t.string :ip, presence: true + t.integer :view_count + t.binary :data, :limit => 5.megabytes + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 4dfbb16..ecf30b0 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,6 +11,17 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 0) do +ActiveRecord::Schema.define(version: 20130928060122) do + + create_table "uploads", force: true do |t| + t.string "filename" + t.string "ext" + t.string "comment" + t.string "ip" + t.integer "view_count" + t.binary "data", limit: 5242880 + t.datetime "created_at" + t.datetime "updated_at" + end end diff --git a/spec/controllers/uploads_controller_spec.rb b/spec/controllers/uploads_controller_spec.rb new file mode 100644 index 0000000..46299ff --- /dev/null +++ b/spec/controllers/uploads_controller_spec.rb @@ -0,0 +1,64 @@ +require 'spec_helper' + +describe UploadsController do + let(:valid_attributes) { FactoryGirl.attributes_for(:upload) } + let(:invalid_attribtues) { {} } + let(:valid_session) { {} } + + describe "GET new" do + it "assigns a new upload as @upload" do + get :new + assigns(:upload).should be_a_new(Upload) + end + end + + describe "POST create" do + describe "with valid params" do + # before { fixture_file_upload('upload.png', 'image/png') } + it "creates a new Upload" do + expect { + post :create, {:upload => valid_attributes}, valid_session + }.to change(Upload, :count).by(1) + end + + it "assigns a newly created upload as @upload" do + post :create, {:upload => valid_attributes}, valid_session + assigns(:upload).should be_a(Upload) + assigns(:upload).should be_persisted + end + + it "redirects to the created upload" do + post :create, {:upload => valid_attributes}, valid_session + response.should redirect_to(root_url) + end + end + + describe "with invalid params" do + it "raises an exception" do + expect { post :create, {upload: invalid_attribtues} }.to raise_error ActionController::ParameterMissing + end + + it "re-renders the 'new' template" do + Upload.any_instance.stub(:save).and_return(false) + post :create, {:upload => valid_attributes.merge(filename: Forgery(:basic).text)}, valid_session + response.should render_template("new") + end + end + end + + describe "DELETE destroy" do + it "destroys the requested upload" do + upload = Upload.create! valid_attributes + expect { + delete :destroy, {:id => upload.to_param}, valid_session + }.to change(Upload, :count).by(-1) + end + + it "redirects to the uploads list" do + upload = Upload.create! valid_attributes + delete :destroy, {:id => upload.to_param}, valid_session + response.should redirect_to(root_url) + end + end + +end diff --git a/spec/factories/uploads.rb b/spec/factories/uploads.rb new file mode 100644 index 0000000..de6fbfb --- /dev/null +++ b/spec/factories/uploads.rb @@ -0,0 +1,11 @@ +# Read about factories at https://github.com/thoughtbot/factory_girl + +FactoryGirl.define do + factory :upload do + file { fixture_file_upload(Rails.root.join('spec', 'fixtures', 'upload.png'), 'image/png') } + comment { Forgery(:basic).text(at_most: 200) } + ip { Forgery(:internet).ip_v4 } + # ext + # view_count + end +end diff --git a/spec/fixtures/upload.png b/spec/fixtures/upload.png new file mode 100644 index 0000000..04a07bc Binary files /dev/null and b/spec/fixtures/upload.png differ diff --git a/spec/helpers/uploads_helper_spec.rb b/spec/helpers/uploads_helper_spec.rb new file mode 100644 index 0000000..e553ed6 --- /dev/null +++ b/spec/helpers/uploads_helper_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +# Specs in this file have access to a helper object that includes +# the UploadsHelper. For example: +# +# describe UploadsHelper do +# describe "string concat" do +# it "concats two strings with spaces" do +# expect(helper.concat_strings("this","that")).to eq("this that") +# end +# end +# end +describe UploadsHelper do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/upload_spec.rb b/spec/models/upload_spec.rb new file mode 100644 index 0000000..384ed34 --- /dev/null +++ b/spec/models/upload_spec.rb @@ -0,0 +1,35 @@ +require 'spec_helper' + +describe Upload do + describe "validations" do + subject { FactoryGirl.build(:upload) } + + shared_context "should not be valid" do + it "" do should_not be_valid end + end + + context "パラメータが設定されていれば" do + it "検証が成功する" do should be_valid end + end + + context "ファイル名が設定されていなければ" do + before { subject.stub(:set_filename).and_return("") } + include_context "should not be valid" + end + + context "ファイル名に拡張子がなければ" do + before { subject.stub(:set_filename).and_return(Forgery(:basic).text) } + include_context "should not be valid" + end + + context "拡張子が設定されていなければ" do + before { subject.stub(:set_ext).and_return("") } + include_context "should not be valid" + end + + context "IPが設定されていなければ" do + before { subject.ip = "" } + include_context "should not be valid" + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 2cda3c1..17a5256 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -16,6 +16,8 @@ # If you are not using ActiveRecord, you can remove this line. ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration) +include ActionDispatch::TestProcess + Capybara.default_driver = :rack_test Capybara.configure do |config| config.match = :one