anonymize students in email notifications

fixes GRADE-1630

When an assignment is anonymous and still muted, students submitting
late will not have their names exposed in the email notification.

Test Plan
- Check your teacher's notification settings for late assignment
  submissions and verify that they are set to send immediately.
- Create a plain assignment, due yesterday.
- Create an anonymous assignment, due yesterday.

- For each assignment:
- As a student, submit to that assignment. Have the submission
  uniquely identify the student somehow.
- As another student, repeat the previous step.
- As the teacher, check your email for the notifications generated by
  the submissions.

- The plain assignment email notification should show the name of
  the student who submitted late. There should be a link to the
  submission details page. Verify this for both html and plain text.
- The anonymous assignment email notification should _not_ show the
  name of the student who submitted late. There should be a link to
  the speed grader page of that submission. Verify this for both html
  and plain text.

Change-Id: I3e0f07f392dc653dcc67a3cff7da409960d6a96a
Reviewed-on: https://gerrit.instructure.com/168528
Tested-by: Jenkins
QA-Review: Gary Mei <gmei@instructure.com>
Product-Review: Sidharth Oberoi <soberoi@instructure.com>
Reviewed-by: Jeremy Neander <jneander@instructure.com>
Reviewed-by: Keith Garner <kgarner@instructure.com>
This commit is contained in:
Gary Mei 2018-10-03 16:14:53 -05:00
parent c4bf6fad50
commit e547154967
5 changed files with 250 additions and 9 deletions

View File

@ -1,12 +1,43 @@
<%
assignment = asset.assignment
anonymize_students = assignment.anonymize_students?
user_name = anonymize_students ? 'A student' : asset.user.name
link = ''
subject = ''
if anonymize_students
subject = t(
'Late anonymous assignment: %{user_name} has submitted late for %{assignment_title}',
user_name: user_name,
assignment_title: assignment.title
)
link = speed_grader_course_gradebook_url(assignment.context, assignment_id: assignment.id) +
"\#{\"anonymous_id\":\"#{asset.anonymous_id}\"}"
else
subject = t(
'Late assignment: %{user_name} has submitted late for %{assignment_title}',
user_name: user_name,
assignment_title: assignment.title
)
link = course_assignment_submission_url(assignment.context, assignment, asset.user_id)
end
%>
<% define_content :link do %>
<%= course_assignment_submission_url(asset.assignment.context, asset.assignment, asset.user_id) %>
<%= link %>
<% end %>
<% define_content :subject do %>
<%= t('user_submitted', 'Late Assignment: %{user_name}, %{assignment_name}', :user_name => asset.user.name, :assignment_name => asset.assignment.title) %>
<%= subject %>
<% end %>
<%= t('user_resubmitted_sentence', '%{user_name} has just turned in a late submission for %{assignment_name} in the course %{course_name}', :user_name => asset.user.name, :assignment_name => asset.assignment.title, :course_name => asset.assignment.context.name) %>
<%= t(
'user_resubmitted_sentence',
'%{user_name} has just turned in a late submission for %{assignment_name} in the course %{course_name}',
user_name: user_name,
assignment_name: assignment.title,
course_name: assignment.context.name
) %>
<%= before_label('view_submission', 'You can view the submission here') %>
<%= content :link %>

View File

@ -1,9 +1,34 @@
<%
assignment = asset.assignment
anonymize_students = assignment.anonymize_students?
user_name = anonymize_students ? 'A student' : asset.user.name
link = ''
subject = ''
if anonymize_students
subject = t(
'Late anonymous assignment: %{user_name} has submitted late for %{assignment_title}',
user_name: user_name,
assignment_title: assignment.title
)
link = speed_grader_course_gradebook_url(assignment.context, assignment_id: assignment.id) +
"\#{\"anonymous_id\":\"#{asset.anonymous_id}\"}"
else
subject = t(
'Late assignment: %{user_name} has submitted late for %{assignment_title}',
user_name: user_name,
assignment_title: assignment.title
)
link = course_assignment_submission_url(assignment.context, assignment, asset.user_id)
end
%>
<% define_content :link do %>
<%= course_assignment_submission_url(asset.assignment.context, asset.assignment, asset.user_id) %>
<%= link.html_safe %>
<% end %>
<% define_content :subject do %>
<%= t('user_submitted', 'Late Assignment: %{user_name}, %{assignment_name}', :user_name => asset.user.name, :assignment_name => asset.assignment.title) %>
<%= subject %>
<% end %>
<% define_content :footer_link do %>
@ -12,7 +37,12 @@
</a>
<% end %>
<p><%= t('user_resubmitted_sentence', '%{user_name} has just turned in a late submission for %{assignment_name} in the course %{course_name}',
:user_name => asset.user.name,
:assignment_name => asset.assignment.title,
:course_name => asset.assignment.context.name) %></p>
<p>
<%= t(
'user_resubmitted_sentence',
'%{user_name} has just turned in a late submission for %{assignment_name} in the course %{course_name}',
user_name: user_name,
assignment_name: assignment.title,
course_name: assignment.context.name
) %>
</p>

View File

@ -0,0 +1,62 @@
#
# Copyright (C) 2018 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
require "spec_helper"
describe "assignment_submitted_late.email" do
include Rails.application.routes.url_helpers
def default_url_options
{ host: 'localhost' }
end
let(:course) { Course.create!(name: "Inst101") }
let(:student) { course_with_user("StudentEnrollment", course: course, name: "Tom", active_all: true).user }
let(:assignment) { course.assignments.create!(name: "Assignment#1", due_at: 1.day.ago) }
let(:submission) { assignment.submit_homework(student) }
let(:message) { generate_message(:assignment_submitted_late, :email, submission, {}) }
include_examples "assignment submitted late email"
it "body includes the student name" do
expect(
message.body
).to include(
"Tom has just turned in a late submission for Assignment#1 in the course Inst101"
)
end
it "body does not include the student name if assignment is anonymous and muted" do
assignment.update!(anonymous_grading: true)
expect(
message.body
).to include(
"A student has just turned in a late submission for Assignment#1 in the course Inst101"
)
end
it "body includes the student name if assignment is anonymous and unmuted" do
assignment.update!(anonymous_grading: true)
assignment.unmute!
expect(
message.body
).to include(
"Tom has just turned in a late submission for Assignment#1 in the course Inst101"
)
end
end

View File

@ -0,0 +1,62 @@
#
# Copyright (C) 2018 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
require "spec_helper"
describe "assignment_submitted_late.email.html" do
include Rails.application.routes.url_helpers
def default_url_options
{ host: 'localhost' }
end
let(:course) { Course.create!(name: "Inst101") }
let(:student) { course_with_user("StudentEnrollment", course: course, name: "Tom", active_all: true).user }
let(:assignment) { course.assignments.create!(name: "Assignment#1", due_at: 1.day.ago) }
let(:submission) { assignment.submit_homework(student) }
let(:message) { generate_message(:assignment_submitted_late, :email, submission, {}) }
include_examples "assignment submitted late email"
it "html body includes the student name" do
expect(
message.html_body
).to include(
"Tom has just turned in a late submission for Assignment#1 in the course Inst101"
)
end
it "html body does not include the student name if assignment is anonymous and muted" do
assignment.update!(anonymous_grading: true)
expect(
message.html_body
).to include(
"A student has just turned in a late submission for Assignment#1 in the course Inst101"
)
end
it "html body includes the student name if assignment is anonymous and unmuted" do
assignment.update!(anonymous_grading: true, muted: false)
assignment.unmute!
expect(
message.html_body
).to include(
"Tom has just turned in a late submission for Assignment#1 in the course Inst101"
)
end
end

View File

@ -0,0 +1,56 @@
#
# Copyright (C) 2018 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
shared_examples_for "assignment submitted late email" do
it "subject includes student name" do
expect(message.subject).to eq "Late assignment: Tom has submitted late for Assignment#1"
end
it "renders a link to the student's submission details page" do
expect(message.url).to eq course_assignment_submission_url(course, assignment, student.id)
end
context "assignment is anonymous and muted" do
before(:each) { assignment.update!(anonymous_grading: true) }
it "subject does not include student name" do
expect(message.subject).to eq "Late anonymous assignment: A student has submitted late for Assignment#1"
end
it "renders a link to speedgrader for that student" do
speed_grader_url = speed_grader_course_gradebook_url(course, assignment_id: assignment.id)
speed_grader_url += "\#{\"anonymous_id\":\"#{submission.anonymous_id}\"}"
expect(message.url).to eq speed_grader_url
end
end
context "assignment is anonymous and unmuted" do
before(:each) do
assignment.update!(anonymous_grading: true)
assignment.unmute!
end
it "subject includes student name" do
expect(message.subject).to eq "Late assignment: Tom has submitted late for Assignment#1"
end
it "renders a link to the student's submission details page" do
expect(message.url).to eq course_assignment_submission_url(course, assignment, student.id)
end
end
end