Skip to content
Snippets Groups Projects
Commit 7cc6c10c authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@master

parent 630101f7
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -134,6 +134,36 @@ to add that `only:` rule to all of your jobs in order to make them always run. Y
can use this for scenarios like having only pipelines with merge requests get a
Review App set up, helping to save resources.
 
## Excluding certain branches
Pipelines for merge requests require special treatement when
using [`only`/`except`](../yaml/README.md#onlyexcept-basic). Unlike ordinary
branch refs (for example `refs/heads/my-feature-branch`), merge request refs
use a special Git reference that looks like `refs/merge-requests/:iid/head`. Because
of this, the following configuration will **not** work as expected:
```yaml
# Does not exclude a branch named "docs-my-fix"!
test:
only: [merge_requests]
except: [/^docs-/]
```
Instead, you can use the
[`$CI_COMMIT_REF_NAME` predefined environment
variable](../variables/predefined_variables.md#variables-reference) in
combination with
[`only:variables`](../yaml/README.md#onlyvariablesexceptvariables) to
accomplish this behavior:
```yaml
test:
only: [merge_requests]
except:
variables:
$CI_COMMIT_REF_NAME =~ /^docs-/
```
## Important notes about merge requests from forked projects
 
Note that the current behavior is subject to change. In the usual contribution
Loading
Loading
Loading
Loading
@@ -7735,6 +7735,9 @@ msgstr ""
msgid "Finished"
msgstr ""
 
msgid "First Seen"
msgstr ""
msgid "First day of the week"
msgstr ""
 
Loading
Loading
@@ -7861,6 +7864,9 @@ msgstr ""
msgid "Free Trial of GitLab.com Gold"
msgstr ""
 
msgid "Frequency"
msgstr ""
msgid "Friday"
msgstr ""
 
Loading
Loading
@@ -10201,6 +10207,9 @@ msgstr ""
msgid "Last Pipeline"
msgstr ""
 
msgid "Last Seen"
msgstr ""
msgid "Last accessed on"
msgstr ""
 
Loading
Loading
@@ -19762,9 +19771,6 @@ msgstr ""
msgid "View group labels"
msgstr ""
 
msgid "View in Sentry"
msgstr ""
msgid "View it on GitLab"
msgstr ""
 
Loading
Loading
import { createLocalVue, shallowMount } from '@vue/test-utils';
import Vuex from 'vuex';
import {
GlButton,
GlEmptyState,
GlLoadingIcon,
GlTable,
Loading
Loading
@@ -24,7 +23,9 @@ describe('ErrorTrackingList', () => {
 
const findErrorListTable = () => wrapper.find('table');
const findErrorListRows = () => wrapper.findAll('tbody tr');
const findButton = () => wrapper.find(GlButton);
const findSortDropdown = () => wrapper.find('.sort-dropdown');
const findRecentSearchesDropdown = () =>
wrapper.find('.filtered-search-history-dropdown-wrapper');
const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
 
function mountComponent({
Loading
Loading
@@ -33,6 +34,8 @@ describe('ErrorTrackingList', () => {
stubs = {
'gl-link': GlLink,
'gl-table': GlTable,
'gl-dropdown': GlDropdown,
'gl-dropdown-item': GlDropdownItem,
},
} = {}) {
wrapper = shallowMount(ErrorTrackingList, {
Loading
Loading
@@ -46,6 +49,9 @@ describe('ErrorTrackingList', () => {
illustrationPath: 'illustration/path',
},
stubs,
data() {
return { errorSearchQuery: 'search' };
},
});
}
 
Loading
Loading
@@ -58,6 +64,9 @@ describe('ErrorTrackingList', () => {
loadRecentSearches: jest.fn(),
setIndexPath: jest.fn(),
clearRecentSearches: jest.fn(),
setEndpoint: jest.fn(),
searchByQuery: jest.fn(),
sortByField: jest.fn(),
};
 
const state = createListState();
Loading
Loading
@@ -101,7 +110,7 @@ describe('ErrorTrackingList', () => {
it('shows table', () => {
expect(findLoadingIcon().exists()).toBe(false);
expect(findErrorListTable().exists()).toBe(true);
expect(findButton().exists()).toBe(true);
expect(findSortDropdown().exists()).toBe(true);
});
 
it('shows list of errors in a table', () => {
Loading
Loading
@@ -121,16 +130,20 @@ describe('ErrorTrackingList', () => {
describe('filtering', () => {
const findSearchBox = () => wrapper.find(GlFormInput);
 
it('shows search box', () => {
it('shows search box & sort dropdown', () => {
expect(findSearchBox().exists()).toBe(true);
expect(findSortDropdown().exists()).toBe(true);
});
 
it('makes network request on submit', () => {
expect(actions.startPolling).toHaveBeenCalledTimes(1);
it('it searches by query', () => {
findSearchBox().trigger('keyup.enter');
expect(actions.searchByQuery.mock.calls[0][1]).toEqual(wrapper.vm.errorSearchQuery);
});
 
expect(actions.startPolling).toHaveBeenCalledTimes(2);
it('it sorts by fields', () => {
const findSortItem = () => wrapper.find('.dropdown-item');
findSortItem().trigger('click');
expect(actions.sortByField).toHaveBeenCalled();
});
});
});
Loading
Loading
@@ -148,7 +161,7 @@ describe('ErrorTrackingList', () => {
it('shows empty table', () => {
expect(findLoadingIcon().exists()).toBe(false);
expect(findErrorListRows().length).toEqual(1);
expect(findButton().exists()).toBe(true);
expect(findSortDropdown().exists()).toBe(true);
});
 
it('shows a message prompting to refresh', () => {
Loading
Loading
@@ -170,7 +183,7 @@ describe('ErrorTrackingList', () => {
expect(wrapper.find(GlEmptyState).exists()).toBe(true);
expect(findLoadingIcon().exists()).toBe(false);
expect(findErrorListTable().exists()).toBe(false);
expect(findButton().exists()).toBe(false);
expect(findSortDropdown().exists()).toBe(false);
});
});
 
Loading
Loading
@@ -201,13 +214,13 @@ describe('ErrorTrackingList', () => {
it('shows empty message', () => {
store.state.list.recentSearches = [];
 
expect(wrapper.find(GlDropdown).text()).toBe("You don't have any recent searches");
expect(findRecentSearchesDropdown().text()).toContain("You don't have any recent searches");
});
 
it('shows items', () => {
store.state.list.recentSearches = ['great', 'search'];
 
const dropdownItems = wrapper.findAll(GlDropdownItem);
const dropdownItems = wrapper.findAll('.filtered-search-box li');
 
expect(dropdownItems.length).toBe(3);
expect(dropdownItems.at(0).text()).toBe('great');
Loading
Loading
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import MockAdapter from 'axios-mock-adapter';
import testAction from 'helpers/vuex_action_helper';
import httpStatusCodes from '~/lib/utils/http_status';
import createFlash from '~/flash';
import * as actions from '~/error_tracking/store/list/actions';
import * as types from '~/error_tracking/store/list/mutation_types';
 
jest.mock('~/flash.js');
describe('error tracking actions', () => {
let mock;
 
Loading
Loading
@@ -15,15 +20,97 @@ describe('error tracking actions', () => {
});
 
describe('startPolling', () => {
it('commits SET_LOADING', () => {
mock.onGet().reply(200);
const endpoint = '/errors';
const commit = jest.fn();
const state = {};
it('should start polling for data', done => {
const payload = { errors: [{ id: 1 }, { id: 2 }] };
mock.onGet().reply(httpStatusCodes.OK, payload);
testAction(
actions.startPolling,
{},
{},
[
{ type: types.SET_LOADING, payload: true },
{ type: types.SET_ERRORS, payload: payload.errors },
{ type: types.SET_LOADING, payload: false },
],
[{ type: 'stopPolling' }],
() => {
done();
},
);
});
it('should show flash on API error', done => {
mock.onGet().reply(httpStatusCodes.BAD_REQUEST);
testAction(
actions.startPolling,
{},
{},
[{ type: types.SET_LOADING, payload: true }, { type: types.SET_LOADING, payload: false }],
[],
() => {
expect(createFlash).toHaveBeenCalledTimes(1);
done();
},
);
});
});
describe('restartPolling', () => {
it('should restart polling', () => {
testAction(
actions.restartPolling,
{},
{},
[{ type: types.SET_ERRORS, payload: [] }, { type: types.SET_LOADING, payload: true }],
[],
);
});
});
describe('searchByQuery', () => {
it('should search by query', () => {
const query = 'search';
testAction(
actions.searchByQuery,
query,
{},
[
{ type: types.SET_SEARCH_QUERY, payload: query },
{ type: types.ADD_RECENT_SEARCH, payload: query },
],
[{ type: 'stopPolling' }, { type: 'startPolling' }],
);
});
});
describe('sortByField', () => {
it('should search by query', () => {
const field = 'frequency';
testAction(
actions.sortByField,
{ field },
{},
[{ type: types.SET_SORT_FIELD, payload: { field } }],
[{ type: 'stopPolling' }, { type: 'startPolling' }],
);
});
});
 
actions.startPolling({ commit, state }, endpoint);
describe('setEnpoint', () => {
it('should set search endpoint', () => {
const endpoint = 'https://sentry.io';
 
expect(commit).toHaveBeenCalledWith(types.SET_LOADING, true);
testAction(
actions.setEndpoint,
{ endpoint },
{},
[{ type: types.SET_ENDPOINT, payload: { endpoint } }],
[],
);
});
});
});
Loading
Loading
@@ -3,17 +3,6 @@ import * as errorTrackingUtils from '~/error_tracking/utils';
const externalUrl = 'https://sentry.io/organizations/test-sentry-nk/issues/1/?project=1';
 
describe('Error Tracking Events', () => {
describe('trackViewInSentryOptions', () => {
it('should return correct event options', () => {
expect(errorTrackingUtils.trackViewInSentryOptions(externalUrl)).toEqual({
category: 'Error Tracking',
action: 'click_view_in_sentry',
label: 'External Url',
property: externalUrl,
});
});
});
describe('trackClickErrorLinkToSentryOptions', () => {
it('should return correct event options', () => {
expect(errorTrackingUtils.trackClickErrorLinkToSentryOptions(externalUrl)).toEqual({
Loading
Loading
import SnippetApp from '~/snippets/components/app.vue';
import { createLocalVue, shallowMount } from '@vue/test-utils';
describe('Snippet view app', () => {
let wrapper;
let snippetDataMock;
const localVue = createLocalVue();
const defaultProps = {
snippetGid: 'gid://gitlab/PersonalSnippet/35',
};
function createComponent({ props = defaultProps, snippetData = {} } = {}) {
snippetDataMock = jest.fn();
const $apollo = {
queries: {
snippetData: snippetDataMock,
},
};
wrapper = shallowMount(SnippetApp, {
sync: false,
mocks: { $apollo },
localVue,
propsData: {
...props,
},
});
wrapper.setData({
snippetData,
});
}
afterEach(() => {
wrapper.destroy();
});
it('renders itself', () => {
createComponent();
expect(wrapper.find('.js-snippet-view').exists()).toBe(true);
});
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment