summaryrefslogtreecommitdiff
path: root/spec/javascripts/vue_shared/components
diff options
context:
space:
mode:
Diffstat (limited to 'spec/javascripts/vue_shared/components')
-rw-r--r--spec/javascripts/vue_shared/components/commit_spec.js130
-rw-r--r--spec/javascripts/vue_shared/components/pipelines_table_row_spec.js87
-rw-r--r--spec/javascripts/vue_shared/components/pipelines_table_spec.js67
-rw-r--r--spec/javascripts/vue_shared/components/table_pagination_spec.js150
4 files changed, 434 insertions, 0 deletions
diff --git a/spec/javascripts/vue_shared/components/commit_spec.js b/spec/javascripts/vue_shared/components/commit_spec.js
new file mode 100644
index 00000000000..df547299d75
--- /dev/null
+++ b/spec/javascripts/vue_shared/components/commit_spec.js
@@ -0,0 +1,130 @@
+import Vue from 'vue';
+import commitComp from '~/vue_shared/components/commit';
+
+describe('Commit component', () => {
+ let props;
+ let component;
+ let CommitComponent;
+
+ beforeEach(() => {
+ CommitComponent = Vue.extend(commitComp);
+ });
+
+ it('should render a code-fork icon if it does not represent a tag', () => {
+ component = new CommitComponent({
+ propsData: {
+ tag: false,
+ commitRef: {
+ name: 'master',
+ ref_url: 'http://localhost/namespace2/gitlabhq/tree/master',
+ },
+ commitUrl: 'https://gitlab.com/gitlab-org/gitlab-ce/commit/b7836eddf62d663c665769e1b0960197fd215067',
+ shortSha: 'b7836edd',
+ title: 'Commit message',
+ author: {
+ avatar_url: 'https://gitlab.com/uploads/user/avatar/300478/avatar.png',
+ web_url: 'https://gitlab.com/jschatz1',
+ username: 'jschatz1',
+ },
+ },
+ }).$mount();
+
+ expect(component.$el.querySelector('.icon-container i').classList).toContain('fa-code-fork');
+ });
+
+ describe('Given all the props', () => {
+ beforeEach(() => {
+ props = {
+ tag: true,
+ commitRef: {
+ name: 'master',
+ ref_url: 'http://localhost/namespace2/gitlabhq/tree/master',
+ },
+ commitUrl: 'https://gitlab.com/gitlab-org/gitlab-ce/commit/b7836eddf62d663c665769e1b0960197fd215067',
+ shortSha: 'b7836edd',
+ title: 'Commit message',
+ author: {
+ avatar_url: 'https://gitlab.com/uploads/user/avatar/300478/avatar.png',
+ web_url: 'https://gitlab.com/jschatz1',
+ username: 'jschatz1',
+ },
+ commitIconSvg: '<svg></svg>',
+ };
+
+ component = new CommitComponent({
+ propsData: props,
+ }).$mount();
+ });
+
+ it('should render a tag icon if it represents a tag', () => {
+ expect(component.$el.querySelector('.icon-container i').classList).toContain('fa-tag');
+ });
+
+ it('should render a link to the ref url', () => {
+ expect(component.$el.querySelector('.branch-name').getAttribute('href')).toEqual(props.commitRef.ref_url);
+ });
+
+ it('should render the ref name', () => {
+ expect(component.$el.querySelector('.branch-name').textContent).toContain(props.commitRef.name);
+ });
+
+ it('should render the commit short sha with a link to the commit url', () => {
+ expect(component.$el.querySelector('.commit-id').getAttribute('href')).toEqual(props.commitUrl);
+ expect(component.$el.querySelector('.commit-id').textContent).toContain(props.shortSha);
+ });
+
+ it('should render the given commitIconSvg', () => {
+ expect(component.$el.querySelector('.js-commit-icon').children).toContain('svg');
+ });
+
+ describe('Given commit title and author props', () => {
+ it('should render a link to the author profile', () => {
+ expect(
+ component.$el.querySelector('.commit-title .avatar-image-container').getAttribute('href'),
+ ).toEqual(props.author.web_url);
+ });
+
+ it('Should render the author avatar with title and alt attributes', () => {
+ expect(
+ component.$el.querySelector('.commit-title .avatar-image-container img').getAttribute('title'),
+ ).toContain(props.author.username);
+ expect(
+ component.$el.querySelector('.commit-title .avatar-image-container img').getAttribute('alt'),
+ ).toContain(`${props.author.username}'s avatar`);
+ });
+ });
+
+ it('should render the commit title', () => {
+ expect(
+ component.$el.querySelector('a.commit-row-message').getAttribute('href'),
+ ).toEqual(props.commitUrl);
+ expect(
+ component.$el.querySelector('a.commit-row-message').textContent,
+ ).toContain(props.title);
+ });
+ });
+
+ describe('When commit title is not provided', () => {
+ it('should render default message', () => {
+ props = {
+ tag: false,
+ commitRef: {
+ name: 'master',
+ ref_url: 'http://localhost/namespace2/gitlabhq/tree/master',
+ },
+ commitUrl: 'https://gitlab.com/gitlab-org/gitlab-ce/commit/b7836eddf62d663c665769e1b0960197fd215067',
+ shortSha: 'b7836edd',
+ title: null,
+ author: {},
+ };
+
+ component = new CommitComponent({
+ propsData: props,
+ }).$mount();
+
+ expect(
+ component.$el.querySelector('.commit-title span').textContent,
+ ).toContain('Cant find HEAD commit for this branch');
+ });
+ });
+});
diff --git a/spec/javascripts/vue_shared/components/pipelines_table_row_spec.js b/spec/javascripts/vue_shared/components/pipelines_table_row_spec.js
new file mode 100644
index 00000000000..699625cdbb7
--- /dev/null
+++ b/spec/javascripts/vue_shared/components/pipelines_table_row_spec.js
@@ -0,0 +1,87 @@
+import Vue from 'vue';
+import tableRowComp from '~/vue_shared/components/pipelines_table_row';
+import pipeline from '../../commit/pipelines/mock_data';
+
+describe('Pipelines Table Row', () => {
+ let component;
+
+ beforeEach(() => {
+ const PipelinesTableRowComponent = Vue.extend(tableRowComp);
+
+ component = new PipelinesTableRowComponent({
+ el: document.querySelector('.test-dom-element'),
+ propsData: {
+ pipeline,
+ service: {},
+ },
+ }).$mount();
+ });
+
+ it('should render a table row', () => {
+ expect(component.$el).toEqual('TR');
+ });
+
+ describe('status column', () => {
+ it('should render a pipeline link', () => {
+ expect(
+ component.$el.querySelector('td.commit-link a').getAttribute('href'),
+ ).toEqual(pipeline.path);
+ });
+
+ it('should render status text', () => {
+ expect(
+ component.$el.querySelector('td.commit-link a').textContent,
+ ).toContain(pipeline.details.status.text);
+ });
+ });
+
+ describe('information column', () => {
+ it('should render a pipeline link', () => {
+ expect(
+ component.$el.querySelector('td:nth-child(2) a').getAttribute('href'),
+ ).toEqual(pipeline.path);
+ });
+
+ it('should render pipeline ID', () => {
+ expect(
+ component.$el.querySelector('td:nth-child(2) a > span').textContent,
+ ).toEqual(`#${pipeline.id}`);
+ });
+
+ describe('when a user is provided', () => {
+ it('should render user information', () => {
+ expect(
+ component.$el.querySelector('td:nth-child(2) a:nth-child(3)').getAttribute('href'),
+ ).toEqual(pipeline.user.web_url);
+
+ expect(
+ component.$el.querySelector('td:nth-child(2) img').getAttribute('title'),
+ ).toEqual(pipeline.user.name);
+ });
+ });
+ });
+
+ describe('commit column', () => {
+ it('should render link to commit', () => {
+ expect(
+ component.$el.querySelector('td:nth-child(3) .commit-id').getAttribute('href'),
+ ).toEqual(pipeline.commit.commit_path);
+ });
+ });
+
+ describe('stages column', () => {
+ it('should render an icon for each stage', () => {
+ expect(
+ component.$el.querySelectorAll('td:nth-child(4) .js-builds-dropdown-button').length,
+ ).toEqual(pipeline.details.stages.length);
+ });
+ });
+
+ describe('actions column', () => {
+ it('should render the provided actions', () => {
+ expect(
+ component.$el.querySelectorAll('td:nth-child(6) ul li').length,
+ ).toEqual(pipeline.details.manual_actions.length);
+ });
+ });
+});
diff --git a/spec/javascripts/vue_shared/components/pipelines_table_spec.js b/spec/javascripts/vue_shared/components/pipelines_table_spec.js
new file mode 100644
index 00000000000..4d3ced944d7
--- /dev/null
+++ b/spec/javascripts/vue_shared/components/pipelines_table_spec.js
@@ -0,0 +1,67 @@
+import Vue from 'vue';
+import pipelinesTableComp from '~/vue_shared/components/pipelines_table';
+import '~/lib/utils/datetime_utility';
+import pipeline from '../../commit/pipelines/mock_data';
+
+describe('Pipelines Table', () => {
+ let PipelinesTableComponent;
+
+ beforeEach(() => {
+ PipelinesTableComponent = Vue.extend(pipelinesTableComp);
+ });
+
+ describe('table', () => {
+ let component;
+ beforeEach(() => {
+ component = new PipelinesTableComponent({
+ propsData: {
+ pipelines: [],
+ service: {},
+ },
+ }).$mount();
+ });
+
+ afterEach(() => {
+ component.$destroy();
+ });
+
+ it('should render a table', () => {
+ expect(component.$el).toEqual('TABLE');
+ });
+
+ it('should render table head with correct columns', () => {
+ expect(component.$el.querySelector('th.js-pipeline-status').textContent).toEqual('Status');
+ expect(component.$el.querySelector('th.js-pipeline-info').textContent).toEqual('Pipeline');
+ expect(component.$el.querySelector('th.js-pipeline-commit').textContent).toEqual('Commit');
+ expect(component.$el.querySelector('th.js-pipeline-stages').textContent).toEqual('Stages');
+ expect(component.$el.querySelector('th.js-pipeline-date').textContent).toEqual('');
+ expect(component.$el.querySelector('th.js-pipeline-actions').textContent).toEqual('');
+ });
+ });
+
+ describe('without data', () => {
+ it('should render an empty table', () => {
+ const component = new PipelinesTableComponent({
+ propsData: {
+ pipelines: [],
+ service: {},
+ },
+ }).$mount();
+ expect(component.$el.querySelectorAll('tbody tr').length).toEqual(0);
+ });
+ });
+
+ describe('with data', () => {
+ it('should render rows', () => {
+ const component = new PipelinesTableComponent({
+ el: document.querySelector('.test-dom-element'),
+ propsData: {
+ pipelines: [pipeline],
+ service: {},
+ },
+ }).$mount();
+
+ expect(component.$el.querySelectorAll('tbody tr').length).toEqual(1);
+ });
+ });
+});
diff --git a/spec/javascripts/vue_shared/components/table_pagination_spec.js b/spec/javascripts/vue_shared/components/table_pagination_spec.js
new file mode 100644
index 00000000000..96038718191
--- /dev/null
+++ b/spec/javascripts/vue_shared/components/table_pagination_spec.js
@@ -0,0 +1,150 @@
+import Vue from 'vue';
+import paginationComp from '~/vue_shared/components/table_pagination';
+import '~/lib/utils/common_utils';
+
+describe('Pagination component', () => {
+ let component;
+ let PaginationComponent;
+
+ const changeChanges = {
+ one: '',
+ };
+
+ const change = (one) => {
+ changeChanges.one = one;
+ };
+
+ beforeEach(() => {
+ PaginationComponent = Vue.extend(paginationComp);
+ });
+
+ it('should render and start at page 1', () => {
+ component = new PaginationComponent({
+ propsData: {
+ pageInfo: {
+ totalPages: 10,
+ nextPage: 2,
+ previousPage: '',
+ },
+ change,
+ },
+ }).$mount();
+
+ expect(component.$el.classList).toContain('gl-pagination');
+
+ component.changePage({ target: { innerText: '1' } });
+
+ expect(changeChanges.one).toEqual(1);
+ });
+
+ it('should go to the previous page', () => {
+ component = new PaginationComponent({
+ propsData: {
+ pageInfo: {
+ totalPages: 10,
+ nextPage: 3,
+ previousPage: 1,
+ },
+ change,
+ },
+ }).$mount();
+
+ component.changePage({ target: { innerText: 'Prev' } });
+
+ expect(changeChanges.one).toEqual(1);
+ });
+
+ it('should go to the next page', () => {
+ component = new PaginationComponent({
+ propsData: {
+ pageInfo: {
+ totalPages: 10,
+ nextPage: 5,
+ previousPage: 3,
+ },
+ change,
+ },
+ }).$mount();
+
+ component.changePage({ target: { innerText: 'Next' } });
+
+ expect(changeChanges.one).toEqual(5);
+ });
+
+ it('should go to the last page', () => {
+ component = new PaginationComponent({
+ propsData: {
+ pageInfo: {
+ totalPages: 10,
+ nextPage: 5,
+ previousPage: 3,
+ },
+ change,
+ },
+ }).$mount();
+
+ component.changePage({ target: { innerText: 'Last »' } });
+
+ expect(changeChanges.one).toEqual(10);
+ });
+
+ it('should go to the first page', () => {
+ component = new PaginationComponent({
+ propsData: {
+ pageInfo: {
+ totalPages: 10,
+ nextPage: 5,
+ previousPage: 3,
+ },
+ change,
+ },
+ }).$mount();
+
+ component.changePage({ target: { innerText: '« First' } });
+
+ expect(changeChanges.one).toEqual(1);
+ });
+
+ it('should do nothing', () => {
+ component = new PaginationComponent({
+ propsData: {
+ pageInfo: {
+ totalPages: 10,
+ nextPage: 2,
+ previousPage: '',
+ },
+ change,
+ },
+ }).$mount();
+
+ component.changePage({ target: { innerText: '...' } });
+
+ expect(changeChanges.one).toEqual(1);
+ });
+});
+
+describe('paramHelper', () => {
+ afterEach(() => {
+ window.history.pushState({}, null, '');
+ });
+
+ it('can parse url parameters correctly', () => {
+ window.history.pushState({}, null, '?scope=all&p=2');
+
+ const scope = gl.utils.getParameterByName('scope');
+ const p = gl.utils.getParameterByName('p');
+
+ expect(scope).toEqual('all');
+ expect(p).toEqual('2');
+ });
+
+ it('returns null if param not in url', () => {
+ window.history.pushState({}, null, '?p=2');
+
+ const scope = gl.utils.getParameterByName('scope');
+ const p = gl.utils.getParameterByName('p');
+
+ expect(scope).toEqual(null);
+ expect(p).toEqual('2');
+ });
+});