Files
leadchat/spec/controllers/super_admin/users_controller_spec.rb
Sojan Jose 52cd70dfa3 fix(super-admin): prefill confirmed_at in new user form (#13662)
On self-hosted instances without email configured, users created from
Super Admin can get stuck in an unconfirmed state. This PR implements
the default at the Super Admin frontend form layer, not in backend
creation logic.

What changed:
- Added a custom `ConfirmedAtField` for Super Admin user forms.
- Prefills `confirmed_at` with current time on the **New User** form
(`GET /super_admin/users/new`).
- Kept backend create behavior unchanged
(`resource_class.new(resource_params)`), so API/manual payloads still
behave normally.

Behavior:
- In Super Admin UI, `confirmed_at` is prefilled by default.
- If someone wants an unconfirmed user, they can clear the
`confirmed_at` field before saving.
- If `confirmed_at` is omitted from payload entirely, the created user
remains unconfirmed.

Scope note: external signup flows are intentionally unchanged in this PR
(`/api/v1/accounts`, `/api/v2/accounts`, and social/omniauth signup
behavior are not modified).

## Demo 





https://github.com/user-attachments/assets/436abbb0-d4cf-49a6-a1b8-4b6aa85aa09f
2026-03-10 12:14:58 +05:30

172 lines
6.1 KiB
Ruby

require 'rails_helper'
RSpec.describe 'Super Admin Users API', type: :request do
let(:super_admin) { create(:super_admin) }
describe 'GET /super_admin/users' do
context 'when it is an unauthenticated super admin' do
it 'returns unauthorized' do
get '/super_admin/users'
expect(response).to have_http_status(:redirect)
end
end
context 'when it is an authenticated super admin' do
let!(:user) { create(:user, name: 'Disabled User') }
let!(:params) do
{ user: {
name: 'admin@example.com',
display_name: 'admin@example.com',
email: 'admin@example.com',
password: 'Password1!',
confirmed_at: '2023-03-20 22:32:41',
type: 'SuperAdmin'
} }
end
let!(:params_without_confirmed_at) do
{ user: {
name: 'agent@example.com',
display_name: 'agent@example.com',
email: 'agent@example.com',
password: 'Password1!',
type: 'SuperAdmin'
} }
end
let!(:params_with_blank_confirmed_at) do
{ user: {
name: 'agent-2@example.com',
display_name: 'agent-2@example.com',
email: 'agent-2@example.com',
password: 'Password1!',
confirmed_at: '',
type: 'SuperAdmin'
} }
end
it 'shows the list of users' do
sign_in(super_admin, scope: :super_admin)
get '/super_admin/users'
doc = Nokogiri::HTML(response.body)
header_texts = doc.css('table thead th').map { |header| header.text.squish }
expect(response).to have_http_status(:success)
expect(response.body).to include('New user')
expect(response.body).to include(CGI.escapeHTML(user.name))
expect(header_texts).not_to include('MFA')
end
it 'prefills confirmed_at on new user form' do
sign_in(super_admin, scope: :super_admin)
get '/super_admin/users/new'
expect(response).to have_http_status(:success)
expect(response.body).to include('name="user[confirmed_at]"')
confirmed_at_value = response.body[/name="user\[confirmed_at\]".*?value="([^"]+)"/m, 1]
expect(confirmed_at_value).to be_present
end
it 'creates the new super_admin record' do
sign_in(super_admin, scope: :super_admin)
post '/super_admin/users', params: params
expect(response).to redirect_to("http://www.example.com/super_admin/users/#{User.last.id}")
expect(SuperAdmin.last.email).to eq('admin@example.com')
post '/super_admin/users', params: params
expect(response).to redirect_to('http://www.example.com/super_admin/users/new')
end
it 'creates unconfirmed users when confirmed_at is not provided in payload' do
sign_in(super_admin, scope: :super_admin)
post '/super_admin/users', params: params_without_confirmed_at
expect(response).to redirect_to("http://www.example.com/super_admin/users/#{User.last.id}")
expect(User.last).not_to be_confirmed
end
it 'creates unconfirmed users when confirmed_at is explicitly cleared' do
sign_in(super_admin, scope: :super_admin)
post '/super_admin/users', params: params_with_blank_confirmed_at
expect(response).to redirect_to("http://www.example.com/super_admin/users/#{User.last.id}")
expect(User.last).not_to be_confirmed
end
end
end
describe 'DELETE /super_admin/users/:id/avatar' do
let!(:user) { create(:user, :with_avatar) }
context 'when it is an unauthenticated super admin' do
it 'returns unauthorized' do
delete "/super_admin/users/#{user.id}/avatar", params: { attachment_id: user.avatar.id }
expect(response).to have_http_status(:redirect)
expect(user.reload.avatar).to be_attached
end
end
context 'when it is an authenticated super admin' do
it 'destroys the avatar' do
sign_in(super_admin, scope: :super_admin)
delete "/super_admin/users/#{user.id}/avatar", params: { attachment_id: user.avatar.id }
expect(response).to have_http_status(:redirect)
expect(user.reload.avatar).not_to be_attached
end
end
end
describe 'PATCH /super_admin/users/:id' do
let!(:user) { create(:user) }
let(:request_path) { "/super_admin/users/#{user.id}" }
before { sign_in(super_admin, scope: :super_admin) }
it 'skips reconfirmation when confirmed_at is provided' do
ActiveJob::Base.queue_adapter.enqueued_jobs.clear
patch request_path, params: { user: { email: 'updated@example.com', confirmed_at: Time.current } }
expect(response).to have_http_status(:redirect)
expect(user.reload.email).to eq('updated@example.com')
expect(user.reload.unconfirmed_email).to be_nil
mail_jobs = ActiveJob::Base.queue_adapter.enqueued_jobs.select do |job|
job[:job].to_s == 'ActionMailer::MailDeliveryJob'
end
expect(mail_jobs.count).to eq(0)
end
it 'does not skip reconfirmation when confirmed_at is blank' do
ActiveJob::Base.queue_adapter.enqueued_jobs.clear
patch request_path, params: { user: { email: 'updated-again@example.com' } }
expect(response).to have_http_status(:redirect)
expect(user.reload.unconfirmed_email).to eq('updated-again@example.com')
mail_jobs = ActiveJob::Base.queue_adapter.enqueued_jobs.select do |job|
job[:job].to_s == 'ActionMailer::MailDeliveryJob'
end
expect(mail_jobs.count).to be >= 1
end
end
describe 'GET /super_admin/users/:id' do
let!(:user) { create(:user, name: 'MFA Enabled User', otp_required_for_login: true) }
it 'shows the MFA status on the user detail page' do
sign_in(super_admin, scope: :super_admin)
get "/super_admin/users/#{user.id}"
doc = Nokogiri::HTML(response.body)
labels = doc.css('dt.attribute-label').map { |label| label.text.squish }
expect(response).to have_http_status(:success)
expect(labels).to include('MFA')
expect(response.body).to include('Enabled')
expect(response.body).to include(CGI.escapeHTML(user.name))
end
end
end