require 'rails_helper'

RSpec.describe Loa::UnidadeOrcamentariaPorNaturezaDaReceita, type: :model do

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

	let(:unidade_orcamentaria_por_natureza_da_receita) {
		natureza_da_receita_corrente_sem_validacao
		FactoryBot.create(:unidade_orcamentaria_por_natureza_da_receita, natureza_da_receita: natureza_da_receita_corrente_sem_validacao)
	}

	it { is_expected.to belong_to(:natureza_da_receita).class_name( 'Base::NaturezaDaReceita').required }
	it { is_expected.to belong_to(:unidade_orcamentaria).required }

	it { is_expected.to have_many(:orcamentos_da_receita).dependent(:destroy)}

	it{ is_expected.to validate_presence_of :natureza_da_receita_id }

	it { is_expected.to accept_nested_attributes_for(:orcamentos_da_receita).allow_destroy(true)}

	describe 'validates_uniqueness_of' do
		it 'validate_uniqueness_of unidade_orcamentaria_id no escopo natureza_da_receita_id' do
			natureza_da_receita = FactoryBot.create(:natureza_receita_corrente_pai)

			atributos_de_natureza_da_receita =  {
				unidades_orcamentarias_por_natureza_da_receita_attributes: {
					"0" => {
						unidade_orcamentaria_id: Loa::UnidadeOrcamentaria.find_or_create_by(FactoryBot.attributes_for :loa_hgf, :orcamento_2016).id,
					},
					"1" => {
						unidade_orcamentaria_id: Loa::UnidadeOrcamentaria.find_or_create_by(FactoryBot.attributes_for :loa_hgf, :orcamento_2016).id,
					}
				}
			}

			natureza_da_receita.update(atributos_de_natureza_da_receita)

			expect(
			natureza_da_receita.errors[:"unidades_orcamentarias_por_natureza_da_receita"][0]
			).to include( 'unidade orçamentária deve ser única dentro de uma natureza da receita' )
		end
	end

	describe "#valor_total" do
		it "retorna a soma dos orçamentos da receita" do
			unidade_orcamentaria_por_natureza_da_receita
			FactoryBot.create(:orcamento_da_receita_saude, unidade_orcamentaria_por_natureza_da_receita: unidade_orcamentaria_por_natureza_da_receita)
			FactoryBot.create(:orcamento_da_receita_educacao, unidade_orcamentaria_por_natureza_da_receita: unidade_orcamentaria_por_natureza_da_receita)

			expect(unidade_orcamentaria_por_natureza_da_receita.valor_total).to eq(30.00)
		end
	end

	describe "#update" do
		before do
			@unidade_orcamentaria = FactoryBot.create :loa_hgf, :orcamento_2016
			@natureza_da_receita = natureza_da_receita_corrente_sem_validacao
			@fonte_de_recursos = FactoryBot.create :alienacao_de_bens
			@fonte_de_recursos_diferente = FactoryBot.create :alienacao_de_bens, codigo: "98", descricao: "Descrição diferente."
		end

		context "quando são passadas fontes de recursos repetidas" do
			it "retorna mensagem de erro" do
				atributos_de_unidade_orcamentaria_por_natureza_da_receita =  {
					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
								},
								"1" => {
									fonte_de_recursos_id: @fonte_de_recursos.id,
									valor: 8.73
								}
							}
						}
					}
				}

				@natureza_da_receita.update(atributos_de_unidade_orcamentaria_por_natureza_da_receita)

				expect( @natureza_da_receita.errors["unidades_orcamentarias_por_natureza_da_receita.orcamentos_da_receita"].join ).to eq( 'fonte de recursos deve ser único dentro de uma unidade orcamentária' )
				expect( @natureza_da_receita.unidades_orcamentarias_por_natureza_da_receita.first.orcamentos_da_receita.first.errors[:fonte_de_recursos_id] ).not_to include( 'fonte de recursos deve ser único dentro de uma unidade orcamentária' )
				expect( @natureza_da_receita.unidades_orcamentarias_por_natureza_da_receita.first.orcamentos_da_receita.last.errors[:fonte_de_recursos_id] ).to include( 'fonte de recursos deve ser único dentro de uma unidade orcamentária' )
			end
		end

		context "quando não são passados fontes de recursos repetidas" do
			it "atualiza unidade orcamentaria" do
				atributos_de_unidade_orcamentaria_por_natureza_da_receita =  {
					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
								},
								"1" => {
									fonte_de_recursos_id: @fonte_de_recursos_diferente.id,
									valor: 8.73
								}
							}
						}
					}
				}

				@natureza_da_receita.update(atributos_de_unidade_orcamentaria_por_natureza_da_receita)
				expect( @natureza_da_receita.errors["unidades_orcamentarias_por_natureza_da_receita.orcamentos_da_receita".to_sym] ).not_to include( 'fonte de recursos deve ser único dentro de natureza da receita' )
				expect( @natureza_da_receita.unidades_orcamentarias_por_natureza_da_receita.first.orcamentos_da_receita.first.errors[:fonte_de_recursos_id] ).not_to include( 'fonte de recursos deve ser único dentro de natureza da receita' )
				expect( @natureza_da_receita.unidades_orcamentarias_por_natureza_da_receita.first.orcamentos_da_receita.last.errors[:fonte_de_recursos_id] ).not_to include( 'fonte de recursos deve ser único dentro de natureza da receita' )
			end
		end
	end
end
