summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Bennett <lbennett@gitlab.com>2019-04-29 12:22:25 +0100
committerLuke Bennett <lbennett@gitlab.com>2019-05-03 17:19:16 +0100
commit1fb499de278ead55384b13f659a0acfc3680e37f (patch)
treef96e024de259b68e04e1e180c81704f14b2f174d
parent7be2796e24e86c421c8988f454c51755b7f3e153 (diff)
downloadgitlab-ce-member-access-granted-leave-email-fe.tar.gz
Add leave link to access_granted emailmember-access-granted-leave-email-fe
Allows users to leave a project/group that they have been added to. Add function to leave a namespace by url param If the `leave` param is present on a project/group show page, click the leave link.
-rw-r--r--app/assets/javascripts/namespaces/leave_by_url.js22
-rw-r--r--app/assets/javascripts/pages/groups/show/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/show/index.js2
-rw-r--r--app/views/notify/member_access_granted_email.html.haml11
-rw-r--r--app/views/notify/member_access_granted_email.text.erb7
-rw-r--r--app/views/shared/members/_access_request_links.html.haml2
-rw-r--r--changelogs/unreleased/member-access-granted-leave-email-fe.yml5
-rw-r--r--locale/gitlab.pot15
-rw-r--r--spec/features/groups/members/leave_group_spec.rb26
-rw-r--r--spec/features/projects/members/group_member_cannot_leave_group_project_spec.rb9
-rw-r--r--spec/features/projects/members/member_leaves_project_spec.rb13
-rw-r--r--spec/mailers/notify_spec.rb4
12 files changed, 110 insertions, 8 deletions
diff --git a/app/assets/javascripts/namespaces/leave_by_url.js b/app/assets/javascripts/namespaces/leave_by_url.js
new file mode 100644
index 00000000000..b817d38960c
--- /dev/null
+++ b/app/assets/javascripts/namespaces/leave_by_url.js
@@ -0,0 +1,22 @@
+import Flash from '~/flash';
+import { __, sprintf } from '~/locale';
+import { getParameterByName } from '~/lib/utils/common_utils';
+
+const PARAMETER_NAME = 'leave';
+const LEAVE_LINK_SELECTOR = '.js-leave-link';
+
+export default function leaveByUrl(namespaceType) {
+ if (!namespaceType) throw new Error('namespaceType not provided');
+
+ const param = getParameterByName(PARAMETER_NAME);
+ if (!param) return;
+
+ const leaveLink = document.querySelector(LEAVE_LINK_SELECTOR);
+ if (leaveLink) {
+ leaveLink.click();
+ } else {
+ Flash(
+ sprintf(__('You do not have permission to leave this %{namespaceType}.'), { namespaceType }),
+ );
+ }
+}
diff --git a/app/assets/javascripts/pages/groups/show/index.js b/app/assets/javascripts/pages/groups/show/index.js
index af924e74f1f..82ee5ead83d 100644
--- a/app/assets/javascripts/pages/groups/show/index.js
+++ b/app/assets/javascripts/pages/groups/show/index.js
@@ -1,5 +1,7 @@
+import leaveByUrl from '~/namespaces/leave_by_url';
import initGroupDetails from '../shared/group_details';
document.addEventListener('DOMContentLoaded', () => {
+ leaveByUrl('group');
initGroupDetails();
});
diff --git a/app/assets/javascripts/pages/projects/show/index.js b/app/assets/javascripts/pages/projects/show/index.js
index 7302c1ab202..869f70e7d33 100644
--- a/app/assets/javascripts/pages/projects/show/index.js
+++ b/app/assets/javascripts/pages/projects/show/index.js
@@ -9,6 +9,7 @@ import Activities from '~/activities';
import { ajaxGet } from '~/lib/utils/common_utils';
import GpgBadges from '~/gpg_badges';
import initReadMore from '~/read_more';
+import leaveByUrl from '~/namespaces/leave_by_url';
import Star from '../../../star';
import notificationsDropdown from '../../../notifications_dropdown';
@@ -44,4 +45,5 @@ document.addEventListener('DOMContentLoaded', () => {
});
GpgBadges.fetch();
+ leaveByUrl('project');
});
diff --git a/app/views/notify/member_access_granted_email.html.haml b/app/views/notify/member_access_granted_email.html.haml
index 18dec806539..1c50dba9c97 100644
--- a/app/views/notify/member_access_granted_email.html.haml
+++ b/app/views/notify/member_access_granted_email.html.haml
@@ -1,3 +1,10 @@
+- link_end = '</a>'.html_safe
+- source_type = member_source.model_name.singular
+- leave_link = polymorphic_url([member_source], leave: 1)
+- source_link = link_to(member_source.human_name, member_source.web_url, target: '_blank', rel: 'noopener noreferrer')
+
%p
- You have been granted #{member.human_access} access to the
- #{link_to member_source.human_name, member_source.web_url} #{member_source.model_name.singular}.
+ = _('You have been granted %{access_level} access to the %{source_link} %{source_type}.').html_safe % { access_level: member.human_access, source_link: source_link, source_type: source_type }
+%p
+ - leave_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: leave_link }
+ = _('If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}.').html_safe % { source_type: source_type, leave_link_start: leave_link_start, link_end: link_end }
diff --git a/app/views/notify/member_access_granted_email.text.erb b/app/views/notify/member_access_granted_email.text.erb
index a9fb3a589a5..445009bb413 100644
--- a/app/views/notify/member_access_granted_email.text.erb
+++ b/app/views/notify/member_access_granted_email.text.erb
@@ -1,3 +1,8 @@
-You have been granted <%= member.human_access %> access to the <%= member_source.human_name %> <%= member_source.model_name.singular %>.
+<% source_type = member_source.model_name.singular %>
+<%= _('You have been granted %{access_level} access to the %{source_name} %{source_type}.') % { access_level: member.human_access, source_name: member_source.human_name, source_type: source_type } %>
<%= member_source.web_url %>
+
+<%= _('If this was a mistake you can leave the %{source_type}.') % { source_type: source_type } %>
+
+<%= polymorphic_url([member_source], leave: 1) %>
diff --git a/app/views/shared/members/_access_request_links.html.haml b/app/views/shared/members/_access_request_links.html.haml
index f7227b9101e..eac743b5206 100644
--- a/app/views/shared/members/_access_request_links.html.haml
+++ b/app/views/shared/members/_access_request_links.html.haml
@@ -5,7 +5,7 @@
= link_to link_text, polymorphic_path([:leave, source, :members]),
method: :delete,
data: { confirm: leave_confirmation_message(source) },
- class: 'access-request-link'
+ class: 'access-request-link js-leave-link'
- elsif requester = source.requesters.find_by(user_id: current_user.id) # rubocop: disable CodeReuse/ActiveRecord
= link_to _('Withdraw Access Request'), polymorphic_path([:leave, source, :members]),
method: :delete,
diff --git a/changelogs/unreleased/member-access-granted-leave-email-fe.yml b/changelogs/unreleased/member-access-granted-leave-email-fe.yml
new file mode 100644
index 00000000000..919a2464a4d
--- /dev/null
+++ b/changelogs/unreleased/member-access-granted-leave-email-fe.yml
@@ -0,0 +1,5 @@
+---
+title: Leave project/group from access granted email
+merge_request: 27892
+author:
+type: added
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 8a51ab80d6f..9a85be6613c 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -4854,6 +4854,12 @@ msgstr ""
msgid "If enabled, access to projects will be validated on an external service using their classification label."
msgstr ""
+msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
+msgstr ""
+
+msgid "If this was a mistake you can leave the %{source_type}."
+msgstr ""
+
msgid "If your HTTP repository is not publicly accessible, add authentication information to the URL: <code>https://username:password@gitlab.company.com/group/project.git</code>."
msgstr ""
@@ -10912,6 +10918,9 @@ msgstr ""
msgid "You do not have any subscriptions yet"
msgstr ""
+msgid "You do not have permission to leave this %{namespaceType}."
+msgstr ""
+
msgid "You don't have any applications"
msgstr ""
@@ -10921,6 +10930,12 @@ msgstr ""
msgid "You don't have any deployments right now."
msgstr ""
+msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
+msgstr ""
+
+msgid "You have been granted %{access_level} access to the %{source_name} %{source_type}."
+msgstr ""
+
msgid "You have been granted %{member_human_access} access to %{label}."
msgstr ""
diff --git a/spec/features/groups/members/leave_group_spec.rb b/spec/features/groups/members/leave_group_spec.rb
index 7a91c64d7db..439803f9255 100644
--- a/spec/features/groups/members/leave_group_spec.rb
+++ b/spec/features/groups/members/leave_group_spec.rb
@@ -21,6 +21,20 @@ describe 'Groups > Members > Leave group' do
expect(group.users).not_to include(user)
end
+ it 'guest leaves the group by url param', :js do
+ group.add_guest(user)
+ group.add_owner(other_user)
+
+ visit group_path(group, leave: 1)
+
+ page.accept_confirm
+
+ expect(find('.flash-notice')).to have_content "You left the \"#{group.full_name}\" group"
+ expect(page).to have_content left_group_message(group)
+ expect(current_path).to eq(dashboard_groups_path)
+ expect(group.users).not_to include(user)
+ end
+
it 'guest leaves the group as last member' do
group.add_guest(user)
@@ -32,7 +46,7 @@ describe 'Groups > Members > Leave group' do
expect(group.users).not_to include(user)
end
- it 'owner leaves the group if they is not the last owner' do
+ it 'owner leaves the group if they are not the last owner' do
group.add_owner(user)
group.add_owner(other_user)
@@ -44,7 +58,7 @@ describe 'Groups > Members > Leave group' do
expect(group.users).not_to include(user)
end
- it 'owner can not leave the group if they is a last owner' do
+ it 'owner can not leave the group if they are the last owner' do
group.add_owner(user)
visit group_path(group)
@@ -56,6 +70,14 @@ describe 'Groups > Members > Leave group' do
expect(find(:css, '.project-members-page li', text: user.name)).not_to have_selector(:css, 'a.btn-remove')
end
+ it 'owner can not leave the group by url param if they are the last owner', :js do
+ group.add_owner(user)
+
+ visit group_path(group, leave: 1)
+
+ expect(find('.flash-alert')).to have_content 'You do not have permission to leave this group'
+ end
+
def left_group_message(group)
"You left the \"#{group.name}\""
end
diff --git a/spec/features/projects/members/group_member_cannot_leave_group_project_spec.rb b/spec/features/projects/members/group_member_cannot_leave_group_project_spec.rb
index 0ab29660189..a645b917568 100644
--- a/spec/features/projects/members/group_member_cannot_leave_group_project_spec.rb
+++ b/spec/features/projects/members/group_member_cannot_leave_group_project_spec.rb
@@ -8,10 +8,17 @@ describe 'Projects > Members > Group member cannot leave group project' do
before do
group.add_developer(user)
sign_in(user)
- visit project_path(project)
end
it 'user does not see a "Leave project" link' do
+ visit project_path(project)
+
expect(page).not_to have_content 'Leave project'
end
+
+ it 'renders a flash message if attempting to leave by url', :js do
+ visit project_path(project, leave: 1)
+
+ expect(find('.flash-alert')).to have_content 'You do not have permission to leave this project'
+ end
end
diff --git a/spec/features/projects/members/member_leaves_project_spec.rb b/spec/features/projects/members/member_leaves_project_spec.rb
index 94b29de4686..bd2ef9c07c4 100644
--- a/spec/features/projects/members/member_leaves_project_spec.rb
+++ b/spec/features/projects/members/member_leaves_project_spec.rb
@@ -7,13 +7,24 @@ describe 'Projects > Members > Member leaves project' do
before do
project.add_developer(user)
sign_in(user)
- visit project_path(project)
end
it 'user leaves project' do
+ visit project_path(project)
+
click_link 'Leave project'
expect(current_path).to eq(dashboard_projects_path)
expect(project.users.exists?(user.id)).to be_falsey
end
+
+ it 'user leaves project by url param', :js do
+ visit project_path(project, leave: 1)
+
+ page.accept_confirm
+
+ expect(find('.flash-notice')).to have_content "You left the \"#{project.full_name}\" project"
+ expect(current_path).to eq(dashboard_projects_path)
+ expect(project.users.exists?(user.id)).to be_falsey
+ end
end
diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb
index fee1d701e3a..8f348b1b053 100644
--- a/spec/mailers/notify_spec.rb
+++ b/spec/mailers/notify_spec.rb
@@ -701,6 +701,8 @@ describe Notify do
is_expected.to have_body_text project.full_name
is_expected.to have_body_text project.web_url
is_expected.to have_body_text project_member.human_access
+ is_expected.to have_body_text 'leave the project'
+ is_expected.to have_body_text project_url(project, leave: 1)
end
end
@@ -1144,6 +1146,8 @@ describe Notify do
is_expected.to have_body_text group.name
is_expected.to have_body_text group.web_url
is_expected.to have_body_text group_member.human_access
+ is_expected.to have_body_text 'leave the group'
+ is_expected.to have_body_text group_url(group, leave: 1)
end
end