diff --git a/app/graphql/types/achievements/achievement_type.rb b/app/graphql/types/achievements/achievement_type.rb index 99f50966cbe45e4d5cda41a3f89edb1e16e53a23..e6b27129f72ba21ca67b9f61f977fdbb43335c54 100644 --- a/app/graphql/types/achievements/achievement_type.rb +++ b/app/graphql/types/achievements/achievement_type.rb @@ -51,6 +51,11 @@ class AchievementType < BaseObject extras: [:lookahead], resolver: ::Resolvers::Achievements::UserAchievementsResolver + field :unique_users, Types::UserType.connection_type, + null: false, + experiment: { milestone: '18.6' }, + description: "Unique users who have received the achievement." + def avatar_url object.avatar_url(only_path: false) end diff --git a/app/models/achievements/achievement.rb b/app/models/achievements/achievement.rb index d47868c4b669d9e4a5b1582790809485c4e54854..97bd13293678cfbc3b27a7b2d0b091aa13c422b4 100644 --- a/app/models/achievements/achievement.rb +++ b/app/models/achievements/achievement.rb @@ -18,6 +18,10 @@ class Achievement < ApplicationRecord uniqueness: { case_sensitive: false, scope: [:namespace_id] } validates :description, length: { maximum: 1024 } + def unique_users + users.distinct + end + def uploads_sharding_key { namespace_id: namespace_id } end diff --git a/doc/api/graphql/reference/_index.md b/doc/api/graphql/reference/_index.md index 013fd60e8381cb20a88ea3cfa54db580fee870ba..3bb5e851e6dc675436bf9cef8361814ac9cfe8ac 100644 --- a/doc/api/graphql/reference/_index.md +++ b/doc/api/graphql/reference/_index.md @@ -23143,6 +23143,7 @@ Representation of a GitLab user. | `id` | [`AchievementsAchievementID!`](#achievementsachievementid) | ID of the achievement. | | `name` | [`String!`](#string) | Name of the achievement. | | `namespace` | [`Namespace`](#namespace) | Namespace of the achievement. | +| `uniqueUsers` {{< icon name="warning-solid" >}} | [`UserCoreConnection!`](#usercoreconnection) | **Introduced** in GitLab 18.6. **Status**: Experiment. Unique users who have received the achievement. | | `updatedAt` | [`Time!`](#time) | Timestamp the achievement was last updated. | | `userAchievements` {{< icon name="warning-solid" >}} | [`UserAchievementConnection`](#userachievementconnection) | **Introduced** in GitLab 15.10. **Status**: Experiment. Recipients for the achievement. | diff --git a/spec/graphql/types/achievements/achievement_type_spec.rb b/spec/graphql/types/achievements/achievement_type_spec.rb index 08fadcdff229fca850e908209049b6e38172c62b..5e0eb1f69754a31a94920d3a8cd18f087a71247f 100644 --- a/spec/graphql/types/achievements/achievement_type_spec.rb +++ b/spec/graphql/types/achievements/achievement_type_spec.rb @@ -15,6 +15,7 @@ created_at updated_at user_achievements + unique_users ] end diff --git a/spec/models/achievements/achievement_spec.rb b/spec/models/achievements/achievement_spec.rb index 5d8d0e90bb0d5826a8c99530b8a986ea090430a2..bd25b6d21ad966d7fb09f201cc7f5d33bbd384b0 100644 --- a/spec/models/achievements/achievement_spec.rb +++ b/spec/models/achievements/achievement_spec.rb @@ -41,4 +41,25 @@ expect(achievement.uploads_sharding_key).to eq(namespace_id: namespace.id) end end + + describe '#unique_users' do + let_it_be(:achievement) { create(:achievement) } + + subject(:unique_users) { achievement.unique_users } + + it 'returns unique users even when a user has multiple awards' do + user1 = create(:user) + user2 = create(:user) + + create(:user_achievement, achievement: achievement, user: user1) + create(:user_achievement, achievement: achievement, user: user1) + create(:user_achievement, achievement: achievement, user: user2) + + expect(unique_users).to contain_exactly(user1, user2) + end + + it 'returns empty when no users have been awarded' do + expect(unique_users).to be_empty + end + end end diff --git a/spec/requests/api/graphql/achievements/user_achievements_query_spec.rb b/spec/requests/api/graphql/achievements/user_achievements_query_spec.rb index eb6e53442f362194ffd29426e030d40a7de44872..ca0bccddcf67a69249ac4a20423a61734902ba2c 100644 --- a/spec/requests/api/graphql/achievements/user_achievements_query_spec.rb +++ b/spec/requests/api/graphql/achievements/user_achievements_query_spec.rb @@ -20,6 +20,12 @@ achievements { count nodes { + uniqueUsers { + count + nodes { + username + } + } userAchievements { count nodes {