require "rails_helper"

RSpec.describe Admin::AccountsController, type: :controller do
  render_views

  let(:current_user) { create(:user, :admin) }

  before do
    sign_in(current_user)
  end

  describe "#index" do
    it "returns a successful response" do
      get :index

      expect(response).to be_successful
    end

    it "has a search field form" do
      get :index

      expect(response.body).to have_button("search-button")
    end

    it "paginates the results" do
      create_list(:account, 20)

      get :index
      expect(response.body).to have_link("2", href: admin_accounts_path(page: 2))
    end

    it "filters the account by a query param" do
      create(:account, name: "First account")
      create(:account, name: "Second account")
      get :index, params: { query: "Second" }

      expect(response.body).not_to have_content("First account")
      expect(response.body).to have_content("Second account")
    end
  end

  describe "#new" do
    it "returns a successful response" do
      get :new

      expect(response).to be_successful
    end

    it "assigns 'account'" do
      get :new

      expect(assigns(:account)).not_to be_nil
    end
  end

  describe "#create" do
    it "responds with a redirect" do
      post :create, params: { account: account_params }

      expect(response).to be_redirect
    end

    it "sets a flash notice" do
      post :create, params: { account: account_params }

      expect(flash.notice).to eq "The account was created"
    end

    it "creates a new Account record" do
      expect {
        post :create, params: { account: account_params }
      }.to change(Account, :count).by(1)

      expect(assigns(:account)).not_to be_nil
    end

    context "when record cannot be saved" do
      before do
        allow_any_instance_of(Account).to receive(:save).and_return(false)
      end

      it "re-displays the form" do
        post :create, params: { account: account_params }

        expect(response).to be_successful
        expect(flash.notice).to be_nil
      end

      it "does not create a new Account record" do
        expect {
          post :create, params: { account: account_params }
        }.not_to change(Account, :count)
      end
    end
  end

  describe "#show" do
    it "returns a successful response" do
      get :show, params: { id: current_user.primary_account }

      expect(response).to be_successful
    end

    it "has a video search field form" do
      get :index

      expect(response.body).to have_button("search-button")
    end

    it "paginates the video list" do
      project = create(:project, account: current_user.primary_account)
      create_list(:video, 20, project: project )

      get :show, params: { id: current_user.primary_account }

      expect(response.body).to have_link("2", href: admin_account_path(current_user.primary_account, page: 2))
    end

    it "filters the videos by a query param" do
      project = create(:project, account: current_user.primary_account)
      create(:video, project: project, name: "First video")
      create(:video, project: project, name: "Second video")

      get :show, params: { id: current_user.primary_account, query: "Second"}

      expect(response.body).not_to have_content("First video")
      expect(response.body).to have_content("Second video")
    end
  end

  describe "#edit" do
    it "assigns account" do
      get :show, params: { id: current_user.primary_account }

      expect(response).to be_successful
      expect(assigns(:account)).to eq current_user.primary_account
    end
  end

  describe "#update" do
    context "when account successfully updated" do
      it "returns updates account" do
        patch :update, params: { id: current_user.primary_account, account: { name: "Fred", plan_uid: "deliverme" } }

        expect(current_user.primary_account.reload.name).to eq "Fred"
        expect(current_user.primary_account.plan_uid).to eq "deliverme"
      end

      it "redirects to accounts page" do
        patch :update, params: { id: current_user.primary_account, account: account_params }

        expect(response).to redirect_to admin_accounts_path
      end
    end

    context "when account update fails" do
      before :each do
        allow_any_instance_of(Account).to receive(:update).and_return(false)
      end

      it "renders edit" do
        patch :update, params: { id: current_user.primary_account, account: account_params }

        expect(response).to render_template :edit
      end
    end
  end

  def account_params
    attributes_for(:account)
  end
end
