mirror of
https://gh.wpcy.net/https://github.com/discourse/discourse.git
synced 2026-05-22 13:03:05 +08:00
204 lines
7.3 KiB
Ruby
Vendored
204 lines
7.3 KiB
Ruby
Vendored
# frozen_string_literal: true
|
|
|
|
RSpec.describe DiscourseGamification::GamificationLeaderboardController do
|
|
fab!(:group)
|
|
fab!(:current_user) { Fabricate(:user, group_ids: [group.id]) }
|
|
fab!(:user_2) { Fabricate(:user) }
|
|
fab!(:staged_user) { Fabricate(:user, staged: true) }
|
|
fab!(:anon_user) { Fabricate(:user, email: "john@anonymized.invalid") }
|
|
fab!(:currently_suspended_user) do
|
|
Fabricate(:user, suspended_at: Time.now, suspended_till: 5.days.from_now)
|
|
end
|
|
fab!(:previously_suspended_user) do
|
|
Fabricate(:user, suspended_at: Time.now, suspended_till: 5.days.ago)
|
|
end
|
|
|
|
fab!(:user_3) { Fabricate(:user) }
|
|
|
|
let!(:create_score) { UserVisit.create(user_id: current_user.id, visited_at: 2.days.ago) }
|
|
let!(:create_score_for_user2) { UserVisit.create(user_id: user_2.id, visited_at: 2.days.ago) }
|
|
let!(:create_score_for_staged_user) do
|
|
UserVisit.create(user_id: staged_user.id, visited_at: 2.days.ago)
|
|
end
|
|
let!(:create_score_for_anon_user) do
|
|
UserVisit.create(user_id: anon_user.id, visited_at: 2.days.ago)
|
|
end
|
|
let!(:create_score_for_currently_suspended_user) do
|
|
UserVisit.create(user_id: currently_suspended_user.id, visited_at: 2.days.ago)
|
|
end
|
|
let!(:create_score_for_previously_suspended_user) do
|
|
UserVisit.create(user_id: previously_suspended_user.id, visited_at: 2.days.ago)
|
|
end
|
|
let!(:create_score_for_user_3) { UserVisit.create(user_id: user_3.id, visited_at: 2.days.ago) }
|
|
let!(:create_topic) { Fabricate(:topic, user: current_user) }
|
|
fab!(:leaderboard) do
|
|
Fabricate(:gamification_leaderboard, name: "test", created_by_id: current_user.id)
|
|
end
|
|
fab!(:leaderboard_2) do
|
|
Fabricate(
|
|
:gamification_leaderboard,
|
|
name: "test_2",
|
|
created_by_id: current_user.id,
|
|
from_date: 3.days.ago,
|
|
to_date: 1.day.ago,
|
|
)
|
|
end
|
|
fab!(:leaderboard_with_group) do
|
|
Fabricate(
|
|
:gamification_leaderboard,
|
|
name: "test_3",
|
|
created_by_id: current_user.id,
|
|
included_groups_ids: [group.id],
|
|
visible_to_groups_ids: [group.id],
|
|
)
|
|
end
|
|
|
|
fab!(:leaderboard_with_default_period_set_to_daily) do
|
|
Fabricate(
|
|
:gamification_leaderboard,
|
|
name: "test_4",
|
|
created_by_id: current_user.id,
|
|
default_period: 5,
|
|
)
|
|
end
|
|
|
|
before do
|
|
SiteSetting.discourse_gamification_enabled = true
|
|
DiscourseGamification::GamificationScore.calculate_scores(since_date: 10.days.ago)
|
|
sign_in(current_user)
|
|
end
|
|
|
|
describe "#respond" do
|
|
it "returns users and their calculated scores" do
|
|
DiscourseGamification::LeaderboardCachedView.new(leaderboard).create
|
|
|
|
get "/leaderboard/#{leaderboard.id}.json"
|
|
expect(response.status).to eq(200)
|
|
|
|
data = response.parsed_body
|
|
expect(data["users"][0]["username"]).to eq(current_user.username)
|
|
expect(data["users"][0]["avatar_template"]).to eq(current_user.avatar_template)
|
|
expect(data["users"][0]["total_score"]).to eq(current_user.gamification_score)
|
|
end
|
|
|
|
it "returns an in progress message when leaderboard positions are not ready" do
|
|
expect do get "/leaderboard/#{leaderboard.id}.json" end.to change {
|
|
Jobs::GenerateLeaderboardPositions.jobs.size
|
|
}.by(1)
|
|
|
|
expect(response.status).to eq(202)
|
|
expect(response.parsed_body["reason"]).to eq(I18n.t("errors.leaderboard_positions_not_ready"))
|
|
end
|
|
|
|
it "only returns users and scores for specified date range" do
|
|
DiscourseGamification::LeaderboardCachedView.new(leaderboard_2).create
|
|
get "/leaderboard/#{leaderboard_2.id}.json"
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
data = response.parsed_body
|
|
expect(data["users"][0]["username"]).to eq(current_user.username)
|
|
expect(data["users"][0]["avatar_template"]).to eq(current_user.avatar_template)
|
|
expect(data["users"][0]["total_score"]).to eq(1)
|
|
end
|
|
|
|
it "respects the user_limit parameter" do
|
|
DiscourseGamification::LeaderboardCachedView.new(leaderboard).create
|
|
|
|
get "/leaderboard/#{leaderboard.id}.json?user_limit=1"
|
|
expect(response.status).to eq(200)
|
|
|
|
data = response.parsed_body
|
|
expect(data["users"].count).to eq(1)
|
|
end
|
|
|
|
it "only returns users that are a part of a group within included_groups_ids" do
|
|
# multiple scores present
|
|
expect(DiscourseGamification::GamificationScore.all.map(&:user_id)).to include(
|
|
current_user.id,
|
|
user_2.id,
|
|
)
|
|
|
|
DiscourseGamification::LeaderboardCachedView.new(leaderboard_with_group).create
|
|
|
|
get "/leaderboard/#{leaderboard_with_group.id}.json"
|
|
expect(response.status).to eq(200)
|
|
|
|
data = response.parsed_body
|
|
# scoped to group
|
|
expect(data["users"].map { |u| u["id"] }).to eq([current_user.id])
|
|
end
|
|
|
|
it "excludes staged, anon users, currently suspended and deleted users" do
|
|
user_3.destroy
|
|
# prove score for staged/anon user exists
|
|
expect(DiscourseGamification::GamificationScore.all.map(&:user_id)).to include(
|
|
staged_user.id,
|
|
anon_user.id,
|
|
)
|
|
|
|
expect(DiscourseGamification::GamificationScore.all.map(&:user_id)).to_not include(
|
|
currently_suspended_user.id,
|
|
user_3.id,
|
|
)
|
|
|
|
DiscourseGamification::LeaderboardCachedView.new(leaderboard).create
|
|
|
|
get "/leaderboard/#{leaderboard.id}.json"
|
|
data = response.parsed_body
|
|
expect(data["users"].map { |u| u["id"] }).to_not include(
|
|
staged_user.id,
|
|
anon_user.id,
|
|
currently_suspended_user.id,
|
|
user_3.id,
|
|
)
|
|
end
|
|
|
|
it "does not error if visible_to_groups_ids or included_groups_ids are empty" do
|
|
DiscourseGamification::LeaderboardCachedView.new(leaderboard).create
|
|
get "/leaderboard/#{leaderboard.id}.json"
|
|
expect(response.status).to eq(200)
|
|
end
|
|
|
|
it "errors if visible_to_groups_ids are present and user in not a part of a included group" do
|
|
current_user.groups = []
|
|
get "/leaderboard/#{leaderboard_with_group.id}.json"
|
|
expect(response.status).to eq(404)
|
|
end
|
|
|
|
it "displays leaderboard to users included in group within visible_to_groups_ids" do
|
|
DiscourseGamification::LeaderboardCachedView.new(leaderboard_with_group).create
|
|
|
|
get "/leaderboard/#{leaderboard_with_group.id}.json"
|
|
expect(response.status).to eq(200)
|
|
end
|
|
|
|
it "allows admins to see all leaderboards" do
|
|
current_user = Fabricate(:admin)
|
|
DiscourseGamification::LeaderboardCachedView.new(leaderboard_with_group).create
|
|
|
|
sign_in(current_user)
|
|
get "/leaderboard/#{leaderboard_with_group.id}.json"
|
|
expect(response.status).to eq(200)
|
|
end
|
|
|
|
it "displays leaderboard for the default leaderboard period" do
|
|
DiscourseGamification::LeaderboardCachedView.new(leaderboard).create
|
|
DiscourseGamification::LeaderboardCachedView.new(
|
|
leaderboard_with_default_period_set_to_daily,
|
|
).create
|
|
|
|
get "/leaderboard/#{leaderboard.id}.json"
|
|
regular_user_score = response.parsed_body["users"][0]["total_score"]
|
|
|
|
get "/leaderboard/#{leaderboard.id}.json?period=daily"
|
|
daily_user_score = response.parsed_body["users"][0]["total_score"]
|
|
|
|
get "/leaderboard/#{leaderboard_with_default_period_set_to_daily.id}.json"
|
|
default_user_score = response.parsed_body["users"][0]["total_score"]
|
|
|
|
expect(default_user_score).to eq(daily_user_score)
|
|
expect(default_user_score).not_to eq(regular_user_score)
|
|
end
|
|
end
|
|
end
|