# Copyright (c) 2013-2014 Public Library of Science
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

require 'spec_helper'

include OpenEvaluation

describe EvaluationsController do
  routes { OpenEvaluation::Engine.routes }

  before do
    @user = create(:user)
    login_user @user
    @evaluation = create(:evaluation, user: @user)
  end

  shared_examples "sorting and searching" do

    it "grabs all created evaluations" do
      get_action
      expect(assigns(:evaluations)).to be_present
      expect(assigns(:evaluations).first).to be_a(Evaluation)
    end

    it "sorts the most completed evaluations first by default" do
      Evaluation.destroy_all
      unstarted = create :unstarted_evaluation
      started = create :started_evaluation
      completed = create :completed_evaluation
      with_contact = create :evaluation_with_contact_info
      newer_with_contact = create :evaluation_with_contact_info, contact_info_added_at: Date.today
      saved = create :saved_evaluation
      logged_in = create :logged_in_evaluation

      get_action
      evaluations = assigns(:evaluations).all

      expect(evaluations.shift).to eq newer_with_contact
      expect(evaluations.shift).to eq with_contact
      expect(evaluations.shift).to eq completed
      expect(evaluations.shift).to eq saved
      expect(evaluations.shift).to eq started
      expect(evaluations.shift).to eq logged_in
      expect(evaluations.shift).to eq unstarted
    end

    it "takes a sort option" do
      Evaluation.destroy_all
      evaluation1 = create :evaluation, doi: "X"
      evaluation2 = create :evaluation, doi: "A"
      evaluation3 = create :evaluation, doi: "W"

      get_action sort:'doi'

      expect(assigns[:evaluations]).to eq([ evaluation2, evaluation3, evaluation1])
    end

    it "takes can sort descending" do
      Evaluation.destroy_all
      evaluation1 = create :evaluation, doi: "X"
      evaluation2 = create :evaluation, doi: "A"
      evaluation3 = create :evaluation, doi: "W"

      get_action sort:'doi', direction:'desc'

      expect(assigns[:evaluations]).to eq([ evaluation1, evaluation3, evaluation2])
    end

    it "takes a search parameter" do
      Evaluation.destroy_all
      evaluation1 = create :evaluation, doi: "XXX"
      evaluation2 = create :evaluation, doi: "AAA"
      evaluation3 = create :evaluation, doi: "WWW"

      get_action search:'aaa'

      expect(assigns[:evaluations]).to eq([ evaluation2 ])
    end

  end

  describe "#index" do

    def get_action(opts={})
      get :index, opts
    end

    context "as admin" do

      before do
        @user.admin = true
        @user.save
      end

      it "renders the template" do
        get_action
        expect(response).to render_template(:index)
      end

      it_behaves_like "sorting and searching"

      it "takes a page parameter" do
        Evaluation.destroy_all
        evaluation1 = create :evaluation, doi: "A"
        evaluation2 = create :evaluation, doi: "B"
        evaluation3 = create :evaluation, doi: "C"
        evaluation4 = create :evaluation, doi: "D"
        Evaluation.stub! per_page:3

        get_action page:2

        expect(assigns[:evaluations]).to eq([ evaluation4 ])
      end

      describe "rendering" do
        render_views
        it "displays pertinent information about the evaluation's user" do
          evaluation = Evaluation.last
          get_action
          expect(response.body).to match /#{evaluation.user.name}/
          expect(response.body).to match /#{evaluation.user.email}/
        end
      end

    end

    context "as regular user" do
      it "informs the user they are not permitted to view this page" do
        get_action
        expect(flash[:notice]).to be_present
        expect(flash[:notice]).to match /not permitted/
      end
      it "redirects to the root path" do
        get_action
        expect(response).to redirect_to root_path
      end
    end
  end

  describe "#export" do

    def get_action(opts={})
      post :export, opts
    end

    context "as admin" do

      before do
        @user.admin = true
        @user.save
      end

      it_behaves_like "sorting and searching"

      it "takes a from_date parameter" do
        Evaluation.destroy_all
        evaluation1 = create :evaluation, created_at:Date.new(2001,10,31)
        evaluation2 = create :evaluation, created_at:Date.new(2001,11, 1)

        get_action export:{from_date:'11/1/2001'}

        expect(assigns[:evaluations]).to eq([ evaluation2 ])
      end

      it "takes a to_date parameter" do
        Evaluation.destroy_all
        evaluation1 = create :evaluation, created_at:Date.new(2001,10,31)
        evaluation2 = create :evaluation, created_at:Date.new(2001,11, 1)

        get_action export:{to_date:'10/31/2001'}

        expect(assigns[:evaluations]).to eq([ evaluation1 ])
      end

      it "should include an attachment" do
        get_action

        expect(response.content_type).to eq('application/vnd.ms-excel')
        expect(response.header["Content-Disposition"]).to eq('attachment; filename="evaluations.xls"')
        expect(response.header["Content-Transfer-Encoding"]).to eq('binary')

        expect(response.body).to be_true
      end

    end

    context "as regular user" do
      it "informs the user they are not permitted to view this page" do
        get_action
        expect(flash[:notice]).to be_present
        expect(flash[:notice]).to match /not permitted/
      end
      it "redirects to the root path" do
        get_action
        expect(response).to redirect_to root_path
      end
    end
  end

  describe "#all_results" do
    before do
      @user.admin = true
      @user.save

      @unstarted = create :unstarted_evaluation
      @started = create :started_evaluation
      @completed = create :completed_evaluation
      @with_contact = create :evaluation_with_contact_info, evaluation_completed_at: nil
      @saved = create :saved_evaluation
      @logged_in = create :logged_in_evaluation
      get :all_results
      @evaluations = assigns(:evaluations)
    end
    it "includes completed evaluations" do
      expect(@evaluations).to include(@completed)
    end
    it "includes incomplete evaluations that have contact info" do
      expect(@evaluations).to include(@with_contact)
    end
    it "excludes others" do
      expect(@evaluations).to have(2).items
    end
  end

  describe "#new" do
    render_views
    context "as admin" do
      let(:researcher) { create :user }
      before do
        @user.admin = true
        @user.save
      end
      it "renders the new evaluation page" do
        get :new, researcher_id: researcher.id
        expect(response).to render_template :new
      end
      it "assigns the requested researcher" do
        get :new, researcher_id: researcher.id
        expect(assigns(:researcher).id).to eql(researcher.id)
      end
      it "displays the user's name" do
        get :new, researcher_id: researcher.id
        expect(response.body).to match /#{researcher.name}/
      end

      it "displays the manual email subject" do
        get :new, researcher_id: researcher.id
        expect(assigns(:evaluation).onboarding_subject).to match(/Invitation to participate in Open Evaluation/)
      end

      it "displays the manual email content" do
        get :new, researcher_id: researcher.id
        expect(assigns(:evaluation).onboarding_content).to match(/remote user beta testing/)
      end

    end

    context "as a regular user" do
      it "informs the user they are not permitted to view this page" do
        get :new
        expect(flash[:notice]).to be_present
        expect(flash[:notice]).to match /not permitted/
      end
      it "redirects to the root path" do
        get :new
        expect(response).to redirect_to :root
      end
    end
  end

  describe "#create" do

    before do
      @user.admin = true
      @user.save
    end

    let(:researcher) { create(:user) }

    context "valid attributes" do
      it "creates an evaluation" do
        expect {
          post :create, evaluation: {user_id: researcher.id, doi: "asdf", onboarding_content: "faked"}
        }.to change(Evaluation, :count).by(1)
      end
      it "attaches the evaluation to the researcher" do
        post :create, evaluation: {user_id: researcher.id, doi: "asdf", onboarding_content: "faked"}
        evaluation = Evaluation.last
        expect(evaluation.user).to eql(researcher)
      end
      it "marks the evaluation as manually generated" do
        post :create, evaluation: {user_id: researcher.id, doi: "asdf", onboarding_content: "faked"}
        evaluation = Evaluation.last
        expect(evaluation.automatically_generated?).to be_false
      end
      it "redirects to the users listing" do
        post :create, evaluation: {user_id: researcher.id, doi: "asdf", onboarding_content: "faked"}
        expect(response).to redirect_to :users
      end

      it "sets a flash notice" do
        post :create, evaluation: {user_id: researcher.id, doi: "asdf", onboarding_content: "faked"}
        expect(flash[:notice]).to be_present
        expect(flash[:notice]).to match /invited successfully/
      end

      it "sends an email" do
        expect {
        post :create, evaluation: {user_id: researcher.id, doi: "asdf", onboarding_content: "faked"}
        }.to change{ActionMailer::Base.deliveries.count}.by(1)
      end

      it "the email should contain the manual subject line" do
        post :create, evaluation: {user_id: researcher.id, doi: "asdf", onboarding_subject:'123-456'}
        expect( ActionMailer::Base.deliveries.last.subject ).to match(/123-456/)
      end

      it "should replace fields" do
        post :create, evaluation: {user_id: researcher.id, doi: "asdf", phone_number:'123-456', onboarding_content: "--%%PHONE_NUMBER%%--"}
        expect(ActionMailer::Base.deliveries.last.to_s).to match(/--123-456--/)
      end

      context "with bad DOI" do
        render_views
        before do
          Evaluation.any_instance.unstub(:retrieve_doi_metadata)
          Crossref.stub(:new) { raise "Bad request" }
          post :create, evaluation: {user_id: researcher.id, doi: "bunk", onboarding_content: "fake"}
        end
        it "re-renders the new evaluation page" do
          expect(response).to render_template :new
        end
        it "renders a flash alert" do
          expect(flash[:alert]).to be_present
        end
      end

      context "as a regular user" do

        before do
          @user.admin = false
        end

        it "informs the user they are not permitted to view this page" do
          post :create, evaluation: {user_id: researcher.id, doi: "asdf", onboarding_content: "faked"}
          expect(flash[:notice]).to be_present
          expect(flash[:notice]).to match /not permitted/
        end

        it "redirects to the root path" do
          post :create, evaluation: {user_id: researcher.id, doi: "asdf", onboarding_content: "faked"}
          expect(response).to redirect_to :root
        end

      end

    end

    context "invalid attributes" do
      it "does not create a evaluation" do
        expect {
          post :create, evaluation: {user_id: User.first.id}
        }.to change(Evaluation, :count).by(0)
      end
      it "re-renders the new evaluation page" do
        post :create, evaluation: {user_id: User.first.id}
        expect(response).to render_template :new
      end
      it "sets a flash alert" do
        post :create, evaluation: {user_id: User.first.id}
        expect(flash[:alert]).to be_present
        expect(flash[:alert]).to match /Unable to create evaluation/
      end
    end
  end

  describe "#batch" do
    render_views

    context "as admin" do

      before do
        @user.admin = true
        @user.save
      end

      it "renders the batch upload page" do
        get :batch
        expect(response).to render_template :batch
      end

      it "displays the manual email subject" do
        get :batch
        expect(assigns(:evaluation).onboarding_subject).to match(/Invitation to participate in Open Evaluation/)
      end

      it "displays the manual email content" do
        get :batch
        expect(assigns(:evaluation).onboarding_content).to match(/remote user beta testing/)
      end

      it "has replacement text for the user name" do
        get :batch
        expect(assigns(:evaluation).onboarding_content).to match(/%%USER_NAME%%/)
      end

    end

    context "as a regular user" do
      it "informs the user they are not permitted to view this page" do
        get :batch
        expect(flash[:notice]).to be_present
        expect(flash[:notice]).to match /not permitted/
      end
      it "redirects to the root path" do
        get :batch
        expect(response).to redirect_to :root
      end
    end
  end

  describe "#batch_create" do

    before do
      @user.admin = true
      @user.save
    end

    context "valid attributes" do

      it "calls the importer" do
        EvaluationImporter.should_receive(:import_from_xls!).with('excel_file', {'doi' => 'asdf'})
        post :batch_create, uploads:[:excel_file], evaluation:{doi:'asdf'}
      end

      it "redirects to the evaluation list and displays a message" do
        EvaluationImporter.should_receive(:import_from_xls!).and_return(123)
        post :batch_create, uploads:[:excel_file], evaluation:{doi:'foi'}
        expect(response).to redirect_to(evaluations_path)
        expect(flash.notice).to eq('123 users were invited successfully')
      end

    end

    context "failure" do

      it "renders the batch page and displays an error" do
        EvaluationImporter.should_receive(:import_from_xls!).and_return('A failure message')
        post :batch_create, uploads:[:excel_file], evaluation:{doi:'doi'}
        expect(response).to render_template(:batch)
        expect(flash.alert).to eq('Unable to create evaluations: A failure message')
      end

    end

    context "as a regular user" do

      before do
        @user.admin = false
      end

      it "informs the user they are not permitted to view this page" do
        post :batch_create
        expect(flash[:notice]).to be_present
        expect(flash[:notice]).to match /not permitted/
      end

      it "redirects to the root path" do
        post :batch_create
        expect(response).to redirect_to :root
      end

    end

  end

  describe "#show" do
    render_views
    context "as admin" do
      before do
        @user.admin = true
        @user.save
      end
      it "displays the evaluation" do
        get :show, id: @evaluation.id
        expect(response).to be_success
        expect(response).to render_template :show
        expect(assigns(:evaluation)).to eq(@evaluation)
      end
      it "displays the milestones" do
        get :show, id: @evaluation.id
        expect(response.body).to have_tag "h4", text: /Milestones/
      end
      context "contact info exists" do
        before do
          create(:contact, evaluation: @evaluation, phone_number: "555", video_account_info: "myscreenname", contact_info: "Hiya bob.")
        end
        it "assigns contact" do
          get :show, id: @evaluation.id
          expect(assigns(:contact)).to be_present
          expect(assigns(:contact).evaluation_id).to eq @evaluation.id
        end
        it "displays the contact info section" do
          get :show, id: @evaluation.id
          expect(response.body).to have_tag "h4", text: /Contact Info/
        end
        it "displays the phone number content" do
          get :show, id: @evaluation.id
          expect(response.body).to have_tag "i", text: /555/
        end
        it "displays the video account info content" do
          get :show, id: @evaluation.id
          expect(response.body).to have_tag "i", text: /myscreenname/
        end
        it "displays the contact info content" do
          get :show, id: @evaluation.id
          expect(response.body).to have_tag "i", text: /Hiya bob/
        end
      end
      context "contact info does not exist" do
        it "does not assign contact" do
          get :show, id: @evaluation.id
          expect(assigns(:contact)).to be_nil
          expect(response).to be_success
        end
      end

      it "assigns the evaluation comments" do
        comment = create(:evaluation_comment, evaluation: @evaluation, body: "XYZ FACE")
        get :show, id: @evaluation.id
        expect(assigns(:evaluation_comments)).to be_present
        expect(assigns(:evaluation_comments)).to eq [comment]
      end
      it "displays the evaluation comments" do
        create(:evaluation_comment, evaluation: @evaluation, body: "XYZ FACE")
        get :show, id: @evaluation.id
        expect(response.body).to match /XYZ FACE/
      end
      it "displays a form for adding a evaluation comments" do
        get :show, id: @evaluation.id
        expect(response.body).to have_tag "form"
      end
    end

    context "as regular owner of the evaluation" do
      it "displays the evaluation" do
        get :show, id: @evaluation.id
        expect(response).to be_success
        expect(response).to render_template :show
        expect(assigns(:evaluation)).to eq(@evaluation)
      end
      it "does not display the milestones" do
        get :show, id: @evaluation.id
        expect(response.body).to_not have_tag "h4", text: /Milestones/
      end
      it "does not display the contact info" do
        create(:contact, evaluation: @evaluation)
        get :show, id: @evaluation.id
        expect(response.body).to_not have_tag "h4", text: /Contact Info/
      end
      it "does not display evaluation comments" do
        create(:evaluation_comment, evaluation: @evaluation, body: "This is my awesome comment")
        expect(@evaluation.evaluation_comments).to have(1).item
        get :show, id: @evaluation.id
        expect(response.body).to_not match /This is my awesome comment/
      end
      it "does not display a form for adding evaluation comments" do
        get :show, id: @evaluation.id
        expect(response.body).to_not have_tag "form"
      end
    end
  end

  describe "#edit" do
    render_views
    let(:evaluation) { create(:evaluation, user: @user) }
    it "retrieves the requested evaluation" do
      get :edit, id: evaluation.id
      assigned_evaluation = assigns(:evaluation)

      expect(assigned_evaluation).to be_present
      expect(assigned_evaluation).to be_a Evaluation
      expect(assigned_evaluation.id).to eql evaluation.id
    end
    it "renders the edit page" do
      get :edit, id: evaluation.id
      expect(response).to render_template :edit
    end
    it "includes a submit button" do
      get :edit, id: evaluation.id
      expect(response.body).to have_tag "input[type=submit]"
    end

    context "evaluation has not yet been started" do
      it "sets the evaluation started at" do
        Evaluation.any_instance.should_receive(:evaluation_started!).once
        get :edit, id: evaluation.id
      end
    end
    context "evaluation has previously been started" do
      before do
        evaluation.evaluation_started!
      end
      it "does not change the evaluation_started_at" do
        Evaluation.any_instance.should_receive(:evaluation_started!).never
        get :edit, id: evaluation.id
      end

    end
  end

  describe "#update" do
    let(:evaluation) { create(:completed_evaluation, user: @user) }
    it "redirects to the new contact page" do
      post :update, id: evaluation.id, evaluation: {}
      expect(response).to redirect_to new_contact_path(evaluation_id: evaluation.id)
    end

    context "contact record exists" do
      it "redirects to the edit contact page" do
        evaluation.create_contact!(contact_info: "This is the text I entered last time")
        post :update, id: evaluation.id, evalution: {}
        expect(response).to redirect_to edit_contact_path(evaluation.contact)
      end
    end

    context "successful update" do
      it "updates the evaluation_saved_at" do
        post :update, id: evaluation.id, evaluation: {}
        expect {
          evaluation.reload
        }.to change(evaluation, :evaluation_saved_at)
      end

      describe "research network names" do
        it "creates an associated research network for each name" do
          evaluation = create(:completed_evaluation, user: @user)
          expect {
            post :update, id: evaluation.id, evaluation: {researcher_names: "Bob Smith, Jane Doe"}
          }.to change(ResearchNetwork, :count).by(2)

          evaluation.reload
          network_names = evaluation.research_networks.map(&:name)
          expect(network_names).to include "Bob Smith"
          expect(network_names).to include "Jane Doe"
        end
        it "handles the case where no researcher names are submitted" do
          expect {
            post :update, id: evaluation.id, evaluation: {researcher_names: ""}
          }.to_not raise_error
        end

        context "research networks already exist" do
          it "removes old research networks" do
            evaluation = create(:completed_evaluation, user: @user)
            expect(evaluation).to have(2).research_networks
            old_name = evaluation.research_networks.first.name
            post :update, id: evaluation.id, evaluation: {researcher_names: "a, b"}
            evaluation.reload
            expect(evaluation).to have(2).research_networks
            expect(evaluation.researcher_names).to_not include(old_name)
            expect(evaluation.researcher_names).to include("a")
            expect(evaluation.researcher_names).to include("b")
          end
        end
      end

      context "signed_as = yourself" do
        before do
          post :update, id: evaluation.id, evaluation: {signed_as: "yourself", accepted_credentials_list: "a, b, c"}
          evaluation.reload
        end
        it "persists signed_as" do
          expect(evaluation.signed_as).to eq "yourself"
        end
        it "does not set accepted_credentials_list" do
          expect(evaluation.accepted_credentials_list).to be_nil
        end
      end
      context "signed_as = credentials_only" do
        before do
          post :update, id: evaluation.id, evaluation: {signed_as: "credentials_only", accepted_credentials_list: "a, b, c"}
          evaluation.reload
        end
        it "persists signed_as" do
          expect(evaluation.signed_as).to eq "credentials_only"
        end
        it "sets accepted_credentials_list" do
          expect(evaluation.accepted_credentials_list).to eq "a, b, c"
        end
      end
      context "signed_as = completely_anonymous" do
        before do
          post :update, id: evaluation.id, evaluation: {signed_as: "completely_anonymous", accepted_credentials_list: "a, b, c"}
          evaluation.reload
        end
        it "persists signed_as" do
          expect(evaluation.signed_as).to eq "completely_anonymous"
        end
        it "does not set accepted_credentials_list" do
          expect(evaluation.accepted_credentials_list).to be_nil
        end
      end
    end

    context "update fails" do
      before do
        Evaluation.any_instance.stub(:update_attributes).and_return(false)
      end
      it "re-renders the edit form" do
        post :update, id: evaluation.id, evaluation: {}
        expect(response).to render_template :edit
      end
      it "sets a flash alert" do
        post :update, id: evaluation.id, evaluation: {}
        expect(flash[:alert]).to be_present
        expect(flash[:alert]).to match /unable to update/i
      end
      it "does not update the evaluation_saved_at" do
        evaluation.reload # force reload of old evaluation_saved_at
        post :update, id: evaluation.id, evaluation: {}
        expect {
          evaluation.reload
        }.to_not change(evaluation, :evaluation_saved_at)
      end
    end
  end

  describe "#new_reminder" do
    render_views
    context "as regular user" do
      it "informs the user they are not permitted to view this page" do
        get :new_reminder, id: @evaluation.id
        expect(flash[:notice]).to be_present
        expect(flash[:notice]).to match /not permitted/
      end
      it "redirects to the root path" do
        get :new_reminder, id: @evaluation.id
        expect(response).to redirect_to :root
      end
    end

    context "as an admin user" do
      before do
        login_user(create(:admin))
      end
      it "renders the new reminder template" do
        get :new_reminder, id: @evaluation.id
        expect(response).to be_success
        expect(response).to render_template :new_reminder
      end
      it "retrieves the evaluation" do
        get :new_reminder, id: @evaluation.id
        expect(assigns(:evaluation)).to be_present
        expect(assigns(:evaluation).id).to eq @evaluation.id
      end
      it "renders the default reminder content" do
        get :new_reminder, id: @evaluation.id
        expect(response.body).to match /We recently sent you an invitation/
      end
      it "retrieves the default email content" do
        mailer_stub = stub()
        mailer_stub.stub(:html_part).and_return(stub(:body => "asdf"))
        UserMailer.should_receive(:evaluation_reminder) { mailer_stub }

        get :new_reminder, id: @evaluation.id
        expect(assigns(:email_content)).to eql("asdf")
      end
      it "includes the correct login link" do
        get :new_reminder, id: @evaluation.id
        expect(assigns(:email_content)).to include('%%LOGIN_LINK%%')
      end

    end

  end

  describe "#start" do

    before do
      logout_user
      @evaluation = create(:evaluation)
      @user = @evaluation.user
      @token = "#{@evaluation.id}-#{@user.login_hash}"
    end

    describe "on success" do

      it "logs the user in" do
        get :start, token:@token
        expect(controller.current_user).to eq(@user)
      end

      it "Track the user login" do
        Evaluation.any_instance.should_receive(:researcher_logged_in!)
        get :start, token:@token
      end

      it "sets the evaluation id" do
        get :start, token:@token
        expect(session[:evaluation_id]).to eq(@evaluation.id)
      end

      it "redirects to the avaluation page" do
        get :start, token:@token

        expect(response).to redirect_to( edit_evaluation_path(@evaluation) )
        # expect(flash[:notice]).to be_present
      end

    end

    describe "failure scenarios" do

      def test(token=@token)
        get :start, token: token

        expect(response).to redirect_to(root_path)
        expect(flash[:alert]).to eq('Invalid credentials')
      end

      it "should fail if the evaluation id is invalid" do
        test("0000-#{@user.login_hash}")
      end

      it "should fail if the login hash does not match" do
        test("#{@evaluation.id}-#{@user.login_hash}-xxx")
      end

      it "should fail if the user is an admin" do
        @user.toggle_admin!
        test
      end

      it "should fail if the user is deleted" do
        @user.soft_delete!
        test
      end

    end

  end

  describe "#send_reminder" do
    context "as a regular user" do
      it "does not send a reminder" do
        UserMailer.should_receive(:evalution_reminder).never
        post :send_reminder, id: @evaluation.id, evaluation: {reminder_content: "asdf"}
      end
      it "redirects to the root path" do
        post :send_reminder, id: @evaluation.id, evaluation: {reminder_content: "asdf"}
        expect(response).to redirect_to :root
      end
    end

    context "as an admin user" do
      before do
        login_user(create(:admin))
      end
      it "sends a reminder" do
        Evaluation.any_instance.should_receive(:send_reminder)
        post :send_reminder, id: @evaluation.id, evaluation: {reminder_content: "asdf"}
      end
      it "sends the override content" do
        Evaluation.any_instance.should_receive(:send_reminder).with("overridden content")
        post :send_reminder, id: @evaluation.id, evaluation: {reminder_content: "overridden content"}
      end
      it "redirects back to the evaluations index" do
        post :send_reminder, id: @evaluation.id, evaluation: {reminder_content: "asdf"}
        expect(response).to redirect_to :evaluations
      end
    end

  end

end
