From 70cf1bdc3b23f52a57fdd908f440e4378bcd7ea7 Mon Sep 17 00:00:00 2001 From: Micha Wrobel Date: Fri, 2 Mar 2012 00:25:55 +0100 Subject: [PATCH] Add comment resource --- app/controllers/application_controller.rb | 8 +++ app/controllers/comments_controller.rb | 34 ++++++++++ app/models/comment.rb | 10 +++ config/routes.rb | 8 ++- db/migrate/20120227230718_create_comments.rb | 14 ++++ db/schema.rb | 13 +++- spec/controllers/comments_controller_spec.rb | 71 ++++++++++++++++++++ spec/factories/asciicasts.rb | 2 + spec/factories/comments.rb | 7 ++ spec/models/comment_spec.rb | 8 +++ spec/spec_helper.rb | 1 + spec/support/controller_macros.rb | 7 ++ 12 files changed, 181 insertions(+), 2 deletions(-) create mode 100644 app/controllers/comments_controller.rb create mode 100644 app/models/comment.rb create mode 100644 db/migrate/20120227230718_create_comments.rb create mode 100644 spec/controllers/comments_controller_spec.rb create mode 100644 spec/factories/comments.rb create mode 100644 spec/models/comment_spec.rb create mode 100644 spec/support/controller_macros.rb diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 27e1244..dca77c5 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -4,6 +4,8 @@ class ApplicationController < ActionController::Base protect_from_forgery rescue_from(ActiveRecord::RecordNotFound) { render 'exceptions/not_found' } + class Unauthorized < Exception; end + helper_method :current_user def current_user @@ -20,4 +22,10 @@ class ApplicationController < ActionController::Base end end + private + + def ensure_authenticated! + raise Unauthorized unless current_user + end + end diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb new file mode 100644 index 0000000..08e8513 --- /dev/null +++ b/app/controllers/comments_controller.rb @@ -0,0 +1,34 @@ +class CommentsController < ApplicationController + respond_to :json + + before_filter :ensure_authenticated!, :only => [:create, :update, :destroy] + before_filter :load_asciicast, :only => [:index, :create] + + def index + respond_with @asciicast.comments + end + + def create + @comment = Comment.new(params[:comment]) + @comment.asciicast = @asciicast + @comment.user = current_user + + @comment.save + + respond_with @comment + end + + def update + respond_with Comment.update(params[:id], params[:comment]) + end + + def destroy + respond_with Comment.destroy(params[:id]) + end + + private + + def load_asciicast + @asciicast = Asciicast.find(params[:asciicast_id]) + end +end diff --git a/app/models/comment.rb b/app/models/comment.rb new file mode 100644 index 0000000..a80e795 --- /dev/null +++ b/app/models/comment.rb @@ -0,0 +1,10 @@ +class Comment < ActiveRecord::Base + + validates :body, :presence => true + validates :asciicast_id, :presence => true + validates :user_id, :presence => true + + belongs_to :user + belongs_to :asciicast + +end diff --git a/config/routes.rb b/config/routes.rb index b7ed804..fc6b128 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,9 +1,15 @@ AsciiIo::Application.routes.draw do + resources :comments + resources :asciicasts match ':id' => 'asciicasts#show', :constraints => { :id => /\d+/ } namespace :api do - resources :asciicasts + resources :asciicasts do + + resources :comments + + end end match "/auth/:provider/callback" => "sessions#create" diff --git a/db/migrate/20120227230718_create_comments.rb b/db/migrate/20120227230718_create_comments.rb new file mode 100644 index 0000000..805d46e --- /dev/null +++ b/db/migrate/20120227230718_create_comments.rb @@ -0,0 +1,14 @@ +class CreateComments < ActiveRecord::Migration + def change + create_table :comments do |t| + t.text :body + t.integer :user_id + t.integer :asciicast_id + + t.timestamps + end + + add_index(:comments, :asciicast_id) + add_index(:comments, :user_id) + end +end diff --git a/db/schema.rb b/db/schema.rb index 32ad090..8d2f980 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20120226184448) do +ActiveRecord::Schema.define(:version => 20120227230718) do create_table "asciicasts", :force => true do |t| t.integer "user_id" @@ -36,6 +36,17 @@ ActiveRecord::Schema.define(:version => 20120226184448) do add_index "asciicasts", ["recorded_at"], :name => "index_asciicasts_on_recorded_at" add_index "asciicasts", ["user_id"], :name => "index_asciicasts_on_user_id" + create_table "comments", :force => true do |t| + t.text "body" + t.integer "user_id" + t.integer "asciicast_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "comments", ["asciicast_id"], :name => "index_comments_on_asciicast_id" + add_index "comments", ["user_id"], :name => "index_comments_on_user_id" + create_table "users", :force => true do |t| t.string "provider", :null => false t.string "uid", :null => false diff --git a/spec/controllers/comments_controller_spec.rb b/spec/controllers/comments_controller_spec.rb new file mode 100644 index 0000000..1d6bdab --- /dev/null +++ b/spec/controllers/comments_controller_spec.rb @@ -0,0 +1,71 @@ +require 'spec_helper' + +describe CommentsController do + + let(:user) { mock_model(User) } + let(:asciicast) { mock_model(Asciicast) } + + it "should ensure user is authenticated" do + + end + + before do + Asciicast.stub(:find).and_return(asciicast) + login_as(user) + end + + describe "#create" do + + context "given valid data" do + def dispatch + post :create, + :asciicast_id => asciicast.id, + :comment => {"body" => "Foo"}, + :format => :json + end + + before do + Comment.any_instance.should_receive(:save).and_return(true) + end + + it "assigns current_user" do + dispatch + assigns(:comment).user.should_not be_blank + end + + it "assigns asciicast" do + dispatch + assigns(:comment).asciicast.should_not be_blank + end + + it "assigns asciicast" do + dispatch + response.status.should == 201 + end + end + + context "given not valid data" do + def dispatch + post :create, + :asciicast_id => asciicast.id, + :comment => {}, + :format => :json + end + + it "response should be 422" do + dispatch + response.status.should == 422 + end + end + end + + describe "#index" do + + it "return comments" do + asciicast.should_receive(:comments).and_return([]) + get :index, :asciicast_id => asciicast.id + end + + end + +end diff --git a/spec/factories/asciicasts.rb b/spec/factories/asciicasts.rb index 4e6dc75..1f3c601 100644 --- a/spec/factories/asciicasts.rb +++ b/spec/factories/asciicasts.rb @@ -3,6 +3,8 @@ FactoryGirl.define do factory :asciicast do user_id 1 + stdout "MyString" + stdout_timing "MyString" title "MyString" duration 1 recorded_at "2011-11-23 22:06:07" diff --git a/spec/factories/comments.rb b/spec/factories/comments.rb new file mode 100644 index 0000000..b80a674 --- /dev/null +++ b/spec/factories/comments.rb @@ -0,0 +1,7 @@ +FactoryGirl.define do + factory :comment do + body "My fancy comment" + association :user + association :asciicast + end +end diff --git a/spec/models/comment_spec.rb b/spec/models/comment_spec.rb new file mode 100644 index 0000000..37d7c7d --- /dev/null +++ b/spec/models/comment_spec.rb @@ -0,0 +1,8 @@ +require 'spec_helper' + +describe Comment do + + it "factory should be valid" do + Factory.build(:comment).should be_valid + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 9e87a00..fc6fdaf 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -11,6 +11,7 @@ RSpec.configure do |config| config.mock_with :rspec config.use_transactional_fixtures = true + config.include(ControllerMacros, :type => :controller) config.infer_base_class_for_anonymous_controllers = false end diff --git a/spec/support/controller_macros.rb b/spec/support/controller_macros.rb new file mode 100644 index 0000000..4dcd33f --- /dev/null +++ b/spec/support/controller_macros.rb @@ -0,0 +1,7 @@ +module ControllerMacros + + def login_as(user) + controller.stub(:current_user => user) + end + +end