Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
a40c1d5046
commit
684f46a082
10 changed files with 86 additions and 60 deletions
|
@ -127,3 +127,5 @@ class GpgKey < ApplicationRecord
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
GpgKey.prepend_if_ee('EE::GpgKey')
|
||||
|
|
|
@ -1485,8 +1485,9 @@ Parameters:
|
|||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/17176) in GitLab 13.6.
|
||||
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/267553) in GitLab 13.8.
|
||||
|
||||
Use this API to create a new personal access token. Token values are returned once.
|
||||
Make sure you save it as you can't access it again.
|
||||
Use this API to create a new personal access token. Token values are returned once so,
|
||||
make sure you save it as you can't access it again. This API can only be used by
|
||||
GitLab administrators.
|
||||
|
||||
```plaintext
|
||||
POST /users/:user_id/personal_access_tokens
|
||||
|
|
|
@ -5,7 +5,6 @@ require 'spec_helper'
|
|||
RSpec.describe 'User filters Alert Management table by status', :js do
|
||||
let_it_be(:project) { create(:project) }
|
||||
let_it_be(:developer) { create(:user) }
|
||||
let_it_be(:alerts_service) { create(:alerts_service, project: project) }
|
||||
let_it_be(:alert1, reload: true) { create(:alert_management_alert, :triggered, project: project) }
|
||||
let_it_be(:alert2, reload: true) { create(:alert_management_alert, :acknowledged, project: project) }
|
||||
let_it_be(:alert3, reload: true) { create(:alert_management_alert, :acknowledged, project: project) }
|
||||
|
|
|
@ -5,7 +5,6 @@ require 'spec_helper'
|
|||
RSpec.describe 'User searches Alert Management alerts', :js do
|
||||
let_it_be(:project) { create(:project) }
|
||||
let_it_be(:developer) { create(:user) }
|
||||
let_it_be(:alerts_service) { create(:alerts_service, project: project) }
|
||||
let_it_be(:alert) { create(:alert_management_alert, project: project, status: 'triggered') }
|
||||
|
||||
before_all do
|
||||
|
|
|
@ -5,7 +5,6 @@ require 'spec_helper'
|
|||
RSpec.describe 'User updates Alert Management status', :js do
|
||||
let_it_be(:project) { create(:project) }
|
||||
let_it_be(:developer) { create(:user) }
|
||||
let_it_be(:alerts_service) { create(:alerts_service, project: project) }
|
||||
let_it_be(:alert) { create(:alert_management_alert, project: project, status: 'triggered') }
|
||||
|
||||
before_all do
|
||||
|
|
|
@ -124,10 +124,9 @@ describe('DiscussionNotes', () => {
|
|||
describe('with groupped notes and replies expanded', () => {
|
||||
const findNoteAtIndex = (index) => {
|
||||
const noteComponents = [NoteableNote, SystemNote, PlaceholderNote, PlaceholderSystemNote];
|
||||
const allowedNames = noteComponents.map((c) => c.name);
|
||||
return wrapper
|
||||
.findAll('.notes *')
|
||||
.filter((w) => allowedNames.includes(w.name()))
|
||||
.filter((w) => noteComponents.some((Component) => w.is(Component)))
|
||||
.at(index);
|
||||
};
|
||||
|
||||
|
|
|
@ -137,7 +137,7 @@ describe('note_app', () => {
|
|||
});
|
||||
|
||||
it('should render form', () => {
|
||||
expect(wrapper.find('.js-main-target-form').name()).toEqual('form');
|
||||
expect(wrapper.find('.js-main-target-form').element.tagName).toBe('FORM');
|
||||
expect(wrapper.find('.js-main-target-form textarea').attributes('placeholder')).toEqual(
|
||||
'Write a comment or drag your files here…',
|
||||
);
|
||||
|
@ -202,7 +202,7 @@ describe('note_app', () => {
|
|||
});
|
||||
|
||||
it('should render form', () => {
|
||||
expect(wrapper.find('.js-main-target-form').name()).toEqual('form');
|
||||
expect(wrapper.find('.js-main-target-form').element.tagName).toBe('FORM');
|
||||
expect(wrapper.find('.js-main-target-form textarea').attributes('placeholder')).toEqual(
|
||||
'Write a comment or drag your files here…',
|
||||
);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { nextTick } from 'vue';
|
||||
import { mount } from '@vue/test-utils';
|
||||
import MockAdapter from 'axios-mock-adapter';
|
||||
import waitForPromises from 'helpers/wait_for_promises';
|
||||
|
@ -72,7 +73,7 @@ describe('Pipelines', () => {
|
|||
|
||||
const findTablePagination = () => wrapper.find(TablePagination);
|
||||
|
||||
const createComponent = (props = defaultProps, methods) => {
|
||||
const createComponent = (props = defaultProps) => {
|
||||
wrapper = mount(PipelinesComponent, {
|
||||
propsData: {
|
||||
store: new Store(),
|
||||
|
@ -80,13 +81,15 @@ describe('Pipelines', () => {
|
|||
params: {},
|
||||
...props,
|
||||
},
|
||||
methods: {
|
||||
...methods,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
delete window.location;
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
window.location = { search: '' };
|
||||
mock = new MockAdapter(axios);
|
||||
pipelines = getJSONFixture(jsonFixtureName);
|
||||
|
||||
|
@ -170,7 +173,7 @@ describe('Pipelines', () => {
|
|||
it('renders tab empty state finished scope', () => {
|
||||
wrapper.vm.scope = 'finished';
|
||||
|
||||
return wrapper.vm.$nextTick().then(() => {
|
||||
return nextTick().then(() => {
|
||||
expect(findBlankState().text()).toBe('There are currently no finished pipelines.');
|
||||
});
|
||||
});
|
||||
|
@ -382,30 +385,23 @@ describe('Pipelines', () => {
|
|||
});
|
||||
|
||||
it('should make an API request when using tabs', () => {
|
||||
const updateContentMock = jest.fn(() => {});
|
||||
createComponent(
|
||||
{ hasGitlabCi: true, canCreatePipeline: true, ...paths },
|
||||
{
|
||||
updateContent: updateContentMock,
|
||||
},
|
||||
);
|
||||
createComponent({ hasGitlabCi: true, canCreatePipeline: true, ...paths });
|
||||
jest.spyOn(wrapper.vm.service, 'getPipelines');
|
||||
|
||||
return waitForPromises().then(() => {
|
||||
findTab('finished').trigger('click');
|
||||
|
||||
expect(updateContentMock).toHaveBeenCalledWith({ scope: 'finished', page: '1' });
|
||||
expect(wrapper.vm.service.getPipelines).toHaveBeenCalledWith({
|
||||
scope: 'finished',
|
||||
page: '1',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('with pagination', () => {
|
||||
it('should make an API request when using pagination', () => {
|
||||
const updateContentMock = jest.fn(() => {});
|
||||
createComponent(
|
||||
{ hasGitlabCi: true, canCreatePipeline: true, ...paths },
|
||||
{
|
||||
updateContent: updateContentMock,
|
||||
},
|
||||
);
|
||||
createComponent({ hasGitlabCi: true, canCreatePipeline: true, ...paths });
|
||||
jest.spyOn(wrapper.vm.service, 'getPipelines');
|
||||
|
||||
return waitForPromises()
|
||||
.then(() => {
|
||||
|
@ -418,12 +414,14 @@ describe('Pipelines', () => {
|
|||
totalPages: 5,
|
||||
};
|
||||
|
||||
return wrapper.vm.$nextTick();
|
||||
return nextTick();
|
||||
})
|
||||
.then(() => {
|
||||
wrapper.find('.next-page-item').trigger('click');
|
||||
|
||||
expect(updateContentMock).toHaveBeenCalledWith({ scope: 'all', page: '2' });
|
||||
expect(wrapper.vm.service.getPipelines).toHaveBeenCalledWith({
|
||||
scope: 'all',
|
||||
page: '2',
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -542,7 +540,7 @@ describe('Pipelines', () => {
|
|||
wrapper.vm.hasError = true;
|
||||
wrapper.vm.isLoading = false;
|
||||
|
||||
return wrapper.vm.$nextTick().then(() => {
|
||||
return nextTick().then(() => {
|
||||
expect(findBlankState().props('message')).toBe(
|
||||
'There was an error fetching the pipelines. Try again in a few moments or contact your support team.',
|
||||
);
|
||||
|
@ -554,7 +552,7 @@ describe('Pipelines', () => {
|
|||
wrapper.vm.hasError = false;
|
||||
wrapper.vm.state.pipelines = pipelines.pipelines;
|
||||
|
||||
return wrapper.vm.$nextTick().then(() => {
|
||||
return nextTick().then(() => {
|
||||
expect(wrapper.find(PipelinesTableComponent).exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
@ -563,7 +561,7 @@ describe('Pipelines', () => {
|
|||
wrapper.vm.state.count.all = 10;
|
||||
wrapper.vm.isLoading = false;
|
||||
|
||||
return wrapper.vm.$nextTick().then(() => {
|
||||
return nextTick().then(() => {
|
||||
expect(findBlankState().exists()).toBe(true);
|
||||
expect(findBlankState().props('message')).toBe('There are currently no pipelines.');
|
||||
});
|
||||
|
@ -572,7 +570,7 @@ describe('Pipelines', () => {
|
|||
it('shows empty tab when project has CI', () => {
|
||||
wrapper.vm.isLoading = false;
|
||||
|
||||
return wrapper.vm.$nextTick().then(() => {
|
||||
return nextTick().then(() => {
|
||||
expect(findBlankState().exists()).toBe(true);
|
||||
expect(findBlankState().props('message')).toBe('There are currently no pipelines.');
|
||||
});
|
||||
|
@ -583,7 +581,7 @@ describe('Pipelines', () => {
|
|||
|
||||
wrapper.vm.isLoading = false;
|
||||
|
||||
return wrapper.vm.$nextTick().then(() => {
|
||||
return nextTick().then(() => {
|
||||
expect(wrapper.find(EmptyState).exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
@ -594,7 +592,7 @@ describe('Pipelines', () => {
|
|||
wrapper.vm.isLoading = true;
|
||||
wrapper.vm.hasMadeRequest = true;
|
||||
|
||||
return wrapper.vm.$nextTick().then(() => {
|
||||
return nextTick().then(() => {
|
||||
expect(findNavigationTabs().exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
@ -604,7 +602,7 @@ describe('Pipelines', () => {
|
|||
wrapper.vm.state.pipelines = pipelines.pipelines;
|
||||
wrapper.vm.hasMadeRequest = true;
|
||||
|
||||
return wrapper.vm.$nextTick().then(() => {
|
||||
return nextTick().then(() => {
|
||||
expect(findNavigationTabs().exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
@ -614,7 +612,7 @@ describe('Pipelines', () => {
|
|||
wrapper.vm.hasError = true;
|
||||
wrapper.vm.hasMadeRequest = true;
|
||||
|
||||
return wrapper.vm.$nextTick().then(() => {
|
||||
return nextTick().then(() => {
|
||||
expect(findNavigationTabs().exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
@ -624,7 +622,7 @@ describe('Pipelines', () => {
|
|||
wrapper.vm.state.count.all = 10;
|
||||
wrapper.vm.hasMadeRequest = true;
|
||||
|
||||
return wrapper.vm.$nextTick().then(() => {
|
||||
return nextTick().then(() => {
|
||||
expect(findNavigationTabs().exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
@ -632,7 +630,7 @@ describe('Pipelines', () => {
|
|||
it('returns false when has not made first request', () => {
|
||||
wrapper.vm.hasMadeRequest = false;
|
||||
|
||||
return wrapper.vm.$nextTick().then(() => {
|
||||
return nextTick().then(() => {
|
||||
expect(findNavigationTabs().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
@ -643,7 +641,7 @@ describe('Pipelines', () => {
|
|||
wrapper.vm.isLoading = false;
|
||||
wrapper.vm.hasMadeRequest = true;
|
||||
|
||||
return wrapper.vm.$nextTick().then(() => {
|
||||
return nextTick().then(() => {
|
||||
expect(findNavigationTabs().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
@ -653,7 +651,7 @@ describe('Pipelines', () => {
|
|||
it('returns true when it has paths & has made the first request', () => {
|
||||
wrapper.vm.hasMadeRequest = true;
|
||||
|
||||
return wrapper.vm.$nextTick().then(() => {
|
||||
return nextTick().then(() => {
|
||||
expect(findNavigationControls().exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
@ -661,7 +659,7 @@ describe('Pipelines', () => {
|
|||
it('returns false when it has not made the first request', () => {
|
||||
wrapper.vm.hasMadeRequest = false;
|
||||
|
||||
return wrapper.vm.$nextTick().then(() => {
|
||||
return nextTick().then(() => {
|
||||
expect(findNavigationControls().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
@ -680,7 +678,7 @@ describe('Pipelines', () => {
|
|||
return waitForPromises();
|
||||
});
|
||||
|
||||
it('updates request data and query params on filter submit', () => {
|
||||
it('updates request data and query params on filter submit', async () => {
|
||||
const expectedQueryParams = {
|
||||
page: '1',
|
||||
scope: 'all',
|
||||
|
@ -690,15 +688,17 @@ describe('Pipelines', () => {
|
|||
};
|
||||
|
||||
findFilteredSearch().vm.$emit('submit', mockSearch);
|
||||
await nextTick();
|
||||
|
||||
expect(wrapper.vm.requestData).toEqual(expectedQueryParams);
|
||||
expect(updateContentMock).toHaveBeenCalledWith(expectedQueryParams);
|
||||
});
|
||||
|
||||
it('does not add query params if raw text search is used', () => {
|
||||
it('does not add query params if raw text search is used', async () => {
|
||||
const expectedQueryParams = { page: '1', scope: 'all' };
|
||||
|
||||
findFilteredSearch().vm.$emit('submit', ['rawText']);
|
||||
await nextTick();
|
||||
|
||||
expect(wrapper.vm.requestData).toEqual(expectedQueryParams);
|
||||
expect(updateContentMock).toHaveBeenCalledWith(expectedQueryParams);
|
||||
|
|
|
@ -9,7 +9,7 @@ RSpec.describe Types::Projects::ServiceType do
|
|||
it 'resolves the corresponding type for objects' do
|
||||
expect(described_class.resolve_type(build(:jira_service), {})).to eq(Types::Projects::Services::JiraServiceType)
|
||||
expect(described_class.resolve_type(build(:service), {})).to eq(Types::Projects::Services::BaseServiceType)
|
||||
expect(described_class.resolve_type(build(:alerts_service), {})).to eq(Types::Projects::Services::BaseServiceType)
|
||||
expect(described_class.resolve_type(build(:drone_ci_service), {})).to eq(Types::Projects::Services::BaseServiceType)
|
||||
expect(described_class.resolve_type(build(:custom_issue_tracker_service), {})).to eq(Types::Projects::Services::BaseServiceType)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,14 +15,6 @@ RSpec.describe 'projects/settings/operations/show' do
|
|||
end
|
||||
|
||||
let_it_be(:prometheus_service) { create(:prometheus_service, project: project) }
|
||||
let_it_be(:alerts_service) { create(:alerts_service, project: project) }
|
||||
|
||||
let(:operations_show_locals) do
|
||||
{
|
||||
prometheus_service: prometheus_service,
|
||||
alerts_service: alerts_service
|
||||
}
|
||||
end
|
||||
|
||||
before_all do
|
||||
project.add_maintainer(user)
|
||||
|
@ -35,13 +27,24 @@ RSpec.describe 'projects/settings/operations/show' do
|
|||
.and_return(error_tracking_setting)
|
||||
allow(view).to receive(:tracing_setting)
|
||||
.and_return(tracing_setting)
|
||||
allow(view).to receive(:prometheus_service)
|
||||
.and_return(prometheus_service)
|
||||
allow(view).to receive(:current_user).and_return(user)
|
||||
end
|
||||
|
||||
describe 'Operations > Alerts' do
|
||||
it 'renders the Operations Settings page' do
|
||||
render
|
||||
|
||||
expect(rendered).to have_content _('Alerts')
|
||||
expect(rendered).to have_content _('Display alerts from all your monitoring tools directly within GitLab.')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Operations > Error Tracking' do
|
||||
context 'Settings page ' do
|
||||
it 'renders the Operations Settings page' do
|
||||
render template: 'projects/settings/operations/show', locals: operations_show_locals
|
||||
render
|
||||
|
||||
expect(rendered).to have_content _('Error tracking')
|
||||
expect(rendered).to have_content _('To link Sentry to GitLab, enter your Sentry URL and Auth Token')
|
||||
|
@ -49,10 +52,34 @@ RSpec.describe 'projects/settings/operations/show' do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'Operations > Prometheus' do
|
||||
context 'when settings_operations_prometheus_service flag is enabled' do
|
||||
it 'renders the Operations Settings page' do
|
||||
render
|
||||
|
||||
expect(rendered).to have_content _('Prometheus')
|
||||
expect(rendered).to have_content _('Link Prometheus monitoring to GitLab.')
|
||||
expect(rendered).to have_content _('To enable the installation of Prometheus on your clusters, deactivate the manual configuration below')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when settings_operations_prometheus_service is disabled' do
|
||||
before do
|
||||
stub_feature_flags(settings_operations_prometheus_service: false)
|
||||
end
|
||||
|
||||
it 'renders the Operations Settings page' do
|
||||
render
|
||||
|
||||
expect(rendered).not_to have_content _('Select the Active checkbox to override the Auto Configuration with custom settings. If unchecked, Auto Configuration settings are used.')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Operations > Tracing' do
|
||||
context 'with project.tracing_external_url' do
|
||||
it 'links to project.tracing_external_url' do
|
||||
render template: 'projects/settings/operations/show', locals: operations_show_locals
|
||||
render
|
||||
|
||||
expect(rendered).to have_link('Tracing', href: tracing_setting.external_url)
|
||||
end
|
||||
|
@ -66,7 +93,7 @@ RSpec.describe 'projects/settings/operations/show' do
|
|||
end
|
||||
|
||||
it 'sanitizes external_url' do
|
||||
render template: 'projects/settings/operations/show', locals: operations_show_locals
|
||||
render
|
||||
|
||||
expect(tracing_setting.external_url).to eq(malicious_tracing_url)
|
||||
expect(rendered).to have_link('Tracing', href: cleaned_url)
|
||||
|
@ -82,7 +109,7 @@ RSpec.describe 'projects/settings/operations/show' do
|
|||
end
|
||||
|
||||
it 'links to Tracing page' do
|
||||
render template: 'projects/settings/operations/show', locals: operations_show_locals
|
||||
render
|
||||
|
||||
expect(rendered).to have_link('Tracing', href: project_tracing_path(project))
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue