require 'spec_helper'

# This spec was generated by rspec-rails when you ran the scaffold generator.
# It demonstrates how one might use RSpec to specify the controller code that
# was generated by Rails when you ran the scaffold generator.
#
# It assumes that the implementation code is generated by the rails scaffold
# generator.  If you are using any extension libraries to generate different
# controller code, this generated spec may or may not pass.
#
# It only uses APIs available in rails and/or rspec-rails.  There are a number
# of tools you can use to make these specs even more expressive, but we're
# sticking to rails and rspec-rails APIs to keep things simple and stable.
#
# Compared to earlier versions of this generator, there is very limited use of
# stubs and message expectations in this spec.  Stubs are only used when there
# is no simpler way to get a handle on the object needed for the example.
# Message expectations are only used when there is no simpler way to specify
# that an instance is receiving a specific message.

describe QuestionsController do
  
  let(:user) { FactoryGirl.create(:user) }
  let(:node) { FactoryGirl.create(:node) }
  let(:admin) { FactoryGirl.create(:admin) }
  let(:question) { FactoryGirl.create(:question, node: node, user: user) }
  let(:another_question) { FactoryGirl.create(:another_question, node: node, user: admin) }
               
  def valid_attributes 
    {
      title: "Question",
      body: "Hello World! AAAAA",
      user: user,
      node: node
    }
  end
  
  
  describe "GET index" do
    it "assigns all questions as @questions" do
      get :index
      response.should be_success
    end
  end
    

  describe "GET show" do
    it "assigns the requested question as @question" do
      get :show, {:id => question.to_param}
      assigns(:question).should eq(question)
    end
  end
  
  context "as user login" do
    
    before(:each) { sign_in user }
    
    describe "GET new" do
      it "assigns a new question as @question" do
        get :new, {}
        assigns(:question).should be_a_new(Question)
      end
    end
    
    describe "GET edit" do
      it "assigns the requested question as @question" do
        get :edit, {:id => question.to_param}
        assigns(:question).should eq(question)
      end
      
      it "can't edit the question not belongs_to current_user" do
        get :edit, {:id => another_question.to_param}
        response.should redirect_to(questions_path)
      end
    end
        
    describe "POST create" do
            
      describe "with valid params" do
        it "creates a new Question" do
          expect {
            post :create, {:question => valid_attributes}
          }.to change(Question, :count).by(1)
        end

        it "assigns a newly created question as @question" do
          post :create, {:question => valid_attributes}
          assigns(:question).should be_a(Question)
          assigns(:question).should be_persisted
        end

        it "redirects to the created question" do
          post :create, {:question => valid_attributes}
          response.should redirect_to(Question.last)
        end
      end

      describe "with invalid params" do
        it "assigns a newly created but unsaved question as @question" do
          # Trigger the behavior that occurs when invalid params are submitted
          Question.any_instance.stub(:save).and_return(false)
          post :create, {:question => {  }}
          assigns(:question).should be_a_new(Question)
        end

        it "re-renders the 'new' template" do
          # Trigger the behavior that occurs when invalid params are submitted
          Question.any_instance.stub(:save).and_return(false)
          post :create, {:question => {  }}
          response.should render_template("new")
        end
      end
    end

    describe "PUT update" do
      describe "with valid params" do
        it "updates the requested question" do
          # Assuming there are no other questions in the database, this
          # specifies that the Question created on the previous line
          # receives the :update_attributes message with whatever params are
          # submitted in the request.
          Question.any_instance.should_receive(:update_attributes).with({ "title" => "params" })
          put :update, {:id => question.to_param, :question => { "title" => "params" }}
        end

        it "assigns the requested question as @question" do
          put :update, {:id => question.to_param, :question => {title: "Question", body: "Hello World! AAAAA"} }
          assigns(:question).should eq(question)
        end

        it "redirects to the question" do
          put :update, {:id => question.to_param, :question => {title: "Question", body: "Hello World! AAAAA"} }
          response.should redirect_to(question)
        end
      end
      
      describe "with invalid params" do
        it "assigns the question as @question" do
          question.should_not be_nil
          # Trigger the behavior that occurs when invalid params are submitted
          Question.any_instance.stub(:save).and_return(false)
          put :update, {:id => question.to_param, :question => {  }}
          assigns(:question).should eq(question)
        end

        it "re-renders the 'edit' template" do
          question.should_not be_nil
          # Trigger the behavior that occurs when invalid params are submitted
          Question.any_instance.stub(:save).and_return(false)
          put :update, {:id => question.to_param, :question => {  }}
          response.should render_template("edit")
        end
      end
      
      
      describe "update question not belongs_to current user" do
        it "updates the requested question" do
          # Assuming there are no other questions in the database, this
          # specifies that the Question created on the previous line
          # receives the :update_attributes message with whatever params are
          # submitted in the request.
          Question.any_instance.should_not_receive(:update_attributes).with({ "title" => "New Title" })
          put :update, {:id => another_question.to_param, :question => { "title" => "New Title" }}
          flash[:alert].should_not be_empty
        end
        
        it "assigns the requested question as @question" do
          put :update, {:id => another_question.to_param, :question => valid_attributes}          
          response.should redirect_to(questions_path)
          flash[:alert].should_not be_empty
        end

      end
    end

    describe "DELETE destroy" do    
      it "destroys the requested question" do
        question.should_not be_nil
        expect {
          delete :destroy, {:id => question.to_param}      
        }.to change(Question, :count).by(-1)
      end
      
      it "destroys the requested question not belongs_to current_user" do
        another_question.should_not be_nil
        expect {
          delete :destroy, {:id => another_question.to_param}      
        }.to change(Question, :count).by(0)
        flash[:alert].should_not be_empty
      end

      it "redirects to the questions list" do
        question.should_not be_nil
        delete :destroy, {:id => question.to_param}
        response.should redirect_to(questions_url)
      end
    end
    
  end
  
  context "as user unlogin" do
        
    describe "GET new" do
      it "assigns a new question as @question" do
        get :new, {}
        response.should redirect_to(questions_url)
      end
    end
    
    describe "GET edit" do
      it "assigns the requested question as @question" do
        get :edit, {:id => question.to_param}
        response.should redirect_to(questions_url)
      end
    end
    
    describe "PUT update" do
      describe "with valid params" do
        it "updates the requested question" do
          # Assuming there are no other questions in the database, this
          # specifies that the Question created on the previous line
          # receives the :update_attributes message with whatever params are
          # submitted in the request.
          Question.any_instance.should_not_receive(:update_attributes).with({ "these" => "params" })
          put :update, {:id => question.to_param, :question => { "these" => "params" }}
          response.should redirect_to(questions_url)
        end

        it "assigns the requested question as @question" do
          put :update, {:id => question.to_param, :question => valid_attributes}
          response.should redirect_to(questions_url)
        end

        it "redirects to the question" do
          put :update, {:id => question.to_param, :question => valid_attributes}
          response.should redirect_to(questions_url)
        end
      end

      describe "with invalid params" do
        it "assigns the question as @question" do
          question = Question.create! valid_attributes
          # Trigger the behavior that occurs when invalid params are submitted
          Question.any_instance.stub(:save).and_return(false)
          put :update, {:id => question.to_param, :question => {  }}
          response.should redirect_to(questions_url)
        end

        it "re-renders the 'edit' template" do
          question = Question.create! valid_attributes
          # Trigger the behavior that occurs when invalid params are submitted
          Question.any_instance.stub(:save).and_return(false)
          put :update, {:id => question.to_param, :question => {  }}
          response.should redirect_to(questions_url)
        end
      end
    end

    describe "DELETE destroy" do 
      it "destroys the requested question" do
        question #load the resouce
        expect {
          delete :destroy, {:id => question.to_param}
        }.to change(Question, :count).by(0)
      end
    end
    
  end
  
end

