From e6358beec862529efd9365f1f827b9f0cd796a53 Mon Sep 17 00:00:00 2001 From: Mark Moser Date: Sun, 7 Aug 2016 09:36:08 -0500 Subject: [PATCH] move summary and questions to quiz controller --- .rubocop.yml | 1 - app/controllers/candidate_controller.rb | 114 ----------------- app/controllers/quiz_controller.rb | 119 ++++++++++++++++++ app/views/candidate/_live_code_text.html.erb | 1 - .../_answer_errors.html.erb | 0 .../{candidate => quiz}/_checkbox.html.erb | 2 +- .../{candidate => quiz}/_live_code.html.erb | 2 +- app/views/quiz/_live_code_text.html.erb | 1 + app/views/{candidate => quiz}/_radio.html.erb | 2 +- app/views/{candidate => quiz}/_text.html.erb | 2 +- .../{candidate => quiz}/live_code.html.erb | 0 .../live_code_text.html.erb | 0 .../{candidate => quiz}/question.html.erb | 0 .../{candidate => quiz}/summary.html.erb | 0 app/views/review/view.html.erb | 2 +- config/routes.rb | 44 +++---- test/controllers/candidate_controller_test.rb | 19 --- test/controllers/quiz_controller_test.rb | 28 +++++ ...s_test.rb => question_attachments_test.rb} | 2 +- test/integration/question_live_coder_test.rb | 18 +++ 20 files changed, 194 insertions(+), 163 deletions(-) create mode 100644 app/controllers/quiz_controller.rb delete mode 100644 app/views/candidate/_live_code_text.html.erb rename app/views/{candidate => quiz}/_answer_errors.html.erb (100%) rename app/views/{candidate => quiz}/_checkbox.html.erb (83%) rename app/views/{candidate => quiz}/_live_code.html.erb (93%) create mode 100644 app/views/quiz/_live_code_text.html.erb rename app/views/{candidate => quiz}/_radio.html.erb (78%) rename app/views/{candidate => quiz}/_text.html.erb (74%) rename app/views/{candidate => quiz}/live_code.html.erb (100%) rename app/views/{candidate => quiz}/live_code_text.html.erb (100%) rename app/views/{candidate => quiz}/question.html.erb (100%) rename app/views/{candidate => quiz}/summary.html.erb (100%) create mode 100644 test/controllers/quiz_controller_test.rb rename test/integration/{question_features_test.rb => question_attachments_test.rb} (94%) create mode 100644 test/integration/question_live_coder_test.rb diff --git a/.rubocop.yml b/.rubocop.yml index f214d03..e67f01d 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -46,7 +46,6 @@ Metrics/AbcSize: # TODO: remove this cop exception after refactor Metrics/ClassLength: Exclude: - - app/controllers/candidate_controller.rb - test/**/* Metrics/LineLength: diff --git a/app/controllers/candidate_controller.rb b/app/controllers/candidate_controller.rb index 59d1e77..60e93e7 100644 --- a/app/controllers/candidate_controller.rb +++ b/app/controllers/candidate_controller.rb @@ -25,40 +25,6 @@ class CandidateController < ApplicationController reset_session end - def question - qid = prep_status.current_question_id || params[:question_id] - redirect_to :summary and return if qid.nil? - prep_question qid - prep_instance_answer @question - end - - def update_answer - qid = answer_params[:question_id] || prep_status.current_question_id - @answer = prep_answer qid - send "process_#{prep_question(qid).input_type}" - end - - def live_coder - prep_question params[:question_id] - prep_instance_answer @question - prep_answer params[:question_id] - render @question.input_type, layout: false - end - - def summary - @quiz = current_candidate.my_quiz - redirect_to :question and return unless prep_status.current_question_id.nil? - end - - def update_summary - prep_status - not_completed_error = 'You must complete all questions to submit your test.' - record_error = 'There was a problem with your submission. Please try again later.' - redirect_to :summary, flash: { error: not_completed_error } and return unless @status.can_submit - redirect_to :thankyou and return if current_candidate.complete! - redirect_to :summary, flash: { error: record_error } - end - def validate candidate = Candidate.find_by(test_hash: params['test_id']) redirect_to(root_path, flash: { error: "Sorry, incorrect test id" }) and return if candidate.nil? @@ -80,84 +46,4 @@ class CandidateController < ApplicationController def send_to_oops redirect_to oops_path if current_candidate end - - def prep_question qid - @question = current_candidate.fetch_question(qid) - end - - def prep_status - @status ||= QuizStatus.new(current_candidate) - end - - def prep_instance_answer question - @answer = question.answer.nil? ? Answer.new : Answer.find(question.answer_id) - end - - def answer_params - params.require(:answer).permit( - :question_id, - :answer_id, - :radio, - :text, - checkbox: [], - live_code: [:later, :html, :css, :js], - live_code_text: [:later, :html, :css, :js, :text] - ) - end - - def prep_answer qid = answer_params[:question_id] - answer_ids = { question_id: qid, candidate_id: current_candidate.to_i } - answer = Answer.find_or_create_by(answer_ids) - answer - end - - def route_answer - if @answer.errors.present? - prep_status - prep_question answer_params[:question_id] - flash[:answer_error] = answer_params[:question_id].to_i - render :question - else - flash.delete(:answer_error) - # TODO: change params.key? to submit = save/next/summary - # redirect_to :summary and return if params.key?(:update) - redirect_to :saved and return if params.key?(:save) - redirect_to :question - end - end - - def process_text - @answer.update(answer: answer_params[:text], - saved: params.key?(:save), - submitted: params.key?(:submit)) - route_answer - end - - def process_radio - @answer.update(answer: answer_params[:radio], - saved: params.key?(:save), - submitted: params.key?(:submit)) - route_answer - end - - def process_checkbox - @answer.update(answer: answer_params[:checkbox], - saved: params.key?(:save), - submitted: params.key?(:submit)) - route_answer - end - - def process_live_code - @answer.update(answer: answer_params[:live_code].to_h, - saved: params.key?(:save), - submitted: params.key?(:submit)) - route_answer - end - - def process_live_code_text - @answer.update(answer: answer_params[:live_code_text].to_h, - saved: params.key?(:save), - submitted: params.key?(:submit)) - route_answer - end end diff --git a/app/controllers/quiz_controller.rb b/app/controllers/quiz_controller.rb new file mode 100644 index 0000000..078b029 --- /dev/null +++ b/app/controllers/quiz_controller.rb @@ -0,0 +1,119 @@ +class QuizController < ApplicationController + before_action :authorize_candidate + + def question + qid = prep_status.current_question_id || params[:question_id] + redirect_to :summary and return if qid.nil? + prep_question qid + prep_instance_answer @question + end + + def update_answer + qid = answer_params[:question_id] || prep_status.current_question_id + @answer = prep_answer qid + send "process_#{prep_question(qid).input_type}" + end + + def live_coder + prep_question params[:question_id] + prep_instance_answer @question + prep_answer params[:question_id] + render @question.input_type, layout: false + end + + def summary + @quiz = current_candidate.my_quiz + redirect_to :question and return unless prep_status.current_question_id.nil? + end + + def update_summary + prep_status + not_completed_error = 'You must complete all questions to submit your test.' + record_error = 'There was a problem with your submission. Please try again later.' + redirect_to :summary, flash: { error: not_completed_error } and return unless @status.can_submit + redirect_to :thankyou and return if current_candidate.complete! + redirect_to :summary, flash: { error: record_error } + end + + private + + def prep_question qid + @question = current_candidate.fetch_question(qid) + end + + def prep_status + @status ||= QuizStatus.new(current_candidate) + end + + def prep_instance_answer question + @answer = question.answer.nil? ? Answer.new : Answer.find(question.answer_id) + end + + def answer_params + params.require(:answer).permit( + :question_id, + :answer_id, + :radio, + :text, + checkbox: [], + live_code: [:later, :html, :css, :js], + live_code_text: [:later, :html, :css, :js, :text] + ) + end + + def prep_answer qid = answer_params[:question_id] + answer_ids = { question_id: qid, candidate_id: current_candidate.to_i } + answer = Answer.find_or_create_by(answer_ids) + answer + end + + def route_answer + if @answer.errors.present? + prep_status + prep_question answer_params[:question_id] + flash[:answer_error] = answer_params[:question_id].to_i + render :question + else + flash.delete(:answer_error) + # TODO: change params.key? to submit = save/next/summary + # redirect_to :summary and return if params.key?(:update) + redirect_to :saved and return if params.key?(:save) + redirect_to :question + end + end + + def process_text + @answer.update(answer: answer_params[:text], + saved: params.key?(:save), + submitted: params.key?(:submit)) + route_answer + end + + def process_radio + @answer.update(answer: answer_params[:radio], + saved: params.key?(:save), + submitted: params.key?(:submit)) + route_answer + end + + def process_checkbox + @answer.update(answer: answer_params[:checkbox], + saved: params.key?(:save), + submitted: params.key?(:submit)) + route_answer + end + + def process_live_code + @answer.update(answer: answer_params[:live_code].to_h, + saved: params.key?(:save), + submitted: params.key?(:submit)) + route_answer + end + + def process_live_code_text + @answer.update(answer: answer_params[:live_code_text].to_h, + saved: params.key?(:save), + submitted: params.key?(:submit)) + route_answer + end +end diff --git a/app/views/candidate/_live_code_text.html.erb b/app/views/candidate/_live_code_text.html.erb deleted file mode 100644 index 11d5458..0000000 --- a/app/views/candidate/_live_code_text.html.erb +++ /dev/null @@ -1 +0,0 @@ -<%= render partial: "candidate/live_code", locals: {question: question, form: form} %> diff --git a/app/views/candidate/_answer_errors.html.erb b/app/views/quiz/_answer_errors.html.erb similarity index 100% rename from app/views/candidate/_answer_errors.html.erb rename to app/views/quiz/_answer_errors.html.erb diff --git a/app/views/candidate/_checkbox.html.erb b/app/views/quiz/_checkbox.html.erb similarity index 83% rename from app/views/candidate/_checkbox.html.erb rename to app/views/quiz/_checkbox.html.erb index ad86f2a..e63e23c 100644 --- a/app/views/candidate/_checkbox.html.erb +++ b/app/views/quiz/_checkbox.html.erb @@ -14,4 +14,4 @@ <% end %> -<%= render partial: "candidate/answer_errors", locals: {question: question, answer: @answer} %> +<%= render partial: "quiz/answer_errors", locals: {question: question, answer: @answer} %> diff --git a/app/views/candidate/_live_code.html.erb b/app/views/quiz/_live_code.html.erb similarity index 93% rename from app/views/candidate/_live_code.html.erb rename to app/views/quiz/_live_code.html.erb index f64a39f..a1df21f 100644 --- a/app/views/candidate/_live_code.html.erb +++ b/app/views/quiz/_live_code.html.erb @@ -11,7 +11,7 @@ Please revisit this page with JavaScript enabled to modify your answer. --> -<%= render partial: "candidate/answer_errors", locals: {question: question, answer: @answer} %> +<%= render partial: "quiz/answer_errors", locals: {question: question, answer: @answer} %>

diff --git a/app/views/quiz/_live_code_text.html.erb b/app/views/quiz/_live_code_text.html.erb new file mode 100644 index 0000000..1349b48 --- /dev/null +++ b/app/views/quiz/_live_code_text.html.erb @@ -0,0 +1 @@ +<%= render partial: "quiz/live_code", locals: {question: question, form: form} %> diff --git a/app/views/candidate/_radio.html.erb b/app/views/quiz/_radio.html.erb similarity index 78% rename from app/views/candidate/_radio.html.erb rename to app/views/quiz/_radio.html.erb index 3d1cd7d..89a2cf6 100644 --- a/app/views/candidate/_radio.html.erb +++ b/app/views/quiz/_radio.html.erb @@ -9,4 +9,4 @@

<% end %> -<%= render partial: "candidate/answer_errors", locals: {question: question, answer: @answer} %> +<%= render partial: "quiz/answer_errors", locals: {question: question, answer: @answer} %> diff --git a/app/views/candidate/_text.html.erb b/app/views/quiz/_text.html.erb similarity index 74% rename from app/views/candidate/_text.html.erb rename to app/views/quiz/_text.html.erb index 1c6011c..ba6b64d 100644 --- a/app/views/candidate/_text.html.erb +++ b/app/views/quiz/_text.html.erb @@ -5,4 +5,4 @@ -<%= render partial: "candidate/answer_errors", locals: {question: question, answer: @answer} %> +<%= render partial: "quiz/answer_errors", locals: {question: question, answer: @answer} %> diff --git a/app/views/candidate/live_code.html.erb b/app/views/quiz/live_code.html.erb similarity index 100% rename from app/views/candidate/live_code.html.erb rename to app/views/quiz/live_code.html.erb diff --git a/app/views/candidate/live_code_text.html.erb b/app/views/quiz/live_code_text.html.erb similarity index 100% rename from app/views/candidate/live_code_text.html.erb rename to app/views/quiz/live_code_text.html.erb diff --git a/app/views/candidate/question.html.erb b/app/views/quiz/question.html.erb similarity index 100% rename from app/views/candidate/question.html.erb rename to app/views/quiz/question.html.erb diff --git a/app/views/candidate/summary.html.erb b/app/views/quiz/summary.html.erb similarity index 100% rename from app/views/candidate/summary.html.erb rename to app/views/quiz/summary.html.erb diff --git a/app/views/review/view.html.erb b/app/views/review/view.html.erb index 51262c9..10f43aa 100644 --- a/app/views/review/view.html.erb +++ b/app/views/review/view.html.erb @@ -21,7 +21,7 @@ <% end %>
<%= hidden_field_tag 'answer[question_id]', question.question_id %> - <%= render partial: "candidate/#{question.input_type}", locals: {question: question, form: form} %> + <%= render partial: "quiz/#{question.input_type}", locals: {question: question, form: form} %>
diff --git a/config/routes.rb b/config/routes.rb index ba4630d..2e7b359 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,30 +1,30 @@ Rails.application.routes.draw do - post "/validate", to: "candidate#validate", as: :validate_candidate - get "/login(/:test_id)", to: "candidate#login", as: :login - get "/welcome", to: "candidate#welcome", as: :welcome - get "/saved", to: "candidate#saved", as: :saved - get "/thankyou", to: "candidate#thankyou", as: :thankyou - get "/oops", to: "candidate#oops", as: :oops + post "/validate", to: "candidate#validate", as: :validate_candidate + get "/login(/:test_id)", to: "candidate#login", as: :login + get "/welcome", to: "candidate#welcome", as: :welcome + get "/saved", to: "candidate#saved", as: :saved + get "/thankyou", to: "candidate#thankyou", as: :thankyou - post "/question(/:answer_id)", to: "candidate#update_answer", as: :post_answer - get "/question(/:question_id)", to: "candidate#question", as: :question - get "/live-coder-entry/:question_id", to: "candidate#live_coder", as: :live_coder + get "/oops", to: "candidate#oops", as: :oops - post "/summary", to: "candidate#update_summary", as: :post_summary - get "/summary", to: "candidate#summary", as: :summary + post "/question(/:answer_id)", to: "quiz#update_answer", as: :post_answer + get "/question(/:question_id)", to: "quiz#question", as: :question + get "/live-coder-entry/:question_id", to: "quiz#live_coder", as: :live_coder + post "/summary", to: "quiz#update_summary", as: :post_summary + get "/summary", to: "quiz#summary", as: :summary - get "/review/logout", to: "review#logout", as: :review_logout - post "/review/login", to: "review#auth", as: :review_auth - get "/review/login", to: "review#login", as: :review_login - get "/review", to: "review#index", as: :review - get "/review/:test_hash", to: "review#view", as: :review_test + get "/review/logout", to: "review#logout", as: :review_logout + post "/review/login", to: "review#auth", as: :review_auth + get "/review/login", to: "review#login", as: :review_login + get "/review", to: "review#index", as: :review + get "/review/:test_hash", to: "review#view", as: :review_test - get "/recruiter", to: "recruiter#index", as: :recruiter - get "/recruiter/new-candidate", to: "recruiter#new", as: :new_candidate - post "/recruiter/new-candidate", to: "recruiter#create", as: :create_candidate - get "/recruiter/logout", to: "recruiter#logout", as: :recruiter_logout - get "/recruiter/login", to: "recruiter#login", as: :recruiter_login - post "/recruiter/login", to: "recruiter#auth", as: :recruiter_auth + get "/recruiter", to: "recruiter#index", as: :recruiter + get "/recruiter/new-candidate", to: "recruiter#new", as: :new_candidate + post "/recruiter/new-candidate", to: "recruiter#create", as: :create_candidate + get "/recruiter/logout", to: "recruiter#logout", as: :recruiter_logout + get "/recruiter/login", to: "recruiter#login", as: :recruiter_login + post "/recruiter/login", to: "recruiter#auth", as: :recruiter_auth root to: "candidate#login" diff --git a/test/controllers/candidate_controller_test.rb b/test/controllers/candidate_controller_test.rb index 74006a6..4500630 100644 --- a/test/controllers/candidate_controller_test.rb +++ b/test/controllers/candidate_controller_test.rb @@ -17,15 +17,6 @@ class CandidateControllerTest < ActionDispatch::IntegrationTest get thankyou_path assert_redirected_to login_path - - get summary_path - assert_redirected_to login_path - - get question_path - assert_redirected_to login_path - - get question_path(questions(:fed1).id) - assert_redirected_to login_path end test "should auth to welcome" do @@ -71,16 +62,6 @@ class CandidateControllerTest < ActionDispatch::IntegrationTest assert_response :success end - test "should get flash message on bad radio response" do - setup_auth candidates(:martha) - qid = questions(:fed1).id - post post_answer_path, params: { answer: { question_id: qid, radio: nil } } - - assert_response :success - assert session[:test_id].present? - assert_equal qid, flash[:answer_error] - end - test "should NOT send mailers on submission" do setup_auth candidates(:dawn) diff --git a/test/controllers/quiz_controller_test.rb b/test/controllers/quiz_controller_test.rb new file mode 100644 index 0000000..41c567b --- /dev/null +++ b/test/controllers/quiz_controller_test.rb @@ -0,0 +1,28 @@ +require 'test_helper' + +class QuizControllerTest < ActionDispatch::IntegrationTest + def setup_auth candidate + post validate_candidate_url, params: { test_id: candidate.test_hash } + end + + test "should require auth and redirect" do + get summary_path + assert_redirected_to login_path + + get question_path + assert_redirected_to login_path + + get question_path(questions(:fed1).id) + assert_redirected_to login_path + end + + test "should get flash message on bad radio response" do + setup_auth candidates(:martha) + qid = questions(:fed1).id + post post_answer_path, params: { answer: { question_id: qid, radio: nil } } + + assert_response :success + assert session[:test_id].present? + assert_equal qid, flash[:answer_error] + end +end diff --git a/test/integration/question_features_test.rb b/test/integration/question_attachments_test.rb similarity index 94% rename from test/integration/question_features_test.rb rename to test/integration/question_attachments_test.rb index 73909af..103a094 100644 --- a/test/integration/question_features_test.rb +++ b/test/integration/question_attachments_test.rb @@ -1,6 +1,6 @@ require 'test_helper' -class QuestionFeatureTest < ActionDispatch::IntegrationTest +class QuestionAttachmentsTest < ActionDispatch::IntegrationTest def setup_auth candidate post validate_candidate_url, params: { test_id: candidate.test_hash } end diff --git a/test/integration/question_live_coder_test.rb b/test/integration/question_live_coder_test.rb new file mode 100644 index 0000000..b61b19f --- /dev/null +++ b/test/integration/question_live_coder_test.rb @@ -0,0 +1,18 @@ +require 'test_helper' + +class QuestionLiveCoderTest < ActionDispatch::IntegrationTest + def setup_auth candidate + post validate_candidate_url, params: { test_id: candidate.test_hash } + end + + test "can load a live coder question" do + setup_auth candidates(:dawn) + question = questions(:fed7) + + get question_path(question.id) + assert_response :success + assert_select '.question-text', question.question + # TODO: add in capybara and test form post + # assert_redirected summary_path + end +end