require 'rails_helper'

RSpec.describe Public::AmendmentsController, type: :controller do
  let(:user) { create(:user) }
  let(:account) { user.primary_account }
  let(:project) { create(:project, account: account) }

  render_views

  shared_examples "amendments signing controller" do
    describe "#new" do
      it "shows amendment signing form for non-signed amendment of a release" do
        expect(subject.amendment_signed?).to be_falsey

        get :new, params: {
          account_id: account,
          project_id: project,
          contract_template_id: subject.contract_template,
          "#{subject.model_name.param_key}_id": subject
        }

        expect(response).to be_successful

        body = CGI.unescape_html(response.body)
        expect(body).not_to match already_signed_message
      end

      it "shows already signed message for signed amendment of a release" do
        expect(signed_release.amendment_signed?).to be_truthy

        get :new, params: {
          account_id: account,
          project_id: project,
          contract_template_id: signed_release.contract_template,
          "#{signed_release.model_name.param_key}_id": signed_release
        }

        expect(response).to be_successful

        body = CGI.unescape_html(response.body)
        expect(body).to match already_signed_message
      end
    end

    describe "#create" do
      it "signs amendment" do
        expect(subject.amendment_signed?).to be_falsey

        post :create, params: {
          account_id: account,
          project_id: project,
          contract_template_id: subject.contract_template,
          "#{subject.model_name.param_key}_id": subject,
          "#{subject.model_name.param_key}": {
            amendment_signer_name: "Signer Name",
            amendment_signature_base64: signature_base64
          }
        }

        expect(response).to be_successful

        body = CGI.unescape_html(response.body)
        expect(body).not_to match already_signed_message
        expect(body).to match signed_successfully_message

        expect(subject.class.last.amendment_signed?).to be_truthy
        expect(subject.class.last.amendment_signer_name).to eq "Signer Name"
      end

      it "shows already signed message for signed amendment of a release" do
        expect(signed_release.amendment_signed?).to be_truthy

        post :create, params: {
          account_id: account,
          project_id: project,
          contract_template_id: signed_release.contract_template,
          "#{signed_release.model_name.param_key}_id": signed_release,
          "#{signed_release.model_name.param_key}": {
            amendment_signer_name: "Signer Who",
            amendment_signature_base64: signature_base64
          }
        }

        expect(response).to be_successful

        body = CGI.unescape_html(response.body)
        expect(body).to match already_signed_message

        expect(signed_release.amendment_signed?).to be_truthy
        expect(signed_release.amendment_signer_name).to eq "Amendment Signer"
      end
    end
  end

  context "for location release" do
    let(:contract_template) { create(:location_release_contract_template, :with_amendment_clause, project: project) }
    let(:signed_release) { create(:location_release, :amendment_signed, contract_template: contract_template, project: project) }
    subject { create(:location_release, contract_template: contract_template, project: project) }

    it_behaves_like "amendments signing controller"
  end

  context "for appearance release" do
    let(:contract_template) { create(:appearance_release_contract_template, :with_amendment_clause, project: project) }
    let(:signed_release) { create(:appearance_release, :amendment_signed, contract_template: contract_template, project: project) }
    subject { create(:appearance_release, contract_template: contract_template, project: project) }

    it_behaves_like "amendments signing controller"
  end

  private

  def already_signed_message
    t 'public.amendments.create.amendment_already_signed_message'
  end

  def signed_successfully_message
    t 'public.amendments.create.amendment_signed_message'
  end

  def signature_base64
    @signature_base64 ||= Base64Image.from_image(file_fixture('signature.png')).data_uri
  end
end
