projects_controller_spec.rb 6.96 KB
require 'spec_helper'

describe ProjectsController do

  describe 'new' do
    before :each do
      sign_in FactoryGirl.create(:user)
      get :new
    end

    it { should respond_with(:success) }
    it { should render_template(:new) }
  end

  describe 'create' do
    before do
      sign_in FactoryGirl.create(:user)
    end

    context 'with valid fields' do
      before :each do
        @subject = FactoryGirl.build(:project)
        @subject_params = Hash[FactoryGirl.attributes_for(:project).map { |k,v| [k.to_s, v.to_s] }] #FIXME: Mocha is creating the expectations with strings, but FactoryGirl returns everything with sybols and integers

        Project.expects(:new).at_least_once.with(@subject_params).returns(@subject)
        Project.any_instance.expects(:save).returns(true)
      end

      context 'rendering the show' do
        before :each do
          Project.expects(:exists?).returns(true)

          post :create, :project => @subject_params
        end

        it 'should redirect to the show view' do
          response.should redirect_to project_path(@subject)
        end
      end

      context 'without rendering the show view' do
        before :each do
          post :create, :project => @subject_params
        end

        it { should respond_with(:redirect) }
      end
    end

    context 'with an invalid field' do
      before :each do
        @subject = FactoryGirl.build(:project)
        @subject_params = Hash[FactoryGirl.attributes_for(:project).map { |k,v| [k.to_s, v.to_s] }] #FIXME: Mocha is creating the expectations with strings, but FactoryGirl returns everything with sybols and integers

        Project.expects(:new).at_least_once.with(@subject_params).returns(@subject)
        Project.any_instance.expects(:save).returns(false)

        post :create, :project => @subject_params
      end

      it { should render_template(:new) }
    end
  end

  describe 'show' do
    before :each do
      @subject = FactoryGirl.build(:project)
      Project.expects(:find).with(@subject.id.to_s).returns(@subject)
      get :show, :id => @subject.id
    end

    it { should render_template(:show) }
  end

  describe 'destroy' do
    before :each do
      sign_in FactoryGirl.create(:user)

      @subject = FactoryGirl.build(:project)
      @subject.expects(:destroy)

      @ownership = FactoryGirl.build(:project_ownership)
      @ownership.expects(:destroy)
      @ownerships = []

      #Those two mocks looks the same but they are necessary since params[:id] is a String and @project.id is an Integer :(
      @ownerships.expects(:find_by_project_id).with("#{@subject.id}").returns(@ownership)
      @ownerships.expects(:find_by_project_id).with(@subject.id).returns(@ownership)

      User.any_instance.expects(:project_ownerships).at_least_once.returns(@ownerships)

      Project.expects(:find).with(@subject.id.to_s).returns(@subject)
      delete :destroy, :id => @subject.id
    end

    it 'should redirect to the projects page' do
      response.should redirect_to projects_url
    end

    it { should respond_with(:redirect) }
  end

  describe 'index' do
    before :each do
      @subject = FactoryGirl.build(:project)
      Project.expects(:all).returns([@subject])
      get :index
    end

    it { should render_template(:index) }
  end

  describe 'edit' do
    before do
      @user = FactoryGirl.create(:user)
      @subject = FactoryGirl.build(:project)
      @ownership = FactoryGirl.build(:project_ownership)
      @ownerships = []

      User.any_instance.expects(:project_ownerships).at_least_once.returns(@ownerships)
     
      sign_in @user
    end

    context 'when the user owns the project' do
      before :each do
        Project.expects(:find).with(@subject.id.to_s).returns(@subject)
        @ownerships.expects(:find_by_project_id).with("#{@subject.id}").returns(@ownership)
        
        get :edit, :id => @subject.id
      end

      it { should render_template(:edit) }

      it 'should assign to @project the @subject' do
        assigns(:project).should eq(@subject)
      end
    end

    context 'when the user does not own the project' do
      before do
        @subject = FactoryGirl.build(:another_project)
        @ownerships.expects(:find_by_project_id).with("#{@subject.id}").returns(nil)

        get :edit, :id => @subject.id
      end

      it { should redirect_to(projects_path)  }

      it 'should set the flash' do
        pending("This ShouldaMatcher test is not compatible yet with Rails 4") do
          should set_the_flash[:notice].to("You shall not edit projects that aren't yours.")
        end
      end
    end
  end

  describe 'update' do
    before do
      @subject = FactoryGirl.build(:project)
      @subject_params = Hash[FactoryGirl.attributes_for(:project).map { |k,v| [k.to_s, v.to_s] }] #FIXME: Mocha is creating the expectations with strings, but FactoryGirl returns everything with sybols and integers
    end

    context 'when the user is logged in' do
      before do
        sign_in FactoryGirl.create(:user)
      end

      context 'when user owns the project' do
        before do
          @ownership = FactoryGirl.build(:project_ownership)
          @ownerships = []

          @ownerships.expects(:find_by_project_id).with("#{@subject.id}").returns(@ownership)
          User.any_instance.expects(:project_ownerships).at_least_once.returns(@ownerships)
        end

        context 'with valid fields' do
          before :each do
            Project.expects(:find).with(@subject.id.to_s).returns(@subject)
            Project.any_instance.expects(:update).with(@subject_params).returns(true)
          end

          context 'rendering the show' do
            before :each do
              Project.expects(:exists?).returns(true)

              post :update, :id => @subject.id, :project => @subject_params
            end

            it 'should redirect to the show view' do
              response.should redirect_to project_path(@subject)
            end
          end

          context 'without rendering the show view' do
            before :each do
              post :update, :id => @subject.id, :project => @subject_params
            end

            it { should respond_with(:redirect) }
          end
        end

        context 'with an invalid field' do
          before :each do
            Project.expects(:find).with(@subject.id.to_s).returns(@subject)
            Project.any_instance.expects(:update).with(@subject_params).returns(false)

            post :update, :id => @subject.id, :project => @subject_params
          end

          it { should render_template(:edit) }
        end
      end

      context 'when the user does not own the project' do
        before :each do
          post :update, :id => @subject.id, :project => @subject_params
        end

        it { should redirect_to projects_path }
      end
    end

    context 'with no user logged in' do
      before :each do
        post :update, :id => @subject.id, :project => @subject_params
      end

      it { should redirect_to new_user_session_path }
    end
  end

end