require 'rails_helper'
include ActiveSupport::Testing::TimeHelpers

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

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

	let(:atributos_invalidos) {
		{ unidade_orcamentaria_id: nil }
	}

	let(:pedido_aberto) {
		Licitacao::Pedido.create!(FactoryBot.attributes_for :pedido, status: 'aberto')
	}

	let(:pedido_fechado) {
		FactoryBot.create :pedido, :fechado
	}

	let(:pedido) {
		pedido_aberto
	}

	let(:pedido_cancelado) {
		Licitacao::Pedido.create!(atributos_validos.merge(status: 'cancelado', motivo_do_cancelamento: "motivo"))
	}

	let(:pedido_aguardando_outras_unidades) {
		FactoryBot.create :pedido, :aguardando_outras_unidades
	}

	let(:pedido_coleta_de_preco) {
		Licitacao::Pedido.create!(FactoryBot.attributes_for :pedido, status: :coleta_de_preco)
	}

	describe "GET #index" do
		it "atribui a lista de pedidos à @pedidos" do
			get :index
			expect(assigns(:pedidos)).to eq([pedido])
		end

		it "exclui pedidos de outros orçamentos" do
			pedido = FactoryBot.attributes_for(:pedido, orcamento_id: Orcamento.last.id + 3)
			get :index
			expect(assigns(:pedidos)).to_not eq(pedido)
		end
	end

	describe "GET #show" do
		it "atribui a pedido requisitado(a) à @pedido" do
			get :show, params: {id: pedido.to_param}
			expect(assigns(:pedido)).to eq(pedido)
		end
	end

	describe "GET #new" do
		it "atribui um(a) novo(a) pedido à @pedido" do
			get :new
			expect(assigns(:pedido)).to be_a_new(Licitacao::Pedido)
		end
	end

	describe "GET #edit" do
		context 'quando pedido está aberto' do
			it "atribui o(a) pedido requisitado à @pedido" do
				get :edit, params: {id: pedido.to_param}
				expect(assigns(:pedido)).to eq(pedido)
			end
		end

		[:cancelado].each do |status|
			context "quando pedido está com status #{status}" do
				it "redireciona de volta à @pedido" do
					get :edit, params: {id: send("pedido_#{status}").to_param}
					expect(response).to redirect_to(send("pedido_#{status}"))
					expect(flash[:alert]).to eq("Essa ação não é permitida nessa etapa")
				end
			end
		end
	end

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

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

			context "com o param 'mantem_form'" do
				it "redireciona a tela de atualização de itens" do
					post :create, params: {:licitacao_pedido => atributos_validos, ir_para_itens: true }
					expect(response).to redirect_to( action: :editar_itens, id: Licitacao::Pedido.last.id)
				end
			end

			context "sem o param 'mantem_form'" do
				it "redireciona para o(a) pedido criado(a)" do
					post :create, params: {:licitacao_pedido => atributos_validos}
					expect(response).to redirect_to(Licitacao::Pedido.last)
				end
			end
		end

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

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

	describe "PUT #update" do
		context 'quando é atualização do pedido' do
			context "com parâmetros válidos" do
				let(:novos_atributos) {
					{objeto: "novo objeto"}
				}

				it "atualiza o(a) pedido requisitado(a)" do
					put :update, params: {id: pedido.to_param, licitacao_pedido: novos_atributos}
					pedido.reload
					expect(pedido.objeto).to eq "novo objeto"
				end

				it "atribui o(a) pedido requisitado(a) à @pedido" do
					put :update, params: {id: pedido.to_param, licitacao_pedido: atributos_validos}
					expect(assigns(:pedido)).to eq(pedido)
				end

				it "redireciona para o(a) pedido" do
					put :update, params: {id: pedido.to_param, licitacao_pedido: atributos_validos}
					expect(response).to redirect_to(pedido)
				end
			end

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

				it "re-renderiza o template 'edit'" do
					put :update, params: {id: pedido.to_param, licitacao_pedido: atributos_invalidos}
					expect(response).to render_template("edit")
				end
			end
		end
	end

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

		it "redireciona para a lista de pedidos" do
			delete :destroy, params: {:id => pedido.to_param}
			expect(response).to redirect_to(licitacao_pedidos_url)
		end

		it "pedido está cancelado" do
			pedido_a_ser_destruido = pedido
			pedido_a_ser_destruido.status = :cancelado
			pedido_a_ser_destruido.save(validate: false)
			delete :destroy, params: {:id => pedido_a_ser_destruido.to_param}
			expect(response).to redirect_to(pedido_a_ser_destruido)
		end
	end

	describe "GET #confirmar_cancelamento" do
		it "atribui o(a) pedido requisitado à @pedido" do
			get :edit, params: {id: pedido.to_param}
			expect(assigns(:pedido)).to eq(pedido)
		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
				patch :cancelar, params: {id: pedido.to_param, licitacao_pedido: novos_atributos}
				pedido.reload
				expect(pedido.motivo_do_cancelamento).to eq "motivo convincente"
			end

			it "muda status do pedido para 'cancelado'" do
				patch :cancelar, params: {id: pedido.to_param, licitacao_pedido: novos_atributos}
				pedido.reload
				expect(pedido.cancelado?).to be_truthy
			end

			it "atribui o(a) pedido requisitado(a) à @pedido" do
				patch :cancelar, params: {id: pedido.to_param, licitacao_pedido: novos_atributos}
				expect(assigns(:pedido)).to eq(pedido)
			end

			it "redireciona para o(a) pedido" do
				patch :cancelar, params: {id: pedido.to_param, licitacao_pedido: novos_atributos}
				expect(response).to redirect_to(pedido)
			end
		end
	end

	describe "GET #editar_itens" do
		context 'quando pedido está aberto' do
			it "atribui o(a) pedido requisitado à @pedido" do
				get :editar_itens, params: {id: pedido.to_param}
				expect(assigns(:pedido)).to eq(pedido)
			end

			it 'atribui itens à @itens' do
				item = FactoryBot.create :caderno
				get :editar_itens, params: {id: pedido.to_param}
				expect(assigns(:itens)).to eq([item])
			end
		end

		[:cancelado, :coleta_de_preco].each do |status|
			context "quando pedido está com status #{status}" do
				it "atribui o(a) pedido requisitado à @pedido" do
					get :editar_itens, params: {id: send("pedido_#{status}").to_param}
					expect(response).to redirect_to(send("pedido_#{status}"))
					expect(flash[:alert]).to eq("Essa ação não é permitida nessa etapa")
				end
			end
		end
	end

	describe "GET #busca_itens" do
		context 'quando pedido está aberto' do
			it 'atribui itens à @itens' do
				item = FactoryBot.create :caderno
				get :busca_itens, params: {id: pedido.to_param, q: {descricao_cont: item.descricao}}
				expect(assigns(:itens)).to eq([item])
			end
		end
	end

	describe "PATCH #adiciona_itens" do
		context 'quando é passado itens por parâmetros' do
			it 'adiciona itens à @pedido' do
				item = FactoryBot.create :caderno
				get :adiciona_itens, params: { id: pedido.to_param, itens: [item.id] }
				expect(flash[:notice]).to include "1 item adicionado com sucesso"
			end
		end

		context 'quando não é passado itens por parâmetros' do
			it 'não adiciona itens à @pedido' do
				item = FactoryBot.create :caderno
				get :adiciona_itens, params: {id: pedido.to_param, itens: []}
				expect(pedido.reload.itens_do_pedido.count).to be == 0
			end

			it 'redireciona para a tela anterior' do
				item = FactoryBot.create :caderno
				get :adiciona_itens, params: {id: pedido.to_param, itens: []}
				expect(response).to redirect_to(busca_itens_licitacao_pedido_path(pedido))
			end
		end
	end

	describe 'PATCH #atualizar_itens' do
		context "com parâmetros válidos" do
			let(:atributos_itens) {
				uo = FactoryBot.create :loa_seduc, :orcamento_2016
				unidade_orcamentaria_por_pedido = FactoryBot.create :unidade_orcamentaria_por_pedido, pedido_id: pedido.id, unidade_orcamentaria_id: uo.id
				{
						itens_do_pedido_attributes: {
								'0': {
									item_id: Base::Item.find_or_create_by(FactoryBot.attributes_for :caderno, descricao: "caderno").id,
									itens_do_pedido_por_unidade_orcamentaria_attributes: {
											'0': {
												quantidade: 1,
												unidade_orcamentaria_por_pedido_id: unidade_orcamentaria_por_pedido.id
												}
									}
								}
						}
				}
			}

			it 'atualiza o pedido com os itens' do
				patch :atualizar_itens, params: {id: pedido.to_param, licitacao_pedido: atributos_itens}
				pedido.reload
				expect(pedido.itens_do_pedido.count).to eq 1
				expect(pedido.itens_do_pedido.first.item.descricao).to eq "CADERNO"
				expect(pedido.itens_do_pedido.first.itens_do_pedido_por_unidade_orcamentaria.first.quantidade).to eq 1
			end

			it 'atualiza o pedido com os itens e continua na tela de cadastro de itens' do
				patch :atualizar_itens, params: {id: pedido.to_param, licitacao_pedido: atributos_itens, continuar_editando: "Salvar e continuar"}
				pedido.reload
				expect(pedido.itens_do_pedido.count).to eq 1
				expect(pedido.itens_do_pedido.first.item.descricao).to eq "CADERNO"
				expect(pedido.itens_do_pedido.first.itens_do_pedido_por_unidade_orcamentaria.first.quantidade).to eq 1
				expect(response).to redirect_to(itens_licitacao_pedido_path(pedido))
			end
		end

		context "com parâmetros inválidos" do
			let(:itens_invalidos) {
				unidade_orcamentaria_por_pedido = FactoryBot.create :unidade_orcamentaria_por_pedido, pedido_id: pedido.id
				{
						itens_do_pedido_attributes: {
								'0': {
									item_id: Base::Item.find_or_create_by(FactoryBot.attributes_for :caderno).id,
									itens_do_pedido_por_unidade_orcamentaria_attributes: {
											'0': {
												quantidade: 0,
												unidade_orcamentaria_por_pedido_id: unidade_orcamentaria_por_pedido.id
												}
									}
								}
						}
				}
			}
			it 're-renderiza o template :editar_itens' do
				patch :atualizar_itens, params: {id: pedido.to_param, licitacao_pedido: itens_invalidos}
				expect(response).to render_template("editar_itens")
			end
		end
	end

	describe "GET #editar_unidades_orcamentarias" do
		context 'quando pedido está aberto' do
			it "atribui o(a) pedido requisitado à @pedido" do
				get :editar_unidades_orcamentarias, params: {id: pedido.to_param}
				expect(assigns(:pedido)).to eq(pedido)
			end

			it 'atribui_unidades_orcamentarias à _unidades_orcamentarias' do
				unidade_orcamentaria = FactoryBot.create :loa_fes, :orcamento_2016
				get :editar_unidades_orcamentarias, params: {id: pedido.to_param}
				expect(assigns(:unidades_orcamentarias)).to eq([unidade_orcamentaria])
			end
			it "quando as unidades estiverem dentro do prazo" do
				pedido_aguardando_outras_unidades.update(data_limite_para_complementacao: (Date.today))
				pedido_aguardando_outras_unidades.reload
				get :editar_unidades_orcamentarias, params: {id: pedido_aguardando_outras_unidades.to_param}
				expect(assigns(:pedido)).to eq(pedido_aguardando_outras_unidades)
			end
			it "quando as unidades estiverem fora do prazo" do
				pedido_aguardando_outras_unidades.update(data_limite_para_complementacao: (Date.today + 10))
				pedido_aguardando_outras_unidades.reload
				get :editar_unidades_orcamentarias, params: {id: pedido_aguardando_outras_unidades.to_param}
				expect(response).to redirect_to(pedido_aguardando_outras_unidades)
			end
		end

		[:cancelado, :aguardando_outras_unidades, :coleta_de_preco].each do |status|
			context "quando pedido está com status #{status}" do
				it "atribui o(a) pedido requisitado à @pedido" do
					get :editar_unidades_orcamentarias, params: {id: send("pedido_#{status}").to_param}
					expect(response).to redirect_to(send("pedido_#{status}"))
					expect(flash[:alert]).to eq("Essa ação não é permitida nessa etapa")
				end
			end
		end
	end

	describe 'PATCH #atualizar_unidades_orcamentarias' do
		context 'atualizar e redirecionar' do
			it 'atualizando e redirecionando' do
				atributos_uo_por_pedido = {
					unidades_orcamentarias_por_pedido_attributes: {
						'0': {
							id: pedido_fechado.unidades_orcamentarias_por_pedido.first.id
							},
						'1': {
							unidade_orcamentaria_id: (FactoryBot.create :loa_fes, :orcamento_2016),
							_destroy: false
						}
					}
				}
				patch :atualizar_unidades_orcamentarias, params: {id: pedido_fechado.to_param, licitacao_pedido:atributos_uo_por_pedido}
				expect{pedido_fechado.reload}.to change{pedido_fechado.unidades_orcamentarias_por_pedido}
				expect(response).to redirect_to(licitacao_pedido_path(pedido_fechado) + "?tab=unidades_orcamentarias")
				expect(flash[:notice]).to include "Unidades do pedido atualizadas com sucesso."
			end
		end
	end

	describe 'GET #editar_quantidades' do
		it "atribui o(a) pedido requisitado à @pedido" do
			get :editar_quantidades, params: {id: pedido.to_param}
			expect(assigns(:pedido)).to eq(pedido)
		end
		it "quando as unidades estiverem dentro do prazo" do
			pedido_aguardando_outras_unidades.update(data_limite_para_complementacao: (Date.today))
			pedido_aguardando_outras_unidades.reload
			get :editar_quantidades, params: {id: pedido_aguardando_outras_unidades.to_param}
			expect(assigns(:pedido)).to eq(pedido_aguardando_outras_unidades)
			expect(response).to render_template(:editar_quantidades)
		end
		it "quando as unidades estiverem fora do prazo" do
			pedido_aguardando_outras_unidades.reload
			get :editar_quantidades, params: {id: pedido_aguardando_outras_unidades.to_param}
			expect(response).to redirect_to(pedido_aguardando_outras_unidades)
			expect(flash[:notice]).to include "Prazo para as unidades convidadas foram encerradas."
		end
	end

	describe 'PATCH #atualizar_quantidades' do
		#teste está quebrando
		let(:unidade_orcamentaria_por_pedido) {
			unidade_orcamentaria_por_pedido = Licitacao::UnidadeOrcamentariaPorPedido.find_or_create_by(FactoryBot.attributes_for :unidade_orcamentaria_por_pedido, pedido_id: pedido.id)
		}
		context 'valores validos' do
			it 'atualizando e redirecionando' do
				item_do_pedido_por_unidade = pedido_aguardando_outras_unidades.reload.itens_do_pedido.first.itens_do_pedido_por_unidade_orcamentaria.last
				atributos_itens_do_pedido = {
					itens_do_pedido_attributes:{
					"0":{
						id: pedido_aguardando_outras_unidades.reload.itens_do_pedido.first.id,
						itens_do_pedido_por_unidade_orcamentaria_attributes:{
							"0":{
									id: pedido_aguardando_outras_unidades.reload.itens_do_pedido.first.itens_do_pedido_por_unidade_orcamentaria.last.id,
									quantidade: 199,
									unidade_orcamentaria_por_pedido_id: unidade_orcamentaria_por_pedido
								}
							}
						}
					}
			}
				patch :atualizar_quantidades, params: {id: pedido_aguardando_outras_unidades.to_param, licitacao_pedido: atributos_itens_do_pedido, unidade_id:Loa::UnidadeOrcamentaria.find_or_create_by(FactoryBot.attributes_for(:loa_fes, :orcamento_2016) )}
				expect(item_do_pedido_por_unidade.quantidade).to_not eq(pedido_aguardando_outras_unidades.reload.itens_do_pedido.first.itens_do_pedido_por_unidade_orcamentaria.last.quantidade)
				expect(response).to redirect_to(licitacao_pedido_path(pedido_aguardando_outras_unidades, tab: "unidades_orcamentarias"))
				expect(flash[:notice]).to include 'Pedido foi atualizado com sucesso.'
			end
		end

		context 'valores invalidos'do
			it 'falhando e redenderizando de volta' do
				quantidade_invalida_params = {itens_do_pedido_attributes:{
					"0":{
						id: pedido_aguardando_outras_unidades.reload.itens_do_pedido.first.id,
						itens_do_pedido_por_unidade_orcamentaria_attributes:{
							"0":{
									id: pedido_aguardando_outras_unidades.reload.itens_do_pedido.first.itens_do_pedido_por_unidade_orcamentaria.last.id,
									quantidade: 'quantidade',
									unidade_orcamentaria_por_pedido_id: unidade_orcamentaria_por_pedido
								}
							}
						}
					}
				}
				patch :atualizar_quantidades, params: {id: pedido_aguardando_outras_unidades.to_param, licitacao_pedido: quantidade_invalida_params, unidade_id:Loa::UnidadeOrcamentaria.find_or_create_by(FactoryBot.attributes_for(:loa_fes, :orcamento_2016) )}
				pedido_aguardando_outras_unidades.reload
				expect(response).to render_template(:editar_quantidades)
			end
		end
	end

	describe "GET #editar_pessoas" do
		context 'quando pedido está ativo' do
			it "atribui o(a) pedido requisitado à @pedido" do
				get :editar_pessoas, params: {id: pedido.to_param}
				expect(assigns(:pedido)).to eq(pedido)
			end
		end

		context 'quando pedido não está ativo' do
			it "atribui o(a) pedido requisitado à @pedido" do
				get :editar_pessoas, params: {id: pedido_cancelado.to_param}
				expect(response).to redirect_to(pedido_cancelado)
				expect(flash[:alert]).to eq("Essa ação não é permitida nessa etapa")
			end
		end
	end

	describe '#atualizar_pessoas' do
		context "com parâmetros válidos" do
			let(:atributos_pessoas) {
				{
						pessoas_do_pedido_attributes: {
								'0': { pessoa_id: Base::Pessoa.find_or_create_by(FactoryBot.attributes_for :pessoa_juridica, nome: "teste").id }
						}
				}
			}

			it 'atualiza o pedido com as pessoas' do
				patch :atualizar_pessoas, params: {id: pedido.to_param, licitacao_pedido: atributos_pessoas}
				pedido.reload
				expect(pedido.pessoas_do_pedido.count).to eq 1
				expect(pedido.pessoas_do_pedido.first.pessoa.nome).to eq "teste"
			end
		end

		context "com parâmetros inválidos" do
			let(:pessoas_invalidas) {
				id = Base::Pessoa.find_or_create_by(FactoryBot.attributes_for :pessoa_juridica, nome: "teste").id
				{
						pessoas_do_pedido_attributes: {
								'0': { pessoa_id: id },
								'1': { pessoa_id: id }
						}
				}
			}
			it 're-renderiza o template :editar_pessoas' do
				patch :atualizar_pessoas, params: {id: pedido.to_param, licitacao_pedido: pessoas_invalidas}
				expect(response).to render_template("editar_pessoas")
			end
		end
	end

	describe "POST #anular_item" do
		context "com parâmetros válidos" do
			let(:anular_atributos) {
				{motivo: "motivo convincente"}
			}

			let(:item_do_pedido) {
				Licitacao::ItemDoPedido.find_or_create_by(FactoryBot.attributes_for :item_do_pedido)
			}

			it "atualiza o(a) motivo do preço da cotação requisitado(a)" do
				post :anular_item, params: {id: pedido_coleta_de_preco.to_param, item_do_pedido_id: item_do_pedido.id, licitacao_item_do_pedido: anular_atributos}
				item_do_pedido.reload
				expect(item_do_pedido.motivo).to eq "motivo convincente"
			end

			it "muda status do preço da cotação para 'não válido'" do
				post :anular_item, params: {id: pedido_coleta_de_preco.to_param, item_do_pedido_id: item_do_pedido.id, licitacao_item_do_pedido: anular_atributos}
				item_do_pedido.reload
				expect(item_do_pedido.valido?).to be_falsy
			end

			it "redireciona para o(a) cotação" do
				post :anular_item, params: {id: pedido_coleta_de_preco.to_param, item_do_pedido_id: item_do_pedido.id, licitacao_item_do_pedido: anular_atributos}
				expect(response).to redirect_to(licitacao_pedido_path(pedido_coleta_de_preco)  + "?tab=itens_do_pedido")
			end
		end

		context "com parâmetros inválidos" do
			let(:anular_atributos_invalidos) {
				{motivo_do_cancelamento: ""}
			}

			let(:item_do_pedido) {
				Licitacao::ItemDoPedido.find_or_create_by(FactoryBot.attributes_for :item_do_pedido)
			}

			it "atribui o(a) pedido à @pedido e item_do_pedido_por_pessoa à @item_do_pedido_por_pessoa" do
				put :anular_item, params: {id: pedido_coleta_de_preco.to_param, item_do_pedido_id: item_do_pedido.id, licitacao_item_do_pedido: anular_atributos_invalidos}
				expect(assigns(:pedido)).to eq(pedido_coleta_de_preco)
				expect(assigns(:item_do_pedido)).to eq(item_do_pedido)
			end

			it "re-renderiza o template 'preco'" do
				put :anular_item, params: {id: pedido_coleta_de_preco.to_param, item_do_pedido_id: item_do_pedido.id, licitacao_item_do_pedido: anular_atributos_invalidos}
				expect(response).to render_template("motivo_anular_item")
			end
		end
	end

	describe "GET #preco" do
		before(:each) do
			@pessoa_do_pedido = FactoryBot.create :pessoa_do_pedido, pedido_id: pedido_coleta_de_preco.id
		end
		context 'quando pedido está ativo' do
			context 'quando o parâmetro corresponde a um preço da cotação' do
				it 'inicializa valores para cotação do fornecedor' do
					item_do_pedido_por_pessoa = FactoryBot.create :licitacao_item_do_pedido_por_pessoa, pessoa_do_pedido_id: @pessoa_do_pedido.id
					get :preco, params: {id: pedido_coleta_de_preco.to_param, item_do_pedido_por_pessoa_id: item_do_pedido_por_pessoa.id}
					expect(assigns(:pedido)).to eq(pedido_coleta_de_preco)
					expect(assigns(:item_do_pedido_por_pessoa)).to eq(item_do_pedido_por_pessoa)
				end
			end
		end

		context 'quando o parâmetro não corresponde a um preço da cotação do pedido' do
			it 'redireciona para o pedido' do
				item_do_pedido_por_pessoa = FactoryBot.create :licitacao_item_do_pedido_por_pessoa, pessoa_do_pedido_id: @pessoa_do_pedido.id
				get :preco, params: {id: pedido_coleta_de_preco.to_param, item_do_pedido_por_pessoa_id: item_do_pedido_por_pessoa.id + 1}
				expect(response).to redirect_to(pedido_coleta_de_preco)
				expect(flash[:alert]).to include 'Fornecedor não existe'
			end
		end

		context 'quando pedido não está ativo' do
			it "atribui o(a) pedido requisitado à @pedido" do
				item_do_pedido_por_pessoa = FactoryBot.create :licitacao_item_do_pedido_por_pessoa, pessoa_do_pedido_id: @pessoa_do_pedido.id
				get :preco, params: {id: pedido_cancelado.to_param, item_do_pedido_por_pessoa_id: item_do_pedido_por_pessoa.id}
				expect(response).to redirect_to(pedido_cancelado)
				expect(flash[:alert]).to eq("Essa ação não é permitida nessa etapa")
			end
		end
	end

	describe "POST #anular_preco" do
		context "com parâmetros válidos" do
			let(:anular_atributos) {
				{motivo: "motivo convincente"}
			}

			let(:item_do_pedido_por_pessoa) {
				Licitacao::ItemDoPedidoPorPessoa.find_or_create_by(FactoryBot.attributes_for :licitacao_item_do_pedido_por_pessoa)
			}

			it "atualiza o(a) motivo do preço da cotação requisitado(a)" do
				post :anular_preco, params: {id: pedido_coleta_de_preco.to_param, item_do_pedido_por_pessoa_id: item_do_pedido_por_pessoa.id, licitacao_item_do_pedido_por_pessoa: anular_atributos}
				item_do_pedido_por_pessoa.reload
				expect(item_do_pedido_por_pessoa.motivo).to eq "motivo convincente"
			end

			it "muda status do preço da cotação para 'não válido'" do
				post :anular_preco, params: {id: pedido_coleta_de_preco.to_param, item_do_pedido_por_pessoa_id: item_do_pedido_por_pessoa.id, licitacao_item_do_pedido_por_pessoa: anular_atributos}
				item_do_pedido_por_pessoa.reload
				expect(item_do_pedido_por_pessoa.valido?).to be_falsy
			end

			it "redireciona para o(a) cotação" do
				post :anular_preco, params: {id: pedido_coleta_de_preco.to_param, item_do_pedido_por_pessoa_id: item_do_pedido_por_pessoa.id, licitacao_item_do_pedido_por_pessoa: anular_atributos}
				expect(response).to redirect_to(mapa_licitacao_pedido_path(pedido_coleta_de_preco))
			end

			it "muda status do preço da cotação para 'não válido' pela cotação" do
				post :anular_preco, params: {id: pedido_coleta_de_preco.to_param, item_do_pedido_por_pessoa_id: item_do_pedido_por_pessoa.id, licitacao_item_do_pedido_por_pessoa: anular_atributos, cotacao: true}
				item_do_pedido_por_pessoa.reload
				expect(item_do_pedido_por_pessoa.valido?).to be_falsy
			end

			it "redireciona para o(a) o pedido da cotação" do
				post :anular_preco, params: {id: pedido_coleta_de_preco.to_param, item_do_pedido_por_pessoa_id: item_do_pedido_por_pessoa.id, licitacao_item_do_pedido_por_pessoa: anular_atributos, cotacao: true, :pessoa_do_pedido_id => item_do_pedido_por_pessoa.pessoa_do_pedido.id}
				expect(response).to redirect_to(licitacao_pessoa_do_pedido_path(item_do_pedido_por_pessoa.pessoa_do_pedido.id))
			end
		end

		context "com parâmetros inválidos" do
			let(:anular_atributos_invalidos) {
				{motivo_do_cancelamento: ""}
			}

			let(:item_do_pedido_por_pessoa) {
				Licitacao::ItemDoPedidoPorPessoa.find_or_create_by(FactoryBot.attributes_for :licitacao_item_do_pedido_por_pessoa)
			}

			it "atribui o(a) pedido à @pedido e item_do_pedido_por_pessoa à @item_do_pedido_por_pessoa" do
				put :anular_preco, params: {id: pedido_coleta_de_preco.to_param, item_do_pedido_por_pessoa_id: item_do_pedido_por_pessoa.id, licitacao_item_do_pedido_por_pessoa: anular_atributos_invalidos}
				expect(assigns(:pedido)).to eq(pedido_coleta_de_preco)
				expect(assigns(:item_do_pedido_por_pessoa)).to eq(item_do_pedido_por_pessoa)
			end

			it "re-renderiza o template 'preco'" do
				put :anular_preco, params: {id: pedido_coleta_de_preco.to_param, item_do_pedido_por_pessoa_id: item_do_pedido_por_pessoa.id, licitacao_item_do_pedido_por_pessoa: anular_atributos_invalidos}
				expect(response).to render_template("preco")
			end
		end
	end

	describe 'GET #mapa' do
		context 'quando o pedido está fechado' do
			it 'atribui o(a) pedido requisitado à @pedido' do
				get :mapa, params: {id: pedido_fechado.to_param}
				expect(assigns(:pedido)).to eq(pedido_fechado)
			end
		end
		context 'quando o pedido está em fase de cotação de preço' do
			it 'redireciona para pedido e mostra erro' do
				get :mapa, params: {id: pedido_aberto.to_param}
				expect(assigns(:pedido_aberto)).to_not eq(pedido)
			end
		end
	end

	describe "GET #reativar_cotacao" do
		context "com parâmetros válidos" do
			let(:pedido_por_pessoa) {
				Licitacao::PessoaDoPedido.find_or_create_by(FactoryBot.attributes_for :pessoa_do_pedido, valido: false)
			}

			it "reativa a cotação requisitada" do
				get :reativar_cotacao, params: {id: pedido_coleta_de_preco.to_param, pessoa_do_pedido_id: pedido_por_pessoa}
				pedido_por_pessoa.reload
				expect(pedido_por_pessoa.valido).to eq true
			end

			it "não reativa a cotação requisitada por já exitir outra ativa" do
				Licitacao::PessoaDoPedido.find_or_create_by(FactoryBot.attributes_for :pessoa_do_pedido, valido: true)
				get :reativar_cotacao, params: {id: pedido_coleta_de_preco.to_param, pessoa_do_pedido_id: pedido_por_pessoa}
				expect(response).to redirect_to(pedido_por_pessoa)
				expect(pedido_por_pessoa.valido).to eq false
			end

			it "redireciona para o fornecedor" do
				get :reativar_cotacao, params: {id: pedido_coleta_de_preco.to_param, pessoa_do_pedido_id: pedido_por_pessoa}
				expect(response).to redirect_to(pedido_por_pessoa)
			end
		end
	end

	describe "GET #reativar_item_da_cotacao" do
		context "com parâmetros válidos" do
			let(:item_do_pedido_por_pessoa) {
				Licitacao::ItemDoPedidoPorPessoa.find_or_create_by(FactoryBot.attributes_for :licitacao_item_do_pedido_por_pessoa, valido: false, motivo: 'motivo convincente')
			}

			let(:pedido_por_pessoa) {
				Licitacao::PessoaDoPedido.find_or_create_by(FactoryBot.attributes_for :pessoa_do_pedido)
			}

			it "reativa a cotação requisitada" do
				get :reativar_item_da_cotacao, params: {id: pedido_coleta_de_preco.id, item_do_pedido_por_pessoa_id: item_do_pedido_por_pessoa.id}
				item_do_pedido_por_pessoa.reload
				expect(item_do_pedido_por_pessoa.valido).to eq true
			end

			it "redireciona para o fornecedor" do
				get :reativar_item_da_cotacao, params: {id: pedido_coleta_de_preco.id, item_do_pedido_por_pessoa_id: item_do_pedido_por_pessoa.id}
				expect(response).to redirect_to(mapa_licitacao_pedido_path(item_do_pedido_por_pessoa.pessoa_do_pedido.pedido))
			end

			it "reativa pela a cotação" do
				get :reativar_item_da_cotacao, params: {id: pedido_coleta_de_preco.id, item_do_pedido_por_pessoa_id: item_do_pedido_por_pessoa.id, cotacao: true}
				item_do_pedido_por_pessoa.reload
				expect(item_do_pedido_por_pessoa.valido).to eq true
			end

			it "redireciona para a cotação" do
				get :reativar_item_da_cotacao, params: {id: pedido_coleta_de_preco.id, item_do_pedido_por_pessoa_id: item_do_pedido_por_pessoa.id, cotacao: true, :pessoa_do_pedido_id => item_do_pedido_por_pessoa.pessoa_do_pedido.id}
				expect(response).to redirect_to(licitacao_pessoa_do_pedido_path(item_do_pedido_por_pessoa.pessoa_do_pedido.id))
			end
		end
	end

	describe "POST #anular_cotacao" do
		context "com parâmetros válidos" do
			let(:anular_atributos) {
				{motivo: "motivo convincente"}
			}

			let(:pedido_por_pessoa) {
				Licitacao::PessoaDoPedido.find_or_create_by(FactoryBot.attributes_for :pessoa_do_pedido)
			}

			it "atualiza o(a) motivo do cancelamento da cotação requisitado(a)" do
				post :anular_cotacao, params: {id: pedido_coleta_de_preco.to_param, pessoa_do_pedido_id: pedido_por_pessoa, licitacao_pessoa_do_pedido: anular_atributos}
				pedido_por_pessoa.reload
				expect(pedido_por_pessoa.motivo).to eq "motivo convincente"
			end

			it "redireciona para o fornecedor" do
				post :anular_cotacao, params: {id: pedido_coleta_de_preco.to_param, pessoa_do_pedido_id: pedido_por_pessoa, licitacao_pessoa_do_pedido: anular_atributos}
				expect(response).to redirect_to(pedido_por_pessoa)
			end
		end

		context "com parâmetros inválidos" do
			let(:anular_atributos_invalidos) {
				{motivo: ""}
			}

			let(:pessoa_do_pedido) {
				Licitacao::PessoaDoPedido.find_or_create_by(FactoryBot.attributes_for :pessoa_do_pedido)
			}

			it "atribui o(a) pedido à @pedido e pedido_por_pessoa à @pedido_por_pessoa" do
				put :anular_cotacao, params: {id: pedido_coleta_de_preco.to_param, pessoa_do_pedido_id: pessoa_do_pedido.id, licitacao_pessoa_do_pedido: anular_atributos_invalidos}
				expect(assigns(:pedido)).to eq(pedido_coleta_de_preco)
				expect(assigns(:pessoa_do_pedido)).to eq(pessoa_do_pedido)
			end

			it "re-renderiza o template 'motivo_anular_cotacao'" do
				put :anular_cotacao, params: {id: pedido_coleta_de_preco.to_param, pessoa_do_pedido_id: pessoa_do_pedido.id, licitacao_pessoa_do_pedido: anular_atributos_invalidos}
				expect(response).to render_template("motivo_anular_cotacao")
			end
		end
	end

	describe 'GET #convidar' do
		before(:each) do
			@pessoa_do_pedido = FactoryBot.create :pessoa_do_pedido, pedido_id: pedido_coleta_de_preco.id
		end
		context 'quando pedido está com status de coleta_de_preco' do
			context 'quando o parâmetro corresponde a um fornecedor do pedido' do
				context 'quando o fornecedor tem email' do
					# envio de email desabilitado
					#it 'envia email de convite para o fornecedor' do
					#	expect {get :convidar, params: {id: pedido_coleta_de_preco.to_param, pessoa_do_pedido_id: @pessoa_do_pedido.id}}.to change { ActionMailer::Base.deliveries.count }.by(1)
					#end
				end

				context 'quando o fornecedor não tem email' do
					it 'redireciona para o fornecedor' do
						pessoa = @pessoa_do_pedido.pessoa
						pessoa.email = nil
						pessoa.save(validate: false)
						get :convidar, params: {id: pedido_coleta_de_preco.to_param, pessoa_do_pedido_id: @pessoa_do_pedido.id}
						expect(response).to redirect_to(@pessoa_do_pedido)
						expect(flash[:alert]).to include 'Fornecedor não tem e-mail informado, altere o cadastro informando um e-mail válido.'
					end
				end
			end

			context 'quando o parâmetro não corresponde a um fornecedor do pedido' do
				it 'redireciona para o pedido' do
					get :convidar, params: {id: pedido_coleta_de_preco.to_param, pessoa_do_pedido_id: @pessoa_do_pedido.id + 1}
					expect(response).to redirect_to(licitacao_pedido_path(pedido_coleta_de_preco) + "?tab=fornecedores")
					expect(flash[:alert]).to include 'Fornecedor não existe'
				end
			end
		end

	end

	describe "GET #confirmar_cancelamento" do
		it "atribui o(a) pedido requisitado à @pedido" do
			get :confirmar_cancelamento, params: {id: pedido.to_param}
			expect(assigns(:pedido)).to eq(pedido)
		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
				patch :cancelar, params: {id: pedido.to_param, licitacao_pedido: novos_atributos}
				pedido.reload
				expect(pedido.motivo_do_cancelamento).to eq "motivo convincente"
			end

			it "muda status do pedido para 'cancelado'" do
				patch :cancelar, params: {id: pedido.to_param, licitacao_pedido: novos_atributos}
				pedido.reload
				expect(pedido.cancelado?).to be_truthy
			end

			it "atribui o(a) pedido requisitado(a) à @pedido" do
				patch :cancelar, params: {id: pedido.to_param, licitacao_pedido: novos_atributos}
				expect(assigns(:pedido)).to eq(pedido)
			end

			it "redireciona para o(a) pedido" do
				patch :cancelar, params: {id: pedido.to_param, licitacao_pedido: novos_atributos}
				expect(response).to redirect_to(pedido)
			end
		end

		context "com parâmetros inválidos" do
			let(:novos_atributos_invalidos) {
				{motivo_do_cancelamento: ""}
			}
			it "atribui o(a) pedido à @pedido" do
				put :cancelar, params: {id: pedido.to_param, licitacao_pedido: novos_atributos_invalidos}
				expect(assigns(:pedido)).to eq(pedido)
			end

			it "re-renderiza o template 'confirmar_cancelamento'" do
				put :cancelar, params: {id: pedido.to_param, licitacao_pedido: novos_atributos_invalidos}
				expect(response).to render_template("confirmar_cancelamento")
			end
		end
	end

	describe 'PATCH #abrir_para_outras_unidades' do
		context 'muda estado do pedido para aguardando_outras_unidades' do
			it 'sucesso' do
				patch :abrir_para_outras_unidades, params: {id: pedido.to_param, licitacao_pedido: pedido.abrir_para_outras_unidades!}
				expect(response).to redirect_to(pedido)
			end
			it 'falha' do
				patch :abrir_para_outras_unidades, params: {id: pedido.to_param}
				expect(flash[:alert]).to include "Não é possível passar da fase atual para a requisitada."
			end
		end
	end

	describe 'PATCH #coletar_precos' do
		context 'muda estado do pedido para coletar_precos' do
			it 'sucesso' do
				patch :coletar_precos, params: {id: pedido.to_param, licitacao_pedido: pedido.coletar_precos!}
				expect(response).to redirect_to(pedido)
			end
			it 'falha' do
				patch :coletar_precos, params: {id: pedido.to_param}
				expect(flash[:alert]).to include "Não é possível passar da fase atual para a requisitada."
			end
		end
	end

	describe 'PATCH #atualizar_data_do_mapa' do
		context 'atualizar data' do
			let(:data_da_impressao_do_mapa) {
				{data_impressao_mapa: "2050-10-18"}
			}

			it 'atualizando e redirecionando' do
				patch :atualizar_data_do_mapa, params: {id: pedido.to_param, licitacao_pedido: data_da_impressao_do_mapa}
				expect{pedido.reload}.to change{pedido.data_impressao_mapa}.from("2016-10-18".to_date).to("2050-10-18".to_date)
				expect(response).to redirect_to(mapa_licitacao_pedido_path(pedido))
			end
		end
	end

	describe 'PATCH #editar_justificativa_da_cotacao' do
		it "atribui o(a) pedido requisitado à @pedido" do
			get :editar_justificativa_da_cotacao, params: {id: pedido.to_param}
			expect(assigns(:pedido)).to eq(pedido)
		end
	end

	describe 'PATCH #atualizar_justificativa_da_cotacao' do
		context 'atualizar justificativa da cotacao' do
			let(:texto_justificativa_da_cotacao) {
				{justificativa_da_cotacao: "justificado"}
			}

			it 'atualizando e redirecionando' do
				patch :atualizar_justificativa_da_cotacao, params: {id: pedido.to_param, licitacao_pedido: texto_justificativa_da_cotacao}
				expect{pedido.reload}.to change{pedido.justificativa_da_cotacao}.from(nil).to("justificado")
				expect(response).to redirect_to(licitacao_pedido_path(pedido) + "?tab=fornecedores")
				expect(flash[:notice]).to include "Justificativa da cotação foi atualizado com sucesso."
			end
		end
	end

	describe "patch #voltar_para_aberto" do
		it "pedido fechado" do
			patch :voltar_para_aberto, params: {id: pedido_fechado.to_param}
			expect(response).to redirect_to(pedido_fechado)
			expect(flash[:success]).to include "Pedido reaberto com sucesso."
		end
		it "pedido aberto" do
			patch :voltar_para_aberto, params: {id: pedido_aberto.to_param}
			expect(response).to redirect_to(pedido_aberto)
		end
	end

	describe "post #duplicar" do
		it "duplica pedido e redireciona para o novo pedido" do
			post :duplicar, params: {id: pedido.to_param}
			expect(response).to redirect_to(Licitacao::Pedido.last)
		end
		it "não duplica e retorna para o @pedido" do
			allow_any_instance_of(Licitacao::Pedido).to receive(:duplica_pedido).and_return(false)
			post :duplicar, params: {id: pedido.to_param, licitacao_pedido: atributos_invalidos}
			expect(response).to redirect_to(pedido)
		end
	end

	describe "GET #busca_pessoas" do
		context 'quando pedido está em sessão' do
			it 'atribui pessoas à @pessoas' do
				pessoa = FactoryBot.create(:pessoa_juridica)
				get :busca_pessoas, params: {id: pedido_coleta_de_preco.to_param, q: {nome_cont: pessoa.nome}}
				expect(assigns(:pessoas).first).to eq(pessoa)
			end
		end
	end

	describe "PATCH #adiciona_pessoas" do
		context 'quando é passado pessoas por parâmetros' do
			it 'adiciona pessoas à @pedido' do
				pessoa = FactoryBot.create(:pessoa_juridica)
				get :adiciona_pessoas, params: { id: pedido_coleta_de_preco.to_param, pessoas: [pessoa.id] }
				expect(response).to render_template("editar_pessoas")
				expect(flash[:notice]).to include "1 pessoa adicionado com sucesso"
			end
		end

		context 'quando não é passado pessoas por parâmetros' do
			it 'não adiciona pessoas à @pedido' do
				get :adiciona_pessoas, params: { id: pedido_coleta_de_preco.to_param, pessoa: [] }
				expect(pedido.reload.pessoas_do_pedido.count).to be == 0
			end

			it 'redireciona para a tela anterior' do
				get :adiciona_pessoas, params: { id: pedido_coleta_de_preco.to_param, pessoa: [] }
				expect(response).to redirect_to(busca_pessoas_licitacao_pedido_path(pedido_coleta_de_preco))
			end
		end
	end
end
