require 'rails_helper'

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

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

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

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

	describe "GET #new" do
		context 'quando orçamento trabalha com subação' do
			it "atribui um(a) novo(a) meta_fisica ao @meta_fisica com subacao_id" do
				orcamento_atual_trabalha_com_subacoes
				meta_fisica = Loa::MetaFisica.create! atributos_validos
				get :new, params: { subacao_id: meta_fisica.subacao_id }
				expect(assigns(:meta_fisica)).to be_a_new(Loa::MetaFisica)
			end
		end
		context 'quando orçamento não trabalha com subação' do
			it "atribui um(a) novo(a) meta_fisica ao @meta_fisica com acao_id" do
				orcamento_atual_nao_trabalha_com_subacoes
				meta_fisica = Loa::MetaFisica.create! atributos_validos
				get :new, params: { acao_id: meta_fisica.subacao.acao_id }
				expect(assigns(:meta_fisica)).to be_a_new(Loa::MetaFisica)
			end
		end
	end

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

	describe "POST #create" do
		context "com parâmetros válidos" do
			it "cria um novo meta_fisica" do
				subacao = FactoryBot.create(:subacao_1005_0001, :orcamento_2016 )

				expect {
					post :create, params: {loa_meta_fisica: atributos_validos, id: subacao.id}
				}.to change(Loa::MetaFisica, :count).by(1)
			end

			it "atribui o meta_fisica recém criado ao @meta_fisica" do
				subacao = FactoryBot.create(:subacao_1005_0001, :orcamento_2016 )

				post :create, params: {loa_meta_fisica: atributos_validos, id: subacao.id}
				expect(assigns(:meta_fisica)).to be_a(Loa::MetaFisica)
				expect(assigns(:meta_fisica)).to be_persisted
			end

			context 'quando orçamento trabalha com subação' do
				it "redireciona para a subacao da meta_fisica criada" do
					subacao = FactoryBot.create(:subacao_1005_0001, :orcamento_2016 )

					post :create, params: {loa_meta_fisica: atributos_validos, id: subacao.id}
					expect(response).to redirect_to(Loa::MetaFisica.last.subacao)
				end
			end
			context 'quando orçamento não trabalha com subação' do
				it "redireciona para a ação da meta_fisica criada" do
					orcamento_atual_nao_trabalha_com_subacoes
					subacao = FactoryBot.create(:subacao_1005_0001, :orcamento_2016 )
					post :create, params: {loa_meta_fisica: atributos_validos, id: subacao.id}
					expect(response).to redirect_to(Loa::MetaFisica.last.subacao.acao)
				end
			end

			context "com o param 'mantem_form'" do
				it "redireciona para a tela de cadastro de metas fisicas" do
					subacao = FactoryBot.create(:subacao_1005_0001, :orcamento_2016 )
					post :create, params: {loa_meta_fisica: atributos_validos, id: subacao.id, manter_form: true}
					expect(response).to redirect_to( action: :new, id: subacao.id)
				end
			end

			context "sem o param 'mantem_form'" do
				it "redireciona para a tela da subacao" do
					subacao = FactoryBot.create(:subacao_1005_0001, :orcamento_2016 )

					post :create, params: {loa_meta_fisica: atributos_validos, id: subacao.id}
					expect(response).to redirect_to( subacao )
				end
			end
		end

		context "com parâmetros inválidos" do
			it "atribui um meta_fisica recém criado, mas não salvo, ao @meta_fisica" do
				subacao = FactoryBot.create(:subacao_1005_0001, :orcamento_2016 )

				post :create, params: {loa_meta_fisica: atributos_invalidos, id: subacao.id}
				expect(assigns(:meta_fisica)).to be_a_new(Loa::MetaFisica)
			end

			it "re-renderiza o template 'new'" do
				subacao = FactoryBot.create(:subacao_1005_0001, :orcamento_2016 )

				post :create, params: {loa_meta_fisica: atributos_invalidos, id: subacao.id}
				expect(response).to render_template("new")
			end
		end
	end

	describe "PUT #update" do
		context "com parâmetros válidos" do
			let(:novos_atributos) {
				{ produto: 'novo nome' }
			}

			it "atualiza o meta_fisica requisitado" do
				meta_fisica = Loa::MetaFisica.create! atributos_validos

				post :update, params: {id: meta_fisica.id, loa_meta_fisica: novos_atributos}
				meta_fisica.reload
				expect( meta_fisica.produto ).to eq 'novo nome'
			end

			it "atribui o meta_fisica requisitado ao @meta_fisica" do
				meta_fisica = Loa::MetaFisica.create! atributos_validos
				post :update, params: {id: meta_fisica.id, loa_meta_fisica: novos_atributos}
				expect(assigns(:meta_fisica)).to eq(meta_fisica)
			end

			context 'quando orçamento trabalha com subação' do
				it "redireciona para a subacao da meta_fisica editada" do
					meta_fisica = Loa::MetaFisica.create! atributos_validos
					post :update, params: {id: meta_fisica.id, loa_meta_fisica: novos_atributos}
					expect(response).to redirect_to(loa_subacao_path(meta_fisica.subacao) + "?tab=metas_fisicas")
				end
			end
			context 'quando orçamento não trabalha com subação' do
				it "redireciona para a ação da subacao da meta_fisica editada" do
					orcamento_atual_nao_trabalha_com_subacoes
					meta_fisica = Loa::MetaFisica.create! atributos_validos
					post :update, params: {id: meta_fisica.id, loa_meta_fisica: novos_atributos}
					expect(response).to redirect_to(loa_acao_path(meta_fisica.subacao.acao) + "?tab=metas_fisicas")
				end
			end
		end

		context "com parâmetros inválidos" do
			it "atribui o meta_fisica ao @meta_fisica" do
				meta_fisica = Loa::MetaFisica.create! atributos_validos
				post :update, params: {id: meta_fisica.id, loa_meta_fisica: atributos_invalidos}
				expect(assigns(:meta_fisica)).to eq(meta_fisica)
			end

			it "re-renderiza o template 'edit'" do
				meta_fisica = Loa::MetaFisica.create! atributos_validos
				post :update, params: {id: meta_fisica.id, loa_meta_fisica: atributos_invalidos}
				expect(response).to render_template("edit")
			end
		end
	end

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

		context 'quando orçamento trabalha com subação' do
			it "redireciona para a subação da meta fisica" do
				meta_fisica = Loa::MetaFisica.create! atributos_validos
				delete :destroy, params: { id: meta_fisica.to_param }
				expect(response).to redirect_to(loa_subacao_path(meta_fisica.subacao) + "?tab=metas_fisicas")
			end
		end

		context 'quando orçamento não trabalha com subação' do
			it "redireciona para a ação da meta fisica" do
				orcamento_atual_nao_trabalha_com_subacoes
				meta_fisica = Loa::MetaFisica.create! atributos_validos
				delete :destroy, params: { id: meta_fisica.to_param }
				expect(response).to redirect_to(loa_acao_path(meta_fisica.subacao.acao) + "?tab=metas_fisicas")
			end
		end
	end

	describe "GET #importar" do
		it "lista metas não importadas" do
			meta = FactoryBot.create(:meta_contratar_profissionais)

			iniciativa = FactoryBot.create( :ppa_iniciativa_para_ensino_fundamental, codigo: '001', objetivo: meta.objetivo )

			acao = FactoryBot.create(:acao_9005, :orcamento_2016)
			acao.iniciativa_id = iniciativa.id
			acao.save(validate: false)

			subacao = FactoryBot.create(:subacao_1005_0001, :orcamento_2016, acao_id: acao.id)

			get :importar, { subacao_id: subacao.id }

			expect(subacao.acao.iniciativa.objetivo.metas).to eq([meta])
		end
	end

	describe "GET #importa" do
		context 'programas selecionados' do
			it 'deve conter uma iniciativa marcada como importada' do
				meta = FactoryBot.create(:meta_contratar_profissionais)
				FactoryBot.create(:ppa_quantitativo, meta_id: meta.id, exercicio:2016)
				meta_fisica = Loa::MetaFisica.create! atributos_validos
				meta_fisica.ppa_meta_id = meta.id
				meta_fisica.importar_dados_da_meta(@orcamento)
				meta_fisica.save

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