diff options
Diffstat (limited to 'spec/frontend/pages')
17 files changed, 1005 insertions, 169 deletions
diff --git a/spec/frontend/pages/admin/abuse_reports/abuse_reports_spec.js b/spec/frontend/pages/admin/abuse_reports/abuse_reports_spec.js index 2c76adf761f..71c9da238b4 100644 --- a/spec/frontend/pages/admin/abuse_reports/abuse_reports_spec.js +++ b/spec/frontend/pages/admin/abuse_reports/abuse_reports_spec.js @@ -14,8 +14,6 @@ describe('Abuse Reports', () => { const findMessage = (searchText) => $messages.filter((index, element) => element.innerText.indexOf(searchText) > -1).first(); - preloadFixtures(FIXTURE); - beforeEach(() => { loadFixtures(FIXTURE); new AbuseReports(); // eslint-disable-line no-new diff --git a/spec/frontend/pages/admin/application_settings/account_and_limits_spec.js b/spec/frontend/pages/admin/application_settings/account_and_limits_spec.js index 8816609d1d2..9f326dc33c0 100644 --- a/spec/frontend/pages/admin/application_settings/account_and_limits_spec.js +++ b/spec/frontend/pages/admin/application_settings/account_and_limits_spec.js @@ -8,7 +8,6 @@ describe('AccountAndLimits', () => { const FIXTURE = 'application_settings/accounts_and_limit.html'; let $userDefaultExternal; let $userInternalRegex; - preloadFixtures(FIXTURE); beforeEach(() => { loadFixtures(FIXTURE); diff --git a/spec/frontend/pages/admin/users/new/index_spec.js b/spec/frontend/pages/admin/users/new/index_spec.js index 60482860e84..ec9fe487030 100644 --- a/spec/frontend/pages/admin/users/new/index_spec.js +++ b/spec/frontend/pages/admin/users/new/index_spec.js @@ -7,8 +7,6 @@ describe('UserInternalRegexHandler', () => { let $userEmail; let $warningMessage; - preloadFixtures(FIXTURE); - beforeEach(() => { loadFixtures(FIXTURE); // eslint-disable-next-line no-new diff --git a/spec/frontend/pages/dashboard/todos/index/todos_spec.js b/spec/frontend/pages/dashboard/todos/index/todos_spec.js index fb612f17669..de8b29d54fc 100644 --- a/spec/frontend/pages/dashboard/todos/index/todos_spec.js +++ b/spec/frontend/pages/dashboard/todos/index/todos_spec.js @@ -14,7 +14,6 @@ const TEST_COUNT_BIG = 2000; const TEST_DONE_COUNT_BIG = 7300; describe('Todos', () => { - preloadFixtures('todos/todos.html'); let todoItem; let mock; diff --git a/spec/frontend/pages/projects/forks/new/components/app_spec.js b/spec/frontend/pages/projects/forks/new/components/app_spec.js new file mode 100644 index 00000000000..e1820606704 --- /dev/null +++ b/spec/frontend/pages/projects/forks/new/components/app_spec.js @@ -0,0 +1,42 @@ +import { shallowMount } from '@vue/test-utils'; +import App from '~/pages/projects/forks/new/components/app.vue'; + +describe('App component', () => { + let wrapper; + + const DEFAULT_PROPS = { + forkIllustration: 'illustrations/project-create-new-sm.svg', + endpoint: '/some/project-full-path/-/forks/new.json', + projectFullPath: '/some/project-full-path', + projectId: '10', + projectName: 'Project Name', + projectPath: 'project-name', + projectDescription: 'some project description', + projectVisibility: 'private', + }; + + const createComponent = (props = {}) => { + wrapper = shallowMount(App, { + propsData: { + ...DEFAULT_PROPS, + ...props, + }, + }); + }; + + beforeEach(() => { + createComponent(); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + it('displays the correct svg illustration', () => { + expect(wrapper.find('img').attributes('src')).toBe('illustrations/project-create-new-sm.svg'); + }); + + it('renders ForkForm component with prop', () => { + expect(wrapper.props()).toEqual(expect.objectContaining(DEFAULT_PROPS)); + }); +}); diff --git a/spec/frontend/pages/projects/forks/new/components/fork_form_spec.js b/spec/frontend/pages/projects/forks/new/components/fork_form_spec.js new file mode 100644 index 00000000000..694a0c2b9c1 --- /dev/null +++ b/spec/frontend/pages/projects/forks/new/components/fork_form_spec.js @@ -0,0 +1,275 @@ +import { GlForm, GlFormInputGroup } from '@gitlab/ui'; +import { shallowMount } from '@vue/test-utils'; +import axios from 'axios'; +import AxiosMockAdapter from 'axios-mock-adapter'; +import createFlash from '~/flash'; +import httpStatus from '~/lib/utils/http_status'; +import * as urlUtility from '~/lib/utils/url_utility'; +import ForkForm from '~/pages/projects/forks/new/components/fork_form.vue'; + +jest.mock('~/flash'); +jest.mock('~/lib/utils/csrf', () => ({ token: 'mock-csrf-token' })); + +describe('ForkForm component', () => { + let wrapper; + let axiosMock; + + const GON_GITLAB_URL = 'https://gitlab.com'; + const GON_API_VERSION = 'v7'; + + const MOCK_NAMESPACES_RESPONSE = [ + { + name: 'one', + id: 1, + }, + { + name: 'two', + id: 2, + }, + ]; + + const DEFAULT_PROPS = { + endpoint: '/some/project-full-path/-/forks/new.json', + projectFullPath: '/some/project-full-path', + projectId: '10', + projectName: 'Project Name', + projectPath: 'project-name', + projectDescription: 'some project description', + projectVisibility: 'private', + }; + + const mockGetRequest = (data = {}, statusCode = httpStatus.OK) => { + axiosMock.onGet(DEFAULT_PROPS.endpoint).replyOnce(statusCode, data); + }; + + const createComponent = (props = {}, data = {}) => { + wrapper = shallowMount(ForkForm, { + provide: { + newGroupPath: 'some/groups/path', + visibilityHelpPath: 'some/visibility/help/path', + }, + propsData: { + ...DEFAULT_PROPS, + ...props, + }, + data() { + return { + ...data, + }; + }, + stubs: { + GlFormInputGroup, + }, + }); + }; + + beforeEach(() => { + axiosMock = new AxiosMockAdapter(axios); + window.gon = { + gitlab_url: GON_GITLAB_URL, + api_version: GON_API_VERSION, + }; + }); + + afterEach(() => { + wrapper.destroy(); + axiosMock.restore(); + }); + + const findPrivateRadio = () => wrapper.find('[data-testid="radio-private"]'); + const findInternalRadio = () => wrapper.find('[data-testid="radio-internal"]'); + const findPublicRadio = () => wrapper.find('[data-testid="radio-public"]'); + const findForkNameInput = () => wrapper.find('[data-testid="fork-name-input"]'); + const findForkUrlInput = () => wrapper.find('[data-testid="fork-url-input"]'); + const findForkSlugInput = () => wrapper.find('[data-testid="fork-slug-input"]'); + const findForkDescriptionTextarea = () => + wrapper.find('[data-testid="fork-description-textarea"]'); + const findVisibilityRadioGroup = () => + wrapper.find('[data-testid="fork-visibility-radio-group"]'); + + it('will go to projectFullPath when click cancel button', () => { + mockGetRequest(); + createComponent(); + + const { projectFullPath } = DEFAULT_PROPS; + const cancelButton = wrapper.find('[data-testid="cancel-button"]'); + + expect(cancelButton.attributes('href')).toBe(projectFullPath); + }); + + it('make POST request with project param', async () => { + jest.spyOn(axios, 'post'); + + const namespaceId = 20; + + mockGetRequest(); + createComponent( + {}, + { + selectedNamespace: { + id: namespaceId, + }, + }, + ); + + wrapper.find(GlForm).vm.$emit('submit', { preventDefault: () => {} }); + + const { + projectId, + projectDescription, + projectName, + projectPath, + projectVisibility, + } = DEFAULT_PROPS; + + const url = `/api/${GON_API_VERSION}/projects/${projectId}/fork`; + const project = { + description: projectDescription, + id: projectId, + name: projectName, + namespace_id: namespaceId, + path: projectPath, + visibility: projectVisibility, + }; + + expect(axios.post).toHaveBeenCalledWith(url, project); + }); + + it('has input with csrf token', () => { + mockGetRequest(); + createComponent(); + + expect(wrapper.find('input[name="authenticity_token"]').attributes('value')).toBe( + 'mock-csrf-token', + ); + }); + + it('pre-populate form from project props', () => { + mockGetRequest(); + createComponent(); + + expect(findForkNameInput().attributes('value')).toBe(DEFAULT_PROPS.projectName); + expect(findForkSlugInput().attributes('value')).toBe(DEFAULT_PROPS.projectPath); + expect(findForkDescriptionTextarea().attributes('value')).toBe( + DEFAULT_PROPS.projectDescription, + ); + }); + + it('sets project URL prepend text with gon.gitlab_url', () => { + mockGetRequest(); + createComponent(); + + expect(wrapper.find(GlFormInputGroup).text()).toContain(`${GON_GITLAB_URL}/`); + }); + + it('will have required attribute for required fields', () => { + mockGetRequest(); + createComponent(); + + expect(findForkNameInput().attributes('required')).not.toBeUndefined(); + expect(findForkUrlInput().attributes('required')).not.toBeUndefined(); + expect(findForkSlugInput().attributes('required')).not.toBeUndefined(); + expect(findVisibilityRadioGroup().attributes('required')).not.toBeUndefined(); + expect(findForkDescriptionTextarea().attributes('required')).toBeUndefined(); + }); + + describe('forks namespaces', () => { + beforeEach(() => { + mockGetRequest({ namespaces: MOCK_NAMESPACES_RESPONSE }); + createComponent(); + }); + + it('make GET request from endpoint', async () => { + await axios.waitForAll(); + + expect(axiosMock.history.get[0].url).toBe(DEFAULT_PROPS.endpoint); + }); + + it('generate default option', async () => { + await axios.waitForAll(); + + const optionsArray = findForkUrlInput().findAll('option'); + + expect(optionsArray.at(0).text()).toBe('Select a namespace'); + }); + + it('populate project url namespace options', async () => { + await axios.waitForAll(); + + const optionsArray = findForkUrlInput().findAll('option'); + + expect(optionsArray).toHaveLength(MOCK_NAMESPACES_RESPONSE.length + 1); + expect(optionsArray.at(1).text()).toBe(MOCK_NAMESPACES_RESPONSE[0].name); + expect(optionsArray.at(2).text()).toBe(MOCK_NAMESPACES_RESPONSE[1].name); + }); + }); + + describe('visibility level', () => { + it.each` + project | namespace | privateIsDisabled | internalIsDisabled | publicIsDisabled + ${'private'} | ${'private'} | ${undefined} | ${'true'} | ${'true'} + ${'private'} | ${'internal'} | ${undefined} | ${'true'} | ${'true'} + ${'private'} | ${'public'} | ${undefined} | ${'true'} | ${'true'} + ${'internal'} | ${'private'} | ${undefined} | ${'true'} | ${'true'} + ${'internal'} | ${'internal'} | ${undefined} | ${undefined} | ${'true'} + ${'internal'} | ${'public'} | ${undefined} | ${undefined} | ${'true'} + ${'public'} | ${'private'} | ${undefined} | ${'true'} | ${'true'} + ${'public'} | ${'internal'} | ${undefined} | ${undefined} | ${'true'} + ${'public'} | ${'public'} | ${undefined} | ${undefined} | ${undefined} + `( + 'sets appropriate radio button disabled state', + async ({ project, namespace, privateIsDisabled, internalIsDisabled, publicIsDisabled }) => { + mockGetRequest(); + createComponent( + { + projectVisibility: project, + }, + { + selectedNamespace: { + visibility: namespace, + }, + }, + ); + + expect(findPrivateRadio().attributes('disabled')).toBe(privateIsDisabled); + expect(findInternalRadio().attributes('disabled')).toBe(internalIsDisabled); + expect(findPublicRadio().attributes('disabled')).toBe(publicIsDisabled); + }, + ); + }); + + describe('onSubmit', () => { + beforeEach(() => { + jest.spyOn(urlUtility, 'redirectTo').mockImplementation(); + }); + + it('redirect to POST web_url response', async () => { + const webUrl = `new/fork-project`; + + jest.spyOn(axios, 'post').mockResolvedValue({ data: { web_url: webUrl } }); + + mockGetRequest(); + createComponent(); + + await wrapper.vm.onSubmit(); + + expect(urlUtility.redirectTo).toHaveBeenCalledWith(webUrl); + }); + + it('display flash when POST is unsuccessful', async () => { + const dummyError = 'Fork project failed'; + + jest.spyOn(axios, 'post').mockRejectedValue(dummyError); + + mockGetRequest(); + createComponent(); + + await wrapper.vm.onSubmit(); + + expect(urlUtility.redirectTo).not.toHaveBeenCalled(); + expect(createFlash).toHaveBeenCalledWith({ + message: dummyError, + }); + }); + }); +}); diff --git a/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_a_spec.js.snap b/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_a_spec.js.snap index c9141d13a46..1c1327e7a4e 100644 --- a/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_a_spec.js.snap +++ b/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_a_spec.js.snap @@ -4,7 +4,7 @@ exports[`Learn GitLab Design A should render the loading state 1`] = ` <ul> <li> <span> - Create a repository + Create or import a repository </span> </li> <li> @@ -14,7 +14,11 @@ exports[`Learn GitLab Design A should render the loading state 1`] = ` </li> <li> <span> - Set-up CI/CD + <gl-link-stub + href="http://example.com/" + > + Set up CI/CD + </gl-link-stub> </span> </li> <li> @@ -22,7 +26,7 @@ exports[`Learn GitLab Design A should render the loading state 1`] = ` <gl-link-stub href="http://example.com/" > - Start a free trial of GitLab Gold + Start a free Ultimate trial </gl-link-stub> </span> </li> @@ -40,7 +44,7 @@ exports[`Learn GitLab Design A should render the loading state 1`] = ` <gl-link-stub href="http://example.com/" > - Enable require merge approvals + Add merge request approval </gl-link-stub> </span> </li> @@ -49,7 +53,7 @@ exports[`Learn GitLab Design A should render the loading state 1`] = ` <gl-link-stub href="http://example.com/" > - Submit a merge request (MR) + Submit a merge request </gl-link-stub> </span> </li> @@ -58,7 +62,7 @@ exports[`Learn GitLab Design A should render the loading state 1`] = ` <gl-link-stub href="http://example.com/" > - Run a Security scan using CI/CD + Run a security scan </gl-link-stub> </span> </li> diff --git a/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_b_spec.js.snap b/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_b_spec.js.snap index 85e3b675e5b..dd899b93302 100644 --- a/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_b_spec.js.snap +++ b/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_b_spec.js.snap @@ -1,66 +1,519 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Learn GitLab Design B should render the loading state 1`] = ` -<ul> - <li> - <span> - Create a repository - </span> - </li> - <li> - <span> - Invite your colleagues - </span> - </li> - <li> - <span> - Set-up CI/CD - </span> - </li> - <li> - <span> - <gl-link-stub - href="http://example.com/" +exports[`Learn GitLab Design B renders correctly 1`] = ` +<div> + <div + class="row" + > + <div + class="gl-mb-7 col-md-8 col-lg-7" + > + <h1 + class="gl-font-size-h1" > - Start a free trial of GitLab Gold - </gl-link-stub> - </span> - </li> - <li> - <span> - <gl-link-stub - href="http://example.com/" + Learn GitLab + </h1> + + <p + class="gl-text-gray-700 gl-mb-0" > - Add code owners - </gl-link-stub> - </span> - </li> - <li> - <span> - <gl-link-stub - href="http://example.com/" + Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project. + </p> + </div> + </div> + + <div + class="gl-mb-3" + > + <p + class="gl-text-gray-500 gl-mb-2" + data-testid="completion-percentage" + > + 25% completed + </p> + + <div + class="progress" + max="8" + value="2" + > + <div + aria-valuemax="8" + aria-valuemin="0" + aria-valuenow="2" + class="progress-bar" + role="progressbar" + style="width: 25%;" > - Enable require merge approvals - </gl-link-stub> - </span> - </li> - <li> - <span> - <gl-link-stub - href="http://example.com/" + <!----> + </div> + </div> + </div> + + <h2 + class="gl-font-lg gl-mb-3" + > + Set up your workspace + </h2> + + <p + class="gl-text-gray-700 gl-mb-6" + > + Complete these tasks first so you can enjoy GitLab's features to their fullest: + </p> + + <div + class="row row-cols-2 row-cols-md-3 row-cols-lg-4" + > + <div + class="col gl-mb-6" + > + <div + class="gl-card gl-pt-0" > - Submit a merge request (MR) - </gl-link-stub> - </span> - </li> - <li> - <span> - <gl-link-stub - href="http://example.com/" + <!----> + + <div + class="gl-card-body" + > + <div + class="gl-text-right gl-h-5" + > + <svg + aria-hidden="true" + class="gl-text-green-500 gl-icon s16" + data-testid="completed-icon" + > + <use + href="#check-circle-filled" + /> + </svg> + </div> + + <div + class="gl-text-center gl-display-flex gl-justify-content-center gl-align-items-center gl-flex-direction-column learn-gitlab-info-card-content" + > + <img + src="http://example.com/images/illustration.svg" + /> + + <h6> + Invite your colleagues + </h6> + + <p + class="gl-font-sm gl-text-gray-700" + > + GitLab works best as a team. Invite your colleague to enjoy all features. + </p> + + <a + class="gl-link" + href="http://example.com/" + rel="noopener noreferrer" + target="_blank" + > + Invite your colleagues + </a> + </div> + </div> + + <!----> + </div> + </div> + + <div + class="col gl-mb-6" + > + <div + class="gl-card gl-pt-0" > - Run a Security scan using CI/CD - </gl-link-stub> - </span> - </li> -</ul> + <!----> + + <div + class="gl-card-body" + > + <div + class="gl-text-right gl-h-5" + > + <svg + aria-hidden="true" + class="gl-text-green-500 gl-icon s16" + data-testid="completed-icon" + > + <use + href="#check-circle-filled" + /> + </svg> + </div> + + <div + class="gl-text-center gl-display-flex gl-justify-content-center gl-align-items-center gl-flex-direction-column learn-gitlab-info-card-content" + > + <img + src="http://example.com/images/illustration.svg" + /> + + <h6> + Create or import a repository + </h6> + + <p + class="gl-font-sm gl-text-gray-700" + > + Create or import your first repository into your new project. + </p> + + <a + class="gl-link" + href="http://example.com/" + rel="noopener noreferrer" + target="_blank" + > + Create or import a repository + </a> + </div> + </div> + + <!----> + </div> + </div> + + <div + class="col gl-mb-6" + > + <div + class="gl-card gl-pt-0" + > + <!----> + + <div + class="gl-card-body" + > + <div + class="gl-text-right gl-h-5" + > + <!----> + </div> + + <div + class="gl-text-center gl-display-flex gl-justify-content-center gl-align-items-center gl-flex-direction-column learn-gitlab-info-card-content" + > + <img + src="http://example.com/images/illustration.svg" + /> + + <h6> + Set up CI/CD + </h6> + + <p + class="gl-font-sm gl-text-gray-700" + > + Save time by automating your integration and deployment tasks. + </p> + + <a + class="gl-link" + href="http://example.com/" + rel="noopener noreferrer" + target="_blank" + > + Set-up CI/CD + </a> + </div> + </div> + + <!----> + </div> + </div> + + <div + class="col gl-mb-6" + > + <div + class="gl-card gl-pt-0" + > + <!----> + + <div + class="gl-card-body" + > + <div + class="gl-text-right gl-h-5" + > + <!----> + </div> + + <div + class="gl-text-center gl-display-flex gl-justify-content-center gl-align-items-center gl-flex-direction-column learn-gitlab-info-card-content" + > + <img + src="http://example.com/images/illustration.svg" + /> + + <h6> + Start a free Ultimate trial + </h6> + + <p + class="gl-font-sm gl-text-gray-700" + > + Try all GitLab features for 30 days, no credit card required. + </p> + + <a + class="gl-link" + href="http://example.com/" + rel="noopener noreferrer" + target="_blank" + > + Try GitLab Ultimate for free + </a> + </div> + </div> + + <!----> + </div> + </div> + + <div + class="col gl-mb-6" + > + <div + class="gl-card gl-pt-0" + > + <!----> + + <div + class="gl-card-body" + > + <div + class="gl-text-right gl-h-5" + > + <span + class="gl-text-gray-500 gl-font-sm gl-font-style-italic" + data-testid="trial-only" + > + Trial only + </span> + </div> + + <div + class="gl-text-center gl-display-flex gl-justify-content-center gl-align-items-center gl-flex-direction-column learn-gitlab-info-card-content" + > + <img + src="http://example.com/images/illustration.svg" + /> + + <h6> + Add code owners + </h6> + + <p + class="gl-font-sm gl-text-gray-700" + > + Prevent unexpected changes to important assets by assigning ownership of files and paths. + </p> + + <a + class="gl-link" + href="http://example.com/" + rel="noopener noreferrer" + target="_blank" + > + Add code owners + </a> + </div> + </div> + + <!----> + </div> + </div> + + <div + class="col gl-mb-6" + > + <div + class="gl-card gl-pt-0" + > + <!----> + + <div + class="gl-card-body" + > + <div + class="gl-text-right gl-h-5" + > + <span + class="gl-text-gray-500 gl-font-sm gl-font-style-italic" + data-testid="trial-only" + > + Trial only + </span> + </div> + + <div + class="gl-text-center gl-display-flex gl-justify-content-center gl-align-items-center gl-flex-direction-column learn-gitlab-info-card-content" + > + <img + src="http://example.com/images/illustration.svg" + /> + + <h6> + Add merge request approval + </h6> + + <p + class="gl-font-sm gl-text-gray-700" + > + Route code reviews to the right reviewers, every time. + </p> + + <a + class="gl-link" + href="http://example.com/" + rel="noopener noreferrer" + target="_blank" + > + Enable require merge approvals + </a> + </div> + </div> + + <!----> + </div> + </div> + </div> + + <h2 + class="gl-font-lg gl-mb-3" + > + Plan and execute + </h2> + + <p + class="gl-text-gray-700 gl-mb-6" + > + Create a workflow for your new workspace, and learn how GitLab features work together: + </p> + + <div + class="row row-cols-2 row-cols-md-3 row-cols-lg-4" + > + <div + class="col gl-mb-6" + > + <div + class="gl-card gl-pt-0" + > + <!----> + + <div + class="gl-card-body" + > + <div + class="gl-text-right gl-h-5" + > + <!----> + </div> + + <div + class="gl-text-center gl-display-flex gl-justify-content-center gl-align-items-center gl-flex-direction-column learn-gitlab-info-card-content" + > + <img + src="http://example.com/images/illustration.svg" + /> + + <h6> + Submit a merge request + </h6> + + <p + class="gl-font-sm gl-text-gray-700" + > + Review and edit proposed changes to source code. + </p> + + <a + class="gl-link" + href="http://example.com/" + rel="noopener noreferrer" + target="_blank" + > + Submit a merge request (MR) + </a> + </div> + </div> + + <!----> + </div> + </div> + </div> + + <h2 + class="gl-font-lg gl-mb-3" + > + Deploy + </h2> + + <p + class="gl-text-gray-700 gl-mb-6" + > + Use your new GitLab workflow to deploy your application, monitor its health, and keep it secure: + </p> + + <div + class="row row-cols-2 row-cols-lg-4 g-2 g-lg-3" + > + <div + class="col gl-mb-6" + > + <div + class="gl-card gl-pt-0" + > + <!----> + + <div + class="gl-card-body" + > + <div + class="gl-text-right gl-h-5" + > + <!----> + </div> + + <div + class="gl-text-center gl-display-flex gl-justify-content-center gl-align-items-center gl-flex-direction-column learn-gitlab-info-card-content" + > + <img + src="http://example.com/images/illustration.svg" + /> + + <h6> + Run a security scan + </h6> + + <p + class="gl-font-sm gl-text-gray-700" + > + Scan your code to uncover vulnerabilities before deploying. + </p> + + <a + class="gl-link" + href="http://example.com/" + rel="noopener noreferrer" + target="_blank" + > + Run a Security scan + </a> + </div> + </div> + + <!----> + </div> + </div> + </div> +</div> `; diff --git a/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_a_spec.js b/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_a_spec.js index ddc5339e7e0..2154358de51 100644 --- a/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_a_spec.js +++ b/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_a_spec.js @@ -1,41 +1,6 @@ import { shallowMount } from '@vue/test-utils'; -import { extendedWrapper } from 'helpers/vue_test_utils_helper'; import LearnGitlabA from '~/pages/projects/learn_gitlab/components/learn_gitlab_a.vue'; - -const TEST_ACTIONS = { - gitWrite: { - url: 'http://example.com/', - completed: true, - }, - userAdded: { - url: 'http://example.com/', - completed: true, - }, - pipelineCreated: { - url: 'http://example.com/', - completed: true, - }, - trialStarted: { - url: 'http://example.com/', - completed: false, - }, - codeOwnersEnabled: { - url: 'http://example.com/', - completed: false, - }, - requiredMrApprovalsEnabled: { - url: 'http://example.com/', - completed: false, - }, - mergeRequestCreated: { - url: 'http://example.com/', - completed: false, - }, - securityScanEnabled: { - url: 'http://example.com/', - completed: false, - }, -}; +import { testActions } from './mock_data'; describe('Learn GitLab Design A', () => { let wrapper; @@ -46,13 +11,7 @@ describe('Learn GitLab Design A', () => { }); const createWrapper = () => { - wrapper = extendedWrapper( - shallowMount(LearnGitlabA, { - propsData: { - actions: TEST_ACTIONS, - }, - }), - ); + wrapper = shallowMount(LearnGitlabA, { propsData: { actions: testActions } }); }; it('should render the loading state', () => { diff --git a/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_b_spec.js b/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_b_spec.js index be4f5768402..fbb989fae32 100644 --- a/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_b_spec.js +++ b/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_b_spec.js @@ -1,63 +1,38 @@ -import { shallowMount } from '@vue/test-utils'; -import { extendedWrapper } from 'helpers/vue_test_utils_helper'; -import LearnGitlabA from '~/pages/projects/learn_gitlab/components/learn_gitlab_a.vue'; - -const TEST_ACTIONS = { - gitWrite: { - url: 'http://example.com/', - completed: true, - }, - userAdded: { - url: 'http://example.com/', - completed: true, - }, - pipelineCreated: { - url: 'http://example.com/', - completed: true, - }, - trialStarted: { - url: 'http://example.com/', - completed: false, - }, - codeOwnersEnabled: { - url: 'http://example.com/', - completed: false, - }, - requiredMrApprovalsEnabled: { - url: 'http://example.com/', - completed: false, - }, - mergeRequestCreated: { - url: 'http://example.com/', - completed: false, - }, - securityScanEnabled: { - url: 'http://example.com/', - completed: false, - }, -}; +import { GlProgressBar } from '@gitlab/ui'; +import { mount } from '@vue/test-utils'; +import LearnGitlabB from '~/pages/projects/learn_gitlab/components/learn_gitlab_b.vue'; +import { testActions } from './mock_data'; describe('Learn GitLab Design B', () => { let wrapper; + const createWrapper = () => { + wrapper = mount(LearnGitlabB, { propsData: { actions: testActions } }); + }; + + beforeEach(() => { + createWrapper(); + }); + afterEach(() => { wrapper.destroy(); wrapper = null; }); - const createWrapper = () => { - wrapper = extendedWrapper( - shallowMount(LearnGitlabA, { - propsData: { - actions: TEST_ACTIONS, - }, - }), - ); - }; + it('renders correctly', () => { + expect(wrapper.element).toMatchSnapshot(); + }); - it('should render the loading state', () => { - createWrapper(); + it('renders the progress percentage', () => { + const text = wrapper.find('[data-testid="completion-percentage"]').text(); - expect(wrapper.element).toMatchSnapshot(); + expect(text).toEqual('25% completed'); + }); + + it('renders the progress bar with correct values', () => { + const progressBar = wrapper.find(GlProgressBar); + + expect(progressBar.attributes('value')).toBe('2'); + expect(progressBar.attributes('max')).toBe('8'); }); }); diff --git a/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_info_card_spec.js b/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_info_card_spec.js new file mode 100644 index 00000000000..ad4bc826a9d --- /dev/null +++ b/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_info_card_spec.js @@ -0,0 +1,57 @@ +import { shallowMount } from '@vue/test-utils'; +import LearnGitlabInfoCard from '~/pages/projects/learn_gitlab/components/learn_gitlab_info_card.vue'; + +const defaultProps = { + title: 'Create Repository', + description: 'Some description', + actionLabel: 'Create Repository now', + url: 'https://example.com', + completed: false, + svg: 'https://example.com/illustration.svg', +}; + +describe('Learn GitLab Info Card', () => { + let wrapper; + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + }); + + const createWrapper = (props = {}) => { + wrapper = shallowMount(LearnGitlabInfoCard, { + propsData: { ...defaultProps, ...props }, + }); + }; + + it('renders no icon when not completed', () => { + createWrapper({ completed: false }); + + expect(wrapper.find('[data-testid="completed-icon"]').exists()).toBe(false); + }); + + it('renders the completion icon when completed', () => { + createWrapper({ completed: true }); + + expect(wrapper.find('[data-testid="completed-icon"]').exists()).toBe(true); + }); + + it('renders no trial only when it is not required', () => { + createWrapper(); + + expect(wrapper.find('[data-testid="trial-only"]').exists()).toBe(false); + }); + + it('renders trial only when trial is required', () => { + createWrapper({ trialRequired: true }); + + expect(wrapper.find('[data-testid="trial-only"]').exists()).toBe(true); + }); + + it('renders completion icon when completed a trial-only feature', () => { + createWrapper({ trialRequired: true, completed: true }); + + expect(wrapper.find('[data-testid="trial-only"]').exists()).toBe(false); + expect(wrapper.find('[data-testid="completed-icon"]').exists()).toBe(true); + }); +}); diff --git a/spec/frontend/pages/projects/learn_gitlab/components/mock_data.js b/spec/frontend/pages/projects/learn_gitlab/components/mock_data.js new file mode 100644 index 00000000000..caac667e2b1 --- /dev/null +++ b/spec/frontend/pages/projects/learn_gitlab/components/mock_data.js @@ -0,0 +1,42 @@ +export const testActions = { + gitWrite: { + url: 'http://example.com/', + completed: true, + svg: 'http://example.com/images/illustration.svg', + }, + userAdded: { + url: 'http://example.com/', + completed: true, + svg: 'http://example.com/images/illustration.svg', + }, + pipelineCreated: { + url: 'http://example.com/', + completed: false, + svg: 'http://example.com/images/illustration.svg', + }, + trialStarted: { + url: 'http://example.com/', + completed: false, + svg: 'http://example.com/images/illustration.svg', + }, + codeOwnersEnabled: { + url: 'http://example.com/', + completed: false, + svg: 'http://example.com/images/illustration.svg', + }, + requiredMrApprovalsEnabled: { + url: 'http://example.com/', + completed: false, + svg: 'http://example.com/images/illustration.svg', + }, + mergeRequestCreated: { + url: 'http://example.com/', + completed: false, + svg: 'http://example.com/images/illustration.svg', + }, + securityScanEnabled: { + url: 'http://example.com/', + completed: false, + svg: 'http://example.com/images/illustration.svg', + }, +}; diff --git a/spec/frontend/pages/projects/pipeline_schedules/shared/components/timezone_dropdown_spec.js b/spec/frontend/pages/projects/pipeline_schedules/shared/components/timezone_dropdown_spec.js index de63409b181..2a3b07f95f2 100644 --- a/spec/frontend/pages/projects/pipeline_schedules/shared/components/timezone_dropdown_spec.js +++ b/spec/frontend/pages/projects/pipeline_schedules/shared/components/timezone_dropdown_spec.js @@ -6,8 +6,6 @@ import TimezoneDropdown, { } from '~/pages/projects/pipeline_schedules/shared/components/timezone_dropdown'; describe('Timezone Dropdown', () => { - preloadFixtures('pipeline_schedules/edit.html'); - let $inputEl = null; let $dropdownEl = null; let $wrapper = null; diff --git a/spec/frontend/pages/projects/shared/permissions/components/settings_panel_spec.js b/spec/frontend/pages/projects/shared/permissions/components/settings_panel_spec.js index d7c754fd3cc..bee628c3a56 100644 --- a/spec/frontend/pages/projects/shared/permissions/components/settings_panel_spec.js +++ b/spec/frontend/pages/projects/shared/permissions/components/settings_panel_spec.js @@ -29,6 +29,7 @@ const defaultProps = { showDefaultAwardEmojis: true, allowEditingCommitMessages: false, }, + isGitlabCom: true, canDisableEmails: true, canChangeVisibilityLevel: true, allowedVisibilityOptions: [0, 10, 20], diff --git a/spec/frontend/pages/sessions/new/preserve_url_fragment_spec.js b/spec/frontend/pages/sessions/new/preserve_url_fragment_spec.js index 8632c852720..e39a3904613 100644 --- a/spec/frontend/pages/sessions/new/preserve_url_fragment_spec.js +++ b/spec/frontend/pages/sessions/new/preserve_url_fragment_spec.js @@ -6,8 +6,6 @@ describe('preserve_url_fragment', () => { return $(`.omniauth-container ${selector}`).parent('form').attr('action'); }; - preloadFixtures('sessions/new.html'); - beforeEach(() => { loadFixtures('sessions/new.html'); }); diff --git a/spec/frontend/pages/sessions/new/signin_tabs_memoizer_spec.js b/spec/frontend/pages/sessions/new/signin_tabs_memoizer_spec.js index f04c16d2ddb..6aa725fbd7d 100644 --- a/spec/frontend/pages/sessions/new/signin_tabs_memoizer_spec.js +++ b/spec/frontend/pages/sessions/new/signin_tabs_memoizer_spec.js @@ -18,8 +18,6 @@ describe('SigninTabsMemoizer', () => { return memo; } - preloadFixtures(fixtureTemplate); - beforeEach(() => { loadFixtures(fixtureTemplate); diff --git a/spec/frontend/pages/shared/wikis/wiki_alert_spec.js b/spec/frontend/pages/shared/wikis/wiki_alert_spec.js new file mode 100644 index 00000000000..6a18473b1a7 --- /dev/null +++ b/spec/frontend/pages/shared/wikis/wiki_alert_spec.js @@ -0,0 +1,40 @@ +import { GlAlert, GlLink, GlSprintf } from '@gitlab/ui'; +import { shallowMount } from '@vue/test-utils'; +import WikiAlert from '~/pages/shared/wikis/components/wiki_alert.vue'; + +describe('WikiAlert', () => { + let wrapper; + const ERROR = 'There is already a page with the same title in that path.'; + const ERROR_WITH_LINK = 'Before text %{wikiLinkStart}the page%{wikiLinkEnd} after text.'; + const PATH = '/test'; + + function createWrapper(propsData = {}, stubs = {}) { + wrapper = shallowMount(WikiAlert, { + propsData: { wikiPagePath: PATH, ...propsData }, + stubs, + }); + } + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + }); + + const findGlAlert = () => wrapper.findComponent(GlAlert); + const findGlLink = () => wrapper.findComponent(GlLink); + const findGlSprintf = () => wrapper.findComponent(GlSprintf); + + describe('Wiki Alert', () => { + it('shows an alert when there is an error', () => { + createWrapper({ error: ERROR }); + expect(findGlAlert().exists()).toBe(true); + expect(findGlSprintf().exists()).toBe(true); + expect(findGlSprintf().attributes('message')).toBe(ERROR); + }); + + it('shows a the link to the help path', () => { + createWrapper({ error: ERROR_WITH_LINK }, { GlAlert, GlSprintf }); + expect(findGlLink().attributes('href')).toBe(PATH); + }); + }); +}); |