require 'rails_helper'

RSpec.describe TaskRequestsController, type: :controller do
  render_views

  let(:user) { create(:user) }
  let(:account) { user.primary_account }
  let(:project) { create(:project, account: user.primary_account) }

  before do
    sign_in user
  end

  describe "#index" do
    it "responds successfully" do
      get :index, params: { project_id: project }

      expect(response).to be_successful
    end

    it "renders content" do
      create(:task_request, project: project, description: "Another Request")

      get :index, params: { project_id: project }

      expect(response.body).to have_link "Create Task Request"
      expect(response.body).to have_content "Pending"
    end

    context "when there are many records" do
      it "paginates the table" do
        create_list(:task_request, 20, project: project)

        get :index, params: { project_id: project }

        expect(response.body).to have_link("2", href: project_task_requests_path(project, page: 2))
      end
    end
  end

  describe "#new" do
    it "responds successfully" do
      get :new, params: { project_id: project }

      expect(response).to be_successful
      expect(assigns(:task_request)).to be_a_new(TaskRequest)
      expect(response).to render_template(:new)
    end
  end

  describe "#create" do
    it "does create a new record" do
      expect {
        post :create, params: { project_id: project.id, task_request: task_request_params }
      }.to change(TaskRequest, :count)
    end

    it "logs an event" do
      expect {
        post :create, params: { project_id: project.id, task_request: task_request_params }
      }.to have_enqueued_job(TrackAnalyticsJob).with(user,  account, :track_create_task_request, user_agent: "Rails Testing", user_ip: "0.0.0.0")
    end

    it "submits data to hubspot form" do
      expect {
        post :create, params: { project_id: project.id, task_request: task_request_params }
      }.to have_enqueued_job(SubmitHubspotTaskRequestFormJob)
    end
  end

  describe "#update" do
    let!(:task_request) { create(:task_request, project: project, description: "My description" ) }

    it "updates task request" do
      patch :update, params: { project_id: project.id, id: task_request.id, task_request: update_params }

      expect(task_request.reload.description).to eq("This is updated description")
    end
  end

  describe "#show" do
    let!(:task_request) { create(:task_request, project: project, description: "Task Request") }

    it "responds successfully" do
      get :show, params: { project_id: project.id, id: task_request.id }

      expect(response).to be_successful
      expect(assigns(:task_request)).to eq(task_request)
    end

    it "renders content" do
      get :show, params: { project_id: project.id, id: task_request.id }
      
      expect(response.body).to have_content "Task Request"
      expect(response.body).to have_content "pending"
    end
  end

  describe "#cancel" do
    let!(:task_request) { create(:task_request, project: project, description: "Task to be cancelled") }

    it "responds with redirect" do
      post :cancel, params: { project_id: project.id, id: task_request.id }

      expect(response).to be_redirect
      expect(response).to redirect_to(project_task_requests_path(project))
      expect(flash.notice).not_to be_nil
    end

    it "updates the status to 'cancelled'" do
      expect {
        post :cancel, params: { project_id: project.id, id: task_request.id }
      }.to change { task_request.reload.status }.from("pending").to("cancelled")
    end
  end

  private

  def task_request_params
    attributes = attributes_for(:task_request).except(:status, :user_email)
    files = 2.times.map { Rack::Test::UploadedFile.new(file_fixture("location_photo.png"), "image/png") }

    attributes.merge({ files: files })
  end

  def update_params
    { description: "This is updated description" }
  end
end
