require 'rails_helper'

RSpec.describe Loa::OrcamentosDaReceitaController, type: :controller do
	sign_in_admin
	set_orcamento_na_sessao

	let(:natureza_da_receita_corrente_sem_validacao) {
		FactoryBot.create(:natureza_receita_corrente)
	}

	let(:fonte_de_recurso_educacao){
		FactoryBot.create(:educacao)
	}

	let(:fonte_de_recurso_saude){
		FactoryBot.create(:saude)
	}

	let(:fonte_de_recurso_codigo_1){
		FactoryBot.create(:taxas_vinculadas, codigo: "01")
	}

	describe "GET #edit" do
		before(:each) do
			@natureza_da_receita = natureza_da_receita_corrente_sem_validacao
			fonte_de_recurso_educacao
			fonte_de_recurso_saude
			fonte_de_recurso_codigo_1
		end

		it "renderiza a(s) natureza(s) da receita da unidade orçamentária requisitada" do
			get :edit, params: { id: @natureza_da_receita.id }
			expect(assigns(:natureza_da_receita)).to eq @natureza_da_receita
		end

		it "renderiza o template 'edit'" do
			get :edit, params: { id: @natureza_da_receita.id }
			expect(response).to render_template('edit')
		end
	end

	describe "PUT #update" do
		before do
			@natureza_da_receita = natureza_da_receita_corrente_sem_validacao
			@unidade_orcamentaria = FactoryBot.create :loa_hgf, :orcamento_2016
			@fonte_de_recursos = FactoryBot.create :alienacao_de_bens
		end

		context "quando não há parâmetro id" do
			it "cria natureza da receita por unidade_orcamentaria da unidade orcamentaria requisitada" do
				atributos_unidade_orcamentaria_por_natureza_da_receita = {
					unidades_orcamentarias_por_natureza_da_receita_attributes:
					{
						'0': {
							unidade_orcamentaria_id: @unidade_orcamentaria.id,
						}
					}
				}

				expect {
					put :update, id: @natureza_da_receita.id, base_natureza_da_receita: atributos_unidade_orcamentaria_por_natureza_da_receita
				}.to change(@natureza_da_receita.unidades_orcamentarias_por_natureza_da_receita, :count).by( 1 )

			end

			it "cria orcamento de receita da natureza da receita requisitada" do
				atributos_unidade_orcamentaria_por_natureza_da_receita = {
					valor_previsto: 9.99,
					unidades_orcamentarias_por_natureza_da_receita_attributes: {
						'0': {
							unidade_orcamentaria_id: @unidade_orcamentaria.id,
							orcamentos_da_receita_attributes: {
								'0': {
									fonte_de_recursos_id: @fonte_de_recursos.id,
									valor: 9.99
								}
							}
						}
					}
				}

				expect {
					put :update, id: @natureza_da_receita.id, base_natureza_da_receita: atributos_unidade_orcamentaria_por_natureza_da_receita
				}.to change(@natureza_da_receita.orcamentos_da_receita, :count).by( 1 )

			end
		end

		context "quando há parâmetro id" do
			it "atualiza a unidade orcamentaria por natureza da receita da natureza da receita requisitada" do

				unidade_orcamentaria_por_natureza_da_receita = @natureza_da_receita.unidades_orcamentarias_por_natureza_da_receita.create!(
					unidade_orcamentaria_id: @unidade_orcamentaria.id,
					status_do_orcamento: 0
				)

				outra_unidade_orcamentaria = FactoryBot.create( :loa_seduc, :orcamento_2016 )

				atributos_unidade_orcamentaria_por_natureza_da_receita = {
					unidades_orcamentarias_por_natureza_da_receita_attributes: {
						'0': {
							id: unidade_orcamentaria_por_natureza_da_receita.id,
							unidade_orcamentaria_id: outra_unidade_orcamentaria.id
						}
					}
				}

				put :update, id: @natureza_da_receita.id, base_natureza_da_receita: atributos_unidade_orcamentaria_por_natureza_da_receita
				unidade_orcamentaria_por_natureza_da_receita.reload
				expect( unidade_orcamentaria_por_natureza_da_receita.unidade_orcamentaria ).to eq outra_unidade_orcamentaria

			end

			it "atualiza o orcamento de receita da natureza da receita requisitada" do
				unidade_orcamentaria_por_natureza_da_receita = FactoryBot.create( :unidade_orcamentaria_por_natureza_da_receita, natureza_da_receita_id: @natureza_da_receita.id )
				orcamento_saude = FactoryBot.create( :orcamento_da_receita_saude, unidade_orcamentaria_por_natureza_da_receita_id: unidade_orcamentaria_por_natureza_da_receita.id )

				atributos_unidade_orcamentaria_por_natureza_da_receita = {
					valor_previsto: 50.05,
					unidades_orcamentarias_por_natureza_da_receita_attributes: {
						'0': {
							id: orcamento_saude.unidade_orcamentaria_por_natureza_da_receita_id,
							orcamentos_da_receita_attributes: {
								'0': {
									id: orcamento_saude.id,
									valor: 50.05
								}
							}
						}
					}
				}

				put :update, id: @natureza_da_receita.id, base_natureza_da_receita: atributos_unidade_orcamentaria_por_natureza_da_receita
				orcamento_saude.reload
				expect( orcamento_saude.valor ).to eq 50.05
			end
		end

		context 'quando há o parâmetro _destroy' do
			it 'apaga a unidade orçamentária por natureza da receita da natureza requisitada' do
			  unidade_orcamentaria_por_natureza_da_receita = FactoryBot.create( :unidade_orcamentaria_por_natureza_da_receita, natureza_da_receita_id: @natureza_da_receita.id )

				atributos_unidade_orcamentaria_por_natureza_da_receita = {
					unidades_orcamentarias_por_natureza_da_receita_attributes: {
						'0' => {
							id: unidade_orcamentaria_por_natureza_da_receita.id,
							_destroy: true
						}
					}
				}

				expect {
					put :update, id: @natureza_da_receita.id, base_natureza_da_receita: atributos_unidade_orcamentaria_por_natureza_da_receita
				}.to change( @natureza_da_receita.unidades_orcamentarias_por_natureza_da_receita, :count ).by( -1 )

			end

			it 'apaga os orçamentos da receita da natureza requisitada' do
				unidade_orcamentaria_por_natureza_da_receita = FactoryBot.create( :unidade_orcamentaria_por_natureza_da_receita, natureza_da_receita_id: @natureza_da_receita.id )
				orcamento_saude = FactoryBot.create( :orcamento_da_receita_saude, unidade_orcamentaria_por_natureza_da_receita_id: unidade_orcamentaria_por_natureza_da_receita.id )

				atributos_unidade_orcamentaria_por_natureza_da_receita = {
					valor_previsto: 50.05,
					unidades_orcamentarias_por_natureza_da_receita_attributes: {
						'0': {
							id: orcamento_saude.unidade_orcamentaria_por_natureza_da_receita_id,
							orcamentos_da_receita_attributes: {
								'0': {
									id: orcamento_saude.id,
									valor: 50.05,
									_destroy: true
								}
							}
						}
					}
				}

				expect {
					put :update, id: @natureza_da_receita.id, base_natureza_da_receita: atributos_unidade_orcamentaria_por_natureza_da_receita
				}.to change( @natureza_da_receita.orcamentos_da_receita, :count ).by( -1 )

			end
		end

		context "com parâmetros inválidos" do
			it "renderiza o template de edit" do
				fonte_de_recurso_educacao
				fonte_de_recurso_saude
				fonte_de_recurso_codigo_1

				FactoryBot.create( :orcamento_da_receita_saude )

				atributos_unidade_orcamentaria_por_natureza_da_receita = {
					valor_previsto: -2.00
				}

				put :update, id: @natureza_da_receita.id, base_natureza_da_receita: atributos_unidade_orcamentaria_por_natureza_da_receita
				expect(response).to render_template('edit')
			end
		end


		context "com parâmetros válidos" do
			it "redireciona para a natureza requisitada" do
				atributos_unidade_orcamentaria_por_natureza_da_receita = {
					unidades_orcamentarias_por_natureza_da_receita_attributes: {}
				}

				put :update, id: @natureza_da_receita.id, base_natureza_da_receita: atributos_unidade_orcamentaria_por_natureza_da_receita
				expect(response).to redirect_to @natureza_da_receita
			end
		end
	end
end
