Skip to content
Snippets Groups Projects
Commit 7810d5c8 authored by Zeger-Jan van de Weg's avatar Zeger-Jan van de Weg
Browse files

Notes that are award emoji are posted as such

parent 37cdfe4f
No related branches found
No related tags found
No related merge requests found
Showing
with 144 additions and 49 deletions
Loading
Loading
@@ -150,7 +150,7 @@ class @Notes
renderNote: (note) ->
unless note.valid
if note.award
flash = new Flash('You have already awarded this emoji!', 'alert')
flash = new Flash('You have already awarded this emoji, and it we\'ve removed it', 'alert')
flash.pinTo('.header-content')
return
 
Loading
Loading
Loading
Loading
@@ -7,7 +7,7 @@ module ToggleAwardEmoji
 
def toggle_award_emoji
name = params.require(:name)
CreateAwardEmojiService.new(project, current_user).execute(awardable, name)
ToggleAwardEmojiService.new(project, current_user).execute(awardable, name)
 
render json: { ok: true }
end
Loading
Loading
Loading
Loading
@@ -111,29 +111,42 @@ class Projects::NotesController < Projects::ApplicationController
)
end
 
# When an ordinairy note is posted, this is straight forward
# But when the note is ":+1:" this toggles the emoji posted
# note is than either an AwardEmoji or an Array (its remove using a where clause)
def note_json(note)
if note.persisted?
case note
when Note
if note.persisted?
{
valid: true,
id: note.id,
discussion_id: note.discussion_id,
html: note_to_html(note),
note: note.note,
discussion_html: note_to_discussion_html(note),
discussion_with_diff_html: note_to_discussion_with_diff_html(note)
}
else
{
valid: false,
errors: note.errors
}
end
when AwardEmoji
{
valid: true,
id: note.id,
discussion_id: note.discussion_id,
html: note_to_html(note),
note: note.note,
discussion_html: note_to_discussion_html(note),
discussion_with_diff_html: note_to_discussion_with_diff_html(note)
}
elsif note.award_emoji?
award_emoji = note.award_emoji
{
valid: award_emoji.valid?,
valid: note.valid?,
award: true,
id: award_emoji.id,
name: award_emoji.name
id: note.id,
name: note.name
}
else
note = note.first
{
valid: false,
errors: note.errors
award: true,
id: note.id,
name: note.name
}
end
end
Loading
Loading
Loading
Loading
@@ -146,7 +146,7 @@ module IssuesHelper
end
 
def awards_sort(awards)
awards.sort_by do |award, notes|
awards.sort_by do |award, _|
if award == "thumbsup"
0
elsif award == "thumbsdown"
Loading
Loading
Loading
Loading
@@ -73,7 +73,7 @@ module Awardable
 
def toggle_award_emoji(emoji_name, current_user)
if awarded_emoji?(emoji_name, current_user)
remove_emoji_award(emoji_name, current_user)
remove_award_emoji(emoji_name, current_user)
else
add_award_emoji(emoji_name, current_user)
end
Loading
Loading
Loading
Loading
@@ -342,11 +342,7 @@ class Note < ActiveRecord::Base
end
 
def award_emoji?
emoji_awards_supported? && contains_only_emoji?
end
def create_award_emoji
self.award_emoji = self.noteable.award_emoji(emoji_award_name, self.author)
award_emoji_supported? && contains_only_emoji?
end
 
def emoji_awardable?
Loading
Loading
@@ -365,15 +361,10 @@ class Note < ActiveRecord::Base
diffs.find { |d| d.new_path == self.diff.new_path }
end
 
def emoji_awards_supported?
def award_emoji_supported?
noteable.kind_of?(Awardable)
end
 
def emoji_award_name
original_name = note.match(Banzai::Filter::EmojiFilter.emoji_pattern)[1]
Gitlab::AwardEmoji.normalize_emoji_name(original_name)
end
def contains_only_emoji?
note =~ /\A#{Banzai::Filter::EmojiFilter.emoji_pattern}\s?\Z/
end
Loading
Loading
Loading
Loading
@@ -6,7 +6,7 @@ module Notes
note.system = false
 
if note.award_emoji?
return CreateAwardEmojiService.new(project, current_user, params).
return ToggleAwardEmojiService.new(project, current_user, params).
execute(note.noteable, note.note)
end
 
Loading
Loading
Loading
Loading
@@ -102,7 +102,7 @@ class TodoService
#
# * mark all pending todos related to the awardable for the current user as done
#
def award_emoji(issuable, current_user)
def new_award_emoji(issuable, current_user)
mark_pending_todos_as_done(issuable, current_user)
end
 
Loading
Loading
require_relative 'base_service'
 
class CreateAwardEmojiService < BaseService
class ToggleAwardEmojiService < BaseService
# For an award emoji being posted we should:
# - Mark the TODO as done for this issuable (skip on snippets)
# - Save the award emoji
def execute(awardable, emoji)
issuable = to_issuable(awardable)
todo_service.award_emoji(issuable, current_user) if issuable
todoable = to_todoable(awardable)
todo_service.new_award_emoji(todoable, current_user) if todoable
 
# Needed if a note is posted as :+1:
emoji = emoji_award_name(emoji) if emoji.start_with? ':'
awardable.toggle_award_emoji(emoji, current_user)
awardable
end
 
private
 
def to_issuable(awardable)
def emoji_award_name(emoji)
original_name = emoji.match(Banzai::Filter::EmojiFilter.emoji_pattern)[1]
Gitlab::AwardEmoji.normalize_emoji_name(original_name)
end
def to_todoable(awardable)
case awardable
when Note
awardable.noteable
Loading
Loading
Loading
Loading
@@ -70,7 +70,7 @@
 
.content-block.content-block-small
= render 'new_branch'
= render 'emoji_awards/awards_block', awardable: @issue, inline: true
= render 'award_emoji/awards_block', awardable: @issue, inline: true
 
.row
%section.col-md-12
Loading
Loading
Loading
Loading
@@ -69,7 +69,7 @@
.tab-content
#notes.notes.tab-pane.voting_notes
.content-block.content-block-small.oneline-block
= render 'emoji_awards/awards_block', awardable: @merge_request, inline: true
= render 'award_emoji/awards_block', awardable: @merge_request, inline: true
 
.row
%section.col-md-12
Loading
Loading
Loading
Loading
@@ -34,7 +34,7 @@
- if note_editable?(note)
= render 'projects/notes/edit_form', note: note
.note-awards
= render 'emoji_awards/awards_block', awardable: note, inline: false
= render 'award_emoji/awards_block', awardable: note, inline: false
= edited_time_ago_with_tooltip(note, placement: 'bottom', html_class: 'note_edited_ago', include_author: true)
 
- if note.attachment.url
Loading
Loading
Loading
Loading
@@ -38,8 +38,3 @@ Feature: Award Emoji
And The search field is focused
And I search "hand"
Then I see search result for "hand"
@javascript
Scenario: I add award emoji using regular comment
Given I leave comment with a single emoji
Then I have award added
Loading
Loading
@@ -128,17 +128,14 @@ describe IssuesHelper do
end
 
describe "#award_active_class" do
before do
@note = create :note
@note1 = create :note
end
let!(:award) { create(:award_emoji) }
 
it "returns empty string for unauthenticated user" do
expect(award_active_class(Note.all, nil)).to eq("")
expect(award_active_class(AwardEmoji.all, nil)).to eq("")
end
 
it "returns active string for author" do
expect(award_active_class(Note.all, @note.author)).to eq("active")
expect(award_active_class(AwardEmoji.all, award.user)).to eq("active")
end
end
 
Loading
Loading
Loading
Loading
@@ -16,7 +16,7 @@ describe AwardEmoji, models: true do
it { is_expected.to validate_presence_of(:name) }
it { is_expected.to validate_presence_of(:awardable) }
 
# To circumvent in the shoulda matchers
# To circumvent a bug in the shoulda matchers
describe "scoped uniqueness validation" do
it "rejects duplicate award emoji" do
user = create(:user)
Loading
Loading
require 'spec_helper'
describe Issue, "Awardable" do
let!(:issue) { create(:issue) }
let!(:award_emoji) { create(:award_emoji, :downvote, awardable: issue) }
describe "Associations" do
it { is_expected.to have_many(:award_emoji).dependent(:destroy) }
end
describe "ClassMethods" do
let!(:issue2) { create(:issue) }
before do
create(:award_emoji, awardable: issue2)
end
it "orders on upvotes" do
expect(Issue.order_upvotes_desc.to_a).to eq [issue2, issue]
end
it "orders on downvotes" do
expect(Issue.order_downvotes_desc.to_a).to eq [issue, issue2]
end
end
describe "#upvotes" do
it "counts the number of upvotes" do
expect(issue.upvotes).to be 0
end
end
describe "#downvotes" do
it "counts the number of downvotes" do
expect(issue.downvotes).to be 1
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
end
it "toggles already awarded emoji" do
expect { issue.toggle_award_emoji("thumbsdown", award_emoji.user) }.to change { AwardEmoji.count }.by -1
end
end
end
Loading
Loading
@@ -93,6 +93,7 @@ describe User, models: true do
it { is_expected.to have_one(:abuse_report) }
it { is_expected.to have_many(:spam_logs).dependent(:destroy) }
it { is_expected.to have_many(:todos).dependent(:destroy) }
it { is_expected.to have_many(:award_emoji).dependent(:destroy) }
end
 
describe 'validations' do
Loading
Loading
Loading
Loading
@@ -106,6 +106,8 @@ describe Issues::MoveService, services: true do
notes_params.each do |note|
create(:note, note_params.merge(note))
end
create(:award_emoji, awardable: old_issue)
end
 
include_context 'issue move executed'
Loading
Loading
@@ -125,6 +127,10 @@ describe Issues::MoveService, services: true do
it 'preserves orignal author of comment' do
expect(user_notes.pluck(:author_id)).to all(eq(author.id))
end
it 'moves the award emoji too' do
expect(new_issue.award_emoji).to eq(old_issue.award_emoji)
end
end
 
context 'note that has been updated' do
Loading
Loading
Loading
Loading
@@ -129,6 +129,16 @@ describe TodoService, services: true do
end
end
 
describe "#new_award_emoji" do
let!(:todo) { create(:todo, :assigned, user: john_doe, project: project, target: issue, author: author) }
it "marks all pending tasks as done" do
service.new_award_emoji(issue, john_doe)
expect(todo.reload).to be_done
end
end
describe '#new_note' do
let!(:first_todo) { create(:todo, :assigned, user: john_doe, project: project, target: issue, author: author) }
let!(:second_todo) { create(:todo, :assigned, user: john_doe, project: project, target: issue, author: author) }
Loading
Loading
@@ -139,7 +149,7 @@ describe TodoService, services: true do
let(:note_on_project_snippet) { create(:note_on_project_snippet, project: project, author: john_doe, note: mentions) }
let(:system_note) { create(:system_note, project: project, noteable: issue) }
 
it 'mark related pending todos to the noteable for the note author as done' do
it 'marks related pending todos to the noteable for the note author as done' do
first_todo = create(:todo, :assigned, user: john_doe, project: project, target: issue, author: author)
second_todo = create(:todo, :assigned, user: john_doe, project: project, target: issue, author: author)
 
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment