0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-05 13:59:03 +08:00
discourse/spec/system/admin_user_badges_spec.rb
Régis Hanol aa33eaa798
FIX: Allow badges with SQL queries to be manually granted (#36866)
Previously, badges with custom SQL queries were hidden from the manual
grant dropdown in the admin UI. This was because `manually_grantable?`
returned false for any badge with a query, regardless of whether it was
a system badge or not.

This fix simplifies the logic: only system badges (the built-in
Discourse badges like "Basic User", "Member", etc.) are excluded from
manual granting. Custom badges with SQL queries can now be manually
granted to users.

Additionally, manually granted badges are now protected from
auto-revocation. When a badge's SQL query runs via backfill, it will
only revoke badges that were originally auto-granted (granted_by_id =
-1), leaving manually granted badges intact. This ensures that an
admin's deliberate decision to grant a badge isn't undone by the
automated badge system.

We considered adding a new `allow_manual_grant` setting per badge, which
would give admins explicit control over dropdown visibility. However,
this adds UI complexity and another knob to configure. The simpler
approach covers the common case: if you created a custom badge, you
probably want the option to grant it manually.

Note: Some users may have been relying on the old behavior to hide
badges from the dropdown by adding a dummy SQL query. This workaround
will no longer work - those badges will now appear in the dropdown.

Ref - t/139277
Ref - https://meta.discourse.org/t/296645
2026-01-09 13:58:09 +01:00

37 lines
1.2 KiB
Ruby
Vendored

# frozen_string_literal: true
describe "Admin User Badges Page", type: :system do
before { SiteSetting.enable_badges = true }
fab!(:granter, :admin)
fab!(:user)
fab!(:badge, :manually_grantable_badge)
let(:user_badges_page) { PageObjects::Pages::AdminUserBadges.new }
before { sign_in(granter) }
it "displays badge granter and links to their profile" do
BadgeGranter.grant(badge, user, granted_by: granter)
badge_row = user_badges_page.visit_page(user).find_badge_row_by_granter(granter)
expect(badge_row).to have_css("[data-badge-name='#{badge.name}']")
badge_row.click_link(granter.username)
expect(page).to have_current_path "/admin/users/#{granter.id}/#{granter.username}"
end
it "shows badges with SQL queries in the grant dropdown" do
badge_with_query =
Fabricate(
:badge,
name: "SQL Badge",
query: "SELECT user_id, current_timestamp granted_at FROM users WHERE false",
)
user_badges_page.visit_page(user)
badge_dropdown = PageObjects::Components::SelectKit.new(".user-badges .combo-box")
badge_dropdown.expand
expect(page).to have_css(".select-kit-row[data-name='#{badge_with_query.name}']")
end
end