From 2b55fed1bc0843f758452a40abdd19ebdb15563c Mon Sep 17 00:00:00 2001 From: Mark Moser Date: Tue, 23 Aug 2016 21:54:53 -0500 Subject: [PATCH] live coder seeding - completes #16 --- app/assets/javascripts/admin.js | 4 +++- app/controllers/admin/question_controller.rb | 4 ++-- app/models/question.rb | 10 ++++++++-- app/validators/answer_format_validator.rb | 16 +++++++++++++++- app/views/admin/question/_live_code.html.erb | 17 +++-------------- app/views/quiz/_live_code.html.erb | 15 ++++++++++----- app/workers/candidate_quiz_question.rb | 2 +- test/fixtures/questions.yml | 2 ++ test/integration/question_live_coder_test.rb | 9 +++++++++ test/models/question_test.rb | 7 +++++++ test/test_helpers/answer_validatable.rb | 4 +++- .../answer_format_validator/live_code_test.rb | 16 ++++++++++++++++ 12 files changed, 79 insertions(+), 27 deletions(-) diff --git a/app/assets/javascripts/admin.js b/app/assets/javascripts/admin.js index 7633280..bd610a5 100644 --- a/app/assets/javascripts/admin.js +++ b/app/assets/javascripts/admin.js @@ -10,7 +10,9 @@ $(function(){ $("#question_input_type").on('change', function(){ var qid = $(this).attr('data-qid') === undefined ? '' : "/" + $(this).attr('data-qid'); // /admin/question(/:question_id)/options/:input_type - $("[data-id=input-options-wrapper]").load("/admin/question" + qid + "/options/" + $(this).val()); + $("[data-id=input-options-wrapper]").load("/admin/question" + qid + "/options/" + $(this).val(), function(){ + $(".code-input textarea").linedtextarea(); + }); }); }); diff --git a/app/controllers/admin/question_controller.rb b/app/controllers/admin/question_controller.rb index c066353..ee5a355 100644 --- a/app/controllers/admin/question_controller.rb +++ b/app/controllers/admin/question_controller.rb @@ -60,9 +60,9 @@ module Admin def process_question_params question = question_params question[:input_options] = question_params[:multi_choice] unless question_params[:multi_choice].nil? - question[:input_options] = question_params[:live_coder] unless question_params[:live_coder].nil? + question[:input_options] = question_params[:live_code] unless question_params[:live_code].nil? question.delete(:multi_choice) - question.delete(:live_coder) + question.delete(:live_code) question end end diff --git a/app/models/question.rb b/app/models/question.rb index cdcdb3e..2b8cac3 100644 --- a/app/models/question.rb +++ b/app/models/question.rb @@ -1,9 +1,10 @@ class Question < ApplicationRecord - serialize :input_options, Array + serialize :input_options has_many :answers belongs_to :quiz + after_initialize :prepare_input_options before_validation :compact_input_options validates :quiz_id, presence: true @@ -15,6 +16,11 @@ class Question < ApplicationRecord private def compact_input_options - self.input_options = input_options.reject(&:blank?) + self.input_options = input_options.reject { |_k, v| v.blank? } if input_options.class == Hash + self.input_options = input_options.reject(&:blank?) if input_options.class == Array + end + + def prepare_input_options + self.input_options = input_options || {} end end diff --git a/app/validators/answer_format_validator.rb b/app/validators/answer_format_validator.rb index 4d62810..bf76fd2 100644 --- a/app/validators/answer_format_validator.rb +++ b/app/validators/answer_format_validator.rb @@ -31,7 +31,9 @@ class AnswerFormatValidator < ActiveModel::EachValidator end def live_code record, attribute, value - return unless value.nil? || value.values.join.blank? + seed = (Question.find_by(id: record.question_id) || Question.new).input_options + + return unless value.nil? || value.values.join.blank? || !match_seed?(value, seed) record.errors[attribute] << (options[:message] || live_code_error_message(value)) end @@ -44,4 +46,16 @@ class AnswerFormatValidator < ActiveModel::EachValidator end "You must write comments or code in one of the textareas to progress." end + + def match_seed? value, seed + s_value = value.stringify_keys + s_seed = seed.stringify_keys + keys = s_value.merge(s_seed).keys.uniq + + matches = keys.inject([]) do |memo, k| + memo << (s_value[k].to_s.strip == s_seed[k].to_s.strip) + end + + matches.include? false + end end diff --git a/app/views/admin/question/_live_code.html.erb b/app/views/admin/question/_live_code.html.erb index 04af9e6..99793f0 100644 --- a/app/views/admin/question/_live_code.html.erb +++ b/app/views/admin/question/_live_code.html.erb @@ -1,29 +1,18 @@ -<% - - return nil - - # don't load this partial yet. Will finish in issue #16 - # https://gitlab.perficientxd.com/pdr/skill-assessment-app/issues/16 - options = { 'text' => '', 'html' => '', 'css' => '', 'js' => '' } -%> - -
- <%= text_area_tag 'question[live_code][html]', options['html'], { data: {id: 'code-html', last: options['html']}, class: 'code-answer code-html' } %> + <%= text_area_tag 'question[live_code][html]', question.input_options['html'], { data: {id: 'code-html', last: question.input_options['html']}, class: 'code-answer code-html' } %>
- <%= text_area_tag 'question[live_code][css]', options['css'], { data: {id: 'code-css', last: options['css']}, class: 'code-answer code-css' } %> + <%= text_area_tag 'question[live_code][css]', question.input_options['css'], { data: {id: 'code-css', last: question.input_options['css']}, class: 'code-answer code-css' } %>
- <%= text_area_tag 'question[live_code][js]', options['js'], { data: {id: 'code-js', last: options['js']}, class: 'code-answer code-js' } %> + <%= text_area_tag 'question[live_code][js]', question.input_options['js'], { data: {id: 'code-js', last: question.input_options['js']}, class: 'code-answer code-js' } %>
- diff --git a/app/views/quiz/_live_code.html.erb b/app/views/quiz/_live_code.html.erb index 9a3a344..b3a92b0 100644 --- a/app/views/quiz/_live_code.html.erb +++ b/app/views/quiz/_live_code.html.erb @@ -5,7 +5,12 @@ name: "answer[#{question.input_type}][later]", checked: Array(question.answer).include?('finish-later') } - answers = answer.try(:answer) || answer + + answers = answer.try(:answer) || answer + value_text = answers['text'] || question.input_options['text'] + value_html = answers['html'] || question.input_options['html'] + value_css = answers['css'] || question.input_options['css'] + value_js = answers['js'] || question.input_options['js'] %> <%= render partial: "quiz/answer_errors", locals: {question: question, answer: answer} %> @@ -38,21 +43,21 @@