<commit_before>require 'rails_helper'

RSpec.describe Admin::PetitionsController, type: :controller do
  include ActiveJob::TestHelper

  before :each do
    creator_signature = FactoryGirl.create(:signature, :email => '<EMAIL>')
    @petition = FactoryGirl.create(:sponsored_petition, :creator_signature => creator_signature)
  end

  describe "not logged in" do
    describe "GET 'edit'" do
      it "redirects to the login page" do
        get :edit, :id => @petition.id
        expect(response).to redirect_to("https://petition.parliament.uk/admin/login")
      end
    end

    describe "GET 'threshold'" do
      it "redirects to the login page" do
        get :threshold
        expect(response).to redirect_to("https://petition.parliament.uk/admin/login")
      end
    end

    describe "GET 'index'" do
      it "redirects to the login page" do
        get :index
        expect(response).to redirect_to("https://petition.parliament.uk/admin/login")
      end
    end

    describe "GET 'show'" do
      it "redirects to the login page" do
        get :show, :id => @petition.id
        expect(response).to redirect_to("https://petition.parliament.uk/admin/login")
      end
    end
  end

  context "logged in as moderator user but need to reset password" do
    before :each do
      @user = FactoryGirl.create(:moderator_user, :force_password_reset => true)
      login_as(@user)
    end

    it "redirects to edit profile page" do
      expect(@user.has_to_change_password?).to be_truthy
      get :edit, :id => @petition.id
      expect(response).to redirect_to("https://petition.parliament.uk/admin/profile/#{@user.id}/edit")
    end
  end

  describe "logged in as moderator user" do
    before :each do
      @user = FactoryGirl.create(:moderator_user)
      login_as(@user)

      @p1 = FactoryGirl.create(:open_petition)
      @p1.update_attribute(:signature_count, 11)
      @p2 = FactoryGirl.create(:open_petition)
      @p2.update_attribute(:signature_count, 10)
      @p3 = FactoryGirl.create(:open_petition)
      @p3.update_attribute(:signature_count, 9)
      @p4 = FactoryGirl.create(:closed_petition)
      @p4.update_attribute(:signature_count, 20)

      allow(Site).to receive(:threshold_for_debate).and_return(10)
    end

    it "returns all petitions that have more than the threshold number of signatures in ascending count order" do
      get :threshold
      expect(assigns[:petitions]).to eq([@p2, @p1, @p4])
    end

    it "assigns petition" do
      get :edit_response, :id => @p1.id
      expect(assigns[:petition]).to eq(@p1)
    end

    context 'update internal response' do
      it "updates internal response and response required flag" do
        patch :update_response, :id => @p1.id, :petition => {:internal_response => 'This is popular', :response_required => '1'}
        @p1.reload
        expect(@p1.internal_response).to eq('This is popular')
        expect(@p1.response_required).to be_truthy
      end
    end

    context "update_response" do
      def do_patch(options = {})
        patch :update_response, :id => @p1.id, :petition => { :response => 'Doh!', :response_summary => 'Summary', :email_signees => '1'}.merge(options)
      end
      it "updates response and email signees flag with true" do
        do_patch
        assert_enqueued_jobs 1
        expect(response).to redirect_to("https://petition.parliament.uk/admin/petitions")
        @p1.reload
        expect(@p1.response).to eq('Doh!')
        expect(@p1.email_requested_at).not_to be_nil
      end

      it "updates response and email signees flag with false" do
        do_patch(:email_signees => '0')
        assert_enqueued_jobs 0
        @p1.reload
        expect(@p1.response).to eq('Doh!')
        expect(@p1.email_requested_at).to be_nil
      end

      it "fails to update response and email signees flag due to validation error" do
        do_patch(:response => '', :email_signees => '1')
        assert_enqueued_jobs 0
        expect(response).to be_success
        @p1.reload
        expect(@p1.email_requested_at).to be_nil
      end

      context "email out threshold update response" do
        before do
          @signature =  FactoryGirl.create(:pending_signature,
                          name: 'Jason',
                          email: '<EMAIL>',
                          notify_by_email: true
                        )

          @petition = FactoryGirl.create(:open_petition,
                        action: 'Make me the PM',
                        creator_signature: @signature
                      )

          6.times do |i|
            attributes = {
              name: "Jason #{i}",
              email: "<EMAIL>",
              notify_by_email: true,
              petition: @petition
            }

            s = FactoryGirl.create(:pending_signature, attributes)
            s.validate!
          end

          3.times do |i|
            attributes = {
              name: "Jason #{i}",
              email: "<EMAIL>",
              notify_by_email: false,
              petition: @petition
            }

            s = FactoryGirl.create(:pending_signature, attributes)
            s.validate!
          end

          2.times do |i|
            attributes = {
              name: "Jason #{i}",
              email: "<EMAIL>",
              notify_by_email: true,
              petition: @petition
            }

            FactoryGirl.create(:pending_signature, attributes)
          end

          @petition.reload
        end

        it "sets up a delayed job" do
          assert_enqueued_jobs 1 do
            patch :update_response, :id => @petition.id, :petition => { :response => 'Doh!', :response_summary => 'Summary', :email_signees => '1'}
          end
        end

        it "sets the email signees flag to false when the job runs" do
          perform_enqueued_jobs do
            patch :update_response, :id => @petition.id, :petition => { :response => 'Doh!', :response_summary => 'Summary', :email_signees => '1'}
            @petition.reload
            expect(@petition.email_requested_at).not_to be_nil
            @petition.signatures.validated.notify_by_email.each do |signature|
              expect(signature.last_emailed_at).to eq(@petition.email_requested_at)
            end
          end
        end

        it "emails out to the validated signees who have opted in when the delayed job runs" do
          perform_enqueued_jobs do
            no_emails = ActionMailer::Base.deliveries.length
            patch :update_response, :id => @petition.id, :petition => { :response => 'Doh!', :response_summary => 'Summary', :email_signees => '1'}
            expect(ActionMailer::Base.deliveries.length - no_emails).to eq(7)
            expect(ActionMailer::Base.deliveries[no_emails].to).to eq(["<EMAIL>"])
            expect(ActionMailer::Base.deliveries[no_emails].subject).to match(/The petition 'Make me the PM' has reached 10 signatures/)
            expect(ActionMailer::Base.deliveries.last.to).to eq(["<EMAIL>"])
          end
        end
      end
    end

    context "updating scheduled debate date" do
      let!(:petition) { FactoryGirl.create(:open_petition) }

      context "edit_scheduled_debate_date" do
        it "renders a view to update scheduled debate date" do
          get :edit_scheduled_debate_date, :id => petition.id
          expect(response).to render_template("edit_scheduled_debate_date")
        end

        shared_examples_for 'trying to view edit scheduled debate date view for a petition in the wrong state' do
          it 'raises a 404 error' do
            expect {
              get :edit_scheduled_debate_date, id: petition.id
            }.to raise_error ActiveRecord::RecordNotFound<commit_msg>Reword and use new API in admin/petitions_controller_spec<commit_after>require 'rails_helper'

RSpec.describe Admin::PetitionsController, type: :controller do
  include ActiveJob::TestHelper

  before :each do
    creator_signature = FactoryGirl.create(:signature, :email => '<EMAIL>')
    @petition = FactoryGirl.create(:sponsored_petition, :creator_signature => creator_signature)
  end

  describe "not logged in" do
    describe "GET 'edit'" do
      it "redirects to the login page" do
        get :edit, :id => @petition.id
        expect(response).to redirect_to("https://petition.parliament.uk/admin/login")
      end
    end

    describe "GET 'threshold'" do
      it "redirects to the login page" do
        get :threshold
        expect(response).to redirect_to("https://petition.parliament.uk/admin/login")
      end
    end

    describe "GET 'index'" do
      it "redirects to the login page" do
        get :index
        expect(response).to redirect_to("https://petition.parliament.uk/admin/login")
      end
    end

    describe "GET 'show'" do
      it "redirects to the login page" do
        get :show, :id => @petition.id
        expect(response).to redirect_to("https://petition.parliament.uk/admin/login")
      end
    end
  end

  context "logged in as moderator user but need to reset password" do
    before :each do
      @user = FactoryGirl.create(:moderator_user, :force_password_reset => true)
      login_as(@user)
    end

    it "redirects to edit profile page" do
      expect(@user.has_to_change_password?).to be_truthy
      get :edit, :id => @petition.id
      expect(response).to redirect_to("https://petition.parliament.uk/admin/profile/#{@user.id}/edit")
    end
  end

  describe "logged in as moderator user" do
    before :each do
      @user = FactoryGirl.create(:moderator_user)
      login_as(@user)

      @p1 = FactoryGirl.create(:open_petition)
      @p1.update_attribute(:signature_count, 11)
      @p2 = FactoryGirl.create(:open_petition)
      @p2.update_attribute(:signature_count, 10)
      @p3 = FactoryGirl.create(:open_petition)
      @p3.update_attribute(:signature_count, 9)
      @p4 = FactoryGirl.create(:closed_petition)
      @p4.update_attribute(:signature_count, 20)

      allow(Site).to receive(:threshold_for_debate).and_return(10)
    end

    it "returns all petitions that have more than the threshold number of signatures in ascending count order" do
      get :threshold
      expect(assigns[:petitions]).to eq([@p2, @p1, @p4])
    end

    it "assigns petition" do
      get :edit_response, :id => @p1.id
      expect(assigns[:petition]).to eq(@p1)
    end

    context 'update internal response' do
      it "updates internal response and response required flag" do
        patch :update_response, :id => @p1.id, :petition => {:internal_response => 'This is popular', :response_required => '1'}
        @p1.reload
        expect(@p1.internal_response).to eq('This is popular')
        expect(@p1.response_required).to be_truthy
      end
    end

    context "update_response" do
      def do_patch(options = {})
        patch :update_response, :id => @p1.id, :petition => { :response => 'Doh!', :response_summary => 'Summary', :email_signees => '1'}.merge(options)
      end

      it "updates response and stamp the 'government_response' email requested receipt timestamp when email signees flag is true" do
        do_patch
        assert_enqueued_jobs 1
        expect(response).to redirect_to("https://petition.parliament.uk/admin/petitions")
        @p1.reload
        expect(@p1.response).to eq('Doh!')
        expect(@p1.get_email_requested_at_for('government_response')).not_to be_nil
      end

      it "updates response and not stamp the 'governent_rsponse' email requested receipt timestamp when email signees flag is false" do
        do_patch(:email_signees => '0')
        assert_enqueued_jobs 0
        @p1.reload
        expect(@p1.response).to eq('Doh!')
        expect(@p1.get_email_requested_at_for('government_response')).to be_nil
      end

      it "doest not update response or stamp the 'government_response' email requested receipt timestamp if there is a validation error" do
        do_patch(:response => '', :email_signees => '1')
        assert_enqueued_jobs 0
        expect(response).to be_success
        @p1.reload
        expect(@p1.get_email_requested_at_for('government_response')).to be_nil
      end

      context "email out threshold update response" do
        before do
          signature =  FactoryGirl.create(:pending_signature,
                          name: 'Jason',
                          email: '<EMAIL>',
                          notify_by_email: true
                        )

          @petition = FactoryGirl.create(:open_petition,
                        action: 'Make me the PM',
                        creator_signature: signature
                      )

          3.times do |i|
            attributes = {
              name: "Jason #{i}",
              email: "<EMAIL>",
              notify_by_email: true,
              petition: @petition
            }

            s = FactoryGirl.create(:pending_signature, attributes)
            s.validate!
          end

          2.times do |i|
            attributes = {
              name: "Jason #{i+3}",
              email: "<EMAIL>",
              notify_by_email: false,
              petition: @petition
            }

            s = FactoryGirl.create(:pending_signature, attributes)
            s.validate!
          end

          2.times do |i|
            attributes = {
              name: "Jason #{i+5}",
              email: "<EMAIL>",
              notify_by_email: true,
              petition: @petition
            }

            FactoryGirl.create(:pending_signature, attributes)
          end

          @petition.reload
        end

        it "queues a job to process the emails" do
          assert_enqueued_jobs 1 do
            patch :update_response, :id => @petition.id, :petition => { :response => 'Doh!', :response_summary => 'Summary', :email_signees => '1'}
          end
        end

        it "stamps the 'government_response' email sent receipt on each signature when the job runs" do
          perform_enqueued_jobs do
            patch :update_response, :id => @petition.id, :petition => { :response => 'Doh!', :response_summary => 'Summary', :email_signees => '1'}
            @petition.reload
            petition_timestamp = @petition.get_email_requested_at_for('government_response')
            expect(petition_timestamp).not_to be_nil
            @petition.signatures.validated.notify_by_email.each do |signature|
              expect(signature.get_email_sent_at_for('government_response')).to eq(petition_timestamp)
            end
          end
        end

        it "emails out to the validated signees who have opted in when the delayed job runs" do
          ActionMailer::Base.deliveries.clear
          perform_enqueued_jobs do
            patch :update_response, :id => @petition.id, :petition => { :response => 'Doh!', :response_summary => 'Summary', :email_signees => '1'}
            expect(ActionMailer::Base.deliveries.length).to eq(4)
            expect(ActionMailer::Base.deliveries.map(&:to)).to eq([
              ["<EMAIL>"],
              ["<EMAIL>"],
              ["<EMAIL>"],
              ["<EMAIL>"]
            ])
            expect(ActionMailer::Base.deliveries[0].subject).to match(/The petition 'Make me the PM' has reached 6 signatures/)
            expect(ActionMailer::Base.deliveries[1].subject).to match(/The petition 'Make me the PM' has reached 6 signatures/)
            expect(ActionMailer::Base.deliveries[2].subject).to match(/The petition 'Make me the PM' has reached 6 signatures/)
            expect(ActionMailer::Base.deliveries[3].subject).to match(/The petition 'Make me the PM' has reached 6 signatures/)
          end
        end
      end
    end

    context "updating scheduled debate date" do
      let!(:petition) { FactoryGirl.create(:open_petition) }

      context "edit_scheduled_debate_date" do
        it "renders a view to update scheduled debate date" do
          get :edit_scheduled_debate_date, :id => petition.id
          expect(response).to render_template("edit_scheduled_debate_date")
        end

        shared_examples_for 'trying to view edit scheduled debate date view for a petition in the wrong state' do
          it 'raises a 404 error' do
            expect {
              get :edit_scheduled_debate_date, id: petition.id
            }.to raise_error ActiveRecord::RecordNotFound
{'fraction_non_alphanumeric': 0.10433504775900074, 'fraction_numerical': 0.007225079598334558, 'mean_word_length': 2.3455551003687014, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 89, 'https://': 12, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '130359', 'n_tokens_mistral': 4858, 'n_tokens_neox': 4564, 'n_words': 1217}