diff --git a/CHANGELOG b/CHANGELOG index d133909748b83b3e0afe519b2fc550e72a621fb8..786e9113af26b121473432cba1b28ee90a00b5f3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -508,6 +508,7 @@ v 8.10.0 - Updated project header design - Issuable collapsed assignee tooltip is now the users name - Fix compare view not changing code view rendering style + - Emoji can be awarded on Snippets !4456 - Exclude email check from the standard health check - Updated layout for Projects, Groups, Users on Admin area. !4424 - Fix changing issue state columns in milestone view diff --git a/app/controllers/concerns/toggle_award_emoji.rb b/app/controllers/concerns/toggle_award_emoji.rb index 172d5344b7a1594bd096b6291616f2d728451eb9..13086da7d5ec716f15a95df189e5971fd54339fb 100644 --- a/app/controllers/concerns/toggle_award_emoji.rb +++ b/app/controllers/concerns/toggle_award_emoji.rb @@ -10,7 +10,9 @@ module ToggleAwardEmoji if awardable.user_can_award?(current_user, name) awardable.toggle_award_emoji(name, current_user) - TodoService.new.new_award_emoji(to_todoable(awardable), current_user) + + todoable = to_todoable(awardable) + TodoService.new.new_award_emoji(todoable, current_user) if todoable render json: { ok: true } else @@ -24,8 +26,10 @@ module ToggleAwardEmoji case awardable when Note awardable.noteable - else + when MergeRequest, Issue awardable + when Snippet + nil end end diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb index 2a17c1f34db2825e9fb35a809fc91fdbef114da1..d198782138a380f52cb54bcf58f85546b722b76c 100644 --- a/app/controllers/snippets_controller.rb +++ b/app/controllers/snippets_controller.rb @@ -1,4 +1,6 @@ class SnippetsController < ApplicationController + include ToggleAwardEmoji + before_action :snippet, only: [:show, :edit, :destroy, :update, :raw] # Allow read snippet @@ -85,6 +87,7 @@ class SnippetsController < ApplicationController PersonalSnippet.find(params[:id]) end end + alias_method :awardable, :snippet def authorize_read_snippet! authenticate_user! unless can?(current_user, :read_personal_snippet, @snippet) diff --git a/app/models/snippet.rb b/app/models/snippet.rb index 5ec933601ac8d2a8486e54ce90722587a748a549..8a1730f3f36a119ed473092039f3873fe4166218 100644 --- a/app/models/snippet.rb +++ b/app/models/snippet.rb @@ -4,6 +4,7 @@ class Snippet < ActiveRecord::Base include Participable include Referable include Sortable + include Awardable default_value_for :visibility_level, Snippet::PRIVATE diff --git a/config/routes.rb b/config/routes.rb index 068c92d1400e1fb7e5000f799949ea01c7c2196a..637e5c1bac4b1ceb8d1010ba048fd0cae181296f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -101,6 +101,7 @@ Rails.application.routes.draw do resources :snippets do member do get 'raw' + post :toggle_award_emoji end end @@ -110,7 +111,6 @@ Rails.application.routes.draw do # # Invites # - resources :invites, only: [:show], constraints: { id: /[A-Za-z0-9_-]+/ } do member do post :accept @@ -665,6 +665,7 @@ Rails.application.routes.draw do resources :snippets, constraints: { id: /\d+/ } do member do get 'raw' + post :toggle_award_emoji end end diff --git a/lib/api/award_emoji.rb b/lib/api/award_emoji.rb index 7c22b17e4e507a9b5397989a05c2e19d668a21d6..2898e8222fa5b9ef722ac1722d67f308a6eaaebf 100644 --- a/lib/api/award_emoji.rb +++ b/lib/api/award_emoji.rb @@ -1,7 +1,7 @@ module API class AwardEmoji < Grape::API before { authenticate! } - AWARDABLES = [Issue, MergeRequest] + AWARDABLES = [Issue, MergeRequest, Snippet] resource :projects do AWARDABLES.each do |awardable_type| diff --git a/spec/controllers/snippets_controller_spec.rb b/spec/controllers/snippets_controller_spec.rb index 2a89159c0706d272f42ed43f8810f1a5f6f6334f..2ea57e50e76d674242d05a688ea66732641a4c67 100644 --- a/spec/controllers/snippets_controller_spec.rb +++ b/spec/controllers/snippets_controller_spec.rb @@ -1,9 +1,9 @@ require 'spec_helper' describe SnippetsController do - describe 'GET #show' do - let(:user) { create(:user) } + let(:user) { create(:user) } + describe 'GET #show' do context 'when the personal snippet is private' do let(:personal_snippet) { create(:personal_snippet, :private, author: user) } @@ -230,4 +230,31 @@ describe SnippetsController do end end end + + context 'award emoji on snippets' do + let(:personal_snippet) { create(:personal_snippet, :private, author: user) } + + before do + sign_in(user) + end + + describe 'POST #toggle_award_emoji' do + it "toggles the award emoji" do + expect do + post(:toggle_award_emoji, id: personal_snippet.to_param, name: "thumbsup") + end.to change { personal_snippet.award_emoji.count }.by(1) + + expect(response.status).to eq(200) + end + + it "removes the already awarded emoji" do + post(:toggle_award_emoji, id: personal_snippet.to_param, name: "thumbsup") + expect do + post(:toggle_award_emoji, id: personal_snippet.to_param, name: "thumbsup") + end.to change { personal_snippet.award_emoji.count }.by(-1) + + expect(response.status).to eq(200) + end + end + end end diff --git a/spec/models/snippet_spec.rb b/spec/models/snippet_spec.rb index 0621c6a06ce68adef67afdbca84c9643992fe8cd..e6bc5296398046f96a55178791fd0f1c9c46bf4d 100644 --- a/spec/models/snippet_spec.rb +++ b/spec/models/snippet_spec.rb @@ -9,12 +9,14 @@ describe Snippet, models: true do it { is_expected.to include_module(Participable) } it { is_expected.to include_module(Referable) } it { is_expected.to include_module(Sortable) } + it { is_expected.to include_module(Awardable) } end describe 'associations' do it { is_expected.to belong_to(:author).class_name('User') } it { is_expected.to belong_to(:project) } it { is_expected.to have_many(:notes).dependent(:destroy) } + it { is_expected.to have_many(:award_emoji).dependent(:destroy) } end describe 'validation' do diff --git a/spec/requests/api/award_emoji_spec.rb b/spec/requests/api/award_emoji_spec.rb index 981a679188105809ec9cebb55c43c15a867fba47..f55702794f66496ef5b03573c53d3e3c989b5328 100644 --- a/spec/requests/api/award_emoji_spec.rb +++ b/spec/requests/api/award_emoji_spec.rb @@ -14,6 +14,9 @@ describe API::API, api: true do describe "GET /projects/:id/awardable/:awardable_id/award_emoji" do context 'on an issue' do + let(:issue) { create(:issue, project: project, author: user) } + let!(:award_emoji) { create(:award_emoji, awardable: issue, user: user) } + it "returns an array of award_emoji" do get api("/projects/#{project.id}/issues/#{issue.id}/award_emoji", user) @@ -39,6 +42,10 @@ describe API::API, api: true do end end + context 'on a snippet' do + it 'returns the awarded ' + end + context 'when the user has no access' do it 'returns a status code 404' do user1 = create(:user)