Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
cfaf98a3b2
commit
0b81231d2d
20 changed files with 148 additions and 171 deletions
|
@ -1,5 +1,5 @@
|
|||
<script>
|
||||
import { GlButton, GlIcon, GlLoadingIcon, GlTooltipDirective } from '@gitlab/ui';
|
||||
import { GlDropdown, GlDropdownItem, GlIcon, GlLoadingIcon, GlTooltipDirective } from '@gitlab/ui';
|
||||
import { __, s__, sprintf } from '~/locale';
|
||||
import { formatTime } from '~/lib/utils/datetime_utility';
|
||||
import eventHub from '../event_hub';
|
||||
|
@ -9,7 +9,8 @@ export default {
|
|||
GlTooltip: GlTooltipDirective,
|
||||
},
|
||||
components: {
|
||||
GlButton,
|
||||
GlDropdown,
|
||||
GlDropdownItem,
|
||||
GlIcon,
|
||||
GlLoadingIcon,
|
||||
},
|
||||
|
@ -35,7 +36,7 @@ export default {
|
|||
if (action.scheduledAt) {
|
||||
const confirmationMessage = sprintf(
|
||||
s__(
|
||||
"DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after it's timer finishes.",
|
||||
'DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes.',
|
||||
),
|
||||
{ jobName: action.name },
|
||||
);
|
||||
|
@ -67,40 +68,32 @@ export default {
|
|||
};
|
||||
</script>
|
||||
<template>
|
||||
<div class="btn-group" role="group">
|
||||
<gl-button
|
||||
v-gl-tooltip
|
||||
:title="title"
|
||||
:aria-label="title"
|
||||
:disabled="isLoading"
|
||||
class="dropdown dropdown-new js-environment-actions-dropdown"
|
||||
data-container="body"
|
||||
data-toggle="dropdown"
|
||||
data-testid="environment-actions-button"
|
||||
<gl-dropdown
|
||||
v-gl-tooltip
|
||||
:title="title"
|
||||
:aria-label="title"
|
||||
:disabled="isLoading"
|
||||
right
|
||||
data-container="body"
|
||||
data-testid="environment-actions-button"
|
||||
>
|
||||
<template #button-content>
|
||||
<gl-icon name="play" />
|
||||
<gl-icon name="chevron-down" />
|
||||
<gl-loading-icon v-if="isLoading" />
|
||||
</template>
|
||||
<gl-dropdown-item
|
||||
v-for="(action, i) in actions"
|
||||
:key="i"
|
||||
:disabled="isActionDisabled(action)"
|
||||
data-testid="manual-action-link"
|
||||
@click="onClickAction(action)"
|
||||
>
|
||||
<span>
|
||||
<gl-icon name="play" />
|
||||
<gl-icon name="chevron-down" />
|
||||
<gl-loading-icon v-if="isLoading" />
|
||||
<span class="gl-flex-fill-1">{{ action.name }}</span>
|
||||
<span v-if="action.scheduledAt" class="gl-text-gray-500 float-right">
|
||||
<gl-icon name="clock" />
|
||||
{{ remainingTime(action) }}
|
||||
</span>
|
||||
</gl-button>
|
||||
|
||||
<ul class="dropdown-menu dropdown-menu-right">
|
||||
<li v-for="(action, i) in actions" :key="i" class="gl-display-flex">
|
||||
<gl-button
|
||||
:class="{ disabled: isActionDisabled(action) }"
|
||||
:disabled="isActionDisabled(action)"
|
||||
variant="link"
|
||||
class="js-manual-action-link gl-flex-fill-1"
|
||||
@click="onClickAction(action)"
|
||||
>
|
||||
<span class="gl-flex-fill-1">{{ action.name }}</span>
|
||||
<span v-if="action.scheduledAt" class="text-secondary float-right">
|
||||
<gl-icon name="clock" />
|
||||
{{ remainingTime(action) }}
|
||||
</span>
|
||||
</gl-button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</gl-dropdown-item>
|
||||
</gl-dropdown>
|
||||
</template>
|
||||
|
|
|
@ -32,7 +32,7 @@ export default {
|
|||
if (action.scheduled_at) {
|
||||
const confirmationMessage = sprintf(
|
||||
s__(
|
||||
"DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after it's timer finishes.",
|
||||
'DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes.',
|
||||
),
|
||||
{ jobName: action.name },
|
||||
);
|
||||
|
|
|
@ -206,7 +206,7 @@ module Ci
|
|||
|
||||
override :dependency_variables
|
||||
def dependency_variables
|
||||
return [] unless ::Feature.enabled?(:ci_bridge_dependency_variables, project)
|
||||
return [] unless ::Feature.enabled?(:ci_bridge_dependency_variables, project, default_enabled: true)
|
||||
|
||||
super
|
||||
end
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Implement passing dotenv variables to bridge jobs
|
||||
merge_request: 47905
|
||||
author:
|
||||
type: fixed
|
|
@ -4,4 +4,4 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46530
|
|||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/273734
|
||||
type: development
|
||||
group: group::pipeline authoring
|
||||
default_enabled: false
|
||||
default_enabled: true
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: codequality_mr_diff
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/47938
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/284140
|
||||
milestone: '13.7'
|
||||
type: development
|
||||
group: group::testing
|
||||
default_enabled: false
|
|
@ -529,12 +529,18 @@ To disable Gitaly on a GitLab server:
|
|||
|
||||
## Enable TLS support
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/22602) in GitLab 11.8.
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/22602) in GitLab 11.8.
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitaly/-/issues/3160) in GitLab 13.6, outgoing TLS connections to GitLab provide client certificates if configured.
|
||||
|
||||
Gitaly supports TLS encryption. To communicate with a Gitaly instance that listens for secure
|
||||
connections, you must use `tls://` URL scheme in the `gitaly_address` of the corresponding
|
||||
storage entry in the GitLab configuration.
|
||||
|
||||
Gitaly provides the same server certificates as client certificates in TLS
|
||||
connections to GitLab. This can be used as part of a mutual TLS authentication strategy
|
||||
when combined with reverse proxies (for example, NGINX) that validate client certificate
|
||||
to grant access to GitLab.
|
||||
|
||||
You must supply your own certificates as this isn't provided automatically. The certificate
|
||||
corresponding to each Gitaly server must be installed on that Gitaly server.
|
||||
|
||||
|
|
|
@ -63,8 +63,6 @@ job finishes but the DAST job fails, the security dashboard doesn't show SAST re
|
|||
the analyzer outputs an
|
||||
[exit code](../../../development/integrations/secure.md#exit-code).
|
||||
|
||||
You can filter the vulnerabilities list by selecting from the **Severity** and **Scanner** dropdowns.
|
||||
|
||||
## Project Security Dashboard
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/235558) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.6.
|
||||
|
@ -107,11 +105,6 @@ You can filter the vulnerabilities by one or more of the following:
|
|||
| Severity | Critical, High, Medium, Low, Info, Unknown |
|
||||
| Scanner | [Available Scanners](../index.md#security-scanning-tools) |
|
||||
|
||||
You can filter the vulnerabilities list by selecting from the **Status**, **Severity**, and
|
||||
**Scanner** dropdowns. In the **Scanner** dropdown, select individual scanners or scanner groups to
|
||||
toggle those scanners. The **Scanner** dropdown includes both GitLab scanners, and in GitLab 13.6
|
||||
and later, custom scanners.
|
||||
|
||||
You can also dismiss vulnerabilities in the table:
|
||||
|
||||
1. Select the checkbox for each vulnerability you want to dismiss.
|
||||
|
@ -267,11 +260,6 @@ You can filter which vulnerabilities the vulnerability report displays by:
|
|||
| Scanner | [Available Scanners](../index.md#security-scanning-tools) |
|
||||
| Project | Projects configured in the Security Center settings |
|
||||
|
||||
You can filter the vulnerabilities list by selecting from the **Status**, **Severity**, and
|
||||
**Scanner**, and **Project** dropdowns. In the **Scanner** dropdown, select individual scanners or
|
||||
scanner groups to toggle those scanners. The **Scanner** dropdown includes both GitLab scanners, and
|
||||
in GitLab 13.6 and later, custom scanners.
|
||||
|
||||
Clicking any vulnerability in the table takes you to its
|
||||
[Vulnerability Details](../vulnerabilities) page to see more information on that vulnerability.
|
||||
To create an issue associated with the vulnerability, click the **Create Issue** button.
|
||||
|
|
|
@ -7710,9 +7710,6 @@ msgstr ""
|
|||
msgid "Could not restore the group"
|
||||
msgstr ""
|
||||
|
||||
msgid "Could not retrieve custom scanners for scanner filter. Please try again later."
|
||||
msgstr ""
|
||||
|
||||
msgid "Could not revoke impersonation token %{token_name}."
|
||||
msgstr ""
|
||||
|
||||
|
@ -8749,7 +8746,7 @@ msgstr ""
|
|||
msgid "Delayed Project Deletion (%{adjourned_deletion})"
|
||||
msgstr ""
|
||||
|
||||
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after it's timer finishes."
|
||||
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
|
||||
msgstr ""
|
||||
|
||||
msgid "DelayedJobs|Are you sure you want to run %{job_name} immediately? This job will run automatically after it's timer finishes."
|
||||
|
|
|
@ -15,16 +15,6 @@ RSpec.describe DashboardController do
|
|||
describe 'GET issues' do
|
||||
it_behaves_like 'issuables list meta-data', :issue, :issues
|
||||
it_behaves_like 'issuables requiring filter', :issues
|
||||
|
||||
it 'lists only incidents and issues' do
|
||||
issue = create(:incident, project: project, author: user)
|
||||
incident = create(:incident, project: project, author: user)
|
||||
create(:quality_test_case, project: project, author: user)
|
||||
|
||||
get :issues, params: { author_id: user.id }
|
||||
|
||||
expect(assigns(:issues)).to match_array([issue, incident])
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET merge requests' do
|
||||
|
|
|
@ -400,15 +400,6 @@ RSpec.describe GroupsController, factory_default: :keep do
|
|||
sign_in(user)
|
||||
end
|
||||
|
||||
it 'lists only incidents and issues' do
|
||||
incident = create(:incident, project: project)
|
||||
create(:quality_test_case, project: project)
|
||||
|
||||
get :issues, params: { id: group.to_param }
|
||||
|
||||
expect(assigns(:issues)).to match_array([issue_1, issue_2, incident])
|
||||
end
|
||||
|
||||
context 'sorting by votes' do
|
||||
it 'sorts most popular issues' do
|
||||
get :issues, params: { id: group.to_param, sort: 'upvotes_desc' }
|
||||
|
|
|
@ -52,9 +52,5 @@ FactoryBot.define do
|
|||
factory :incident do
|
||||
issue_type { :incident }
|
||||
end
|
||||
|
||||
factory :quality_test_case do
|
||||
issue_type { :test_case }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,8 +12,16 @@ RSpec.describe 'Environments page', :js do
|
|||
sign_in(user)
|
||||
end
|
||||
|
||||
def actions_button_selector
|
||||
'[data-testid="environment-actions-button"]'
|
||||
end
|
||||
|
||||
def action_link_selector
|
||||
'[data-testid="manual-action-link"]'
|
||||
end
|
||||
|
||||
def stop_button_selector
|
||||
%q{button[title="Stop environment"]}
|
||||
'button[title="Stop environment"]'
|
||||
end
|
||||
|
||||
describe 'page tabs' do
|
||||
|
@ -187,18 +195,17 @@ RSpec.describe 'Environments page', :js do
|
|||
end
|
||||
|
||||
it 'shows a play button' do
|
||||
find('.js-environment-actions-dropdown').click
|
||||
|
||||
find(actions_button_selector).click
|
||||
expect(page).to have_content(action.name)
|
||||
end
|
||||
|
||||
it 'allows to play a manual action', :js do
|
||||
expect(action).to be_manual
|
||||
|
||||
find('.js-environment-actions-dropdown').click
|
||||
find(actions_button_selector).click
|
||||
expect(page).to have_content(action.name)
|
||||
|
||||
expect { find('.js-manual-action-link').click }
|
||||
expect { find(action_link_selector).click }
|
||||
.not_to change { Ci::Pipeline.count }
|
||||
end
|
||||
|
||||
|
@ -301,11 +308,11 @@ RSpec.describe 'Environments page', :js do
|
|||
end
|
||||
|
||||
it 'has a dropdown for actionable jobs' do
|
||||
expect(page).to have_selector('.dropdown-new.btn.btn-default [data-testid="play-icon"]')
|
||||
expect(page).to have_selector("#{actions_button_selector} [data-testid=\"play-icon\"]")
|
||||
end
|
||||
|
||||
it "has link to the delayed job's action" do
|
||||
find('.js-environment-actions-dropdown').click
|
||||
find(actions_button_selector).click
|
||||
|
||||
expect(page).to have_button('delayed job')
|
||||
expect(page).to have_content(/\d{2}:\d{2}:\d{2}/)
|
||||
|
@ -320,7 +327,7 @@ RSpec.describe 'Environments page', :js do
|
|||
end
|
||||
|
||||
it "shows 00:00:00 as the remaining time" do
|
||||
find('.js-environment-actions-dropdown').click
|
||||
find(actions_button_selector).click
|
||||
|
||||
expect(page).to have_content("00:00:00")
|
||||
end
|
||||
|
@ -328,8 +335,8 @@ RSpec.describe 'Environments page', :js do
|
|||
|
||||
context 'when user played a delayed job immediately' do
|
||||
before do
|
||||
find('.js-environment-actions-dropdown').click
|
||||
page.accept_confirm { click_button('delayed job') }
|
||||
find(actions_button_selector).click
|
||||
accept_confirm { find(action_link_selector).click }
|
||||
wait_for_requests
|
||||
end
|
||||
|
||||
|
|
|
@ -1,51 +1,69 @@
|
|||
import { shallowMount } from '@vue/test-utils';
|
||||
import { shallowMount, mount } from '@vue/test-utils';
|
||||
import { TEST_HOST } from 'helpers/test_constants';
|
||||
import { GlLoadingIcon, GlIcon } from '@gitlab/ui';
|
||||
import { GlDropdown, GlDropdownItem, GlLoadingIcon, GlIcon } from '@gitlab/ui';
|
||||
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
|
||||
import eventHub from '~/environments/event_hub';
|
||||
import EnvironmentActions from '~/environments/components/environment_actions.vue';
|
||||
|
||||
const scheduledJobAction = {
|
||||
name: 'scheduled action',
|
||||
playPath: `${TEST_HOST}/scheduled/job/action`,
|
||||
playable: true,
|
||||
scheduledAt: '2063-04-05T00:42:00Z',
|
||||
};
|
||||
|
||||
const expiredJobAction = {
|
||||
name: 'expired action',
|
||||
playPath: `${TEST_HOST}/expired/job/action`,
|
||||
playable: true,
|
||||
scheduledAt: '2018-10-05T08:23:00Z',
|
||||
};
|
||||
|
||||
describe('EnvironmentActions Component', () => {
|
||||
let vm;
|
||||
let wrapper;
|
||||
|
||||
const findEnvironmentActionsButton = () => vm.find('[data-testid="environment-actions-button"]');
|
||||
const findEnvironmentActionsButton = () =>
|
||||
wrapper.find('[data-testid="environment-actions-button"]');
|
||||
|
||||
beforeEach(() => {
|
||||
vm = shallowMount(EnvironmentActions, {
|
||||
propsData: { actions: [] },
|
||||
function createComponent(props, { mountFn = shallowMount } = {}) {
|
||||
wrapper = mountFn(EnvironmentActions, {
|
||||
propsData: { actions: [], ...props },
|
||||
directives: {
|
||||
GlTooltip: createMockDirective(),
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function createComponentWithScheduledJobs(opts = {}) {
|
||||
return createComponent({ actions: [scheduledJobAction, expiredJobAction] }, opts);
|
||||
}
|
||||
|
||||
const findDropdownItem = action => {
|
||||
const buttons = wrapper.findAll(GlDropdownItem);
|
||||
return buttons.filter(button => button.text().startsWith(action.name)).at(0);
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
vm.destroy();
|
||||
wrapper.destroy();
|
||||
wrapper = null;
|
||||
});
|
||||
|
||||
it('should render a dropdown button with 2 icons', () => {
|
||||
expect(vm.find('.dropdown-new').findAll(GlIcon).length).toBe(2);
|
||||
createComponent({}, { mountFn: mount });
|
||||
expect(wrapper.find(GlDropdown).findAll(GlIcon).length).toBe(2);
|
||||
});
|
||||
|
||||
it('should render a dropdown button with aria-label description', () => {
|
||||
expect(vm.find('.dropdown-new').attributes('aria-label')).toEqual('Deploy to...');
|
||||
createComponent();
|
||||
expect(wrapper.find(GlDropdown).attributes('aria-label')).toBe('Deploy to...');
|
||||
});
|
||||
|
||||
it('should render a tooltip', () => {
|
||||
createComponent();
|
||||
const tooltip = getBinding(findEnvironmentActionsButton().element, 'gl-tooltip');
|
||||
expect(tooltip).toBeDefined();
|
||||
});
|
||||
|
||||
describe('is loading', () => {
|
||||
beforeEach(() => {
|
||||
vm.setData({ isLoading: true });
|
||||
});
|
||||
|
||||
it('should render a dropdown button with a loading icon', () => {
|
||||
expect(vm.findAll(GlLoadingIcon).length).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('manual actions', () => {
|
||||
const actions = [
|
||||
{
|
||||
|
@ -64,68 +82,71 @@ describe('EnvironmentActions Component', () => {
|
|||
];
|
||||
|
||||
beforeEach(() => {
|
||||
vm.setProps({ actions });
|
||||
createComponent({ actions });
|
||||
});
|
||||
|
||||
it('should render a dropdown with the provided list of actions', () => {
|
||||
expect(vm.findAll('.dropdown-menu li').length).toEqual(actions.length);
|
||||
expect(wrapper.findAll(GlDropdownItem)).toHaveLength(actions.length);
|
||||
});
|
||||
|
||||
it("should render a disabled action when it's not playable", () => {
|
||||
expect(vm.find('.dropdown-menu li:last-child gl-button-stub').props('disabled')).toBe(true);
|
||||
const dropdownItems = wrapper.findAll(GlDropdownItem);
|
||||
const lastDropdownItem = dropdownItems.at(dropdownItems.length - 1);
|
||||
expect(lastDropdownItem.attributes('disabled')).toBe('true');
|
||||
});
|
||||
});
|
||||
|
||||
describe('scheduled jobs', () => {
|
||||
const scheduledJobAction = {
|
||||
name: 'scheduled action',
|
||||
playPath: `${TEST_HOST}/scheduled/job/action`,
|
||||
playable: true,
|
||||
scheduledAt: '2063-04-05T00:42:00Z',
|
||||
};
|
||||
const expiredJobAction = {
|
||||
name: 'expired action',
|
||||
playPath: `${TEST_HOST}/expired/job/action`,
|
||||
playable: true,
|
||||
scheduledAt: '2018-10-05T08:23:00Z',
|
||||
};
|
||||
const findDropdownItem = action => {
|
||||
const buttons = vm.findAll('.dropdown-menu li gl-button-stub');
|
||||
return buttons.filter(button => button.text().startsWith(action.name)).at(0);
|
||||
let emitSpy;
|
||||
|
||||
const clickAndConfirm = async ({ confirm = true } = {}) => {
|
||||
jest.spyOn(window, 'confirm').mockImplementation(() => confirm);
|
||||
|
||||
findDropdownItem(scheduledJobAction).vm.$emit('click');
|
||||
await wrapper.vm.$nextTick();
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
emitSpy = jest.fn();
|
||||
eventHub.$on('postAction', emitSpy);
|
||||
jest.spyOn(Date, 'now').mockImplementation(() => new Date('2063-04-04T00:42:00Z').getTime());
|
||||
vm.setProps({ actions: [scheduledJobAction, expiredJobAction] });
|
||||
});
|
||||
|
||||
it('emits postAction event after confirming', () => {
|
||||
const emitSpy = jest.fn();
|
||||
eventHub.$on('postAction', emitSpy);
|
||||
jest.spyOn(window, 'confirm').mockImplementation(() => true);
|
||||
describe('when postAction event is confirmed', () => {
|
||||
beforeEach(async () => {
|
||||
createComponentWithScheduledJobs({ mountFn: mount });
|
||||
clickAndConfirm();
|
||||
});
|
||||
|
||||
findDropdownItem(scheduledJobAction).vm.$emit('click');
|
||||
it('emits postAction event', () => {
|
||||
expect(window.confirm).toHaveBeenCalled();
|
||||
expect(emitSpy).toHaveBeenCalledWith({ endpoint: scheduledJobAction.playPath });
|
||||
});
|
||||
|
||||
expect(window.confirm).toHaveBeenCalled();
|
||||
expect(emitSpy).toHaveBeenCalledWith({ endpoint: scheduledJobAction.playPath });
|
||||
it('should render a dropdown button with a loading icon', () => {
|
||||
expect(wrapper.find(GlLoadingIcon).isVisible()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
it('does not emit postAction event if confirmation is cancelled', () => {
|
||||
const emitSpy = jest.fn();
|
||||
eventHub.$on('postAction', emitSpy);
|
||||
jest.spyOn(window, 'confirm').mockImplementation(() => false);
|
||||
describe('when postAction event is denied', () => {
|
||||
beforeEach(() => {
|
||||
createComponentWithScheduledJobs({ mountFn: mount });
|
||||
clickAndConfirm({ confirm: false });
|
||||
});
|
||||
|
||||
findDropdownItem(scheduledJobAction).vm.$emit('click');
|
||||
|
||||
expect(window.confirm).toHaveBeenCalled();
|
||||
expect(emitSpy).not.toHaveBeenCalled();
|
||||
it('does not emit postAction event if confirmation is cancelled', () => {
|
||||
expect(window.confirm).toHaveBeenCalled();
|
||||
expect(emitSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('displays the remaining time in the dropdown', () => {
|
||||
createComponentWithScheduledJobs();
|
||||
expect(findDropdownItem(scheduledJobAction).text()).toContain('24:00:00');
|
||||
});
|
||||
|
||||
it('displays 00:00:00 for expired jobs in the dropdown', () => {
|
||||
createComponentWithScheduledJobs();
|
||||
expect(findDropdownItem(expiredJobAction).text()).toContain('00:00:00');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -46,7 +46,7 @@ RSpec.describe Gitlab::Tracking::Destinations::Snowplow do
|
|||
it 'sends event to tracker' do
|
||||
allow(tracker).to receive(:track_self_describing_event).and_call_original
|
||||
|
||||
subject.self_describing_event('iglu:com.gitlab/foo/jsonschema/1-0-0', foo: 'bar')
|
||||
subject.self_describing_event('iglu:com.gitlab/foo/jsonschema/1-0-0', { foo: 'bar' })
|
||||
|
||||
expect(tracker).to have_received(:track_self_describing_event) do |event, context, timestamp|
|
||||
expect(event.to_json[:schema]).to eq('iglu:com.gitlab/foo/jsonschema/1-0-0')
|
||||
|
@ -71,7 +71,7 @@ RSpec.describe Gitlab::Tracking::Destinations::Snowplow do
|
|||
it 'does not send event to tracker' do
|
||||
expect_any_instance_of(SnowplowTracker::Tracker).not_to receive(:track_self_describing_event)
|
||||
|
||||
subject.self_describing_event('iglu:com.gitlab/foo/jsonschema/1-0-0', foo: 'bar')
|
||||
subject.self_describing_event('iglu:com.gitlab/foo/jsonschema/1-0-0', { foo: 'bar' })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -51,7 +51,7 @@ RSpec.describe Gitlab::Tracking do
|
|||
.to receive(:self_describing_event)
|
||||
.with('iglu:com.gitlab/foo/jsonschema/1-0-0', { foo: 'bar' }, context: nil)
|
||||
|
||||
described_class.self_describing_event('iglu:com.gitlab/foo/jsonschema/1-0-0', foo: 'bar')
|
||||
described_class.self_describing_event('iglu:com.gitlab/foo/jsonschema/1-0-0', { foo: 'bar' })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -141,7 +141,6 @@ RSpec.describe Issue do
|
|||
describe '.with_issue_type' do
|
||||
let_it_be(:issue) { create(:issue, project: reusable_project) }
|
||||
let_it_be(:incident) { create(:incident, project: reusable_project) }
|
||||
let_it_be(:test_case) { create(:quality_test_case, project: reusable_project) }
|
||||
|
||||
it 'gives issues with the given issue type' do
|
||||
expect(described_class.with_issue_type('issue'))
|
||||
|
@ -149,8 +148,8 @@ RSpec.describe Issue do
|
|||
end
|
||||
|
||||
it 'gives issues with the given issue type' do
|
||||
expect(described_class.with_issue_type(%w(issue incident test_case)))
|
||||
.to contain_exactly(issue, incident, test_case)
|
||||
expect(described_class.with_issue_type(%w(issue incident)))
|
||||
.to contain_exactly(issue, incident)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -10,14 +10,6 @@ RSpec.describe Projects::OpenIssuesCountService, :use_clean_rails_memory_store_c
|
|||
it_behaves_like 'a counter caching service'
|
||||
|
||||
describe '#count' do
|
||||
it 'does not count test cases' do
|
||||
create(:issue, :opened, project: project)
|
||||
create(:incident, :opened, project: project)
|
||||
create(:quality_test_case, :opened, project: project)
|
||||
|
||||
expect(described_class.new(project).count).to eq(2)
|
||||
end
|
||||
|
||||
context 'when user is nil' do
|
||||
it 'does not include confidential issues in the issue count' do
|
||||
create(:issue, :opened, project: project)
|
||||
|
|
|
@ -37,7 +37,7 @@ module MultipartHelpers
|
|||
# *without* the "#{key}." prefix
|
||||
result.deep_transform_keys! { |k| k.remove("#{key}.") }
|
||||
{
|
||||
"#{key}.gitlab-workhorse-upload" => jwt_token('upload' => result)
|
||||
"#{key}.gitlab-workhorse-upload" => jwt_token(data: { 'upload' => result })
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
@ -85,15 +85,15 @@ module WorkhorseHelpers
|
|||
|
||||
return {} if upload_params.empty?
|
||||
|
||||
{ "#{key}.gitlab-workhorse-upload" => jwt_token('upload' => upload_params) }
|
||||
{ "#{key}.gitlab-workhorse-upload" => jwt_token(data: { 'upload' => upload_params }) }
|
||||
end
|
||||
|
||||
def jwt_token(data = {}, issuer: 'gitlab-workhorse', secret: Gitlab::Workhorse.secret, algorithm: 'HS256')
|
||||
def jwt_token(data: {}, issuer: 'gitlab-workhorse', secret: Gitlab::Workhorse.secret, algorithm: 'HS256')
|
||||
JWT.encode({ 'iss' => issuer }.merge(data), secret, algorithm)
|
||||
end
|
||||
|
||||
def workhorse_rewritten_fields_header(fields)
|
||||
{ Gitlab::Middleware::Multipart::RACK_ENV_KEY => jwt_token('rewritten_fields' => fields) }
|
||||
{ Gitlab::Middleware::Multipart::RACK_ENV_KEY => jwt_token(data: { 'rewritten_fields' => fields }) }
|
||||
end
|
||||
|
||||
def workhorse_disk_accelerated_file_params(key, file)
|
||||
|
|
Loading…
Reference in a new issue