require 'rails_helper'

RSpec.describe Ppa::ProjecoesDeDespesaController, type: :controller do
	sign_in_admin
	set_ppa_id_na_sessao
	cria_tipos_de_despesa

	before do
		request.env['HTTP_REFERER'] = root_url
		@iniciativa = FactoryBot.create( :ppa_iniciativa_para_ensino_fundamental )

		@outra_iniciativa = FactoryBot.create(:ppa_iniciativa_para_ensino_fundamental,
			codigo: '002',
			descricao: 'outra iniciativa',
			unidade_orcamentaria:  FactoryBot.create(:unidade_orcamentaria_gabinete_do_secretario)
		)

		@unidade_orcamentaria = @iniciativa.unidade_orcamentaria
		@outra_unidade_orcamentaria = @outra_iniciativa.unidade_orcamentaria
		@programa = @iniciativa.programa
	end

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

	describe "com ppa detalhado no programa" do
		describe "GET #edit" do
			it "atribui o programa requisitado ao @programa" do
				get :edit, id: @programa.id
				expect( assigns(:programa) ).to eq @programa
			end

			it "atribui as projeções de despesa à @projecoes_de_despesa" do
				get :edit, id: @programa.id
				projecoes_de_despesa = {}
				projecoes_de_despesa[@unidade_orcamentaria] = @programa.projecoes_de_despesa.where( unidade_orcamentaria_id: @unidade_orcamentaria.id )
				projecoes_de_despesa[@outra_unidade_orcamentaria] = @programa.projecoes_de_despesa.where( unidade_orcamentaria_id: @outra_unidade_orcamentaria.id )
				expect( assigns(:projecoes_de_despesa) ).to eq projecoes_de_despesa
			end
		end

		describe "PUT #update" do
			it "atualiza os valores das projeções de despesas" do
				projecao_de_despesa = @programa.projecoes_de_despesa.first
				outra_projecao_de_despesa = @programa.projecoes_de_despesa.last
				put :update, id: @programa.id, "projecoes_de_despesa"=> {
					projecao_de_despesa.id.to_s => { valor: 150 },
					outra_projecao_de_despesa.id.to_s => { valor: 500 }
				}

				expect( @programa.projecoes_de_despesa.sum(:valor) ).to eq 650
			end

			context "ao atualizar com sucessso" do
				before do
					allow( controller ).to receive( :projecoes_de_despesa_programas_params ).and_return( {} )
					allow_any_instance_of( Ppa::Programa ).to receive( :projecoes_de_despesa ).and_return( @programa.projecoes_de_despesa )
					expect(@programa.projecoes_de_despesa ).to receive( :update ).and_return( true )
					put :update, id: @programa.id
				end

				it "mostra mensagem de sucesso" do
					expect(flash[:notice]).to eq "Projeções de despesa atualizadas com sucesso"
				end

				it "redireciona para o show do programa" do
					expect( response ).to redirect_to @programa
				end
			end

			context "ao atualizar sem sucessso" do
				before do
					allow( controller ).to receive( :projecoes_de_despesa_programas_params ).and_return( {} )
					allow_any_instance_of( Ppa::Programa ).to receive( :projecoes_de_despesa ).and_return( @programa.projecoes_de_despesa )
					expect(@programa.projecoes_de_despesa ).to receive( :update ).and_return( false )
					put :update, id: @programa.id
				end

				it "mostra mensagem de erro" do
					expect(flash[:alert]).to eq "Um erro aconteceu ao atualizar as projeções de despesa"
				end

				it "redireciona para o edit" do
					expect( response ).to redirect_to  projecoes_de_despesa_edit_ppa_programa_path( id: @programa.id )
				end
			end
		end
	end

	describe "com ppa detalhado na iniciativa" do
		before(:each) do
			allow_any_instance_of( Ppa::Ppa ).to receive( :detalha_despesas_nas_iniciativas? ).and_return( true )
		end

		describe "GET #edit" do
			it "atribui a iniciativa requisitada a @iniciativa" do
				get :edit, id: @iniciativa.id
				expect( assigns(:iniciativa) ).to eq @iniciativa
			end
		end

		describe "PUT #update" do
			it "atualiza os valores das projeções de despesas" do
				Ppa::Iniciativa.all.each {|iniciativa| iniciativa.run_callbacks :create}
				projecao_de_despesa = @iniciativa.projecoes_de_despesa.first
				outra_projecao_de_despesa = @iniciativa.projecoes_de_despesa.last
				atributos = { "projecoes_de_despesa_attributes"=> {
						"0" => {id:projecao_de_despesa.id.to_s, valor: 150 },
						"1" => {id: outra_projecao_de_despesa.id.to_s, valor: 500 }
					}
				}
				put :update, id: @iniciativa.id, ppa_iniciativa: atributos
				expect( @iniciativa.projecoes_de_despesa.sum(:valor) ).to eq 650
			end

			context "ao atualizar com sucessso" do
				before do
					Ppa::Iniciativa.all.each {|iniciativa| iniciativa.run_callbacks :create}
					projecao_de_despesa = @iniciativa.projecoes_de_despesa.first
					outra_projecao_de_despesa = @iniciativa.projecoes_de_despesa.last
					atributos = { "projecoes_de_despesa_attributes"=> {
							"0" => {id:projecao_de_despesa.id.to_s, valor: 150 },
							"1" => {id: outra_projecao_de_despesa.id.to_s, valor: 500 }
						}
					}
					put :update, id: @iniciativa.id, ppa_iniciativa: atributos
				end

				it "mostra mensagem de sucesso" do
					expect(flash[:notice]).to eq "Metas Financeiras atualizada(s) com sucesso."
				end

				it "redireciona para o show do programa" do
					expect( response ).to redirect_to @iniciativa.objetivo
				end
			end

			context "ao atualizar sem sucessso" do
				before do
					Ppa::Iniciativa.all.each {|iniciativa| iniciativa.run_callbacks :create}
					projecao_de_despesa = @iniciativa.projecoes_de_despesa.first
					atributos = { "projecoes_de_despesa_attributes"=> {
							"0" => {id:projecao_de_despesa.id.to_s, valor: 150 },
							"1" => {id: nil, valor: 500 }
						}
					}
					put :update, id: @iniciativa.id, ppa_iniciativa: atributos
				end

				it "renderiza edit" do
					expect(response).to render_template("ppa/projecoes_de_despesa/iniciativas/edit")
				end
			end
		end
	end

end
