require 'rails_helper'

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

	# Isso deve retornar o mínimo de atributos obrigatórios para criar uma
	# ação válida.
	let(:atributos_validos) {
		FactoryBot.attributes_for(:programa_bolsa_familia, :orcamento_2016)
	}

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

	let(:orcamento_2016) {
		FactoryBot.attributes_for(:orcamento_2016)
	}

	describe "GET #index" do
		context 'quando não é especificado formato' do
			it "retorna apenas os programas do ppa atual da sessão" do
				orcamento_2016 = Orcamento.find(@request.session[:contexto_id])
				programa_2016 = FactoryBot.create(:programa_bolsa_familia, orcamento: orcamento_2016 )
				programa_2017 = FactoryBot.create(:programa_bolsa_familia, :orcamento_2017 )
				get :index, {exercicio: orcamento_2016.to_param}
				expect( assigns[:programas_de_governo]).to eq( [programa_2016] )
				expect( assigns[:programas_de_governo]).to_not include( programa_2017 )
			end
		end

		context 'quando o formato utilizado é PDF' do
			it 'retorna um arquivo PDF' do
				orcamento_2016 = Orcamento.find(@request.session[:contexto_id])
				get :index, {exercicio: orcamento_2016.to_param, format: :pdf}
				expect(response.headers["Content-Type"]).to eq "application/pdf"
			end
	end
	end

	describe "GET #new" do
		it "atribui um(a) novo(a) programa_de_governo ao @programa_de_governo" do
			tipo_de_programa_tematico = FactoryBot.create(:tipo_de_programa_tematico)

			programa_de_governo = Loa::ProgramaDeGoverno.create! atributos_validos
			get :new, params: { id: programa_de_governo.to_param, exercicio: orcamento_2016[:exercicio], tipo_de_programa_id: tipo_de_programa_tematico.id }
			expect(assigns(:programa_de_governo)).to be_a_new(Loa::ProgramaDeGoverno)
		end
	end

	describe "GET #show" do
		it "atribui o programa_de_governo requisitado(a) ao @programa_de_governo" do
			programa_de_governo = Loa::ProgramaDeGoverno.create! atributos_validos
			get :show, params: {id: programa_de_governo.to_param}
			expect(assigns(:programa_de_governo)).to eq(programa_de_governo)
		end
	end

	describe "GET #edit" do
		context 'não importado do ppa' do
			it "atribui o programa_de_governo requisitado ao @programa_de_governo" do
				programa_de_governo = Loa::ProgramaDeGoverno.create! atributos_validos
				get :edit, params: {id: programa_de_governo.to_param}
				expect(assigns(:programa_de_governo)).to eq(programa_de_governo)
			end
		end
		context 'importado do ppa' do
			it "atribui o programa_de_governo requisitado ao @programa_de_governo" do
				programa_de_governo = Loa::ProgramaDeGoverno.create!(atributos_validos)
				programa_de_governo.programa_id = 1
				programa_de_governo.save
				get :edit, params: {id: programa_de_governo.to_param}
				expect(response).to redirect_to(loa_programas_de_governo_path(programa_de_governo.orcamento))
			end
		end
	end

	describe "POST #create" do
		context "com parâmetros válidos" do
			it "cria um novo programa_de_governo" do
				expect {
					post :create, params: {loa_programa_de_governo: atributos_validos, exercicio: orcamento_2016[:exercicio]}
				}.to change(Loa::ProgramaDeGoverno, :count).by(1)
			end

			it "atribui o programa_de_governo recém criado ao @programa_de_governo" do
				post :create, params: {loa_programa_de_governo: atributos_validos, exercicio: orcamento_2016[:exercicio]}
				expect(assigns(:programa_de_governo)).to be_a(Loa::ProgramaDeGoverno)
				expect(assigns(:programa_de_governo)).to be_persisted
			end

			it "redireciona para o programa_de_governo criado" do
				post :create, params: {loa_programa_de_governo: atributos_validos, exercicio: orcamento_2016[:exercicio]}
				expect(response).to redirect_to(Loa::ProgramaDeGoverno.last)
			end

			context "com o param 'mantem_form'" do
				it "redireciona para a tela de cadastro de programa de governo" do
					post :create, params: {loa_programa_de_governo: atributos_validos, exercicio: orcamento_2016[:exercicio], manter_form: true}
					expect(response).to redirect_to( action: :new)
				end
			end

			context "sem o param 'mantem_form'" do
				it "redireciona para o programa de governo cadastrado" do
					post :create, params: {loa_programa_de_governo: atributos_validos, exercicio: orcamento_2016[:exercicio] }
					expect(response).to redirect_to( assigns(:programa_de_governo) )
				end
			end
		end

		context "com parâmetros inválidos" do
			it "atribui um programa_de_governo recém criado, mas não salvo, ao @programa_de_governo" do
				post :create, params: {loa_programa_de_governo: atributos_invalidos, exercicio: orcamento_2016[:exercicio]}
				expect(assigns(:programa_de_governo)).to be_a_new(Loa::ProgramaDeGoverno)
			end

			it "re-renderiza o template 'new'" do
				post :create, params: {loa_programa_de_governo: atributos_invalidos, exercicio: orcamento_2016[:exercicio]}
				expect(response).to render_template("new")
			end
		end
	end

	describe "PUT #update" do
		context "com parâmetros válidos" do
			let(:novos_atributos) {
				{ nome: 'novo nome' }
			}

			it "atualiza o programa_de_governo requisitado" do
				programa_de_governo = Loa::ProgramaDeGoverno.create! atributos_validos
				post :update, params: {id: programa_de_governo.id, loa_programa_de_governo: novos_atributos}
				programa_de_governo.reload
				expect( programa_de_governo.nome ).to eq 'novo nome'
			end

			it "atribui o programa_de_governo requisitado ao @programa_de_governo" do
				programa_de_governo = Loa::ProgramaDeGoverno.create! atributos_validos
				post :update, params: {id: programa_de_governo.id, loa_programa_de_governo: atributos_validos}
				expect(assigns(:programa_de_governo)).to eq(programa_de_governo)
			end

			it "redireciona para o programa_de_governo" do
				programa_de_governo = Loa::ProgramaDeGoverno.create! atributos_validos
				post :update, params: {id: programa_de_governo.id, loa_programa_de_governo: atributos_validos}
				expect(response).to redirect_to(programa_de_governo)
			end
		end

		context "com parâmetros inválidos" do
			it "atribui o programa_de_governo ao @programa_de_governo" do
				programa_de_governo = Loa::ProgramaDeGoverno.create! atributos_validos
				post :update, params: {id: programa_de_governo.id, loa_programa_de_governo: atributos_invalidos}
				expect(assigns(:programa_de_governo)).to eq(programa_de_governo)
			end

			it "re-renderiza o template 'edit'" do
				programa_de_governo = Loa::ProgramaDeGoverno.create! atributos_validos
				post :update, params: {id: programa_de_governo.id, loa_programa_de_governo: atributos_invalidos}
				expect(response).to render_template("edit")
			end
		end
	end

	describe "DELETE #destroy" do
		it "destrói o programa_de_governo requisitado" do
			programa_de_governo = Loa::ProgramaDeGoverno.create! atributos_validos
			expect {
				delete :destroy, params: { id: programa_de_governo.to_param}
			}.to change(Loa::ProgramaDeGoverno, :count).by(-1)
		end

		it "redireciona para a lista de programas de governo" do
			programa_de_governo = Loa::ProgramaDeGoverno.create! atributos_validos
			delete :destroy, params: { id: programa_de_governo.to_param }
			expect(response).to redirect_to(loa_programas_de_governo_url(programa_de_governo.orcamento))
		end
	end

	describe "GET #importar" do
		it "lista programas não importados" do
			@programa_do_ppa = FactoryBot.create(:programa_escolar, :ppa_2014 )
			@orcamento = Orcamento.last
			@orcamento.ppa_id =  @programa_do_ppa.ppa_id
			@orcamento.save(validate: false)

			get :prepara_importacao, { exercicio: @orcamento.exercicio }

			expect(assigns(:ppa_programas)).to eq([@programa_do_ppa])
		end
	end

	describe "GET #importa" do
		context 'nenhum programa selecionado' do
			it "redireciona para a lista de programas de governo" do
				@orcamento = Orcamento.last
				Loa::ProgramaDeGoverno.create! atributos_validos
				post :importar, { exercicio: @orcamento.exercicio }
				expect(response).to redirect_to(importar_programas_do_ppa_path(@orcamento))
			end
		end

		context 'programas selecionados' do
			it 'deve conter um programa marcado como importado' do
				@programa_do_ppa = FactoryBot.create(:programa_escolar, :ppa_2014, codigo: '102')
				@orcamento = Orcamento.last
				@orcamento.ppa_id =  @programa_do_ppa.ppa_id
				@orcamento.save(validate: false)

				programa_de_governo = Loa::ProgramaDeGoverno.create! atributos_validos
				programa_de_governo.programa_id = @programa_do_ppa.id
				programa_de_governo.importar_dados_do_programa
				programa_de_governo.save

				expect(@orcamento.programas_de_governo.where("programa_id is not null").count).to be > 0
			end
		end
	end

end
