From ccc28cdc904171979eadcfd4d9fd7209923b88fb Mon Sep 17 00:00:00 2001 From: Aditya Prakash Date: Thu, 25 Feb 2016 12:36:35 +0530 Subject: [PATCH] Add test for QuestionsController new method was dead code. @questions_conference was dead variable. assignment of question's foreign key was unnecessary. fixes in type of flash messages. --- app/controllers/admin/questions_controller.rb | 17 +- .../admin/questions_controller_spec.rb | 197 ++++++++++++++++++ spec/factories/qanswer.rb | 1 + spec/factories/question.rb | 2 + 4 files changed, 205 insertions(+), 12 deletions(-) create mode 100644 spec/controllers/admin/questions_controller_spec.rb diff --git a/app/controllers/admin/questions_controller.rb b/app/controllers/admin/questions_controller.rb index 590182c3..5c8c22c4 100644 --- a/app/controllers/admin/questions_controller.rb +++ b/app/controllers/admin/questions_controller.rb @@ -6,7 +6,6 @@ module Admin def index authorize! :index, Question.new(conference_id: @conference.id) @questions = Question.where(global: true).all | Question.where(conference_id: @conference.id) - @questions_conference = @conference.questions @new_question = @conference.questions.new end @@ -14,14 +13,8 @@ module Admin @registrations = @conference.registrations.joins(:qanswers).uniq end - def new - @question = Question.new(conference_id: @conference.id) - authorize! :create, @question - end - def create @question = @conference.questions.new(question_params) - @question.conference_id = @conference.id authorize! :create, @question if @question.question_type_id == QuestionType.find_by(title: 'Yes/No').id @@ -45,12 +38,13 @@ module Admin end end - # PUT questions/1 + # PATCH questions/1 def update if @question.update_attributes(question_params) redirect_to(admin_conference_questions_path(conference_id: @conference.short_title), notice: "Question '#{@question.title}' for #{@conference.short_title} successfully updated.") else - redirect_to(admin_conference_questions_path(conference_id: @conference.short_title), notice: "Update of questions for #{@conference.short_title} failed. #{@question.errors.full_messages.join('. ')}") + flash[:error] = "Update of questions for #{@conference.short_title} failed. #{@question.errors.full_messages.join('. ')}" + redirect_to(admin_conference_questions_path(conference_id: @conference.short_title)) end end @@ -60,7 +54,7 @@ module Admin if @conference.update_attributes(conference_params) redirect_to(admin_conference_questions_path(conference_id: @conference.short_title), notice: "Questions for #{@conference.short_title} successfully updated.") else - redirect_to(admin_conference_questions_path(conference_id: @conference.short_title), notice: "Update of questions for #{@conference.short_title} failed.") + redirect_to(admin_conference_questions_path(conference_id: @conference.short_title), flash: { error: "Update of questions for #{@conference.short_title} failed." }) end end @@ -69,7 +63,6 @@ module Admin if can? :destroy, @question # Do not delete global questions if !@question.global - # Delete question and its answers begin Question.transaction do @@ -84,7 +77,7 @@ module Admin flash[:error] = 'Could not delete question.' end else - flash[:error] = 'You cannot delete global questions.' + flash[:alert] = 'You cannot delete global questions.' end else flash[:error] = 'You must be an admin to delete a question.' diff --git a/spec/controllers/admin/questions_controller_spec.rb b/spec/controllers/admin/questions_controller_spec.rb new file mode 100644 index 00000000..9d98e76d --- /dev/null +++ b/spec/controllers/admin/questions_controller_spec.rb @@ -0,0 +1,197 @@ +require 'spec_helper' + +describe Admin::QuestionsController, type: :controller do + let(:conference) { create(:conference) } + let(:user) { create(:user) } + let(:question) { create(:question, conferences: [conference]) } + + context 'user is signed in' do + before { sign_in(user) } + + describe 'GET #index' do + before do + get :index, conference_id: conference.short_title + end + + it 'renders the index template' do + expect(response).to render_template('index') + end + + it 'populates an array of questions and creates new question object' do + global_questions = Question.where(global: true).all + expect(assigns(:questions)).to match_array(global_questions) + expect(assigns(:new_question)).to be_instance_of(Question) + end + end + + describe 'GET #show' do + before do + @registration = create(:registration, conference: conference) + create(:qanswer, registrations: [@registration]) + get :show, conference_id: conference.short_title, id: question.id + end + + it 'renders the show template' do + expect(response).to render_template('show') + end + + it 'assigns registration answers to registrations' do + expect(assigns(:registrations)).to match_array([@registration]) + end + end + + describe 'POST #create' do + context 'saves successfully' do + before do + post :create, question: attributes_for(:question), conference_id: conference.short_title + end + + it 'shows success message in flash notice' do + expect(flash[:notice]).to match('Question was successfully created.') + end + + it 'redirects to questions index path' do + expect(response).to redirect_to admin_conference_questions_path + end + end + + context 'save fails' do + before do + allow_any_instance_of(Question).to receive(:save).and_return(false) + post :create, question: attributes_for(:question), conference_id: conference.short_title + end + + it 'shows error in flash message' do + expect(flash[:error]).to include "Oops, couldn't save Question." + end + end + end + + describe 'GET #edit' do + context 'non global question' do + before do + get :edit, conference_id: conference.short_title, id: question.id + end + + it 'renders the index template' do + expect(response).to render_template('edit') + end + end + + context 'global question' do + before do + question.update_attributes(global: true) + get :edit, conference_id: conference.short_title, id: question.id + end + + it 'redirects to questions index path' do + expect(response).to redirect_to admin_conference_questions_path(conference_id: conference.short_title) + end + + it 'shows error in flash message' do + expect(flash[:alert]).to include 'Sorry, you cannot edit global questions. Create a new one.' + end + end + end + + describe 'PATCH #update' do + context 'updates successfully' do + before do + patch :update, question: attributes_for(:question, global: true), + commit: 'Save', + conference_id: conference.short_title, + id: question.id + end + + it 'shows success message in flash notice' do + expect(flash[:notice]).to match "Question '#{question.title}' for #{conference.short_title} successfully updated." + end + + it 'redirects to questions index path' do + expect(response).to redirect_to admin_conference_questions_path(conference_id: conference.short_title) + end + end + + context 'update fails' do + before do + allow_any_instance_of(Question).to receive(:save).and_return(false) + patch :update, question: attributes_for(:question, global: true), + commit: 'Save', + conference_id: conference.short_title, + id: question.id + end + + it 'shows error in flash message' do + expect(flash[:error]).to include "Update of questions for #{conference.short_title} failed." + end + end + end + + describe 'PATCH #update_conference' do + context 'updates successfully' do + before do + patch :update_conference, conference: { question_ids: ['', '1', '', '', '', '']}, + commit: 'Save Questions', + conference_id: conference.short_title + end + + it 'shows success message in flash notice' do + expect(flash[:notice]).to match "Questions for #{conference.short_title} successfully updated." + end + + it 'redirects to questions index path' do + expect(response).to redirect_to admin_conference_questions_path(conference_id: conference.short_title) + end + end + + context 'update fails' do + before do + allow_any_instance_of(Conference).to receive(:save).and_return(false) + patch :update_conference, conference: { question_ids: ['', '1', '', '', '', '']}, + commit: 'Save Questions', + conference_id: conference.short_title + end + + it 'shows error in flash message' do + expect(flash[:error]).to include "Update of questions for #{conference.short_title} failed." + end + end + end + + describe 'DELETE #destroy' do + context 'non gloabl question' do + context 'deletes successfully' do + before do + xhr :delete, :destroy, conference_id: conference.short_title, id: question.id + end + + it 'shows success message in flash notice' do + expect(flash[:notice]).to include "Deleted question: #{question.title} and its answers:" + end + end + + context 'delete fails' do + before do + allow_any_instance_of(Question).to receive(:destroy).and_raise(ActiveRecord::RecordInvalid.new(question)) + xhr :delete, :destroy, conference_id: conference.short_title, id: question.id + end + + it 'shows error in flash message' do + expect(flash[:error]).to match 'Could not delete question.' + end + end + end + + context 'global question' do + before do + question.update_attributes(global: true) + xhr :delete, :destroy, conference_id: conference.short_title, id: question.id + end + + it 'shows error in flash message' do + expect(flash[:alert]).to match 'You cannot delete global questions.' + end + end + end + end +end diff --git a/spec/factories/qanswer.rb b/spec/factories/qanswer.rb index 136b5655..60b2930f 100644 --- a/spec/factories/qanswer.rb +++ b/spec/factories/qanswer.rb @@ -4,5 +4,6 @@ FactoryGirl.define do factory :qanswer do question answer + registrations { [create(:registration)] } end end diff --git a/spec/factories/question.rb b/spec/factories/question.rb index 9bb933cb..488bc0e9 100644 --- a/spec/factories/question.rb +++ b/spec/factories/question.rb @@ -3,7 +3,9 @@ FactoryGirl.define do factory :question do title 'blah' + question_type_id 1 question_type + global false after(:build) do |question| question.answers << build(:answer) question.conferences << build(:conference)