Commit b123ea82 authored by wortschi's avatar wortschi

Remove vue_notification_dropdown feature flag

- This enables the Vue notifications
dropdown implementation by default
and removes legacy code
parent 71f8a6f8
......@@ -291,8 +291,6 @@ linters:
- 'app/views/shared/milestones/_sidebar.html.haml'
- 'app/views/shared/milestones/_top.html.haml'
- 'app/views/shared/notes/_hints.html.haml'
- 'app/views/shared/notifications/_button.html.haml'
- 'app/views/shared/notifications/_new_button.html.haml'
- 'app/views/shared/runners/_runner_description.html.haml'
- 'app/views/shared/runners/show.html.haml'
- 'app/views/shared/snippets/_header.html.haml'
......
......@@ -115,7 +115,11 @@ export default {
<gl-loading-icon v-if="isLoading" size="lg" class="gl-mt-3" />
<template v-else>
<gl-form-group v-for="event in events" :key="event.id">
<gl-form-checkbox v-model="event.enabled" @change="updateEvent($event, event)">
<gl-form-checkbox
v-model="event.enabled"
:data-testid="`notification-setting-${event.id}`"
@change="updateEvent($event, event)"
>
<strong>{{ event.name }}</strong
><gl-loading-icon v-if="event.loading" :inline="true" class="gl-ml-2" />
</gl-form-checkbox>
......
......@@ -128,7 +128,8 @@ export default {
<gl-button-group
v-if="isCustomNotification"
v-gl-tooltip="{ title: buttonTooltip }"
data-testid="notificationButton"
data-testid="notification-button"
:class="{ disabled: disabled }"
:size="buttonSize"
>
<gl-button
......@@ -165,12 +166,13 @@ export default {
<gl-dropdown
v-else
v-gl-tooltip="{ title: buttonTooltip }"
data-testid="notificationButton"
data-testid="notification-button"
:text="buttonText"
:icon="buttonIcon"
:loading="isLoading"
:size="buttonSize"
:disabled="disabled"
:class="{ disabled: disabled }"
>
<notifications-dropdown-item
v-for="item in notificationLevels"
......
......@@ -33,7 +33,13 @@ export default {
</script>
<template>
<gl-dropdown-item is-check-item :is-checked="isActive" @click="$emit('item-selected', level)">
<gl-dropdown-item
is-check-item
:is-checked="isActive"
:class="{ 'is-active': isActive }"
data-testid="notification-item"
@click="$emit('item-selected', level)"
>
<div class="gl-display-flex gl-flex-direction-column">
<span class="gl-font-weight-bold">{{ title }}</span>
<span class="gl-text-gray-500">{{ description }}</span>
......
import $ from 'jquery';
import { Rails } from '~/lib/utils/rails_ujs';
import { __ } from '~/locale';
import { deprecatedCreateFlash as Flash } from './flash';
export default function notificationsDropdown() {
$(document).on('click', '.update-notification', function updateNotificationCallback(e) {
e.preventDefault();
if ($(this).is('.is-active') && $(this).data('notificationLevel') === 'custom') {
return;
}
const notificationLevel = $(this).data('notificationLevel');
const form = $(this).parents('.notification-form').first();
form.find('.js-notification-loading').toggleClass('spinner');
if (form.hasClass('no-label')) {
form.find('.js-notification-loading').toggleClass('hidden');
form.find('.js-notifications-icon').toggleClass('hidden');
}
form.find('#notification_setting_level').val(notificationLevel);
Rails.fire(form[0], 'submit');
});
$(document).on('ajax:success', '.notification-form', (e) => {
const data = e.detail[0];
if (data.saved) {
$(e.currentTarget).closest('.js-notification-dropdown').replaceWith(data.html);
} else {
Flash(__('Failed to save new settings'), 'alert');
}
});
}
import $ from 'jquery';
import { deprecatedCreateFlash as flash } from './flash';
import axios from './lib/utils/axios_utils';
import { __ } from './locale';
export default class NotificationsForm {
constructor() {
this.toggleCheckbox = this.toggleCheckbox.bind(this);
this.initEventListeners();
}
initEventListeners() {
$(document).on('change', '.js-custom-notification-event', this.toggleCheckbox);
}
toggleCheckbox(e) {
const $checkbox = $(e.currentTarget);
const $parent = $checkbox.closest('.form-check');
this.saveEvent($checkbox, $parent);
}
// eslint-disable-next-line class-methods-use-this
showCheckboxLoadingSpinner($parent) {
$parent.find('.is-loading').removeClass('gl-display-none');
$parent.find('.is-done').addClass('gl-display-none');
}
saveEvent($checkbox, $parent) {
const form = $parent.parents('form').first();
this.showCheckboxLoadingSpinner($parent);
axios[form.attr('method')](form.attr('action'), form.serialize())
.then(({ data }) => {
$checkbox.enable();
if (data.saved) {
$parent.find('.is-loading').addClass('gl-display-none');
$parent.find('.is-done').removeClass('gl-display-none');
setTimeout(() => {
$parent.find('.is-done').addClass('gl-display-none');
}, 2000);
}
})
.catch(() => flash(__('There was an error saving your notification settings.')));
}
}
......@@ -7,8 +7,6 @@ import initInviteMembersModal from '~/invite_members/init_invite_members_modal';
import initInviteMembersTrigger from '~/invite_members/init_invite_members_trigger';
import { getPagePath, getDashPath } from '~/lib/utils/common_utils';
import initNotificationsDropdown from '~/notifications';
import notificationsDropdown from '~/notifications_dropdown';
import NotificationsForm from '~/notifications_form';
import ProjectsList from '~/projects_list';
import GroupTabs from './group_tabs';
......@@ -22,13 +20,8 @@ export default function initGroupDetails(actionName = 'show') {
new GroupTabs({ parentEl: '.groups-listing', action });
new ShortcutsNavigation();
new NotificationsForm();
if (gon.features?.vueNotificationDropdown) {
initNotificationsDropdown();
} else {
notificationsDropdown();
}
initNotificationsDropdown();
new ProjectsList();
......
import notificationsDropdown from '../../../notifications_dropdown';
import NotificationsForm from '../../../notifications_form';
document.addEventListener('DOMContentLoaded', () => {
new NotificationsForm(); // eslint-disable-line no-new
notificationsDropdown();
});
import initNotificationsDropdown from '~/notifications';
import notificationsDropdown from '../../../../notifications_dropdown';
import NotificationsForm from '../../../../notifications_form';
document.addEventListener('DOMContentLoaded', () => {
new NotificationsForm(); // eslint-disable-line no-new
notificationsDropdown();
initNotificationsDropdown();
});
......@@ -7,16 +7,13 @@ import initInviteMembersModal from '~/invite_members/init_invite_members_modal';
import initInviteMembersTrigger from '~/invite_members/init_invite_members_trigger';
import leaveByUrl from '~/namespaces/leave_by_url';
import initVueNotificationsDropdown from '~/notifications';
import NotificationsForm from '~/notifications_form';
import initReadMore from '~/read_more';
import UserCallout from '~/user_callout';
import notificationsDropdown from '../../../notifications_dropdown';
import Star from '../../../star';
initReadMore();
new Star(); // eslint-disable-line no-new
new NotificationsForm(); // eslint-disable-line no-new
// eslint-disable-next-line no-new
new UserCallout({
setCalloutPerProject: false,
......@@ -43,12 +40,6 @@ if (document.querySelector('.project-show-activity')) {
leaveByUrl('project');
if (gon.features?.vueNotificationDropdown) {
initVueNotificationsDropdown();
} else {
notificationsDropdown();
}
initVueNotificationsDropdown();
new ShortcutsNavigation(); // eslint-disable-line no-new
......
......@@ -30,7 +30,6 @@ class GroupsController < Groups::ApplicationController
before_action do
push_frontend_feature_flag(:vue_issuables_list, @group)
push_frontend_feature_flag(:vue_notification_dropdown, @group, default_enabled: :yaml)
end
before_action do
......
# frozen_string_literal: true
class NotificationSettingsController < ApplicationController
before_action :authenticate_user!
feature_category :users
def create
return render_404 unless can_read?(resource)
@notification_setting = current_user.notification_settings_for(resource)
@saved = @notification_setting.update(notification_setting_params_for(resource))
render_response
end
def update
@notification_setting = current_user.notification_settings.find(params[:id])
@saved = @notification_setting.update(notification_setting_params_for(@notification_setting.source))
render_response
end
private
def resource
@resource ||=
if params[:project_id].present?
Project.find(params[:project_id])
elsif params[:namespace_id].present?
Group.find(params[:namespace_id])
end
end
def can_read?(resource)
ability_name = resource.class.name.downcase
ability_name = "read_#{ability_name}".to_sym
can?(current_user, ability_name, resource)
end
def render_response
btn_class = nil
if params[:hide_label].present?
btn_class = 'btn-xs' if params[:project_id].present?
response_template = 'shared/notifications/_new_button'
else
response_template = 'shared/notifications/_button'
end
render json: {
html: view_to_html_string(response_template, notification_setting: @notification_setting, btn_class: btn_class),
saved: @saved
}
end
def notification_setting_params_for(source)
params.require(:notification_setting).permit(NotificationSetting.allowed_fields(source))
end
end
......@@ -31,10 +31,6 @@ class ProjectsController < Projects::ApplicationController
# Project Export Rate Limit
before_action :export_rate_limit, only: [:export, :download_export, :generate_new_export]
before_action do
push_frontend_feature_flag(:vue_notification_dropdown, @project, default_enabled: :yaml)
end
before_action only: [:edit] do
push_frontend_feature_flag(:allow_editing_commit_messages, @project)
end
......
......@@ -23,11 +23,8 @@
.home-panel-buttons.col-md-12.col-lg-6
- if current_user
.gl-display-flex.gl-flex-wrap.gl-lg-justify-content-end.gl-mx-n2{ data: { testid: 'group-buttons' } }
- if Feature.enabled?(:vue_notification_dropdown, @group, default_enabled: :yaml)
- if @notification_setting
.js-vue-notification-dropdown{ data: { disabled: emails_disabled, dropdown_items: notification_dropdown_items(@notification_setting).to_json, notification_level: @notification_setting.level, help_page_path: help_page_path('user/profile/notifications'), group_id: @group.id, container_class: 'gl-mr-3 gl-mt-3 gl-vertical-align-top' } }
- else
= render 'shared/notifications/new_button', notification_setting: @notification_setting, btn_class: 'btn gl-button gl-sm-w-auto gl-w-full', dropdown_container_class: 'gl-mr-0 gl-px-2 gl-sm-w-auto gl-w-full', emails_disabled: emails_disabled
- if @notification_setting
.js-vue-notification-dropdown{ data: { disabled: emails_disabled.to_s, dropdown_items: notification_dropdown_items(@notification_setting).to_json, notification_level: @notification_setting.level, help_page_path: help_page_path('user/profile/notifications'), group_id: @group.id, container_class: 'gl-mr-3 gl-mt-3 gl-vertical-align-top' } }
- if can_create_subgroups
.gl-px-2.gl-sm-w-auto.gl-w-full
= link_to _("New subgroup"), new_group_path(parent_id: @group.id), class: "btn btn-success btn-md gl-button btn-success-secondary gl-mt-3 gl-sm-w-auto gl-w-full", data: { qa_selector: 'new_subgroup_button' }
......
......@@ -9,11 +9,8 @@
= link_to group.name, group_path(group)
.table-section.section-30.text-right
- if Feature.enabled?(:vue_notification_dropdown, default_enabled: :yaml)
- if setting
.js-vue-notification-dropdown{ data: { disabled: emails_disabled, dropdown_items: notification_dropdown_items(setting).to_json, notification_level: setting.level, group_id: group.id, container_class: 'gl-mr-3', show_label: "true" } }
- else
= render 'shared/notifications/button', notification_setting: setting, emails_disabled: emails_disabled
- if setting
.js-vue-notification-dropdown{ data: { disabled: emails_disabled.to_s, dropdown_items: notification_dropdown_items(setting).to_json, notification_level: setting.level, group_id: group.id, container_class: 'gl-mr-3', show_label: "true" } }
.table-section.section-30
= form_for setting, url: profile_notifications_group_path(group), method: :put, html: { class: 'update-notifications gl-display-flex' } do |f|
......
......@@ -8,8 +8,5 @@
= link_to_project(project)
.float-right
- if Feature.enabled?(:vue_notification_dropdown, default_enabled: :yaml)
- if setting
.js-vue-notification-dropdown{ data: { disabled: emails_disabled, dropdown_items: notification_dropdown_items(setting).to_json, notification_level: setting.level, project_id: project.id, container_class: 'gl-mr-3', show_label: "true" } }
- else
= render 'shared/notifications/button', notification_setting: setting, emails_disabled: emails_disabled
- if setting
.js-vue-notification-dropdown{ data: { disabled: emails_disabled.to_s, dropdown_items: notification_dropdown_items(setting).to_json, notification_level: setting.level, project_id: project.id, container_class: 'gl-mr-3', show_label: "true" } }
......@@ -32,11 +32,8 @@
%br
.clearfix
.form-group.float-left.global-notification-setting
- if Feature.enabled?(:vue_notification_dropdown, default_enabled: :yaml)
- if @global_notification_setting
.js-vue-notification-dropdown{ data: { dropdown_items: notification_dropdown_items(@global_notification_setting).to_json, notification_level: @global_notification_setting.level, help_page_path: help_page_path('user/profile/notifications'), show_label: 'true' } }
- else
= render 'shared/notifications/button', notification_setting: @global_notification_setting
- if @global_notification_setting
.js-vue-notification-dropdown{ data: { dropdown_items: notification_dropdown_items(@global_notification_setting).to_json, notification_level: @global_notification_setting.level, help_page_path: help_page_path('user/profile/notifications'), show_label: 'true' } }
.clearfix
......
......@@ -46,11 +46,8 @@
.project-repo-buttons.col-md-12.col-lg-6.d-inline-flex.flex-wrap.justify-content-lg-end
- if current_user
.d-inline-flex
- if Feature.enabled?(:vue_notification_dropdown, @project, default_enabled: :yaml)
- if @notification_setting
.js-vue-notification-dropdown{ data: { button_size: "small", disabled: emails_disabled, dropdown_items: notification_dropdown_items(@notification_setting).to_json, notification_level: @notification_setting.level, help_page_path: help_page_path('user/profile/notifications'), project_id: @project.id, container_class: 'gl-mr-3 gl-mt-5 gl-vertical-align-top' } }
- else
= render 'shared/notifications/new_button', notification_setting: @notification_setting, btn_class: 'btn-xs', dropdown_container_class: 'gl-mr-3', emails_disabled: emails_disabled
- if @notification_setting
.js-vue-notification-dropdown{ data: { button_size: "small", disabled: emails_disabled.to_s, dropdown_items: notification_dropdown_items(@notification_setting).to_json, notification_level: @notification_setting.level, help_page_path: help_page_path('user/profile/notifications'), project_id: @project.id, container_class: 'gl-mr-3 gl-mt-5 gl-vertical-align-top' } }
.count-buttons.d-inline-flex
= render 'projects/buttons/star'
......
- btn_class = local_assigns.fetch(:btn_class, '')
- emails_disabled = local_assigns.fetch(:emails_disabled, false)
- if notification_setting
- if emails_disabled
- button_title = notification_description(:owner_disabled)
- aria_label = button_title
- btn_class << " disabled"
- else
- button_title = _("Notification setting")
- aria_label = _("Notification setting - %{notification_title}") % { notification_title: notification_title(notification_setting.level) }
.js-notification-dropdown.notification-dropdown.mr-md-2.home-panel-action-button.dropdown.inline
= form_for notification_setting, remote: true, html: { class: "inline notification-form" } do |f|
= hidden_setting_source_input(notification_setting)
= f.hidden_field :level, class: "notification_setting_level"
.js-notification-toggle-btns
%div{ class: ("btn-group" if notification_setting.custom?) }
- if notification_setting.custom?
%button.dropdown-new.btn.btn-default.btn-icon.gl-button.has-tooltip.notifications-btn.text-left#notifications-button{ type: "button", title: button_title, class: "#{btn_class}", "aria-label" => aria_label, data: { container: "body", toggle: "modal", target: "#" + notifications_menu_identifier("modal", notification_setting), display: 'static' } }
= sprite_icon("notifications", css_class: "js-notification-loading")
= notification_title(notification_setting.level)
%button.btn.dropdown-toggle.gl-display-flex.gl-align-items-center{ data: { toggle: "dropdown", target: notifications_menu_identifier("dropdown", notification_setting), flip: "false" } }
= sprite_icon('chevron-down')
.sr-only Toggle dropdown
- else
%button.dropdown-new.btn.btn-default.btn-icon.gl-button.has-tooltip.notifications-btn#notifications-button{ type: "button", title: button_title, class: "#{btn_class}", "aria-label" => aria_label, data: { container: "body", toggle: "dropdown", target: notifications_menu_identifier("dropdown", notification_setting), flip: "false" } }
.float-left
= sprite_icon("notifications", css_class: "js-notification-loading")
= notification_title(notification_setting.level)
.float-right
= sprite_icon("chevron-down")
= render "shared/notifications/notification_dropdown", notification_setting: notification_setting
= content_for :scripts_body do
= render "shared/notifications/custom_notifications", notification_setting: notification_setting
- hide_label = local_assigns.fetch(:hide_label, false)
.modal.fade{ tabindex: "-1", role: "dialog", id: notifications_menu_identifier("modal", notification_setting), "aria-labelledby": "custom-notifications-title" }
.modal-dialog
.modal-content
.modal-header
%h4#custom-notifications-title.modal-title
#{ _('Custom notification events') }
%button.close{ type: "button", "data-dismiss": "modal", "aria-label" => _('Close') }
%span{ "aria-hidden": true } &times;
.modal-body
.container-fluid
= form_for notification_setting, html: { class: "custom-notifications-form" } do |f|
= hidden_setting_source_input(notification_setting)
= hidden_field_tag("hide_label", true) if hide_label
.row
.col-lg-4
%h4.gl-mt-0= _('Notification events')
%p
- notification_link = link_to _('notification emails'), help_page_path('user/profile/notifications'), target: '_blank'
- paragraph = _('Custom notification levels are the same as participating levels. With custom notification levels you will also receive notifications for select events. To find out more, check out %{notification_link}.') % { notification_link: notification_link.html_safe }
#{ paragraph.html_safe }
.col-lg-8
- notification_setting.email_events.each_with_index do |event, index|
- field_id = "#{notifications_menu_identifier("modal", notification_setting)}_notification_setting[#{event}]"
.form-group
.form-check{ class: ("gl-mt-0" if index == 0) }
= check_box("notification_setting", event, id: field_id, class: "js-custom-notification-event form-check-input", checked: notification_setting.public_send(event))
%label.form-check-label{ for: field_id }
%strong
= notification_event_name(event)
%span.spinner.is-loading.gl-vertical-align-middle.gl-display-none
= sprite_icon('check', css_class: 'is-done gl-display-none gl-vertical-align-middle gl-text-green-600')
- btn_class = local_assigns.fetch(:btn_class, '')
- dropdown_container_class = local_assigns.fetch(:dropdown_container_class, '')
- emails_disabled = local_assigns.fetch(:emails_disabled, false)
- if notification_setting
- if emails_disabled
- button_title = notification_description(:owner_disabled)
- btn_class << " disabled"
- else
- button_title = _("Notification setting - %{notification_title}") % { notification_title: notification_title(notification_setting.level) }
.js-notification-dropdown.notification-dropdown.home-panel-action-button.gl-mt-3.dropdown.inline{ class: dropdown_container_class }
= form_for notification_setting, remote: true, html: { class: "notification-form no-label" } do |f|
= hidden_setting_source_input(notification_setting)
= hidden_field_tag "hide_label", true
= f.hidden_field :level, class: "notification_setting_level"
.js-notification-toggle-btns
%div{ class: ("btn-group" if notification_setting.custom?) }
- if notification_setting.custom?
%button.dropdown-new.btn.gl-button.btn-default.has-tooltip.notifications-btn#notifications-button{ type: "button", title: button_title, class: "#{btn_class}", "aria-label" => button_title, data: { container: "body", placement: 'top', toggle: "modal", target: "#" + notifications_menu_identifier("modal", notification_setting), display: 'static' } }
= notification_setting_icon(notification_setting)
%span.js-notification-loading.fa.hidden
%button.btn.gl-button.btn-default.dropdown-toggle{ data: { toggle: "dropdown", target: notifications_menu_identifier("dropdown", notification_setting), flip: "false" }, class: "#{btn_class}" }
= sprite_icon("chevron-down", css_class: "icon mr-0")
.sr-only Toggle dropdown
- else
%button.dropdown-new.btn.gl-button.btn-default.has-tooltip.notifications-btn#notifications-button{ type: "button", title: button_title, class: "#{btn_class}", "aria-label" => button_title, data: { container: "body", placement: 'top', toggle: "dropdown", target: notifications_menu_identifier("dropdown", notification_setting), flip: "false" } }
= notification_setting_icon(notification_setting)
%span.js-notification-loading.fa.hidden
= sprite_icon("chevron-down", css_class: "icon")
= render "shared/notifications/notification_dropdown", notification_setting: notification_setting
= content_for :scripts_body do
= render "shared/notifications/custom_notifications", notification_setting: notification_setting, hide_label: true
%ul.dropdown-menu.dropdown-menu-no-wrap.dropdown-menu-selectable.dropdown-menu-large{ role: "menu", class: [notifications_menu_identifier("dropdown", notification_setting)] }
- NotificationSetting.levels.each_key do |level|
- next if level == "custom"
- next if level == "global" && notification_setting.source.nil?
= notification_list_item(level, notification_setting)
%li.divider
%li
%a.update-notification{ href: "#", role: "button", class: ("is-active" if notification_setting.custom?), data: { toggle: "modal", target: "#" + notifications_menu_identifier("modal", notification_setting), notification_level: "custom", notification_title: "Custom" } }
%strong.dropdown-menu-inner-title= s_('NotificationSetting|Custom')
%span.dropdown-menu-inner-content= notification_description("custom")
---
title: Add Vue notifications dropdown component
merge_request: 54422
author:
type: other
---
name: vue_notification_dropdown
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/52068
rollout_issue_url:
milestone: '13.8'
type: development
group: group::optimize
default_enabled: false
......@@ -166,9 +166,6 @@ Rails.application.routes.draw do
end
end
# Notification settings
resources :notification_settings, only: [:create, :update]
resources :invites, only: [:show], constraints: { id: /[A-Za-z0-9_-]+/ } do
member do
post :accept
......
......@@ -8986,9 +8986,6 @@ msgstr ""
msgid "Custom notification levels are the same as participating levels. With custom notification levels you will also receive notifications for select events. To find out more, check out %{notificationLinkStart} notification emails%{notificationLinkEnd}."
msgstr ""
msgid "Custom notification levels are the same as participating levels. With custom notification levels you will also receive notifications for select events. To find out more, check out %{notification_link}."
msgstr ""
msgid "Custom project templates"
msgstr ""
......@@ -20636,9 +20633,6 @@ msgstr ""
msgid "Notification events"
msgstr ""
msgid "Notification setting"
msgstr ""
msgid "Notification setting - %{notification_title}"
msgstr ""
......@@ -20723,9 +20717,6 @@ msgstr ""
msgid "NotificationLevel|Watch"
msgstr ""
msgid "NotificationSetting|Custom"
msgstr ""
msgid "Notifications"
msgstr ""
......@@ -30042,9 +30033,6 @@ msgstr ""
msgid "There was an error saving your changes."
msgstr ""
msgid "There was an error saving your notification settings."
msgstr ""
msgid "There was an error subscribing to this label."
msgstr ""
......@@ -35808,9 +35796,6 @@ msgstr ""
msgid "not found"
msgstr ""
msgid "notification emails"
msgstr ""
msgid "nounSeries|%{firstItem} and %{lastItem}"
msgstr ""
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe NotificationSettingsController do
let(:project) { create(:project) }
let(:group) { create(:group, :internal) }
let(:user) { create(:user) }
before do
project.add_developer(user)
end
describe '#create' do
context 'when not authorized' do
it 'redirects to sign in page' do
post :create,
params: {
project_id: project.id,
notification_setting: { level: :participating }
}
expect(response).to redirect_to(new_user_session_path)
end
end
context 'when authorized' do
let(:notification_setting) { user.notification_settings_for(source) }
let(:custom_events) do
events = {}
NotificationSetting.email_events(source).each do |event|
events[event.to_s] = true
end
events
end
before do
sign_in(user)
end
context 'for projects' do
let(:source) { project }
it 'creates notification setting' do
post :create,
params: {
project_id: project.id,
notification_setting: { level: :participating }
}
expect(response).to have_gitlab_http_status(:ok)
expect(notification_setting.level).to eq("participating")
expect(notification_setting.user_id).to eq(user.id)
expect(notification_setting.source_id).to eq(project.id)
expect(notification_setting.source_type).to eq("Project")
end
context 'with custom settings' do
it 'creates notification setting' do
post :create,
params: {
project_id: project.id,
notification_setting: { level: :custom }.merge(custom_events)
}
expect(response).to have_gitlab_http_status(:ok)
expect(notification_setting.level).to eq("custom")
custom_events.each do |event, value|
expect(notification_setting.event_enabled?(event)).to eq(value)
end
end
end
end
context 'for groups' do
let(:source) { group }
it 'creates notification setting' do
post :create,
params: {
namespace_id: group.id,
notification_setting: { level: :watch }
}
expect(response).to have_gitlab_http_status(:ok)
expect(notification_setting.level).to eq("watch")
expect(notification_setting.user_id).to eq(user.id)
expect(notification_setting.source_id).to eq(group.id)
expect(notification_setting.source_type).to eq("Namespace")
end
context 'with custom settings' do
it 'creates notification setting' do
post :create,
params: {
namespace_id: group.id,
notification_setting: { level: :custom }.merge(custom_events)
}
expect(response).to have_gitlab_http_status(:ok)
expect(notification_setting.level).to eq("custom")
custom_events.each do |event, value|
expect(notification_setting.event_enabled?(event)).to eq(value)
end
end
end
end
end
context 'not authorized' do
let(:private_project) { create(:project, :private) }
before do
sign_in(user)
end
it 'returns 404' do
post :create,
params: {
project_id: private_project.id,
notification_setting: { level: :participating }
}
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
describe '#update' do
let(:notification_setting) { user.global_notification_setting }
context 'when not authorized' do
it 'redirects to sign in page' do
put :update,
params: {
id: notification_setting,
notification_setting: { level: :participating }
}
expect(response).to redirect_to(new_user_session_path)
end
end
context 'when authorized' do
before do
sign_in(user)
end
it 'returns success' do
put :update,
params: {
id: notification_setting,
notification_setting: { level: :participating }
}
expect(response).to have_gitlab_http_status(:ok)
end
context 'and setting custom notification setting' do
let(:custom_events) do
events = {}
notification_setting.email_events.each do |event|
events[event] = "true"
end
end
it 'returns success' do
put :update,
params: {
id: notification_setting,
notification_setting: { level: :participating, events: custom_events }
}
expect(response).to have_gitlab_http_status(:ok)
end
end
end
context 'not authorized' do
let(:other_user) { create(:user) }
before do
sign_in(other_user)
end
it 'returns 404' do
put :update,
params: {
id: notification_setting,
notification_setting: { level: :participating }
}
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
end
......@@ -163,7 +163,6 @@ RSpec.describe 'Group show page' do
let!(:project) { create(:project, namespace: group) }
before do
stub_feature_flags(vue_notification_dropdown: false)
group.add_maintainer(maintainer)
sign_in(maintainer)
end
......@@ -171,14 +170,14 @@ RSpec.describe 'Group show page' do
it 'is enabled by default' do
visit path
expect(page).to have_selector('.notifications-btn:not(.disabled)', visible: true)
expect(page).to have_selector('[data-testid="notification-button"]:not(.disabled)')
end
it 'is disabled if emails are disabled' do
group.update_attribute(:emails_disabled, true)
visit path
expect(page).to have_selector('.notifications-btn.disabled', visible: true)
expect(page).to have_selector('[data-testid="notification-button"].disabled')
end
end
......
......@@ -7,7 +7,6 @@ RSpec.describe 'User visits the notifications tab', :js do
let(:user) { create(:user) }
before do
stub_feature_flags(vue_notification_dropdown: false)
project.add_maintainer(user)
sign_in(user)
visit(profile_notifications_path)
......@@ -16,17 +15,17 @@ RSpec.describe 'User visits the notifications tab', :js do
it 'changes the project notifications setting' do
expect(page).to have_content('Notifications')
first('#notifications-button').click
click_link('On mention')
first('[data-testid="notification-button"]').click
click_button('On mention')
expect(page).to have_selector('#notifications-button', text: 'On mention')
expect(page).to have_selector('[data-testid="notification-button"]', text: 'On mention')
end
context 'when project emails are disabled' do
let(:project) { create(:project, emails_disabled: true) }
it 'notification button is disabled' do
expect(page).to have_selector('.notifications-btn.disabled', visible: true)
expect(page).to have_selector('[data-testid="notification-button"].disabled')
end
end
end
......@@ -6,38 +6,36 @@ RSpec.describe 'Projects > Show > User manages notifications', :js do
let(:project) { create(:project, :public, :repository) }
before do
stub_feature_flags(vue_notification_dropdown: false)
sign_in(project.owner)
end
def click_notifications_button
first('.notifications-btn').click
first('[data-testid="notification-button"]').click
end
it 'changes the notification setting' do
visit project_path(project)
click_notifications_button
click_link 'On mention'
click_button 'On mention'
page.within('.notification-dropdown') do
expect(page).not_to have_css('.gl-spinner')
end
wait_for_requests
click_notifications_button
expect(find('.update-notification.is-active')).to have_content('On mention')
expect(page).to have_css('.notifications-icon[data-testid="notifications-icon"]')
page.within first('[data-testid="notification-button"]') do
expect(page.find('.gl-new-dropdown-item.is-active')).to have_content('On mention')
expect(page).to have_css('[data-testid="notifications-icon"]')
end
end
it 'changes the notification setting to disabled' do
visit project_path(project)
click_notifications_button
click_link 'Disabled'
click_button 'Disabled'
page.within('.notification-dropdown') do
expect(page).not_to have_css('.gl-spinner')
page.within first('[data-testid="notification-button"]') do
expect(page).to have_css('[data-testid="notifications-off-icon"]')
end
expect(page).to have_css('.notifications-icon[data-testid="notifications-off-icon"]')
end
context 'custom notification settings' do
......@@ -65,11 +63,13 @@ RSpec.describe 'Projects > Show > User manages notifications', :js do
it 'shows notification settings checkbox' do
visit project_path(project)
click_notifications_button
page.find('a[data-notification-level="custom"]').click
click_button 'Custom'
wait_for_requests
page.within('.custom-notifications-form') do
page.within('#custom-notifications-modal') do
email_events.each do |event_name|
expect(page).to have_selector("input[name='notification_setting[#{event_name}]']")
expect(page).to have_selector("[data-testid='notification-setting-#{event_name}']")
end
end
end
......@@ -80,7 +80,7 @@ RSpec.describe 'Projects > Show > User manages notifications', :js do
it 'is disabled' do
visit project_path(project)
expect(page).to have_selector('.notifications-btn.disabled', visible: true)
expect(page).to have_selector('[data-testid="notification-button"].disabled', visible: true)
end
end
end
......@@ -162,7 +162,7 @@ describe('NotificationsDropdown', () => {
initialNotificationLevel: level,
});
const tooltipElement = findByTestId('notificationButton');
const tooltipElement = findByTestId('notification-button');
const tooltip = getBinding(tooltipElement.element, 'gl-tooltip');
expect(tooltip.value.title).toBe(`${tooltipTitlePrefix} - ${title}`);
......
......@@ -9,7 +9,6 @@ RSpec.describe 'projects/_home_panel' do
let(:project) { create(:project) }
before do
stub_feature_flags(vue_notification_dropdown: false)
assign(:project, project)
allow(view).to receive(:current_user).and_return(user)
......@@ -25,11 +24,10 @@ RSpec.describe 'projects/_home_panel' do
assign(:notification_setting, notification_settings)
end
it 'makes it possible to set notification level' do
it 'renders Vue app root' do
render
expect(view).to render_template('shared/notifications/_new_button')
expect(rendered).to have_selector('.notification-dropdown')
expect(rendered).to have_selector('.js-vue-notification-dropdown')
end
end
......@@ -40,10 +38,10 @@ RSpec.describe 'projects/_home_panel' do
assign(:notification_setting, nil)
end
it 'is not possible to set notification level' do
it 'does not render Vue app root' do
render
expect(rendered).not_to have_selector('.notification_dropdown')
expect(rendered).not_to have_selector('.js-vue-notification-dropdown')
end
end
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment