require 'rails_helper'


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

	let(:atributos_validos) {
		FactoryBot.attributes_for(:diaria)
	}

	let(:atributos_invalidos) {
		{data_da_portaria: ''}
	}

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

	describe "GET #index" do
		before do
			@diaria = Contabilidade::Diaria.create! atributos_validos
			@outra_diaria = FactoryBot.create :diaria, :unidade_orcamentaria_diferente
		end
		context 'quando o usuário acessa todas as unidades' do
			it "atribui a lista completa de diarias solicitados à @diarias" do
				sign_in FactoryBot.create(:usuario_comum)
				get :index, exercicio: 2016
				expect(assigns(:diarias)).to include(@diaria, @outra_diaria)
			end
		end
		context 'quando o usuário possui unidades selecionadas' do
			sign_in_secretario
			it 'retorna apenas diarias solicitados das unidades do usuário' do
				get :index, exercicio: 2016
				expect(assigns(:diarias)).to eq([@diaria])
			end
		end
	end

	describe "GET #show" do
		sign_in_secretario
		context 'quando empenho está em fase de solicitação' do
			context 'e o usuário pode acessar unidade do empenho' do
				it 'atribui a empenho requisitado(a) à @empenho' do
					diaria = Contabilidade::Diaria.create! atributos_validos
					get :show, params: {id: diaria.to_param}
					expect(assigns(:diaria)).to eq(diaria)
				end
			end

			context 'e o usuário não pode acessar unidade do empenho' do
				it 'redireciona para o index' do
					diaria = FactoryBot.create :diaria, :unidade_orcamentaria_diferente
					get :show, params: {id: diaria.to_param}
					expect(response).to redirect_to(diarias_url(2016))
				end
			end
		end
	end

	describe "GET #new" do
		it "atribui um(a) novo(a) diaria à @diaria" do
			get :new, exercicio: orcamento_2016[:exercicio]
			expect(assigns(:diaria)).to be_a_new(Contabilidade::Diaria)
		end
	end

	describe "GET #edit" do
		it "atribui o(a) diaria requisitado à @diaria" do
			diaria = Contabilidade::Diaria.create! atributos_validos
			get :edit, params: {id: diaria.to_param}
			expect(assigns(:diaria)).to eq(diaria)
		end

		it "não redireciona para diaria se não existir empenho" do
			diaria = Contabilidade::Diaria.create! atributos_validos

			get :edit, params: {id: diaria.to_param}
			expect(assigns(:diaria)).to eq(diaria)
		end

		it "redireciona para diaria se existir empenho lançado" do
			diaria = Contabilidade::Diaria.create! atributos_validos
			empenho = Contabilidade::Empenho.new(diaria: diaria, valor: 100)
			empenho.save(validate: false)

			get :edit, params: {id: diaria.to_param}
			expect(response).to redirect_to(diaria_path(Contabilidade::Diaria.last))
		end

		it "não redireciona para diaria se existir empenho lançado mas está anulado" do
			diaria = Contabilidade::Diaria.create! atributos_validos
			empenho = Contabilidade::Empenho.new(diaria: diaria, valor: 100, valor_anulado: 100)
			empenho.save(validate: false)

			get :edit, params: {id: diaria.to_param}
			expect(assigns(:diaria)).to eq(diaria)
		end
	end

	describe "POST #create" do
		context "com parâmetros válidos" do
			it "cria um(a) novo(a) Contabilidade::Diaria" do
				expect {
					post :create, params: {contabilidade_diaria: atributos_validos, exercicio: orcamento_2016[:exercicio]}
				}.to change(Contabilidade::Diaria, :count).by(1)
			end

			it "atribui o(a) diaria recém criado(a) à @diaria" do
				post :create, params: {contabilidade_diaria: atributos_validos, exercicio: orcamento_2016[:exercicio]}
				expect(assigns(:diaria)).to be_a(Contabilidade::Diaria)
				expect(assigns(:diaria)).to be_persisted
			end

			it "redireciona para o(a) diaria criado(a)" do
				post :create, params: {:contabilidade_diaria => atributos_validos, exercicio: orcamento_2016[:exercicio]}
				expect(response).to redirect_to(diaria_path(Contabilidade::Diaria.last))
			end
		end

		context "com parâmetros inválidos" do
			it "atribui um(a) diaria recém criado(a), mas não salvo(a), à @diaria" do
				post :create, params: {contabilidade_diaria: atributos_invalidos, exercicio: orcamento_2016[:exercicio]}
				expect(assigns(:diaria)).to be_a_new(Contabilidade::Diaria)
			end

			it "re-renderiza o template 'new'" do
				post :create, params: {contabilidade_diaria: atributos_invalidos, exercicio: orcamento_2016[:exercicio]}
				expect(response).to render_template("new")
			end
		end
	end

	describe "PUT #update" do
		context "com parâmetros válidos" do
			let(:novos_atributos) {
				{data_da_portaria: '2016-09-06'}
			}

			it "atualiza o(a) diaria requisitado(a)" do
				diaria = Contabilidade::Diaria.create! atributos_validos
				post :update, params: {id: diaria.to_param, contabilidade_diaria: novos_atributos}
				diaria.reload
				expect( diaria.data_da_portaria ).to eq Date.parse('2016-09-06')
			end

			it "atribui o(a) diaria requisitado(a) à @diaria" do
				diaria = Contabilidade::Diaria.create! atributos_validos
				post :update, params: {id: diaria.to_param, contabilidade_diaria: atributos_validos}
				expect(assigns(:diaria)).to eq(diaria)
			end

			it "redireciona para o(a) diaria" do
				diaria = Contabilidade::Diaria.create! atributos_validos
				post :update, params: {id: diaria.to_param, contabilidade_diaria: atributos_validos}
				expect(response).to redirect_to(diaria_path(diaria))
			end
		end

		context "com parâmetros inválidos" do
			it "atribui o(a) diaria à @diaria" do
				diaria = Contabilidade::Diaria.create! atributos_validos
				post :update, params: {id: diaria.to_param, contabilidade_diaria: atributos_invalidos}
				expect(assigns(:diaria)).to eq(diaria)
			end

			it "re-renderiza o template 'edit'" do
				diaria = Contabilidade::Diaria.create! atributos_validos
				post :update, params: {id: diaria.to_param, contabilidade_diaria: atributos_invalidos}
				expect(response).to render_template("edit")
			end
		end
	end

	describe "DELETE #destroy" do
		it "destrói o(a) diaria requisitado(a)" do
			diaria = Contabilidade::Diaria.create! atributos_validos
			expect {
				delete :destroy, params: {:id => diaria.to_param}
			}.to change(Contabilidade::Diaria, :count).by(-1)
		end

		it "redireciona para a lista de diarias" do
			diaria = Contabilidade::Diaria.create! atributos_validos
			delete :destroy, params: {:id => diaria.to_param}
			expect(response).to redirect_to(diarias_url(diaria.orcamento))
		end
	end
end
