Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-12-13 21:09:27 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-12-13 21:09:27 +0300
commit5248c5e2212b8e42b28b23e6839d69db0006829b (patch)
treef989d4b4cd06fc5dc28c024a5f230b42b0af179b /spec/frontend/admin
parent0d55697d64b5f053bbd0f69da2962e7478097de3 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend/admin')
-rw-r--r--spec/frontend/admin/broadcast_messages/components/datetime_picker_spec.js46
-rw-r--r--spec/frontend/admin/broadcast_messages/components/message_form_spec.js201
-rw-r--r--spec/frontend/admin/broadcast_messages/mock_data.js8
3 files changed, 255 insertions, 0 deletions
diff --git a/spec/frontend/admin/broadcast_messages/components/datetime_picker_spec.js b/spec/frontend/admin/broadcast_messages/components/datetime_picker_spec.js
new file mode 100644
index 00000000000..291c3aed1cf
--- /dev/null
+++ b/spec/frontend/admin/broadcast_messages/components/datetime_picker_spec.js
@@ -0,0 +1,46 @@
+import { mount } from '@vue/test-utils';
+import { GlDatepicker } from '@gitlab/ui';
+import DatetimePicker from '~/admin/broadcast_messages/components/datetime_picker.vue';
+
+describe('DatetimePicker', () => {
+ let wrapper;
+
+ const toDate = (day, time) => new Date(`${day}T${time}:00.000Z`);
+ const findDatepicker = () => wrapper.findComponent(GlDatepicker);
+ const findTimepicker = () => wrapper.findComponent('[data-testid="time-picker"]');
+
+ const testDay = '2022-03-22';
+ const testTime = '01:23';
+
+ function createComponent() {
+ wrapper = mount(DatetimePicker, {
+ propsData: {
+ value: toDate(testDay, testTime),
+ },
+ });
+ }
+
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('renders the Date in the datepicker and timepicker inputs', () => {
+ expect(findDatepicker().props().value).toEqual(toDate(testDay, testTime));
+ expect(findTimepicker().element.value).toEqual(testTime);
+ });
+
+ it('emits Date with the new day/old time when the date picker changes', () => {
+ const newDay = '1992-06-30';
+ const newTime = '08:00';
+
+ findDatepicker().vm.$emit('input', toDate(newDay, newTime));
+ expect(wrapper.emitted().input).toEqual([[toDate(newDay, testTime)]]);
+ });
+
+ it('emits Date with the old day/new time when the time picker changes', () => {
+ const newTime = '08:00';
+
+ findTimepicker().vm.$emit('input', newTime);
+ expect(wrapper.emitted().input).toEqual([[toDate(testDay, newTime)]]);
+ });
+});
diff --git a/spec/frontend/admin/broadcast_messages/components/message_form_spec.js b/spec/frontend/admin/broadcast_messages/components/message_form_spec.js
new file mode 100644
index 00000000000..88ea79f38b3
--- /dev/null
+++ b/spec/frontend/admin/broadcast_messages/components/message_form_spec.js
@@ -0,0 +1,201 @@
+import { mount } from '@vue/test-utils';
+import { GlBroadcastMessage, GlForm } from '@gitlab/ui';
+import AxiosMockAdapter from 'axios-mock-adapter';
+import { createAlert } from '~/flash';
+import axios from '~/lib/utils/axios_utils';
+import httpStatus 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 waitForPromises from 'helpers/wait_for_promises';
+import { extendedWrapper } from 'helpers/vue_test_utils_helper';
+import { MOCK_TARGET_ACCESS_LEVELS } from '../mock_data';
+
+jest.mock('~/flash');
+
+describe('MessageForm', () => {
+ let wrapper;
+ let axiosMock;
+
+ const defaultProps = {
+ message: 'zzzzzzz',
+ broadcastType: TYPE_BANNER,
+ theme: THEMES[0].value,
+ dismissable: false,
+ targetPath: '',
+ targetAccessLevels: [],
+ startsAt: new Date(),
+ endsAt: new Date(),
+ };
+
+ const findPreview = () => extendedWrapper(wrapper.findComponent(GlBroadcastMessage));
+ const findThemeSelect = () => wrapper.findComponent('[data-testid=theme-select]');
+ const findDismissable = () => wrapper.findComponent('[data-testid=dismissable-checkbox]');
+ const findTargetRoles = () => wrapper.findComponent('[data-testid=target-roles-checkboxes]');
+ const findSubmitButton = () => wrapper.findComponent('[data-testid=submit-button]');
+ const findForm = () => wrapper.findComponent(GlForm);
+
+ function createComponent({ broadcastMessage = {}, glFeatures = {} }) {
+ wrapper = mount(MessageForm, {
+ provide: {
+ glFeatures,
+ targetAccessLevelOptions: MOCK_TARGET_ACCESS_LEVELS,
+ },
+ propsData: {
+ broadcastMessage: {
+ ...defaultProps,
+ ...broadcastMessage,
+ },
+ },
+ });
+ }
+
+ beforeEach(() => {
+ axiosMock = new AxiosMockAdapter(axios);
+ });
+
+ afterEach(() => {
+ axiosMock.restore();
+ createAlert.mockClear();
+ });
+
+ describe('the message preview', () => {
+ it('renders the preview with the user selected theme', () => {
+ const theme = 'blue';
+ createComponent({ broadcastMessage: { theme } });
+ expect(findPreview().props().theme).toEqual(theme);
+ });
+
+ it('renders the placeholder text when the user message is blank', () => {
+ createComponent({ broadcastMessage: { message: ' ' } });
+ expect(wrapper.text()).toContain(wrapper.vm.$options.i18n.messagePlaceholder);
+ });
+ });
+
+ describe('theme select dropdown', () => {
+ it('renders for Banners', () => {
+ createComponent({ broadcastMessage: { broadcastType: TYPE_BANNER } });
+ expect(findThemeSelect().exists()).toBe(true);
+ });
+
+ it('does not render for Notifications', () => {
+ createComponent({ broadcastMessage: { broadcastType: TYPE_NOTIFICATION } });
+ expect(findThemeSelect().exists()).toBe(false);
+ });
+ });
+
+ describe('dismissable checkbox', () => {
+ it('renders for Banners', () => {
+ createComponent({ broadcastMessage: { broadcastType: TYPE_BANNER } });
+ expect(findDismissable().exists()).toBe(true);
+ });
+
+ it('does not render for Notifications', () => {
+ createComponent({ broadcastMessage: { broadcastType: TYPE_NOTIFICATION } });
+ expect(findDismissable().exists()).toBe(false);
+ });
+ });
+
+ describe('target roles checkboxes', () => {
+ it('renders when roleTargetedBroadcastMessages feature is enabled', () => {
+ createComponent({ glFeatures: { roleTargetedBroadcastMessages: true } });
+ expect(findTargetRoles().exists()).toBe(true);
+ });
+
+ it('does not render when roleTargetedBroadcastMessages feature is disabled', () => {
+ createComponent({ glFeatures: { roleTargetedBroadcastMessages: false } });
+ expect(findTargetRoles().exists()).toBe(false);
+ });
+ });
+
+ describe('form submit button', () => {
+ it('renders the "add" text when the message is not persisted', () => {
+ createComponent({ broadcastMessage: { id: undefined } });
+ expect(wrapper.text()).toContain(wrapper.vm.$options.i18n.add);
+ });
+
+ it('renders the "update" text when the message is persisted', () => {
+ createComponent({ broadcastMessage: { id: 100 } });
+ expect(wrapper.text()).toContain(wrapper.vm.$options.i18n.update);
+ });
+
+ it('is disabled when the user message is blank', () => {
+ createComponent({ broadcastMessage: { message: ' ' } });
+ expect(findSubmitButton().props().disabled).toBe(true);
+ });
+
+ it('is not disabled when the user message is present', () => {
+ createComponent({ broadcastMessage: { message: 'alsdjfkldsj' } });
+ expect(findSubmitButton().props().disabled).toBe(false);
+ });
+ });
+
+ describe('form submission', () => {
+ const defaultPayload = {
+ message: defaultProps.message,
+ broadcast_type: defaultProps.broadcastType,
+ theme: defaultProps.theme,
+ dismissable: defaultProps.dismissable,
+ target_path: defaultProps.targetPath,
+ target_access_levels: defaultProps.targetAccessLevels,
+ starts_at: defaultProps.startsAt,
+ ends_at: defaultProps.endsAt,
+ };
+
+ it('sends a create request for a new message form', async () => {
+ createComponent({ broadcastMessage: { id: undefined } });
+ findForm().vm.$emit('submit', { preventDefault: () => {} });
+ await waitForPromises();
+
+ expect(axiosMock.history.post).toHaveLength(1);
+ expect(axiosMock.history.post[0]).toMatchObject({
+ url: BROADCAST_MESSAGES_PATH,
+ 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(httpStatus.BAD_REQUEST);
+ findForm().vm.$emit('submit', { preventDefault: () => {} });
+ await waitForPromises();
+
+ expect(createAlert).toHaveBeenCalledWith(
+ expect.objectContaining({
+ message: wrapper.vm.$options.i18n.addError,
+ }),
+ );
+ });
+
+ it('sends an update request for a persisted message form', async () => {
+ const id = 1337;
+ createComponent({ broadcastMessage: { id } });
+ findForm().vm.$emit('submit', { preventDefault: () => {} });
+ await waitForPromises();
+
+ expect(axiosMock.history.patch).toHaveLength(1);
+ expect(axiosMock.history.patch[0]).toMatchObject({
+ url: `${BROADCAST_MESSAGES_PATH}/${id}`,
+ data: JSON.stringify(defaultPayload),
+ });
+ });
+
+ it('shows an error alert if the update request fails', async () => {
+ const id = 1337;
+ createComponent({ broadcastMessage: { id } });
+ axiosMock.onPost(`${BROADCAST_MESSAGES_PATH}/${id}`).replyOnce(httpStatus.BAD_REQUEST);
+ findForm().vm.$emit('submit', { preventDefault: () => {} });
+ await waitForPromises();
+
+ expect(createAlert).toHaveBeenCalledWith(
+ expect.objectContaining({
+ message: wrapper.vm.$options.i18n.updateError,
+ }),
+ );
+ });
+ });
+});
diff --git a/spec/frontend/admin/broadcast_messages/mock_data.js b/spec/frontend/admin/broadcast_messages/mock_data.js
index 8dd98c2319d..2e20b5cf638 100644
--- a/spec/frontend/admin/broadcast_messages/mock_data.js
+++ b/spec/frontend/admin/broadcast_messages/mock_data.js
@@ -15,3 +15,11 @@ export const generateMockMessages = (n) =>
[...Array(n).keys()].map((id) => generateMockMessage(id + 1));
export const MOCK_MESSAGES = generateMockMessages(5).map((id) => generateMockMessage(id));
+
+export const MOCK_TARGET_ACCESS_LEVELS = [
+ ['Guest', 10],
+ ['Reporter', 20],
+ ['Developer', 30],
+ ['Maintainer', 40],
+ ['Owner', 50],
+];