summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-04-12 06:47:21 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2023-04-12 06:47:21 +0000
commitc20ce49bdab650656be01968381f6ee1a5f96e7c (patch)
tree808be3d86edf4e29a5f148aae6bb9817ea3ee9be
parent2dd1c1ab9db62a17d8f7ccaa29cec5a5f437d8de (diff)
downloadgitlab-ce-c20ce49bdab650656be01968381f6ee1a5f96e7c.tar.gz
Add latest changes from gitlab-org/gitlab@15-10-stable-ee
-rw-r--r--app/assets/javascripts/admin/broadcast_messages/components/message_form.vue39
-rw-r--r--app/assets/javascripts/admin/broadcast_messages/constants.js3
-rw-r--r--app/assets/javascripts/admin/broadcast_messages/edit.js4
-rw-r--r--app/assets/javascripts/admin/broadcast_messages/index.js11
-rw-r--r--app/helpers/broadcast_messages_helper.rb17
-rw-r--r--app/views/admin/broadcast_messages/edit.html.haml13
-rw-r--r--app/views/admin/broadcast_messages/index.html.haml2
-rw-r--r--spec/features/admin/broadcast_messages_spec.rb73
-rw-r--r--spec/frontend/admin/broadcast_messages/components/message_form_spec.js19
-rw-r--r--spec/helpers/broadcast_messages_helper_spec.rb20
10 files changed, 161 insertions, 40 deletions
diff --git a/app/assets/javascripts/admin/broadcast_messages/components/message_form.vue b/app/assets/javascripts/admin/broadcast_messages/components/message_form.vue
index 65aa4cba074..4482198675d 100644
--- a/app/assets/javascripts/admin/broadcast_messages/components/message_form.vue
+++ b/app/assets/javascripts/admin/broadcast_messages/components/message_form.vue
@@ -17,13 +17,7 @@ import { redirectTo } from '~/lib/utils/url_utility';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
import SafeHtml from '~/vue_shared/directives/safe_html';
-import {
- BROADCAST_MESSAGES_PATH,
- MESSAGES_PREVIEW_PATH,
- THEMES,
- TYPES,
- TYPE_BANNER,
-} from '../constants';
+import { THEMES, TYPES, TYPE_BANNER } from '../constants';
import MessageFormGroup from './message_form_group.vue';
import DatetimePicker from './datetime_picker.vue';
@@ -49,7 +43,17 @@ export default {
SafeHtml,
},
mixins: [glFeatureFlagsMixin()],
- inject: ['targetAccessLevelOptions'],
+ inject: {
+ targetAccessLevelOptions: {
+ default: [[]],
+ },
+ messagesPath: {
+ default: '',
+ },
+ previewPath: {
+ default: '',
+ },
+ },
i18n: {
message: s__('BroadcastMessages|Message'),
messagePlaceholder: s__('BroadcastMessages|Your message here'),
@@ -111,8 +115,8 @@ export default {
},
formPath() {
return this.isAddForm
- ? BROADCAST_MESSAGES_PATH
- : `${BROADCAST_MESSAGES_PATH}/${this.broadcastMessage.id}`;
+ ? this.messagesPath
+ : `${this.messagesPath}/${this.broadcastMessage.id}`;
},
formPayload() {
return JSON.stringify({
@@ -138,7 +142,7 @@ export default {
const success = await this.submitForm();
if (success) {
- redirectTo(BROADCAST_MESSAGES_PATH);
+ redirectTo(this.messagesPath);
} else {
this.loading = false;
}
@@ -161,7 +165,7 @@ export default {
async renderPreview() {
try {
- const res = await axios.post(MESSAGES_PREVIEW_PATH, this.formPayload, FORM_HEADERS);
+ const res = await axios.post(this.previewPath, this.formPayload, FORM_HEADERS);
this.renderedMessage = res.data;
} catch (e) {
this.renderedMessage = '';
@@ -175,7 +179,13 @@ export default {
</script>
<template>
<gl-form @submit.prevent="onSubmit">
- <gl-broadcast-message class="gl-my-6" :type="type" :theme="theme" :dismissible="dismissable">
+ <gl-broadcast-message
+ class="gl-my-6"
+ :type="type"
+ :theme="theme"
+ :dismissible="dismissable"
+ data-testid="preview-broadcast-message"
+ >
<div v-safe-html:[$options.safeHtmlConfig]="messagePreview"></div>
</gl-broadcast-message>
@@ -186,6 +196,7 @@ export default {
size="sm"
:debounce="$options.DEFAULT_DEBOUNCE_AND_THROTTLE_MS"
:placeholder="$options.i18n.messagePlaceholder"
+ data-testid="message-input"
/>
</message-form-group>
@@ -241,7 +252,7 @@ export default {
<datetime-picker v-model="endsAt" />
</message-form-group>
- <div class="form-actions gl-mb-3">
+ <div class="form-actions gl-my-3">
<gl-button
type="submit"
variant="confirm"
diff --git a/app/assets/javascripts/admin/broadcast_messages/constants.js b/app/assets/javascripts/admin/broadcast_messages/constants.js
index 323ac6857f6..9f64b2dcaa0 100644
--- a/app/assets/javascripts/admin/broadcast_messages/constants.js
+++ b/app/assets/javascripts/admin/broadcast_messages/constants.js
@@ -1,8 +1,5 @@
import { s__ } from '~/locale';
-export const BROADCAST_MESSAGES_PATH = '/admin/broadcast_messages';
-export const MESSAGES_PREVIEW_PATH = '/admin/broadcast_messages/preview';
-
export const TYPE_BANNER = 'banner';
export const TYPE_NOTIFICATION = 'notification';
diff --git a/app/assets/javascripts/admin/broadcast_messages/edit.js b/app/assets/javascripts/admin/broadcast_messages/edit.js
index 70a270f7a56..91dae949d45 100644
--- a/app/assets/javascripts/admin/broadcast_messages/edit.js
+++ b/app/assets/javascripts/admin/broadcast_messages/edit.js
@@ -11,6 +11,8 @@ export default () => {
dismissable,
targetAccessLevels,
targetAccessLevelOptions,
+ messagesPath,
+ previewPath,
targetPath,
startsAt,
endsAt,
@@ -21,6 +23,8 @@ export default () => {
name: 'EditBroadcastMessage',
provide: {
targetAccessLevelOptions: JSON.parse(targetAccessLevelOptions),
+ messagesPath,
+ previewPath,
},
render(createElement) {
return createElement(MessageForm, {
diff --git a/app/assets/javascripts/admin/broadcast_messages/index.js b/app/assets/javascripts/admin/broadcast_messages/index.js
index fd8b2aad4ec..29021043b1a 100644
--- a/app/assets/javascripts/admin/broadcast_messages/index.js
+++ b/app/assets/javascripts/admin/broadcast_messages/index.js
@@ -3,13 +3,22 @@ import BroadcastMessagesBase from './components/base.vue';
export default () => {
const el = document.querySelector('#js-broadcast-messages');
- const { page, targetAccessLevelOptions, messagesCount, messages } = el.dataset;
+ const {
+ page,
+ targetAccessLevelOptions,
+ messagesPath,
+ previewPath,
+ messagesCount,
+ messages,
+ } = el.dataset;
return new Vue({
el,
name: 'BroadcastMessages',
provide: {
targetAccessLevelOptions: JSON.parse(targetAccessLevelOptions),
+ messagesPath,
+ previewPath,
},
render(createElement) {
return createElement(BroadcastMessagesBase, {
diff --git a/app/helpers/broadcast_messages_helper.rb b/app/helpers/broadcast_messages_helper.rb
index 1c5a601de25..bc3527565a6 100644
--- a/app/helpers/broadcast_messages_helper.rb
+++ b/app/helpers/broadcast_messages_helper.rb
@@ -79,6 +79,23 @@ module BroadcastMessagesHelper
end.to_json
end
+ def broadcast_message_data(broadcast_message)
+ {
+ id: broadcast_message.id,
+ message: broadcast_message.message,
+ broadcast_type: broadcast_message.broadcast_type,
+ theme: broadcast_message.theme,
+ dismissable: broadcast_message.dismissable.to_s,
+ target_access_levels: broadcast_message.target_access_levels,
+ messages_path: admin_broadcast_messages_path,
+ preview_path: preview_admin_broadcast_messages_path,
+ target_path: broadcast_message.target_path,
+ starts_at: broadcast_message.starts_at.iso8601,
+ ends_at: broadcast_message.ends_at.iso8601,
+ target_access_level_options: target_access_level_options.to_json
+ }
+ end
+
private
def current_user_access_level_for_project_or_group
diff --git a/app/views/admin/broadcast_messages/edit.html.haml b/app/views/admin/broadcast_messages/edit.html.haml
index 212cc437d3d..63ce08eef85 100644
--- a/app/views/admin/broadcast_messages/edit.html.haml
+++ b/app/views/admin/broadcast_messages/edit.html.haml
@@ -2,15 +2,4 @@
- breadcrumb_title @broadcast_message.id
- page_title _("Broadcast Messages")
-#js-broadcast-message{ data: {
- id: @broadcast_message.id,
- message: @broadcast_message.message,
- broadcast_type: @broadcast_message.broadcast_type,
- theme: @broadcast_message.theme,
- dismissable: @broadcast_message.dismissable.to_s,
- target_access_levels: @broadcast_message.target_access_levels,
- target_path: @broadcast_message.target_path,
- starts_at: @broadcast_message.starts_at,
- ends_at: @broadcast_message.ends_at,
- target_access_level_options: target_access_level_options.to_json,
-} }
+#js-broadcast-message{ data: broadcast_message_data(@broadcast_message) }
diff --git a/app/views/admin/broadcast_messages/index.html.haml b/app/views/admin/broadcast_messages/index.html.haml
index 010cc493ddf..fb63e761f69 100644
--- a/app/views/admin/broadcast_messages/index.html.haml
+++ b/app/views/admin/broadcast_messages/index.html.haml
@@ -9,5 +9,7 @@
#js-broadcast-messages{ data: {
page: params[:page] || 1,
target_access_level_options: target_access_level_options.to_json,
+ messages_path: admin_broadcast_messages_path,
+ preview_path: preview_admin_broadcast_messages_path,
messages_count: @broadcast_messages.total_count,
messages: admin_broadcast_messages_data(@broadcast_messages) } }
diff --git a/spec/features/admin/broadcast_messages_spec.rb b/spec/features/admin/broadcast_messages_spec.rb
new file mode 100644
index 00000000000..fca4cdb0ff4
--- /dev/null
+++ b/spec/features/admin/broadcast_messages_spec.rb
@@ -0,0 +1,73 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Admin Broadcast Messages', :js, feature_category: :onboarding do
+ context 'when creating and editing' do
+ it 'previews, creates and edits a broadcast message' do
+ admin = create(:admin)
+ sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
+
+ # create
+ visit admin_broadcast_messages_path
+
+ fill_in 'Message', with: 'test message'
+
+ wait_for_requests
+
+ page.within(preview_container) do
+ expect(page).to have_content('test message')
+ end
+
+ click_button 'Add broadcast message'
+
+ wait_for_requests
+
+ page.within(preview_container) do
+ expect(page).to have_content('Your message here')
+ end
+
+ page.within(first_message_container) do
+ expect(page).to have_content('test message')
+ end
+
+ # edit
+ page.within(first_message_container) do
+ find('[data-testid="edit-message"]').click
+ end
+
+ wait_for_requests
+
+ expect(find('[data-testid="message-input"]').value).to eq('test message')
+
+ fill_in 'Message', with: 'changed test message'
+
+ wait_for_requests
+
+ page.within(preview_container) do
+ expect(page).to have_content('changed test message')
+ end
+
+ click_button 'Update broadcast message'
+
+ wait_for_requests
+
+ page.within(preview_container) do
+ expect(page).to have_content('Your message here')
+ end
+
+ page.within(first_message_container) do
+ expect(page).to have_content('changed test message')
+ end
+ end
+
+ def preview_container
+ find('[data-testid="preview-broadcast-message"]')
+ end
+
+ def first_message_container
+ find('[data-testid="message-row"]', match: :first)
+ end
+ end
+end
diff --git a/spec/frontend/admin/broadcast_messages/components/message_form_spec.js b/spec/frontend/admin/broadcast_messages/components/message_form_spec.js
index 292575c984b..ba8b9dd1345 100644
--- a/spec/frontend/admin/broadcast_messages/components/message_form_spec.js
+++ b/spec/frontend/admin/broadcast_messages/components/message_form_spec.js
@@ -5,12 +5,7 @@ import { createAlert } from '~/alert';
import axios from '~/lib/utils/axios_utils';
import { HTTP_STATUS_BAD_REQUEST } from '~/lib/utils/http_status';
import MessageForm from '~/admin/broadcast_messages/components/message_form.vue';
-import {
- BROADCAST_MESSAGES_PATH,
- TYPE_BANNER,
- TYPE_NOTIFICATION,
- THEMES,
-} from '~/admin/broadcast_messages/constants';
+import { TYPE_BANNER, TYPE_NOTIFICATION, THEMES } from '~/admin/broadcast_messages/constants';
import waitForPromises from 'helpers/wait_for_promises';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import { MOCK_TARGET_ACCESS_LEVELS } from '../mock_data';
@@ -32,6 +27,8 @@ describe('MessageForm', () => {
endsAt: new Date(),
};
+ const messagesPath = '_messages_path_';
+
const findPreview = () => extendedWrapper(wrapper.findComponent(GlBroadcastMessage));
const findThemeSelect = () => wrapper.findComponent('[data-testid=theme-select]');
const findDismissable = () => wrapper.findComponent('[data-testid=dismissable-checkbox]');
@@ -44,6 +41,8 @@ describe('MessageForm', () => {
provide: {
glFeatures,
targetAccessLevelOptions: MOCK_TARGET_ACCESS_LEVELS,
+ messagesPath,
+ previewPath: '_preview_path_',
},
propsData: {
broadcastMessage: {
@@ -153,14 +152,14 @@ describe('MessageForm', () => {
expect(axiosMock.history.post).toHaveLength(1);
expect(axiosMock.history.post[0]).toMatchObject({
- url: BROADCAST_MESSAGES_PATH,
+ url: messagesPath,
data: JSON.stringify(defaultPayload),
});
});
it('shows an error alert if the create request fails', async () => {
createComponent({ broadcastMessage: { id: undefined } });
- axiosMock.onPost(BROADCAST_MESSAGES_PATH).replyOnce(HTTP_STATUS_BAD_REQUEST);
+ axiosMock.onPost(messagesPath).replyOnce(HTTP_STATUS_BAD_REQUEST);
findForm().vm.$emit('submit', { preventDefault: () => {} });
await waitForPromises();
@@ -179,7 +178,7 @@ describe('MessageForm', () => {
expect(axiosMock.history.patch).toHaveLength(1);
expect(axiosMock.history.patch[0]).toMatchObject({
- url: `${BROADCAST_MESSAGES_PATH}/${id}`,
+ url: `${messagesPath}/${id}`,
data: JSON.stringify(defaultPayload),
});
});
@@ -187,7 +186,7 @@ describe('MessageForm', () => {
it('shows an error alert if the update request fails', async () => {
const id = 1337;
createComponent({ broadcastMessage: { id } });
- axiosMock.onPost(`${BROADCAST_MESSAGES_PATH}/${id}`).replyOnce(HTTP_STATUS_BAD_REQUEST);
+ axiosMock.onPost(`${messagesPath}/${id}`).replyOnce(HTTP_STATUS_BAD_REQUEST);
findForm().vm.$emit('submit', { preventDefault: () => {} });
await waitForPromises();
diff --git a/spec/helpers/broadcast_messages_helper_spec.rb b/spec/helpers/broadcast_messages_helper_spec.rb
index e0bdb09f257..8d2245c820f 100644
--- a/spec/helpers/broadcast_messages_helper_spec.rb
+++ b/spec/helpers/broadcast_messages_helper_spec.rb
@@ -157,4 +157,24 @@ RSpec.describe BroadcastMessagesHelper, feature_category: :onboarding do
expect(single_broadcast_message['ends_at']).to eq('2020-01-02T00:00:00Z')
end
end
+
+ describe '#broadcast_message_data' do
+ let(:starts_at) { 1.day.ago }
+ let(:ends_at) { 1.day.from_now }
+ let(:message) { build(:broadcast_message, id: non_existing_record_id, starts_at: starts_at, ends_at: ends_at) }
+
+ it 'returns the expected message data attributes' do
+ keys = [
+ :id, :message, :broadcast_type, :theme, :dismissable, :target_access_levels, :messages_path,
+ :preview_path, :target_path, :starts_at, :ends_at, :target_access_level_options
+ ]
+
+ expect(broadcast_message_data(message).keys).to match(keys)
+ end
+
+ it 'has the correct iso formatted date', time_travel_to: '2020-01-01 00:00:00 +0000' do
+ expect(broadcast_message_data(message)[:starts_at]).to eq('2019-12-31T00:00:00Z')
+ expect(broadcast_message_data(message)[:ends_at]).to eq('2020-01-02T00:00:00Z')
+ end
+ end
end