require "rails_helper"

# This spec was generated by rspec-rails when you ran the scaffold generator.
# It demonstrates how one might use RSpec to test the controller code that
# was generated by Rails when you ran the scaffold generator.
#
# It assumes that the implementation code is generated by the rails scaffold
# generator. If you are using any extension libraries to generate different
# controller code, this generated spec may or may not pass.
#
# It only uses APIs available in rails and/or rspec-rails. There are a number
# of tools you can use to make these specs even more expressive, but we're
# sticking to rails and rspec-rails APIs to keep things simple and stable.

RSpec.describe "/documents", type: :request do
  # This should return the minimal set of attributes required to create a valid
  # Document. As you add validations to Document, be sure to
  # adjust the attributes here as well.
  let(:valid_attributes) {
    {
      title: "NIST 800-53r5 Catalog",
      url: "https://raw.githubusercontent.com/usnistgov/oscal-content/main/nist.gov/SP800-53/rev5/json/NIST_SP-800-53_rev5_catalog.json",
      description: "The full 800-53r5 catalog"
    }
  }

  let(:invalid_attributes) {
    valid_attributes.tap do |attr|
      attr[:url] = "javascript:alert('you+get+an+xss')"
    end
  }

  let(:user) { User.create! email: "user@gsa.gov", password: SecureRandom.alphanumeric }

  before { sign_in user }

  describe "GET /index" do
    it "renders a successful response" do
      Document.create! valid_attributes
      get documents_url
      expect(response).to be_successful
    end
  end

  describe "GET /show" do
    it "renders a successful response" do
      document = Document.create! valid_attributes
      get document_url(document, locale: "en")
      expect(response).to be_successful
    end
  end

  describe "GET /new" do
    let(:user) { User.create! email: "admin@gsa.gov", password: SecureRandom.alphanumeric, admin: true }

    it "renders a successful response" do
      get new_document_url
      expect(response).to be_successful
    end
  end

  describe "GET /edit" do
    let(:user) { User.create! email: "admin@gsa.gov", password: SecureRandom.alphanumeric, admin: true }

    it "renders a successful response" do
      document = Document.create! valid_attributes
      get edit_document_url(document, locale: "en")
      expect(response).to be_successful
    end
  end

  describe "POST /create" do
    let(:user) { User.create! email: "admin@gsa.gov", password: SecureRandom.alphanumeric, admin: true }

    context "with valid parameters" do
      it "creates a new Document" do
        expect {
          post documents_url, params: {document: valid_attributes}
        }.to change(Document, :count).by(1)
      end

      it "redirects to the created document" do
        post documents_url, params: {document: valid_attributes}
        expect(response).to redirect_to(document_url(Document.last, locale: "en"))
      end

      it "logs the use of this privileged function", control_id: "ac-6.9", statement_id: "ac-6.9_smt", implementation_statement_uuid: "c2db0c86-cfa5-4fb5-9f92-66a066bf5604" do
        allow(Rails.logger).to receive(:info)
        expect(Rails.logger).to receive(:info).with(/\[PRIVILEGED\] Document\(\d+\) created by #{user.id}/)
        post documents_url, params: {document: valid_attributes}
      end
    end

    context "with invalid parameters" do
      it "does not create a new Document" do
        expect {
          post documents_url, params: {document: invalid_attributes}
        }.to change(Document, :count).by(0)
      end

      it "renders a response with 422 status (i.e. to display the 'new' template)" do
        post documents_url, params: {document: invalid_attributes}
        expect(response).to have_http_status(:unprocessable_entity)
      end
    end
  end

  describe "PATCH /update" do
    let(:user) { User.create! email: "admin@gsa.gov", password: SecureRandom.alphanumeric, admin: true }
    let!(:document) { Document.create! valid_attributes }

    context "with valid parameters" do
      let(:new_attributes) {
        valid_attributes.tap do |attr|
          attr[:description] = "We updated the description!"
        end
      }

      it "updates the requested document" do
        patch document_url(document, locale: "en"), params: {document: new_attributes}
        document.reload
        expect(document.description).to eq "We updated the description!"
      end

      it "redirects to the document" do
        patch document_url(document, locale: "en"), params: {document: new_attributes}
        document.reload
        expect(response).to redirect_to(document_url(document, locale: "en"))
      end

      it "logs the use of this privileged function", control_id: "ac-6.9", statement_id: "ac-6.9_smt", implementation_statement_uuid: "c2db0c86-cfa5-4fb5-9f92-66a066bf5604" do
        allow(Rails.logger).to receive(:info)
        expect(Rails.logger).to receive(:info).with("[PRIVILEGED] Document(#{document.id}) updated by #{user.id}")
        patch document_url(document, locale: "en"), params: {document: new_attributes}
      end
    end

    context "with invalid parameters" do
      it "renders a response with 422 status (i.e. to display the 'edit' template)" do
        document = Document.create! valid_attributes
        patch document_url(document, locale: "en"), params: {document: invalid_attributes}
        expect(response).to have_http_status(:unprocessable_entity)
      end
    end
  end

  describe "DELETE /destroy" do
    let(:user) { User.create! email: "admin@gsa.gov", password: SecureRandom.alphanumeric, admin: true }
    let!(:document) { Document.create! valid_attributes }

    it "destroys the requested document" do
      expect {
        delete document_url(document, locale: "en")
      }.to change(Document, :count).by(-1)
    end

    it "redirects to the documents list" do
      delete document_url(document, locale: "en")
      expect(response).to redirect_to(documents_url)
    end

    it "logs the use of this privileged function", control_id: "ac-6.9", statement_id: "ac-6.9_smt", implementation_statement_uuid: "c2db0c86-cfa5-4fb5-9f92-66a066bf5604" do
      allow(Rails.logger).to receive(:info)
      expect(Rails.logger).to receive(:info).with("[PRIVILEGED] Document(#{document.id}) destroyed by #{user.id}")
      delete document_url(document, locale: "en")
    end
  end
end
