Implandação da customização das permissões dos usuarios e das notificaçoes

This commit is contained in:
2026-08-26 17:24:25 -03:00
parent 808c2c7545
commit 5bb5d74e22
71 changed files with 2487 additions and 269 deletions

View File

@@ -0,0 +1,101 @@
require 'rails_helper'
# Perfis de acesso: quem entra na tela, e as travas que impedem o ADM de se
# trancar para fora do próprio sistema.
RSpec.describe 'Admin::PerfisAcesso', type: :request do
# Perfil com acesso total, para o usuário que administra nos testes.
let(:perfil_admin) { create(:perfil_acesso, nome: 'Administrador', permissoes: Permissao.chaves) }
let(:administrador) { create(:admin, perfil_acesso: perfil_admin) }
describe 'quem entra' do
it 'exige login' do
get admin_perfis_path
expect(response).to redirect_to(new_user_session_path)
end
it 'nega quem não tem admin.perfis' do
sign_in create(:gerente, perfil_acesso: create(:perfil_acesso, permissoes: ['consolidacao.ver']))
get admin_perfis_path
expect(response).to have_http_status(:redirect)
end
it 'permite quem tem admin.perfis' do
sign_in administrador
get admin_perfis_path
expect(response).to have_http_status(:ok)
end
end
describe 'criar e editar' do
before { sign_in administrador }
it 'cria perfil só com as chaves do catálogo' do
post admin_perfis_path, params: {
perfil_acesso: { nome: 'Financeiro', descricao: 'Paga',
ativo: '1', permissoes: ['consolidacao.ver', 'inventada.chave'] }
}
perfil = PerfilAcesso.find_by(nome: 'Financeiro')
expect(perfil.permissoes).to eq(['consolidacao.ver'])
end
it 'desmarcar tudo realmente zera as permissões' do
perfil = create(:perfil_acesso, permissoes: ['consolidacao.ver'])
# O form manda um valor vazio quando nenhuma caixa está marcada; sem ele o
# parâmetro sumiria e "desmarcar tudo" viraria "não mexeu".
patch admin_perfil_path(perfil), params: {
perfil_acesso: { nome: perfil.nome, ativo: '1', permissoes: [''] }
}
expect(perfil.reload.permissoes).to eq([])
end
end
describe 'trava do último administrador' do
before { sign_in administrador }
it 'impede tirar admin.perfis do único perfil que administra' do
patch admin_perfil_path(perfil_admin), params: {
perfil_acesso: { nome: perfil_admin.nome, ativo: '1',
permissoes: Permissao.chaves - ['admin.perfis'] }
}
expect(response).to have_http_status(:unprocessable_entity)
expect(perfil_admin.reload.permissoes).to include('admin.perfis')
end
it 'libera quando outra pessoa mantém o acesso' do
outro = create(:perfil_acesso, nome: 'Admin 2', permissoes: Permissao.chaves)
create(:admin, perfil_acesso: outro)
patch admin_perfil_path(perfil_admin), params: {
perfil_acesso: { nome: perfil_admin.nome, ativo: '1',
permissoes: Permissao.chaves - ['admin.perfis'] }
}
expect(perfil_admin.reload.permissoes).not_to include('admin.perfis')
end
end
describe 'exclusão' do
before { sign_in administrador }
it 'não exclui perfil de sistema' do
perfil = create(:perfil_acesso, sistema: true)
expect { delete admin_perfil_path(perfil) }.not_to change(PerfilAcesso, :count)
end
it 'não exclui perfil em uso' do
perfil = create(:perfil_acesso)
create(:operador, perfil_acesso: perfil)
expect { delete admin_perfil_path(perfil) }.not_to change(PerfilAcesso, :count)
end
it 'exclui perfil livre' do
perfil = create(:perfil_acesso)
expect { delete admin_perfil_path(perfil) }.to change(PerfilAcesso, :count).by(-1)
end
end
end

View File

@@ -0,0 +1,89 @@
require 'rails_helper'
# As três falhas de acesso que existiam antes dos perfis. Cada exemplo aqui é um
# furo real que foi fechado — se algum voltar a passar "verde ao contrário", o
# sistema regrediu para o estado em que qualquer usuário virava admin.
RSpec.describe 'Controle de acesso', type: :request do
describe 'auto-promoção a administrador' do
it 'ignora role e perfil enviados por quem edita a PRÓPRIA ficha' do
operador = create(:operador)
perfil_total = create(:perfil_acesso, permissoes: Permissao.chaves)
sign_in operador
patch admin_usuario_path(operador), params: {
user: { nome: 'Nome Novo', role: 'admin', perfil_acesso_id: perfil_total.id }
}
operador.reload
expect(operador.nome).to eq('Nome Novo') # o que ele PODE mudar, mudou
expect(operador.role).to eq('operador') # o que ele não pode, não mudou
expect(operador.perfil_acesso_id).to be_nil
expect(operador.pode?('admin.usuarios_gerenciar')).to be(false)
end
it 'quem administra usuários continua podendo trocar o perfil de outra pessoa' do
perfil_admin = create(:perfil_acesso, permissoes: Permissao.chaves)
admin = create(:admin, perfil_acesso: perfil_admin)
alvo = create(:operador)
novo = create(:perfil_acesso, nome: 'Financeiro', permissoes: ['consolidacao.ver'])
sign_in admin
patch admin_usuario_path(alvo), params: { user: { nome: alvo.nome, perfil_acesso_id: novo.id } }
expect(alvo.reload.perfil_acesso_id).to eq(novo.id)
end
end
describe 'papel externo no dashboard' do
it 'entra no dashboard mas não vê custo nem pagamento' do
sign_in create(:externo)
get dashboard_path
expect(response).to have_http_status(:ok)
expect(response.body).not_to include('Consolidado / Pago')
expect(response.body).not_to include('Ticket médio')
end
it 'não baixa o relatório financeiro nem abre as entregas em aberto' do
sign_in create(:externo)
get dashboard_relatorio_financeiro_path
expect(response).to have_http_status(:redirect)
get dashboard_pendentes_path
expect(response).to have_http_status(:redirect)
end
it 'gerente continua vendo o financeiro' do
sign_in create(:gerente)
get dashboard_path
expect(response.body).to include('Consolidado / Pago')
end
end
describe 'conta desativada' do
it 'não faz login por e-mail e senha' do
usuario = create(:gerente, ativo: false, password: 'Gade@2026!')
post user_session_path, params: { user: { email: usuario.email, password: 'Gade@2026!' } }
expect(response).not_to redirect_to(dashboard_path)
expect(controller.current_user).to be_nil
end
end
describe 'sem nenhuma permissão' do
it 'cai na tela de sem-acesso em vez de entrar em loop com a raiz' do
usuario = create(:operador, perfil_acesso: create(:perfil_acesso, permissoes: []))
sign_in usuario
get dashboard_path
expect(response).to redirect_to(sem_acesso_path)
get sem_acesso_path
expect(response).to have_http_status(:ok)
expect(response.body).to include('não tem acesso')
end
end
end