diff --git a/Dockerfile b/Dockerfile index cfa101c..213f238 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,8 +3,7 @@ MAINTAINER Mark Moser WORKDIR ~/ -ENV MYSQL_ALLOW_EMPTY_PASSWORD=yes -ENV MYSQL_ROOT_PASSWORD= +ENV MYSQL_ROOT_PASSWORD=root ENV BUILD_PACKAGES="build-essential libmysqlclient-dev openssl graphviz nodejs curl wget zlib1g-dev tmux" RUN apt-get update \ diff --git a/Guardfile b/Guardfile index 8273564..738d098 100644 --- a/Guardfile +++ b/Guardfile @@ -15,7 +15,7 @@ # # and, you'll have to watch "config/Guardfile" instead of "Guardfile" -guard :minitest do +guard :minitest, spring: true, all_after_pass: true do watch(%r{^test/test_helper\.rb$}) { 'test' } watch(%r{^test/(.*)\/?(.*)_test\.rb$}) watch(%r{^app/(.*/)?([^/]+)\.rb$}) { |m| "test/#{m[1]}#{m[2]}_test.rb" } diff --git a/app/models/candidate.rb b/app/models/candidate.rb index 4c0042a..e2850f6 100644 --- a/app/models/candidate.rb +++ b/app/models/candidate.rb @@ -1,4 +1,6 @@ class Candidate < ApplicationRecord + belongs_to :quiz + has_many :questions, through: :quiz has_many :answers belongs_to :recruiter, class_name: "User" @@ -8,6 +10,14 @@ class Candidate < ApplicationRecord validates_presence_of :test_hash validates_uniqueness_of :test_hash + def submitted_answers + answers.where(submitted: true) + end + + def answered_questions + answers.where.not(answer: nil) + end + private def generate_test_hash diff --git a/app/models/quiz.rb b/app/models/quiz.rb index 6813001..e1195de 100644 --- a/app/models/quiz.rb +++ b/app/models/quiz.rb @@ -1,3 +1,4 @@ class Quiz < ApplicationRecord has_many :questions + has_many :candidates end diff --git a/app/workers/quiz_status.rb b/app/workers/quiz_status.rb new file mode 100644 index 0000000..9e6d695 --- /dev/null +++ b/app/workers/quiz_status.rb @@ -0,0 +1,23 @@ +class QuizStatus + attr_reader :candidate + + def initialize candidate + @candidate = Candidate.find(candidate.to_i) + end + + def started + candidate.answers.count > 0 + end + + def on_summary + candidate.submitted_answers.count == candidate.questions.count + end + + def completed + candidate.completed + end + + def can_submit + on_summary && candidate.answered_questions.count == candidate.questions.count + end +end diff --git a/config/database.yml b/config/database.yml index e7ff6d0..b60aa35 100644 --- a/config/database.yml +++ b/config/database.yml @@ -14,7 +14,7 @@ default: &default encoding: utf8 pool: 5 username: root - password: + password: root host: localhost development: diff --git a/db/migrate/20160727154057_add_quiz_to_candidate.rb b/db/migrate/20160727154057_add_quiz_to_candidate.rb new file mode 100644 index 0000000..88ee3e2 --- /dev/null +++ b/db/migrate/20160727154057_add_quiz_to_candidate.rb @@ -0,0 +1,6 @@ +class AddQuizToCandidate < ActiveRecord::Migration[5.0] + def change + add_column :candidates, :quiz_id, :integer + add_index :candidates, :quiz_id + end +end diff --git a/db/schema.rb b/db/schema.rb index 0feb124..bc22151 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160726193255) do +ActiveRecord::Schema.define(version: 20160727154057) do create_table "answers", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t| t.integer "candidate_id" @@ -35,6 +35,8 @@ ActiveRecord::Schema.define(version: 20160726193255) do t.boolean "reminded" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.integer "quiz_id" + t.index ["quiz_id"], name: "index_candidates_on_quiz_id", using: :btree t.index ["recruiter_id"], name: "index_candidates_on_recruiter_id", using: :btree t.index ["test_hash"], name: "index_candidates_on_test_hash", unique: true, using: :btree end diff --git a/erd.pdf b/erd.pdf new file mode 100644 index 0000000..b7f2f8b Binary files /dev/null and b/erd.pdf differ diff --git a/rebuild-dev-db.sh b/rebuild-dev-db.sh new file mode 100755 index 0000000..fcb014e --- /dev/null +++ b/rebuild-dev-db.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +rails db:drop && \ +rails db:setup && \ +rails db:migrate && \ +rails db:fixtures:load diff --git a/start-dev.sh b/start-dev.sh index b74e8cd..8e5b2b7 100755 --- a/start-dev.sh +++ b/start-dev.sh @@ -1,3 +1,4 @@ +#!/bin/bash if [ -d '/usr/app' ]; then cd /usr/app bundle diff --git a/start-server.sh b/start-server.sh index a7592d7..0b36159 100755 --- a/start-server.sh +++ b/start-server.sh @@ -1,3 +1,4 @@ +#!/bin/bash if [ -d '/usr/app' ]; then cd /usr/app bundle diff --git a/test/fixtures/answers.yml b/test/fixtures/answers.yml index c03a940..4297a9b 100644 --- a/test/fixtures/answers.yml +++ b/test/fixtures/answers.yml @@ -24,8 +24,8 @@ dawn1: answer: option-1 saved: 0 submitted: true - created_at: <%= DateTime.now() - 2280.minutes %> - updated_at: <%= DateTime.now() - 2280.minutes %> + created_at: <%= DateTime.now() - 38.hours - 50.minutes %> + updated_at: <%= DateTime.now() - 38.hours - 50.minutes %> dawn2: candidate: dawn @@ -33,8 +33,8 @@ dawn2: answer: ["option2", "option-4"] saved: 0 submitted: true - created_at: <%= DateTime.now() - 2282.minutes %> - updated_at: <%= DateTime.now() - 2282.minutes %> + created_at: <%= DateTime.now() - 38.hours - 50.minutes %> + updated_at: <%= DateTime.now() - 38.hours - 50.minutes %> dawn3: candidate: dawn @@ -42,8 +42,8 @@ dawn3: answer: {html: "

I'm a little tealpot

", css: 'h1: {color: teal;}', js: ''} saved: 0 submitted: true - created_at: <%= DateTime.now() - 2284.minutes %> - updated_at: <%= DateTime.now() - 2284.minutes %> + created_at: <%= DateTime.now() - 38.hours - 50.minutes %> + updated_at: <%= DateTime.now() - 38.hours - 50.minutes %> dawn4: candidate: dawn @@ -51,8 +51,8 @@ dawn4: answer: Vestibulum id ligula porta felis euismod semper. Sed posuere consectetur est at lobortis. saved: 0 submitted: true - created_at: <%= DateTime.now() - 2288.minutes %> - updated_at: <%= DateTime.now() - 2288.minutes %> + created_at: <%= DateTime.now() - 38.hours - 50.minutes %> + updated_at: <%= DateTime.now() - 38.hours - 50.minutes %> dawn5: candidate: dawn @@ -60,8 +60,53 @@ dawn5: answer: "option 3" saved: 0 submitted: true - created_at: <%= DateTime.now() - 2292.minutes %> - updated_at: <%= DateTime.now() - 2292.minutes %> + created_at: <%= DateTime.now() - 38.hours - 50.minutes %> + updated_at: <%= DateTime.now() - 38.hours - 50.minutes %> + +dawn6: + candidate: dawn + question: fed6 + answer: Integer posuere erat a ante venenatis dapibus posuere velit aliquet. + saved: 0 + submitted: true + created_at: <%= DateTime.now() - 38.hours - 32.minutes %> + updated_at: <%= DateTime.now() - 38.hours - 12.minutes %> + +dawn7: + candidate: dawn + question: fed7 + answer: {html: '

This means jQuery needs to be available in live-coder!

', css: 'strong: {font-size: 1.6em;} green: {color: green;}', js: '$("strong").addClass("green");'} + saved: 0 + submitted: true + created_at: <%= DateTime.now() - 38.hours - 34.minutes %> + updated_at: <%= DateTime.now() - 38.hours - 14.minutes %> + +dawn8: + candidate: dawn + question: fed8 + answer: option2 + saved: 0 + submitted: true + created_at: <%= DateTime.now() - 38.hours - 38.minutes %> + updated_at: <%= DateTime.now() - 38.hours - 16.minutes %> + +dawn9: + candidate: dawn + question: fed9 + answer: Grunt + saved: 0 + submitted: true + created_at: <%= DateTime.now() - 38.hours - 38.minutes %> + updated_at: <%= DateTime.now() - 38.hours - 18.minutes %> + +dawn10: + candidate: dawn + question: fed10 + answer: + saved: 1 + submitted: true + created_at: <%= DateTime.now() - 38.hours - 40.minutes %> + updated_at: <%= DateTime.now() - 38.hours - 20.minutes %> richard1: candidate: richard diff --git a/test/fixtures/candidates.yml b/test/fixtures/candidates.yml index b29d177..c5c8342 100644 --- a/test/fixtures/candidates.yml +++ b/test/fixtures/candidates.yml @@ -5,6 +5,7 @@ roy: email: roy.cruz@mailinator.com experience: 0-3 recruiter: reviewer + quiz: fed completed: false reminded: false test_hash: NmEjDkOEKY4 @@ -14,6 +15,7 @@ martha: email: martha.watts@mailinator.com experience: 4-6 recruiter: reviewer + quiz: fed completed: false reminded: false test_hash: R67PmfDHGiw @@ -23,6 +25,7 @@ dawn: email: dawn.hopkins@mailinator.com experience: 0-2 recruiter: reviewer + quiz: fed completed: false reminded: true test_hash: OvP0ZqGKwJ0 @@ -32,6 +35,7 @@ richard: email: richard.burns@mailinator.com experience: 15+ recruiter: reviewer + quiz: fed completed: true reminded: false test_hash: 6NjnourLE6Y diff --git a/test/test_helper.rb b/test/test_helper.rb index 6c33b16..5087494 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,6 +1,5 @@ ENV['RAILS_ENV'] ||= 'test' -# require 'single_cov' -# SingleCov.setup :minitest + require File.expand_path('../../config/environment', __FILE__) require 'rails/test_help' require "minitest/autorun" diff --git a/test/workers/quiz_status_test.rb b/test/workers/quiz_status_test.rb new file mode 100644 index 0000000..8dffbe1 --- /dev/null +++ b/test/workers/quiz_status_test.rb @@ -0,0 +1,59 @@ +require 'test_helper' + +class QuizStatusTest < ActiveSupport::TestCase + test "roy has started test" do + roy = candidates :roy + status = QuizStatus.new roy + + assert status.started + end + + test "martha has NOT started test" do + martha = candidates :martha + status = QuizStatus.new martha + + refute status.started + end + + test "dawn is on summary page" do + dawn = candidates :dawn + status = QuizStatus.new dawn + + assert status.on_summary + end + + test "roy is NOT on summary" do + roy = candidates :roy + status = QuizStatus.new roy + + refute status.on_summary + end + + test "roy has NOT submitted" do + roy = candidates :roy + status = QuizStatus.new roy + + refute status.completed + end + + test "richard is complete" do + richard = candidates :richard + status = QuizStatus.new richard + + assert status.completed + end + + test "dawn can NOT submit" do + dawn = candidates :dawn + status = QuizStatus.new dawn + + refute status.can_submit + end + + test "richard can submit" do + richard = candidates :richard + status = QuizStatus.new richard + + assert status.can_submit + end +end