require 'rails_helper'

RSpec.describe Ppa::MetasController, type: :controller do
	sign_in_admin
	set_ppa_id_na_sessao

	# Isso deve retornar o mínimo de atributos obrigatórios para criar um
	# Ppa::Meta válido.
	let(:atributos_validos) {
		FactoryBot.attributes_for(:meta_contratar_profissionais)
	}

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

	let(:atributos_quantitativos) {
		{
			quantitativos_attributes: {
				"0" => {
					unidade_de_medida_id: FactoryBot.create( :unidade_de_medida ).id,
					indice_de_referencia: 100.00,
				}
			}
		}
	}

	it{ is_expected.to use_before_action(:verifica_se_tem_ppa_na_sessao!) }

	describe "GET #new" do
		let(:objetivo) {
			FactoryBot.create(:meta_contratar_profissionais).objetivo
		}

		it "atribui um(a) novo(a) ppa_meta à @ppa_meta" do
			get :new, objetivo_id: objetivo.id
			expect(assigns(:ppa_meta)).to be_a_new(Ppa::Meta)
		end

		it "@ppa_meta pertence ao objetivo requisitado nos params" do
			get :new, objetivo_id: objetivo.id
			expect(assigns(:ppa_meta).objetivo).to eq (objetivo)
		end
	end

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

	describe "POST #create" do
		context "com parâmetros válidos" do
			it "cria um(a) novo(a) Ppa::Meta" do
				expect {
					post :create, params: {ppa_meta: atributos_validos}
				}.to change(Ppa::Meta, :count).by(1)
			end

			it "atribui o(a) ppa_meta recém criado(a) à @ppa_meta" do
				post :create, params: {ppa_meta: atributos_validos}
				expect(assigns(:ppa_meta)).to be_a(Ppa::Meta)
				expect(assigns(:ppa_meta)).to be_persisted
			end

			context "com o param 'mantem_form'" do
				it "redireciona para o objetivo da meta cadastrada" do
					post :create, params: {:ppa_meta => atributos_validos, manter_form: true}
					expect(response).to redirect_to( action: :new, objetivo_id: assigns(:ppa_meta).objetivo.id)
				end
			end

			context "tentando salvar objetivo para programa tipo gestão'" do
				it "redireciona para o show" do
					programa_de_gestao = FactoryBot.create(:programa_escolar, :ppa_2014, tipo_de_programa_id: Ppa::TipoDePrograma.find_or_create_by(FactoryBot.attributes_for :programas_de_gestao_e_manutencao).id)
					objetivo = FactoryBot.create(:ppa_objetivo, programa_id: programa_de_gestao.id)
					post :create, params: {ppa_meta: atributos_validos,objetivo_id: objetivo.id}
					expect(assigns(:ppa_meta)).to be_a_new(Ppa::Meta)
				end
			end

			context "sem o param 'mantem_form'" do
				it "redireciona para o objetivo da meta cadastrada" do
					post :create, params: {ppa_meta: atributos_validos}
					expect(response).to redirect_to( assigns(:ppa_meta).objetivo)
				end
			end
		end

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

			it "re-renderiza o template 'new'" do
				post :create, params: {ppa_meta: 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) {
				{ descricao: 'nova descrição' }
			}

			it "atualiza o(a) ppa_meta requisitado(a)" do
				meta = Ppa::Meta.create! atributos_validos
				post :update, params: {id: meta.to_param, ppa_meta: novos_atributos,quantitativos_attributes: atributos_quantitativos}
				meta.reload
				expect( meta.descricao ).to eq 'nova descrição'
			end

			it "atribui o(a) ppa_meta requisitado(a) à @ppa_meta" do
				meta = Ppa::Meta.create! atributos_validos
				post :update, params: {id: meta.to_param, ppa_meta: atributos_validos}
				expect(assigns(:ppa_meta)).to eq(meta)
			end

			it "redireciona para o o objetivo da meta cadastrada" do
				meta = Ppa::Meta.create! atributos_validos
				post :update, params: {id: meta.to_param, ppa_meta: atributos_validos}
				expect(response).to redirect_to(meta.objetivo)
			end

			it "redireciona para o o objetivo da meta cadastrada com meta fisica" do
				meta = Ppa::Meta.create! atributos_validos
				post :update, params: {id: meta.to_param, ppa_meta: atributos_validos,quantitativos_attributes: atributos_quantitativos}
				expect(response).to redirect_to(meta.objetivo)
			end
		end

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

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

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

		it "redireciona para o objetivo da meta excluída" do
			meta = Ppa::Meta.create! atributos_validos
			delete :destroy, params: {:id => meta.to_param}
			expect(response).to redirect_to(meta.objetivo)
		end
	end
end
