From 9c2b53aa79fca87b8e1a2fa258d8d34ec293cabd Mon Sep 17 00:00:00 2001 From: Mark Moser Date: Fri, 10 Feb 2017 12:03:50 -0600 Subject: [PATCH 01/10] init comments --- app/models/candidate.rb | 1 + app/models/quiz_comment.rb | 7 ++ app/models/user.rb | 1 + .../20170210165110_create_quiz_comments.rb | 12 ++++ db/schema.rb | 10 ++- test/fixtures/quiz_comments.yml | 72 +++++++++++++++++++ test/models/quiz_comment_test.rb | 27 +++++++ test/models/reviewer_vote_test.rb | 2 +- 8 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 app/models/quiz_comment.rb create mode 100644 db/migrate/20170210165110_create_quiz_comments.rb create mode 100644 test/fixtures/quiz_comments.yml create mode 100644 test/models/quiz_comment_test.rb diff --git a/app/models/candidate.rb b/app/models/candidate.rb index 7d5b287..af91ff7 100644 --- a/app/models/candidate.rb +++ b/app/models/candidate.rb @@ -6,6 +6,7 @@ class Candidate < ApplicationRecord belongs_to :recruiter, class_name: "User" has_many :votes, class_name: "ReviewerVote" has_many :reviewers, through: :quiz + has_many :quiz_comments, foreign_key: :test_hash, primary_key: :test_hash serialize :email, CryptSerializer diff --git a/app/models/quiz_comment.rb b/app/models/quiz_comment.rb new file mode 100644 index 0000000..8819997 --- /dev/null +++ b/app/models/quiz_comment.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true +class QuizComment < ApplicationRecord + belongs_to :user + belongs_to :candidate, foreign_key: :test_hash, primary_key: :test_hash + + validates :message, presence: true +end diff --git a/app/models/user.rb b/app/models/user.rb index 773cb1f..6179a94 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -5,6 +5,7 @@ class User < ApplicationRecord has_many :reviewer_to_quizzes has_many :quizzes, through: :reviewer_to_quizzes has_many :votes, class_name: 'ReviewerVote' + has_many :quiz_comments has_many :reviewees, through: :quizzes, source: :candidates diff --git a/db/migrate/20170210165110_create_quiz_comments.rb b/db/migrate/20170210165110_create_quiz_comments.rb new file mode 100644 index 0000000..caae162 --- /dev/null +++ b/db/migrate/20170210165110_create_quiz_comments.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true +class CreateQuizComments < ActiveRecord::Migration[5.0] + def change + create_table :quiz_comments do |t| + t.integer :user_id + t.string :test_hash + t.text :message + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 5e5c4cc..ae6704d 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: 20170208212526) do +ActiveRecord::Schema.define(version: 20170210165110) do create_table "answers", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t| t.integer "candidate_id" @@ -60,6 +60,14 @@ ActiveRecord::Schema.define(version: 20170208212526) do t.index ["sort"], name: "index_questions_on_sort", using: :btree end + create_table "quiz_comments", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t| + t.integer "user_id" + t.string "test_hash" + t.text "message", limit: 65535 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + create_table "quizzes", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t| t.string "unit" t.string "dept" diff --git a/test/fixtures/quiz_comments.yml b/test/fixtures/quiz_comments.yml new file mode 100644 index 0000000..68a7938 --- /dev/null +++ b/test/fixtures/quiz_comments.yml @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +com1: + test_hash: BkSkpapJnkz2N #wade + user: reviewer + message: Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Etiam porta sem malesuada magna mollis euismod. Aenean lacinia bibendum nulla sed consectetur. Maecenas faucibus mollis interdum. + +com2: + test_hash: BkSkpapJnkz2N #wade + user: reviewer + message: Donec sed odio dui. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Curabitur blandit tempus porttitor. Nullam quis risus eget urna mollis ornare vel eu leo. Nullam id dolor id nibh ultricies vehicula ut id elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. + +com3: + test_hash: BkSkpapJnkz2N #wade + user: reviewer2 + message: Cras mattis consectetur purus sit amet fermentum. Donec sed odio dui. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. + +com4: + test_hash: iC5FdWJxcyySBmpOpU #jorge + user: manager + message: Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed posuere consectetur est at lobortis. + +com5: + test_hash: egPomAuVDeCEp #henry + user: manager + message: no. + +com6: + test_hash: egPomAuVDeCEp #henry + user: reviewer2 + message: fine. + +com7: + test_hash: iC5FdWJxcyySBmpOpU #jorge + user: reviewer + message: Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. + +com8: + test_hash: egPomAuVDeCEp #henry + user: manager + message: no. + +com9: + test_hash: rLSoizA3ATMNSCx #elsie + user: reviewer + message: Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Donec ullamcorper nulla non metus auctor fringilla. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Etiam porta sem malesuada magna mollis euismod. Vestibulum id ligula porta felis euismod semper. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Maecenas faucibus mollis interdum. + +com10: + test_hash: rLSoizA3ATMNSCx #elsie + user: reviewer2 + message: Ornare Tellus Nullam Mattis + +com11: + test_hash: rLSoizA3ATMNSCx #elsie + user: reviewer2 + message: Nibh Ultricies Purus + +com12: + test_hash: rLSoizA3ATMNSCx #elsie + user: reviewer + message: Donec id elit non mi porta gravida at eget metus. + +com13: + test_hash: rLSoizA3ATMNSCx #elsie + user: manager + message: Donec id elit non mi porta gravida at eget metus. + +com14: + test_hash: rLSoizA3ATMNSCx #elsie + user: reviewer2 + message: Ultricies Vulputate Bibendum Parturient + diff --git a/test/models/quiz_comment_test.rb b/test/models/quiz_comment_test.rb new file mode 100644 index 0000000..90e3ec8 --- /dev/null +++ b/test/models/quiz_comment_test.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true +require 'test_helper' + +class QuizCommentTest < ActiveSupport::TestCase + test "the truth" do + assert QuizComment + end + + test "user to comments association" do + manager = users(:manager) + + assert_equal 4, manager.quiz_comments.size + end + + test "candidate to comments association" do + candidate = candidates(:elsie) + + assert_equal 6, candidate.quiz_comments.size + end + + test 'comment to user' do + comment = quiz_comments(:com1) + + assert_match 'Wade', comment.candidate.name + assert_match 'Tina', comment.user.name + end +end diff --git a/test/models/reviewer_vote_test.rb b/test/models/reviewer_vote_test.rb index 5f73233..d5a9ef3 100644 --- a/test/models/reviewer_vote_test.rb +++ b/test/models/reviewer_vote_test.rb @@ -3,7 +3,7 @@ require 'test_helper' class ReviewerVoteTest < ActiveSupport::TestCase test "the truth" do - assert ReviewerVoteTest + assert ReviewerVote end test "richard has 3 votes" do From 17d62131c91616868c4f9342353c1dc86d9251a7 Mon Sep 17 00:00:00 2001 From: Mark Moser Date: Fri, 10 Feb 2017 15:46:43 -0600 Subject: [PATCH 02/10] scratched in view partials --- .../stylesheets/molecules/_admin_review.scss | 25 +++++- app/controllers/admin/result_controller.rb | 2 + app/views/admin/result/_comment.html.erb | 2 + app/views/admin/result/_comment_form.html.erb | 10 +++ app/views/admin/result/view.html.erb | 76 ++++++++++--------- 5 files changed, 80 insertions(+), 35 deletions(-) create mode 100644 app/views/admin/result/_comment.html.erb create mode 100644 app/views/admin/result/_comment_form.html.erb diff --git a/app/assets/stylesheets/molecules/_admin_review.scss b/app/assets/stylesheets/molecules/_admin_review.scss index 586367d..8cbab59 100644 --- a/app/assets/stylesheets/molecules/_admin_review.scss +++ b/app/assets/stylesheets/molecules/_admin_review.scss @@ -1,12 +1,14 @@ .admin-review { counter-reset: question; + float: left; + width: 66%; form { margin-left: 2.3em; position: relative; &::before { - content: counter(question) ") "; + content: counter(question) ') '; counter-increment: question; font-size: 1.25em; left: -1.8em; @@ -17,6 +19,27 @@ } +.review-comments { + float: right; + padding-left: 30px; + width: 33%; + + .comment-message { + margin-right: 5px; + } + + .comment-author { + font-size: 0.85em; + font-weight: 700; + margin-bottom: 30px; + text-align: right; + + &:before { + content: '- '; + } + } +} + .review_meta { @media screen and (min-width: 768px) { diff --git a/app/controllers/admin/result_controller.rb b/app/controllers/admin/result_controller.rb index 867c922..67be27a 100644 --- a/app/controllers/admin/result_controller.rb +++ b/app/controllers/admin/result_controller.rb @@ -19,6 +19,8 @@ module Admin @candidate = Candidate.find_by(test_hash: params[:test_hash]) @quiz = @candidate.my_quiz @status = QuizStatus.new(@candidate) + @comments = QuizComment.includes(:user).where(test_hash: @candidate.test_hash).order(:created_at) + @comment = QuizComment.new end end end diff --git a/app/views/admin/result/_comment.html.erb b/app/views/admin/result/_comment.html.erb new file mode 100644 index 0000000..b260eca --- /dev/null +++ b/app/views/admin/result/_comment.html.erb @@ -0,0 +1,2 @@ +
<%= comment.message %>
+
<%= comment.user.name %>
diff --git a/app/views/admin/result/_comment_form.html.erb b/app/views/admin/result/_comment_form.html.erb new file mode 100644 index 0000000..8867b8e --- /dev/null +++ b/app/views/admin/result/_comment_form.html.erb @@ -0,0 +1,10 @@ +<%= render partial: 'shared/form_model_errors', locals: { obj: @comment } %> + +<%= form_for @comment, url: "#", method: :post do |form| %> +
+ <%= form.label :message, "Comment" %> + <%= form.text_area :message %> +
+ + <%= submit_tag "Save Comment" %> +<% end %> diff --git a/app/views/admin/result/view.html.erb b/app/views/admin/result/view.html.erb index d0452ca..3b1abaa 100644 --- a/app/views/admin/result/view.html.erb +++ b/app/views/admin/result/view.html.erb @@ -2,42 +2,50 @@ content_for :title, "Quiz Review - Skills Assessment Admin" %> -
-

Quiz Review

+
+
+

Quiz Review

-
-
- Test ID: <%= @candidate.test_hash %>
- Years of Experience: <%= @candidate.experience %>
- Client/Project: <%= @candidate.project %>
- Recruiter Email: <%= mail_to @candidate.recruiter.name, @candidate.recruiter.email %>
+
+
+ Test ID: <%= @candidate.test_hash %>
+ Years of Experience: <%= @candidate.experience %>
+ Client/Project: <%= @candidate.project %>
+ Recruiter Email: <%= mail_to @candidate.recruiter.name, @candidate.recruiter.email %>
+
+ +
<%= render partial: 'voting' %>
-
<%= render partial: 'voting' %>
+ <% @quiz.each do |question| %> + <%= form_for(:answer, url: '#never-post', html:{id: 'summary-form'}) do |form| %> +
+
+
+

<%= question.question %>

+
+
+ +
+ <% if question.attachment.present? %> + <%= image_tag question.attachment %> + <% end %> +
+ <%= render partial: "quiz/#{question.input_type}", locals: {question: question, answer: question.answer, form: form} %> +
+
+
+ <% end #form_tag %> + <% end #questions loop %> + + <%= link_to(admin_results_path, { class: 'secondary-btn' }) do %> + + <% end %>
- <% @quiz.each do |question| %> - <%= form_for(:answer, url: '#never-post', html:{id: 'summary-form'}) do |form| %> -
-
-
-

<%= question.question %>

-
-
- -
- <% if question.attachment.present? %> - <%= image_tag question.attachment %> - <% end %> -
- <%= render partial: "quiz/#{question.input_type}", locals: {question: question, answer: question.answer, form: form} %> -
-
-
- <% end #form_tag %> - <% end #questions loop %> - - <%= link_to(admin_results_path, { class: 'secondary-btn' }) do %> - - <% end %> -
+
+

Comments

+ <%= render partial: 'comment', collection: @comments %> +
<%= render partial: 'comment_form' %>
+
+ From 43c77677f600dadca3010ea731cd167d7772ff87 Mon Sep 17 00:00:00 2001 From: Mark Moser Date: Mon, 13 Feb 2017 15:03:08 -0600 Subject: [PATCH 03/10] rubocop autofix! --- Guardfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Guardfile b/Guardfile index 1027353..305fd8e 100644 --- a/Guardfile +++ b/Guardfile @@ -79,7 +79,7 @@ guard :shell, all_on_start: true do end end -guard :rubocop, cli: %w(-D -S) do +guard :rubocop, cli: %w(-D -S -a) do watch(/.rubocop.yml/) watch(/.+\.rb$/) watch(/Rakefile/) From d3a28707478d44f94134d5dface3ff9f04500a7d Mon Sep 17 00:00:00 2001 From: Mark Moser Date: Mon, 13 Feb 2017 15:04:47 -0600 Subject: [PATCH 04/10] a simple comment policy --- app/policies/quiz_comment_policy.rb | 21 ++++++++++++++++++ test/policies/quiz_comment_policy_test.rb | 27 +++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 app/policies/quiz_comment_policy.rb create mode 100644 test/policies/quiz_comment_policy_test.rb diff --git a/app/policies/quiz_comment_policy.rb b/app/policies/quiz_comment_policy.rb new file mode 100644 index 0000000..49b850e --- /dev/null +++ b/app/policies/quiz_comment_policy.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true +class QuizCommentPolicy < ApplicationPolicy + # Quiz Comment Policy + # + # Anyone with access to the results can comment + # Only Comment owner can edit + + def create? + user.acts_as_reviewer? + end + + def update? + user.acts_as_reviewer? && user.id == record.user_id + end + + class Scope < Scope + def resolve + true + end + end +end diff --git a/test/policies/quiz_comment_policy_test.rb b/test/policies/quiz_comment_policy_test.rb new file mode 100644 index 0000000..518681f --- /dev/null +++ b/test/policies/quiz_comment_policy_test.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true +require 'test_helper' + +class QuizCommentPolicyTest < PolicyAssertions::Test + test 'should require current_user' do + assert_raise Pundit::NotAuthorizedError do + QuizCommentPolicy.new(nil, User.first).create? + end + end + + def test_create + assert_permit users(:admin), QuizComment + assert_permit users(:manager), QuizComment + assert_permit users(:reviewer), QuizComment + + refute_permit users(:recruiter), QuizComment + end + + def test_update + assert_permit users(:reviewer2), quiz_comments(:com6) + + refute_permit users(:reviewer), quiz_comments(:com6) + refute_permit users(:manager), quiz_comments(:com6) + refute_permit users(:admin), quiz_comments(:com6) + refute_permit users(:recruiter), quiz_comments(:com6) + end +end From 567b4a409de0d076c656400b5a7e04ecc00d45db Mon Sep 17 00:00:00 2001 From: Mark Moser Date: Mon, 13 Feb 2017 15:52:01 -0600 Subject: [PATCH 05/10] Don't auto corect debug statements --- .rubocop.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.rubocop.yml b/.rubocop.yml index ddbc53a..2f5dff1 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -5,6 +5,9 @@ AllCops: - bin/**/* - vendor/assets/**/* +Lint/Debugger: + AutoCorrect: False + Style/AndOr: Enabled: false From da5dc4bd94a44a53616e7aeae2e98785c617519e Mon Sep 17 00:00:00 2001 From: Mark Moser Date: Mon, 13 Feb 2017 15:54:57 -0600 Subject: [PATCH 06/10] comment creation --- app/controllers/admin/comment_controller.rb | 26 +++++++++++++++++++ app/views/admin/result/_comment_form.html.erb | 2 +- app/views/admin/result/view.html.erb | 4 +-- config/routes.rb | 2 ++ .../admin/comment_controller_test.rb | 19 ++++++++++++++ 5 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 app/controllers/admin/comment_controller.rb create mode 100644 test/controllers/admin/comment_controller_test.rb diff --git a/app/controllers/admin/comment_controller.rb b/app/controllers/admin/comment_controller.rb new file mode 100644 index 0000000..d02ee24 --- /dev/null +++ b/app/controllers/admin/comment_controller.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true +module Admin + class CommentController < AdminController + before_action { authorize QuizComment } + + def create + comment = QuizComment.create( + comment_params.merge(user_id: current_user.id, test_hash: params[:test_hash]) + ) + + if comment.persisted? + redirect_to admin_result_path(params[:test_hash]), + flash: { success: "Sucessfully created comment" } + else + redirect_to admin_result_path(params[:test_hash]), + flash: { error: "Failed to save comment" } + end + end + + private + + def comment_params + params.require(:quiz_comment).permit(:message, :id) + end + end +end diff --git a/app/views/admin/result/_comment_form.html.erb b/app/views/admin/result/_comment_form.html.erb index 8867b8e..d4c1b55 100644 --- a/app/views/admin/result/_comment_form.html.erb +++ b/app/views/admin/result/_comment_form.html.erb @@ -1,6 +1,6 @@ <%= render partial: 'shared/form_model_errors', locals: { obj: @comment } %> -<%= form_for @comment, url: "#", method: :post do |form| %> +<%= form_for @comment, url: admin_create_comment_path(test_hash), method: :post do |form| %>
<%= form.label :message, "Comment" %> <%= form.text_area :message %> diff --git a/app/views/admin/result/view.html.erb b/app/views/admin/result/view.html.erb index 3b1abaa..b07c69a 100644 --- a/app/views/admin/result/view.html.erb +++ b/app/views/admin/result/view.html.erb @@ -45,7 +45,7 @@

Comments

- <%= render partial: 'comment', collection: @comments %> -
<%= render partial: 'comment_form' %>
+ <%= render partial: 'comment', collection: @comments, locals: { test_hash: @candidate.test_hash } %> +
<%= render partial: 'comment_form', locals: { test_hash: @candidate.test_hash } %>
diff --git a/config/routes.rb b/config/routes.rb index e7a7558..edff83f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -52,6 +52,8 @@ Rails.application.routes.draw do get "/admin/results", to: "admin/result#index", as: :admin_results get "/admin/result/:test_hash", to: "admin/result#view", as: :admin_result + post "/admin/comment/:test_hash", to: "admin/comment#create", as: :admin_create_comment + get "admin/vote/:test_hash/up", to: "admin/vote#up", as: :admin_up_vote, defaults: { format: 'json' } get "admin/vote/:test_hash/down", to: "admin/vote#down", as: :admin_down_vote, defaults: { format: 'json' } get "admin/vote/:test_hash/approve", to: "admin/vote#approve", as: :admin_approve_vote, defaults: { format: 'json' } diff --git a/test/controllers/admin/comment_controller_test.rb b/test/controllers/admin/comment_controller_test.rb new file mode 100644 index 0000000..d900269 --- /dev/null +++ b/test/controllers/admin/comment_controller_test.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true +require 'test_helper' + +module Admin + class CommentControllerTest < ActionDispatch::IntegrationTest + test "should post create" do + auth_reviewer + candidate = candidates(:stacy) + + assert_difference("QuizComment.count") do + post admin_create_comment_url(test_hash: candidate.test_hash), params: { quiz_comment: { + message: 'this is a test comment' + } } + end + assert_redirected_to admin_result_url(test_hash: candidate.test_hash) + assert flash[:success] + end + end +end From 39ba1a8369fbfef8d4c72dff8b8a508279b98fe5 Mon Sep 17 00:00:00 2001 From: Mark Moser Date: Mon, 13 Feb 2017 16:12:59 -0600 Subject: [PATCH 07/10] comment updates --- app/controllers/admin/comment_controller.rb | 29 +++++++++++++------ app/views/admin/result/_comment_form.html.erb | 1 + config/routes.rb | 1 + .../admin/comment_controller_test.rb | 17 +++++++++-- 4 files changed, 36 insertions(+), 12 deletions(-) diff --git a/app/controllers/admin/comment_controller.rb b/app/controllers/admin/comment_controller.rb index d02ee24..cef5cff 100644 --- a/app/controllers/admin/comment_controller.rb +++ b/app/controllers/admin/comment_controller.rb @@ -1,26 +1,37 @@ # frozen_string_literal: true module Admin class CommentController < AdminController - before_action { authorize QuizComment } + def update + comment = QuizComment.find_by(id: params[:id], test_hash: params[:test_hash]) + authorize comment + + comment.update(comment_params) + flash_message = if comment.save + { success: "Sucessfully updated comment" } + else + { error: "Failed to update comment" } + end + redirect_to admin_result_path(params[:test_hash]), flash: flash_message + end def create + authorize QuizComment comment = QuizComment.create( comment_params.merge(user_id: current_user.id, test_hash: params[:test_hash]) ) - if comment.persisted? - redirect_to admin_result_path(params[:test_hash]), - flash: { success: "Sucessfully created comment" } - else - redirect_to admin_result_path(params[:test_hash]), - flash: { error: "Failed to save comment" } - end + flash_message = if comment.persisted? + { success: "Sucessfully created comment" } + else + { error: "Failed to save comment" } + end + redirect_to admin_result_path(params[:test_hash]), flash: flash_message end private def comment_params - params.require(:quiz_comment).permit(:message, :id) + params.require(:quiz_comment).permit(:message) end end end diff --git a/app/views/admin/result/_comment_form.html.erb b/app/views/admin/result/_comment_form.html.erb index d4c1b55..c2ab89c 100644 --- a/app/views/admin/result/_comment_form.html.erb +++ b/app/views/admin/result/_comment_form.html.erb @@ -1,5 +1,6 @@ <%= render partial: 'shared/form_model_errors', locals: { obj: @comment } %> +<% # admin_update_comment_path # admin_create_comment_path %> <%= form_for @comment, url: admin_create_comment_path(test_hash), method: :post do |form| %>
<%= form.label :message, "Comment" %> diff --git a/config/routes.rb b/config/routes.rb index edff83f..c806362 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -52,6 +52,7 @@ Rails.application.routes.draw do get "/admin/results", to: "admin/result#index", as: :admin_results get "/admin/result/:test_hash", to: "admin/result#view", as: :admin_result + post "/admin/comment/:test_hash/:id", to: "admin/comment#update", as: :admin_update_comment post "/admin/comment/:test_hash", to: "admin/comment#create", as: :admin_create_comment get "admin/vote/:test_hash/up", to: "admin/vote#up", as: :admin_up_vote, defaults: { format: 'json' } diff --git a/test/controllers/admin/comment_controller_test.rb b/test/controllers/admin/comment_controller_test.rb index d900269..d864127 100644 --- a/test/controllers/admin/comment_controller_test.rb +++ b/test/controllers/admin/comment_controller_test.rb @@ -3,15 +3,26 @@ require 'test_helper' module Admin class CommentControllerTest < ActionDispatch::IntegrationTest + test "should post update" do + auth_manager + comment = quiz_comments(:com5) + post admin_update_comment_url(test_hash: comment.test_hash, id: comment.id), + params: { quiz_comment: { message: 'updated comment' } } + + assert_redirected_to admin_result_url(test_hash: comment.test_hash) + assert flash[:success] + refute_equal comment.message, QuizComment.find_by(id: comment.id).message + end + test "should post create" do auth_reviewer candidate = candidates(:stacy) assert_difference("QuizComment.count") do - post admin_create_comment_url(test_hash: candidate.test_hash), params: { quiz_comment: { - message: 'this is a test comment' - } } + post admin_create_comment_url(test_hash: candidate.test_hash), + params: { quiz_comment: { message: 'this is a test comment' } } end + assert_redirected_to admin_result_url(test_hash: candidate.test_hash) assert flash[:success] end From 906b62247bc2d52e27ae0d5d24d3584579ac5b76 Mon Sep 17 00:00:00 2001 From: Mark Moser Date: Mon, 13 Feb 2017 18:08:51 -0600 Subject: [PATCH 08/10] comment updates --- .sass-lint.yml | 28 +++++++++++++++ .../stylesheets/molecules/_admin_review.scss | 34 ++++++++++++++++++- app/models/quiz_comment.rb | 4 +++ app/views/admin/result/_comment.html.erb | 21 +++++++++++- app/views/admin/result/_comment_form.html.erb | 30 +++++++++++----- app/views/admin/result/view.html.erb | 4 ++- 6 files changed, 110 insertions(+), 11 deletions(-) create mode 100644 .sass-lint.yml diff --git a/.sass-lint.yml b/.sass-lint.yml new file mode 100644 index 0000000..84ba9b0 --- /dev/null +++ b/.sass-lint.yml @@ -0,0 +1,28 @@ +# https://github.com/sasstools/sass-lint/tree/master/docs/rules +files: + include: app/assets/stylesheets/**/*.scss + +options: + formatter: stylish + merge-default-rules: true + +rules: + class-name-format: 0 + id-name-format: 0 + leading-zero: + - 1 + - include: true + no-duplicate-properties: + - 1 + - + exclude: + - src # for @font mixins + no-qualifying-elements: + - 1 + - allow-element-with-attribute: true # input[type='email'] but not div.class-name + quotes: 0 + no-vendor-prefixes: + - + excluded-identifiers: + - -moz-osx-font-smoothing + - -webkit-font-smoothing diff --git a/app/assets/stylesheets/molecules/_admin_review.scss b/app/assets/stylesheets/molecules/_admin_review.scss index 8cbab59..9077423 100644 --- a/app/assets/stylesheets/molecules/_admin_review.scss +++ b/app/assets/stylesheets/molecules/_admin_review.scss @@ -34,10 +34,42 @@ margin-bottom: 30px; text-align: right; - &:before { + &::before { content: '- '; } } + + .comment-edit-stamp { + color: rgba($gray-dark, 0.65); + font-size: 0.75em; + text-align: right; + } + + .comment-edit-btn { + cursor: pointer; + display: inline-block; + font-size: 0.85em; + font-weight: bold; + padding: 2px 5px; + + &:hover { + background-color: $gray-base; + color: $gray-lighter; + } + } + + .comment-edit-form { + display: none; + margin: 30px 0; + padding: 10px 0; + + } + + [type="checkbox"] { + &:checked + .comment-edit-form { + display: block; + } + } } .review_meta { diff --git a/app/models/quiz_comment.rb b/app/models/quiz_comment.rb index 8819997..a918447 100644 --- a/app/models/quiz_comment.rb +++ b/app/models/quiz_comment.rb @@ -4,4 +4,8 @@ class QuizComment < ApplicationRecord belongs_to :candidate, foreign_key: :test_hash, primary_key: :test_hash validates :message, presence: true + + def edits? + updated_at > (created_at + 5.seconds) + end end diff --git a/app/views/admin/result/_comment.html.erb b/app/views/admin/result/_comment.html.erb index b260eca..d47d8be 100644 --- a/app/views/admin/result/_comment.html.erb +++ b/app/views/admin/result/_comment.html.erb @@ -1,2 +1,21 @@ -
<%= comment.message %>
+
+ <%= comment.message %> + + <% if policy(comment).update? %> + + <% end %> + + <% if comment.edits? %> +
Updated <%= time_ago_in_words(comment.updated_at) %> ago
+ <% end %> +
+
<%= comment.user.name %>
+ + +<% if policy(comment).update? %> + +
+ <%= render partial: 'comment_form', locals: {comment: comment, test_hash: comment.test_hash } %> +
+<% end %> diff --git a/app/views/admin/result/_comment_form.html.erb b/app/views/admin/result/_comment_form.html.erb index c2ab89c..701cb7a 100644 --- a/app/views/admin/result/_comment_form.html.erb +++ b/app/views/admin/result/_comment_form.html.erb @@ -1,11 +1,25 @@ -<%= render partial: 'shared/form_model_errors', locals: { obj: @comment } %> +<%= render partial: 'shared/form_model_errors', locals: { obj: comment } %> -<% # admin_update_comment_path # admin_create_comment_path %> -<%= form_for @comment, url: admin_create_comment_path(test_hash), method: :post do |form| %> -
- <%= form.label :message, "Comment" %> - <%= form.text_area :message %> -
+<% if comment.id.nil? %> + + <%= form_for comment, url: admin_create_comment_path(test_hash: test_hash), method: :post do |form| %> +
+ <%= form.label :message, "New Comment" %> + <%= form.text_area :message %> +
+ + <%= submit_tag "Save Comment" %> + <% end %> + +<% else %> + + <%= form_for comment, url: admin_update_comment_path(test_hash: test_hash, id: comment.id), method: :post do |form| %> +
+ <%= form.label :message, "Update Comment" %> + <%= form.text_area :message %> +
+ + <%= submit_tag "Update" %> + <% end %> - <%= submit_tag "Save Comment" %> <% end %> diff --git a/app/views/admin/result/view.html.erb b/app/views/admin/result/view.html.erb index b07c69a..bcc3a8b 100644 --- a/app/views/admin/result/view.html.erb +++ b/app/views/admin/result/view.html.erb @@ -46,6 +46,8 @@

Comments

<%= render partial: 'comment', collection: @comments, locals: { test_hash: @candidate.test_hash } %> -
<%= render partial: 'comment_form', locals: { test_hash: @candidate.test_hash } %>
+ <% if policy(QuizComment).create? %> + <%= render partial: 'comment_form', locals: {comment: @comment, test_hash: @candidate.test_hash } %> + <% end %>
From a8c42af3de44a2f60446edd2200acb99410ba81a Mon Sep 17 00:00:00 2001 From: Mark Moser Date: Tue, 14 Feb 2017 10:17:42 -0600 Subject: [PATCH 09/10] comment policy and test updates --- app/controllers/admin/comment_controller.rb | 8 ++-- app/policies/quiz_comment_policy.rb | 16 +++---- app/views/admin/result/view.html.erb | 2 +- .../admin/comment_controller_test.rb | 46 +++++++++++++++++++ test/policies/quiz_comment_policy_test.rb | 11 +++-- 5 files changed, 64 insertions(+), 19 deletions(-) diff --git a/app/controllers/admin/comment_controller.rb b/app/controllers/admin/comment_controller.rb index cef5cff..9a12d50 100644 --- a/app/controllers/admin/comment_controller.rb +++ b/app/controllers/admin/comment_controller.rb @@ -15,12 +15,10 @@ module Admin end def create - authorize QuizComment - comment = QuizComment.create( - comment_params.merge(user_id: current_user.id, test_hash: params[:test_hash]) - ) + comment = QuizComment.new(comment_params.merge(user_id: current_user.id, test_hash: params[:test_hash])) + authorize comment - flash_message = if comment.persisted? + flash_message = if comment.save { success: "Sucessfully created comment" } else { error: "Failed to save comment" } diff --git a/app/policies/quiz_comment_policy.rb b/app/policies/quiz_comment_policy.rb index 49b850e..f4128f9 100644 --- a/app/policies/quiz_comment_policy.rb +++ b/app/policies/quiz_comment_policy.rb @@ -2,20 +2,18 @@ class QuizCommentPolicy < ApplicationPolicy # Quiz Comment Policy # - # Anyone with access to the results can comment - # Only Comment owner can edit + # Anyone who can vote on results, can comment + # Only comment owner can edit her comment + + def new? + user.acts_as_reviewer? + end def create? - user.acts_as_reviewer? + user.acts_as_reviewer? && record.candidate.reviewers.where(id: user.id).count.positive? end def update? user.acts_as_reviewer? && user.id == record.user_id end - - class Scope < Scope - def resolve - true - end - end end diff --git a/app/views/admin/result/view.html.erb b/app/views/admin/result/view.html.erb index bcc3a8b..0372f3d 100644 --- a/app/views/admin/result/view.html.erb +++ b/app/views/admin/result/view.html.erb @@ -46,7 +46,7 @@

Comments

<%= render partial: 'comment', collection: @comments, locals: { test_hash: @candidate.test_hash } %> - <% if policy(QuizComment).create? %> + <% if policy(QuizComment).new? %> <%= render partial: 'comment_form', locals: {comment: @comment, test_hash: @candidate.test_hash } %> <% end %>
diff --git a/test/controllers/admin/comment_controller_test.rb b/test/controllers/admin/comment_controller_test.rb index d864127..0c2bf00 100644 --- a/test/controllers/admin/comment_controller_test.rb +++ b/test/controllers/admin/comment_controller_test.rb @@ -14,6 +14,17 @@ module Admin refute_equal comment.message, QuizComment.find_by(id: comment.id).message end + test "should require message to update" do + auth_manager + comment = quiz_comments(:com5) + post admin_update_comment_url(test_hash: comment.test_hash, id: comment.id), + params: { quiz_comment: { message: '' } } + + assert_redirected_to admin_result_url(test_hash: comment.test_hash) + assert flash[:error] + assert_equal comment.message, QuizComment.find_by(id: comment.id).message + end + test "should post create" do auth_reviewer candidate = candidates(:stacy) @@ -26,5 +37,40 @@ module Admin assert_redirected_to admin_result_url(test_hash: candidate.test_hash) assert flash[:success] end + + test "should require comment to create" do + auth_reviewer + candidate = candidates(:stacy) + + assert_difference("QuizComment.count", 0) do + post admin_create_comment_url(test_hash: candidate.test_hash), + params: { quiz_comment: { message: '' } } + end + + assert_redirected_to admin_result_url(test_hash: candidate.test_hash) + assert flash[:error] + end + + test "should not edit others comments" do + auth_reviewer + comment = quiz_comments(:com5) + post admin_update_comment_url(test_hash: comment.test_hash, id: comment.id), + params: { quiz_comment: { message: 'updated comment' } } + + assert_redirected_to admin_login_url + assert_equal comment.message, QuizComment.find_by(id: comment.id).message + end + + test "can not comment on Gustov" do + auth_reviewer + candidate = candidates(:gustov) + + assert_difference("QuizComment.count", 0) do + post admin_create_comment_url(test_hash: candidate.test_hash), + params: { quiz_comment: { message: 'this is a test comment' } } + end + + assert_redirected_to admin_login_url + end end end diff --git a/test/policies/quiz_comment_policy_test.rb b/test/policies/quiz_comment_policy_test.rb index 518681f..6298093 100644 --- a/test/policies/quiz_comment_policy_test.rb +++ b/test/policies/quiz_comment_policy_test.rb @@ -9,11 +9,14 @@ class QuizCommentPolicyTest < PolicyAssertions::Test end def test_create - assert_permit users(:admin), QuizComment - assert_permit users(:manager), QuizComment - assert_permit users(:reviewer), QuizComment + candidate = candidates(:stacy) + comment = QuizComment.new(test_hash: candidate.test_hash) - refute_permit users(:recruiter), QuizComment + assert_permit users(:manager), comment + assert_permit users(:reviewer), comment + + refute_permit users(:admin), comment + refute_permit users(:recruiter), comment end def test_update From 2424fa021fcd98a14ed593121fd476e1dbacffc2 Mon Sep 17 00:00:00 2001 From: Mark Moser Date: Tue, 14 Feb 2017 11:32:39 -0600 Subject: [PATCH 10/10] sends emails to all reviewers on new comment --- app/controllers/admin/comment_controller.rb | 2 ++ app/mailers/reviewer_mailer.rb | 7 +++++++ app/views/layouts/mailer.html.inky | 2 +- app/views/reviewer_mailer/new_comment.html.inky | 13 +++++++++++++ app/views/reviewer_mailer/new_comment.text.erb | 9 +++++++++ test/controllers/admin/comment_controller_test.rb | 14 ++++++++++++++ test/mailers/previews/reviewer_mailer_preview.rb | 4 ++++ test/mailers/reviewer_mailer_test.rb | 10 ++++++++++ 8 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 app/views/reviewer_mailer/new_comment.html.inky create mode 100644 app/views/reviewer_mailer/new_comment.text.erb diff --git a/app/controllers/admin/comment_controller.rb b/app/controllers/admin/comment_controller.rb index 9a12d50..6da6843 100644 --- a/app/controllers/admin/comment_controller.rb +++ b/app/controllers/admin/comment_controller.rb @@ -23,6 +23,8 @@ module Admin else { error: "Failed to save comment" } end + + ReviewerMailer.new_comment(comment).deliver_later if comment.persisted? redirect_to admin_result_path(params[:test_hash]), flash: flash_message end diff --git a/app/mailers/reviewer_mailer.rb b/app/mailers/reviewer_mailer.rb index 3955ef9..b640169 100644 --- a/app/mailers/reviewer_mailer.rb +++ b/app/mailers/reviewer_mailer.rb @@ -19,4 +19,11 @@ class ReviewerMailer < ApplicationMailer mail to: @manager.email, subject: "Voting Complete" end + + def new_comment comment + @comment = comment + recipients = comment.candidate.reviewers.map(&:email) + + mail to: recipients, subject: "Skills Assessment Review Comment - #{@comment.test_hash}" + end end diff --git a/app/views/layouts/mailer.html.inky b/app/views/layouts/mailer.html.inky index 12f03c3..9761da3 100644 --- a/app/views/layouts/mailer.html.inky +++ b/app/views/layouts/mailer.html.inky @@ -23,7 +23,7 @@