summaryrefslogtreecommitdiff
path: root/spec/frontend/packages/list/coming_soon
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/packages/list/coming_soon')
-rw-r--r--spec/frontend/packages/list/coming_soon/helpers_spec.js36
-rw-r--r--spec/frontend/packages/list/coming_soon/mock_data.js90
-rw-r--r--spec/frontend/packages/list/coming_soon/packages_coming_soon_spec.js138
3 files changed, 264 insertions, 0 deletions
diff --git a/spec/frontend/packages/list/coming_soon/helpers_spec.js b/spec/frontend/packages/list/coming_soon/helpers_spec.js
new file mode 100644
index 00000000000..4a996bfad76
--- /dev/null
+++ b/spec/frontend/packages/list/coming_soon/helpers_spec.js
@@ -0,0 +1,36 @@
+import * as comingSoon from '~/packages/list/coming_soon/helpers';
+import { fakeIssues, asGraphQLResponse, asViewModel } from './mock_data';
+
+jest.mock('~/api.js');
+
+describe('Coming Soon Helpers', () => {
+ const [noLabels, acceptingMergeRequestLabel, workflowLabel] = fakeIssues;
+
+ describe('toViewModel', () => {
+ it('formats a GraphQL response correctly', () => {
+ expect(comingSoon.toViewModel(asGraphQLResponse)).toEqual(asViewModel);
+ });
+ });
+
+ describe('findWorkflowLabel', () => {
+ it('finds a workflow label', () => {
+ expect(comingSoon.findWorkflowLabel(workflowLabel.labels)).toEqual(workflowLabel.labels[0]);
+ });
+
+ it("returns undefined when there isn't one", () => {
+ expect(comingSoon.findWorkflowLabel(noLabels.labels)).toBeUndefined();
+ });
+ });
+
+ describe('findAcceptingContributionsLabel', () => {
+ it('finds the correct label when it exists', () => {
+ expect(comingSoon.findAcceptingContributionsLabel(acceptingMergeRequestLabel.labels)).toEqual(
+ acceptingMergeRequestLabel.labels[0],
+ );
+ });
+
+ it("returns undefined when there isn't one", () => {
+ expect(comingSoon.findAcceptingContributionsLabel(noLabels.labels)).toBeUndefined();
+ });
+ });
+});
diff --git a/spec/frontend/packages/list/coming_soon/mock_data.js b/spec/frontend/packages/list/coming_soon/mock_data.js
new file mode 100644
index 00000000000..bb4568e4bd5
--- /dev/null
+++ b/spec/frontend/packages/list/coming_soon/mock_data.js
@@ -0,0 +1,90 @@
+export const fakeIssues = [
+ {
+ id: 1,
+ iid: 1,
+ title: 'issue one',
+ webUrl: 'foo',
+ },
+ {
+ id: 2,
+ iid: 2,
+ title: 'issue two',
+ labels: [{ title: 'Accepting merge requests', color: '#69d100' }],
+ milestone: {
+ title: '12.10',
+ },
+ webUrl: 'foo',
+ },
+ {
+ id: 3,
+ iid: 3,
+ title: 'issue three',
+ labels: [{ title: 'workflow::In dev', color: '#428bca' }],
+ webUrl: 'foo',
+ },
+ {
+ id: 4,
+ iid: 4,
+ title: 'issue four',
+ labels: [
+ { title: 'Accepting merge requests', color: '#69d100' },
+ { title: 'workflow::In dev', color: '#428bca' },
+ ],
+ webUrl: 'foo',
+ },
+];
+
+export const asGraphQLResponse = {
+ project: {
+ issues: {
+ nodes: fakeIssues.map(x => ({
+ ...x,
+ labels: {
+ nodes: x.labels,
+ },
+ })),
+ },
+ },
+};
+
+export const asViewModel = [
+ {
+ ...fakeIssues[0],
+ labels: [],
+ },
+ {
+ ...fakeIssues[1],
+ labels: [
+ {
+ title: 'Accepting merge requests',
+ color: '#69d100',
+ scoped: false,
+ },
+ ],
+ },
+ {
+ ...fakeIssues[2],
+ labels: [
+ {
+ title: 'workflow::In dev',
+ color: '#428bca',
+ scoped: true,
+ },
+ ],
+ },
+ {
+ ...fakeIssues[3],
+ labels: [
+ {
+ title: 'workflow::In dev',
+ color: '#428bca',
+ scoped: true,
+ },
+ {
+ title: 'Accepting merge requests',
+ color: '#69d100',
+ scoped: false,
+ },
+ ],
+ },
+];
diff --git a/spec/frontend/packages/list/coming_soon/packages_coming_soon_spec.js b/spec/frontend/packages/list/coming_soon/packages_coming_soon_spec.js
new file mode 100644
index 00000000000..c4cdadc45e6
--- /dev/null
+++ b/spec/frontend/packages/list/coming_soon/packages_coming_soon_spec.js
@@ -0,0 +1,138 @@
+import { GlEmptyState, GlSkeletonLoader, GlLabel } from '@gitlab/ui';
+import { mount, createLocalVue } from '@vue/test-utils';
+import VueApollo, { ApolloQuery } from 'vue-apollo';
+import ComingSoon from '~/packages/list/coming_soon/packages_coming_soon.vue';
+import { TrackingActions } from '~/packages/shared/constants';
+import { asViewModel } from './mock_data';
+import Tracking from '~/tracking';
+
+jest.mock('~/packages/list/coming_soon/helpers.js');
+
+const localVue = createLocalVue();
+localVue.use(VueApollo);
+
+describe('packages_coming_soon', () => {
+ let wrapper;
+
+ const findSkeletonLoader = () => wrapper.find(GlSkeletonLoader);
+ const findAllIssues = () => wrapper.findAll('[data-testid="issue-row"]');
+ const findIssuesData = () =>
+ findAllIssues().wrappers.map(x => {
+ const titleLink = x.find('[data-testid="issue-title-link"]');
+ const milestone = x.find('[data-testid="milestone"]');
+ const issueIdLink = x.find('[data-testid="issue-id-link"]');
+ const labels = x.findAll(GlLabel);
+
+ const issueId = Number(issueIdLink.text().substr(1));
+
+ return {
+ id: issueId,
+ iid: issueId,
+ title: titleLink.text(),
+ webUrl: titleLink.attributes('href'),
+ labels: labels.wrappers.map(label => ({
+ color: label.props('backgroundColor'),
+ title: label.props('title'),
+ scoped: label.props('scoped'),
+ })),
+ ...(milestone.exists() ? { milestone: { title: milestone.text() } } : {}),
+ };
+ });
+ const findIssueTitleLink = () => wrapper.find('[data-testid="issue-title-link"]');
+ const findIssueIdLink = () => wrapper.find('[data-testid="issue-id-link"]');
+ const findEmptyState = () => wrapper.find(GlEmptyState);
+
+ const mountComponent = (testParams = {}) => {
+ const $apolloData = {
+ loading: testParams.isLoading || false,
+ };
+
+ wrapper = mount(ComingSoon, {
+ localVue,
+ propsData: {
+ illustration: 'foo',
+ projectPath: 'foo',
+ suggestedContributionsPath: 'foo',
+ },
+ stubs: {
+ ApolloQuery,
+ GlLink: true,
+ },
+ mocks: {
+ $apolloData,
+ },
+ });
+
+ // Mock the GraphQL query result
+ wrapper.find(ApolloQuery).setData({
+ result: {
+ data: testParams.issues || asViewModel,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ describe('when loading', () => {
+ beforeEach(() => mountComponent({ isLoading: true }));
+
+ it('renders the skeleton loader', () => {
+ expect(findSkeletonLoader().exists()).toBe(true);
+ });
+ });
+
+ describe('when there are no issues', () => {
+ beforeEach(() => mountComponent({ issues: [] }));
+
+ it('renders the empty state', () => {
+ expect(findEmptyState().exists()).toBe(true);
+ });
+ });
+
+ describe('when there are issues', () => {
+ beforeEach(() => mountComponent());
+
+ it('renders each issue', () => {
+ expect(findIssuesData()).toEqual(asViewModel);
+ });
+ });
+
+ describe('tracking', () => {
+ const firstIssue = asViewModel[0];
+ let eventSpy;
+
+ beforeEach(() => {
+ eventSpy = jest.spyOn(Tracking, 'event');
+ mountComponent();
+ });
+
+ it('tracks when mounted', () => {
+ expect(eventSpy).toHaveBeenCalledWith(undefined, TrackingActions.COMING_SOON_REQUESTED, {});
+ });
+
+ it('tracks when an issue title link is clicked', () => {
+ eventSpy.mockClear();
+
+ findIssueTitleLink().vm.$emit('click');
+
+ expect(eventSpy).toHaveBeenCalledWith(undefined, TrackingActions.COMING_SOON_LIST, {
+ label: firstIssue.title,
+ value: firstIssue.iid,
+ });
+ });
+
+ it('tracks when an issue id link is clicked', () => {
+ eventSpy.mockClear();
+
+ findIssueIdLink().vm.$emit('click');
+
+ expect(eventSpy).toHaveBeenCalledWith(undefined, TrackingActions.COMING_SOON_LIST, {
+ label: firstIssue.title,
+ value: firstIssue.iid,
+ });
+ });
+ });
+});