require 'rails_helper'

RSpec.describe Contabilidade::ContasPorEventosContabeisController, type: :controller do
	sign_in_admin
	cria_configuracao_default
	set_contabilidade_na_sessao

	let(:evento_contabil) { FactoryBot.create( :evento_contabil, :empenhar )	}

	describe 'GET #new' do
		it 'rendezira template :new' do
			get :new, evento_contabil_id: evento_contabil.id
			expect(response).to render_template(:new)
		end

		it 'atribui os pares de contas débito e crédito à @conta_debito e @conta_credito' do
			get :new, evento_contabil_id: evento_contabil.id

			expect(assigns(:conta_debito)).to be_a_new(Contabilidade::ContaPorEventoContabil)
			expect(assigns(:conta_credito)).to be_a_new(Contabilidade::ContaPorEventoContabil)
		end
	end

	describe 'POST #create' do
		before(:each) do
			@conta_credor = FactoryBot.create :conta_patrimonial, :sem_validacao
			@conta_devedor = FactoryBot.create :conta_patrimonial_tres, :sem_validacao
		end

		context 'com parâmetros válidos' do
			it 'cria um par de contas débito e crédito' do
				expect{
					post :create, evento_contabil_id: evento_contabil.id, contas_por_eventos_contabeis: [
						{conta_id: @conta_credor.id, tipo_de_lancamento: 'debito'},
						{conta_id: @conta_devedor.id, tipo_de_lancamento: 'credito'}
					]
				}.to change(Contabilidade::ContaPorEventoContabil, :count).by(4)
			end

			it "atribui as contas recém criadoas à @conta_debito e @conta_credito" do
				post :create, evento_contabil_id: evento_contabil.id, contas_por_eventos_contabeis: [
					{conta_id: @conta_credor.id, tipo_de_lancamento: 'debito'},
					{conta_id: @conta_devedor.id, tipo_de_lancamento: 'credito'}
				]

				expect(assigns(:conta_debito)).to be_persisted
				expect(assigns(:conta_credito)).to be_persisted
			end

			it "redireciona para o evento_contabil das contas" do
				post :create, evento_contabil_id: evento_contabil.id, contas_por_eventos_contabeis: [
					{conta_id: @conta_credor.id, tipo_de_lancamento: 'debito'},
					{conta_id: @conta_devedor.id, tipo_de_lancamento: 'credito'}
				]

				expect(response).to redirect_to(evento_contabil)
			end
		end

		context 'com parâmetros inválidos' do
			it "atribui as contas recém criadoas à @conta_debito e @conta_credito, mas não salvas" do
				post :create, evento_contabil_id: evento_contabil.id, contas_por_eventos_contabeis: [
					{conta_id: @conta_credor.id, tipo_de_lancamento: ''},
					{conta_id: @conta_devedor.id, tipo_de_lancamento: 'credito'}
				]

				expect(assigns(:conta_debito)).to be_a_new(Contabilidade::ContaPorEventoContabil)
				expect(assigns(:conta_credito)).to be_a_new(Contabilidade::ContaPorEventoContabil)
			end

			it 'redireciona para o template de :new' do
				post :create, evento_contabil_id: evento_contabil.id, contas_por_eventos_contabeis: [
					{conta_id: @conta_credor.id, tipo_de_lancamento: ''},
					{conta_id: @conta_devedor.id, tipo_de_lancamento: 'credito'}
				]

				expect(response).to redirect_to(contabilidade_conta_por_evento_contabil_new_path(evento_contabil_id: evento_contabil.id))
			end
		end

		context 'quando as contas são iguais' do
			it 'redireciona para o template :new' do
				post :create, evento_contabil_id: evento_contabil.id, contas_por_eventos_contabeis: [
					{conta_id: @conta_credor.id, tipo_de_lancamento: 'debito'},
					{conta_id: @conta_credor.id, tipo_de_lancamento: 'credito'}
				]

				expect(response).to redirect_to(contabilidade_conta_por_evento_contabil_new_path(evento_contabil_id: evento_contabil.id))
			end

			it 'mostra mensagem flash de erro' do
				post :create, evento_contabil_id: evento_contabil.id, contas_por_eventos_contabeis: [
					{conta_id: @conta_credor.id, tipo_de_lancamento: 'debito'},
					{conta_id: @conta_credor.id, tipo_de_lancamento: 'credito'}
				]

				expect(flash[:alert]).to include 'Não é possível selecionar duas contas iguais.'
			end
		end

		context 'quando as contas já existem no evento contábil' do
			it 'redireciona para o template :new' do
				post :create, evento_contabil_id: evento_contabil.id, contas_por_eventos_contabeis: [
					{conta_id: @conta_credor.id, tipo_de_lancamento: 'debito'},
					{conta_id: @conta_devedor.id, tipo_de_lancamento: 'credito'}
				]

				post :create, evento_contabil_id: evento_contabil.id, contas_por_eventos_contabeis: [
					{conta_id: @conta_credor.id, tipo_de_lancamento: 'debito'},
					{conta_id: @conta_devedor.id, tipo_de_lancamento: 'credito'}
				]

				expect(response).to redirect_to(contabilidade_conta_por_evento_contabil_new_path(evento_contabil_id: evento_contabil.id))
			end

			it 'mostra mensagem flash de erro' do
				post :create, evento_contabil_id: evento_contabil.id, contas_por_eventos_contabeis: [
					{conta_id: @conta_credor.id, tipo_de_lancamento: 'debito'},
					{conta_id: @conta_devedor.id, tipo_de_lancamento: 'credito'}
				]

				post :create, evento_contabil_id: evento_contabil.id, contas_por_eventos_contabeis: [
					{conta_id: @conta_credor.id, tipo_de_lancamento: 'debito'},
					{conta_id: @conta_devedor.id, tipo_de_lancamento: 'credito'}
				]

				expect(flash[:alert]).to include 'O par de contas selecionado já existe no evento contábil.'
			end
		end
	end
end
