allow anonymous peer reviews; respect anonymity for reviewers
Anonymous peer reviews will arrive in a couple of patches, but this is the first, and 1) allows an assignment to require anonymous peer reviews, and 2) respects anonymity from the perspective of the student whose work has been reviewed. A couple tangential changes: - update styles / html of _submission_sidebar on assignments page. - Update `submission_comment_model` factory to use `@submission` instance var if present. - Update `Submission#add_comment` to allow setting of recipient. fixes CNVS-5531 test plan: - As a teacher of a course with at least two students, create or edit an assignment. - Associate a rubric with the assignment. - Click the `Require Peer Reviews` check box, and observe the checkbox under the headline, "Anonymity." Click the checkbox labeled: "Peer Reviews Appear Anonymously." - As a student, we will call the reviewed, complete the assignment. - As the teacher, go to the assignment peer reviews page locate a user different than the one that completed the assignment above, we will call the reviewer, and assign them a peer review of the reviewed's assignment. - As the reviewer, log in and complete the peer review by leaving a coment, and by showing the rubric and adding number of points. - Observe that you are able to see your own name below the comment you have left. - Observe that, when you view the rubric, you can see your own name in the 'Show Assessment By' dropdown. - As the teacher, observe that you are able to see the reviewer's name underneath the comment they have left, and when you view the rubric, you can see the reviewer's name in the 'Show Assignment By' dropdown. - As the reviewed, observe that you are unable to see the review's name underneath the comment they have left, or in the 'Show Assignment By' drowndown when viewing the rubric. Change-Id: I1cadc7ac65a32188095949dfd758d4cd0883ac3e Reviewed-on: https://gerrit.instructure.com/47841 Tested-by: Jenkins Reviewed-by: Mike Nomitch <mnomitch@instructure.com> Reviewed-by: Matt Berns <mberns@instructure.com> QA-Review: Adam Stone <astone@instructure.com> Product-Review: Hilary Scharton <hilary@instructure.com>
This commit is contained in:
parent
578c6f3315
commit
4658e125a4
|
@ -145,6 +145,10 @@ define [
|
|||
return @get 'peer_reviews' unless arguments.length > 0
|
||||
@set 'peer_reviews', peerReviewBoolean
|
||||
|
||||
anonymousPeerReviews: (anonymousPeerReviewBoolean) =>
|
||||
return @get 'anonymous_peer_reviews' unless arguments.length > 0
|
||||
@set 'anonymous_peer_reviews', anonymousPeerReviewBoolean
|
||||
|
||||
automaticPeerReviews: (autoPeerReviewBoolean) =>
|
||||
return @get 'automatic_peer_reviews' unless arguments.length > 0
|
||||
@set 'automatic_peer_reviews', autoPeerReviewBoolean
|
||||
|
@ -281,7 +285,7 @@ define [
|
|||
fields = [
|
||||
'name', 'dueAt','description','pointsPossible', 'lockAt', 'unlockAt',
|
||||
'gradingType', 'notifyOfUpdate', 'peerReviews', 'automaticPeerReviews',
|
||||
'peerReviewCount', 'peerReviewsAssignAt',
|
||||
'peerReviewCount', 'peerReviewsAssignAt', 'anonymousPeerReviews',
|
||||
'acceptsOnlineUpload','acceptsMediaRecording', 'submissionType',
|
||||
'acceptsOnlineTextEntries', 'acceptsOnlineURL', 'allowedExtensions',
|
||||
'restrictFileExtensions', 'isOnlineSubmission', 'isNotGraded',
|
||||
|
|
|
@ -16,6 +16,7 @@ define [
|
|||
AUTO_PEER_REVIEWS = '#assignment_automatic_peer_reviews'
|
||||
PEER_REVIEWS_DETAILS = '#peer_reviews_details'
|
||||
AUTO_PEER_REVIEWS_OPTIONS = '#automatic_peer_reviews_options'
|
||||
ANONYMOUS_PEER_REVIEWS = '#anonymous_peer_reviews'
|
||||
|
||||
events: do ->
|
||||
events = {}
|
||||
|
@ -48,6 +49,7 @@ define [
|
|||
toJSON: =>
|
||||
frozenAttributes = @parentModel.frozenAttributes()
|
||||
|
||||
anonymousPeerReviews: @parentModel.anonymousPeerReviews()
|
||||
peerReviews: @parentModel.peerReviews()
|
||||
automaticPeerReviews: @parentModel.automaticPeerReviews()
|
||||
peerReviewCount: @parentModel.peerReviewCount()
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
module SubmissionCommentsHelper
|
||||
def comment_author_name_for(comment)
|
||||
can_do(comment, @current_user, :read_author) ?
|
||||
comment.author_name : t("Anonymous User")
|
||||
end
|
||||
end
|
|
@ -33,7 +33,7 @@ class Assignment < ActiveRecord::Base
|
|||
|
||||
attr_accessible :title, :name, :description, :due_at, :points_possible,
|
||||
:grading_type, :submission_types, :assignment_group, :unlock_at, :lock_at,
|
||||
:group_category, :group_category_id, :peer_review_count,
|
||||
:group_category, :group_category_id, :peer_review_count, :anonymous_peer_reviews,
|
||||
:peer_reviews_due_at, :peer_reviews_assign_at, :grading_standard_id,
|
||||
:peer_reviews, :automatic_peer_reviews, :grade_group_students_individually,
|
||||
:notify_of_update, :time_zone_edited, :turnitin_enabled,
|
||||
|
|
|
@ -168,6 +168,11 @@ class RubricAssessment < ActiveRecord::Base
|
|||
(self.rubric_association.association_object.context.grants_right?(self.assessor, :manage_rubrics) rescue false)
|
||||
}
|
||||
can :update
|
||||
|
||||
given {|user, session|
|
||||
self.can_read_assessor_name?(user, session)
|
||||
}
|
||||
can :read_assessor
|
||||
end
|
||||
|
||||
scope :of_type, lambda { |type| where(:assessment_type => type.to_s) }
|
||||
|
@ -188,6 +193,19 @@ class RubricAssessment < ActiveRecord::Base
|
|||
self.artifact.url rescue nil
|
||||
end
|
||||
|
||||
def can_read_assessor_name?(user, session)
|
||||
!self.considered_anonymous? ||
|
||||
self.assessor_id == user.id ||
|
||||
self.rubric_association.association_object.context.grants_right?(
|
||||
user, session, :view_all_grades
|
||||
)
|
||||
end
|
||||
|
||||
def considered_anonymous?
|
||||
self.rubric_association.association_type == 'Assignment' &&
|
||||
self.rubric_association.association_object.anonymous_peer_reviews?
|
||||
end
|
||||
|
||||
def ratings
|
||||
self.data
|
||||
end
|
||||
|
|
|
@ -904,7 +904,7 @@ class Submission < ActiveRecord::Base
|
|||
self.save! if self.new_record?
|
||||
valid_keys = [:comment, :author, :media_comment_id, :media_comment_type,
|
||||
:group_comment_id, :assessment_request, :attachments,
|
||||
:anonymous, :hidden]
|
||||
:anonymous, :hidden, :recipient]
|
||||
if opts[:comment].present?
|
||||
comment = submission_comments.create!(opts.slice(*valid_keys))
|
||||
end
|
||||
|
|
|
@ -99,6 +99,13 @@ class SubmissionComment < ActiveRecord::Base
|
|||
|
||||
given {|user, session| self.submission.grants_right?(user, session, :grade) }
|
||||
can :read and can :delete
|
||||
|
||||
given { |user, session|
|
||||
!self.anonymous? ||
|
||||
self.author == user ||
|
||||
self.submission.assignment.context.grants_right?(user, session, :view_all_grades)
|
||||
}
|
||||
can :read_author
|
||||
end
|
||||
|
||||
set_broadcast_policy do |p|
|
||||
|
@ -172,6 +179,7 @@ class SubmissionComment < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def infer_details
|
||||
self.anonymous = self.submission.assignment.anonymous_peer_reviews
|
||||
self.author_name ||= self.author.short_name rescue t(:unknown_author, "Someone")
|
||||
self.cached_attachments = self.attachments.map{|a| OpenObject.build('attachment', a.attributes) }
|
||||
self.context = self.read_attribute(:context) || self.submission.assignment.context rescue nil
|
||||
|
@ -182,7 +190,6 @@ class SubmissionComment < ActiveRecord::Base
|
|||
self.save
|
||||
end
|
||||
|
||||
|
||||
def attachments
|
||||
ids = Set.new((attachment_ids || "").split(",").map { |id| id.to_i})
|
||||
attachments = associated_attachments
|
||||
|
@ -215,7 +222,7 @@ class SubmissionComment < ActiveRecord::Base
|
|||
def context_code
|
||||
"#{self.context_type.downcase}_#{self.context_id}"
|
||||
end
|
||||
|
||||
|
||||
def avatar_path
|
||||
"/images/users/#{User.avatar_key(self.author_id)}"
|
||||
end
|
||||
|
|
|
@ -159,3 +159,47 @@
|
|||
#content {
|
||||
padding-bottom: 110px;
|
||||
}
|
||||
|
||||
#sidebar_content {
|
||||
.details {
|
||||
h3 {
|
||||
margin: 0;
|
||||
}
|
||||
.header {
|
||||
font-size: 1.2em;
|
||||
font-weight: bold;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.content {
|
||||
padding-left: 5px;
|
||||
h4 {
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.module {
|
||||
padding-top: 10px;
|
||||
}
|
||||
.late {
|
||||
color: #880000;
|
||||
font-weight: bold;
|
||||
}
|
||||
.unstyled_list {
|
||||
margin: 5px 10px 0 10px;
|
||||
}
|
||||
.comments {
|
||||
font-size: 11px;
|
||||
max-height: 300px;
|
||||
overflow: auto;
|
||||
.comment {
|
||||
margin-left: 10px;
|
||||
.signature {
|
||||
color: #888888;
|
||||
font-size: 0.8em;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
@current_user_submission.assigned_assessments.incomplete.count
|
||||
].cache_key) do %>
|
||||
<div class="details">
|
||||
<h3 style="margin: 0;"><%= t 'titles.submission', "Submission" %></h3>
|
||||
<h3><%= t 'titles.submission', "Submission" %></h3>
|
||||
<% if @assignment.expects_submission? %>
|
||||
<div class="header" style="margin-top:2px; font-weight: bold; font-size: 1.2em;">
|
||||
<div class="header">
|
||||
<% if @current_user_submission.has_submission? %>
|
||||
<%= image_tag "graded.png" %> <%= t 'titles.submission_turned_in', "Turned In!" %>
|
||||
<% else %>
|
||||
|
@ -16,50 +16,74 @@
|
|||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
<div style="padding-left: 5px;">
|
||||
<span style="<%= "color: #800; font-weight: bold;" if @current_user_submission.late? %>">
|
||||
<div class="content">
|
||||
<span class="<%= "late" if @current_user_submission.late? %>">
|
||||
<% if @current_user_submission.late? %>
|
||||
<%= t 'messages.submission_late_timestamp', "%{submitted_at} (late)", :submitted_at => datetime_string(@current_user_submission.submitted_at) %>
|
||||
<% else %>
|
||||
<%= datetime_string(@current_user_submission.submitted_at) %>
|
||||
<% end %>
|
||||
</span>
|
||||
<br/>
|
||||
|
||||
<a href="<%= context_url(@assignment.context, :context_assignment_submission_url, @assignment.id, @current_user.id) %>" class='forward'><%= t 'links.submission.details', "Submission Details" %></a><br/>
|
||||
<a href="<%= context_url(@assignment.context, :context_assignment_submission_url, @assignment.id, @current_user.id) %>" class="forward">
|
||||
<%= t 'links.submission.details', "Submission Details" %>
|
||||
</a>
|
||||
|
||||
<% if @current_user_submission.submission_type == "online_url" %>
|
||||
<a href="<%= @current_user_submission.url %>" target="_new" class='link'><%= t 'links.submission.view_original_page', "View the Original Page" %></a><br/>
|
||||
<a href="<%= @current_user_submission.url %>" target="_new" class='link'>
|
||||
<%= t 'links.submission.view_original_page', "View the Original Page" %>
|
||||
</a>
|
||||
<% elsif @current_user_submission.submission_type == "online_upload" %>
|
||||
<% @current_user_submission.attachments.each do |attachment| %>
|
||||
<a href="<%= context_url(@context, :context_assignment_submission_url, @assignment.id, @current_user_submission.user_id, :download => attachment.id) %>" class='file-big'><%= t 'links.submission.download_attachment', "Download %{attachment_display_name}", :attachment_display_name => attachment.display_name %></a><br/>
|
||||
<a href="<%= context_url(@context, :context_assignment_submission_url, @assignment.id, @current_user_submission.user_id, :download => attachment.id) %>" class='file-big'>
|
||||
<%= t 'links.submission.download_attachment', "Download %{attachment_display_name}", {
|
||||
:attachment_display_name => attachment.display_name
|
||||
} %>
|
||||
</a>
|
||||
<% end %>
|
||||
<% elsif @current_user_submission.submission_type == "online_quiz" %>
|
||||
<a href="<%= context_url(@assignment.context, :context_quiz_url, @assignment.quiz.id) %>" target="_new" class='quiz'>
|
||||
<%= @assignment.quiz.survey? ? t('links.submission.view_survey', "View the Survey Submission") :
|
||||
t('links.submission.view_quiz', "View the Quiz Submission") %></a><br />
|
||||
<% end %>
|
||||
<% if @current_user_submission.grade && !@assignment.muted? %>
|
||||
<br/>
|
||||
<%= t 'labels.grade', "Grade: %{grade} *(%{points_possible} pts possible)*", :grade => @current_user_submission.grade,
|
||||
:points_possible => @assignment.points_possible, :wrapper => '<span style="font-size: 0.8em;">\1</span>' %>
|
||||
<% end %>
|
||||
<% if @current_user_submission.rubric_assessment %>
|
||||
<a href="<%= context_url(@context, :context_assignment_submission_url, @assignment.id, @current_user_submission.user_id) %>#rubric" class='rubric'><%= t 'links.view_rubric_evaluation', "View Rubric Evaluation" %></a>
|
||||
t('links.submission.view_quiz', "View the Quiz Submission") %>
|
||||
</a>
|
||||
<% end %>
|
||||
|
||||
<div class="module">
|
||||
<% if @current_user_submission.grade && !@assignment.muted? %>
|
||||
<span>
|
||||
<%= t 'labels.grade', "Grade: %{grade} *(%{points_possible} pts possible)*", {
|
||||
:grade => @current_user_submission.grade,
|
||||
:points_possible => @assignment.points_possible,
|
||||
:wrapper => '<span style="font-size: 0.8em;">\1</span>'
|
||||
} %>
|
||||
</span>
|
||||
<% end %>
|
||||
|
||||
<% if @current_user_submission.rubric_assessment %>
|
||||
<a href="<%= context_url(@context, :context_assignment_submission_url, @assignment.id, @current_user_submission.user_id) %>#rubric" class='rubric'>
|
||||
<%= t 'links.view_rubric_evaluation', "View Rubric Evaluation" %>
|
||||
</a>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<% if @assignment.has_peer_reviews? && @current_user_submission.user == @current_user %>
|
||||
<br/><b><%= t 'titles.assigned_peer_reviews', "Assigned Peer Reviews" %></b>
|
||||
<ul class="unstyled_list" style="margin: 5px 10px 10px;">
|
||||
<h4><%= t 'titles.assigned_peer_reviews', "Assigned Peer Reviews" %></h4>
|
||||
|
||||
<ul class="unstyled_list">
|
||||
<li style="<%= hidden unless @current_user_submission.assigned_assessments.empty? %>"><%= t 'labels.none_assigned', "None Assigned" %></li>
|
||||
<% @current_user_submission.assigned_assessments.each do |assessment| %>
|
||||
<li><%= student_peer_review_link_for @context, @assignment, assessment %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
<div style="font-size: 11px; padding-top: 10px; max-height: 300px; overflow: auto;"><b><%= t 'titles.comments', "Comments:" %> </b>
|
||||
|
||||
<div class="comments module">
|
||||
<h4><%= t 'titles.comments', "Comments:" %> </h4>
|
||||
|
||||
<% visible_comments = @current_user_submission.visible_submission_comments -%>
|
||||
<%= t('messages.no_comments', "No Comments") if visible_comments.empty? %>
|
||||
<% visible_comments.each do |comment| %>
|
||||
<div style="margin-left: 10px;">
|
||||
<div id="comment-<%= comment.id %>" class="comment">
|
||||
<%= comment.comment %>
|
||||
<div class="comment_attachments">
|
||||
<% comment.attachments.each do |attachment| %>
|
||||
|
@ -68,8 +92,11 @@
|
|||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<div style="font-size: 0.8em; text-align: right; color: #888;">
|
||||
<%= t :comment_signature, "%{author}, %{created_at}", :author => comment.author_name, :created_at => datetime_string(comment.created_at) %>
|
||||
<div class="signature" style="font-size: 0.8em; text-align: right; color: #888;">
|
||||
<%= t :comment_signature, "%{author}, %{created_at}", {
|
||||
:author => comment_author_name_for(comment),
|
||||
:created_at => datetime_string(comment.created_at)
|
||||
} %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
|
@ -88,6 +88,25 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="nested">
|
||||
<div class="subtitle">
|
||||
<strong>
|
||||
{{#t 'anonymous_peer_reviews'}}Anonymity{{/t}}
|
||||
</strong>
|
||||
</div>
|
||||
|
||||
<label class="checkbox" for="anonymous_peer_reviews">
|
||||
{{checkbox "anonymousPeerReviews"
|
||||
id="anonymous_peer_reviews"
|
||||
name="anonymous_peer_reviews"
|
||||
aria-controls="anonymous_peer_reviews"
|
||||
disabled=peerReviewsFrozen}}
|
||||
{{#t "labels.anonymous_peer_reviews"}}
|
||||
Peer Reviews Appear Anonymously
|
||||
{{/t}}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -113,7 +113,13 @@
|
|||
<%= before_label('show_assessment_by', 'Show Assessment By') %>
|
||||
<select id="rubric_assessments_select">
|
||||
<% @visible_rubric_assessments.each do |assessment| %>
|
||||
<option id="rubric_assessment_option_<%= assessment.id %>" value="<%= assessment.id %>"><%= assessment.assessor_name %></option>
|
||||
<option id="rubric_assessment_option_<%= assessment.id %>" value="<%= assessment.id %>">
|
||||
<% if can_do(assessment, @current_user, :read_assessor) -%>
|
||||
<%= assessment.assessor_name %>
|
||||
<% else -%>
|
||||
<%= t(:anonymous_user, "Anonymous User") %>
|
||||
<% end -%>
|
||||
</option>
|
||||
<% end %>
|
||||
<% if can_do(@assignment.rubric_association, @current_user, :assess) && @submission.user != @current_user %>
|
||||
<% unless @visible_rubric_assessments.map{|a| a.assessor_id}.include?(@current_user.id) %>
|
||||
|
@ -182,7 +188,9 @@
|
|||
<% end %>
|
||||
</div>
|
||||
<div style="text-align: right; font-size: 0.8em; color: #888;">
|
||||
<span class="author_name"><%= comment.author_name %></span>,
|
||||
<span class="author_name">
|
||||
<%= comment_author_name_for(comment) %>
|
||||
</span>,
|
||||
<span class="posted_at"><%= datetime_string(comment.created_at) %></span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -37,6 +37,7 @@ module Api::V1::Assignment
|
|||
unlock_at
|
||||
assignment_group_id
|
||||
peer_reviews
|
||||
anonymous_peer_reviews
|
||||
automatic_peer_reviews
|
||||
post_to_sis
|
||||
grade_group_students_individually
|
||||
|
@ -256,6 +257,7 @@ module Api::V1::Assignment
|
|||
assignment_group_id
|
||||
group_category_id
|
||||
peer_reviews
|
||||
anonymous_peer_reviews
|
||||
peer_reviews_assign_at
|
||||
peer_review_count
|
||||
automatic_peer_reviews
|
||||
|
|
|
@ -25,6 +25,5 @@ end
|
|||
|
||||
def submission_comment_model(opts={})
|
||||
args = valid_submission_comment_attributes.merge(opts)
|
||||
submission_model
|
||||
@submission_comment = @submission.add_comment(args)
|
||||
end
|
||||
@submission_comment = (@submission || submission_model).add_comment(args)
|
||||
end
|
||||
|
|
|
@ -74,7 +74,7 @@ describe RubricAssessment do
|
|||
expect(@assessment.artifact.score).to eql(5.0)
|
||||
expect(@assessment.data.first[:comments_html]).to be_nil
|
||||
end
|
||||
|
||||
|
||||
it "should not update scores if not used for grading" do
|
||||
rubric_model
|
||||
@association = @rubric.associate_with(@assignment, @course, :purpose => 'grading', :use_for_grading => false)
|
||||
|
@ -98,7 +98,7 @@ describe RubricAssessment do
|
|||
expect(@assessment.artifact.grader).to eql(nil)
|
||||
expect(@assessment.artifact.score).to eql(nil)
|
||||
end
|
||||
|
||||
|
||||
it "should not update scores if not a valid grader" do
|
||||
@student2 = user(:active_all => true)
|
||||
@course.enroll_student(@student2).accept
|
||||
|
@ -122,5 +122,38 @@ describe RubricAssessment do
|
|||
expect(@assessment.artifact.grader).to eql(nil)
|
||||
expect(@assessment.artifact.score).to eql(nil)
|
||||
end
|
||||
|
||||
describe "for assignment requiring anonymous peer reviews" do
|
||||
before(:once) do
|
||||
@assignment.update_attribute(:anonymous_peer_reviews, true)
|
||||
@reviewed = @student
|
||||
@reviewer = student_in_course(:active_all => true).user
|
||||
@assignment.assign_peer_review(@reviewer, @student)
|
||||
@assessment = @association.assess({
|
||||
:user => @reviewed,
|
||||
:assessor => @reviewer,
|
||||
:artifact => @assignment.find_or_create_submission(@student),
|
||||
:assessment => {
|
||||
:assessment_type => 'peer_review',
|
||||
:criterion_crit1 => {
|
||||
:points => 5,
|
||||
:comments => "Hey, it's a comment."
|
||||
}
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
it "should prevent reviewed from seeing reviewer's name" do
|
||||
expect(@assessment.grants_right?(@reviewed, :read_assessor)).to be_falsey
|
||||
end
|
||||
|
||||
it "should allow reviewer to see own name" do
|
||||
expect(@assessment.grants_right?(@reviewer, :read_assessor)).to be_truthy
|
||||
end
|
||||
|
||||
it "should allow teacher to see reviewer's name" do
|
||||
expect(@assessment.grants_right?(@teacher, :read_assessor)).to be_truthy
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -31,7 +31,7 @@ describe SubmissionComment do
|
|||
:comment => "some comment"
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
it "should create a new instance given valid attributes" do
|
||||
SubmissionComment.create!(@valid_attributes)
|
||||
end
|
||||
|
@ -85,7 +85,7 @@ describe SubmissionComment do
|
|||
@comment = @submission.add_comment(:author => se.user, :comment => "some comment")
|
||||
expect(@comment.messages_sent).to_not be_include('Submission Comment')
|
||||
end
|
||||
|
||||
|
||||
it "should dispatch notification on create to teachers even if submission not submitted yet" do
|
||||
assignment_model
|
||||
@assignment.workflow_state = 'published'
|
||||
|
@ -99,7 +99,7 @@ describe SubmissionComment do
|
|||
@comment = @submission.add_comment(:author => se.user, :comment => "some comment")
|
||||
expect(@comment.messages_sent).to be_include('Submission Comment For Teacher')
|
||||
end
|
||||
|
||||
|
||||
it "should allow valid attachments" do
|
||||
a = Attachment.create!(:context => @assignment, :uploaded_data => default_uploaded_data)
|
||||
@comment = SubmissionComment.create!(@valid_attributes)
|
||||
|
@ -108,7 +108,7 @@ describe SubmissionComment do
|
|||
@comment.update_attributes(:attachments => [a])
|
||||
expect(@comment.attachment_ids).to eql(a.id.to_s)
|
||||
end
|
||||
|
||||
|
||||
it "should reject invalid attachments" do
|
||||
a = Attachment.create!(:context => @assignment, :uploaded_data => default_uploaded_data)
|
||||
a.recently_created = false
|
||||
|
@ -116,7 +116,7 @@ describe SubmissionComment do
|
|||
@comment.update_attributes(:attachments => [a])
|
||||
expect(@comment.attachment_ids).to eql("")
|
||||
end
|
||||
|
||||
|
||||
it "should render formatted_body correctly" do
|
||||
@comment = SubmissionComment.create!(@valid_attributes)
|
||||
@comment.comment = %{
|
||||
|
@ -130,7 +130,7 @@ This text has a http://www.google.com link in it...
|
|||
expect(body).to match(/\<a/)
|
||||
expect(body).to match(/quoted_text/)
|
||||
end
|
||||
|
||||
|
||||
it "should send the submission to the stream" do
|
||||
assignment_model
|
||||
@assignment.workflow_state = 'published'
|
||||
|
@ -160,27 +160,53 @@ This text has a http://www.google.com link in it...
|
|||
@comment = @submission.add_comment(:author => se.user, :media_comment_type => 'audio', :media_comment_id => 'fake')
|
||||
end
|
||||
|
||||
it "should prevent peer reviewer from seeing other comments" do
|
||||
@student1 = @student
|
||||
@student2 = student_in_course(:active_all => true).user
|
||||
@student3 = student_in_course(:active_all => true).user
|
||||
describe "peer reviews" do
|
||||
before(:once) do
|
||||
@student1 = @student
|
||||
@student2 = student_in_course(:active_all => true).user
|
||||
@student3 = student_in_course(:active_all => true).user
|
||||
|
||||
@assignment.peer_reviews = true
|
||||
@assignment.save!
|
||||
@assignment.assign_peer_review(@student2, @student1)
|
||||
@assignment.assign_peer_review(@student3, @student1)
|
||||
@assignment.peer_reviews = true
|
||||
@assignment.save!
|
||||
@assignment.assign_peer_review(@student2, @student1)
|
||||
@assignment.assign_peer_review(@student3, @student1)
|
||||
end
|
||||
|
||||
@teacher_comment = @submission.add_comment(:author => @teacher, :comment => "some comment from teacher")
|
||||
@reviewer_comment = @submission.add_comment(:author => @student2, :comment => "some comment from peer reviewer")
|
||||
@my_comment = @submission.add_comment(:author => @student3, :comment => "some comment from me")
|
||||
it "should prevent peer reviewer from seeing other comments" do
|
||||
@teacher_comment = @submission.add_comment(:author => @teacher, :comment => "some comment from teacher")
|
||||
@reviewer_comment = @submission.add_comment(:author => @student2, :comment => "some comment from peer reviewer")
|
||||
@my_comment = @submission.add_comment(:author => @student3, :comment => "some comment from me")
|
||||
|
||||
expect(@teacher_comment.grants_right?(@student3, :read)).to be_falsey
|
||||
expect(@reviewer_comment.grants_right?(@student3, :read)).to be_falsey
|
||||
expect(@my_comment.grants_right?(@student3, :read)).to be_truthy
|
||||
expect(@teacher_comment.grants_right?(@student3, :read)).to be_falsey
|
||||
expect(@reviewer_comment.grants_right?(@student3, :read)).to be_falsey
|
||||
expect(@my_comment.grants_right?(@student3, :read)).to be_truthy
|
||||
|
||||
expect(@teacher_comment.grants_right?(@student1, :read)).to be_truthy
|
||||
expect(@reviewer_comment.grants_right?(@student1, :read)).to be_truthy
|
||||
expect(@my_comment.grants_right?(@student1, :read)).to be_truthy
|
||||
expect(@teacher_comment.grants_right?(@student1, :read)).to be_truthy
|
||||
expect(@reviewer_comment.grants_right?(@student1, :read)).to be_truthy
|
||||
expect(@my_comment.grants_right?(@student1, :read)).to be_truthy
|
||||
end
|
||||
|
||||
describe "when anonymous" do
|
||||
before(:once) do
|
||||
@assignment.update_attribute(:anonymous_peer_reviews, true)
|
||||
@reviewer_comment = @submission.add_comment({
|
||||
author: @student2,
|
||||
comment: "My peer review comment."
|
||||
})
|
||||
end
|
||||
|
||||
it "should mark submission comment as anonymous" do
|
||||
expect(@reviewer_comment.anonymous?).to be_truthy
|
||||
end
|
||||
|
||||
it "should prevent reviewed from seeing reviewer name" do
|
||||
expect(@reviewer_comment.grants_right?(@student1, :read_author)).to be_falsey
|
||||
end
|
||||
|
||||
it "should allow teacher to see reviewer name" do
|
||||
expect(@reviewer_comment.grants_right?(@teacher, :read_author)).to be_truthy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "reply_from" do
|
||||
|
@ -188,8 +214,8 @@ This text has a http://www.google.com link in it...
|
|||
comment = @submission.add_comment(:user => @teacher, :comment => "some comment")
|
||||
Account.default.destroy
|
||||
comment.reload
|
||||
expect {
|
||||
comment.reply_from(:user => @student, :text => "some reply")
|
||||
expect {
|
||||
comment.reply_from(:user => @student, :text => "some reply")
|
||||
}.to raise_error(IncomingMail::Errors::UnknownAddress)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -55,4 +55,109 @@ describe "assignments" do
|
|||
expect(assessment.assessment_type).to eq 'peer_review'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with anonymous peer reviews' do
|
||||
let!(:review_course) { course(active_all: true) }
|
||||
let!(:teacher) { review_course.teachers.first }
|
||||
let!(:reviewed) { student_in_course(active_all: true).user }
|
||||
let!(:reviewer) { student_in_course(active_all: true).user }
|
||||
let!(:assignment) {
|
||||
assignment_model({
|
||||
course: review_course,
|
||||
peer_reviews: true,
|
||||
anonymous_peer_reviews: true
|
||||
})
|
||||
}
|
||||
let!(:submission) {
|
||||
submission_model({
|
||||
assignment: assignment,
|
||||
body: 'submission body',
|
||||
course: review_course,
|
||||
grade: "5",
|
||||
score: "5",
|
||||
submission_type: 'online_text_entry',
|
||||
user: reviewed
|
||||
})
|
||||
}
|
||||
let!(:comment) {
|
||||
submission_comment_model({
|
||||
author: reviewer,
|
||||
recipient: reviewed
|
||||
})
|
||||
}
|
||||
let!(:rubric) { rubric_model }
|
||||
let!(:association) {
|
||||
rubric.associate_with(assignment, review_course, {
|
||||
:purpose => 'grading', :use_for_grading => true
|
||||
})
|
||||
}
|
||||
let!(:assessment) {
|
||||
association.assess({
|
||||
:user => reviewed,
|
||||
:assessor => reviewer,
|
||||
:artifact => submission,
|
||||
:assessment => {
|
||||
:assessment_type => 'peer_review',
|
||||
:criterion_crit1 => {
|
||||
:points => 5,
|
||||
:comments => "Hey, it's a comment."
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
before(:each) { assignment.assign_peer_review(reviewer, reviewed) }
|
||||
|
||||
context 'when reviewed is logged in' do
|
||||
before(:each) { user_logged_in(user: reviewed) }
|
||||
|
||||
it 'should block reviewer name on assignments page' do
|
||||
get "/courses/#{review_course.id}/assignments/#{assignment.id}"
|
||||
expect(f("#comment-#{comment.id} .signature")).to include_text(t("Anonymous User"))
|
||||
end
|
||||
|
||||
it 'should hide comment reviewer name on submission page' do
|
||||
get "/courses/#{review_course.id}/assignments/#{assignment.id}/submissions/#{reviewed.id}"
|
||||
expect(f("#submission_comment_#{comment.id} .author_name")).to include_text(t("Anonymous User"))
|
||||
end
|
||||
|
||||
it 'should hide comment reviewer name on rubric popup' do
|
||||
get "/courses/#{review_course.id}/assignments/#{assignment.id}/submissions/#{reviewed.id}"
|
||||
f('.assess_submission_link').click
|
||||
wait_for_animations
|
||||
expect(f("#rubric_assessment_option_#{assessment.id}")).to include_text(t("Anonymous User"))
|
||||
end
|
||||
end
|
||||
|
||||
context 'when reviewer is logged in' do
|
||||
before(:each) { user_logged_in(user: reviewer) }
|
||||
|
||||
it 'should show comment reviewer name on submission page' do
|
||||
get "/courses/#{review_course.id}/assignments/#{assignment.id}/submissions/#{reviewed.id}"
|
||||
expect(f("#submission_comment_#{comment.id} .author_name")).to include_text(comment.author_name)
|
||||
end
|
||||
|
||||
it 'should show comment reviewer name on rubric popup' do
|
||||
get "/courses/#{review_course.id}/assignments/#{assignment.id}/submissions/#{reviewed.id}"
|
||||
f('.assess_submission_link').click
|
||||
wait_for_animations
|
||||
expect(f("#rubric_assessment_option_#{assessment.id}")).to include_text(reviewer.email)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when teacher is logged in' do
|
||||
before(:each) { user_logged_in(user: teacher) }
|
||||
|
||||
it 'should show comment reviewer name on submission page' do
|
||||
get "/courses/#{review_course.id}/assignments/#{assignment.id}/submissions/#{reviewed.id}"
|
||||
expect(f("#submission_comment_#{comment.id} .author_name")).to include_text(comment.author_name)
|
||||
end
|
||||
|
||||
it 'should show comment reviewer name on rubric popup' do
|
||||
get "/courses/#{review_course.id}/assignments/#{assignment.id}/submissions/#{reviewed.id}"
|
||||
f('.assess_submission_link').click
|
||||
wait_for_animations
|
||||
expect(f("#rubric_assessment_option_#{assessment.id}")).to include_text(assessment.assessor_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue