require 'rails_helper'

RSpec.describe Licitacao::ProjetosController, type: :controller do
	sign_in_admin
	cria_configuracao_default
	set_licitacao_na_sessao

	let(:atributos_validos) {
		FactoryBot.attributes_for(:licitacao_projeto)
	}

	let(:atributos_invalidos) {
		{ legislacao_id: nil, vigencia: nil }
	}

	describe "GET #confirmar_cancelamento" do
		it "atribui o(a) pedido requisitado à @pedido" do
			projeto = Licitacao::Projeto.create! atributos_validos
			get :confirmar_cancelamento, params: {id: projeto.to_param}
			expect(assigns(:projeto)).to eq(projeto)
		end
	end

	describe "PATCH #cancelar" do
		context "com parâmetros válidos" do
			let(:novos_atributos) {
				{motivo_do_cancelamento: "motivo convincente"}
			}

			it "atualiza o(a) pedido requisitado(a)" do
				projeto = Licitacao::Projeto.create! atributos_validos
				patch :cancelar, params: {id: projeto.to_param, licitacao_projeto: novos_atributos}
				projeto.reload
				expect(projeto.motivo_do_cancelamento).to eq "motivo convincente"
			end

			it "muda status do projeto para 'cancelado'" do
				projeto = Licitacao::Projeto.create! atributos_validos
				patch :cancelar, params: {id: projeto.to_param, licitacao_projeto: novos_atributos}
				projeto.reload
				expect(projeto.cancelado?).to be_truthy
			end

			it "atribui o(a) projeto requisitado(a) à @projeto" do
				projeto = Licitacao::Projeto.create! atributos_validos
				patch :cancelar, params: {id: projeto.to_param, licitacao_projeto: novos_atributos}
				expect(assigns(:projeto)).to eq(projeto)
			end

			it "redireciona para o(a) projeto" do
				projeto = Licitacao::Projeto.create! atributos_validos
				patch :cancelar, params: {id: projeto.to_param, licitacao_projeto: novos_atributos}
				expect(response).to redirect_to(projeto)
			end
		end
	end

	describe "GET #index" do
		it "atribui a lista de agencias à @projetos" do
			projeto = Licitacao::Projeto.create! atributos_validos
			get :index
			expect(assigns(:projetos)).to eq([projeto])
		end
	end

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

	describe "GET #new" do
		context 'quando não é passado um id de pedido' do
			it 'retorna para a lista de pedidos com erro' do
				get :new
				expect(response).to redirect_to(licitacao_projetos_url)
				expect( flash[:alert] ).to eq( "Não é possivel criar um projeto sem pedido" )
			end
		end
		it "atribui um(a) novo(a) pedido à @projeto" do
			projeto = Licitacao::Projeto.create! atributos_validos
			get :new, params: {pedido_id: projeto.pedido.id}
			expect(assigns(:projeto)).to be_a_new(Licitacao::Projeto)
		end
	end

	describe "GET #edit" do
		it "atribui o(a) pedido requisitado à @pedido" do
			projeto = Licitacao::Projeto.create! atributos_validos
			get :edit, params: {id: projeto.id}
			expect(assigns(:projeto)).to eq(projeto)
		end

		it "redireciona para o projeto exceto se estiver aberto" do
			projeto_encaminhado = FactoryBot.attributes_for(:licitacao_projeto, status: "cancelado")
			projeto = Licitacao::Projeto.create! projeto_encaminhado
			get :edit, params: {id: projeto.id}
			expect(response).to redirect_to(projeto)
		end
	end

	describe "POST #create" do
		context "com parâmetros válidos" do
			it "cria um(a) novo(a) Licitacao::Projeto" do
				expect {
					post :create, params: {licitacao_projeto: atributos_validos}
				}.to change(Licitacao::Projeto, :count).by(1)
			end

			it "atribui o(a) projeto recém criado(a) à @projeto" do
				post :create, params: {licitacao_projeto: atributos_validos}
				expect(assigns(:projeto)).to be_persisted
			end

			it "redireciona para a lista de orgãos" do
				post :create, params: {:licitacao_projeto => atributos_validos}
				expect(response).to redirect_to( licitacao_projeto_path(Licitacao::Projeto.last))
			end
		end

		context "com parâmetros inválidos" do
			it "atribui um(a) projeto recém criado(a), mas não salvo(a), à @projeto" do
				post :create, params: {licitacao_projeto: atributos_invalidos}
				expect(assigns(:projeto)).to be_a_new(Licitacao::Projeto)
			end

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

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

			it "atualiza o(a) projeto requisitado(a)" do
				projeto = Licitacao::Projeto.create! atributos_validos
				post :update, params: {id: projeto.id, licitacao_projeto: novos_atributos}
				projeto.reload
				expect( projeto.numero_do_processo ).to eq "56667"
			end

			it "redireciona para o projeto exceto se estiver aberto" do
				projeto_encaminhado = FactoryBot.attributes_for(:licitacao_projeto, status: "aguardando_publicacao")
				projeto = Licitacao::Projeto.create! projeto_encaminhado
				post :update, params: {id: projeto.id, licitacao_projeto: novos_atributos}
				expect(response).to redirect_to(projeto)
			end
		end

		context "com parâmetros inválidos" do
			it "atribui o(a) projeto à @legislacao" do
				projeto = Licitacao::Projeto.create! atributos_validos
				post :update, params: {id: projeto.to_param, licitacao_projeto: atributos_invalidos}
				expect(assigns(:projeto)).to eq(projeto)
			end

			it "re-renderiza o template 'edit'" do
				projeto = Licitacao::Projeto.create! atributos_validos
				post :update, params: {id: projeto.to_param, licitacao_projeto: atributos_invalidos}
				expect(response).to render_template("edit")
			end
		end
	end

	describe "DELETE #destroy" do
		it "destrói o(a) pedido requisitado(a)" do
			projeto = Licitacao::Projeto.create! atributos_validos
			expect {
				delete :destroy, params: {:id => projeto.id}
			}.to change(Licitacao::Projeto, :count).by(-1)
		end

		it "redireciona para a lista de ppa_orgaos" do
			projeto = Licitacao::Projeto.create! atributos_validos
			delete :destroy, params: {:id => projeto.id}
			expect(response).to redirect_to(licitacao_projetos_url)
		end

		it "redireciona para o projeto exceto se estiver aberto" do
			projeto_encaminhado = FactoryBot.attributes_for(:licitacao_projeto, status: "aguardando_publicacao")
			projeto = Licitacao::Projeto.create! projeto_encaminhado
			delete :destroy, params: {id: projeto.id}
			expect(response).to redirect_to(projeto)
		end
	end

	describe 'GET #selecionar_dotacao' do
		context 'quando está em status permitido' do
			it "atribui um(a) novo(a) orcamento_da_despesa_por_projeto à @orcamento_da_despesa_por_projeto" do
				projeto = Licitacao::Projeto.create! atributos_validos
				get :selecionar_dotacao, params: { id: projeto.id }
				expect(assigns(:orcamento_da_despesa_por_projeto)).to be_a_new(Licitacao::OrcamentoDaDespesaPorProjeto)
			end
		end

		context 'quando está em estado não permitido (cancelado)' do
			it 'redireciona para @projeto' do
				projeto = FactoryBot.create :licitacao_projeto, status: :cancelado
				get :selecionar_dotacao, params: { id: projeto.id }
				expect(response).to redirect_to(projeto)
			end
		end

	end

	describe "POST #adicionar_dotacao" do
		before(:each) do
			@projeto = Licitacao::Projeto.create! atributos_validos
			@orcamento_da_despesa = FactoryBot.create :orcamento_da_despesa_saude
			@sub_elemento_de_despesa = FactoryBot.create :sub_elemento_de_despesa_outros_materiais_de_consumo
		end
		context "com parâmetros válidos" do
			it "cria um novo orçamento da receita" do
				expect {
					post :adicionar_dotacao, params: {id: @projeto.id, licitacao_orcamento_da_despesa_por_projeto: {orcamento_da_despesa_id: @orcamento_da_despesa.id, sub_elemento_de_despesa_id: @sub_elemento_de_despesa.id } }
				}.to change(Licitacao::OrcamentoDaDespesaPorProjeto, :count).by(1)
			end

			context 'com um projeto aberto' do
				it "redireciona o projeto" do
					post :adicionar_dotacao, params: {id: @projeto.id, licitacao_orcamento_da_despesa_por_projeto: {orcamento_da_despesa_id: @orcamento_da_despesa.id, sub_elemento_de_despesa_id: @sub_elemento_de_despesa.id}}
					expect(response).to redirect_to( licitacao_projeto_path(@projeto) + "?tab=dotacoes" )
					expect(flash[:success]).to eq 'Dotação foi adicionada com sucesso.'
				end
			end
		end

		context "com parâmetros inválidos" do
			it "atribui um(a) projeto recém criado(a), mas não salvo(a), à @projeto" do
				post :adicionar_dotacao, params: {id: @projeto.id, licitacao_orcamento_da_despesa_por_projeto: {orcamento_da_despesa_id: nil}}
				expect(assigns(:orcamento_da_despesa_por_projeto)).to be_a_new(Licitacao::OrcamentoDaDespesaPorProjeto)
			end

			it "re-renderiza o template 'new'" do
				post :adicionar_dotacao, params: {id: @projeto.id, licitacao_orcamento_da_despesa_por_projeto: {orcamento_da_despesa_id: nil}}
				expect(response).to render_template("selecionar_dotacao")
			end
		end
	end

	describe "DELETE #excluir_dotacao" do
		it "destrói o orcamento_da_despesa_por_projeto requisitado" do
			orcamento_da_despesa_por_projeto = FactoryBot.create :orcamento_da_despesa_por_projeto
			expect {
				delete :excluir_dotacao, params: {:orcamento_da_despesa_por_projeto_id => orcamento_da_despesa_por_projeto.id}
			}.to change(Licitacao::OrcamentoDaDespesaPorProjeto, :count).by(-1)
		end

		it "redireciona para a lista de ppa_orgaos" do
			orcamento_da_despesa_por_projeto = FactoryBot.create :orcamento_da_despesa_por_projeto
			delete :excluir_dotacao, params: {:orcamento_da_despesa_por_projeto_id => orcamento_da_despesa_por_projeto.id}
			expect(response).to redirect_to(licitacao_projeto_path(orcamento_da_despesa_por_projeto.projeto) + "?tab=dotacoes")
		end
	end

	describe "PATCH #encaminhar_para_comissao" do
		it 'atribui o status encaminhado_para_comissao' do
			projeto = Licitacao::Projeto.create!(FactoryBot.attributes_for(:licitacao_projeto, status: :autorizado, modalidade_de_licitacao: :pregao_presencial))
			projeto.lotes.first.produto!
			patch :encaminhar_para_comissao, params: {id: projeto.to_param}
			expect(projeto.reload.enviado_para_comissao?).to be_truthy
		end
	end

	describe "PATCH #encaminhar_para_controladoria" do
		before(:each) do
			configuracao = Configuracao.last
			configuracao.update_column(:envia_projeto_para_controladoria, true)
		end
		it 'atribui o status encaminhado_para_controladoria, se paramatrizado, e redireciona para o projeto' do
			projeto = Licitacao::Projeto.create!(FactoryBot.attributes_for(:licitacao_projeto, status: :aberto, modalidade_de_licitacao: :pregao_presencial, registro_de_preco: true))
			FactoryBot.create( :licitacao_documento_do_processo, projeto_id: projeto.id, tipo_de_documento: 'termo_de_referencia' )
			projeto.lotes.first.produto!
			patch :encaminhar_para_controladoria, params: {id: projeto.to_param}
			expect(projeto.reload.enviado_para_controladoria?).to be_truthy
			expect(response).to redirect_to(licitacao_projeto_path(projeto))
		end
	end

	describe "PATCH #autorizar" do
		it 'atribui o status autorizado e redireciona para o projeto' do
			projeto = Licitacao::Projeto.create!(FactoryBot.attributes_for(:licitacao_projeto, status: :aguardando_autorizacao, modalidade_de_licitacao: :pregao_presencial, registro_de_preco: true))
			FactoryBot.create( :licitacao_documento_do_processo, projeto_id: projeto.id, tipo_de_documento: 'autorizacao' )
			projeto.lotes.first.produto!
			patch :autorizar, params: {id: projeto.to_param}
			expect(projeto.reload.autorizado?).to be_truthy
			expect(response).to redirect_to(licitacao_projeto_path(projeto))
		end
	end

	describe "GET/arquivo Planilha com os licitantes XLSX" do
		it "gera xlsx" do
			projeto = Licitacao::Projeto.create! atributos_validos
			get :arquivo, params: { id: projeto.id, format: :xlsx }
			expect(response.header['Content-Type']).to include 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=utf-8'
		end
	end
end
