require 'rails_helper'

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

	let(:liquidacao) {
		FactoryBot.attributes_for( :liquidacao_001 )
	}

	let(:atributos) {
		FactoryBot.attributes_for(:pagamento_de_pessoal)
	}

	let(:atributos_validos) {
		atributos.except(:evento_contabil).merge({evento_contabil_id: atributos[:evento_contabil][:id]})
	}

	let(:atributos_invalidos) {
		{
			valor: 0
		}
	}

	let(:item_da_nota_fiscal_caderno) {
		FactoryBot.attributes_for( :item_da_nota_fiscal_caderno )
	}

	before(:all) do
		DatabaseCleaner.strategy = :transaction
		DatabaseCleaner.start

		@pagamento = FactoryBot.create(:pagamento_de_pessoal)
	end
	after(:all) do
		DatabaseCleaner.clean
	end

	describe "GET #show" do
		it "atribui a pagamento requisitado à @pagamento" do
			get :show, params: {id: @pagamento.to_param}
			expect(assigns(:pagamento)).to eq(@pagamento)
		end

		context "caso o credor não tenha conta bancaria" do
			it "atribui a mensagem de alerta à @mensagem_de_alerta_das_pessoas_sem_contas_bancarias" do
				get :show, params: {id: @pagamento.to_param}
				expect(assigns(:mensagem_de_alerta_das_pessoas_sem_contas_bancarias)).to eq('O(A) credor Antonio de Sousa, não possui uma conta bancária associada ao seu cadastro no sistema. Para associar uma conta, já cadastrada, com esse credor clique ')
			end

			it "atribui a liquidacao associada à @liquidacao" do
				get :show, params: {id: @pagamento.to_param}
				expect(assigns(:liquidacao)).to eq(@pagamento.liquidacao)
			end
		end

		context "caso o credor tenha conta bancaria" do
			it "atribui nil à @mensagem_de_alerta_das_pessoas_sem_contas_bancarias" do
				pessoa_conta_bancaria = FactoryBot.create(:pessoa_conta_bancaria)
				get :show, params: {id: @pagamento.to_param}
				expect(assigns(:mensagem_de_alerta_das_pessoas_sem_contas_bancarias)).to eq(nil)
			end
		end
	end

	describe "GET #new" do
		before(:each) do
			allow_any_instance_of(Contabilidade::Liquidacao).to receive(:total_dos_itens_fecha_com_liquidacao?).and_return(true)
		end
		context 'quando o usuário está no administrativo' do
			it 'atribui um pagamento solicitado a @pagamento' do
				@request.session[:contexto_tipo] = 'Administrativo'
				@request.session[:modulo] = 'administrativo'
				get :new,  { liquidacao_id: @pagamento.liquidacao.id }
				expect(assigns(:pagamento).status).to eq "solicitado"
			end
		end
		context 'quando o usuário está na contabilidade' do
			it 'atribui um pagamento confirmado a @pagamento' do
				get :new,  { liquidacao_id: @pagamento.liquidacao.id }
				expect(assigns(:pagamento).status).to eq "confirmado"
			end
		end
	end

	describe "GET #edit" do
		it "atribui o pagamento requisitado à @pagamento" do
			@pagamento.liquidacao.nota_fiscal_numero = 1234515
			@pagamento.liquidacao.save(validate: false)
			get :edit,  { id: @pagamento.id }
			expect(assigns(:pagamento)).to eq(@pagamento)
		end
	end

	describe "POST #create" do
		before(:each) do
			@liquidacao = Contabilidade::Liquidacao.create! liquidacao
			load File.expand_path('seed_acoes_do_sistema.rb', Rails.root.to_s + '/db')
		end

		context "com parâmetros válidos" do
			it "cria um novo pagamento" do
				expect {
					post :create,  { liquidacao_id: @liquidacao.id, contabilidade_pagamento: atributos_validos }
				}.to change(@liquidacao.pagamentos, :count).by( 1 )
			end

			it "atribui o pagamento recém criado à @pagamento" do
				post :create,  { liquidacao_id: @liquidacao.id, contabilidade_pagamento: atributos_validos }
				expect(assigns(:pagamento)).to be_a(Contabilidade::Pagamento)
				expect(assigns(:pagamento)).to be_persisted
			end

			it "redireciona para os pagamentos da liquidacao" do
				post :create,  { liquidacao_id: @liquidacao.id, contabilidade_pagamento: atributos_validos }
				expect(response).to redirect_to(Contabilidade::Pagamento.last)
			end
		end

		context "com parâmetros inválidos" do
			it "atribui um pagamento recém criado, mas não salvo, à @pagamento" do
				post :create,  { liquidacao_id: @liquidacao.id, contabilidade_pagamento: atributos_invalidos }
				expect(assigns(:pagamento)).to be_a_new(Contabilidade::Pagamento)
			end

			it "re-renderiza o template 'new'" do
				post :create,  { liquidacao_id: @liquidacao.id, contabilidade_pagamento: atributos_invalidos }
				expect(response).to render_template("new")
			end
		end
	end

	describe "PUT #update" do
		context "com parâmetros válidos" do
			let(:novos_atributos) {
				{
					valor: 100.0
				}
			}

			it "atualiza o pagamento requisitado" do
				put :update,  { id: @pagamento.to_param, contabilidade_pagamento: novos_atributos }
				@pagamento.reload
				expect( @pagamento.valor ).to eq 100.0
			end

			it "atribui o pagamento requisitado à @pagamento" do
				put :update,  { id: @pagamento.to_param, contabilidade_pagamento: novos_atributos }
				expect(assigns(:pagamento)).to eq(@pagamento)
			end

			it "redireciona para os pagamentos da liquidacao" do
				put :update,  { id: @pagamento.to_param, contabilidade_pagamento: novos_atributos }
				expect(response).to redirect_to(@pagamento)
			end
		end

		context "com parâmetros inválidos" do
			it "atribui o pagamento à @pagamento" do
				put :update,  { id: @pagamento.to_param, contabilidade_pagamento: atributos_invalidos }
				expect(assigns(:pagamento)).to eq(@pagamento)
			end

			it "re-renderiza o template 'edit'" do
				put :update,  { id: @pagamento.to_param, contabilidade_pagamento: atributos_invalidos }
				expect(response).to render_template("edit")
			end
		end
	end

	describe "DELETE #destroy" do
		it "destrói o pagamento requisitado" do
			expect {
				delete :destroy, params: {id: @pagamento.to_param}
			}.to change(Contabilidade::Pagamento, :count).by(-1)
		end

		it "redireciona para os pagamentos da liquidacao" do
			delete :destroy,  { id: @pagamento.to_param }
			expect(response).to redirect_to(@pagamento.liquidacao)
		end
	end

	describe "UPDATE #atualizar_prepagamento_em_pagamento" do
		context "ao tentar converter em pagamento uma liquidacao estornada" do
			it "pagamento continua como prepagamento" do
				pagamento = FactoryBot.create(:pagamento_de_pessoal, prepagamento: true)
				usuario = FactoryBot.create(:usuario_comum)
				Contabilidade::EstornoDeLiquidacao.create(liquidacao: pagamento.liquidacao, data_do_estorno: Date.today, justificativa: "...", usuario_id: usuario.id)

				put :atualizar_prepagamento_em_pagamento,  { id: pagamento.to_param }
				pagamento.reload
				expect(pagamento[:prepagamento]).to eq(true)
			end

			it "redireciona para detalhe da liquidacao" do
				pagamento = FactoryBot.create(:pagamento_de_pessoal, prepagamento: true)
				usuario = FactoryBot.create(:usuario_comum)
				Contabilidade::EstornoDeLiquidacao.create(liquidacao: pagamento.liquidacao, data_do_estorno: Date.today, justificativa: "...", usuario_id: usuario.id)

				put :atualizar_prepagamento_em_pagamento,  { id: pagamento.to_param }
				pagamento.reload
				expect(response).to redirect_to(pagamento.liquidacao)
			end
		end

		context "ao converter prepagamento em pagamento" do
			it "retorna prepagamento como pagamento" do
				pagamento = FactoryBot.create(:pagamento_de_pessoal, prepagamento: true)
				put :atualizar_prepagamento_em_pagamento,  { id: pagamento.to_param }

				pagamento.reload
				expect(pagamento[:prepagamento]).to eq(false)
			end

			it "redireciona para detalhe da liquidacao" do
				pagamento = FactoryBot.create(:pagamento_de_pessoal, prepagamento: true)
				put :atualizar_prepagamento_em_pagamento,  { id: pagamento.to_param }
				expect(response).to redirect_to(pagamento.liquidacao)
			end
		end
	end

	describe 'PATCH #enviar_para_controladoria' do
		it 'atribui o status enviado_para_controladoria' do
			pagamento = FactoryBot.create :pagamento_de_pessoal, status: 'solicitado'
			patch :enviar_para_controladoria, {id: pagamento.to_param}
			expect(pagamento.reload.enviado_para_controladoria?).to be_truthy
		end
	end
	describe 'PATCH #confirmar_pagamento' do
		it 'atribui o status confirmado' do
			pagamento = FactoryBot.create :pagamento_de_pessoal, status: 'enviado_para_controladoria'
			pagamento.vistos.create(aprovado: true,  vistoriador_id: subject.current_usuario.id, tipo: 'controladoria')
			patch :confirmar_pagamento, {id: pagamento.to_param}
			expect(pagamento.reload.confirmado?).to be_truthy
		end
	end
	describe 'PATCH #retornar_para_administrativo' do
		it 'atribui o status solicitado' do
			pagamento = FactoryBot.create :pagamento_de_pessoal, status: 'enviado_para_controladoria'
			pagamento.vistos.create( FactoryBot.attributes_for(:controladoria_visto, :negativo) )
			patch :retornar_para_administrativo, {id: pagamento.to_param}
			expect(pagamento.reload.solicitado?).to be_truthy
		end
	end
end
