require 'rails_helper'

RSpec.describe Base::NaturezasDaReceitaController, type: :controller do
	sign_in_admin
	set_orcamento_na_sessao

	let(:natureza_da_receita_corrente) {
		FactoryBot.create(:nova_natureza_receita_corrente)
	}

	let(:natureza_da_receita_corrente_pai) {
		FactoryBot.create(:nova_natureza_receita_corrente_pai)
	}

	let(:atributos_validos) {
		{
			descricao: 'Teste de atributos validos',
			codigo: '05',
			tipo_de_orcamento_id: Base::TipoDeOrcamento.find_or_create_by!( FactoryBot.attributes_for(  :orcamento_fiscal, :orcamento_2016 ) ).id
		}
	}

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


	describe "GET #index" do
		it "atribui a lista de naturezadareceitas à @natureza_da_receitas" do
			natureza_da_receita = natureza_da_receita_corrente
			get :index, modulo: 'orcamento', exercicio: '2016'
			expect(assigns(:naturezas_da_receita)).to eq([natureza_da_receita])
		end
	end

	describe "GET #show" do
		it "atribui a natureza da receita à @natureza_da_receita" do
			natureza_da_receita = natureza_da_receita_corrente
			get :show, id: natureza_da_receita.id
			expect(assigns(:natureza_da_receita)).to eq(natureza_da_receita)
		end
	end

	describe "GET #configurar_natureza_da_receita" do
		it "atribui a natureza da receita requisitado à @natureza_da_receita" do
			@natureza_da_receita = natureza_da_receita_corrente
			get :configurar_natureza_da_receita, { modulo: 'orcamento', exercicio: '2016', id: @natureza_da_receita.id }
			expect(assigns(:natureza_da_receita)).to eq(@natureza_da_receita)
		end
	end

	describe "GET #configurar_natureza_da_receita_update" do
		it "atribui a natureza da receita requisitado à @natureza_da_receita" do
			@natureza_da_receita = natureza_da_receita_corrente
			put :configurar_natureza_da_receita_update,  modulo: 'orcamento', exercicio: '2016', id: @natureza_da_receita, base_natureza_da_receita: { id: @natureza_da_receita }
			expect(assigns(:natureza_da_receita)).to eq(@natureza_da_receita)
		end
	end

	describe "GET #new" do
		it "atribui uma nova natureza da receita à @natureza_da_receita" do
			get :new, modulo: 'orcamento', exercicio: '2016'
			expect(assigns(:natureza_da_receita)).to be_a_new(Base::NaturezaDaReceita)
		end
	end

	describe "GET #edit" do
		it "atribui a natureza da receita requisitado à @natureza_da_receita" do
			natureza_da_receita = natureza_da_receita_corrente
			get :edit, params: {id: natureza_da_receita.to_param, modulo: 'orcamento'.to_param, exercicio: '2016'.to_param}
			expect(assigns(:natureza_da_receita)).to eq(natureza_da_receita)
		end
	end

	describe "POST #create" do
		context "com parâmetros válidos" do
			it "cria uma nova natureza da receita" do
				receita = natureza_da_receita_corrente

				expect {
					post :create, params: { modulo: 'orcamento', exercicio: '2016', base_natureza_da_receita: atributos_validos,
					possivel_pai: Base::NaturezaDaReceita.find_by(codigo: receita.codigo) }
				}.to change(Base::NaturezaDaReceita, :count).by(1)
			end

			it "atribui a natureza da receita recém criado(a) à @natureza_da_receita" do
				receita = natureza_da_receita_corrente
				post :create, params: { modulo: 'orcamento', exercicio: '2016', base_natureza_da_receita: atributos_validos,
				possivel_pai: Base::NaturezaDaReceita.find_by(codigo: receita.codigo) }
				expect(assigns(:natureza_da_receita)).to be_a(Base::NaturezaDaReceita)
				expect(assigns(:natureza_da_receita)).to be_persisted
			end

			context "com o param 'mantem_form'" do
				it "redireciona a tela de cadastro de natureza da receita" do
					receita = natureza_da_receita_corrente
					post :create, params: { modulo: 'orcamento', exercicio: '2016', base_natureza_da_receita: atributos_validos,
					possivel_pai: Base::NaturezaDaReceita.find_by(codigo: receita.codigo), manter_form: true }
					expect(response).to redirect_to( action: :new)
				end
			end

			context "sem o param 'mantem_form'" do
				it "redireciona para a natureza da receita cadastrada" do
					receita = natureza_da_receita_corrente
					post :create, params: { modulo: 'orcamento', exercicio: '2016', base_natureza_da_receita: atributos_validos,
					possivel_pai: Base::NaturezaDaReceita.find_by(codigo: receita.codigo) }
					expect(response).to redirect_to base_naturezas_da_receita_path('orcamento', '2016')
				end
			end
		end

		context "com parâmetros inválidos" do
			it "atribui uma natureza da receita recém criada, mas não salva, à @natureza_da_receita" do
				receita = natureza_da_receita_corrente
				post :create, params: { modulo: 'orcamento', exercicio: '2016', base_natureza_da_receita: atributos_invalidos,
				possivel_pai: Base::NaturezaDaReceita.find_by(codigo: receita.codigo) }
				expect(assigns(:natureza_da_receita)).to be_a_new(Base::NaturezaDaReceita)
			end

			it "re-renderiza o template 'new'" do
				receita = natureza_da_receita_corrente
				post :create, params: { modulo: 'orcamento', exercicio: '2016', base_natureza_da_receita: atributos_invalidos,
				possivel_pai: Base::NaturezaDaReceita.find_by(codigo: receita.codigo) }
				expect(response).to render_template("new")
			end
		end
	end

	describe "PUT #update" do
		context "com parâmetros válidos" do
			let(:novos_atributos) {
				{descricao: 'Teste de atributos validos', codigo: '05', tipo_de_receita: "financeira"}
			}

			it "atualiza a natureza da receita requisitado(a)" do
				natureza_da_receita_corrente_pai
				natureza_da_receita = natureza_da_receita_corrente
				post :update, params: {id: natureza_da_receita.to_param, base_natureza_da_receita: novos_atributos}
				natureza_da_receita.reload
				expect( natureza_da_receita.descricao ).to eq 'Teste de atributos validos'
			end

			it "atribui o(a) natureza da receita requisitado(a) à @natureza_da_receita" do
				natureza_da_receita_corrente_pai
				natureza_da_receita = natureza_da_receita_corrente
				post :update, params: {id: natureza_da_receita.to_param, base_natureza_da_receita: atributos_validos}
				expect(assigns(:natureza_da_receita)).to eq(natureza_da_receita)
			end

			it "redireciona para a natureza da receita" do
				natureza_da_receita_corrente_pai
				natureza_da_receita = natureza_da_receita_corrente
				post :update, params: {id: natureza_da_receita.to_param, base_natureza_da_receita: atributos_validos}

				expect(response).to redirect_to base_naturezas_da_receita_path('orcamento', '2016')
			end
		end

		context "com parâmetros inválidos" do
			it "atribui o(a) natureza_da_receita à @natureza_da_receita" do
				natureza_da_receita = natureza_da_receita_corrente
				post :update, params: {id: natureza_da_receita.to_param, base_natureza_da_receita: atributos_invalidos}
				expect(assigns(:natureza_da_receita)).to eq(natureza_da_receita)
			end

			it "re-renderiza o template 'edit'" do
				natureza_da_receita = natureza_da_receita_corrente
				post :update, params: {id: natureza_da_receita.to_param, base_natureza_da_receita: atributos_invalidos}
				expect(response).to render_template("edit")
			end
		end
	end

	describe "DELETE #destroy" do
		it "destrói a natureza da receita requisitada" do
			natureza_da_receita = FactoryBot.create(:nova_natureza_receita_corrente, :criar_niveis_acima)

			expect {
				delete :destroy, params: {:id => natureza_da_receita.to_param}
			}.to change(Base::NaturezaDaReceita, :count).by(-8)
		end

		it "redireciona para a lista de naturezas da receita" do
			natureza_da_receita = natureza_da_receita_corrente

			delete :destroy, params: {:id => natureza_da_receita.to_param}
			expect(response).to redirect_to( base_naturezas_da_receita_path(@orcamento.class.to_s.downcase, @orcamento.exercicio) )
		end
	end

	describe "GET #detalhar_nova_classificacao" do
		it "busca classificacao do codigo a ser editado" do
			receita = FactoryBot.create(:nova_natureza_receita_corrente, :criar_niveis_acima)

			get :detalhar_nova_classificacao, { id: receita.id, format: :json }

			expect(JSON.parse(response.body)["classificacao_niveis_utilizados"]).to eq '001.1.1.1.01.1.1.50'
			expect(JSON.parse(response.body)["classificacao_niveis_nao_utilizados"]).to eq '00'
			expect(JSON.parse(response.body)["tipo_de_orcamento"]).to eq receita.tipo_de_orcamento.id
			expect(JSON.parse(response.body)["descricao_tipo_de_orcamento"]).to eq receita.tipo_de_orcamento.descricao
			expect(JSON.parse(response.body)["tipo_de_receita"]).to eq receita.tipo_de_receita
			expect(JSON.parse(response.body)["descricao_tipo_de_receita"]).to eq receita.tipo_de_receita.capitalize
		end
	end
end
