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-03-10 21:09:14 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-03-10 21:09:14 +0300
commitd18b7dc5eea84db5008986c6879a24ad7f6462a6 (patch)
tree98d6e8635ac32f210f15fcfb3dc583a6295e0b9a /spec/frontend
parent6ebe886c82111e1ab9e71d4c02a888d2312898bc (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend')
-rw-r--r--spec/frontend/packages_and_registries/settings/project/settings/components/__snapshots__/settings_form_spec.js.snap2
-rw-r--r--spec/frontend/packages_and_registries/settings/project/settings/components/settings_form_spec.js26
-rw-r--r--spec/frontend/packages_and_registries/settings/project/settings/graphql/cache_updated_spec.js25
-rw-r--r--spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_spec.js12
-rw-r--r--spec/frontend/search/topbar/components/app_spec.js33
-rw-r--r--spec/frontend/security_configuration/components/training_provider_list_spec.js7
-rw-r--r--spec/frontend/security_configuration/mock_data.js12
-rw-r--r--spec/frontend/vue_shared/components/user_avatar/user_avatar_image_spec.js172
8 files changed, 180 insertions, 109 deletions
diff --git a/spec/frontend/packages_and_registries/settings/project/settings/components/__snapshots__/settings_form_spec.js.snap b/spec/frontend/packages_and_registries/settings/project/settings/components/__snapshots__/settings_form_spec.js.snap
index 9938357ed24..841a9bf8290 100644
--- a/spec/frontend/packages_and_registries/settings/project/settings/components/__snapshots__/settings_form_spec.js.snap
+++ b/spec/frontend/packages_and_registries/settings/project/settings/components/__snapshots__/settings_form_spec.js.snap
@@ -58,7 +58,7 @@ exports[`Settings Form Remove regex matches snapshot 1`] = `
error=""
label="Remove tags matching:"
name="remove-regex"
- placeholder=".*"
+ placeholder=""
value="asdasdssssdfdf"
/>
`;
diff --git a/spec/frontend/packages_and_registries/settings/project/settings/components/settings_form_spec.js b/spec/frontend/packages_and_registries/settings/project/settings/components/settings_form_spec.js
index 625aa37fc0f..266f953c3e0 100644
--- a/spec/frontend/packages_and_registries/settings/project/settings/components/settings_form_spec.js
+++ b/spec/frontend/packages_and_registries/settings/project/settings/components/settings_form_spec.js
@@ -49,6 +49,11 @@ describe('Settings Form', () => {
const findOlderThanDropdown = () => wrapper.find('[data-testid="older-than-dropdown"]');
const findRemoveRegexInput = () => wrapper.find('[data-testid="remove-regex-input"]');
+ const submitForm = async () => {
+ findForm().trigger('submit');
+ return waitForPromises();
+ };
+
const mountComponent = ({
props = defaultProps,
data,
@@ -318,27 +323,24 @@ describe('Settings Form', () => {
mutationResolver: jest.fn().mockResolvedValue(expirationPolicyMutationPayload()),
});
- findForm().trigger('submit');
- await waitForPromises();
- await nextTick();
+ await submitForm();
expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(UPDATE_SETTINGS_SUCCESS_MESSAGE);
});
describe('when submit fails', () => {
describe('user recoverable errors', () => {
- it('when there is an error is shown in a toast', async () => {
+ it('when there is an error is shown in the nameRegex field t', async () => {
mountComponentWithApollo({
mutationResolver: jest
.fn()
.mockResolvedValue(expirationPolicyMutationPayload({ errors: ['foo'] })),
});
- findForm().trigger('submit');
- await waitForPromises();
- await nextTick();
+ await submitForm();
- expect(wrapper.vm.$toast.show).toHaveBeenCalledWith('foo');
+ expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(UPDATE_SETTINGS_ERROR_MESSAGE);
+ expect(findRemoveRegexInput().props('error')).toBe('foo');
});
});
@@ -348,9 +350,7 @@ describe('Settings Form', () => {
mutationResolver: jest.fn().mockRejectedValue(expirationPolicyMutationPayload()),
});
- findForm().trigger('submit');
- await waitForPromises();
- await nextTick();
+ await submitForm();
expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(UPDATE_SETTINGS_ERROR_MESSAGE);
});
@@ -367,9 +367,7 @@ describe('Settings Form', () => {
});
mountComponent({ mocks: { $apollo: { mutate } } });
- findForm().trigger('submit');
- await waitForPromises();
- await nextTick();
+ await submitForm();
expect(findKeepRegexInput().props('error')).toEqual('baz');
});
diff --git a/spec/frontend/packages_and_registries/settings/project/settings/graphql/cache_updated_spec.js b/spec/frontend/packages_and_registries/settings/project/settings/graphql/cache_updated_spec.js
index 4d6bd65bd93..76d5f8a6659 100644
--- a/spec/frontend/packages_and_registries/settings/project/settings/graphql/cache_updated_spec.js
+++ b/spec/frontend/packages_and_registries/settings/project/settings/graphql/cache_updated_spec.js
@@ -4,15 +4,15 @@ import { updateContainerExpirationPolicy } from '~/packages_and_registries/setti
describe('Registry settings cache update', () => {
let client;
- const payload = {
+ const payload = (value) => ({
data: {
updateContainerExpirationPolicy: {
containerExpirationPolicy: {
- enabled: true,
+ ...value,
},
},
},
- };
+ });
const cacheMock = {
project: {
@@ -35,12 +35,12 @@ describe('Registry settings cache update', () => {
});
describe('Registry settings cache update', () => {
it('calls readQuery', () => {
- updateContainerExpirationPolicy('foo')(client, payload);
+ updateContainerExpirationPolicy('foo')(client, payload({ enabled: true }));
expect(client.readQuery).toHaveBeenCalledWith(queryAndVariables);
});
it('writes the correct result in the cache', () => {
- updateContainerExpirationPolicy('foo')(client, payload);
+ updateContainerExpirationPolicy('foo')(client, payload({ enabled: true }));
expect(client.writeQuery).toHaveBeenCalledWith({
...queryAndVariables,
data: {
@@ -52,5 +52,20 @@ describe('Registry settings cache update', () => {
},
});
});
+
+ it('with an empty update preserves the state', () => {
+ updateContainerExpirationPolicy('foo')(client, payload());
+
+ expect(client.writeQuery).toHaveBeenCalledWith({
+ ...queryAndVariables,
+ data: {
+ project: {
+ containerExpirationPolicy: {
+ enabled: false,
+ },
+ },
+ },
+ });
+ });
});
});
diff --git a/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_spec.js b/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_spec.js
index ee682b18af3..5f1aff99578 100644
--- a/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_spec.js
+++ b/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_spec.js
@@ -9,7 +9,6 @@ import { testActions, testSections, testProject } from './mock_data';
describe('Learn GitLab', () => {
let wrapper;
let sidebar;
- let inviteMembers = false;
const createWrapper = () => {
wrapper = mount(LearnGitlab, {
@@ -17,7 +16,6 @@ describe('Learn GitLab', () => {
actions: testActions,
sections: testSections,
project: testProject,
- inviteMembers,
},
});
};
@@ -38,7 +36,6 @@ describe('Learn GitLab', () => {
afterEach(() => {
wrapper.destroy();
wrapper = null;
- inviteMembers = false;
sidebar.remove();
});
@@ -73,7 +70,6 @@ describe('Learn GitLab', () => {
});
it('emits openModal', () => {
- inviteMembers = true;
Cookies.set(INVITE_MODAL_OPEN_COOKIE, true);
createWrapper();
@@ -86,19 +82,11 @@ describe('Learn GitLab', () => {
});
it('does not emit openModal when cookie is not set', () => {
- inviteMembers = true;
-
createWrapper();
expect(spy).not.toHaveBeenCalled();
expect(cookieSpy).toHaveBeenCalledWith(INVITE_MODAL_OPEN_COOKIE);
});
-
- it('does not emit openModal when inviteMembers is false', () => {
- createWrapper();
-
- expect(spy).not.toHaveBeenCalled();
- });
});
describe('when the showSuccessfulInvitationsAlert event is fired', () => {
diff --git a/spec/frontend/search/topbar/components/app_spec.js b/spec/frontend/search/topbar/components/app_spec.js
index 7ce5efb3c52..0a44688bfe0 100644
--- a/spec/frontend/search/topbar/components/app_spec.js
+++ b/spec/frontend/search/topbar/components/app_spec.js
@@ -1,4 +1,4 @@
-import { GlForm, GlSearchBoxByType, GlButton } from '@gitlab/ui';
+import { GlSearchBoxByClick } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vuex from 'vuex';
@@ -36,40 +36,19 @@ describe('GlobalSearchTopbar', () => {
wrapper.destroy();
});
- const findTopbarForm = () => wrapper.find(GlForm);
- const findGlSearchBox = () => wrapper.find(GlSearchBoxByType);
+ const findGlSearchBox = () => wrapper.find(GlSearchBoxByClick);
const findGroupFilter = () => wrapper.find(GroupFilter);
const findProjectFilter = () => wrapper.find(ProjectFilter);
- const findSearchButton = () => wrapper.find(GlButton);
describe('template', () => {
beforeEach(() => {
createComponent();
});
- it('renders Topbar Form always', () => {
- expect(findTopbarForm().exists()).toBe(true);
- });
-
describe('Search box', () => {
it('renders always', () => {
expect(findGlSearchBox().exists()).toBe(true);
});
-
- describe('onSearch', () => {
- const testSearch = 'test search';
-
- beforeEach(() => {
- findGlSearchBox().vm.$emit('input', testSearch);
- });
-
- it('calls setQuery when input event is fired from GlSearchBoxByType', () => {
- expect(actionSpies.setQuery).toHaveBeenCalledWith(expect.any(Object), {
- key: 'search',
- value: testSearch,
- });
- });
- });
});
describe.each`
@@ -92,10 +71,6 @@ describe('GlobalSearchTopbar', () => {
expect(findProjectFilter().exists()).toBe(showFilters);
});
});
-
- it('renders SearchButton always', () => {
- expect(findSearchButton().exists()).toBe(true);
- });
});
describe('actions', () => {
@@ -103,8 +78,8 @@ describe('GlobalSearchTopbar', () => {
createComponent();
});
- it('clicking SearchButton calls applyQuery', () => {
- findTopbarForm().vm.$emit('submit', { preventDefault: () => {} });
+ it('clicking search button inside search box calls applyQuery', () => {
+ findGlSearchBox().vm.$emit('submit', { preventDefault: () => {} });
expect(actionSpies.applyQuery).toHaveBeenCalled();
});
diff --git a/spec/frontend/security_configuration/components/training_provider_list_spec.js b/spec/frontend/security_configuration/components/training_provider_list_spec.js
index 08ba4bcbf69..5e2efa2425c 100644
--- a/spec/frontend/security_configuration/components/training_provider_list_spec.js
+++ b/spec/frontend/security_configuration/components/training_provider_list_spec.js
@@ -26,6 +26,7 @@ import {
updateSecurityTrainingProvidersErrorResponse,
testProjectPath,
testProviderIds,
+ testProviderName,
tempProviderLogos,
} from '../mock_data';
@@ -207,9 +208,13 @@ describe('TrainingProviderList component', () => {
expect(findLogos().at(provider).attributes('width')).toBe('18');
});
+ it.each(providerIndexArray)('has a11y decorative attribute for provider %s', (provider) => {
+ expect(findLogos().at(provider).attributes('role')).toBe('presentation');
+ });
+
it.each(providerIndexArray)('displays the correct svg path for provider %s', (provider) => {
expect(findLogos().at(provider).attributes('src')).toBe(
- tempProviderLogos[testProviderIds[provider]].svg,
+ tempProviderLogos[testProviderName[provider]].svg,
);
});
});
diff --git a/spec/frontend/security_configuration/mock_data.js b/spec/frontend/security_configuration/mock_data.js
index 588fac11987..3bad687740c 100644
--- a/spec/frontend/security_configuration/mock_data.js
+++ b/spec/frontend/security_configuration/mock_data.js
@@ -1,11 +1,11 @@
export const testProjectPath = 'foo/bar';
-
export const testProviderIds = [101, 102, 103];
+export const testProviderName = ['Vendor Name 1', 'Vendor Name 2', 'Vendor Name 3'];
const createSecurityTrainingProviders = ({ providerOverrides = {} }) => [
{
id: testProviderIds[0],
- name: 'Vendor Name 1',
+ name: testProviderName[0],
description: 'Interactive developer security education',
url: 'https://www.example.org/security/training',
isEnabled: false,
@@ -14,7 +14,7 @@ const createSecurityTrainingProviders = ({ providerOverrides = {} }) => [
},
{
id: testProviderIds[1],
- name: 'Vendor Name 2',
+ name: testProviderName[1],
description: 'Security training with guide and learning pathways.',
url: 'https://www.vendornametwo.com/',
isEnabled: false,
@@ -23,7 +23,7 @@ const createSecurityTrainingProviders = ({ providerOverrides = {} }) => [
},
{
id: testProviderIds[2],
- name: 'Vendor Name 3',
+ name: testProviderName[2],
description: 'Security training for the everyday developer.',
url: 'https://www.vendornamethree.com/',
isEnabled: false,
@@ -99,10 +99,10 @@ export const updateSecurityTrainingProvidersErrorResponse = {
// Will remove once this issue is resolved where the svg path will be available in the GraphQL query
// https://gitlab.com/gitlab-org/gitlab/-/issues/346899
export const tempProviderLogos = {
- [testProviderIds[0]]: {
+ [testProviderName[0]]: {
svg: '/assets/illustrations/vulnerability/vendor-1.svg',
},
- [testProviderIds[1]]: {
+ [testProviderName[1]]: {
svg: '/assets/illustrations/vulnerability/vendor-2.svg',
},
};
diff --git a/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_spec.js b/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_spec.js
index 2c3fc70e116..64ce210b6c8 100644
--- a/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_spec.js
+++ b/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_spec.js
@@ -1,12 +1,13 @@
import { shallowMount } from '@vue/test-utils';
+import { GlAvatar, GlTooltip } from '@gitlab/ui';
import defaultAvatarUrl from 'images/no_avatar.png';
import { placeholderImage } from '~/lazy_loader';
import UserAvatarImage from '~/vue_shared/components/user_avatar/user_avatar_image.vue';
jest.mock('images/no_avatar.png', () => 'default-avatar-url');
-const DEFAULT_PROPS = {
- size: 99,
+const PROVIDED_PROPS = {
+ size: 32,
imgSrc: 'myavatarurl.com',
imgAlt: 'mydisplayname',
cssClasses: 'myextraavatarclass',
@@ -14,6 +15,10 @@ const DEFAULT_PROPS = {
tooltipPlacement: 'bottom',
};
+const DEFAULT_PROPS = {
+ size: 20,
+};
+
describe('User Avatar Image Component', () => {
let wrapper;
@@ -21,64 +26,149 @@ describe('User Avatar Image Component', () => {
wrapper.destroy();
});
- describe('Initialization', () => {
- beforeEach(() => {
- wrapper = shallowMount(UserAvatarImage, {
- propsData: {
- ...DEFAULT_PROPS,
- },
+ describe('`glAvatarForAllUserAvatars` feature flag enabled', () => {
+ describe('Initialization', () => {
+ beforeEach(() => {
+ wrapper = shallowMount(UserAvatarImage, {
+ propsData: {
+ ...PROVIDED_PROPS,
+ },
+ provide: {
+ glFeatures: {
+ glAvatarForAllUserAvatars: true,
+ },
+ },
+ });
+ });
+
+ it('should render `GlAvatar` and provide correct properties to it', () => {
+ const avatar = wrapper.findComponent(GlAvatar);
+
+ expect(avatar.attributes('data-src')).toBe(
+ `${PROVIDED_PROPS.imgSrc}?width=${PROVIDED_PROPS.size}`,
+ );
+ expect(avatar.props()).toMatchObject({
+ src: `${PROVIDED_PROPS.imgSrc}?width=${PROVIDED_PROPS.size}`,
+ alt: PROVIDED_PROPS.imgAlt,
+ });
+ });
+
+ it('should add correct CSS classes', () => {
+ const classes = wrapper.findComponent(GlAvatar).classes();
+ expect(classes).toContain(PROVIDED_PROPS.cssClasses);
+ expect(classes).not.toContain('lazy');
});
});
- it('should have <img> as a child element', () => {
- const imageElement = wrapper.find('img');
+ describe('Initialization when lazy', () => {
+ beforeEach(() => {
+ wrapper = shallowMount(UserAvatarImage, {
+ propsData: {
+ ...PROVIDED_PROPS,
+ lazy: true,
+ },
+ provide: {
+ glFeatures: {
+ glAvatarForAllUserAvatars: true,
+ },
+ },
+ });
+ });
+
+ it('should add lazy attributes', () => {
+ const avatar = wrapper.findComponent(GlAvatar);
- expect(imageElement.exists()).toBe(true);
- expect(imageElement.attributes('src')).toBe(`${DEFAULT_PROPS.imgSrc}?width=99`);
- expect(imageElement.attributes('data-src')).toBe(`${DEFAULT_PROPS.imgSrc}?width=99`);
- expect(imageElement.attributes('alt')).toBe(DEFAULT_PROPS.imgAlt);
+ expect(avatar.classes()).toContain('lazy');
+ expect(avatar.attributes()).toMatchObject({
+ src: placeholderImage,
+ 'data-src': `${PROVIDED_PROPS.imgSrc}?width=${PROVIDED_PROPS.size}`,
+ });
+ });
});
- it('should properly render img css', () => {
- const classes = wrapper.find('img').classes();
- expect(classes).toEqual(expect.arrayContaining(['avatar', 's99', DEFAULT_PROPS.cssClasses]));
- expect(classes).not.toContain('lazy');
+ describe('Initialization without src', () => {
+ beforeEach(() => {
+ wrapper = shallowMount(UserAvatarImage);
+ });
+
+ it('should have default avatar image', () => {
+ const imageElement = wrapper.find('img');
+
+ expect(imageElement.attributes('src')).toBe(
+ `${defaultAvatarUrl}?width=${DEFAULT_PROPS.size}`,
+ );
+ });
});
});
- describe('Initialization when lazy', () => {
- beforeEach(() => {
- wrapper = shallowMount(UserAvatarImage, {
- propsData: {
- ...DEFAULT_PROPS,
- lazy: true,
- },
+ describe('`glAvatarForAllUserAvatars` feature flag disabled', () => {
+ describe('Initialization', () => {
+ beforeEach(() => {
+ wrapper = shallowMount(UserAvatarImage, {
+ propsData: {
+ ...PROVIDED_PROPS,
+ },
+ });
});
- });
- it('should add lazy attributes', () => {
- const imageElement = wrapper.find('img');
+ it('should have <img> as a child element', () => {
+ const imageElement = wrapper.find('img');
+
+ expect(imageElement.exists()).toBe(true);
+ expect(imageElement.attributes('src')).toBe(
+ `${PROVIDED_PROPS.imgSrc}?width=${PROVIDED_PROPS.size}`,
+ );
+ expect(imageElement.attributes('data-src')).toBe(
+ `${PROVIDED_PROPS.imgSrc}?width=${PROVIDED_PROPS.size}`,
+ );
+ expect(imageElement.attributes('alt')).toBe(PROVIDED_PROPS.imgAlt);
+ });
- expect(imageElement.classes()).toContain('lazy');
- expect(imageElement.attributes('src')).toBe(placeholderImage);
- expect(imageElement.attributes('data-src')).toBe(`${DEFAULT_PROPS.imgSrc}?width=99`);
+ it('should properly render img css', () => {
+ const classes = wrapper.find('img').classes();
+ expect(classes).toEqual(['avatar', 's32', PROVIDED_PROPS.cssClasses]);
+ expect(classes).not.toContain('lazy');
+ });
});
- });
- describe('Initialization without src', () => {
- beforeEach(() => {
- wrapper = shallowMount(UserAvatarImage);
+ describe('Initialization when lazy', () => {
+ beforeEach(() => {
+ wrapper = shallowMount(UserAvatarImage, {
+ propsData: {
+ ...PROVIDED_PROPS,
+ lazy: true,
+ },
+ });
+ });
+
+ it('should add lazy attributes', () => {
+ const imageElement = wrapper.find('img');
+
+ expect(imageElement.classes()).toContain('lazy');
+ expect(imageElement.attributes('src')).toBe(placeholderImage);
+ expect(imageElement.attributes('data-src')).toBe(
+ `${PROVIDED_PROPS.imgSrc}?width=${PROVIDED_PROPS.size}`,
+ );
+ });
});
- it('should have default avatar image', () => {
- const imageElement = wrapper.find('img');
+ describe('Initialization without src', () => {
+ beforeEach(() => {
+ wrapper = shallowMount(UserAvatarImage);
+ });
+
+ it('should have default avatar image', () => {
+ const imageElement = wrapper.find('img');
- expect(imageElement.attributes('src')).toBe(`${defaultAvatarUrl}?width=20`);
+ expect(imageElement.attributes('src')).toBe(
+ `${defaultAvatarUrl}?width=${DEFAULT_PROPS.size}`,
+ );
+ });
});
});
describe('dynamic tooltip content', () => {
- const props = DEFAULT_PROPS;
+ const props = PROVIDED_PROPS;
const slots = {
default: ['Action!'],
};
@@ -91,11 +181,11 @@ describe('User Avatar Image Component', () => {
});
it('renders the tooltip slot', () => {
- expect(wrapper.find('.js-user-avatar-image-tooltip').exists()).toBe(true);
+ expect(wrapper.findComponent(GlTooltip).exists()).toBe(true);
});
it('renders the tooltip content', () => {
- expect(wrapper.find('.js-user-avatar-image-tooltip').text()).toContain(slots.default[0]);
+ expect(wrapper.findComponent(GlTooltip).text()).toContain(slots.default[0]);
});
it('does not render tooltip data attributes for on avatar image', () => {