summaryrefslogtreecommitdiff
path: root/spec/frontend/admin/broadcast_messages/components/message_form_spec.js
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/admin/broadcast_messages/components/message_form_spec.js')
-rw-r--r--spec/frontend/admin/broadcast_messages/components/message_form_spec.js201
1 files changed, 201 insertions, 0 deletions
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,
+ }),
+ );
+ });
+ });
+});