diff --git a/Dockerfile b/Dockerfile index b933c69..cfa101c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,7 +17,8 @@ RUN apt-get update \ && mkdir -p /usr/app \ && ln -s /usr/bin/nodejs /usr/bin/node \ && echo "alias ll='ls -Ahl'" >> /root/.bashrc \ - && echo "alias la='ls -ahl'" >> /root/.bashrc + && echo "alias la='ls -ahl'" >> /root/.bashrc \ + && echo "export HISTCONTROL=ignoredups" >> /root/.bashrc # install current Ruby RUN curl -L --progress https://github.com/postmodern/ruby-install/archive/v0.6.0.tar.gz | tar xz \ diff --git a/README.md b/README.md index 4d6c5f9..82d0c91 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ This application manages quizzes intended to be used as pre-interview skill asse * honor RuboCop * keep tests green * pull --rebase !always `git config --global pull.rebase true` +* place all required dev seed data in fixtures for rails db:fixtures:load # Docker diff --git a/app/models/answer.rb b/app/models/answer.rb new file mode 100644 index 0000000..1d6ebf2 --- /dev/null +++ b/app/models/answer.rb @@ -0,0 +1,6 @@ +class Answer < ApplicationRecord + serialize :answer + + belongs_to :question + belongs_to :candidate +end diff --git a/app/models/candidate.rb b/app/models/candidate.rb new file mode 100644 index 0000000..4c0042a --- /dev/null +++ b/app/models/candidate.rb @@ -0,0 +1,20 @@ +class Candidate < ApplicationRecord + has_many :answers + belongs_to :recruiter, class_name: "User" + + before_create :generate_test_hash + + validates_presence_of :recruiter_id + validates_presence_of :test_hash + validates_uniqueness_of :test_hash + + private + + def generate_test_hash + loop do + self[:test_hash] = SecureRandom.urlsafe_base64(8) + + break unless Candidate.exists?(test_hash: self[:test_hash]) + end + end +end diff --git a/app/models/question.rb b/app/models/question.rb new file mode 100644 index 0000000..3abd437 --- /dev/null +++ b/app/models/question.rb @@ -0,0 +1,6 @@ +class Question < ApplicationRecord + serialize :input_options, Array + + has_many :answers + belongs_to :quiz +end diff --git a/app/models/quiz.rb b/app/models/quiz.rb new file mode 100644 index 0000000..6813001 --- /dev/null +++ b/app/models/quiz.rb @@ -0,0 +1,3 @@ +class Quiz < ApplicationRecord + has_many :questions +end diff --git a/app/models/user.rb b/app/models/user.rb new file mode 100644 index 0000000..e1b1ee7 --- /dev/null +++ b/app/models/user.rb @@ -0,0 +1,4 @@ +class User < ApplicationRecord + has_secure_password + has_many :candidates, foreign_key: "recruiter_id" +end diff --git a/db/migrate/20160726193255_db_init.rb b/db/migrate/20160726193255_db_init.rb new file mode 100644 index 0000000..6351352 --- /dev/null +++ b/db/migrate/20160726193255_db_init.rb @@ -0,0 +1,63 @@ +class DbInit < ActiveRecord::Migration[5.0] + def change + create_table :candidates do |t| + t.string :test_hash, null: false + t.string :name + t.string :email + t.string :experience + t.integer :recruiter_id + t.boolean :completed, null: false, default: false + t.boolean :reminded, null: false, default: false + + t.timestamps + end + add_index :candidates, :test_hash, unique: true + add_index :candidates, :recruiter_id + + create_table :questions do |t| + t.integer :quiz_id + t.text :question + t.string :category + t.string :input_type + t.text :input_options + t.string :sort, null: false, default: 0 + t.boolean :active, null: false, default: true + + t.timestamps + end + add_index :questions, :quiz_id + add_index :questions, :sort + add_index :questions, :active + + create_table :answers do |t| + t.integer :candidate_id + t.integer :question_id + t.text :answer + t.integer :saved, null: false, default: 0 + t.boolean :submitted, null: false, default: false + + t.timestamps + end + add_index :answers, :candidate_id + add_index :answers, :question_id + add_index :answers, :submitted + + create_table :quizzes do |t| + t.string :unit + t.string :dept + + t.timestamps + end + + create_table :users do |t| + t.string :name, null: false + t.string :email, null: false + t.string :password_digest + t.string :role, null: false + t.boolean :active, null: false, default: true + + t.timestamps + end + add_index :users, :email, unique: true + end +end diff --git a/db/schema.rb b/db/schema.rb index 52ab025..0feb124 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,6 +10,65 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 0) do +ActiveRecord::Schema.define(version: 20160726193255) do + + create_table "answers", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t| + t.integer "candidate_id" + t.integer "question_id" + t.text "answer", limit: 65535 + t.integer "saved" + t.boolean "submitted" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["candidate_id"], name: "index_answers_on_candidate_id", using: :btree + t.index ["question_id"], name: "index_answers_on_question_id", using: :btree + t.index ["submitted"], name: "index_answers_on_submitted", using: :btree + end + + create_table "candidates", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t| + t.string "test_hash" + t.string "name" + t.string "email" + t.string "experience" + t.integer "recruiter_id" + t.boolean "completed" + t.boolean "reminded" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + 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 + + create_table "questions", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t| + t.integer "quiz_id" + t.text "question", limit: 65535 + t.string "category" + t.string "input_type" + t.text "input_options", limit: 65535 + t.string "sort" + t.boolean "active" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["active"], name: "index_questions_on_active", using: :btree + t.index ["quiz_id"], name: "index_questions_on_quiz_id", using: :btree + t.index ["sort"], name: "index_questions_on_sort", using: :btree + end + + create_table "quizzes", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t| + t.string "unit" + t.string "dept" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "users", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t| + t.string "name" + t.string "email" + t.string "password_digest" + t.string "role" + t.boolean "active" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end end diff --git a/db/seeds.rb b/db/seeds.rb index 1beea2a..e9590a6 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -5,3 +5,12 @@ # # movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }]) # Character.create(name: 'Luke', movie: movies.first) + +User.create( + name: 'admin', + email: 'pdr.admin@mailinator.com', + password_digest: BCrypt::Password.create("this is the admin password"), + role: 'admin' +) + +Quiz.create(unit: 'FED', dept: 'PDR') diff --git a/spec_fixtures/quizzes.yml b/spec_fixtures/quizzes.yml deleted file mode 100644 index e3c4620..0000000 --- a/spec_fixtures/quizzes.yml +++ /dev/null @@ -1,3 +0,0 @@ -fed: - unit: PDR - dept: FED diff --git a/spec_fixtures/users.yml b/spec_fixtures/users.yml deleted file mode 100644 index 29bf65f..0000000 --- a/spec_fixtures/users.yml +++ /dev/null @@ -1,15 +0,0 @@ -recruiter: - name: Sam Recruiter - email: pdr.recruiter@mailinator.com - role: recruiter - -reviewer: - name: Tina Reviewer - email: fed.reviewer@mailinator.com - role: reviewer - -admin: - name: Alan Admin - email: alan.admin@mailinator.com - role: admin - diff --git a/spec_fixtures/answers.yml b/test/fixtures/answers.yml similarity index 97% rename from spec_fixtures/answers.yml rename to test/fixtures/answers.yml index 42bbec0..c03a940 100644 --- a/spec_fixtures/answers.yml +++ b/test/fixtures/answers.yml @@ -1,3 +1,5 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + roy1: candidate: roy question: fed1 diff --git a/spec_fixtures/candidates.yml b/test/fixtures/candidates.yml similarity index 74% rename from spec_fixtures/candidates.yml rename to test/fixtures/candidates.yml index 9e53d57..b29d177 100644 --- a/spec_fixtures/candidates.yml +++ b/test/fixtures/candidates.yml @@ -1,36 +1,37 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + roy: - # test_hash: name: Roy Cruz email: roy.cruz@mailinator.com experience: 0-3 recruiter: reviewer completed: false reminded: false + test_hash: NmEjDkOEKY4 martha: - # test_hash: name: Martha Watts email: martha.watts@mailinator.com experience: 4-6 recruiter: reviewer completed: false reminded: false + test_hash: R67PmfDHGiw dawn: - # test_hash: name: Dawn Hopkins email: dawn.hopkins@mailinator.com experience: 0-2 recruiter: reviewer completed: false reminded: true + test_hash: OvP0ZqGKwJ0 richard: - # test_hash: name: Richard Burns email: richard.burns@mailinator.com experience: 15+ recruiter: reviewer completed: true reminded: false - + test_hash: 6NjnourLE6Y diff --git a/spec_fixtures/questions.yml b/test/fixtures/questions.yml similarity index 90% rename from spec_fixtures/questions.yml rename to test/fixtures/questions.yml index c90cc61..8ecfbc1 100644 --- a/spec_fixtures/questions.yml +++ b/test/fixtures/questions.yml @@ -1,4 +1,7 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + fed1: + quiz: fed question: Select an example of media query from below. category: CSS input_type: radio @@ -7,6 +10,7 @@ fed1: active: true fed2: + quiz: fed question: What are some ways you can improve a site's performance (load time)? category: Performance input_type: checkbox @@ -15,6 +19,7 @@ fed2: active: true fed3: + quiz: fed question: How would you create a widget that would fit in a 250px wide area as well as a 400px wide area? category: CSS input_type: live-coder @@ -23,6 +28,7 @@ fed3: active: true fed4: + quiz: fed question: Briefly explain the principles of Progressive Enhancement. category: Performance input_type: text @@ -31,6 +37,7 @@ fed4: active: true fed5: + quiz: fed question: Which is your favorite grid system? category: CSS input_type: radio @@ -39,6 +46,7 @@ fed5: active: true fed6: + quiz: fed question: List one advantage of using IDs over classes. List one disadvantage. category: CSS input_type: text @@ -47,6 +55,7 @@ fed6: active: true fed7: + quiz: fed question: Provide a code example to manipulate the DOM using jQuery/JavaScript to change the classname of a div 'classB' to 'classC', only if the div 'classA' exists in the page? category: Javascript input_type: live-coder @@ -55,6 +64,7 @@ fed7: active: true fed8: + quiz: fed question: Select the HTML from below that would create an input field which restricts the number of characters inside it to 10. category: HTML input_type: radio @@ -63,6 +73,7 @@ fed8: active: true fed9: + quiz: fed question: Grunt or Gulp? category: Javascript input_type: radio @@ -71,6 +82,7 @@ fed9: active: true fed10: + quiz: fed question: StarWars or Star Trek? category: Performance input_type: checkbox diff --git a/test/fixtures/quizzes.yml b/test/fixtures/quizzes.yml new file mode 100644 index 0000000..87dc32d --- /dev/null +++ b/test/fixtures/quizzes.yml @@ -0,0 +1,5 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +fed: + unit: PDR + dept: FED diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml new file mode 100644 index 0000000..54ff4ec --- /dev/null +++ b/test/fixtures/users.yml @@ -0,0 +1,20 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +recruiter: + name: Sam Recruiter + email: pdr.recruiter@mailinator.com + password_digest: <%= BCrypt::Password.create("password", cost: 4) %> + role: recruiter + +reviewer: + name: Tina Reviewer + email: fed.reviewer@mailinator.com + password_digest: <%= BCrypt::Password.create("password", cost: 4) %> + role: reviewer + +admin: + name: Alan Admin + email: alan.admin@mailinator.com + password_digest: <%= BCrypt::Password.create("password", cost: 4) %> + role: admin + diff --git a/test/models/answer_test.rb b/test/models/answer_test.rb new file mode 100644 index 0000000..c0af5c3 --- /dev/null +++ b/test/models/answer_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class AnswerTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/candidate_test.rb b/test/models/candidate_test.rb new file mode 100644 index 0000000..85798b8 --- /dev/null +++ b/test/models/candidate_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class CandidateTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/question_test.rb b/test/models/question_test.rb new file mode 100644 index 0000000..88f6ea7 --- /dev/null +++ b/test/models/question_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class QuestionTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/quiz_test.rb b/test/models/quiz_test.rb new file mode 100644 index 0000000..f0c73ff --- /dev/null +++ b/test/models/quiz_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class QuizTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/user_test.rb b/test/models/user_test.rb new file mode 100644 index 0000000..82f61e0 --- /dev/null +++ b/test/models/user_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class UserTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end