CSC/ECE 517 Fall 2020 - E2059. Email notification to reviewers and instructors.rb

From Expertiza_Wiki
Jump to navigation Jump to search

This project is a contribution to the opensource project Experteiza which was built using Ruby on Rails. The project was created for North Carolina State University's CSC/ECE 517 course to introduce and expose students to a large open-source project. The web application is designed where students can submit and be peer-review various assignments.

Introduction

The purpose of this project is to improve and test the email handling systems in Experteiza. The project's primary goals are to solve the following issues; unreliable student email receipts, and unreliable instructor email notices. Expertiza is intended to send students email notices when they receive a project submission for review, when their own work is reviewed, or when their reviews are reviewed. However, this functionality has proven to be unreliable and inconsistent. Additionally, instructors are intended to receive email copies of all emails being sent from the system. This functionality is also inconsistent and unreliable. This issue aims to address these errors and the remainder of this page describes how this is accomplished.

Identified Tasks

The following are identified tasks to be accomplished for the project:

Email Queue Appropriate tests for the following:

  • Check queues to ensure that emails are being sent out.
  • Check to see that the recipient of this message is the correct recipient
  • Check to see that the body of the message has the correct content.

Instructor Email Notifier

  1. Appropriate tests instructor should be able to get copies of emails:
    • Rails message that queues the email to the instructor
    • Check to see that emails sent by the system are also sent to the professor.

Merge in PR1604 to address Issues

This pull request was the last attempt to address the changes made that are required to be tested above.

Running Tests

 bash test_set.sh

Implementation

All tests are written using rspec. A list of all files changed are found at the bottom of the report and the following section explains each test.

generic_message

This method is used to send a generic email to user by passing the email, subject and the contents of the message. The RSpec test for this method first creates an generic_message object and verifies if the correct parameters were passed. Then the next test was to test if the ActionMailer successfully sent the email using generic_email. This was done by using the ActionMailer::Base.deliveries to check the outbox of the ActionMailer and ensured the contents of the outbox mached that of the mailer.

Setup

email = Mailer.generic_message(
      to: 'tluo@ncsu.edu',
      subject: "Test",
      body: {
        partial_name: "new_submission",
        user: "John Doe",
        first_name: "John",
        password: "Password",
        new_pct: 97,
        avg_pct: 90,
        assignment: "code assignment"
      }
    )

Test

it 'should be able to pass parameters to generic message' do
    # Send the email, then test that it got queued
    email = Mailer.generic_message(
      to: 'tluo@ncsu.edu',
      subject: "Test",
      body: {
        partial_name: "new_submission",
        user: "John Doe",
        first_name: "John",
        password: "Password",
        new_pct: 97,
        avg_pct: 90,
        assignment: "code assignment"
      }
    )
    expect(email.from[0]).to eq("expertiza.development@gmail.com")
    expect(email.to[0]).to eq('expertiza.development@gmail.com')
    expect(email.subject).to eq('Test')
  end

  it 'should be able to send an email using generic message' do
    ActionMailer::Base.deliveries.clear

    email = Mailer.generic_message(
      to: 'tluo@ncsu.edu',
      subject: "Test",
      body: {
        partial_name: "new_submission",
        user: "John Doe",
        first_name: "John",
        password: "Password",
        new_pct: 97,
        avg_pct: 90,
        assignment: "code assignment"
      }
    ).deliver_now

    ActionMailer::Base.deliveries.last.tap do |mail|
      expect(mail.from).to eq(["expertiza.development@gmail.com"])
      expect(mail.to).to eq(["expertiza.development@gmail.com"])
      expect(mail.subject).to eq("Test")
      expect(mail.body).to eq(email.body)
    end
  end

request_user_message

This method is used to request_user_message to a user by passing the super_user details, user name and the email subject. The RSpec for this creates a User object to be passed into generic message. Once done, the first test was to ensure that request_user_message received the correct parameters that were passed, the next test was to ensure that the ActionMailer successfully sent the email by checking the outbox in

Setup

  let(:user) do
    User.new name: 'abc', fullname: 'abc xyz', email: 'abcxyz@gmail.com', password: '12345678', password_confirmation: '12345678',
              email_on_submission: 1, email_on_review: 1, email_on_review_of_review: 0, copy_of_emails: 1, handle: 'handle'
  end

Test

  it 'should pass parameters correctly to request user message' do
    email = Mailer.request_user_message(
      to: 'tluo@ncsu.edu',
      subject: "Test",
      bcc: 'bccuser@email.com',
      body: {
        user: user,
        super_user: "superjohn",
        first_name: "John",
        new_pct: 97,
        avg_pct: 90,
              assignment: "code assignment"
      }
    )
    expect(email.from[0]).to eq("expertiza.development@gmail.com")
    expect(email.to[0]).to eq('expertiza.development@gmail.com')
    expect(email.subject).to eq('Test')
  end

  it 'should be able to send an email using request_user_message message' do
    ActionMailer::Base.deliveries.clear

    email = Mailer.request_user_message(
      to: 'tluo@ncsu.edu',
      subject: "Test",
      bcc: 'bccuser@email.com',
      body: {
        user: user,
        super_user: "superjohn",
        first_name: "John",
        new_pct: 97,
        avg_pct: 90,
              assignment: "code assignment"
      }
    ).deliver_now

    ActionMailer::Base.deliveries.last.tap do |mail|
      expect(mail.from).to eq(["expertiza.development@gmail.com"])
      expect(mail.to).to eq(["expertiza.development@gmail.com"])
      expect(mail.subject).to eq("Test")
      expect(mail.body).to eq(email.body)
    end
  end

send_mail_to_all_super_users

The send_mail_to_all_super_users method is a method that uses the request_user_message method to send emails. For this we wrote a proxy test to ensure that it and request_user_message were correctly sending emails by creating user object and passing the necessary fields to the send_mail_to_all_super_users and ensuring the ActionMailer::Base outbox had the correct outputs.

Setup

    let(:super_user) do
        User.new name: 'superabc', fullname: 'superabc xyz', email: 'abcxyz@gmail.com', password: '12345678', password_confirmation: '12345678',
                 email_on_submission: 1, email_on_review: 1, email_on_review_of_review: 0, copy_of_emails: 1, handle: 'handle'
    end

Test

    it 'Check if send_mail_to_all_super_users can properly send emails to super_users' do 
        ActionMailer::Base.deliveries.clear
        
        MailerHelper.send_mail_to_all_super_users(
          super_user, user, @subject
        ).deliver_now

        email = Mailer.generic_message(
            to: 'tluo@ncsu.edu',
            subject: "Test",
            body: {
              partial_name: "new_submission",
              user: "John Doe",
              first_name: "John",
              password: "Password",
              new_pct: 97,
              avg_pct: 90,
              assignment: "code assignment"
            }
          )
        ActionMailer::Base.deliveries.last.tap do |mail|
            expect(mail.from).to eq(["expertiza.development@gmail.com"])
            expect(mail.to).to eq(["expertiza.development@gmail.com"])
            expect(mail.subject).to eq("Test")
          end
    end

    it 'Check if send_mail_to_user can properly send emails using generic message' do 
      ActionMailer::Base.deliveries.clear
      MailerHelper.send_mail_to_user(
          user, @subject, @partial_name, @password
      ).deliver_now

      email = Mailer.generic_message(
          to: 'tluo@ncsu.edu',
          subject: "Test",
          body: {
            partial_name: "new_submission",
            user: "John Doe",
            first_name: "John",
            password: "Password",
            new_pct: 97,
            avg_pct: 90,
            assignment: "code assignment"
          }
        )
      ActionMailer::Base.deliveries.last.tap do |mail|
          expect(mail.from).to eq(["expertiza.development@gmail.com"])
          expect(mail.to).to eq(["expertiza.development@gmail.com"])
          expect(mail.subject).to eq("Test")
        end
  end

notify_reviewer_for_new_submission

This method is used to notify_reviewer_for_new_submission to a user by passing the user object, partial name and the message to be sent. The RSpec for this creates a User object to be passed into notify_reviewer_for_new_submission message. Once done, the first test was to ensure that notify_reviewer_for_new_submission received the correct parameters that were passed, the next test was to ensure that the ActionMailer successfully sent the email by checking the outbox to see if the contents of email matched that of the outbox.


Setup

  let(:user) do
    User.new name: 'abc', fullname: 'abc xyz', email: 'abcxyz@gmail.com', password: '12345678', password_confirmation: '12345678',
              email_on_submission: 1, email_on_review: 1, email_on_review_of_review: 0, copy_of_emails: 1, handle: 'handle'

Test

  it 'should pass parameters correctly to notify_reviewer_for_new_submission' do 
    email = Mailer.notify_reviewer_for_new_submission(
      to: 'tluo@ncsu.edu',
      subject: "Test",
      body: {
        partial_name: "new_submission",
        user: user,
        message: "Random Message"
      }
    )
    expect(email.from[0]).to eq("expertiza.development@gmail.com")
    expect(email.to[0]).to eq('tluo@ncsu.edu')
    expect(email.subject).to eq('Test')
  end


  it 'should be able to send an email using notify_reviewer_for_new_submission message' do 
    ActionMailer::Base.deliveries.clear
    email = Mailer.notify_reviewer_for_new_submission(
      to: 'tluo@ncsu.edu',
      subject: "Test",
      body: {
        partial_name: "new_submission",
        user: user,
        message: "Random Message"
      }
    ).deliver_now
    ActionMailer::Base.deliveries.last.tap do |mail|
      expect(mail.from).to eq(["expertiza.development@gmail.com"])
      expect(mail.to).to eq(["tluo@ncsu.edu"])
      expect(mail.subject).to eq("Test")
      expect(mail.body).to eq(email.body)
    end
  end

submission_mail_to_reviewer

The submission_mail_to_reviewer method is a method that uses the notify_reviewer_for_new_submission method to send emails. For this we wrote a proxy test to ensure that it and notify_reviewer_for_new_submission were correctly sending emails by creating user object and passing the necessary fields to the submission_mail_to_reviewer and ensuring the ActionMailer::Base outbox had the correct outputs.

Setup

describe 'Tests MailerHelper' do
...
    let(:user) do
      User.new name: 'abc', fullname: 'abc xyz', email: 'abcxyz@gmail.com', password: '12345678', password_confirmation: '12345678',
               email_on_submission: 1, email_on_review: 1, email_on_review_of_review: 0, copy_of_emails: 1, handle: 'handle'
  end
    
    
  before do
    @subject = "Test"
    @partial_name = "new_submission"
    @password = "pa$Sw0rD"
    @mail_partial = "new_submission"
  end

Test

  it 'Check if send_mail_to_all_super_users can properly send emails to super_users' do 
    ActionMailer::Base.deliveries.clear
    
    MailerHelper.submission_mail_to_reviewer(
      user, @subject, @mail_partial
    ).deliver_now

    email = Mailer.notify_reviewer_for_new_submission(
        to: 'tluo@ncsu.edu',
        subject: "Test",
        body: {
          partial_name: "new_submission",
          user: "John Doe",
          first_name: "John",
          password: "Password",
          new_pct: 97,
          avg_pct: 90,
          assignment: "code assignment"
        }
      )
    ActionMailer::Base.deliveries.last.tap do |mail|
        expect(mail.from).to eq(["expertiza.development@gmail.com"])
        expect(mail.to).to eq(["abcxyz@gmail.com"])
        expect(mail.subject).to eq("Test")
      end
  end

sync_message

Tests in this portion ensures emails are being sent upon a submission via the sync_message protocol.

Feedback Response Setup

Feedback review response submission is being tested to ensure emails are sent upon a feedback submission.

let(:team) { build(:assignment_team, id: 1, name: 'team no name', assignment: assignment, users: [student], parent_id: 1) }
  let(:team1) { build(:assignment_team, id: 2, name: 'team has name', assignment: assignment, users: [student]) }
  let(:review_response_map) { build(:review_response_map, id: 1, assignment: assignment, reviewer: participant, reviewee: team) }
  let(:review_response_map1) do
    build :review_response_map,
          id: 2,
          assignment: assignment,
          reviewer: participant1,
          reviewee: team1,
          reviewed_object_id: 1,
          response: [response],
          calibrate_to: 0
  end
  let(:feedback) { FeedbackResponseMap.create(id: 1, reviewed_object_id: 1, reviewer_id: 1, reviewee_id: 1) }
  let(:participant) { build(:participant, id: 1, parent_id: 1, user: student) }
  let(:participant1) { build(:participant, id: 2, parent_id: 2, user: student1) }
  let(:assignment) { build(:assignment, id: 1, name: 'Test Assgt', rounds_of_reviews: 2) }
  let(:assignment1) { build(:assignment, id: 2, name: 'Test Assgt', rounds_of_reviews: 1) }
  let(:response) { build(:response, id: 1, map_id: 1, round: 1, response_map: review_response_map,  is_submitted: true) }
  let(:response1) { build(:response, id: 2, map_id: 1, round: 2, response_map: review_response_map) }
  let(:response2) { build(:response, id: 3, map_id: 1, round: nil, response_map: review_response_map, is_submitted: true) }
  let(:metareview_response_map) { build(:meta_review_response_map, reviewed_object_id: 1) }
  let(:student) { build(:student, id: 1, name: 'name', fullname: 'no one', email: 'expertiza@mailinator.com') }
  let(:student1) { build(:student, id: 2, name: "name1", fullname: 'no one', email: 'expertiza@mailinator.com') }


  before(:each) do
    allow(feedback).to receive(:response).and_return(response)
  end

Feedback Test

  # Test if email is sent upon a feedback response submission
  it '#email' do
    allow(Participant).to receive(:find).with(1).and_return(participant)
    allow(Assignment).to receive(:find).with(1).and_return(assignment)
    allow(review_response_map).to receive(:response).and_return([response])
    allow(Response).to receive(:find).and_return(response)
    allow(FeedbackResponseMap).to receive(:find_by).with(reviewed_object_id: 1).and_return(feedback)
    feedback.reviewed_object_id = 1
    user = User.find(participant.user_id)

    defn = {body: {type: "Author Feedback", obj_name: assignment.name, first_name: user.fullname, partial_name: "new_submission"}, to: user.email}
    expect { feedback.email(defn, participant, assignment) }
        .to change { ActionMailer::Base.deliveries.count }.by 1
  end

Metareview Response Setup

This test ensures that an email is sent upon a review of a review being submitted.

  let(:team) { build(:assignment_team, id: 1, name: 'team no name', assignment: assignment, users: [student], parent_id: 1) }
  let(:team1) { build(:assignment_team, id: 2, name: 'team has name', assignment: assignment, users: [student]) }
  let(:review_response_map) { build(:review_response_map, id: 1, assignment: assignment, reviewer: participant, reviewee: team) }
  let(:review_response_map1) do
    build :review_response_map,
          id: 2,
          assignment: assignment,
          reviewer: participant1,
          reviewee: team1,
          reviewed_object_id: 1,
          response: [response],
          calibrate_to: 0
  end
  let(:feedback) { FeedbackResponseMap.new(id: 1, reviewed_object_id: 1, reviewer_id: 1, reviewee_id: 1) }
  let(:participant) { build(:participant, id: 1, parent_id: 1, user: student) }
  let(:participant1) { build(:participant, id: 2, parent_id: 2, user: student1) }
  let(:assignment) { build(:assignment, id: 1, name: 'Test Assgt', rounds_of_reviews: 2) }
  let(:assignment1) { build(:assignment, id: 2, name: 'Test Assgt', rounds_of_reviews: 1) }
  let(:response) { build(:response, id: 1, map_id: 1, round: 1, response_map: review_response_map,  is_submitted: true) }
  let(:response1) { build(:response, id: 2, map_id: 1, round: 2, response_map: review_response_map) }
  let(:response2) { build(:response, id: 3, map_id: 1, round: nil, response_map: review_response_map, is_submitted: true) }
  let(:metareview_response_map) { build(:meta_review_response_map, reviewed_object_id: 1) }
  let(:student) { build(:student, id: 1, name: 'name', fullname: 'no one', email: 'expertiza@mailinator.com') }
  let(:student1) { build(:student, id: 2, name: "name1", fullname: 'no one', email: 'expertiza@mailinator.com') }
  let(:assignment_questionnaire1) { build(:assignment_questionnaire, id: 1, assignment_id: 1, questionnaire_id: 1) }
  let(:assignment_questionnaire2) { build(:assignment_questionnaire, id: 2, assignment_id: 1, questionnaire_id: 2) }
  let(:questionnaire1) { build(:questionnaire, type: 'ReviewQuestionnaire') }
  let(:questionnaire2) { build(:questionnaire, type: 'MetareviewQuestionnaire') }
  let(:next_due_date) { build(:assignment_due_date, round: 1) }

  before(:each) do
    allow(review_response_map).to receive(:response).and_return(response)
  end

Metareview Test

  it '#email' do
    allow(Participant).to receive(:find).with(1).and_return(participant)
    reviewee_user = participant.id

    allow(Assignment).to receive(:find).with(reviewee_user).and_return(assignment)
    allow(AssignmentTeam).to receive(:find).with(reviewee_user).and_return(team)
    allow(AssignmentTeam).to receive(:users).and_return(student)
    allow(User).to receive(:find).with(reviewee_user).and_return(student)
    allow(MetareviewResponseMap).to receive(:where).with(reviewed_object_id: 1).and_return([metareview_response_map])
    metareview_response_map.reviewee_id = participant.id
    defn = {body: {type: "Metareview", obj_name: assignment.name, first_name: student.fullname, partial_name: "new_submission"}, to: student.email}
    
    expect { metareview_response_map.email(defn, participant, assignment)}
         .to change { ActionMailer::Base.deliveries.count }.by 1
  end

Response Survey Setup

This set of tests ensure that an email is sent upon an assignment or course survey submission.

let(:participant) { build(:participant, id: 1, user: build(:student, name: 'no name', fullname: 'no one')) }
  let(:participant2) { build(:participant, id: 2) }
  let(:course) { build(:course, id: 1, name: 'History', instructor: build(:instructor, email: 'tluo@ncsu.edu'))}
  let(:assignment) { build(:assignment, id: 1, name: 'Test Assgt', instructor: build(:instructor, email: 'tluo@ncsu.edu')) }
  let(:team) { build(:assignment_team) }
  let(:signed_up_team) { build(:signed_up_team, team_id: team.id) }
  let(:review_response_map) { build(:review_response_map, assignment: assignment, reviewer: participant, reviewee: team) }
  let(:response) { build(:response, id: 1, map_id: 1, response_map: review_response_map, scores: [answer]) }
  let(:answer) { Answer.new(answer: 1, comments: 'Answer text', question_id: 1) }
  let(:answer2) { Answer.new(answer: 2, comments: 'Answer text', question_id: 2) }
  let(:question) { Criterion.new(id: 1, weight: 2, break_before: true) }
  let(:question2) { TextArea.new(id: 1, weight: 2, break_before: true) }
  let(:questionnaire) { ReviewQuestionnaire.new(id: 1, questions: [question], max_question_score: 5) }
  let(:questionnaire2) { ReviewQuestionnaire.new(id: 2, questions: [question2], max_question_score: 5) }
  let(:tag_prompt) {TagPrompt.new(id: 1, prompt: "prompt")}
  let(:tag_prompt_deployment) {TagPromptDeployment.new(id: 1, tag_prompt_id: 1, assignment_id: 1, questionnaire_id: 1, question_type: 'Criterion')}
  let(:mail) { Mailer.notify_grade_conflict_message(
    to: 'tluo@ncsu.edu',
    subject: 'Expertiza Notification: A review score is outside the acceptable range',
    body: {
      reviewer_name: 'no one',
      type: 'review',
      reviewee_name: 'no one',
      new_score: 0.96,
      assignment: assignment,
      conflicting_response_url: 'https://expertiza.ncsu.edu/response/view?id=1',
      summary_url: 'https://expertiza.ncsu.edu/grades/view_team?id=2',
      assignment_edit_url: 'https://expertiza.ncsu.edu/assignments/1/edit'
    }
  )}
  before(:each) do
    allow(response).to receive(:map).and_return(review_response_map)
  end

Response Survey Tests

describe '#email' do
    it 'calls email method in assignment survey response maps' do
      assignment_survey_response_map = double('AssignmentSurveyResponseMap', reviewer_id: 1)
      allow(ResponseMap).to receive(:find).with(1).and_return(assignment_survey_response_map)
      allow(Participant).to receive(:find).with(1).and_return(participant)
      allow(assignment_survey_response_map).to receive(:survey?).and_return(true)
      allow(assignment_survey_response_map).to receive(:survey_parent).and_return(assignment)
      allow(assignment_survey_response_map).to receive(:email).with({body: {partial_name: "new_submission"},
                                                   subject: "A new submission is available for Test Assgt"},
                                                  participant, assignment).and_return(true)
      expect(response.email).to eq(true)
    end

    it 'calls email method on course survey response map' do
      course_survey_response_map = double('CourseSurveyResponseMap', reviewer_id: 1)
      allow(ResponseMap).to receive(:find).with(1).and_return(course_survey_response_map)
      allow(Participant).to receive(:find).with(1).and_return(participant)
      allow(course_survey_response_map).to receive(:survey?).and_return(true)
      allow(course_survey_response_map).to receive(:survey_parent).and_return(course)

      allow(course_survey_response_map).to receive(:email).with({body: {partial_name: "new_submission"},
                                                   subject: "A new submission is available for History"},
                                                  participant, course).and_return(true)
      expect(response.email).to eq(true)

    end

  end

Teammate Review Response Setup

This test ensures an email is sent upon submission of a teammate peer review.

let(:team) { build(:assignment_team, id: 1, name: 'team no name', assignment: assignment, users: [student], parent_id: 1) }
  let(:team1) { build(:assignment_team, id: 2, name: 'team has name', assignment: assignment, users: [student]) }
  let(:review_response_map) { build(:review_response_map, id: 1, assignment: assignment, reviewer: participant, reviewee: team) }
  let(:review_response_map1) do
    build :review_response_map,
          id: 2,
          assignment: assignment,
          reviewer: participant1,
          reviewee: team1,
          reviewed_object_id: 1,
          response: [response],
          calibrate_to: 0
  end
  let(:feedback) { FeedbackResponseMap.new(id: 1, reviewed_object_id: 1, reviewer_id: 1, reviewee_id: 1) }
  let(:participant) { build(:participant, id: 1, parent_id: 1, user: student) }
  let(:participant1) { build(:participant, id: 2, parent_id: 2, user: student1) }
  let(:assignment) { build(:assignment, id: 1, name: 'Test Assgt', rounds_of_reviews: 2) }
  let(:assignment1) { build(:assignment, id: 2, name: 'Test Assgt', rounds_of_reviews: 1) }
  let(:response) { build(:response, id: 1, map_id: 1, round: 1, response_map: review_response_map,  is_submitted: true) }
  let(:response1) { build(:response, id: 2, map_id: 1, round: 2, response_map: review_response_map) }
  let(:response2) { build(:response, id: 3, map_id: 1, round: nil, response_map: review_response_map, is_submitted: true) }
  let(:teammate_review_response_map) { TeammateReviewResponseMap.new(id: 1, reviewed_object_id: 1, reviewee_id: 1) }
  let(:student) { build(:student, id: 1, name: 'name', fullname: 'no one', email: 'expertiza@mailinator.com') }
  let(:student1) { build(:student, id: 2, name: "name1", fullname: 'no one', email: 'expertiza@mailinator.com') }

  before(:each) do
    allow(review_response_map).to receive(:response).and_return(response)
  end

Teammate Review Response Test

  it '#email' do
    allow(Participant).to receive(:find).with(1).and_return(participant)
    reviewee_user = participant.id

    allow(Assignment).to receive(:find).with(reviewee_user).and_return(assignment)
    allow(AssignmentTeam).to receive(:find).with(reviewee_user).and_return(team)
    allow(AssignmentTeam).to receive(:users).and_return(student)
    allow(User).to receive(:find).with(reviewee_user).and_return(student)
    allow(TeammateReviewResponseMap).to receive(:where).with(reviewed_object_id: 1).and_return([teammate_review_response_map])
    teammate_review_response_map.reviewee_id = reviewee_user
    defn = {body: {type: "Teammate Review", obj_name: assignment.name, first_name: student.fullname, partial_name: "new_submission"}, to: student.email}

    expect { teammate_review_response_map.email(defn, participant, assignment)}
        .to change { ActionMailer::Base.deliveries.count }.by 1
  end

suggested_topic_approved_message

Suggested Topic Approved Test This test ensures an email is sent upon approval of a suggested topic.

  it 'should send email with a suggested topic is approved' do
    ActionMailer::Base.deliveries.clear
    # Send the email, then test that it got queued
    email = Mailer.suggested_topic_approved_message(
      to: 'tluo@ncsu.edu',
      cc: 'tluo2@ncsu.edu',
      subject: "Suggested topic 'Test' has been approved",
      body: {
        approved_topic_name: 'assignment',
        proposer: 'User'
      }
    ).deliver_now

    ActionMailer::Base.deliveries.last.tap do |mail|
      expect(mail.from).to eq(["expertiza.development@gmail.com"])
      expect(mail.to).to eq(["expertiza.development@gmail.com"])
      expect(mail.bcc).to eq(["expertiza.development@gmail.com"])
      expect(mail.subject).to eq(email.subject)
      expect(mail.body).to eq(email.body)
    end
  end

notify_grade_conflict_message

Notify Grade Conflict Notification Setup This test ensures an email is sent when a score is outside the acceptable value.

  let(:assignment) {
    build(:assignment, name: "test_assignment")
  }

Notify Grade Conflict Notification Test

  it 'should send email to required email address when score is outside acceptable value ' do
    ActionMailer::Base.deliveries.clear
    # Send the email, then test that it got queued
    email = Mailer.notify_grade_conflict_message(
      to: 'tluo@ncsu.edu',
      subject: "Test",
      body: {
        assignment: assignment,
        type: 'review',
        reviewer_name: 'Reviewer',
        reviewee_name: 'Reviewee',
        new_score: 0.95,
        conflicting_response_url: 'https://expertiza.ncsu.edu/response/view?id=1',
        summary_url: 'https://expertiza.ncsu.edu/grades/view_team?id=1',
        assignment_edit_url: 'https://expertiza.ncsu.edu/assignments/1/edit'
      }
    ).deliver_now

    ActionMailer::Base.deliveries.last.tap do |mail|
      expect(mail.from).to eq(["expertiza.development@gmail.com"])
      expect(mail.to).to eq(["expertiza.development@gmail.com"])
      expect(mail.subject).to eq(email.subject)
      expect(mail.body).to eq(email.body)
    end
  end

Notify Instructor On Difference Setup This is a proxy method that calls the Mailer method to send e-mail to the instructor when a score is outside the acceptable value. This test verifies that the Mailer method is called with the expected arguments.

  let(:assignment) { build(:assignment, id: 1, name: 'Test Assgt', instructor: build(:instructor, email: 'tluo@ncsu.edu')) }
  let(:mail) { Mailer.notify_grade_conflict_message(
    to: 'tluo@ncsu.edu',
    subject: 'Expertiza Notification: A review score is outside the acceptable range',
    body: {
      reviewer_name: 'no one',
      type: 'review',
      reviewee_name: 'no one',
      new_score: 0.96,
      assignment: assignment,
      conflicting_response_url: 'https://expertiza.ncsu.edu/response/view?id=1',
      summary_url: 'https://expertiza.ncsu.edu/grades/view_team?id=2',
      assignment_edit_url: 'https://expertiza.ncsu.edu/assignments/1/edit'
    }
  )}

Notify Instructor On Difference Test

  describe '#notify_instructor_on_difference' do
    before(:each) do
      allow(review_response_map).to receive(:reviewer_id).and_return(1)
      allow(review_response_map).to receive(:reviewee_id).and_return(2)
    end

    context 'when a review score is outside the acceptable range' do
      it 'sends notification to assignment instructor' do
        allow(AssignmentParticipant).to receive(:find).with(1).and_return(participant)
        allow(participant).to receive(:user_id).and_return(2)
        allow(User).to receive(:find).with(2).and_return(participant.user)
        allow(AssignmentTeam).to receive(:find).with(2).and_return(team)
        allow(team).to receive(:participants).and_return([participant])
        allow(User).to receive(:find).with(2).and_return(participant.user)
        allow(participant).to receive(:parent_id).and_return(3)
        allow(Assignment).to receive(:find).with(3).and_return(assignment)
        allow(response).to receive(:total_score).and_return(96)
        allow(response).to receive(:maximum_score).and_return(100)
        allow(Mailer).to receive(:notify_grade_conflict_message).and_return(mail)
        expect(Mailer).to receive(:notify_grade_conflict_message).with(
          to: 'tluo@ncsu.edu',
          subject: 'Expertiza Notification: A review score is outside the acceptable range',
          body: {
            reviewer_name: 'no one',
            type: 'review',
            reviewee_name: 'no one',
            new_score: 0.96,
            assignment: assignment,
            conflicting_response_url: 'https://expertiza.ncsu.edu/response/view?id=1',
            summary_url: 'https://expertiza.ncsu.edu/grades/view_team?id=1',
            assignment_edit_url: 'https://expertiza.ncsu.edu/assignments/1/edit'
          }
        )
        response.notify_instructor_on_difference
      end
    end
  end

Test Result

77 examples, 0 failures

Team

Josh Beerel (jbeerel)

Joshua Horwitz (jahorwitz)

Anjaney C Mahajan (acmahaja)