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 @@
- <%= text_area_tag 'answer[live_code][text]', (answers['text']), { disabled: true, data: {last: answers['text']}} %>
+ <%= text_area_tag 'answer[live_code][text]', value_text, { disabled: true, data: {last: answers['text']}} %>
- <%= text_area_tag 'answer[live_code][html]', (answers['html']), { disabled: true, data: {id: 'code-html', last: answers['html']}, class: 'code-answer code-html' } %>
+ <%= text_area_tag 'answer[live_code][html]', value_html, { disabled: true, data: {id: 'code-html', last: answers['html']}, class: 'code-answer code-html' } %>
- <%= text_area_tag 'answer[live_code][css]', (answers['css']), { disabled: true, data: {id: 'code-css', last: answers['css']}, class: 'code-answer code-css' } %>
+ <%= text_area_tag 'answer[live_code][css]', value_css, { disabled: true, data: {id: 'code-css', last: answers['css']}, class: 'code-answer code-css' } %>
- <%= text_area_tag 'answer[live_code][js]', (answers['js']), { disabled: true, data: {id: 'code-js', last: answers['js']}, class: 'code-answer code-js' } %>
+ <%= text_area_tag 'answer[live_code][js]', value_js, { disabled: true, data: {id: 'code-js', last: answers['js']}, class: 'code-answer code-js' } %>
diff --git a/app/workers/candidate_quiz_question.rb b/app/workers/candidate_quiz_question.rb
index 70220e8..20e4d9b 100644
--- a/app/workers/candidate_quiz_question.rb
+++ b/app/workers/candidate_quiz_question.rb
@@ -39,7 +39,7 @@ class CandidateQuizQuestion
end
def input_options
- YAML.load(row["input_options"].to_s)
+ YAML.load(row["input_options"].to_s) || {}
end
def answer
diff --git a/test/fixtures/questions.yml b/test/fixtures/questions.yml
index e0e02ed..db562de 100644
--- a/test/fixtures/questions.yml
+++ b/test/fixtures/questions.yml
@@ -68,6 +68,8 @@ fed7:
category: Javascript
input_type: live_code
input_options:
+ :html: "
sample seed html
"
+ :css: "body { color: #644; }"
sort: 6
active: true
diff --git a/test/integration/question_live_coder_test.rb b/test/integration/question_live_coder_test.rb
index b61b19f..9fec713 100644
--- a/test/integration/question_live_coder_test.rb
+++ b/test/integration/question_live_coder_test.rb
@@ -15,4 +15,13 @@ class QuestionLiveCoderTest < ActionDispatch::IntegrationTest
# TODO: add in capybara and test form post
# assert_redirected summary_path
end
+
+ test "should load seed data into live coder" do
+ setup_auth candidates(:juan)
+ question = questions(:fed7)
+
+ get question_path(question.id)
+ assert_response :success
+ assert_select '#answer_live_code_html', question.input_options['html']
+ end
end
diff --git a/test/models/question_test.rb b/test/models/question_test.rb
index c5465fa..ab2e1ec 100644
--- a/test/models/question_test.rb
+++ b/test/models/question_test.rb
@@ -11,4 +11,11 @@ class QuestionTest < ActiveSupport::TestCase
assert_equal 2, question.input_options.count
end
+
+ test 'should have seed input for live_coder' do
+ question = Question.find questions(:fed7).to_i
+
+ assert_kind_of Hash, question.input_options
+ assert question.input_options.keys.include? :html
+ end
end
diff --git a/test/test_helpers/answer_validatable.rb b/test/test_helpers/answer_validatable.rb
index 0b0e71e..cb2ba6d 100644
--- a/test/test_helpers/answer_validatable.rb
+++ b/test/test_helpers/answer_validatable.rb
@@ -3,13 +3,15 @@ class AnswerValidatable
attr_accessor :answer
attr_accessor :question
+ attr_accessor :question_id
validates :answer, answer_format: true
MockQuestion = Struct.new(:input_type)
- def initialize input_type
+ def initialize input_type, qid = nil
@input_type = input_type
+ @question_id = qid
end
def question
diff --git a/test/validators/answer_format_validator/live_code_test.rb b/test/validators/answer_format_validator/live_code_test.rb
index 9f6de95..68515d1 100644
--- a/test/validators/answer_format_validator/live_code_test.rb
+++ b/test/validators/answer_format_validator/live_code_test.rb
@@ -48,4 +48,20 @@ class AnswerFormatValidatorTest < ActiveSupport::TestCase
assert obj.valid?
assert obj.errors.messages.empty?
end
+
+ test "live_code should PASS using seed data" do
+ obj = AnswerValidatable.new('live_code', questions(:fed7).id)
+ obj.answer = { text: "no thanks", html: "
sample seed html
", css: "body { color: #644; }", js: "" }
+
+ assert obj.valid?
+ assert obj.errors.messages.empty?
+ end
+
+ test "live_code should FAIL with seed data only" do
+ obj = AnswerValidatable.new('live_code', questions(:fed7).id)
+ obj.answer = { text: "", html: "
sample seed html
", css: "body { color: #644; }", js: "" }
+
+ refute obj.valid?
+ assert_match(/write.*code/, obj.errors.messages[:answer][0])
+ end
end