mirror of
https://gh.wpcy.net/https://github.com/discourse/discourse.git
synced 2026-05-07 12:53:27 +08:00
## Summary - Moves scorable weight configuration and category filtering from global site settings to individual leaderboards - Each leaderboard can override any of the 15 score weight values and specify its own scorable categories - Score calculation now runs per leaderboard into a new `gamification_leaderboard_scores` table - Admin UI gains a "Scoring configuration" section on the leaderboard edit form ## Details Previously all leaderboards shared the same pre-calculated scores from global site settings. This made it impossible to have e.g. a "posts-only" leaderboard alongside a "likes-focused" one. Now each leaderboard can optionally override: - **Score weights**: Set per-action point values (empty = inherit global default, 0 = disabled) - **Scorable categories**: Restrict which categories count toward scoring (empty = inherit global setting) The old `gamification_scores` table is no longer written to — a post-deploy migration to drop it will follow separately. ## Test plan - [ ] Create a leaderboard with default scoring — scores match current behavior - [ ] Create a leaderboard with custom weights (e.g. `post_created` = 10, all others empty) — only overridden weights differ - [ ] Set a weight to 0 — that scorable is disabled for the leaderboard - [ ] Set per-leaderboard categories — only those categories count - [ ] Clear categories — inherits global `scorable_categories` setting - [ ] Existing leaderboards with no overrides behave identically after upgrade - [ ] Directory scores and user card scores work correctly (read from default leaderboard) - [ ] `bin/rspec plugins/discourse-gamification/spec/` — 120 examples, 0 failures
59 lines
1.9 KiB
Ruby
59 lines
1.9 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
describe DiscourseGamification do
|
|
fab!(:user)
|
|
fab!(:leaderboard, :gamification_leaderboard)
|
|
|
|
it "adds gamification_score to the UserCardSerializer" do
|
|
serializer = UserCardSerializer.new(user)
|
|
expect(serializer).to respond_to(:gamification_score)
|
|
end
|
|
|
|
context "with leaderboard positions" do
|
|
before { SiteSetting.discourse_gamification_enabled = true }
|
|
|
|
it "enqueues job to regenerate leaderboard positions for score ranking strategy changes" do
|
|
expect do SiteSetting.score_ranking_strategy = "row_number" end.to change {
|
|
Jobs::RegenerateLeaderboardPositions.jobs.size
|
|
}.by(1)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe DiscourseGamification do
|
|
let(:guardian) { Guardian.new }
|
|
let!(:default_gamification_leaderboard) { Fabricate(:gamification_leaderboard) }
|
|
|
|
it "adds default_gamification_leaderboard_id to the SiteSettingSerializer" do
|
|
site = Site.new(guardian)
|
|
serializer = SiteSerializer.new(site)
|
|
expect(serializer).to respond_to(:default_gamification_leaderboard_id)
|
|
expect(serializer.default_gamification_leaderboard_id).to eq(
|
|
default_gamification_leaderboard.id,
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when merging users" do
|
|
fab!(:user_1, :user)
|
|
fab!(:user_2, :user)
|
|
fab!(:leaderboard, :gamification_leaderboard)
|
|
|
|
before do
|
|
SiteSetting.discourse_gamification_enabled = true
|
|
DiscourseGamification::LeaderboardCachedView.create_all
|
|
Fabricate.times(1, :topic, user: user_1)
|
|
Fabricate.times(1, :topic, user: user_2)
|
|
DiscourseGamification::GamificationLeaderboardScore.calculate_all
|
|
DiscourseGamification::LeaderboardCachedView.refresh_all
|
|
end
|
|
|
|
it "sums the scores" do
|
|
expect(user_2.gamification_score).to eq(5)
|
|
|
|
UserMerger.new(user_1, user_2, Discourse.system_user).merge!
|
|
DiscourseGamification::LeaderboardCachedView.refresh_all
|
|
|
|
expect(user_2.gamification_score).to eq(10)
|
|
end
|
|
end
|