Commit 0068380c authored by Ryan Cobb's avatar Ryan Cobb Committed by Vitali Tatarintev

GraphQL: Add notificationEmail to GroupMembers

Add ability to fetch a group members notification email via GraphQL.

Changelog: added
parent d959694a
# frozen_string_literal: true
module Resolvers
module GroupMembers
class NotificationEmailResolver < BaseResolver
include Gitlab::Graphql::Authorize::AuthorizeResource
type GraphQL::Types::String, null: true
def resolve
authorize!
BatchLoader::GraphQL.for(object.user_id).batch do |user_ids, loader|
User.find(user_ids).each do |user|
loader.call(user.id, user.notification_email_for(object.group))
end
end
end
def authorize!
raise_resource_not_available_error! unless user_is_admin?
end
def user_is_admin?
context[:current_user].present? && context[:current_user].can_admin_all_resources?
end
end
end
end
...@@ -13,6 +13,10 @@ module Types ...@@ -13,6 +13,10 @@ module Types
field :group, Types::GroupType, null: true, field :group, Types::GroupType, null: true,
description: 'Group that a User is a member of.' description: 'Group that a User is a member of.'
field :notification_email,
resolver: Resolvers::GroupMembers::NotificationEmailResolver,
description: "Group notification email for User. Only availble for admins."
def group def group
Gitlab::Graphql::Loaders::BatchModelLoader.new(Group, object.source_id).find Gitlab::Graphql::Loaders::BatchModelLoader.new(Group, object.source_id).find
end end
......
...@@ -11788,6 +11788,7 @@ Represents a Group Membership. ...@@ -11788,6 +11788,7 @@ Represents a Group Membership.
| <a id="groupmemberexpiresat"></a>`expiresAt` | [`Time`](#time) | Date and time the membership expires. | | <a id="groupmemberexpiresat"></a>`expiresAt` | [`Time`](#time) | Date and time the membership expires. |
| <a id="groupmembergroup"></a>`group` | [`Group`](#group) | Group that a User is a member of. | | <a id="groupmembergroup"></a>`group` | [`Group`](#group) | Group that a User is a member of. |
| <a id="groupmemberid"></a>`id` | [`ID!`](#id) | ID of the member. | | <a id="groupmemberid"></a>`id` | [`ID!`](#id) | ID of the member. |
| <a id="groupmembernotificationemail"></a>`notificationEmail` | [`String`](#string) | Group notification email for User. Only availble for admins. |
| <a id="groupmemberupdatedat"></a>`updatedAt` | [`Time`](#time) | Date and time the membership was last updated. | | <a id="groupmemberupdatedat"></a>`updatedAt` | [`Time`](#time) | Date and time the membership was last updated. |
| <a id="groupmemberuser"></a>`user` | [`UserCore`](#usercore) | User that is associated with the member object. | | <a id="groupmemberuser"></a>`user` | [`UserCore`](#usercore) | User that is associated with the member object. |
| <a id="groupmemberuserpermissions"></a>`userPermissions` | [`GroupPermissions!`](#grouppermissions) | Permissions for the current user on the resource. | | <a id="groupmemberuserpermissions"></a>`userPermissions` | [`GroupPermissions!`](#grouppermissions) | Permissions for the current user on the resource. |
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Resolvers::GroupMembers::NotificationEmailResolver do
include GraphqlHelpers
describe '#resolve' do
let_it_be(:group) { create(:group) }
let_it_be(:developer) { create(:user) }
before do
group.add_developer(developer)
end
specify do
expect(described_class).to have_nullable_graphql_type(GraphQL::Types::String)
end
subject { batch_sync { resolve_notification_email(developer.group_members.first, current_user) }}
context 'when current_user is admin' do
let(:current_user) { create(:user, :admin) }
before do
allow(current_user).to receive(:can_admin_all_resources?).and_return(true)
end
it 'returns email' do
expect(subject).to eq(developer.email)
end
end
context 'when current_user is not admin' do
let(:current_user) { create(:user) }
it 'raises ResourceNotAvailable error' do
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
end
end
end
def resolve_notification_email(obj, user)
resolve(described_class, obj: obj, ctx: { current_user: user })
end
end
...@@ -11,7 +11,7 @@ RSpec.describe Types::GroupMemberType do ...@@ -11,7 +11,7 @@ RSpec.describe Types::GroupMemberType do
it 'has the expected fields' do it 'has the expected fields' do
expected_fields = %w[ expected_fields = %w[
access_level created_by created_at updated_at expires_at group access_level created_by created_at updated_at expires_at group notification_email
] ]
expect(described_class).to include_graphql_fields(*expected_fields) expect(described_class).to include_graphql_fields(*expected_fields)
......
...@@ -53,6 +53,30 @@ RSpec.describe 'getting group members information' do ...@@ -53,6 +53,30 @@ RSpec.describe 'getting group members information' do
end end
end end
context "when requesting member's notification email" do
context 'when current_user is admin' do
let_it_be(:admin_user) { create(:user, :admin) }
it 'returns notification email' do
fetch_members_notification_email(current_user: admin_user)
notification_emails = graphql_data_at(:group, :group_members, :edges, :node, :notification_email)
expect(notification_emails).to all be_present
expect(graphql_errors).to be_nil
end
end
context 'when current_user is not admin' do
it 'returns an error' do
fetch_members_notification_email
expect(graphql_errors.first)
.to include('path' => ['group', 'groupMembers', 'edges', 0, 'node', 'notificationEmail'],
'message' => a_string_including("you don't have permission to perform this action"))
end
end
end
context 'member relations' do context 'member relations' do
let_it_be(:child_group) { create(:group, :public, parent: parent_group) } let_it_be(:child_group) { create(:group, :public, parent: parent_group) }
let_it_be(:grandchild_group) { create(:group, :public, parent: child_group) } let_it_be(:grandchild_group) { create(:group, :public, parent: child_group) }
...@@ -117,6 +141,10 @@ RSpec.describe 'getting group members information' do ...@@ -117,6 +141,10 @@ RSpec.describe 'getting group members information' do
post_graphql(members_query(group.full_path, args), current_user: current_user) post_graphql(members_query(group.full_path, args), current_user: current_user)
end end
def fetch_members_notification_email(group: parent_group, current_user: user)
post_graphql(member_notification_email_query(group.full_path), current_user: current_user)
end
def members_query(group_path, args = {}) def members_query(group_path, args = {})
members_node = <<~NODE members_node = <<~NODE
edges { edges {
...@@ -134,6 +162,24 @@ RSpec.describe 'getting group members information' do ...@@ -134,6 +162,24 @@ RSpec.describe 'getting group members information' do
) )
end end
def member_notification_email_query(group_path)
members_node = <<~NODE
edges {
node {
user {
id
}
notificationEmail
}
}
NODE
graphql_query_for("group",
{ full_path: group_path },
[query_graphql_field("groupMembers", {}, members_node)]
)
end
def expect_array_response(*items) def expect_array_response(*items)
expect(response).to have_gitlab_http_status(:success) expect(response).to have_gitlab_http_status(:success)
member_gids = graphql_data_at(:group, :group_members, :edges, :node, :user, :id) member_gids = graphql_data_at(:group, :group_members, :edges, :node, :user, :id)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment