Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
2b7a521434
commit
38c79b697f
18 changed files with 252 additions and 391 deletions
|
@ -56,7 +56,7 @@ Style/FrozenStringLiteralComment:
|
|||
- 'qa/**/*'
|
||||
- 'rubocop/**/*'
|
||||
- 'scripts/**/*'
|
||||
- 'spec/lib/**/*'
|
||||
- 'spec/lib/gitlab/**/*'
|
||||
|
||||
RSpec/FilePath:
|
||||
Exclude:
|
||||
|
|
|
@ -1,17 +1,30 @@
|
|||
/* eslint-disable import/prefer-default-export */
|
||||
import _ from 'underscore';
|
||||
|
||||
/**
|
||||
* @param {Array} queryResults - Array of Result objects
|
||||
* @param {Object} defaultConfig - Default chart config values (e.g. lineStyle, name)
|
||||
* @returns {Array} The formatted values
|
||||
*/
|
||||
export const makeDataSeries = (queryResults, defaultConfig) =>
|
||||
queryResults.reduce((acc, result) => {
|
||||
const data = result.values.filter(([, value]) => !Number.isNaN(value));
|
||||
if (!data.length) {
|
||||
return acc;
|
||||
}
|
||||
const relevantMetric = defaultConfig.name.toLowerCase().replace(' ', '_');
|
||||
const name = result.metric[relevantMetric];
|
||||
const series = { data };
|
||||
if (name) {
|
||||
series.name = `${defaultConfig.name}: ${name}`;
|
||||
}
|
||||
queryResults
|
||||
.map(result => {
|
||||
const data = result.values.filter(([, value]) => !Number.isNaN(value));
|
||||
if (!data.length) {
|
||||
return null;
|
||||
}
|
||||
const relevantMetric = defaultConfig.name.toLowerCase().replace(' ', '_');
|
||||
const name = result.metric[relevantMetric];
|
||||
const series = { data };
|
||||
if (name) {
|
||||
series.name = `${defaultConfig.name}: ${name}`;
|
||||
} else {
|
||||
const template = _.template(defaultConfig.name, {
|
||||
interpolate: /\{\{(.+?)\}\}/g,
|
||||
});
|
||||
series.name = template(result.metric);
|
||||
}
|
||||
|
||||
return acc.concat({ ...defaultConfig, ...series });
|
||||
}, []);
|
||||
return { ...defaultConfig, ...series };
|
||||
})
|
||||
.filter(series => series !== null);
|
||||
|
|
|
@ -553,14 +553,10 @@ export const calculateRemainingMilliseconds = endDate => {
|
|||
*
|
||||
* @param {Date} date the date that we will substract days from
|
||||
* @param {number} daysInPast number of days that are subtracted from a given date
|
||||
* @returns {String} Date string in ISO format
|
||||
* @returns {Date} Date in past as Date object
|
||||
*/
|
||||
export const getDateInPast = (date, daysInPast) => {
|
||||
const dateClone = newDate(date);
|
||||
return new Date(
|
||||
dateClone.setTime(dateClone.getTime() - daysInPast * 24 * 60 * 60 * 1000),
|
||||
).toISOString();
|
||||
};
|
||||
export const getDateInPast = (date, daysInPast) =>
|
||||
new Date(newDate(date).setDate(date.getDate() - daysInPast));
|
||||
|
||||
export const beginOfDayTime = 'T00:00:00Z';
|
||||
export const endOfDayTime = 'T23:59:59Z';
|
||||
|
|
|
@ -7,7 +7,7 @@ import { s__, __ } from '../../locale';
|
|||
|
||||
const MAX_REQUESTS = 3;
|
||||
|
||||
function backOffRequest(makeRequestCallback) {
|
||||
export function backOffRequest(makeRequestCallback) {
|
||||
let requestCounter = 0;
|
||||
return backOff((next, stop) => {
|
||||
makeRequestCallback()
|
||||
|
@ -111,8 +111,7 @@ export const fetchDashboard = ({ state, dispatch }, params) => {
|
|||
params.dashboard = state.currentDashboard;
|
||||
}
|
||||
|
||||
return axios
|
||||
.get(state.dashboardEndpoint, { params })
|
||||
return backOffRequest(() => axios.get(state.dashboardEndpoint, { params }))
|
||||
.then(resp => resp.data)
|
||||
.then(response => {
|
||||
dispatch('receiveMetricsDashboardSuccess', { response, params });
|
||||
|
|
|
@ -18,12 +18,6 @@ class ApplicationSetting < ApplicationRecord
|
|||
# fix a lot of tests using allow_any_instance_of
|
||||
include ApplicationSettingImplementation
|
||||
|
||||
attr_encrypted :asset_proxy_secret_key,
|
||||
mode: :per_attribute_iv,
|
||||
insecure_mode: true,
|
||||
key: Settings.attr_encrypted_db_key_base_truncated,
|
||||
algorithm: 'aes-256-cbc'
|
||||
|
||||
serialize :restricted_visibility_levels # rubocop:disable Cop/ActiveRecordSerialize
|
||||
serialize :import_sources # rubocop:disable Cop/ActiveRecordSerialize
|
||||
serialize :disabled_oauth_sign_in_sources, Array # rubocop:disable Cop/ActiveRecordSerialize
|
||||
|
@ -286,6 +280,12 @@ class ApplicationSetting < ApplicationRecord
|
|||
pass: :external_auth_client_key_pass,
|
||||
if: -> (setting) { setting.external_auth_client_cert.present? }
|
||||
|
||||
attr_encrypted :asset_proxy_secret_key,
|
||||
mode: :per_attribute_iv,
|
||||
key: Settings.attr_encrypted_db_key_base_truncated,
|
||||
algorithm: 'aes-256-cbc',
|
||||
insecure_mode: true
|
||||
|
||||
attr_encrypted :external_auth_client_key,
|
||||
mode: :per_attribute_iv,
|
||||
key: Settings.attr_encrypted_db_key_base_truncated,
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Change return type of getDateInPast to Date
|
||||
merge_request: 19081
|
||||
author:
|
||||
type: changed
|
|
@ -83,7 +83,7 @@ Therefore "create a new user" would translate into "Benutzer(in) anlegen".
|
|||
### Updating the glossary
|
||||
|
||||
To propose additions to the glossary please
|
||||
[open an issue](https://gitlab.com/gitlab-org/gitlab-foss/issues).
|
||||
[open an issue](https://gitlab.com/gitlab-org/gitlab/issues?scope=all&utf8=✓&state=all&label_name[]=Category%3AInternationalization).
|
||||
|
||||
## French Translation Guidelines
|
||||
|
||||
|
|
|
@ -30,21 +30,68 @@ The following table describes the version types and their release cadence:
|
|||
|
||||
## Patch releases
|
||||
|
||||
Patch releases usually only include bug fixes and are only done for the current
|
||||
stable release. That said, in some cases, we may backport it to previous stable
|
||||
Our current policy is to support **only the current stable release** at any given time.
|
||||
|
||||
Patch releases **only include bug fixes** for the current stable released version of
|
||||
GitLab.
|
||||
|
||||
These two policies are in place because:
|
||||
|
||||
1. GitLab has Community and Enterprise distributions, doubling the amount of work
|
||||
necessary to test/release the software.
|
||||
1. Backporting to more than one release creates a high development, quality assurance,
|
||||
and support cost.
|
||||
1. Supporting parallel version discourages incremental upgrades which over time accumulate in
|
||||
complexity and create upgrade challenges for all users. GitLab has a dedicated team ensuring that
|
||||
incremental upgrades (and installations) are as simple as possible.
|
||||
1. The number of changes created in the GitLab application is high, which contributes to backporting complexity to older releases. In number of cases, backporting has to go through the same
|
||||
review process a new change goes through.
|
||||
1. Ensuring that tests pass on older release is a considerable challenge in some cases, and as such is very time consuming.
|
||||
|
||||
Including new features in patch releases is not possible as that would break [Semantic Versioning].
|
||||
Breaking [Semantic Versioning] has the following consequences for users that
|
||||
have to adhere to various internal requirements (e.g. org. compliance, verifying new features and similar):
|
||||
|
||||
1. Inability to quickly upgrade to leverage bug fixes included in patch versions.
|
||||
1. Inability to quickly upgrade to leverage security fixes included in patch versions.
|
||||
1. Requirements consisting of extensive testing for not only stable GitLab release, but every patch version.
|
||||
|
||||
In cases where a strategic user has a requirement to test a feature before it is
|
||||
officially released, we can offer to create a Release Candidate (RC) version that will
|
||||
include the specific feature. This should be needed only in extreme cases, and can be requested for consideration by raising an issue in [release/tasks] issue tracker.
|
||||
It is important to note that the Release Candidate will also contain other
|
||||
features and changes as it is not possible to easily isolate a specific feature (similar reasons as noted above). The Release Candidate will be no different than any code that is deployed to GitLab.com or is publicly accessible.
|
||||
|
||||
### Backporting to older releases
|
||||
|
||||
Backporting to more than one stable release is reserved for [security releases](#security-releases).
|
||||
In some cases however, we may need to backport *a bug fix* to more than one stable
|
||||
release, depending on the severity of the bug.
|
||||
|
||||
For instance, if we release `10.1.1` with a fix for a severe bug introduced in
|
||||
`10.0.0`, we could backport the fix to a new `10.0.x` patch release.
|
||||
Decision on whether backporting a change will be performed is done at the discretion of the [current release managers][release-managers], similar to what is described in the [managing bugs] process, based on *all* of the following:
|
||||
|
||||
1. Estimated [severity][severity-labels] of the bug: Highest possible impact to users based on the current definition of severity.
|
||||
|
||||
1. Estimated [priority][priority-labels] of the bug: Immediate impact on all impacted users based on the above estimated severity.
|
||||
|
||||
1. Potentially incurring data loss and/or security breach.
|
||||
|
||||
1. Potentially affecting one or more strategic accounts due to a proven inability by the user to upgrade to the current stable version.
|
||||
|
||||
If *all* of the above are satisfied, the backport releases can be created for
|
||||
the current stable stable release, and two previous monthly releases.
|
||||
For instance, if we release `11.2.1` with a fix for a severe bug introduced in
|
||||
`11.0.0`, we could backport the fix to a new `11.0.x`, and `11.1.x` patch release.
|
||||
|
||||
To request backporting to more than one stable release for consideration, raise an issue in [release/tasks] issue tracker.
|
||||
|
||||
### Security releases
|
||||
|
||||
Security releases are a special kind of patch release that only include security
|
||||
fixes and patches (see below).
|
||||
|
||||
Our current policy is to support one stable release at any given time, but for
|
||||
medium-level security issues, we may backport security fixes to the previous two
|
||||
monthly releases.
|
||||
Our current policy is to backport security fixes to the previous two
|
||||
monthly releases in addition to the current stable release.
|
||||
|
||||
For very serious security issues, there is
|
||||
[precedent](https://about.gitlab.com/blog/2016/05/02/cve-2016-4340-patches/)
|
||||
|
@ -91,3 +138,9 @@ Please see the table below for some examples:
|
|||
More information about the release procedures can be found in our
|
||||
[release documentation](https://gitlab.com/gitlab-org/release/docs). You may also want to read our
|
||||
[Responsible Disclosure Policy](https://about.gitlab.com/security/disclosure/).
|
||||
|
||||
[release-managers]: https://about.gitlab.com/community/release-managers/
|
||||
[priority-definition]: ../development/contributing/issue_workflow.md#priority-labels
|
||||
[severity-labels]: ../development/contributing/issue_workflow.html#severity-labels
|
||||
[managing bugs]: https://gitlab.com/gitlab-org/gitlab/blob/master/PROCESS.md#managing-bugs
|
||||
[release/tasks]: https://gitlab.com/gitlab-org/release/tasks/issues
|
||||
|
|
|
@ -139,7 +139,7 @@ GitLab supports a limited set of [CI variables](../../../ci/variables/README.htm
|
|||
- CI_ENVIRONMENT_SLUG
|
||||
- KUBE_NAMESPACE
|
||||
|
||||
To specify a variable in a query, enclose it in curly braces with a leading percent. For example: `%{ci_environment_slug}`.
|
||||
To specify a variable in a query, enclose it in quotation marks with curly braces with a leading percent. For example: `"%{ci_environment_slug}"`.
|
||||
|
||||
### Defining custom dashboards per project
|
||||
|
||||
|
|
|
@ -28,6 +28,10 @@ module Gitlab
|
|||
true
|
||||
end
|
||||
|
||||
def thread_name
|
||||
self.class.name.demodulize.underscore
|
||||
end
|
||||
|
||||
def start
|
||||
return unless enabled?
|
||||
|
||||
|
@ -35,7 +39,10 @@ module Gitlab
|
|||
break thread if thread?
|
||||
|
||||
if start_working
|
||||
@thread = Thread.new { run_thread }
|
||||
@thread = Thread.new do
|
||||
Thread.current.name = thread_name
|
||||
run_thread
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,6 +4,7 @@ module Gitlab
|
|||
module SidekiqDaemon
|
||||
class Monitor < Daemon
|
||||
include ::Gitlab::Utils::StrongMemoize
|
||||
extend ::Gitlab::Utils::Override
|
||||
|
||||
NOTIFICATION_CHANNEL = 'sidekiq:cancel:notifications'
|
||||
CANCEL_DEADLINE = 24.hours.seconds
|
||||
|
@ -24,6 +25,11 @@ module Gitlab
|
|||
@jobs_mutex = Mutex.new
|
||||
end
|
||||
|
||||
override :thread_name
|
||||
def thread_name
|
||||
"job_monitor"
|
||||
end
|
||||
|
||||
def within_job(worker_class, jid, queue)
|
||||
jobs_mutex.synchronize do
|
||||
jobs[jid] = { worker_class: worker_class, thread: Thread.current, started_at: Gitlab::Metrics::System.monotonic_time }
|
||||
|
|
|
@ -41,5 +41,76 @@ describe('monitor helper', () => {
|
|||
),
|
||||
).toEqual([{ ...expectedDataSeries[0], data: [[1, 1]] }]);
|
||||
});
|
||||
|
||||
it('updates series name from templates', () => {
|
||||
const config = {
|
||||
...defaultConfig,
|
||||
name: '{{cmd}}',
|
||||
};
|
||||
|
||||
const [result] = monitorHelper.makeDataSeries(
|
||||
[{ metric: { cmd: 'brpop' }, values: series }],
|
||||
config,
|
||||
);
|
||||
|
||||
expect(result.name).toEqual('brpop');
|
||||
});
|
||||
|
||||
it('supports space-padded template expressions', () => {
|
||||
const config = {
|
||||
...defaultConfig,
|
||||
name: 'backend: {{ backend }}',
|
||||
};
|
||||
|
||||
const [result] = monitorHelper.makeDataSeries(
|
||||
[{ metric: { backend: 'HA Server' }, values: series }],
|
||||
config,
|
||||
);
|
||||
|
||||
expect(result.name).toEqual('backend: HA Server');
|
||||
});
|
||||
|
||||
it('supports repeated template variables', () => {
|
||||
const config = { ...defaultConfig, name: '{{cmd}}, {{cmd}}' };
|
||||
|
||||
const [result] = monitorHelper.makeDataSeries(
|
||||
[{ metric: { cmd: 'brpop' }, values: series }],
|
||||
config,
|
||||
);
|
||||
|
||||
expect(result.name).toEqual('brpop, brpop');
|
||||
});
|
||||
|
||||
it('updates multiple series names from templates', () => {
|
||||
const config = {
|
||||
...defaultConfig,
|
||||
name: '{{job}}: {{cmd}}',
|
||||
};
|
||||
|
||||
const [result] = monitorHelper.makeDataSeries(
|
||||
[{ metric: { cmd: 'brpop', job: 'redis' }, values: series }],
|
||||
config,
|
||||
);
|
||||
|
||||
expect(result.name).toEqual('redis: brpop');
|
||||
});
|
||||
|
||||
it('updates name for each series', () => {
|
||||
const config = {
|
||||
...defaultConfig,
|
||||
name: '{{cmd}}',
|
||||
};
|
||||
|
||||
const [firstSeries, secondSeries] = monitorHelper.makeDataSeries(
|
||||
[
|
||||
{ metric: { cmd: 'brpop' }, values: series },
|
||||
{ metric: { cmd: 'zrangebyscore' }, values: series },
|
||||
],
|
||||
config,
|
||||
);
|
||||
|
||||
expect(firstSeries.name).toEqual('brpop');
|
||||
expect(secondSeries.name).toEqual('zrangebyscore');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -428,17 +428,19 @@ describe('newDate', () => {
|
|||
});
|
||||
|
||||
describe('getDateInPast', () => {
|
||||
const date = new Date(1563235200000); // 2019-07-16T00:00:00.000Z;
|
||||
const date = new Date('2019-07-16T00:00:00.000Z');
|
||||
const daysInPast = 90;
|
||||
|
||||
it('returns the correct date in the past', () => {
|
||||
const dateInPast = datetimeUtility.getDateInPast(date, daysInPast);
|
||||
expect(dateInPast).toBe('2019-04-17T00:00:00.000Z');
|
||||
const expectedDateInPast = new Date('2019-04-17T00:00:00.000Z');
|
||||
|
||||
expect(dateInPast).toStrictEqual(expectedDateInPast);
|
||||
});
|
||||
|
||||
it('does not modifiy the original date', () => {
|
||||
datetimeUtility.getDateInPast(date, daysInPast);
|
||||
expect(date).toStrictEqual(new Date(1563235200000));
|
||||
expect(date).toStrictEqual(new Date('2019-07-16T00:00:00.000Z'));
|
||||
});
|
||||
});
|
||||
|
||||
|
|
53
spec/frontend/monitoring/store/actions_spec.js
Normal file
53
spec/frontend/monitoring/store/actions_spec.js
Normal file
|
@ -0,0 +1,53 @@
|
|||
import axios from '~/lib/utils/axios_utils';
|
||||
import MockAdapter from 'axios-mock-adapter';
|
||||
import { TEST_HOST } from 'helpers/test_constants';
|
||||
import { backOffRequest } from '~/monitoring/stores/actions';
|
||||
import statusCodes from '~/lib/utils/http_status';
|
||||
import { backOff } from '~/lib/utils/common_utils';
|
||||
|
||||
jest.mock('~/lib/utils/common_utils');
|
||||
|
||||
const MAX_REQUESTS = 3;
|
||||
|
||||
describe('Monitoring store helpers', () => {
|
||||
let mock;
|
||||
|
||||
// Mock underlying `backOff` function to remove in-built delay.
|
||||
backOff.mockImplementation(
|
||||
callback =>
|
||||
new Promise((resolve, reject) => {
|
||||
const stop = arg => (arg instanceof Error ? reject(arg) : resolve(arg));
|
||||
const next = () => callback(next, stop);
|
||||
callback(next, stop);
|
||||
}),
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
mock = new MockAdapter(axios);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
mock.restore();
|
||||
});
|
||||
|
||||
describe('backOffRequest', () => {
|
||||
it('returns immediately when recieving a 200 status code', () => {
|
||||
mock.onGet(TEST_HOST).reply(200);
|
||||
|
||||
return backOffRequest(() => axios.get(TEST_HOST)).then(() => {
|
||||
expect(mock.history.get.length).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
it(`repeats the network call ${MAX_REQUESTS} times when receiving a 204 response`, done => {
|
||||
mock.onGet(TEST_HOST).reply(statusCodes.NO_CONTENT, {});
|
||||
|
||||
backOffRequest(() => axios.get(TEST_HOST))
|
||||
.then(done.fail)
|
||||
.catch(() => {
|
||||
expect(mock.history.get.length).toBe(MAX_REQUESTS);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,332 +0,0 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Release block with default props matches the snapshot 1`] = `
|
||||
<div
|
||||
class="card release-block"
|
||||
id="v0.3"
|
||||
>
|
||||
<div
|
||||
class="card-body"
|
||||
>
|
||||
<div
|
||||
class="d-flex align-items-start"
|
||||
>
|
||||
<h2
|
||||
class="card-title mt-0 mr-auto"
|
||||
>
|
||||
|
||||
New release
|
||||
|
||||
<!---->
|
||||
</h2>
|
||||
|
||||
<a
|
||||
class="btn btn-default js-edit-button ml-2"
|
||||
data-original-title="Edit this release"
|
||||
href="http://0.0.0.0:3001/root/release-test/-/releases/v0.3/edit"
|
||||
title=""
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="s16 ic-pencil"
|
||||
>
|
||||
<use
|
||||
xlink:href="#pencil"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="card-subtitle d-flex flex-wrap text-secondary"
|
||||
>
|
||||
<div
|
||||
class="append-right-8"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="align-middle s16 ic-commit"
|
||||
>
|
||||
<use
|
||||
xlink:href="#commit"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
<span
|
||||
data-original-title="Initial commit"
|
||||
title=""
|
||||
>
|
||||
c22b0728
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="append-right-8"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="align-middle s16 ic-tag"
|
||||
>
|
||||
<use
|
||||
xlink:href="#tag"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
<span
|
||||
data-original-title="Tag"
|
||||
title=""
|
||||
>
|
||||
v0.3
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="js-milestone-list-label"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="align-middle s16 ic-flag"
|
||||
>
|
||||
<use
|
||||
xlink:href="#flag"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
<span
|
||||
class="js-label-text"
|
||||
>
|
||||
Milestones
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<a
|
||||
class="append-right-4 prepend-left-4 js-milestone-link"
|
||||
data-original-title="The 13.6 milestone!"
|
||||
href="http://0.0.0.0:3001/root/release-test/-/milestones/2"
|
||||
title=""
|
||||
>
|
||||
|
||||
13.6
|
||||
|
||||
</a>
|
||||
|
||||
•
|
||||
|
||||
<a
|
||||
class="append-right-4 prepend-left-4 js-milestone-link"
|
||||
data-original-title="The 13.5 milestone!"
|
||||
href="http://0.0.0.0:3001/root/release-test/-/milestones/1"
|
||||
title=""
|
||||
>
|
||||
|
||||
13.5
|
||||
|
||||
</a>
|
||||
|
||||
<!---->
|
||||
|
||||
<div
|
||||
class="append-right-4"
|
||||
>
|
||||
|
||||
•
|
||||
|
||||
<span
|
||||
data-original-title="Aug 26, 2019 5:54pm GMT+0000"
|
||||
title=""
|
||||
>
|
||||
|
||||
released 1 month ago
|
||||
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
|
||||
by
|
||||
|
||||
<a
|
||||
class="user-avatar-link prepend-left-4"
|
||||
href=""
|
||||
>
|
||||
<span>
|
||||
<img
|
||||
alt="root's avatar"
|
||||
class="avatar s20 "
|
||||
data-original-title=""
|
||||
data-src="https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon"
|
||||
height="20"
|
||||
src="https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon"
|
||||
title=""
|
||||
width="20"
|
||||
/>
|
||||
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="js-user-avatar-image-toolip d-none"
|
||||
style="display: none;"
|
||||
>
|
||||
<div>
|
||||
root
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
<!---->
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="card-text prepend-top-default"
|
||||
>
|
||||
<b>
|
||||
|
||||
Assets
|
||||
|
||||
<span
|
||||
class="js-assets-count badge badge-pill"
|
||||
>
|
||||
5
|
||||
</span>
|
||||
</b>
|
||||
|
||||
<ul
|
||||
class="pl-0 mb-0 prepend-top-8 list-unstyled js-assets-list"
|
||||
>
|
||||
<li
|
||||
class="append-bottom-8"
|
||||
>
|
||||
<a
|
||||
class=""
|
||||
data-original-title="Download asset"
|
||||
href="https://google.com"
|
||||
title=""
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="align-middle append-right-4 align-text-bottom s16 ic-package"
|
||||
>
|
||||
<use
|
||||
xlink:href="#package"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
my link
|
||||
|
||||
<span>
|
||||
(external source)
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li
|
||||
class="append-bottom-8"
|
||||
>
|
||||
<a
|
||||
class=""
|
||||
data-original-title="Download asset"
|
||||
href="https://gitlab.com/gitlab-org/gitlab-foss/-/jobs/artifacts/v11.6.0-rc4/download?job=rspec-mysql+41%2F50"
|
||||
title=""
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="align-middle append-right-4 align-text-bottom s16 ic-package"
|
||||
>
|
||||
<use
|
||||
xlink:href="#package"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
my second link
|
||||
|
||||
<!---->
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div
|
||||
class="dropdown"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
class="btn btn-link"
|
||||
data-toggle="dropdown"
|
||||
type="button"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="align-top append-right-4 s16 ic-doc-code"
|
||||
>
|
||||
<use
|
||||
xlink:href="#doc-code"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
Source code
|
||||
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="s16 ic-arrow-down"
|
||||
>
|
||||
<use
|
||||
xlink:href="#arrow-down"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<div
|
||||
class="js-sources-dropdown dropdown-menu"
|
||||
>
|
||||
<li>
|
||||
<a
|
||||
class=""
|
||||
href="http://0.0.0.0:3001/root/release-test/-/archive/v0.3/release-test-v0.3.zip"
|
||||
>
|
||||
Download zip
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class=""
|
||||
href="http://0.0.0.0:3001/root/release-test/-/archive/v0.3/release-test-v0.3.tar.gz"
|
||||
>
|
||||
Download tar.gz
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class=""
|
||||
href="http://0.0.0.0:3001/root/release-test/-/archive/v0.3/release-test-v0.3.tar.bz2"
|
||||
>
|
||||
Download tar.bz2
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class=""
|
||||
href="http://0.0.0.0:3001/root/release-test/-/archive/v0.3/release-test-v0.3.tar"
|
||||
>
|
||||
Download tar
|
||||
</a>
|
||||
</li>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="card-text prepend-top-default"
|
||||
>
|
||||
<div>
|
||||
<p
|
||||
data-sourcepos="1:1-1:21"
|
||||
dir="auto"
|
||||
>
|
||||
A super nice release!
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
|
@ -39,34 +39,18 @@ describe('Release block', () => {
|
|||
|
||||
const milestoneListLabel = () => wrapper.find('.js-milestone-list-label');
|
||||
const editButton = () => wrapper.find('.js-edit-button');
|
||||
const RealDate = Date;
|
||||
|
||||
beforeEach(() => {
|
||||
// timeago.js calls Date(), so let's mock that case to avoid time-dependent test failures.
|
||||
const constantDate = new Date('2019-10-25T00:12:00');
|
||||
|
||||
/* eslint no-global-assign:off */
|
||||
global.Date = jest.fn((...props) =>
|
||||
props.length ? new RealDate(...props) : new RealDate(constantDate),
|
||||
);
|
||||
|
||||
Object.assign(Date, RealDate);
|
||||
|
||||
releaseClone = JSON.parse(JSON.stringify(release));
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
wrapper.destroy();
|
||||
global.Date = RealDate;
|
||||
});
|
||||
|
||||
describe('with default props', () => {
|
||||
beforeEach(() => factory(release));
|
||||
|
||||
it('matches the snapshot', () => {
|
||||
expect(wrapper.element).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("renders the block with an id equal to the release's tag name", () => {
|
||||
expect(wrapper.attributes().id).toBe('v0.3');
|
||||
});
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe Banzai::Filter::AssetProxyFilter do
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe OmniAuth::Strategies::SAML, type: :strategy do
|
||||
|
|
Loading…
Reference in a new issue