require 'rails_helper'

RSpec.describe Ppa::Programa, type: :model do
	it{ is_expected.to belong_to :ppa }
	it{ is_expected.to belong_to :eixo }
	it{ is_expected.to belong_to :orgao }
	it{ is_expected.to belong_to :tipo_de_programa }

	it{ is_expected.to have_many( :objetivos ).dependent(:restrict_with_exception) }
	it{ is_expected.to have_many( :indicadores ).dependent(:destroy) }
	it{ is_expected.to have_many( :projecoes_de_despesa ).dependent(:restrict_with_exception) }
	it{ is_expected.to have_many( :iniciativas ).through( :objetivos ) }
	it{ is_expected.to have_many( :metas ).through( :objetivos ) }
	it{ is_expected.to have_many( :programas_de_governo ).class_name('Loa::ProgramaDeGoverno').dependent(:restrict_with_exception) }

	[:nome, :codigo, :ppa_id, :orgao_id, :tipo_de_programa_id, :eixo_id].each do |atributo|
		it{ is_expected.to validate_presence_of atributo}
	end

	it{
		FactoryBot.create(:programa_escolar, :ppa_2014)
		is_expected.to validate_uniqueness_of( :nome ).scoped_to( :ppa_id )
	}

	it{
		FactoryBot.create(:programa_escolar, :ppa_2014)
		is_expected.to validate_uniqueness_of( :codigo ).scoped_to([:ppa_id, :tipo_de_programa_id] )
	}


	it "não permite alterações no atributo ppa_id" do
		programa = FactoryBot.create( :programa_escolar, :ppa_2014 )
		programa.ppa_id = programa.ppa_id + 1
		programa.save
		expect( programa.errors[:ppa_id] ).to include "não pode ser alterado"
	end

	it "não pode ter o ppa_id diferente do ppa_id do seu orgão" do
		programa = FactoryBot.build( :programa_escolar, :ppa_2014 )
		programa.orgao.ppa_id = programa.orgao.ppa_id + 1
		programa.save
		expect( programa.errors[:ppa_id] ).to include "deve ser o mesmo PPA do Orgão Responsável"
	end

	it "valida se metodo codigo_com_zeros esta retornando zeros necessarios" do
		programa_escolar = FactoryBot.create( :programa_escolar, :ppa_2014 )
		expect( programa_escolar.codigo_com_zeros ).to eq( programa_escolar.codigo.digitos(3) )
	end

	describe "#sugestao_de_codigo" do
		before(:each) do
			@tipo_de_programa_1 = FactoryBot.create(:programas_tematicos)
			@tipo_de_programa_2 = FactoryBot.create(:programas_de_gestao_e_manutencao)
		end

		context "quando não há programas cadastrados" do
			it "retorna 01" do
				programa = Ppa::Programa.new( FactoryBot.attributes_for( :programa_escolar, :ppa_2014, codigo: nil, tipo_de_programa_id: @tipo_de_programa_1.id ) )

				expect(programa.codigo).to eq 1
			end
		end

		context "quando há programas cadastrados" do
			it "retorna o próximo código" do
				programa_0001 = Ppa::Programa.new(FactoryBot.attributes_for( :programa_escolar, :ppa_2014, codigo: nil, tipo_de_programa_id: @tipo_de_programa_1.id ))
				programa_0001.save(validate: false)
				programa_0002 = Ppa::Programa.new( FactoryBot.attributes_for( :programa_escolar, :ppa_2014, codigo: nil, tipo_de_programa_id: @tipo_de_programa_1.id ) )

				expect(programa_0002.codigo).to eq 2
			end
		end

		context "quando há lacunas na sequência dos códigos" do
			it "retorna a primeira lacuna" do
				programa_0003 = Ppa::Programa.new(FactoryBot.attributes_for( :programa_escolar, :ppa_2014, codigo: "003", tipo_de_programa_id: @tipo_de_programa_1.id ))
				programa_0003.save(validate: false)

				programa_0001 = Ppa::Programa.new( FactoryBot.attributes_for( :programa_escolar, :ppa_2014, codigo: nil, tipo_de_programa_id: @tipo_de_programa_1.id ) )

				expect(programa_0001.codigo).to eq 1
			end
		end
	end
end
