diff options
24 files changed, 231 insertions, 26 deletions
diff --git a/app/assets/javascripts/notes/components/note_actions.vue b/app/assets/javascripts/notes/components/note_actions.vue index a7e2d857013..626b0799581 100644 --- a/app/assets/javascripts/notes/components/note_actions.vue +++ b/app/assets/javascripts/notes/components/note_actions.vue @@ -40,6 +40,10 @@ export default { type: Boolean, required: true, }, + canAwardEmoji: { + type: Boolean, + required: true, + }, canDelete: { type: Boolean, required: true, @@ -74,9 +78,6 @@ export default { shouldShowActionsDropdown() { return this.currentUserId && (this.canEdit || this.canReportAsAbuse); }, - canAddAwardEmoji() { - return this.currentUserId; - }, isAuthoredByCurrentUser() { return this.authorId === this.currentUserId; }, @@ -149,7 +150,7 @@ export default { </button> </div> <div - v-if="canAddAwardEmoji" + v-if="canAwardEmoji" class="note-actions-item"> <a v-tooltip diff --git a/app/assets/javascripts/notes/components/note_awards_list.vue b/app/assets/javascripts/notes/components/note_awards_list.vue index 6cb8229e268..e8fd155a1ee 100644 --- a/app/assets/javascripts/notes/components/note_awards_list.vue +++ b/app/assets/javascripts/notes/components/note_awards_list.vue @@ -28,6 +28,10 @@ export default { type: Number, required: true, }, + canAwardEmoji: { + type: Boolean, + required: true, + }, }, computed: { ...mapGetters(['getUserData']), @@ -67,9 +71,6 @@ export default { isAuthoredByMe() { return this.noteAuthorId === this.getUserData.id; }, - isLoggedIn() { - return this.getUserData.id; - }, }, created() { this.emojiSmiling = emojiSmiling; @@ -156,7 +157,7 @@ export default { return title; }, handleAward(awardName) { - if (!this.isLoggedIn) { + if (!this.canAwardEmoji) { return; } @@ -208,7 +209,7 @@ export default { </span> </button> <div - v-if="isLoggedIn" + v-if="canAwardEmoji" class="award-menu-holder"> <button v-tooltip diff --git a/app/assets/javascripts/notes/components/note_body.vue b/app/assets/javascripts/notes/components/note_body.vue index 069f94c5845..0cb626c14f4 100644 --- a/app/assets/javascripts/notes/components/note_body.vue +++ b/app/assets/javascripts/notes/components/note_body.vue @@ -112,6 +112,7 @@ export default { :note-author-id="note.author.id" :awards="note.award_emoji" :toggle-award-path="note.toggle_award_path" + :can-award-emoji="note.current_user.can_award_emoji" /> <note-attachment v-if="note.attachment" diff --git a/app/assets/javascripts/notes/components/noteable_note.vue b/app/assets/javascripts/notes/components/noteable_note.vue index 3554027d2b4..566f5c68e66 100644 --- a/app/assets/javascripts/notes/components/noteable_note.vue +++ b/app/assets/javascripts/notes/components/noteable_note.vue @@ -177,6 +177,7 @@ export default { :note-id="note.id" :access-level="note.human_access" :can-edit="note.current_user.can_edit" + :can-award-emoji="note.current_user.can_award_emoji" :can-delete="note.current_user.can_edit" :can-report-as-abuse="canReportAsAbuse" :report-abuse-path="note.report_abuse_path" diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb index 0f25d401406..5a2f7bb01c7 100644 --- a/app/helpers/issues_helper.rb +++ b/app/helpers/issues_helper.rb @@ -82,8 +82,8 @@ module IssuesHelper names.to_sentence end - def award_state_class(awards, current_user) - if !current_user + def award_state_class(awardable, awards, current_user) + if !can?(current_user, :award_emoji, awardable) "disabled" elsif current_user && awards.find { |a| a.user_id == current_user.id } "active" diff --git a/app/models/concerns/awardable.rb b/app/models/concerns/awardable.rb index d8394415362..fce37e7f78e 100644 --- a/app/models/concerns/awardable.rb +++ b/app/models/concerns/awardable.rb @@ -79,11 +79,7 @@ module Awardable end def user_can_award?(current_user, name) - if user_authored?(current_user) - !awardable_votes?(normalize_name(name)) - else - true - end + awardable_by_user?(current_user, name) && Ability.allowed?(current_user, :award_emoji, self) end def user_authored?(current_user) @@ -119,4 +115,12 @@ module Awardable def normalize_name(name) Gitlab::Emoji.normalize_emoji_name(name) end + + def awardable_by_user?(current_user, name) + if user_authored?(current_user) + !awardable_votes?(normalize_name(name)) + else + true + end + end end diff --git a/app/policies/note_policy.rb b/app/policies/note_policy.rb index 6659bf062c4..077a6761ee6 100644 --- a/app/policies/note_policy.rb +++ b/app/policies/note_policy.rb @@ -1,6 +1,6 @@ class NotePolicy < BasePolicy delegate { @subject.project } - delegate { @subject.noteable if @subject.noteable.lockable? } + delegate { @subject.noteable if DeclarativePolicy.has_policy?(@subject.noteable) } condition(:is_author) { @user && @subject.author == @user } condition(:is_noteable_author) { @user && @subject.noteable.author_id == @user.id } diff --git a/app/policies/personal_snippet_policy.rb b/app/policies/personal_snippet_policy.rb index cac0530b9f7..c1a84727cfa 100644 --- a/app/policies/personal_snippet_policy.rb +++ b/app/policies/personal_snippet_policy.rb @@ -25,4 +25,6 @@ class PersonalSnippetPolicy < BasePolicy end rule { anonymous }.prevent :comment_personal_snippet + + rule { can?(:comment_personal_snippet) }.enable :award_emoji end diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb index ac154270236..3529d0aa60c 100644 --- a/app/policies/project_policy.rb +++ b/app/policies/project_policy.rb @@ -155,6 +155,7 @@ class ProjectPolicy < BasePolicy enable :create_note enable :upload_file enable :read_cycle_analytics + enable :award_emoji end # These abilities are not allowed to admins that are not members of the project, @@ -253,6 +254,7 @@ class ProjectPolicy < BasePolicy prevent :resolve_note prevent :create_merge_request_from prevent :create_merge_request_in + prevent :award_emoji READONLY_FEATURES_WHEN_ARCHIVED.each do |feature| prevent(*create_update_admin_destroy(feature)) diff --git a/app/serializers/issue_entity.rb b/app/serializers/issue_entity.rb index b5e2334b6e3..840fdbcbf14 100644 --- a/app/serializers/issue_entity.rb +++ b/app/serializers/issue_entity.rb @@ -29,6 +29,10 @@ class IssueEntity < IssuableEntity expose :can_update do |issue| can?(request.current_user, :update_issue, issue) end + + expose :can_award_emoji do |issue| + can?(request.current_user, :award_emoji, issue) + end end expose :create_note_path do |issue| diff --git a/app/serializers/note_entity.rb b/app/serializers/note_entity.rb index fa516fee6ec..06d603b277e 100644 --- a/app/serializers/note_entity.rb +++ b/app/serializers/note_entity.rb @@ -17,6 +17,10 @@ class NoteEntity < API::Entities::Note expose :can_edit do |note| Ability.allowed?(request.current_user, :admin_note, note) end + + expose :can_award_emoji do |note| + Ability.allowed?(request.current_user, :award_emoji, note) + end end expose :resolved?, as: :resolved diff --git a/app/views/award_emoji/_awards_block.html.haml b/app/views/award_emoji/_awards_block.html.haml index 5f07d2720c2..4b3c52af16a 100644 --- a/app/views/award_emoji/_awards_block.html.haml +++ b/app/views/award_emoji/_awards_block.html.haml @@ -3,13 +3,13 @@ .awards.js-awards-block{ class: ("hidden" if !inline && grouped_emojis.empty?), data: { award_url: toggle_award_url(awardable) } } - awards_sort(grouped_emojis).each do |emoji, awards| %button.btn.award-control.js-emoji-btn.has-tooltip{ type: "button", - class: [(award_state_class(awards, current_user)), (award_user_authored_class(emoji) if user_authored)], + class: [(award_state_class(awardable, awards, current_user)), (award_user_authored_class(emoji) if user_authored)], data: { placement: "bottom", title: award_user_list(awards, current_user) } } = emoji_icon(emoji) %span.award-control-text.js-counter = awards.count - - if current_user + - if can?(current_user, :award_emoji, awardable) .award-menu-holder.js-award-holder %button.btn.award-control.has-tooltip.js-add-award{ type: 'button', 'aria-label': 'Add reaction', diff --git a/app/views/projects/notes/_actions.html.haml b/app/views/projects/notes/_actions.html.haml index 5ea653ccad5..b4fe1cabdfd 100644 --- a/app/views/projects/notes/_actions.html.haml +++ b/app/views/projects/notes/_actions.html.haml @@ -36,7 +36,7 @@ %template{ 'v-else' => '' } = render 'shared/icons/icon_resolve_discussion.svg' -- if current_user +- if can?(current_user, :award_emoji, note) - if note.emoji_awardable? - user_authored = note.user_authored?(current_user) .note-actions-item diff --git a/spec/factories/award_emoji.rb b/spec/factories/award_emoji.rb index a0abbbce686..d37e2bf511e 100644 --- a/spec/factories/award_emoji.rb +++ b/spec/factories/award_emoji.rb @@ -4,6 +4,10 @@ FactoryBot.define do user awardable factory: :issue + after(:create) do |award, evaluator| + award.awardable.project.add_guest(evaluator.user) + end + trait :upvote trait :downvote do name "thumbsdown" diff --git a/spec/features/merge_request/user_awards_emoji_spec.rb b/spec/features/merge_request/user_awards_emoji_spec.rb index 2f24cfbd9e3..fa254e8c6c5 100644 --- a/spec/features/merge_request/user_awards_emoji_spec.rb +++ b/spec/features/merge_request/user_awards_emoji_spec.rb @@ -35,6 +35,14 @@ describe 'Merge request > User awards emoji', :js do expect(page).to have_selector('.emoji-menu', count: 1) end + + describe 'the project is archived' do + let(:project) { create(:project, :public, :repository, archived: true) } + + it 'does not see award menu button' do + expect(page).not_to have_selector('.js-award-holder') + end + end end describe 'logged out' do diff --git a/spec/features/projects/awards/user_interacts_with_awards_in_issue_spec.rb b/spec/features/projects/awards/user_interacts_with_awards_in_issue_spec.rb index adff0a10f0e..8a3d83da93f 100644 --- a/spec/features/projects/awards/user_interacts_with_awards_in_issue_spec.rb +++ b/spec/features/projects/awards/user_interacts_with_awards_in_issue_spec.rb @@ -101,4 +101,72 @@ describe 'User interacts with awards in an issue', :js do expect(page).to have_selector('gl-emoji[data-name="smile"]') end + + context 'when a project is archived' do + let(:project) { create(:project, archived: true) } + + it 'hides the add award button' do + page.within('.awards') do + expect(page).not_to have_css('.js-add-award') + end + end + end + + context 'awards on a note' do + let!(:note) { create(:note, noteable: issue, project: issue.project) } + let!(:award_emoji) { create(:award_emoji, awardable: note, name: '100') } + + it 'shows the award on the note' do + page.within('.note-awards') do + expect(page).to have_selector('gl-emoji[data-name="100"]') + end + end + + it 'allows adding a vote to an award' do + page.within('.note-awards') do + find('gl-emoji[data-name="100"]').click + end + wait_for_requests + + expect(note.reload.award_emoji.size).to eq(2) + end + + it 'allows adding a new emoji' do + page.within('.note-actions') do + find('a.js-add-award').click + end + page.within('.emoji-menu-content') do + find('gl-emoji[data-name="8ball"]').click + end + wait_for_requests + + page.within('.note-awards') do + expect(page).to have_selector('gl-emoji[data-name="8ball"]') + end + expect(note.reload.award_emoji.size).to eq(2) + end + + context 'when the project is archived' do + let(:project) { create(:project, archived: true) } + + it 'hides the buttons for adding new emoji' do + page.within('.note-awards') do + expect(page).not_to have_css('.award-menu-holder') + end + + page.within('.note-actions') do + expect(page).not_to have_css('a.js-add-award') + end + end + + it 'does not allow toggling existing emoji' do + page.within('.note-awards') do + find('gl-emoji[data-name="100"]').click + end + wait_for_requests + + expect(note.reload.award_emoji.size).to eq(1) + end + end + end end diff --git a/spec/helpers/issues_helper_spec.rb b/spec/helpers/issues_helper_spec.rb index aeef5352333..95da9a6f3d4 100644 --- a/spec/helpers/issues_helper_spec.rb +++ b/spec/helpers/issues_helper_spec.rb @@ -96,13 +96,32 @@ describe IssuesHelper do describe '#award_state_class' do let!(:upvote) { create(:award_emoji) } + let(:awardable) { upvote.awardable } + let(:user) { upvote.user } + + before do + allow(helper).to receive(:can?) do |*args| + Ability.allowed?(*args) + end + end it "returns disabled string for unauthenticated user" do - expect(award_state_class(AwardEmoji.all, nil)).to eq("disabled") + expect(helper.award_state_class(awardable, AwardEmoji.all, nil)).to eq("disabled") + end + + it "returns disabled for a user that does not have access to the awardable" do + expect(helper.award_state_class(awardable, AwardEmoji.all, build(:user))).to eq("disabled") end it "returns active string for author" do - expect(award_state_class(AwardEmoji.all, upvote.user)).to eq("active") + expect(helper.award_state_class(awardable, AwardEmoji.all, upvote.user)).to eq("active") + end + + it "is blank for a user that has access to the awardable" do + user = build(:user) + expect(helper).to receive(:can?).with(user, :award_emoji, awardable).and_return(true) + + expect(helper.award_state_class(awardable, AwardEmoji.all, user)).to be_blank end end diff --git a/spec/javascripts/notes/components/note_actions_spec.js b/spec/javascripts/notes/components/note_actions_spec.js index ab81aabb992..1dfe890e05e 100644 --- a/spec/javascripts/notes/components/note_actions_spec.js +++ b/spec/javascripts/notes/components/note_actions_spec.js @@ -3,7 +3,7 @@ import store from '~/notes/stores'; import noteActions from '~/notes/components/note_actions.vue'; import { userDataMock } from '../mock_data'; -describe('issse_note_actions component', () => { +describe('issue_note_actions component', () => { let vm; let Component; @@ -24,6 +24,7 @@ describe('issse_note_actions component', () => { authorId: 26, canDelete: true, canEdit: true, + canAwardEmoji: true, canReportAsAbuse: true, noteId: 539, reportAbusePath: '/abuse_reports/new?ref_url=http%3A%2F%2Flocalhost%3A3000%2Fgitlab-org%2Fgitlab-ce%2Fissues%2F7%23note_539&user_id=26', @@ -70,6 +71,7 @@ describe('issse_note_actions component', () => { authorId: 26, canDelete: false, canEdit: false, + canAwardEmoji: false, canReportAsAbuse: false, noteId: 539, reportAbusePath: '/abuse_reports/new?ref_url=http%3A%2F%2Flocalhost%3A3000%2Fgitlab-org%2Fgitlab-ce%2Fissues%2F7%23note_539&user_id=26', diff --git a/spec/javascripts/notes/components/note_awards_list_spec.js b/spec/javascripts/notes/components/note_awards_list_spec.js index 15995ec5a05..1c30d8691b1 100644 --- a/spec/javascripts/notes/components/note_awards_list_spec.js +++ b/spec/javascripts/notes/components/note_awards_list_spec.js @@ -29,6 +29,7 @@ describe('note_awards_list component', () => { awards: awardsMock, noteAuthorId: 2, noteId: 545, + canAwardEmoji: true, toggleAwardPath: '/gitlab-org/gitlab-ce/notes/545/toggle_award_emoji', }, }).$mount(); @@ -43,14 +44,45 @@ describe('note_awards_list component', () => { expect(vm.$el.querySelector('.js-awards-block button [data-name="cartwheel_tone3"]')).toBeDefined(); }); - it('should be possible to remove awareded emoji', () => { + it('should be possible to remove awarded emoji', () => { spyOn(vm, 'handleAward').and.callThrough(); + spyOn(vm, 'toggleAwardRequest').and.callThrough(); vm.$el.querySelector('.js-awards-block button').click(); expect(vm.handleAward).toHaveBeenCalledWith('flag_tz'); + expect(vm.toggleAwardRequest).toHaveBeenCalled(); }); it('should be possible to add new emoji', () => { expect(vm.$el.querySelector('.js-add-award')).toBeDefined(); }); + + describe('when the user cannot award emoji', () => { + beforeEach(() => { + const Component = Vue.extend(awardsNote); + + vm = new Component({ + store, + propsData: { + awards: awardsMock, + noteAuthorId: 2, + noteId: 545, + canAwardEmoji: false, + toggleAwardPath: '/gitlab-org/gitlab-ce/notes/545/toggle_award_emoji', + }, + }).$mount(); + }); + + it('should not be possible to remove awarded emoji', () => { + spyOn(vm, 'toggleAwardRequest').and.callThrough(); + + vm.$el.querySelector('.js-awards-block button').click(); + + expect(vm.toggleAwardRequest).not.toHaveBeenCalled(); + }); + + it('should not be possible to add new emoji', () => { + expect(vm.$el.querySelector('.js-add-award')).toBeNull(); + }); + }); }); diff --git a/spec/javascripts/notes/components/note_body_spec.js b/spec/javascripts/notes/components/note_body_spec.js index 0ff804f0e55..4e551496ff0 100644 --- a/spec/javascripts/notes/components/note_body_spec.js +++ b/spec/javascripts/notes/components/note_body_spec.js @@ -18,6 +18,7 @@ describe('issue_note_body component', () => { propsData: { note, canEdit: true, + canAwardEmoji: true, }, }).$mount(); }); diff --git a/spec/javascripts/notes/mock_data.js b/spec/javascripts/notes/mock_data.js index 24388fba219..bfe3a65feee 100644 --- a/spec/javascripts/notes/mock_data.js +++ b/spec/javascripts/notes/mock_data.js @@ -9,6 +9,7 @@ export const notesDataMock = { totalNotes: 1, closePath: '/twitter/flight/issues/9.json?issue%5Bstate_event%5D=close', reopenPath: '/twitter/flight/issues/9.json?issue%5Bstate_event%5D=reopen', + canAwardEmoji: true, }; export const userDataMock = { @@ -30,6 +31,7 @@ export const noteableDataMock = { current_user: { can_create_note: true, can_update: true, + can_award_emoji: true, }, description: '', due_date: null, @@ -86,7 +88,10 @@ export const individualNote = { human_access: 'Owner', note: 'sdfdsaf', note_html: "<p dir='auto'>sdfdsaf</p>", - current_user: { can_edit: true }, + current_user: { + can_edit: true, + can_award_emoji: true, + }, discussion_id: '0fb4e0e3f9276e55ff32eb4195add694aece4edd', emoji_awardable: true, award_emoji: [ @@ -129,6 +134,7 @@ export const note = { note_html: '<p dir="auto">Vel id placeat reprehenderit sit numquam.</p>', current_user: { can_edit: true, + can_award_emoji: true, }, discussion_id: 'd3842a451b7f3d9a5dfce329515127b2d29a4cd0', emoji_awardable: true, @@ -187,6 +193,7 @@ export const discussionMock = { note_html: "<p dir='auto'>THIS IS A DICUSSSION!</p>", current_user: { can_edit: true, + can_award_emoji: true, }, discussion_id: '9e3bd2f71a01de45fd166e6719eb380ad9f270b1', emoji_awardable: true, @@ -231,6 +238,7 @@ export const discussionMock = { }, current_user: { can_edit: true, + can_award_emoji: true, }, discussion_id: '9e3bd2f71a01de45fd166e6719eb380ad9f270b1', emoji_awardable: true, @@ -275,6 +283,7 @@ export const discussionMock = { }, current_user: { can_edit: true, + can_award_emoji: true, }, discussion_id: '9e3bd2f71a01de45fd166e6719eb380ad9f270b1', emoji_awardable: true, @@ -365,6 +374,7 @@ export const INDIVIDUAL_NOTE_RESPONSE_MAP = { note_html: '\u003cp dir="auto"\u003esdfdsaf\u003c/p\u003e', current_user: { can_edit: true, + can_award_emoji: true, }, discussion_id: '0fb4e0e3f9276e55ff32eb4195add694aece4edd', emoji_awardable: true, @@ -425,6 +435,7 @@ export const INDIVIDUAL_NOTE_RESPONSE_MAP = { note_html: '\u003cp dir="auto"\u003eNew note!\u003c/p\u003e', current_user: { can_edit: true, + can_award_emoji: true, }, discussion_id: '70d5c92a4039a36c70100c6691c18c27e4b0a790', emoji_awardable: true, @@ -478,6 +489,7 @@ export const INDIVIDUAL_NOTE_RESPONSE_MAP = { }, current_user: { can_edit: true, + can_award_emoji: true, }, discussion_id: 'a3ed36e29b1957efb3b68c53e2d7a2b24b1df052', emoji_awardable: true, @@ -527,6 +539,7 @@ export const DISCUSSION_NOTE_RESPONSE_MAP = { note_html: '\u003cp dir="auto"\u003eAdding a comment\u003c/p\u003e', current_user: { can_edit: true, + can_award_emoji: true, }, discussion_id: 'a3ed36e29b1957efb3b68c53e2d7a2b24b1df052', emoji_awardable: true, diff --git a/spec/models/concerns/awardable_spec.rb b/spec/models/concerns/awardable_spec.rb index 34f923d3f0c..a980cff28fb 100644 --- a/spec/models/concerns/awardable_spec.rb +++ b/spec/models/concerns/awardable_spec.rb @@ -46,6 +46,31 @@ describe Awardable do end end + describe '#user_can_award?' do + let(:user) { create(:user) } + + before do + issue.project.add_guest(user) + end + + it 'does not allow upvoting or downvoting your own issue' do + issue.update!(author: user) + + expect(issue.user_can_award?(user, AwardEmoji::DOWNVOTE_NAME)).to be_falsy + expect(issue.user_can_award?(user, AwardEmoji::UPVOTE_NAME)).to be_falsy + end + + it 'is truthy when the user is allowed to award emoji' do + expect(issue.user_can_award?(user, AwardEmoji::UPVOTE_NAME)).to be_truthy + end + + it 'is falsy when the project is archived' do + issue.project.update!(archived: true) + + expect(issue.user_can_award?(user, AwardEmoji::UPVOTE_NAME)).to be_falsy + end + end + describe "#toggle_award_emoji" do it "adds an emoji if it isn't awarded yet" do expect { issue.toggle_award_emoji("thumbsup", award_emoji.user) }.to change { AwardEmoji.count }.by(1) diff --git a/spec/policies/personal_snippet_policy_spec.rb b/spec/policies/personal_snippet_policy_spec.rb index 50bb0899eba..3809692b373 100644 --- a/spec/policies/personal_snippet_policy_spec.rb +++ b/spec/policies/personal_snippet_policy_spec.rb @@ -27,6 +27,7 @@ describe PersonalSnippetPolicy do it do is_expected.to be_allowed(:read_personal_snippet) is_expected.to be_disallowed(:comment_personal_snippet) + is_expected.to be_disallowed(:award_emoji) is_expected.to be_disallowed(*author_permissions) end end @@ -37,6 +38,7 @@ describe PersonalSnippetPolicy do it do is_expected.to be_allowed(:read_personal_snippet) is_expected.to be_allowed(:comment_personal_snippet) + is_expected.to be_allowed(:award_emoji) is_expected.to be_disallowed(*author_permissions) end end @@ -47,6 +49,7 @@ describe PersonalSnippetPolicy do it do is_expected.to be_allowed(:read_personal_snippet) is_expected.to be_allowed(:comment_personal_snippet) + is_expected.to be_allowed(:award_emoji) is_expected.to be_allowed(*author_permissions) end end @@ -61,6 +64,7 @@ describe PersonalSnippetPolicy do it do is_expected.to be_disallowed(:read_personal_snippet) is_expected.to be_disallowed(:comment_personal_snippet) + is_expected.to be_disallowed(:award_emoji) is_expected.to be_disallowed(*author_permissions) end end @@ -71,6 +75,7 @@ describe PersonalSnippetPolicy do it do is_expected.to be_allowed(:read_personal_snippet) is_expected.to be_allowed(:comment_personal_snippet) + is_expected.to be_allowed(:award_emoji) is_expected.to be_disallowed(*author_permissions) end end @@ -81,6 +86,7 @@ describe PersonalSnippetPolicy do it do is_expected.to be_disallowed(:read_personal_snippet) is_expected.to be_disallowed(:comment_personal_snippet) + is_expected.to be_disallowed(:award_emoji) is_expected.to be_disallowed(*author_permissions) end end @@ -91,6 +97,7 @@ describe PersonalSnippetPolicy do it do is_expected.to be_allowed(:read_personal_snippet) is_expected.to be_allowed(:comment_personal_snippet) + is_expected.to be_allowed(:award_emoji) is_expected.to be_allowed(*author_permissions) end end @@ -105,6 +112,7 @@ describe PersonalSnippetPolicy do it do is_expected.to be_disallowed(:read_personal_snippet) is_expected.to be_disallowed(:comment_personal_snippet) + is_expected.to be_disallowed(:award_emoji) is_expected.to be_disallowed(*author_permissions) end end @@ -115,6 +123,7 @@ describe PersonalSnippetPolicy do it do is_expected.to be_disallowed(:read_personal_snippet) is_expected.to be_disallowed(:comment_personal_snippet) + is_expected.to be_disallowed(:award_emoji) is_expected.to be_disallowed(*author_permissions) end end @@ -125,6 +134,7 @@ describe PersonalSnippetPolicy do it do is_expected.to be_disallowed(:read_personal_snippet) is_expected.to be_disallowed(:comment_personal_snippet) + is_expected.to be_disallowed(:award_emoji) is_expected.to be_disallowed(*author_permissions) end end @@ -135,6 +145,7 @@ describe PersonalSnippetPolicy do it do is_expected.to be_allowed(:read_personal_snippet) is_expected.to be_allowed(:comment_personal_snippet) + is_expected.to be_allowed(:award_emoji) is_expected.to be_allowed(*author_permissions) end end diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb index 33d5a61c563..8b9c4ac0b4b 100644 --- a/spec/policies/project_policy_spec.rb +++ b/spec/policies/project_policy_spec.rb @@ -15,6 +15,7 @@ describe ProjectPolicy do read_project_for_iids read_issue_iid read_merge_request_iid read_label read_milestone read_project_snippet read_project_member read_note create_project create_issue create_note upload_file create_merge_request_in + award_emoji ] end @@ -166,6 +167,7 @@ describe ProjectPolicy do request_access upload_file resolve_note + award_emoji ] end @@ -193,7 +195,7 @@ describe ProjectPolicy do context 'when a project has pending invites' do let(:group) { create(:group, :public) } let(:project) { create(:project, :public, namespace: group) } - let(:user_permissions) { [:create_merge_request_in, :create_project, :create_issue, :create_note, :upload_file] } + let(:user_permissions) { [:create_merge_request_in, :create_project, :create_issue, :create_note, :upload_file, :award_emoji] } let(:anonymous_permissions) { guest_permissions - user_permissions } subject { described_class.new(nil, project) } |