require 'rails_helper'

RSpec.describe Loa::AcoesController, type: :controller do
	sign_in_admin
	set_orcamento_na_sessao
	render_views
	cria_tipos_de_despesa

	let(:atributos_validos) {
		FactoryBot.attributes_for :acao_9005, :orcamento_2016
	}

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

	let(:programa) {
		FactoryBot.attributes_for :programa_bolsa_familia, :orcamento_2016
	}

	describe "GET #show" do
		it "atribui a acao requisitado(a) à @acao" do
			acao = Loa::Acao.create! atributos_validos
			get :show, params: {id: acao.to_param}
			expect(assigns(:acao)).to eq(acao)
		end

		context 'quando orçamento não trabalha com subação' do
			it 'renderiza o template de show da subação' do
				orcamento = Orcamento.last
				orcamento.update(trabalha_com_subacao: false)
				acao = Loa::Acao.create! atributos_validos
				FactoryBot.create :subacao_1005_0001, :orcamento_2016, acao: acao
				get :show, params: {id: acao.to_param}
				expect(response).to render_template "loa/subacoes/show"
			end
		end
		context 'quando orçamento trabalha com subação' do
			it 'renderiza o template de show da ação' do
				acao = Loa::Acao.create! atributos_validos
				get :show, params: {id: acao.to_param}
				expect(response).to render_template "show"
			end
		end
	end

	describe "GET #new" do
		before(:each) do
			orcamento_atual_trabalha_com_subacoes
			@acao = Loa::Acao.create! atributos_validos
		end
		it "atribui um(a) novo(a) acao à @acao" do
			get :new, id: @acao.programa_de_governo.to_param
			expect(assigns(:acao)).to be_a_new(Loa::Acao)
		end

		context 'quando orçamento não trabalha com subação' do
			it "atribui subacao vazia à @subacao" do
				orcamento_atual_nao_trabalha_com_subacoes
				get :new, id: @acao.programa_de_governo.to_param
				expect(assigns(:subacao)).to be_a_new(Loa::Subacao)
			end
		end
		context 'quando orçamento não trabalha com subação' do
			it "não atribui subacao" do
				get :new, id: @acao.programa_de_governo.to_param
				expect(assigns(:subacao)).to be_nil
			end
		end
	end

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

	describe "POST #create" do
		before do
			@programa_de_governo = Loa::ProgramaDeGoverno.create! programa
		end
		context "com parâmetros válidos" do
			it "cria um(a) novo(a) acao" do
				expect {
					post :create, params: {id: @programa_de_governo.to_param, loa_acao: atributos_validos}
				}.to change(Loa::Acao, :count).by(1)
			end

			it "atribui o(a) ação recém criado(a) à @acao" do
				post :create, params: {id: @programa_de_governo.to_param, loa_acao: atributos_validos}

				expect(assigns(:acao)).to be_a(Loa::Acao)
				expect(assigns(:acao)).to be_persisted
			end

			it "redireciona para o(a) acao criado(a)" do
				post :create, params: {id: @programa_de_governo.to_param, loa_acao: atributos_validos}
				expect(response).to redirect_to(Loa::Acao.last)
			end

			context "com o param 'mantem_form'" do
				it "redireciona a tela de cadastro de ação" do
					post :create, params: {id: @programa_de_governo.to_param, loa_acao: atributos_validos, manter_form: true }
					expect(response).to redirect_to( action: :new, id: @programa_de_governo.id)
				end
			end

			context "sem o param 'mantem_form'" do
				it "redireciona para a ação cadastrada" do
					post :create, params: {id: @programa_de_governo.to_param, loa_acao: atributos_validos }
					expect(response).to redirect_to( assigns(:acao) )
				end
			end
		end

		context "com parâmetros inválidos" do
			it "atribui um(a) acao recém criado(a), mas não salvo(a), à @acao" do
				post :create, params: {id: @programa_de_governo.to_param, loa_acao: atributos_invalidos}
				expect(assigns(:acao)).to be_a_new(Loa::Acao)
			end

			it "re-renderiza o template 'new'" do
				post :create, params: {id: @programa_de_governo.to_param, loa_acao: atributos_invalidos}
				expect(response).to render_template("new")
			end
		end
	end

	describe "PUT #update" do
		before do
			@acao = Loa::Acao.create! atributos_validos
		end
		context "com parâmetros válidos" do
			let(:novos_atributos) {
				{ nome: 'novo nome' }
			}

			it "atualiza o(a) acao requisitado(a)" do
				post :update, params: {id: @acao.id, loa_acao: novos_atributos}
				@acao.reload
				expect( @acao.nome ).to eq 'novo nome'
			end

			it "atribui o(a) acao requisitado(a) à @acao" do
				post :update, params: {id: @acao.id, loa_acao: atributos_validos}
				expect(assigns(:acao)).to eq(@acao)
			end

			it "redireciona para o(a) acao" do
				post :update, params: {id: @acao.id, loa_acao: atributos_validos}
				expect(response).to redirect_to(@acao)
			end
		end

		context "com parâmetros inválidos" do
			it "atribui o(a) acao à @acao" do
				post :update, params: {id: @acao.id, loa_acao: atributos_invalidos}
				expect(assigns(:acao)).to eq(@acao)
			end

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

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

		it "redireciona para a lista de ações" do
			acao = Loa::Acao.create! atributos_validos
			delete :destroy, params: { id: acao.to_param}
			expect(response).to redirect_to(acao.programa_de_governo)
		end
	end

	describe "GET #prepara_importacao" do
		it "lista iniciativas não importadas" do
			iniciativa = FactoryBot.create( :ppa_iniciativa_para_ensino_fundamental, codigo: '001' )

			programa_de_governo = FactoryBot.build(:programa_bolsa_familia, :orcamento_2016)
			programa_de_governo.programa_id = iniciativa.programa.id
			programa_de_governo.save!(validate: false)

			get :prepara_importacao, { id: programa_de_governo.id }

			expect(assigns(:ppa_iniciativas)).to eq([iniciativa])
		end
	end

	describe "GET #importar" do
		context 'nenhum programa selecionado' do
			it "redireciona para o programa" do
				programa_de_governo = Loa::ProgramaDeGoverno.create! programa
				post :importar, { id: programa_de_governo.id }
				expect(response).to redirect_to(prepara_importacao_das_acoes_do_ppa_path(programa_de_governo))
			end
		end

		context 'programas selecionados' do
			it 'deve conter uma iniciativa marcada como importada' do
				iniciativa = FactoryBot.create( :ppa_iniciativa_para_ensino_fundamental, codigo: '001' )

				@orcamento = Orcamento.last
				@orcamento.ppa_id = iniciativa.unidade_orcamentaria.orgao.ppa_id
				@orcamento.save(validate: false)

				acao = Loa::Acao.create! atributos_validos
				acao.iniciativa_id = iniciativa.id
				acao.save
				acao.importar_dados_da_iniciativa

				expect(Loa::Acao.where("iniciativa_id is not null").count).to be > 0
			end
		end
	end

end
