policies and auto review builds
This commit is contained in:
parent
e8e745f356
commit
df997aa258
@ -2,8 +2,8 @@
|
|||||||
module Admin
|
module Admin
|
||||||
class VoteController < AdminController
|
class VoteController < AdminController
|
||||||
def up
|
def up
|
||||||
authorize ReviewerVote
|
|
||||||
@candidate = Candidate.find_by(test_hash: params[:test_hash])
|
@candidate = Candidate.find_by(test_hash: params[:test_hash])
|
||||||
|
authorize ReviewerVote.find_by(user_id: current_user.id, candidate_id: @candidate.id)
|
||||||
current_user.cast_yea_on(@candidate)
|
current_user.cast_yea_on(@candidate)
|
||||||
|
|
||||||
results = {
|
results = {
|
||||||
@ -16,8 +16,8 @@ module Admin
|
|||||||
end
|
end
|
||||||
|
|
||||||
def down
|
def down
|
||||||
authorize ReviewerVote
|
|
||||||
@candidate = Candidate.find_by(test_hash: params[:test_hash])
|
@candidate = Candidate.find_by(test_hash: params[:test_hash])
|
||||||
|
authorize ReviewerVote.find_by(user_id: current_user.id, candidate_id: @candidate.id)
|
||||||
current_user.cast_nay_on(@candidate)
|
current_user.cast_nay_on(@candidate)
|
||||||
|
|
||||||
results = {
|
results = {
|
||||||
@ -30,8 +30,8 @@ module Admin
|
|||||||
end
|
end
|
||||||
|
|
||||||
def approve
|
def approve
|
||||||
authorize ReviewerVote
|
|
||||||
@candidate = Candidate.find_by(test_hash: params[:test_hash])
|
@candidate = Candidate.find_by(test_hash: params[:test_hash])
|
||||||
|
authorize ReviewerVote.find_by(user_id: current_user.id, candidate_id: @candidate.id)
|
||||||
current_user.approve_candidate(@candidate)
|
current_user.approve_candidate(@candidate)
|
||||||
|
|
||||||
results = {
|
results = {
|
||||||
@ -43,8 +43,8 @@ module Admin
|
|||||||
end
|
end
|
||||||
|
|
||||||
def decline
|
def decline
|
||||||
authorize ReviewerVote
|
|
||||||
@candidate = Candidate.find_by(test_hash: params[:test_hash])
|
@candidate = Candidate.find_by(test_hash: params[:test_hash])
|
||||||
|
authorize ReviewerVote.find_by(user_id: current_user.id, candidate_id: @candidate.id)
|
||||||
current_user.decline_candidate(@candidate)
|
current_user.decline_candidate(@candidate)
|
||||||
|
|
||||||
results = {
|
results = {
|
||||||
|
@ -36,6 +36,7 @@ class QuizController < ApplicationController
|
|||||||
|
|
||||||
def complete_and_email
|
def complete_and_email
|
||||||
if current_candidate.update_attributes(completed: true)
|
if current_candidate.update_attributes(completed: true)
|
||||||
|
current_candidate.build_reviews
|
||||||
CandidateMailer.submitted(current_candidate).deliver_later
|
CandidateMailer.submitted(current_candidate).deliver_later
|
||||||
RecruiterMailer.candidate_submitted(current_candidate).deliver_later
|
RecruiterMailer.candidate_submitted(current_candidate).deliver_later
|
||||||
ReviewerMailer.candidate_submission(current_candidate).deliver_later
|
ReviewerMailer.candidate_submission(current_candidate).deliver_later
|
||||||
|
@ -5,6 +5,7 @@ class Candidate < ApplicationRecord
|
|||||||
has_many :answers
|
has_many :answers
|
||||||
belongs_to :recruiter, class_name: "User"
|
belongs_to :recruiter, class_name: "User"
|
||||||
has_many :votes, class_name: "ReviewerVote"
|
has_many :votes, class_name: "ReviewerVote"
|
||||||
|
has_many :reviewers, through: :quiz
|
||||||
|
|
||||||
serialize :email, CryptSerializer
|
serialize :email, CryptSerializer
|
||||||
|
|
||||||
@ -22,6 +23,12 @@ class Candidate < ApplicationRecord
|
|||||||
declined: 2
|
declined: 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def build_reviews
|
||||||
|
reviewers.each do |reviewer|
|
||||||
|
votes.find_or_create_by(user_id: reviewer.id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def submitted_answers
|
def submitted_answers
|
||||||
answers.where(submitted: true)
|
answers.where(submitted: true)
|
||||||
end
|
end
|
||||||
|
@ -20,13 +20,13 @@ class User < ApplicationRecord
|
|||||||
|
|
||||||
# Voting
|
# Voting
|
||||||
def cast_yea_on candidate
|
def cast_yea_on candidate
|
||||||
vote = votes.find_or_create_by(candidate_id: candidate.to_i)
|
vote = votes.find_by(candidate_id: candidate.to_i)
|
||||||
vote.vote = :yea
|
vote.vote = :yea
|
||||||
vote.save
|
vote.save
|
||||||
end
|
end
|
||||||
|
|
||||||
def cast_nay_on candidate
|
def cast_nay_on candidate
|
||||||
vote = votes.find_or_create_by(candidate_id: candidate.to_i)
|
vote = votes.find_by(candidate_id: candidate.to_i)
|
||||||
vote.vote = :nay
|
vote.vote = :nay
|
||||||
vote.save
|
vote.save
|
||||||
end
|
end
|
||||||
@ -34,7 +34,7 @@ class User < ApplicationRecord
|
|||||||
def approve_candidate candidate
|
def approve_candidate candidate
|
||||||
candidate = Candidate.find(candidate.to_i)
|
candidate = Candidate.find(candidate.to_i)
|
||||||
|
|
||||||
vote = votes.find_or_create_by(candidate_id: candidate.to_i)
|
vote = votes.find_by(candidate_id: candidate.to_i)
|
||||||
vote.veto = :approved
|
vote.veto = :approved
|
||||||
candidate.update_attribute(:review_status, :approved) if vote.save
|
candidate.update_attribute(:review_status, :approved) if vote.save
|
||||||
end
|
end
|
||||||
@ -42,7 +42,7 @@ class User < ApplicationRecord
|
|||||||
def decline_candidate candidate
|
def decline_candidate candidate
|
||||||
candidate = Candidate.find(candidate.to_i)
|
candidate = Candidate.find(candidate.to_i)
|
||||||
|
|
||||||
vote = votes.find_or_create_by(candidate_id: candidate.to_i)
|
vote = votes.find_by(candidate_id: candidate.to_i)
|
||||||
vote.veto = :rejected
|
vote.veto = :rejected
|
||||||
candidate.update_attribute(:review_status, :declined) if vote.save
|
candidate.update_attribute(:review_status, :declined) if vote.save
|
||||||
end
|
end
|
||||||
@ -50,7 +50,8 @@ class User < ApplicationRecord
|
|||||||
def my_vote candidate
|
def my_vote candidate
|
||||||
candidate = Candidate.find(candidate.to_i)
|
candidate = Candidate.find(candidate.to_i)
|
||||||
|
|
||||||
votes.find_by(candidate_id: candidate.id).vote
|
my_vote = votes.find_by(candidate_id: candidate.id)
|
||||||
|
my_vote.vote unless my_vote.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
# Roles
|
# Roles
|
||||||
@ -83,7 +84,7 @@ class User < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def acts_as_reviewer?
|
def acts_as_reviewer?
|
||||||
%w(admin reviewer).include? role
|
%w(admin manager reviewer).include? role
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -8,21 +8,26 @@ class ReviewerVotePolicy < ApplicationPolicy
|
|||||||
# Only Managers, and Admins, can veto a quiz result
|
# Only Managers, and Admins, can veto a quiz result
|
||||||
|
|
||||||
def up?
|
def up?
|
||||||
# return true if user.reviewees.include? record.candidate
|
return true if user.acts_as_admin?
|
||||||
true
|
return false unless record.candidate.reviewers.include? user
|
||||||
|
user.acts_as_reviewer?
|
||||||
end
|
end
|
||||||
|
|
||||||
def down?
|
def down?
|
||||||
# return true if user.acts_as_manager?
|
return true if user.acts_as_admin?
|
||||||
# user.quizzes.include? record
|
return false unless record.candidate.reviewers.include? user
|
||||||
true
|
user.acts_as_reviewer?
|
||||||
end
|
end
|
||||||
|
|
||||||
def approve?
|
def approve?
|
||||||
|
return true if user.acts_as_admin?
|
||||||
|
return false unless record.candidate.reviewers.include? user
|
||||||
user.acts_as_manager?
|
user.acts_as_manager?
|
||||||
end
|
end
|
||||||
|
|
||||||
def decline?
|
def decline?
|
||||||
|
return true if user.acts_as_admin?
|
||||||
|
return false unless record.candidate.reviewers.include? user
|
||||||
user.acts_as_manager?
|
user.acts_as_manager?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
34
app/views/admin/result/_voting.html.erb
Normal file
34
app/views/admin/result/_voting.html.erb
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<% # TODO: This needs to be extracted into a decorator, or something. It is only a quick hack solution. %>
|
||||||
|
|
||||||
|
<% if current_user.acts_as_reviewer? %>
|
||||||
|
<div class="review_meta__votes" data-id="vote-count">
|
||||||
|
<strong>Votes: </strong>
|
||||||
|
<%= link_to admin_up_vote_path(test_hash: @candidate.test_hash), remote: true do %>
|
||||||
|
Yea (<span data-id="up-votes"><%= @candidate.votes.yea.count %></span>)
|
||||||
|
<% end %>
|
||||||
|
<%= link_to admin_down_vote_path(test_hash: @candidate.test_hash), remote: true do %>
|
||||||
|
Nay (<span data-id="down-votes"><%= @candidate.votes.nay.count %></span>)
|
||||||
|
<% end %>
|
||||||
|
<small>(Your vote: <span data-id="my-vote"><%= current_user.my_vote(@candidate) %></span>)</small>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if current_user.acts_as_manager? %>
|
||||||
|
<div class="review_meta__vetos" data-id="veto-status">
|
||||||
|
<strong>Manager Vetos: </strong>
|
||||||
|
<%= link_to admin_approve_vote_path(test_hash: @candidate.test_hash), remote: true do %>
|
||||||
|
<span data-id="interview-request">
|
||||||
|
<%= @candidate.approved? ? "Requested" : "Request Interview" %>
|
||||||
|
</span>
|
||||||
|
<% end %>
|
||||||
|
<%= link_to admin_decline_vote_path(test_hash: @candidate.test_hash), remote: true do %>
|
||||||
|
<span data-id="interview-decline">
|
||||||
|
<%= @candidate.declined? ? "Declined" : "Decline Interview" %>
|
||||||
|
</span>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<% else %>
|
||||||
|
|
||||||
|
<strong>Candidate Interview Status: </strong><%= @candidate.review_status %>
|
||||||
|
<% end %>
|
@ -7,36 +7,9 @@
|
|||||||
<strong>Years of Experience:</strong> <%= @candidate.experience %><br />
|
<strong>Years of Experience:</strong> <%= @candidate.experience %><br />
|
||||||
<strong>Recruiter Email:</strong> <%= mail_to @candidate.recruiter.name, @candidate.recruiter.email %><br />
|
<strong>Recruiter Email:</strong> <%= mail_to @candidate.recruiter.name, @candidate.recruiter.email %><br />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
|
||||||
<div class="review_meta__votes" data-id="vote-count">
|
<div><%= render partial: 'voting' %></div>
|
||||||
<strong>Votes: </strong>
|
</div>
|
||||||
<%= link_to admin_up_vote_path(test_hash: @candidate.test_hash), remote: true do %>
|
|
||||||
Yea (<span data-id="up-votes"><%= @candidate.votes.yea.count %></span>)
|
|
||||||
<% end %>
|
|
||||||
<%= link_to admin_down_vote_path(test_hash: @candidate.test_hash), remote: true do %>
|
|
||||||
Nay (<span data-id="down-votes"><%= @candidate.votes.nay.count %></span>)
|
|
||||||
<% end %>
|
|
||||||
<small>(Your vote: <span data-id="my-vote"><%= current_user.my_vote(@candidate) %></span>)</small>
|
|
||||||
</div>
|
|
||||||
<% if current_user.acts_as_manager? %>
|
|
||||||
<div class="review_meta__vetos" data-id="veto-status">
|
|
||||||
<strong>Manager Vetos: </strong>
|
|
||||||
<%= link_to admin_approve_vote_path(test_hash: @candidate.test_hash), remote: true do %>
|
|
||||||
<span data-id="interview-request">
|
|
||||||
<%= @candidate.approved? ? "Requested" : "Request Interview" %>
|
|
||||||
</span>
|
|
||||||
<% end %>
|
|
||||||
<%= link_to admin_decline_vote_path(test_hash: @candidate.test_hash), remote: true do %>
|
|
||||||
<span data-id="interview-decline">
|
|
||||||
<%= @candidate.declined? ? "Declined" : "Decline Interview" %>
|
|
||||||
</span>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
<% else %>
|
|
||||||
<strong>Candidate Interview Status: </strong><%= @candidate.review_status %>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<% @quiz.each do |question| %>
|
<% @quiz.each do |question| %>
|
||||||
<%= form_for(:answer, url: '#never-post', html:{id: 'summary-form'}) do |form| %>
|
<%= form_for(:answer, url: '#never-post', html:{id: 'summary-form'}) do |form| %>
|
||||||
|
6
db/migrate/20161120175737_init_reviewer_votes.rb
Normal file
6
db/migrate/20161120175737_init_reviewer_votes.rb
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
class InitReviewerVotes < ActiveRecord::Migration[5.0]
|
||||||
|
def up
|
||||||
|
Candidate.where(completed: true).each(&:build_reviews)
|
||||||
|
end
|
||||||
|
end
|
@ -10,7 +10,7 @@
|
|||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 20161118023249) do
|
ActiveRecord::Schema.define(version: 20161120175737) do
|
||||||
|
|
||||||
create_table "answers", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
|
create_table "answers", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
|
||||||
t.integer "candidate_id"
|
t.integer "candidate_id"
|
||||||
|
@ -26,5 +26,12 @@ module Admin
|
|||||||
get admin_result_url(candidates(:henry).test_hash)
|
get admin_result_url(candidates(:henry).test_hash)
|
||||||
assert_response :success
|
assert_response :success
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "recruiter can view result for henry" do
|
||||||
|
auth_user users(:recruiter)
|
||||||
|
|
||||||
|
get admin_result_url(candidates(:henry).test_hash)
|
||||||
|
assert_response :success
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
4
test/fixtures/reviewer_votes.yml
vendored
4
test/fixtures/reviewer_votes.yml
vendored
@ -1,3 +1,7 @@
|
|||||||
|
gustov:
|
||||||
|
candidate: gustov
|
||||||
|
user_id: 12341234
|
||||||
|
|
||||||
|
|
||||||
manager_richard:
|
manager_richard:
|
||||||
candidate: richard
|
candidate: richard
|
||||||
|
@ -24,4 +24,11 @@ class CandidateTest < ActiveSupport::TestCase
|
|||||||
|
|
||||||
refute_equal email, enc_email
|
refute_equal email, enc_email
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "can build reviewer records" do
|
||||||
|
candidate = candidates(:dawn)
|
||||||
|
|
||||||
|
candidate.build_reviews
|
||||||
|
assert_equal 3, candidate.votes.count
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -20,14 +20,14 @@ class UserTest < ActiveSupport::TestCase
|
|||||||
refute user.reviewer?
|
refute user.reviewer?
|
||||||
end
|
end
|
||||||
|
|
||||||
test 'manager should act as manager' do
|
test 'manager should act as manager and reviewer' do
|
||||||
user = users(:manager)
|
user = users(:manager)
|
||||||
|
|
||||||
assert user.acts_as_manager?
|
assert user.acts_as_manager?
|
||||||
|
assert user.acts_as_reviewer?
|
||||||
|
|
||||||
refute user.acts_as_admin?
|
refute user.acts_as_admin?
|
||||||
refute user.acts_as_recruiter?
|
refute user.acts_as_recruiter?
|
||||||
refute user.acts_as_reviewer?
|
|
||||||
end
|
end
|
||||||
|
|
||||||
test 'manager should only be manager' do
|
test 'manager should only be manager' do
|
||||||
|
@ -29,20 +29,38 @@ class ReviewerVotePolicyTest < PolicyAssertions::Test
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_up
|
def test_up
|
||||||
# refute_permit users(:admin), reviewer_votes(:manager_henry)
|
assert_permit users(:manager), reviewer_votes(:manager_richard)
|
||||||
# refute_permit users(:recruiter), candidates(:richard)
|
assert_permit users(:reviewer), reviewer_votes(:reviewer_richard)
|
||||||
# refute_permit users(:reviewer), candidates(:gustov)
|
assert_permit users(:admin), reviewer_votes(:manager_henry)
|
||||||
|
|
||||||
# assert_permit users(:admin), candidates(:gustov)
|
refute_permit users(:recruiter), reviewer_votes(:manager_henry)
|
||||||
# assert_permit users(:manager), candidates(:richard)
|
refute_permit users(:reviewer), reviewer_votes(:gustov)
|
||||||
# assert_permit users(:reviewer), candidates(:richard)
|
refute_permit users(:manager), reviewer_votes(:gustov)
|
||||||
end
|
end
|
||||||
|
|
||||||
# def test_create_and_update
|
def test_down
|
||||||
# assert_permit users(:admin), Vote
|
assert_permit users(:manager), reviewer_votes(:manager_richard)
|
||||||
# assert_permit users(:manager), Vote
|
assert_permit users(:reviewer), reviewer_votes(:reviewer_richard)
|
||||||
#
|
assert_permit users(:admin), reviewer_votes(:manager_henry)
|
||||||
# refute_permit users(:recruiter), Vote
|
|
||||||
# refute_permit users(:reviewer), Vote
|
refute_permit users(:recruiter), reviewer_votes(:manager_henry)
|
||||||
# end
|
refute_permit users(:reviewer), reviewer_votes(:gustov)
|
||||||
|
refute_permit users(:manager), reviewer_votes(:gustov)
|
||||||
|
end
|
||||||
|
|
||||||
|
def approve
|
||||||
|
assert_permit users(:manager), reviewer_votes(:manager_richard)
|
||||||
|
assert_permit users(:admin), reviewer_votes(:manager_henry)
|
||||||
|
|
||||||
|
refute_permit users(:recruiter), reviewer_votes(:manager_henry)
|
||||||
|
refute_permit users(:reviewer), reviewer_votes(:reviewer_richard)
|
||||||
|
end
|
||||||
|
|
||||||
|
def decline
|
||||||
|
assert_permit users(:manager), reviewer_votes(:manager_richard)
|
||||||
|
assert_permit users(:admin), reviewer_votes(:manager_henry)
|
||||||
|
|
||||||
|
refute_permit users(:recruiter), reviewer_votes(:manager_henry)
|
||||||
|
refute_permit users(:reviewer), reviewer_votes(:reviewer_richard)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user