require 'rails_helper'

RSpec.describe Ppa::PerfisController, type: :controller do
	sign_in_admin
	set_ppa_id_na_sessao

	# Isso deve retornar o mínimo de atributos obrigatórios
	let(:atributos_validos) {
		FactoryBot.attributes_for( :perfil_comum )
	}

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

	describe "GET #index" do
		it "retorna apenas os perfis atuais do sistema" do
			perfil = Perfil.first
			get :index

			expect(assigns(:perfis)).to eq([perfil])
		end
	end

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

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

	describe "POST #atualiza_permissoes" do
		it "redireciona para perfil atualizado" do
			perfil = Perfil.create! atributos_validos
			modulo = FactoryBot.create( :modulo_administrativo)
			post :atualiza_permissoes, {id: perfil.id, modulo_id: modulo.id}
			expect(response).to redirect_to(perfil)
		end

		it "atribui ações ao perfil" do
			perfil = Perfil.create! atributos_validos

			acao1 = FactoryBot.create( :acesso_acao_show_de_application )
			acao2 = FactoryBot.create( :acesso_acao_show_de_application )
			acao3 = FactoryBot.create( :acesso_acao_show_de_application )

			modulo = FactoryBot.create( :modulo_administrativo)

			post :atualiza_permissoes, {id: perfil.id, acoes: [acao1.id, acao2.id, acao3.id], modulo_id: modulo.id}

			expect(perfil.permissoes.pluck(:acao_id)).to eq([acao1.id, acao2.id, acao3.id])
		end

		it "remove acao do perfil" do
			permissao = FactoryBot.create( :permissao_show_de_application_para_perfil_comum)
			modulo_id = permissao.acao.controle.modulo.id

			perfil = permissao.perfil

			post :atualiza_permissoes, {id: permissao.perfil_id, acoes: [], modulo_id: modulo_id}

			expect(perfil.permissoes.pluck(:acao_id)).to eq([])
		end

		it "ao atualizar modulo mantem acao de outro modulo" do
			permissao_modulo_administracao = FactoryBot.create( :permissao_show_de_application_para_perfil_comum)
			permissao_modulo_ppa = FactoryBot.create( :permissao_show_de_tecnicos_para_perfil_comum)
			modulo_administracao_id = permissao_modulo_administracao.acao.controle.modulo.id

			post :atualiza_permissoes, {id: permissao_modulo_administracao.perfil_id, acoes: [], modulo_id: modulo_administracao_id}

			perfil = permissao_modulo_ppa.perfil

			expect(perfil.permissoes.pluck(:acao_id)).to eq([permissao_modulo_ppa.acao_id])
		end
	end

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

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

			it "redireciona para a lista de perfis" do
				post :create, params: {:perfil => atributos_validos}
				expect(response).to redirect_to(perfis_path)
			end
		end

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

			it "re-renderiza o template 'new'" do
				post :create, params: {perfil: 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) {
				{ nome: 'Novo nome' }
			}

			it "atualiza o(a) perfil requisitado(a)" do
				perfil = Perfil.create! atributos_validos
				post :update, params: {id: perfil.to_param, perfil: novos_atributos}
				perfil.reload
				expect( perfil.nome ).to eq 'Novo nome'
			end

			it "atribui o(a) perfil requisitado(a) à @perfil" do
				perfil = Perfil.create! atributos_validos
				post :update, params: {id: perfil.to_param, perfil: atributos_validos}
				expect(assigns(:perfil)).to eq(perfil)
			end

			it "redireciona para a lista de perfis" do
				perfil = Perfil.create! atributos_validos
				post :update, params: {id: perfil.to_param, perfil: atributos_validos}
				expect(response).to redirect_to(perfis_path)
			end
		end

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

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

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

		it "redireciona para a lista de perfis" do
			perfil = Perfil.create! atributos_validos
			delete :destroy, params: {:id => perfil.to_param}
			expect(response).to redirect_to(perfis_url)
		end
	end

end
