require 'rails_helper'

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

	let(:conta_pai) { FactoryBot.create :conta_patrimonial_pai }

	let(:conta_pai_sem_validacao) {
		conta = FactoryBot.create(:conta_patrimonial_pai, :sem_validacao)
		conta.atribui_classificacao_da_conta
		conta.save(validate: false)
		conta
	}

	let(:conta) {
		conta_pai_sem_validacao
		FactoryBot.create :conta_patrimonial
	}

	let(:atributos_validos) { FactoryBot.attributes_for( :conta_patrimonial) }
	let(:atributos_invalidos) { {nome: ''} }

	describe 'GET #index' do
		it 'atribui a lista de contas à @contas' do
			get :index, exercicio: conta.orcamento.exercicio

			expect(assigns(:contas)).to eq([conta_pai_sem_validacao, conta])
		end
	end

	describe 'GET #show' do
		it 'atribui a conta requisitada à @conta' do
			get :show, id: conta.id

			expect(assigns(:conta)).to eq conta
		end
	end

	describe 'GET #new' do
		it 'atribui uma nova conta à @conta' do
			get :new, exercicio: conta.orcamento.exercicio, conta_pai_id: conta.id

			expect(assigns[:conta]).to be_a_new(Contabilidade::Conta)
		end
	end

	describe 'POST #create' do
		context 'com parâmetros válidos' do
			it 'cria uma nova Contabilidade::Conta' do
				atributos_validos[:codigo] = '1'
				expect{
					post :create, params: {exercicio: '2017', conta_pai_id: conta_pai_sem_validacao.id, contabilidade_conta: atributos_validos }
				}.to change(Contabilidade::Conta, :count).by(2)
			end

			it 'atribui a conta recém criada à @conta' do
				atributos_validos[:codigo] = '1'
			  post :create, params: {exercicio: '2017', conta_pai_id: conta_pai_sem_validacao.id, contabilidade_conta: atributos_validos }
				expect(assigns[:conta]).to be_a(Contabilidade::Conta)
				expect(assigns[:conta]).to be_persisted
			end

			it 'redireciona para à conta criada' do
				atributos_validos[:codigo] = '1'
				post :create, params: {exercicio: '2017', conta_pai_id: conta_pai_sem_validacao.id, contabilidade_conta: atributos_validos }
				expect(response).to redirect_to(Contabilidade::Conta.last)
			end
		end

		context 'com parâmetros inválidos' do
			it 'atribui uma conta recém criada à @conta, mas não salva' do
			  post :create, params: {exercicio: '2017', conta_pai_id: conta_pai_sem_validacao.id, contabilidade_conta: atributos_invalidos}
				expect(assigns[:conta]).to be_a(Contabilidade::Conta)
				expect(assigns[:conta]).to_not be_persisted
			end

			it 're-renderiza o template new' do
			  post :create, params: {exercicio: '2017', conta_pai_id: conta_pai_sem_validacao.id, contabilidade_conta: atributos_invalidos}
				expect(response).to render_template(:new)
			end
		end
	end

	describe 'GET #edit' do
	  it 'atribui a conta requisitada à @conta' do
			get :edit, id: conta.id

			expect(assigns[:conta]).to eq conta
	  end
	end

	describe 'PUT #update' do
		let(:novos_atributos) {
			{ atributo_de_conta: 'permanente' }
		}

		context 'com parâmetros válidos' do
			it 'atualiza a conta requisitada' do
				post :update, params: {id: conta.id, contabilidade_conta: novos_atributos}
				conta.reload
				expect(conta.permanente?).to be_truthy
			end

			it 'atribui a conta requisitada à @conta' do
			  post :update, params: {id: conta.id, contabilidade_conta: novos_atributos}
				expect(assigns(:conta)).to eq conta
			end

			it 'redireciona para a conta atualizada' do
				post :update, params: {id: conta.id, contabilidade_conta: novos_atributos}
				expect(response).to redirect_to(conta)
			end
		end

		context 'com parâmetros inválidos' do
			it 'atribui uma conta recém criada à @conta, mas não salva' do
				post :update, params: {id: conta.id, contabilidade_conta: atributos_invalidos}
				expect(assigns(:conta)).to eq conta
			end

			it 're-renderiza o template edit' do
				post :update, params: {id: conta.id, contabilidade_conta: atributos_invalidos}
				expect(response).to render_template(:edit)
			end
		end
	end

	describe 'DELETE #destroy' do
		it 'destrói a conta requisitada' do
			conta
			expect{
				delete :destroy, params: {id: conta.id}
			}.to change(Contabilidade::Conta, :count).by(-1)
		end

		it 'redireciona para a lista de contas' do
			conta
			delete :destroy, params: {id: conta.id}

			expect(response).to redirect_to contabilidade_contas_path(exercicio: conta.orcamento.exercicio)
		end
	end
end
