Adds model and controller tests for Question.

This commit is contained in:
Stella Rouzi 2015-09-16 12:20:52 +03:00
parent e25425bd77
commit a04df00bdc
6 changed files with 311 additions and 24 deletions

View file

@ -34,10 +34,10 @@ module Admin
respond_to do |format|
# Do not automatically associate newly created question with the conference. The new question shall be enabled for the conference manually.
if @question.save
format.html { redirect_to admin_conference_questions_path, notice: 'Question was successfully created.' }
format.html { redirect_to admin_conference_questions_path(@conference.short_title), notice: 'Question was successfully created.' }
else
flash[:error] = "Oops, couldn't save Question. #{@question.errors.full_messages.join('. ')}"
format.html { redirect_to admin_conference_questions_path }
format.html { redirect_to admin_conference_questions_path(@conference.short_title) }
end
end
end
@ -59,10 +59,11 @@ module Admin
@conference.questions.delete(@question)
end
redirect_to(admin_conference_questions_path(conference_id: @conference.short_title), notice: "Question '#{@question.title}' for #{@conference.short_title} updated successfully.")
flash[:notice] = "Question '#{@question.title}' for #{@conference.short_title} updated successfully."
redirect_to admin_conference_questions_path(@conference.short_title)
else
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)
redirect_to admin_conference_questions_path(@conference.short_title)
end
end
@ -77,16 +78,19 @@ module Admin
ids.delete(@question.id)
end
if @conference.update_attributes(question_ids: ids)
flash[:notice] = "Questions for #{@conference.short_title} successfully updated. Note: Only questions with answers can be enabled for a conference."
if @conference.update(question_ids: ids)
flash[:notice] = "Question '#{@question.title}' #{params[:enable]=='true' ? 'enabled' : 'disabled'} for #{@conference.title}."
else
flash[:error] = "Update of questions for #{@conference.short_title} failed."
flash[:error] = "Failed to #{params[:enable]=='true' ? 'enable' : 'disable'} question '#{@question.title}' for #{@conference.title}. Note: Only questions with answers can be enabled for a conference."
end
if request.xhr?
render js: 'index'
else
redirect_to admin_conference_questions_path(conference_id: @conference.short_title)
respond_to do |format|
format.html do
redirect_to admin_conference_questions_path(@conference.short_title)
end
format.js do
render js: 'index'
end
end
end
@ -114,7 +118,7 @@ module Admin
flash[:error] = 'You cannot delete global questions that are currently being used for a conference.'
end
else
flash[:error] = 'You must be an admin to delete a question.'
flash[:error] = 'You cannot delete the question. Do you have the necessary permissions?'
end
@questions = Question.where(global: true).all | Question.where(conference_id: @conference.id) | @conference.questions

View file

@ -1,16 +1,21 @@
require 'spec_helper'
describe Admin::QuestionsController do
let!(:conference) { create(:conference) }
let!(:question_with_answers) { create(:question_with_answers) }
let!(:question_without_answers) { create(:question) }
let!(:conference) { create(:conference, title: 'my conference') }
let!(:question_with_answers) { create(:question_with_answers, conference_id: conference.id) }
let!(:question_without_answers) { create(:question, conference_id: conference.id) }
let(:question_type_yes_no) { QuestionType.find_by(title: 'Yes/No') }
let(:question_type_single_choice) { create(:single_choice) }
let(:first_answer) { create(:first_answer) }
let(:second_answer) { create(:second_answer) }
let(:organizer) { create(:organizer) }
let(:question) { create(:question, title: 'test title', question_type_id: create(:single_choice).id) }
describe 'PATCH #update_conference' do
before(:each) do
sign_in(organizer)
end
before(:each) do
sign_in(organizer)
end
describe 'PATCH #toggle_question' do
it 'enables a question for a conference if the question has answers' do
patch :toggle_question, conference_id: conference.short_title, id: question_with_answers, enable: 'true'
@ -19,8 +24,225 @@ describe Admin::QuestionsController do
expect(conference.question_ids).to eq([question_with_answers.id])
expect(conference.question_ids).to_not include([question_without_answers.id])
expect(flash[:notice]).to eq("Questions for #{conference.short_title} successfully updated. Note: Only questions with answers can be enabled for a conference.")
expect(flash[:notice]).to eq("Question 'Which do you choose?' enabled for my conference.")
expect(response).to redirect_to admin_conference_questions_path(conference.short_title)
end
it 'disables a question for a conference if the question has answers' do
patch :toggle_question, conference_id: conference.short_title, id: question_with_answers, enable: 'true'
patch :toggle_question, conference_id: conference.short_title, id: question_with_answers, enable: 'false'
conference.reload
expect(conference.question_ids).to eq([])
expect(conference.question_ids).to_not include([question_with_answers.id])
expect(flash[:notice]).to eq("Question 'Which do you choose?' disabled for my conference.")
expect(response).to redirect_to admin_conference_questions_path(conference.short_title)
end
end
describe 'GET #index' do
it 'renders the index template' do
get :index, conference_id: conference.short_title
expect(response).to render_template :index
end
it 'properly assigns questions, when conference does not have enabled questions' do
questions_global = Question.where(global: true)
get :index, conference_id: conference.short_title
questions_array = questions_global.to_a
questions_array << question_with_answers
questions_array << question_without_answers
expect(assigns(:questions)).to match_array(questions_array)
end
end
describe 'GET #show' do
before :each do
@registration = create(:registration, conference: conference)
conference.questions << question_with_answers
@registration.qanswers << question_with_answers.qanswers.first
end
it 'properly assigns registrations' do
get :show, conference_id: conference.short_title, id: question_with_answers.id
expect(assigns(:registrations).to_a).to eq [@registration]
end
end
describe 'POST #create' do
context 'creates a question' do
before :each do
@expected = Question.count + 1
post :create, conference_id: conference.short_title, question: attributes_for(:question, title: 'test',
question_type_id: question_type_single_choice.id)
end
it 'successfully' do
expect(Question.count).to eq @expected
end
it 'assigns question object with correct attributes' do
expect(assigns(:question).title).to eq 'test'
expect(assigns(:question).conference_id).to eq conference.id
end
it 'renders flash with success message' do
expect(flash[:notice]).to eq 'Question was successfully created.'
end
it 'redirects to index' do
expect(response).to redirect_to admin_conference_questions_path(conference.short_title)
end
end
context 'creates a question with Yes/No question type' do
before :each do
@expected = Question.count + 1
post :create, conference_id: conference.short_title, question: attributes_for(:question, title: 'test',
question_type_id: QuestionType.find_by(title: 'Yes/No').id)
end
it 'successfully' do
expect(Question.count).to eq @expected
end
it 'assigns question object with correct attributes' do
expect(assigns(:question).title).to eq 'test'
expect(assigns(:question).conference_id).to eq conference.id
end
it 'renders flash with success message' do
expect(flash[:notice]).to eq 'Question was successfully created.'
end
it 'redirects to index' do
expect(response).to redirect_to admin_conference_questions_path(conference.short_title)
end
it 'assigns answers automatically' do
expect(assigns(:question).answers.to_a).to eq [ Answer.find_by(title: 'Yes'), Answer.find_by(title: 'No') ]
end
end
context 'with invalid attributes' do
before :each do
@expected = Question.count
post :create, conference_id: conference.short_title, question: attributes_for(:question, title: '', question_type_id: question_type_single_choice.id)
end
it 'does not save the new question in database' do
expect(Question.count).to eq @expected
end
it 'redirects to index page' do
expect(response).to redirect_to admin_conference_questions_path(conference.short_title)
end
it 'shows flash error message' do
expect(flash[:error]).to eq "Oops, couldn't save Question. Title can't be blank"
end
end
end
describe 'PATCH #update' do
before :each do
question.answers << first_answer
question.answers << second_answer
question.conferences << conference
end
context 'with invalid attributes' do
before :each do
patch :update, conference_id: conference.short_title, id: question.id, question: attributes_for(:question, title: '')
end
it 'does not save the question' do
expect(question.title).to eq 'test title'
end
it 'renders failure flash error message' do
expect(flash[:error]).to eq "Update of questions for #{conference.short_title} failed. Title can't be blank"
end
it 'redirects to index' do
expect(response).to redirect_to admin_conference_questions_path(conference.short_title)
end
end
context 'with valid attibutes' do
before :each do
patch :update, conference_id: conference.short_title, id: question.id, question: attributes_for(:question, title: 'new title')
end
it 'successfully' do
question.reload
expect(question.title).to eq 'new title'
end
it 'renders success flash notice message' do
question.reload
expect(flash[:notice]).to eq "Question 'new title' for #{conference.short_title} updated successfully."
end
it 'redirects to index' do
expect(response).to redirect_to admin_conference_questions_path(conference.short_title)
end
end
it 'disables question for conference, if question does not have answers' do
question.answers = []
patch :update, conference_id: conference.short_title, id: question.id, question: attributes_for(:question)
question.reload
expect(question.conferences).to eq []
end
end
describe 'DELETE #destroy' do
context 'global questions' do
it 'deletes question not used in any conference' do
global_question = Question.find_by(global: true)
expected = Question.count - 1
delete :destroy, conference_id: conference.short_title, id: global_question.id
expect(Question.count).to eq expected
end
it 'does not delete question used in a conference' do
global_question = Question.find_by(global: true)
conference.questions << global_question
expected = Question.count
delete :destroy, conference_id: conference.short_title, id: global_question.id
expect(Question.count).to eq expected
end
end
context 'not global questions' do
it 'deletes a question not used in the conference' do
expected = Question.count - 1
expect(conference.questions).not_to include question_with_answers
delete :destroy, conference_id: conference.short_title, id: question_with_answers.id
expect(Question.count).to eq expected
end
it 'deletes question used in a conference' do
conference.questions << question_with_answers
expect(question_with_answers.conferences).to include conference
expected = Question.count - 1
delete :destroy, conference_id: conference.short_title, id: question_with_answers.id
expect(Question.count).to eq expected
end
end
end
end

View file

@ -4,11 +4,11 @@ FactoryGirl.define do
factory :answer do
title 'I do'
factory :answer1 do
factory :first_answer do
title 'First Answer'
end
factory :answer2 do
factory :second_answer do
title 'Second Answer'
end

View file

@ -9,8 +9,8 @@ FactoryGirl.define do
title 'Which do you choose?'
after(:build) do |question|
question.answers << build(:answer1)
question.answers << build(:answer2)
question.answers << build(:first_answer)
question.answers << build(:second_answer)
end
end

View file

@ -0,0 +1,39 @@
require 'spec_helper'
describe Answer do
let(:conference) { create(:conference) }
let(:question) { create(:question) }
let(:second_answer) { create(:second_answer) }
let(:registration) { create(:registration, conference: conference) }
describe 'validations' do
it 'has a valid factory' do
expect(build(:answer)).to be_valid
end
it 'is not valid without a title' do
should validate_presence_of(:title)
expect(build(:answer, title: nil)).not_to be_valid
end
it 'cannot be modified if the question is being used' do
question.answers << second_answer
second_answer.title = 'new title'
expect(second_answer.valid?).to be false
end
end
describe '#sum_replies' do
before :each do
conference.questions << question
registration.qanswers << create(:qanswer, question: question, answer: second_answer)
end
it 'returns no of replies for the answer, given a question and a conference' do
expect(second_answer.sum_replies(question, conference)).to eq 1
end
end
end

View file

@ -0,0 +1,22 @@
require 'spec_helper'
describe Question do
describe 'validations' do
it 'has a valid factory' do
expect(build(:question)).to be_valid
end
it 'is not valid without a title' do
should validate_presence_of(:title)
expect(build(:question, title: nil)).not_to be_valid
end
it 'is not valid without a question type' do
should validate_presence_of(:question_type_id)
expect(build(:question, question_type_id: nil)).not_to be_valid
end
end
end