Merge branch 'winh-restyle-user-status' into 'master'
Restyle status message input on profile settings Closes #49645 See merge request gitlab-org/gitlab-ce!20903
This commit is contained in:
commit
7a3d74af9c
|
@ -33,19 +33,24 @@ const categoryLabelMap = {
|
|||
const IS_VISIBLE = 'is-visible';
|
||||
const IS_RENDERED = 'is-rendered';
|
||||
|
||||
class AwardsHandler {
|
||||
export class AwardsHandler {
|
||||
constructor(emoji) {
|
||||
this.emoji = emoji;
|
||||
this.eventListeners = [];
|
||||
this.toggleButtonSelector = '.js-add-award';
|
||||
this.menuClass = 'js-award-emoji-menu';
|
||||
}
|
||||
|
||||
bindEvents() {
|
||||
// If the user shows intent let's pre-build the menu
|
||||
this.registerEventListener(
|
||||
'one',
|
||||
$(document),
|
||||
'mouseenter focus',
|
||||
'.js-add-award',
|
||||
this.toggleButtonSelector,
|
||||
'mouseenter focus',
|
||||
() => {
|
||||
const $menu = $('.emoji-menu');
|
||||
const $menu = $(`.${this.menuClass}`);
|
||||
if ($menu.length === 0) {
|
||||
requestAnimationFrame(() => {
|
||||
this.createEmojiMenu();
|
||||
|
@ -53,7 +58,7 @@ class AwardsHandler {
|
|||
}
|
||||
},
|
||||
);
|
||||
this.registerEventListener('on', $(document), 'click', '.js-add-award', e => {
|
||||
this.registerEventListener('on', $(document), 'click', this.toggleButtonSelector, e => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
this.showEmojiMenu($(e.currentTarget));
|
||||
|
@ -61,15 +66,17 @@ class AwardsHandler {
|
|||
|
||||
this.registerEventListener('on', $('html'), 'click', e => {
|
||||
const $target = $(e.target);
|
||||
if (!$target.closest('.emoji-menu').length) {
|
||||
if (!$target.closest(`.${this.menuClass}`).length) {
|
||||
$('.js-awards-block.current').removeClass('current');
|
||||
if ($('.emoji-menu').is(':visible')) {
|
||||
$('.js-add-award.is-active').removeClass('is-active');
|
||||
this.hideMenuElement($('.emoji-menu'));
|
||||
if ($(`.${this.menuClass}`).is(':visible')) {
|
||||
$(`${this.toggleButtonSelector}.is-active`).removeClass('is-active');
|
||||
this.hideMenuElement($(`.${this.menuClass}`));
|
||||
}
|
||||
}
|
||||
});
|
||||
this.registerEventListener('on', $(document), 'click', '.js-emoji-btn', e => {
|
||||
|
||||
const emojiButtonSelector = `.js-awards-block .js-emoji-btn, .${this.menuClass} .js-emoji-btn`;
|
||||
this.registerEventListener('on', $(document), 'click', emojiButtonSelector, e => {
|
||||
e.preventDefault();
|
||||
const $target = $(e.currentTarget);
|
||||
const $glEmojiElement = $target.find('gl-emoji');
|
||||
|
@ -101,7 +108,7 @@ class AwardsHandler {
|
|||
$addBtn.closest('.js-awards-block').addClass('current');
|
||||
}
|
||||
|
||||
const $menu = $('.emoji-menu');
|
||||
const $menu = $(`.${this.menuClass}`);
|
||||
const $thumbsBtn = $menu.find('[data-name="thumbsup"], [data-name="thumbsdown"]').parent();
|
||||
const $userAuthored = this.isUserAuthored($addBtn);
|
||||
if ($menu.length) {
|
||||
|
@ -118,7 +125,7 @@ class AwardsHandler {
|
|||
} else {
|
||||
$addBtn.addClass('is-loading is-active');
|
||||
this.createEmojiMenu(() => {
|
||||
const $createdMenu = $('.emoji-menu');
|
||||
const $createdMenu = $(`.${this.menuClass}`);
|
||||
$addBtn.removeClass('is-loading');
|
||||
this.positionMenu($createdMenu, $addBtn);
|
||||
return setTimeout(() => {
|
||||
|
@ -156,7 +163,7 @@ class AwardsHandler {
|
|||
}
|
||||
|
||||
const emojiMenuMarkup = `
|
||||
<div class="emoji-menu">
|
||||
<div class="emoji-menu ${this.menuClass}">
|
||||
<input type="text" name="emoji-menu-search" value="" class="js-emoji-menu-search emoji-search search-input form-control" placeholder="Search emoji" />
|
||||
|
||||
<div class="emoji-menu-content">
|
||||
|
@ -185,7 +192,7 @@ class AwardsHandler {
|
|||
|
||||
// Avoid the jank and render the remaining categories separately
|
||||
// This will take more time, but makes UI more responsive
|
||||
const menu = document.querySelector('.emoji-menu');
|
||||
const menu = document.querySelector(`.${this.menuClass}`);
|
||||
const emojiContentElement = menu.querySelector('.emoji-menu-content');
|
||||
const remainingCategories = Object.keys(categoryMap).slice(1);
|
||||
const allCategoriesAddedPromise = remainingCategories.reduce(
|
||||
|
@ -270,9 +277,9 @@ class AwardsHandler {
|
|||
if (isInVueNoteablePage() && !isMainAwardsBlock) {
|
||||
const id = votesBlock.attr('id').replace('note_', '');
|
||||
|
||||
this.hideMenuElement($('.emoji-menu'));
|
||||
this.hideMenuElement($(`.${this.menuClass}`));
|
||||
|
||||
$('.js-add-award.is-active').removeClass('is-active');
|
||||
$(`${this.toggleButtonSelector}.is-active`).removeClass('is-active');
|
||||
const toggleAwardEvent = new CustomEvent('toggleAward', {
|
||||
detail: {
|
||||
awardName: emoji,
|
||||
|
@ -291,9 +298,9 @@ class AwardsHandler {
|
|||
return typeof callback === 'function' ? callback() : undefined;
|
||||
});
|
||||
|
||||
this.hideMenuElement($('.emoji-menu'));
|
||||
this.hideMenuElement($(`.${this.menuClass}`));
|
||||
|
||||
return $('.js-add-award.is-active').removeClass('is-active');
|
||||
return $(`${this.toggleButtonSelector}.is-active`).removeClass('is-active');
|
||||
}
|
||||
|
||||
addAwardToEmojiBar(votesBlock, emoji, checkForMutuality) {
|
||||
|
@ -321,7 +328,7 @@ class AwardsHandler {
|
|||
|
||||
getVotesBlock() {
|
||||
if (isInVueNoteablePage()) {
|
||||
const $el = $('.js-add-award.is-active').closest('.note.timeline-entry');
|
||||
const $el = $(`${this.toggleButtonSelector}.is-active`).closest('.note.timeline-entry');
|
||||
|
||||
if ($el.length) {
|
||||
return $el;
|
||||
|
@ -458,7 +465,7 @@ class AwardsHandler {
|
|||
}
|
||||
|
||||
createEmoji(votesBlock, emoji) {
|
||||
if ($('.emoji-menu').length) {
|
||||
if ($(`.${this.menuClass}`).length) {
|
||||
this.createAwardButtonForVotesBlock(votesBlock, emoji);
|
||||
}
|
||||
this.createEmojiMenu(() => {
|
||||
|
@ -538,7 +545,7 @@ class AwardsHandler {
|
|||
this.searchEmojis(term);
|
||||
});
|
||||
|
||||
const $menu = $('.emoji-menu');
|
||||
const $menu = $(`.${this.menuClass}`);
|
||||
this.registerEventListener('on', $menu, transitionEndEventString, e => {
|
||||
if (e.target === e.currentTarget) {
|
||||
// Clear the search
|
||||
|
@ -608,7 +615,7 @@ class AwardsHandler {
|
|||
this.eventListeners.forEach(entry => {
|
||||
entry.element.off.call(entry.element, ...entry.args);
|
||||
});
|
||||
$('.emoji-menu').remove();
|
||||
$(`.${this.menuClass}`).remove();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -616,7 +623,11 @@ let awardsHandlerPromise = null;
|
|||
export default function loadAwardsHandler(reload = false) {
|
||||
if (!awardsHandlerPromise || reload) {
|
||||
awardsHandlerPromise = import(/* webpackChunkName: 'emoji' */ './emoji').then(
|
||||
Emoji => new AwardsHandler(Emoji),
|
||||
Emoji => {
|
||||
const awardsHandler = new AwardsHandler(Emoji);
|
||||
awardsHandler.bindEvents();
|
||||
return awardsHandler;
|
||||
},
|
||||
);
|
||||
}
|
||||
return awardsHandlerPromise;
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
import { AwardsHandler } from '~/awards_handler';
|
||||
|
||||
class EmojiMenu extends AwardsHandler {
|
||||
constructor(emoji, toggleButtonSelector, menuClass, selectEmojiCallback) {
|
||||
super(emoji);
|
||||
|
||||
this.selectEmojiCallback = selectEmojiCallback;
|
||||
this.toggleButtonSelector = toggleButtonSelector;
|
||||
this.menuClass = menuClass;
|
||||
}
|
||||
|
||||
postEmoji($emojiButton, awardUrl, selectedEmoji, callback) {
|
||||
this.selectEmojiCallback(selectedEmoji, this.emoji.glEmojiTag(selectedEmoji));
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
export default EmojiMenu;
|
|
@ -0,0 +1,49 @@
|
|||
import $ from 'jquery';
|
||||
import createFlash from '~/flash';
|
||||
import GfmAutoComplete from '~/gfm_auto_complete';
|
||||
import EmojiMenu from './emoji_menu';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const toggleEmojiMenuButtonSelector = '.js-toggle-emoji-menu';
|
||||
const toggleEmojiMenuButton = document.querySelector(toggleEmojiMenuButtonSelector);
|
||||
const statusEmojiField = document.getElementById('js-status-emoji-field');
|
||||
const statusMessageField = document.getElementById('js-status-message-field');
|
||||
const findNoEmojiPlaceholder = () => document.getElementById('js-no-emoji-placeholder');
|
||||
|
||||
const removeStatusEmoji = () => {
|
||||
const statusEmoji = toggleEmojiMenuButton.querySelector('gl-emoji');
|
||||
if (statusEmoji) {
|
||||
statusEmoji.remove();
|
||||
}
|
||||
};
|
||||
|
||||
const selectEmojiCallback = (emoji, emojiTag) => {
|
||||
statusEmojiField.value = emoji;
|
||||
findNoEmojiPlaceholder().classList.add('hidden');
|
||||
removeStatusEmoji();
|
||||
toggleEmojiMenuButton.innerHTML += emojiTag;
|
||||
};
|
||||
|
||||
const clearEmojiButton = document.getElementById('js-clear-user-status-button');
|
||||
clearEmojiButton.addEventListener('click', () => {
|
||||
statusEmojiField.value = '';
|
||||
statusMessageField.value = '';
|
||||
removeStatusEmoji();
|
||||
findNoEmojiPlaceholder().classList.remove('hidden');
|
||||
});
|
||||
|
||||
const emojiAutocomplete = new GfmAutoComplete();
|
||||
emojiAutocomplete.setup($(statusMessageField), { emojis: true });
|
||||
|
||||
import(/* webpackChunkName: 'emoji' */ '~/emoji')
|
||||
.then(Emoji => {
|
||||
const emojiMenu = new EmojiMenu(
|
||||
Emoji,
|
||||
toggleEmojiMenuButtonSelector,
|
||||
'js-status-emoji-menu',
|
||||
selectEmojiCallback,
|
||||
);
|
||||
emojiMenu.bindEvents();
|
||||
})
|
||||
.catch(() => createFlash('Failed to load emoji list!'));
|
||||
});
|
|
@ -339,3 +339,13 @@ input[type=color].form-control {
|
|||
vertical-align: unset;
|
||||
}
|
||||
}
|
||||
|
||||
// Bootstrap 3 compatibility because bootstrap_form Gem is not updated yet
|
||||
.input-group-btn:first-child {
|
||||
@extend .input-group-prepend;
|
||||
}
|
||||
|
||||
// Bootstrap 3 compatibility because bootstrap_form Gem is not updated yet
|
||||
.input-group-btn:last-child {
|
||||
@extend .input-group-append;
|
||||
}
|
||||
|
|
|
@ -546,6 +546,7 @@ ul.notes {
|
|||
|
||||
svg {
|
||||
@include btn-svg;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.award-control-icon-positive,
|
||||
|
|
|
@ -418,3 +418,23 @@ table.u2f-registrations {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.edit-user {
|
||||
.clear-user-status {
|
||||
svg {
|
||||
fill: $gl-text-color-secondary;
|
||||
}
|
||||
}
|
||||
|
||||
.emoji-menu-toggle-button {
|
||||
@extend .note-action-button;
|
||||
|
||||
.no-emoji-placeholder {
|
||||
position: relative;
|
||||
|
||||
svg {
|
||||
fill: $gl-text-color-secondary;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,4 @@ module ProfilesHelper
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
def show_user_status_field?
|
||||
Feature.enabled?(:user_status_form) || cookies[:feature_user_status_form] == 'true'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -31,17 +31,37 @@
|
|||
%hr
|
||||
= link_to _('Remove avatar'), profile_avatar_path, data: { confirm: _('Avatar will be removed. Are you sure?') }, method: :delete, class: 'btn btn-danger btn-inverted'
|
||||
|
||||
- if show_user_status_field?
|
||||
%hr
|
||||
.row
|
||||
.col-lg-4.profile-settings-sidebar
|
||||
%h4.prepend-top-0= s_("User|Current Status")
|
||||
%p= s_("Profiles|This emoji and message will appear on your profile and throughout the interface. The message can contain emoji codes, too.")
|
||||
.col-lg-8
|
||||
.row
|
||||
= f.fields_for :status, @user.status do |status_form|
|
||||
= status_form.text_field :emoji
|
||||
= status_form.text_field :message, maxlength: 100
|
||||
%hr
|
||||
.row
|
||||
.col-lg-4.profile-settings-sidebar
|
||||
%h4.prepend-top-0= s_("User|Current status")
|
||||
%p= s_("Profiles|This emoji and message will appear on your profile and throughout the interface.")
|
||||
.col-lg-8
|
||||
= f.fields_for :status, @user.status do |status_form|
|
||||
- emoji_button = button_tag type: :button,
|
||||
class: 'js-toggle-emoji-menu emoji-menu-toggle-button btn has-tooltip',
|
||||
title: s_("Profiles|Add status emoji") do
|
||||
- if @user.status
|
||||
= emoji_icon @user.status.emoji
|
||||
%span#js-no-emoji-placeholder.no-emoji-placeholder{ class: ('hidden' if @user.status) }
|
||||
= sprite_icon('emoji_slightly_smiling_face', css_class: 'award-control-icon-neutral')
|
||||
= sprite_icon('emoji_smiley', css_class: 'award-control-icon-positive')
|
||||
= sprite_icon('emoji_smile', css_class: 'award-control-icon-super-positive')
|
||||
- reset_message_button = button_tag type: :button,
|
||||
id: 'js-clear-user-status-button',
|
||||
class: 'clear-user-status btn has-tooltip',
|
||||
title: s_("Profiles|Clear status") do
|
||||
= sprite_icon("close")
|
||||
|
||||
= status_form.hidden_field :emoji, id: 'js-status-emoji-field'
|
||||
= status_form.text_field :message,
|
||||
id: 'js-status-message-field',
|
||||
class: 'form-control input-lg',
|
||||
label: s_("Profiles|Your status"),
|
||||
prepend: emoji_button,
|
||||
append: reset_message_button,
|
||||
placeholder: s_("Profiles|What's your status?")
|
||||
|
||||
%hr
|
||||
.row
|
||||
.col-lg-4.profile-settings-sidebar
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Restyle status message input on profile settings
|
||||
merge_request: 20903
|
||||
author:
|
||||
type: changed
|
|
@ -4118,9 +4118,15 @@ msgstr ""
|
|||
msgid "Profiles|Add key"
|
||||
msgstr ""
|
||||
|
||||
msgid "Profiles|Add status emoji"
|
||||
msgstr ""
|
||||
|
||||
msgid "Profiles|Change username"
|
||||
msgstr ""
|
||||
|
||||
msgid "Profiles|Clear status"
|
||||
msgstr ""
|
||||
|
||||
msgid "Profiles|Current path: %{path}"
|
||||
msgstr ""
|
||||
|
||||
|
@ -4148,7 +4154,7 @@ msgstr ""
|
|||
msgid "Profiles|This doesn't look like a public SSH key, are you sure you want to add it?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Profiles|This emoji and message will appear on your profile and throughout the interface. The message can contain emoji codes, too."
|
||||
msgid "Profiles|This emoji and message will appear on your profile and throughout the interface."
|
||||
msgstr ""
|
||||
|
||||
msgid "Profiles|Type your %{confirmationValue} to confirm:"
|
||||
|
@ -4166,6 +4172,9 @@ msgstr ""
|
|||
msgid "Profiles|Username successfully changed"
|
||||
msgstr ""
|
||||
|
||||
msgid "Profiles|What's your status?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Profiles|You don't have access to delete this user."
|
||||
msgstr ""
|
||||
|
||||
|
@ -4175,6 +4184,9 @@ msgstr ""
|
|||
msgid "Profiles|Your account is currently an owner in these groups:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Profiles|Your status"
|
||||
msgstr ""
|
||||
|
||||
msgid "Profiles|e.g. My MacBook key"
|
||||
msgstr ""
|
||||
|
||||
|
@ -5763,7 +5775,7 @@ msgstr ""
|
|||
msgid "Users"
|
||||
msgstr ""
|
||||
|
||||
msgid "User|Current Status"
|
||||
msgid "User|Current status"
|
||||
msgstr ""
|
||||
|
||||
msgid "Variables"
|
||||
|
|
|
@ -8,6 +8,10 @@ describe 'User edit profile' do
|
|||
visit(profile_path)
|
||||
end
|
||||
|
||||
def submit_settings
|
||||
click_button 'Update profile settings'
|
||||
end
|
||||
|
||||
it 'changes user profile' do
|
||||
fill_in 'user_skype', with: 'testskype'
|
||||
fill_in 'user_linkedin', with: 'testlinkedin'
|
||||
|
@ -16,7 +20,7 @@ describe 'User edit profile' do
|
|||
fill_in 'user_location', with: 'Ukraine'
|
||||
fill_in 'user_bio', with: 'I <3 GitLab'
|
||||
fill_in 'user_organization', with: 'GitLab'
|
||||
click_button 'Update profile settings'
|
||||
submit_settings
|
||||
|
||||
expect(user.reload).to have_attributes(
|
||||
skype: 'testskype',
|
||||
|
@ -34,7 +38,7 @@ describe 'User edit profile' do
|
|||
context 'user avatar' do
|
||||
before do
|
||||
attach_file(:user_avatar, Rails.root.join('spec', 'fixtures', 'banana_sample.gif'))
|
||||
click_button 'Update profile settings'
|
||||
submit_settings
|
||||
end
|
||||
|
||||
it 'changes user avatar' do
|
||||
|
@ -56,30 +60,75 @@ describe 'User edit profile' do
|
|||
end
|
||||
end
|
||||
|
||||
context 'user status' do
|
||||
it 'hides user status when the feature is disabled' do
|
||||
stub_feature_flags(user_status_form: false)
|
||||
|
||||
visit(profile_path)
|
||||
|
||||
expect(page).not_to have_content('Current Status')
|
||||
context 'user status', :js do
|
||||
def select_emoji(emoji_name)
|
||||
toggle_button = find('.js-toggle-emoji-menu')
|
||||
toggle_button.click
|
||||
emoji_button = find(%Q{.js-status-emoji-menu .js-emoji-btn gl-emoji[data-name="#{emoji_name}"]})
|
||||
emoji_button.click
|
||||
end
|
||||
|
||||
it 'shows the status form when the feature is enabled' do
|
||||
stub_feature_flags(user_status_form: true)
|
||||
|
||||
it 'shows the user status form' do
|
||||
visit(profile_path)
|
||||
|
||||
expect(page).to have_content('Current Status')
|
||||
expect(page).to have_content('Current status')
|
||||
end
|
||||
|
||||
it 'shows the status form when the feature is enabled by setting a cookie', :js do
|
||||
stub_feature_flags(user_status_form: false)
|
||||
set_cookie('feature_user_status_form', 'true')
|
||||
it 'adds emoji to user status' do
|
||||
emoji = 'biohazard'
|
||||
visit(profile_path)
|
||||
select_emoji(emoji)
|
||||
submit_settings
|
||||
|
||||
visit user_path(user)
|
||||
within('.cover-status') do
|
||||
expect(page).to have_emoji(emoji)
|
||||
end
|
||||
end
|
||||
|
||||
it 'adds message to user status' do
|
||||
message = 'I have something to say'
|
||||
visit(profile_path)
|
||||
fill_in 'js-status-message-field', with: message
|
||||
submit_settings
|
||||
|
||||
visit user_path(user)
|
||||
within('.cover-status') do
|
||||
expect(page).to have_emoji('speech_balloon')
|
||||
expect(page).to have_content message
|
||||
end
|
||||
end
|
||||
|
||||
it 'adds message and emoji to user status' do
|
||||
emoji = 'tanabata_tree'
|
||||
message = 'Playing outside'
|
||||
visit(profile_path)
|
||||
select_emoji(emoji)
|
||||
fill_in 'js-status-message-field', with: message
|
||||
submit_settings
|
||||
|
||||
visit user_path(user)
|
||||
within('.cover-status') do
|
||||
expect(page).to have_emoji(emoji)
|
||||
expect(page).to have_content message
|
||||
end
|
||||
end
|
||||
|
||||
it 'clears the user status' do
|
||||
user_status = create(:user_status, user: user, message: 'Eating bread', emoji: 'stuffed_flatbread')
|
||||
|
||||
visit user_path(user)
|
||||
within('.cover-status') do
|
||||
expect(page).to have_emoji(user_status.emoji)
|
||||
expect(page).to have_content user_status.message
|
||||
end
|
||||
|
||||
visit(profile_path)
|
||||
click_button 'js-clear-user-status-button'
|
||||
submit_settings
|
||||
|
||||
expect(page).to have_content('Current Status')
|
||||
visit user_path(user)
|
||||
expect(page).not_to have_selector '.cover-status'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
import $ from 'jquery';
|
||||
import axios from '~/lib/utils/axios_utils';
|
||||
import EmojiMenu from '~/pages/profiles/show/emoji_menu';
|
||||
import { TEST_HOST } from 'spec/test_constants';
|
||||
|
||||
describe('EmojiMenu', () => {
|
||||
const dummyEmojiTag = '<dummy></tag>';
|
||||
const dummyToggleButtonSelector = '.toggle-button-selector';
|
||||
const dummyMenuClass = 'dummy-menu-class';
|
||||
|
||||
let emojiMenu;
|
||||
let dummySelectEmojiCallback;
|
||||
let dummyEmojiList;
|
||||
|
||||
beforeEach(() => {
|
||||
dummySelectEmojiCallback = jasmine.createSpy('dummySelectEmojiCallback');
|
||||
dummyEmojiList = {
|
||||
glEmojiTag() {
|
||||
return dummyEmojiTag;
|
||||
},
|
||||
normalizeEmojiName(emoji) {
|
||||
return emoji;
|
||||
},
|
||||
isEmojiNameValid() {
|
||||
return true;
|
||||
},
|
||||
getEmojiCategoryMap() {
|
||||
return { dummyCategory: [] };
|
||||
},
|
||||
};
|
||||
|
||||
emojiMenu = new EmojiMenu(
|
||||
dummyEmojiList,
|
||||
dummyToggleButtonSelector,
|
||||
dummyMenuClass,
|
||||
dummySelectEmojiCallback,
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
emojiMenu.destroy();
|
||||
});
|
||||
|
||||
describe('addAward', () => {
|
||||
const dummyAwardUrl = `${TEST_HOST}/award/url`;
|
||||
const dummyEmoji = 'tropical_fish';
|
||||
const dummyVotesBlock = () => $('<div />');
|
||||
|
||||
it('calls selectEmojiCallback', done => {
|
||||
expect(dummySelectEmojiCallback).not.toHaveBeenCalled();
|
||||
|
||||
emojiMenu.addAward(dummyVotesBlock(), dummyAwardUrl, dummyEmoji, false, () => {
|
||||
expect(dummySelectEmojiCallback).toHaveBeenCalledWith(dummyEmoji, dummyEmojiTag);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('does not make an axios requst', done => {
|
||||
spyOn(axios, 'request').and.stub();
|
||||
|
||||
emojiMenu.addAward(dummyVotesBlock(), dummyAwardUrl, dummyEmoji, false, () => {
|
||||
expect(axios.request).not.toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('bindEvents', () => {
|
||||
beforeEach(() => {
|
||||
spyOn(emojiMenu, 'registerEventListener').and.stub();
|
||||
});
|
||||
|
||||
it('binds event listeners to custom toggle button', () => {
|
||||
emojiMenu.bindEvents();
|
||||
|
||||
expect(emojiMenu.registerEventListener).toHaveBeenCalledWith(
|
||||
'one',
|
||||
jasmine.anything(),
|
||||
'mouseenter focus',
|
||||
dummyToggleButtonSelector,
|
||||
'mouseenter focus',
|
||||
jasmine.anything(),
|
||||
);
|
||||
expect(emojiMenu.registerEventListener).toHaveBeenCalledWith(
|
||||
'on',
|
||||
jasmine.anything(),
|
||||
'click',
|
||||
dummyToggleButtonSelector,
|
||||
jasmine.anything(),
|
||||
);
|
||||
});
|
||||
|
||||
it('binds event listeners to custom menu class', () => {
|
||||
emojiMenu.bindEvents();
|
||||
|
||||
expect(emojiMenu.registerEventListener).toHaveBeenCalledWith(
|
||||
'on',
|
||||
jasmine.anything(),
|
||||
'click',
|
||||
`.js-awards-block .js-emoji-btn, .${dummyMenuClass} .js-emoji-btn`,
|
||||
jasmine.anything(),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('createEmojiMenu', () => {
|
||||
it('renders the menu with custom menu class', () => {
|
||||
const menuElement = () =>
|
||||
document.body.querySelector(`.emoji-menu.${dummyMenuClass} .emoji-menu-content`);
|
||||
expect(menuElement()).toBe(null);
|
||||
|
||||
emojiMenu.createEmojiMenu();
|
||||
|
||||
expect(menuElement()).not.toBe(null);
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue