Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2019-11-26 15:06:50 +00:00
parent 6a4ffad420
commit 68d3f33d51
24 changed files with 758 additions and 721 deletions

2
.gitignore vendored
View file

@ -66,7 +66,7 @@ eslint-report.html
/vendor/gitaly-ruby /vendor/gitaly-ruby
/builds* /builds*
/.gitlab_workhorse_secret /.gitlab_workhorse_secret
/.gitlab_pages_shared_secret /.gitlab_pages_secret
/webpack-report/ /webpack-report/
/knapsack/ /knapsack/
/rspec_flaky/ /rspec_flaky/

View file

@ -148,26 +148,6 @@ module Issuable
strip_attributes :title strip_attributes :title
# The state_machine gem will reset the value of state_id unless it
# is a raw attribute passed in here:
# https://gitlab.com/gitlab-org/gitlab/issues/35746#note_241148787
#
# This assumes another initialize isn't defined. Otherwise this
# method may need to be prepended.
def initialize(attributes = nil)
if attributes.is_a?(Hash)
attr = attributes.symbolize_keys
if attr.key?(:state) && !attr.key?(:state_id)
value = attr.delete(:state)
state_id = self.class.available_states[value]
attributes[:state_id] = state_id if state_id
end
end
super(attributes)
end
# We want to use optimistic lock for cases when only title or description are involved # We want to use optimistic lock for cases when only title or description are involved
# http://api.rubyonrails.org/classes/ActiveRecord/Locking/Optimistic.html # http://api.rubyonrails.org/classes/ActiveRecord/Locking/Optimistic.html
def locking_enabled? def locking_enabled?

View file

@ -77,7 +77,7 @@ class Issue < ApplicationRecord
attr_spammable :title, spam_title: true attr_spammable :title, spam_title: true
attr_spammable :description, spam_description: true attr_spammable :description, spam_description: true
state_machine :state_id, initial: :opened do state_machine :state_id, initial: :opened, initialize: false do
event :close do event :close do
transition [:opened] => :closed transition [:opened] => :closed
end end

View file

@ -103,7 +103,7 @@ class MergeRequest < ApplicationRecord
super + [:merged, :locked] super + [:merged, :locked]
end end
state_machine :state_id, initial: :opened do state_machine :state_id, initial: :opened, initialize: false do
event :close do event :close do
transition [:opened] => :closed transition [:opened] => :closed
end end

View file

@ -0,0 +1,5 @@
---
title: Add template repository usage to the usage ping
merge_request: 20126
author: minghuan lei
type: changed

View file

@ -321,8 +321,8 @@ production: &base
# external_https: ["1.1.1.1:443", "[2001::1]:443"] # If defined, enables custom domain and certificate support in GitLab Pages # external_https: ["1.1.1.1:443", "[2001::1]:443"] # If defined, enables custom domain and certificate support in GitLab Pages
# File that contains the shared secret key for verifying access for gitlab-pages. # File that contains the shared secret key for verifying access for gitlab-pages.
# Default is '.gitlab_pages_shared_secret' relative to Rails.root (i.e. root of the GitLab app). # Default is '.gitlab_pages_secret' relative to Rails.root (i.e. root of the GitLab app).
# secret_file: /home/git/gitlab/.gitlab_pages_shared_secret # secret_file: /home/git/gitlab/.gitlab_pages_secret
## Mattermost ## Mattermost
## For enabling Add to Mattermost button ## For enabling Add to Mattermost button

View file

@ -291,7 +291,7 @@ Settings.pages['url'] ||= Settings.__send__(:build_pages_url)
Settings.pages['external_http'] ||= false unless Settings.pages['external_http'].present? Settings.pages['external_http'] ||= false unless Settings.pages['external_http'].present?
Settings.pages['external_https'] ||= false unless Settings.pages['external_https'].present? Settings.pages['external_https'] ||= false unless Settings.pages['external_https'].present?
Settings.pages['artifacts_server'] ||= Settings.pages['enabled'] if Settings.pages['artifacts_server'].nil? Settings.pages['artifacts_server'] ||= Settings.pages['enabled'] if Settings.pages['artifacts_server'].nil?
Settings.pages['secret_file'] ||= Rails.root.join('.gitlab_pages_shared_secret') Settings.pages['secret_file'] ||= Rails.root.join('.gitlab_pages_secret')
# #
# Geo # Geo

View file

@ -336,6 +336,49 @@ Generated docker images should have the program at their `Entrypoint` to create
portable commands. That way, anyone can run the image, and without parameters portable commands. That way, anyone can run the image, and without parameters
it will display its help message (if `cli` has been used). it will display its help message (if `cli` has been used).
## Distributing Go binaries
With the exception of [GitLab Runner](https://gitlab.com/gitlab-org/gitlab-runner),
which publishes its own binaries, our Go binaries are created by projects
managed by the [Distribution group](https://about.gitlab.com/handbook/product/categories/#distribution-group).
The [Omnibus GitLab](https://gitlab.com/gitlab-org/omnibus-gitlab) project creates a
single, monolithic operating system package containing all the binaries, while
the [Cloud-Native GitLab (CNG)](https://gitlab.com/gitlab-org/build/CNG) project
publishes a set of Docker images and Helm charts to glue them together.
Both approaches use the same version of Go for all projects, so it's important
to ensure all our Go-using projects have at least one Go version in common in
their test matrices. You can check the version of Go currently being used by
[Omnibus](https://gitlab.com/gitlab-org/gitlab-omnibus-builder/blob/master/docker/Dockerfile_debian_10#L59),
and the version being used for [CNG](https://gitlab.com/gitlab-org/build/cng/blob/master/ci_files/variables.yml#L12).
### Updating Go version
We should always use a [supported version](https://golang.org/doc/devel/release.html#policy)
of Go, i.e., one of the three most recent minor releases, and should always use
the most recent patch-level for that version, as it may contain security fixes.
Changing the version affects every project being compiled, so it's important to
ensure that all projects have been updated to test against the new Go version
before changing the package builders to use it. Despite [Go's compatibility promise](https://golang.org/doc/go1compat),
changes between minor versions can expose bugs or cause problems in our projects.
Once you've picked a new Go version to use, the steps to update Omnibus and CNG
are:
- [Create a merge request in the CNG project](https://gitlab.com/gitlab-org/build/CNG/edit/master/ci_files/variables.yml?branch_name=update-go-version),
updating the `GO_VERSION` in `ci_files/variables.yml`.
- Create a merge request in the [`gitlab-omnibus-builder` project](https://gitlab.com/gitlab-org/gitlab-omnibus-builder),
updating every file in the `docker/` directory so the `GO_VERSION` is set
appropriately. [Here's an example](https://gitlab.com/gitlab-org/gitlab-omnibus-builder/merge_requests/125/diffs).
- Tag a new release of `gitlab-omnibus-builder` containing the change.
- [Create a merge request in the `gitlab-omnibus` project](https://gitlab.com/gitlab-org/omnibus-gitlab/edit/master/.gitlab-ci.yml?branch_name=update-gitlab-omnibus-builder-version),
updating the `BUILDER_IMAGE_REVISION` to match the newly-created tag.
To reduce unnecessary differences between two distribution methods, Omnibus and
CNG **should always use the same Go version**.
--- ---
[Return to Development documentation](../README.md). [Return to Development documentation](../README.md).

View file

@ -121,7 +121,7 @@ module Banzai
def autolink_filter(text) def autolink_filter(text)
Gitlab::StringRegexMarker.new(CGI.unescapeHTML(text), text.html_safe).mark(LINK_PATTERN) do |link, left:, right:| Gitlab::StringRegexMarker.new(CGI.unescapeHTML(text), text.html_safe).mark(LINK_PATTERN) do |link, left:, right:|
autolink_match(link) autolink_match(link).html_safe
end end
end end

View file

@ -77,7 +77,7 @@ module Banzai
def spaced_link_filter(text) def spaced_link_filter(text)
Gitlab::StringRegexMarker.new(CGI.unescapeHTML(text), text.html_safe).mark(LINK_OR_IMAGE_PATTERN) do |link, left:, right:| Gitlab::StringRegexMarker.new(CGI.unescapeHTML(text), text.html_safe).mark(LINK_OR_IMAGE_PATTERN) do |link, left:, right:|
spaced_link_match(link) spaced_link_match(link).html_safe
end end
end end

View file

@ -62,7 +62,7 @@ module Gitlab
end end
def link_tag(name, url) def link_tag(name, url)
%{<a href="#{ERB::Util.html_escape_once(url)}" rel="nofollow noreferrer noopener" target="_blank">#{ERB::Util.html_escape_once(name)}</a>} %{<a href="#{ERB::Util.html_escape_once(url)}" rel="nofollow noreferrer noopener" target="_blank">#{ERB::Util.html_escape_once(name)}</a>}.html_safe
end end
# Links package names based on regex. # Links package names based on regex.

View file

@ -9,7 +9,7 @@ module Gitlab
def mark(line_inline_diffs, mode: nil) def mark(line_inline_diffs, mode: nil)
super(line_inline_diffs) do |text, left:, right:| super(line_inline_diffs) do |text, left:, right:|
%{<span class="#{html_class_names(left, right, mode)}">#{text}</span>} %{<span class="#{html_class_names(left, right, mode)}">#{text}</span>}.html_safe
end end
end end

View file

@ -373,6 +373,14 @@ FactoryBot.define do
end end
end end
trait :license_management do
options do
{
artifacts: { reports: { license_management: 'gl-license-management-report.json' } }
}
end
end
trait :non_playable do trait :non_playable do
status { 'created' } status { 'created' }
self.when { 'manual' } self.when { 'manual' }

View file

@ -1,10 +1,13 @@
import Vue from 'vue'; import { trimText } from 'helpers/text_helper';
import { mount } from '@vue/test-utils';
import JobItem from '~/pipelines/components/graph/job_item.vue'; import JobItem from '~/pipelines/components/graph/job_item.vue';
import mountComponent from 'spec/helpers/vue_mount_component_helper';
describe('pipeline graph job item', () => { describe('pipeline graph job item', () => {
const JobComponent = Vue.extend(JobItem); let wrapper;
let component;
const createWrapper = propsData => {
wrapper = mount(JobItem, { sync: false, attachToDocument: true, propsData });
};
const delayedJobFixture = getJSONFixture('jobs/delayed.json'); const delayedJobFixture = getJSONFixture('jobs/delayed.json');
const mockJob = { const mockJob = {
@ -28,27 +31,25 @@ describe('pipeline graph job item', () => {
}; };
afterEach(() => { afterEach(() => {
component.$destroy(); wrapper.destroy();
}); });
describe('name with link', () => { describe('name with link', () => {
it('should render the job name and status with a link', done => { it('should render the job name and status with a link', done => {
component = mountComponent(JobComponent, { job: mockJob }); createWrapper({ job: mockJob });
Vue.nextTick(() => { wrapper.vm.$nextTick(() => {
const link = component.$el.querySelector('a'); const link = wrapper.find('a');
expect(link.getAttribute('href')).toEqual(mockJob.status.details_path); expect(link.attributes('href')).toBe(mockJob.status.details_path);
expect(link.getAttribute('data-original-title')).toEqual( expect(link.attributes('data-original-title')).toEqual(
`${mockJob.name} - ${mockJob.status.label}`, `${mockJob.name} - ${mockJob.status.label}`,
); );
expect(component.$el.querySelector('.js-status-icon-success')).toBeDefined(); expect(wrapper.find('.js-status-icon-success')).toBeDefined();
expect(component.$el.querySelector('.ci-status-text').textContent.trim()).toEqual( expect(trimText(wrapper.find('.ci-status-text').text())).toBe(mockJob.name);
mockJob.name,
);
done(); done();
}); });
@ -57,7 +58,7 @@ describe('pipeline graph job item', () => {
describe('name without link', () => { describe('name without link', () => {
it('it should render status and name', () => { it('it should render status and name', () => {
component = mountComponent(JobComponent, { createWrapper({
job: { job: {
id: 4257, id: 4257,
name: 'test', name: 'test',
@ -72,36 +73,34 @@ describe('pipeline graph job item', () => {
}, },
}); });
expect(component.$el.querySelector('.js-status-icon-success')).toBeDefined(); expect(wrapper.find('.js-status-icon-success')).toBeDefined();
expect(component.$el.querySelector('a')).toBeNull(); expect(wrapper.find('a').exists()).toBe(false);
expect(component.$el.querySelector('.ci-status-text').textContent.trim()).toEqual( expect(trimText(wrapper.find('.ci-status-text').text())).toEqual(mockJob.name);
mockJob.name,
);
}); });
}); });
describe('action icon', () => { describe('action icon', () => {
it('it should render the action icon', () => { it('it should render the action icon', () => {
component = mountComponent(JobComponent, { job: mockJob }); createWrapper({ job: mockJob });
expect(component.$el.querySelector('a.ci-action-icon-container')).toBeDefined(); expect(wrapper.find('a.ci-action-icon-container')).toBeDefined();
expect(component.$el.querySelector('i.ci-action-icon-wrapper')).toBeDefined(); expect(wrapper.find('i.ci-action-icon-wrapper')).toBeDefined();
}); });
}); });
it('should render provided class name', () => { it('should render provided class name', () => {
component = mountComponent(JobComponent, { createWrapper({
job: mockJob, job: mockJob,
cssClassJobName: 'css-class-job-name', cssClassJobName: 'css-class-job-name',
}); });
expect(component.$el.querySelector('a').classList.contains('css-class-job-name')).toBe(true); expect(wrapper.find('a').classes()).toContain('css-class-job-name');
}); });
describe('status label', () => { describe('status label', () => {
it('should not render status label when it is not provided', () => { it('should not render status label when it is not provided', () => {
component = mountComponent(JobComponent, { createWrapper({
job: { job: {
id: 4258, id: 4258,
name: 'test', name: 'test',
@ -111,15 +110,13 @@ describe('pipeline graph job item', () => {
}, },
}); });
expect( expect(wrapper.find('.js-job-component-tooltip').attributes('data-original-title')).toBe(
component.$el 'test',
.querySelector('.js-job-component-tooltip') );
.getAttribute('data-original-title'),
).toEqual('test');
}); });
it('should not render status label when it is provided', () => { it('should not render status label when it is provided', () => {
component = mountComponent(JobComponent, { createWrapper({
job: { job: {
id: 4259, id: 4259,
name: 'test', name: 'test',
@ -131,25 +128,21 @@ describe('pipeline graph job item', () => {
}, },
}); });
expect( expect(wrapper.find('.js-job-component-tooltip').attributes('data-original-title')).toEqual(
component.$el 'test - success',
.querySelector('.js-job-component-tooltip') );
.getAttribute('data-original-title'),
).toEqual('test - success');
}); });
}); });
describe('for delayed job', () => { describe('for delayed job', () => {
it('displays remaining time in tooltip', () => { it('displays remaining time in tooltip', () => {
component = mountComponent(JobComponent, { createWrapper({
job: delayedJobFixture, job: delayedJobFixture,
}); });
expect( expect(wrapper.find('.js-pipeline-graph-job-link').attributes('data-original-title')).toEqual(
component.$el `delayed job - delayed manual action (${wrapper.vm.remainingTime})`,
.querySelector('.js-pipeline-graph-job-link') );
.getAttribute('data-original-title'),
).toEqual(`delayed job - delayed manual action (${component.remainingTime})`);
}); });
}); });
}); });

View file

@ -0,0 +1,127 @@
import { mount } from '@vue/test-utils';
import LinkedPipelineComponent from '~/pipelines/components/graph/linked_pipeline.vue';
import mockData from './linked_pipelines_mock_data';
const mockPipeline = mockData.triggered[0];
describe('Linked pipeline', () => {
let wrapper;
afterEach(() => {
wrapper.destroy();
});
describe('rendered output', () => {
const props = {
pipeline: mockPipeline,
};
beforeEach(() => {
wrapper = mount(LinkedPipelineComponent, {
sync: false,
attachToDocument: true,
propsData: props,
});
});
it('should render a list item as the containing element', () => {
expect(wrapper.is('li')).toBe(true);
});
it('should render a button', () => {
const linkElement = wrapper.find('.js-linked-pipeline-content');
expect(linkElement.exists()).toBe(true);
});
it('should render the project name', () => {
expect(wrapper.text()).toContain(props.pipeline.project.name);
});
it('should render an svg within the status container', () => {
const pipelineStatusElement = wrapper.find('.js-linked-pipeline-status');
expect(pipelineStatusElement.find('svg').exists()).toBe(true);
});
it('should render the pipeline status icon svg', () => {
expect(wrapper.find('.js-ci-status-icon-running').exists()).toBe(true);
expect(wrapper.find('.js-ci-status-icon-running').html()).toContain('<svg');
});
it('should have a ci-status child component', () => {
expect(wrapper.find('.js-linked-pipeline-status').exists()).toBe(true);
});
it('should render the pipeline id', () => {
expect(wrapper.text()).toContain(`#${props.pipeline.id}`);
});
it('should correctly compute the tooltip text', () => {
expect(wrapper.vm.tooltipText).toContain(mockPipeline.project.name);
expect(wrapper.vm.tooltipText).toContain(mockPipeline.details.status.label);
});
it('should render the tooltip text as the title attribute', () => {
const tooltipRef = wrapper.find('.js-linked-pipeline-content');
const titleAttr = tooltipRef.attributes('data-original-title');
expect(titleAttr).toContain(mockPipeline.project.name);
expect(titleAttr).toContain(mockPipeline.details.status.label);
});
it('does not render the loading icon when isLoading is false', () => {
expect(wrapper.find('.js-linked-pipeline-loading').exists()).toBe(false);
});
});
describe('when isLoading is true', () => {
const props = {
pipeline: { ...mockPipeline, isLoading: true },
};
beforeEach(() => {
wrapper = mount(LinkedPipelineComponent, {
sync: false,
attachToDocument: true,
propsData: props,
});
});
it('renders a loading icon', () => {
expect(wrapper.find('.js-linked-pipeline-loading').exists()).toBe(true);
});
});
describe('on click', () => {
const props = {
pipeline: mockPipeline,
};
beforeEach(() => {
wrapper = mount(LinkedPipelineComponent, {
sync: false,
attachToDocument: true,
propsData: props,
});
});
it('emits `pipelineClicked` event', () => {
jest.spyOn(wrapper.vm, '$emit');
wrapper.find('button').trigger('click');
expect(wrapper.vm.$emit).toHaveBeenCalledWith('pipelineClicked');
});
it('should emit `bv::hide::tooltip` to close the tooltip', () => {
jest.spyOn(wrapper.vm.$root, '$emit');
wrapper.find('button').trigger('click');
expect(wrapper.vm.$root.$emit.mock.calls[0]).toEqual([
'bv::hide::tooltip',
'js-linked-pipeline-132',
]);
});
});
});

View file

@ -0,0 +1,407 @@
export default {
triggered_by: {
id: 129,
active: true,
path: '/gitlab-org/gitlab-foss/pipelines/129',
project: {
name: 'GitLabCE',
},
details: {
status: {
icon: 'status_running',
text: 'running',
label: 'running',
group: 'running',
has_details: true,
details_path: '/gitlab-org/gitlab-foss/pipelines/129',
favicon:
'/assets/ci_favicons/dev/favicon_status_running-c3ad2fc53ea6079c174e5b6c1351ff349e99ec3af5a5622fb77b0fe53ea279c1.ico',
},
},
flags: {
latest: false,
triggered: false,
stuck: false,
yaml_errors: false,
retryable: true,
cancelable: true,
},
ref: {
name: '7-5-stable',
path: '/gitlab-org/gitlab-foss/commits/7-5-stable',
tag: false,
branch: true,
},
commit: {
id: '23433d4d8b20d7e45c103d0b6048faad38a130ab',
short_id: '23433d4d',
title: 'Version 7.5.0.rc1',
created_at: '2014-11-17T15:44:14.000+01:00',
parent_ids: ['30ac909f30f58d319b42ed1537664483894b18cd'],
message: 'Version 7.5.0.rc1\n',
author_name: 'Jacob Vosmaer',
author_email: 'contact@jacobvosmaer.nl',
authored_date: '2014-11-17T15:44:14.000+01:00',
committer_name: 'Jacob Vosmaer',
committer_email: 'contact@jacobvosmaer.nl',
committed_date: '2014-11-17T15:44:14.000+01:00',
author_gravatar_url:
'http://www.gravatar.com/avatar/e66d11c0eedf8c07b3b18fca46599807?s=80&d=identicon',
commit_url:
'http://localhost:3000/gitlab-org/gitlab-foss/commit/23433d4d8b20d7e45c103d0b6048faad38a130ab',
commit_path: '/gitlab-org/gitlab-foss/commit/23433d4d8b20d7e45c103d0b6048faad38a130ab',
},
retry_path: '/gitlab-org/gitlab-foss/pipelines/129/retry',
cancel_path: '/gitlab-org/gitlab-foss/pipelines/129/cancel',
created_at: '2017-05-24T14:46:20.090Z',
updated_at: '2017-05-24T14:46:29.906Z',
},
triggered: [
{
id: 132,
active: true,
path: '/gitlab-org/gitlab-foss/pipelines/132',
project: {
name: 'GitLabCE',
},
details: {
status: {
icon: 'status_running',
text: 'running',
label: 'running',
group: 'running',
has_details: true,
details_path: '/gitlab-org/gitlab-foss/pipelines/132',
favicon:
'/assets/ci_favicons/dev/favicon_status_running-c3ad2fc53ea6079c174e5b6c1351ff349e99ec3af5a5622fb77b0fe53ea279c1.ico',
},
},
flags: {
latest: false,
triggered: false,
stuck: false,
yaml_errors: false,
retryable: true,
cancelable: true,
},
ref: {
name: 'crowd',
path: '/gitlab-org/gitlab-foss/commits/crowd',
tag: false,
branch: true,
},
commit: {
id: 'b9d58c4cecd06be74c3cc32ccfb522b31544ab2e',
short_id: 'b9d58c4c',
title: 'getting user keys publically through http without any authentication, the github…',
created_at: '2013-10-03T12:50:33.000+05:30',
parent_ids: ['e219cf7246c6a0495e4507deaffeba11e79f13b8'],
message:
'getting user keys publically through http without any authentication, the github way. E.g: http://github.com/devaroop.keys\n\nchangelog updated to include ssh key retrieval feature update\n',
author_name: 'devaroop',
author_email: 'devaroop123@yahoo.co.in',
authored_date: '2013-10-02T20:39:29.000+05:30',
committer_name: 'devaroop',
committer_email: 'devaroop123@yahoo.co.in',
committed_date: '2013-10-03T12:50:33.000+05:30',
author_gravatar_url:
'http://www.gravatar.com/avatar/35df4b155ec66a3127d53459941cf8a2?s=80&d=identicon',
commit_url:
'http://localhost:3000/gitlab-org/gitlab-foss/commit/b9d58c4cecd06be74c3cc32ccfb522b31544ab2e',
commit_path: '/gitlab-org/gitlab-foss/commit/b9d58c4cecd06be74c3cc32ccfb522b31544ab2e',
},
retry_path: '/gitlab-org/gitlab-foss/pipelines/132/retry',
cancel_path: '/gitlab-org/gitlab-foss/pipelines/132/cancel',
created_at: '2017-05-24T14:46:24.644Z',
updated_at: '2017-05-24T14:48:55.226Z',
},
{
id: 133,
active: true,
path: '/gitlab-org/gitlab-foss/pipelines/133',
project: {
name: 'GitLabCE',
},
details: {
status: {
icon: 'status_running',
text: 'running',
label: 'running',
group: 'running',
has_details: true,
details_path: '/gitlab-org/gitlab-foss/pipelines/133',
favicon:
'/assets/ci_favicons/dev/favicon_status_running-c3ad2fc53ea6079c174e5b6c1351ff349e99ec3af5a5622fb77b0fe53ea279c1.ico',
},
},
flags: {
latest: false,
triggered: false,
stuck: false,
yaml_errors: false,
retryable: true,
cancelable: true,
},
ref: {
name: 'crowd',
path: '/gitlab-org/gitlab-foss/commits/crowd',
tag: false,
branch: true,
},
commit: {
id: 'b6bd4856a33df3d144be66c4ed1f1396009bb08b',
short_id: 'b6bd4856',
title: 'getting user keys publically through http without any authentication, the github…',
created_at: '2013-10-02T20:39:29.000+05:30',
parent_ids: ['e219cf7246c6a0495e4507deaffeba11e79f13b8'],
message:
'getting user keys publically through http without any authentication, the github way. E.g: http://github.com/devaroop.keys\n',
author_name: 'devaroop',
author_email: 'devaroop123@yahoo.co.in',
authored_date: '2013-10-02T20:39:29.000+05:30',
committer_name: 'devaroop',
committer_email: 'devaroop123@yahoo.co.in',
committed_date: '2013-10-02T20:39:29.000+05:30',
author_gravatar_url:
'http://www.gravatar.com/avatar/35df4b155ec66a3127d53459941cf8a2?s=80&d=identicon',
commit_url:
'http://localhost:3000/gitlab-org/gitlab-foss/commit/b6bd4856a33df3d144be66c4ed1f1396009bb08b',
commit_path: '/gitlab-org/gitlab-foss/commit/b6bd4856a33df3d144be66c4ed1f1396009bb08b',
},
retry_path: '/gitlab-org/gitlab-foss/pipelines/133/retry',
cancel_path: '/gitlab-org/gitlab-foss/pipelines/133/cancel',
created_at: '2017-05-24T14:46:24.648Z',
updated_at: '2017-05-24T14:48:59.673Z',
},
{
id: 130,
active: true,
path: '/gitlab-org/gitlab-foss/pipelines/130',
project: {
name: 'GitLabCE',
},
details: {
status: {
icon: 'status_running',
text: 'running',
label: 'running',
group: 'running',
has_details: true,
details_path: '/gitlab-org/gitlab-foss/pipelines/130',
favicon:
'/assets/ci_favicons/dev/favicon_status_running-c3ad2fc53ea6079c174e5b6c1351ff349e99ec3af5a5622fb77b0fe53ea279c1.ico',
},
},
flags: {
latest: false,
triggered: false,
stuck: false,
yaml_errors: false,
retryable: true,
cancelable: true,
},
ref: {
name: 'crowd',
path: '/gitlab-org/gitlab-foss/commits/crowd',
tag: false,
branch: true,
},
commit: {
id: '6d7ced4a2311eeff037c5575cca1868a6d3f586f',
short_id: '6d7ced4a',
title: 'Whitespace fixes to patch',
created_at: '2013-10-08T13:53:22.000-05:00',
parent_ids: ['1875141a963a4238bda29011d8f7105839485253'],
message: 'Whitespace fixes to patch\n',
author_name: 'Dale Hamel',
author_email: 'dale.hamel@srvthe.net',
authored_date: '2013-10-08T13:53:22.000-05:00',
committer_name: 'Dale Hamel',
committer_email: 'dale.hamel@invenia.ca',
committed_date: '2013-10-08T13:53:22.000-05:00',
author_gravatar_url:
'http://www.gravatar.com/avatar/cd08930e69fa5ad1a669206e7bafe476?s=80&d=identicon',
commit_url:
'http://localhost:3000/gitlab-org/gitlab-foss/commit/6d7ced4a2311eeff037c5575cca1868a6d3f586f',
commit_path: '/gitlab-org/gitlab-foss/commit/6d7ced4a2311eeff037c5575cca1868a6d3f586f',
},
retry_path: '/gitlab-org/gitlab-foss/pipelines/130/retry',
cancel_path: '/gitlab-org/gitlab-foss/pipelines/130/cancel',
created_at: '2017-05-24T14:46:24.630Z',
updated_at: '2017-05-24T14:49:45.091Z',
},
{
id: 131,
active: true,
path: '/gitlab-org/gitlab-foss/pipelines/132',
project: {
name: 'GitLabCE',
},
details: {
status: {
icon: 'status_running',
text: 'running',
label: 'running',
group: 'running',
has_details: true,
details_path: '/gitlab-org/gitlab-foss/pipelines/132',
favicon:
'/assets/ci_favicons/dev/favicon_status_running-c3ad2fc53ea6079c174e5b6c1351ff349e99ec3af5a5622fb77b0fe53ea279c1.ico',
},
},
flags: {
latest: false,
triggered: false,
stuck: false,
yaml_errors: false,
retryable: true,
cancelable: true,
},
ref: {
name: 'crowd',
path: '/gitlab-org/gitlab-foss/commits/crowd',
tag: false,
branch: true,
},
commit: {
id: 'b9d58c4cecd06be74c3cc32ccfb522b31544ab2e',
short_id: 'b9d58c4c',
title: 'getting user keys publically through http without any authentication, the github…',
created_at: '2013-10-03T12:50:33.000+05:30',
parent_ids: ['e219cf7246c6a0495e4507deaffeba11e79f13b8'],
message:
'getting user keys publically through http without any authentication, the github way. E.g: http://github.com/devaroop.keys\n\nchangelog updated to include ssh key retrieval feature update\n',
author_name: 'devaroop',
author_email: 'devaroop123@yahoo.co.in',
authored_date: '2013-10-02T20:39:29.000+05:30',
committer_name: 'devaroop',
committer_email: 'devaroop123@yahoo.co.in',
committed_date: '2013-10-03T12:50:33.000+05:30',
author_gravatar_url:
'http://www.gravatar.com/avatar/35df4b155ec66a3127d53459941cf8a2?s=80&d=identicon',
commit_url:
'http://localhost:3000/gitlab-org/gitlab-foss/commit/b9d58c4cecd06be74c3cc32ccfb522b31544ab2e',
commit_path: '/gitlab-org/gitlab-foss/commit/b9d58c4cecd06be74c3cc32ccfb522b31544ab2e',
},
retry_path: '/gitlab-org/gitlab-foss/pipelines/132/retry',
cancel_path: '/gitlab-org/gitlab-foss/pipelines/132/cancel',
created_at: '2017-05-24T14:46:24.644Z',
updated_at: '2017-05-24T14:48:55.226Z',
},
{
id: 134,
active: true,
path: '/gitlab-org/gitlab-foss/pipelines/133',
project: {
name: 'GitLabCE',
},
details: {
status: {
icon: 'status_running',
text: 'running',
label: 'running',
group: 'running',
has_details: true,
details_path: '/gitlab-org/gitlab-foss/pipelines/133',
favicon:
'/assets/ci_favicons/dev/favicon_status_running-c3ad2fc53ea6079c174e5b6c1351ff349e99ec3af5a5622fb77b0fe53ea279c1.ico',
},
},
flags: {
latest: false,
triggered: false,
stuck: false,
yaml_errors: false,
retryable: true,
cancelable: true,
},
ref: {
name: 'crowd',
path: '/gitlab-org/gitlab-foss/commits/crowd',
tag: false,
branch: true,
},
commit: {
id: 'b6bd4856a33df3d144be66c4ed1f1396009bb08b',
short_id: 'b6bd4856',
title: 'getting user keys publically through http without any authentication, the github…',
created_at: '2013-10-02T20:39:29.000+05:30',
parent_ids: ['e219cf7246c6a0495e4507deaffeba11e79f13b8'],
message:
'getting user keys publically through http without any authentication, the github way. E.g: http://github.com/devaroop.keys\n',
author_name: 'devaroop',
author_email: 'devaroop123@yahoo.co.in',
authored_date: '2013-10-02T20:39:29.000+05:30',
committer_name: 'devaroop',
committer_email: 'devaroop123@yahoo.co.in',
committed_date: '2013-10-02T20:39:29.000+05:30',
author_gravatar_url:
'http://www.gravatar.com/avatar/35df4b155ec66a3127d53459941cf8a2?s=80&d=identicon',
commit_url:
'http://localhost:3000/gitlab-org/gitlab-foss/commit/b6bd4856a33df3d144be66c4ed1f1396009bb08b',
commit_path: '/gitlab-org/gitlab-foss/commit/b6bd4856a33df3d144be66c4ed1f1396009bb08b',
},
retry_path: '/gitlab-org/gitlab-foss/pipelines/133/retry',
cancel_path: '/gitlab-org/gitlab-foss/pipelines/133/cancel',
created_at: '2017-05-24T14:46:24.648Z',
updated_at: '2017-05-24T14:48:59.673Z',
},
{
id: 135,
active: true,
path: '/gitlab-org/gitlab-foss/pipelines/130',
project: {
name: 'GitLabCE',
},
details: {
status: {
icon: 'status_running',
text: 'running',
label: 'running',
group: 'running',
has_details: true,
details_path: '/gitlab-org/gitlab-foss/pipelines/130',
favicon:
'/assets/ci_favicons/dev/favicon_status_running-c3ad2fc53ea6079c174e5b6c1351ff349e99ec3af5a5622fb77b0fe53ea279c1.ico',
},
},
flags: {
latest: false,
triggered: false,
stuck: false,
yaml_errors: false,
retryable: true,
cancelable: true,
},
ref: {
name: 'crowd',
path: '/gitlab-org/gitlab-foss/commits/crowd',
tag: false,
branch: true,
},
commit: {
id: '6d7ced4a2311eeff037c5575cca1868a6d3f586f',
short_id: '6d7ced4a',
title: 'Whitespace fixes to patch',
created_at: '2013-10-08T13:53:22.000-05:00',
parent_ids: ['1875141a963a4238bda29011d8f7105839485253'],
message: 'Whitespace fixes to patch\n',
author_name: 'Dale Hamel',
author_email: 'dale.hamel@srvthe.net',
authored_date: '2013-10-08T13:53:22.000-05:00',
committer_name: 'Dale Hamel',
committer_email: 'dale.hamel@invenia.ca',
committed_date: '2013-10-08T13:53:22.000-05:00',
author_gravatar_url:
'http://www.gravatar.com/avatar/cd08930e69fa5ad1a669206e7bafe476?s=80&d=identicon',
commit_url:
'http://localhost:3000/gitlab-org/gitlab-foss/commit/6d7ced4a2311eeff037c5575cca1868a6d3f586f',
commit_path: '/gitlab-org/gitlab-foss/commit/6d7ced4a2311eeff037c5575cca1868a6d3f586f',
},
retry_path: '/gitlab-org/gitlab-foss/pipelines/130/retry',
cancel_path: '/gitlab-org/gitlab-foss/pipelines/130/cancel',
created_at: '2017-05-24T14:46:24.630Z',
updated_at: '2017-05-24T14:49:45.091Z',
},
],
};

View file

@ -0,0 +1,112 @@
import $ from 'jquery';
import { trimText } from 'helpers/text_helper';
import { shallowMount } from '@vue/test-utils';
import PipelineUrlComponent from '~/pipelines/components/pipeline_url.vue';
$.fn.popover = () => {};
describe('Pipeline Url Component', () => {
let wrapper;
const createComponent = props => {
wrapper = shallowMount(PipelineUrlComponent, {
sync: false,
attachToDocument: true,
propsData: props,
});
};
afterEach(() => {
wrapper.destroy();
});
it('should render a table cell', () => {
createComponent({
pipeline: {
id: 1,
path: 'foo',
flags: {},
},
autoDevopsHelpPath: 'foo',
});
expect(wrapper.attributes('class')).toContain('table-section');
});
it('should render a link the provided path and id', () => {
createComponent({
pipeline: {
id: 1,
path: 'foo',
flags: {},
},
autoDevopsHelpPath: 'foo',
});
expect(wrapper.find('.js-pipeline-url-link').attributes('href')).toBe('foo');
expect(wrapper.find('.js-pipeline-url-link span').text()).toBe('#1');
});
it('should render latest, yaml invalid, merge request, and stuck flags when provided', () => {
createComponent({
pipeline: {
id: 1,
path: 'foo',
flags: {
latest: true,
yaml_errors: true,
stuck: true,
merge_request_pipeline: true,
detached_merge_request_pipeline: true,
},
},
autoDevopsHelpPath: 'foo',
});
expect(wrapper.find('.js-pipeline-url-latest').text()).toContain('latest');
expect(wrapper.find('.js-pipeline-url-yaml').text()).toContain('yaml invalid');
expect(wrapper.find('.js-pipeline-url-stuck').text()).toContain('stuck');
expect(wrapper.find('.js-pipeline-url-detached').text()).toContain('detached');
});
it('should render a badge for autodevops', () => {
createComponent({
pipeline: {
id: 1,
path: 'foo',
flags: {
latest: true,
yaml_errors: true,
stuck: true,
auto_devops: true,
},
},
autoDevopsHelpPath: 'foo',
});
expect(trimText(wrapper.find('.js-pipeline-url-autodevops').text())).toEqual('Auto DevOps');
});
it('should render error badge when pipeline has a failure reason set', () => {
createComponent({
pipeline: {
id: 1,
path: 'foo',
flags: {
failure_reason: true,
},
failure_reason: 'some reason',
},
autoDevopsHelpPath: 'foo',
});
expect(wrapper.find('.js-pipeline-url-failure').text()).toContain('error');
expect(wrapper.find('.js-pipeline-url-failure').attributes('data-original-title')).toContain(
'some reason',
);
});
});

View file

@ -1,116 +0,0 @@
import Vue from 'vue';
import LinkedPipelineComponent from '~/pipelines/components/graph/linked_pipeline.vue';
import mountComponent from 'spec/helpers/vue_mount_component_helper';
import mockData from './linked_pipelines_mock_data';
const mockPipeline = mockData.triggered[0];
describe('Linked pipeline', () => {
const Component = Vue.extend(LinkedPipelineComponent);
let vm;
afterEach(() => {
vm.$destroy();
});
describe('rendered output', () => {
const props = {
pipeline: mockPipeline,
};
beforeEach(() => {
vm = mountComponent(Component, props);
});
it('should render a list item as the containing element', () => {
expect(vm.$el.tagName).toBe('LI');
});
it('should render a button', () => {
const linkElement = vm.$el.querySelector('.js-linked-pipeline-content');
expect(linkElement).not.toBeNull();
});
it('should render the project name', () => {
expect(vm.$el.innerText).toContain(props.pipeline.project.name);
});
it('should render an svg within the status container', () => {
const pipelineStatusElement = vm.$el.querySelector('.js-linked-pipeline-status');
expect(pipelineStatusElement.querySelector('svg')).not.toBeNull();
});
it('should render the pipeline status icon svg', () => {
expect(vm.$el.querySelector('.js-ci-status-icon-running')).not.toBeNull();
expect(vm.$el.querySelector('.js-ci-status-icon-running').innerHTML).toContain('<svg');
});
it('should have a ci-status child component', () => {
expect(vm.$el.querySelector('.js-linked-pipeline-status')).not.toBeNull();
});
it('should render the pipeline id', () => {
expect(vm.$el.innerText).toContain(`#${props.pipeline.id}`);
});
it('should correctly compute the tooltip text', () => {
expect(vm.tooltipText).toContain(mockPipeline.project.name);
expect(vm.tooltipText).toContain(mockPipeline.details.status.label);
});
it('should render the tooltip text as the title attribute', () => {
const tooltipRef = vm.$el.querySelector('.js-linked-pipeline-content');
const titleAttr = tooltipRef.getAttribute('data-original-title');
expect(titleAttr).toContain(mockPipeline.project.name);
expect(titleAttr).toContain(mockPipeline.details.status.label);
});
it('does not render the loading icon when isLoading is false', () => {
expect(vm.$el.querySelector('.js-linked-pipeline-loading')).toBeNull();
});
});
describe('when isLoading is true', () => {
const props = {
pipeline: { ...mockPipeline, isLoading: true },
};
beforeEach(() => {
vm = mountComponent(Component, props);
});
it('renders a loading icon', () => {
expect(vm.$el.querySelector('.js-linked-pipeline-loading')).not.toBeNull();
});
});
describe('on click', () => {
const props = {
pipeline: mockPipeline,
};
beforeEach(() => {
vm = mountComponent(Component, props);
});
it('emits `pipelineClicked` event', () => {
spyOn(vm, '$emit');
vm.$el.querySelector('button').click();
expect(vm.$emit).toHaveBeenCalledWith('pipelineClicked');
});
it('should emit `bv::hide::tooltip` to close the tooltip', () => {
spyOn(vm.$root, '$emit');
vm.$el.querySelector('button').click();
expect(vm.$root.$emit.calls.argsFor(0)).toEqual([
'bv::hide::tooltip',
'js-linked-pipeline-132',
]);
});
});
});

View file

@ -1,407 +1,3 @@
export default { import mockData from '../../../frontend/pipelines/graph/linked_pipelines_mock_data';
triggered_by: {
id: 129, export default mockData;
active: true,
path: '/gitlab-org/gitlab-foss/pipelines/129',
project: {
name: 'GitLabCE',
},
details: {
status: {
icon: 'status_running',
text: 'running',
label: 'running',
group: 'running',
has_details: true,
details_path: '/gitlab-org/gitlab-foss/pipelines/129',
favicon:
'/assets/ci_favicons/dev/favicon_status_running-c3ad2fc53ea6079c174e5b6c1351ff349e99ec3af5a5622fb77b0fe53ea279c1.ico',
},
},
flags: {
latest: false,
triggered: false,
stuck: false,
yaml_errors: false,
retryable: true,
cancelable: true,
},
ref: {
name: '7-5-stable',
path: '/gitlab-org/gitlab-foss/commits/7-5-stable',
tag: false,
branch: true,
},
commit: {
id: '23433d4d8b20d7e45c103d0b6048faad38a130ab',
short_id: '23433d4d',
title: 'Version 7.5.0.rc1',
created_at: '2014-11-17T15:44:14.000+01:00',
parent_ids: ['30ac909f30f58d319b42ed1537664483894b18cd'],
message: 'Version 7.5.0.rc1\n',
author_name: 'Jacob Vosmaer',
author_email: 'contact@jacobvosmaer.nl',
authored_date: '2014-11-17T15:44:14.000+01:00',
committer_name: 'Jacob Vosmaer',
committer_email: 'contact@jacobvosmaer.nl',
committed_date: '2014-11-17T15:44:14.000+01:00',
author_gravatar_url:
'http://www.gravatar.com/avatar/e66d11c0eedf8c07b3b18fca46599807?s=80&d=identicon',
commit_url:
'http://localhost:3000/gitlab-org/gitlab-foss/commit/23433d4d8b20d7e45c103d0b6048faad38a130ab',
commit_path: '/gitlab-org/gitlab-foss/commit/23433d4d8b20d7e45c103d0b6048faad38a130ab',
},
retry_path: '/gitlab-org/gitlab-foss/pipelines/129/retry',
cancel_path: '/gitlab-org/gitlab-foss/pipelines/129/cancel',
created_at: '2017-05-24T14:46:20.090Z',
updated_at: '2017-05-24T14:46:29.906Z',
},
triggered: [
{
id: 132,
active: true,
path: '/gitlab-org/gitlab-foss/pipelines/132',
project: {
name: 'GitLabCE',
},
details: {
status: {
icon: 'status_running',
text: 'running',
label: 'running',
group: 'running',
has_details: true,
details_path: '/gitlab-org/gitlab-foss/pipelines/132',
favicon:
'/assets/ci_favicons/dev/favicon_status_running-c3ad2fc53ea6079c174e5b6c1351ff349e99ec3af5a5622fb77b0fe53ea279c1.ico',
},
},
flags: {
latest: false,
triggered: false,
stuck: false,
yaml_errors: false,
retryable: true,
cancelable: true,
},
ref: {
name: 'crowd',
path: '/gitlab-org/gitlab-foss/commits/crowd',
tag: false,
branch: true,
},
commit: {
id: 'b9d58c4cecd06be74c3cc32ccfb522b31544ab2e',
short_id: 'b9d58c4c',
title: 'getting user keys publically through http without any authentication, the github…',
created_at: '2013-10-03T12:50:33.000+05:30',
parent_ids: ['e219cf7246c6a0495e4507deaffeba11e79f13b8'],
message:
'getting user keys publically through http without any authentication, the github way. E.g: http://github.com/devaroop.keys\n\nchangelog updated to include ssh key retrieval feature update\n',
author_name: 'devaroop',
author_email: 'devaroop123@yahoo.co.in',
authored_date: '2013-10-02T20:39:29.000+05:30',
committer_name: 'devaroop',
committer_email: 'devaroop123@yahoo.co.in',
committed_date: '2013-10-03T12:50:33.000+05:30',
author_gravatar_url:
'http://www.gravatar.com/avatar/35df4b155ec66a3127d53459941cf8a2?s=80&d=identicon',
commit_url:
'http://localhost:3000/gitlab-org/gitlab-foss/commit/b9d58c4cecd06be74c3cc32ccfb522b31544ab2e',
commit_path: '/gitlab-org/gitlab-foss/commit/b9d58c4cecd06be74c3cc32ccfb522b31544ab2e',
},
retry_path: '/gitlab-org/gitlab-foss/pipelines/132/retry',
cancel_path: '/gitlab-org/gitlab-foss/pipelines/132/cancel',
created_at: '2017-05-24T14:46:24.644Z',
updated_at: '2017-05-24T14:48:55.226Z',
},
{
id: 133,
active: true,
path: '/gitlab-org/gitlab-foss/pipelines/133',
project: {
name: 'GitLabCE',
},
details: {
status: {
icon: 'status_running',
text: 'running',
label: 'running',
group: 'running',
has_details: true,
details_path: '/gitlab-org/gitlab-foss/pipelines/133',
favicon:
'/assets/ci_favicons/dev/favicon_status_running-c3ad2fc53ea6079c174e5b6c1351ff349e99ec3af5a5622fb77b0fe53ea279c1.ico',
},
},
flags: {
latest: false,
triggered: false,
stuck: false,
yaml_errors: false,
retryable: true,
cancelable: true,
},
ref: {
name: 'crowd',
path: '/gitlab-org/gitlab-foss/commits/crowd',
tag: false,
branch: true,
},
commit: {
id: 'b6bd4856a33df3d144be66c4ed1f1396009bb08b',
short_id: 'b6bd4856',
title: 'getting user keys publically through http without any authentication, the github…',
created_at: '2013-10-02T20:39:29.000+05:30',
parent_ids: ['e219cf7246c6a0495e4507deaffeba11e79f13b8'],
message:
'getting user keys publically through http without any authentication, the github way. E.g: http://github.com/devaroop.keys\n',
author_name: 'devaroop',
author_email: 'devaroop123@yahoo.co.in',
authored_date: '2013-10-02T20:39:29.000+05:30',
committer_name: 'devaroop',
committer_email: 'devaroop123@yahoo.co.in',
committed_date: '2013-10-02T20:39:29.000+05:30',
author_gravatar_url:
'http://www.gravatar.com/avatar/35df4b155ec66a3127d53459941cf8a2?s=80&d=identicon',
commit_url:
'http://localhost:3000/gitlab-org/gitlab-foss/commit/b6bd4856a33df3d144be66c4ed1f1396009bb08b',
commit_path: '/gitlab-org/gitlab-foss/commit/b6bd4856a33df3d144be66c4ed1f1396009bb08b',
},
retry_path: '/gitlab-org/gitlab-foss/pipelines/133/retry',
cancel_path: '/gitlab-org/gitlab-foss/pipelines/133/cancel',
created_at: '2017-05-24T14:46:24.648Z',
updated_at: '2017-05-24T14:48:59.673Z',
},
{
id: 130,
active: true,
path: '/gitlab-org/gitlab-foss/pipelines/130',
project: {
name: 'GitLabCE',
},
details: {
status: {
icon: 'status_running',
text: 'running',
label: 'running',
group: 'running',
has_details: true,
details_path: '/gitlab-org/gitlab-foss/pipelines/130',
favicon:
'/assets/ci_favicons/dev/favicon_status_running-c3ad2fc53ea6079c174e5b6c1351ff349e99ec3af5a5622fb77b0fe53ea279c1.ico',
},
},
flags: {
latest: false,
triggered: false,
stuck: false,
yaml_errors: false,
retryable: true,
cancelable: true,
},
ref: {
name: 'crowd',
path: '/gitlab-org/gitlab-foss/commits/crowd',
tag: false,
branch: true,
},
commit: {
id: '6d7ced4a2311eeff037c5575cca1868a6d3f586f',
short_id: '6d7ced4a',
title: 'Whitespace fixes to patch',
created_at: '2013-10-08T13:53:22.000-05:00',
parent_ids: ['1875141a963a4238bda29011d8f7105839485253'],
message: 'Whitespace fixes to patch\n',
author_name: 'Dale Hamel',
author_email: 'dale.hamel@srvthe.net',
authored_date: '2013-10-08T13:53:22.000-05:00',
committer_name: 'Dale Hamel',
committer_email: 'dale.hamel@invenia.ca',
committed_date: '2013-10-08T13:53:22.000-05:00',
author_gravatar_url:
'http://www.gravatar.com/avatar/cd08930e69fa5ad1a669206e7bafe476?s=80&d=identicon',
commit_url:
'http://localhost:3000/gitlab-org/gitlab-foss/commit/6d7ced4a2311eeff037c5575cca1868a6d3f586f',
commit_path: '/gitlab-org/gitlab-foss/commit/6d7ced4a2311eeff037c5575cca1868a6d3f586f',
},
retry_path: '/gitlab-org/gitlab-foss/pipelines/130/retry',
cancel_path: '/gitlab-org/gitlab-foss/pipelines/130/cancel',
created_at: '2017-05-24T14:46:24.630Z',
updated_at: '2017-05-24T14:49:45.091Z',
},
{
id: 131,
active: true,
path: '/gitlab-org/gitlab-foss/pipelines/132',
project: {
name: 'GitLabCE',
},
details: {
status: {
icon: 'status_running',
text: 'running',
label: 'running',
group: 'running',
has_details: true,
details_path: '/gitlab-org/gitlab-foss/pipelines/132',
favicon:
'/assets/ci_favicons/dev/favicon_status_running-c3ad2fc53ea6079c174e5b6c1351ff349e99ec3af5a5622fb77b0fe53ea279c1.ico',
},
},
flags: {
latest: false,
triggered: false,
stuck: false,
yaml_errors: false,
retryable: true,
cancelable: true,
},
ref: {
name: 'crowd',
path: '/gitlab-org/gitlab-foss/commits/crowd',
tag: false,
branch: true,
},
commit: {
id: 'b9d58c4cecd06be74c3cc32ccfb522b31544ab2e',
short_id: 'b9d58c4c',
title: 'getting user keys publically through http without any authentication, the github…',
created_at: '2013-10-03T12:50:33.000+05:30',
parent_ids: ['e219cf7246c6a0495e4507deaffeba11e79f13b8'],
message:
'getting user keys publically through http without any authentication, the github way. E.g: http://github.com/devaroop.keys\n\nchangelog updated to include ssh key retrieval feature update\n',
author_name: 'devaroop',
author_email: 'devaroop123@yahoo.co.in',
authored_date: '2013-10-02T20:39:29.000+05:30',
committer_name: 'devaroop',
committer_email: 'devaroop123@yahoo.co.in',
committed_date: '2013-10-03T12:50:33.000+05:30',
author_gravatar_url:
'http://www.gravatar.com/avatar/35df4b155ec66a3127d53459941cf8a2?s=80&d=identicon',
commit_url:
'http://localhost:3000/gitlab-org/gitlab-foss/commit/b9d58c4cecd06be74c3cc32ccfb522b31544ab2e',
commit_path: '/gitlab-org/gitlab-foss/commit/b9d58c4cecd06be74c3cc32ccfb522b31544ab2e',
},
retry_path: '/gitlab-org/gitlab-foss/pipelines/132/retry',
cancel_path: '/gitlab-org/gitlab-foss/pipelines/132/cancel',
created_at: '2017-05-24T14:46:24.644Z',
updated_at: '2017-05-24T14:48:55.226Z',
},
{
id: 134,
active: true,
path: '/gitlab-org/gitlab-foss/pipelines/133',
project: {
name: 'GitLabCE',
},
details: {
status: {
icon: 'status_running',
text: 'running',
label: 'running',
group: 'running',
has_details: true,
details_path: '/gitlab-org/gitlab-foss/pipelines/133',
favicon:
'/assets/ci_favicons/dev/favicon_status_running-c3ad2fc53ea6079c174e5b6c1351ff349e99ec3af5a5622fb77b0fe53ea279c1.ico',
},
},
flags: {
latest: false,
triggered: false,
stuck: false,
yaml_errors: false,
retryable: true,
cancelable: true,
},
ref: {
name: 'crowd',
path: '/gitlab-org/gitlab-foss/commits/crowd',
tag: false,
branch: true,
},
commit: {
id: 'b6bd4856a33df3d144be66c4ed1f1396009bb08b',
short_id: 'b6bd4856',
title: 'getting user keys publically through http without any authentication, the github…',
created_at: '2013-10-02T20:39:29.000+05:30',
parent_ids: ['e219cf7246c6a0495e4507deaffeba11e79f13b8'],
message:
'getting user keys publically through http without any authentication, the github way. E.g: http://github.com/devaroop.keys\n',
author_name: 'devaroop',
author_email: 'devaroop123@yahoo.co.in',
authored_date: '2013-10-02T20:39:29.000+05:30',
committer_name: 'devaroop',
committer_email: 'devaroop123@yahoo.co.in',
committed_date: '2013-10-02T20:39:29.000+05:30',
author_gravatar_url:
'http://www.gravatar.com/avatar/35df4b155ec66a3127d53459941cf8a2?s=80&d=identicon',
commit_url:
'http://localhost:3000/gitlab-org/gitlab-foss/commit/b6bd4856a33df3d144be66c4ed1f1396009bb08b',
commit_path: '/gitlab-org/gitlab-foss/commit/b6bd4856a33df3d144be66c4ed1f1396009bb08b',
},
retry_path: '/gitlab-org/gitlab-foss/pipelines/133/retry',
cancel_path: '/gitlab-org/gitlab-foss/pipelines/133/cancel',
created_at: '2017-05-24T14:46:24.648Z',
updated_at: '2017-05-24T14:48:59.673Z',
},
{
id: 135,
active: true,
path: '/gitlab-org/gitlab-foss/pipelines/130',
project: {
name: 'GitLabCE',
},
details: {
status: {
icon: 'status_running',
text: 'running',
label: 'running',
group: 'running',
has_details: true,
details_path: '/gitlab-org/gitlab-foss/pipelines/130',
favicon:
'/assets/ci_favicons/dev/favicon_status_running-c3ad2fc53ea6079c174e5b6c1351ff349e99ec3af5a5622fb77b0fe53ea279c1.ico',
},
},
flags: {
latest: false,
triggered: false,
stuck: false,
yaml_errors: false,
retryable: true,
cancelable: true,
},
ref: {
name: 'crowd',
path: '/gitlab-org/gitlab-foss/commits/crowd',
tag: false,
branch: true,
},
commit: {
id: '6d7ced4a2311eeff037c5575cca1868a6d3f586f',
short_id: '6d7ced4a',
title: 'Whitespace fixes to patch',
created_at: '2013-10-08T13:53:22.000-05:00',
parent_ids: ['1875141a963a4238bda29011d8f7105839485253'],
message: 'Whitespace fixes to patch\n',
author_name: 'Dale Hamel',
author_email: 'dale.hamel@srvthe.net',
authored_date: '2013-10-08T13:53:22.000-05:00',
committer_name: 'Dale Hamel',
committer_email: 'dale.hamel@invenia.ca',
committed_date: '2013-10-08T13:53:22.000-05:00',
author_gravatar_url:
'http://www.gravatar.com/avatar/cd08930e69fa5ad1a669206e7bafe476?s=80&d=identicon',
commit_url:
'http://localhost:3000/gitlab-org/gitlab-foss/commit/6d7ced4a2311eeff037c5575cca1868a6d3f586f',
commit_path: '/gitlab-org/gitlab-foss/commit/6d7ced4a2311eeff037c5575cca1868a6d3f586f',
},
retry_path: '/gitlab-org/gitlab-foss/pipelines/130/retry',
cancel_path: '/gitlab-org/gitlab-foss/pipelines/130/cancel',
created_at: '2017-05-24T14:46:24.630Z',
updated_at: '2017-05-24T14:49:45.091Z',
},
],
};

View file

@ -1,118 +0,0 @@
import Vue from 'vue';
import pipelineUrlComp from '~/pipelines/components/pipeline_url.vue';
describe('Pipeline Url Component', () => {
let PipelineUrlComponent;
beforeEach(() => {
PipelineUrlComponent = Vue.extend(pipelineUrlComp);
});
it('should render a table cell', () => {
const component = new PipelineUrlComponent({
propsData: {
pipeline: {
id: 1,
path: 'foo',
flags: {},
},
autoDevopsHelpPath: 'foo',
},
}).$mount();
expect(component.$el.getAttribute('class')).toContain('table-section');
});
it('should render a link the provided path and id', () => {
const component = new PipelineUrlComponent({
propsData: {
pipeline: {
id: 1,
path: 'foo',
flags: {},
},
autoDevopsHelpPath: 'foo',
},
}).$mount();
expect(component.$el.querySelector('.js-pipeline-url-link').getAttribute('href')).toEqual(
'foo',
);
expect(component.$el.querySelector('.js-pipeline-url-link span').textContent).toEqual('#1');
});
it('should render latest, yaml invalid, merge request, and stuck flags when provided', () => {
const component = new PipelineUrlComponent({
propsData: {
pipeline: {
id: 1,
path: 'foo',
flags: {
latest: true,
yaml_errors: true,
stuck: true,
merge_request_pipeline: true,
detached_merge_request_pipeline: true,
},
},
autoDevopsHelpPath: 'foo',
},
}).$mount();
expect(component.$el.querySelector('.js-pipeline-url-latest').textContent).toContain('latest');
expect(component.$el.querySelector('.js-pipeline-url-yaml').textContent).toContain(
'yaml invalid',
);
expect(component.$el.querySelector('.js-pipeline-url-stuck').textContent).toContain('stuck');
expect(component.$el.querySelector('.js-pipeline-url-detached').textContent).toContain(
'detached',
);
});
it('should render a badge for autodevops', () => {
const component = new PipelineUrlComponent({
propsData: {
pipeline: {
id: 1,
path: 'foo',
flags: {
latest: true,
yaml_errors: true,
stuck: true,
auto_devops: true,
},
},
autoDevopsHelpPath: 'foo',
},
}).$mount();
expect(component.$el.querySelector('.js-pipeline-url-autodevops').textContent.trim()).toEqual(
'Auto DevOps',
);
});
it('should render error badge when pipeline has a failure reason set', () => {
const component = new PipelineUrlComponent({
propsData: {
pipeline: {
id: 1,
path: 'foo',
flags: {
failure_reason: true,
},
failure_reason: 'some reason',
},
autoDevopsHelpPath: 'foo',
},
}).$mount();
expect(component.$el.querySelector('.js-pipeline-url-failure').textContent).toContain('error');
expect(
component.$el.querySelector('.js-pipeline-url-failure').getAttribute('data-original-title'),
).toContain('some reason');
});
});

View file

@ -3,10 +3,10 @@
require 'spec_helper' require 'spec_helper'
describe Gitlab::Pages do describe Gitlab::Pages do
let(:pages_shared_secret) { SecureRandom.random_bytes(Gitlab::Pages::SECRET_LENGTH) } let(:pages_secret) { SecureRandom.random_bytes(Gitlab::Pages::SECRET_LENGTH) }
before do before do
allow(described_class).to receive(:secret).and_return(pages_shared_secret) allow(described_class).to receive(:secret).and_return(pages_secret)
end end
describe '.verify_api_request' do describe '.verify_api_request' do

View file

@ -9,7 +9,7 @@ describe Gitlab::StringRangeMarker do
inline_diffs = [2..5] inline_diffs = [2..5]
described_class.new(raw, rich).mark(inline_diffs) do |text, left:, right:| described_class.new(raw, rich).mark(inline_diffs) do |text, left:, right:|
"LEFT#{text}RIGHT" "LEFT#{text}RIGHT".html_safe
end end
end end

View file

@ -10,7 +10,7 @@ describe Gitlab::StringRegexMarker do
subject do subject do
described_class.new(raw, rich).mark(/"[^"]+":\s*"(?<name>[^"]+)"/, group: :name) do |text, left:, right:| described_class.new(raw, rich).mark(/"[^"]+":\s*"(?<name>[^"]+)"/, group: :name) do |text, left:, right:|
%{<a href="#">#{text}</a>} %{<a href="#">#{text}</a>}.html_safe
end end
end end
@ -26,7 +26,7 @@ describe Gitlab::StringRegexMarker do
subject do subject do
described_class.new(raw, rich).mark(/<[a-z]>/) do |text, left:, right:| described_class.new(raw, rich).mark(/<[a-z]>/) do |text, left:, right:|
%{<strong>#{text}</strong>} %{<strong>#{text}</strong>}.html_safe
end end
end end

View file

@ -4,10 +4,10 @@ require 'spec_helper'
describe API::Internal::Pages do describe API::Internal::Pages do
describe "GET /internal/pages" do describe "GET /internal/pages" do
let(:pages_shared_secret) { SecureRandom.random_bytes(Gitlab::Pages::SECRET_LENGTH) } let(:pages_secret) { SecureRandom.random_bytes(Gitlab::Pages::SECRET_LENGTH) }
before do before do
allow(Gitlab::Pages).to receive(:secret).and_return(pages_shared_secret) allow(Gitlab::Pages).to receive(:secret).and_return(pages_secret)
end end
def query_host(host, headers = {}) def query_host(host, headers = {})