Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
ef615776bf
commit
edfc0f680f
|
@ -1,12 +1,22 @@
|
|||
<script>
|
||||
import { GlTabs, GlTab } from '@gitlab/ui';
|
||||
import { CLUSTERS_TABS, MAX_CLUSTERS_LIST, MAX_LIST_COUNT, AGENT } from '../constants';
|
||||
import Tracking from '~/tracking';
|
||||
import {
|
||||
CLUSTERS_TABS,
|
||||
MAX_CLUSTERS_LIST,
|
||||
MAX_LIST_COUNT,
|
||||
AGENT,
|
||||
EVENT_LABEL_TABS,
|
||||
EVENT_ACTIONS_CHANGE,
|
||||
} from '../constants';
|
||||
import Agents from './agents.vue';
|
||||
import InstallAgentModal from './install_agent_modal.vue';
|
||||
import ClustersActions from './clusters_actions.vue';
|
||||
import Clusters from './clusters.vue';
|
||||
import ClustersViewAll from './clusters_view_all.vue';
|
||||
|
||||
const trackingMixin = Tracking.mixin({ label: EVENT_LABEL_TABS });
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GlTabs,
|
||||
|
@ -18,6 +28,7 @@ export default {
|
|||
InstallAgentModal,
|
||||
},
|
||||
CLUSTERS_TABS,
|
||||
mixins: [trackingMixin],
|
||||
props: {
|
||||
defaultBranchName: {
|
||||
default: '.noBranch',
|
||||
|
@ -34,9 +45,12 @@ export default {
|
|||
methods: {
|
||||
onTabChange(tabName) {
|
||||
this.selectedTabIndex = CLUSTERS_TABS.findIndex((tab) => tab.queryParamValue === tabName);
|
||||
|
||||
this.maxAgents = tabName === AGENT ? MAX_LIST_COUNT : MAX_CLUSTERS_LIST;
|
||||
},
|
||||
trackTabChange(tab) {
|
||||
const tabName = CLUSTERS_TABS[tab].queryParamValue;
|
||||
this.track(EVENT_ACTIONS_CHANGE, { property: tabName });
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
@ -47,6 +61,7 @@ export default {
|
|||
sync-active-tab-with-query-params
|
||||
nav-class="gl-flex-grow-1 gl-align-items-center"
|
||||
lazy
|
||||
@input="trackTabChange"
|
||||
>
|
||||
<gl-tab
|
||||
v-for="(tab, idx) in $options.CLUSTERS_TABS"
|
||||
|
|
|
@ -11,8 +11,19 @@ import {
|
|||
import { helpPagePath } from '~/helpers/help_page_helper';
|
||||
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
|
||||
import CodeBlock from '~/vue_shared/components/code_block.vue';
|
||||
import Tracking from '~/tracking';
|
||||
import { generateAgentRegistrationCommand } from '../clusters_util';
|
||||
import { INSTALL_AGENT_MODAL_ID, I18N_AGENT_MODAL, KAS_DISABLED_ERROR } from '../constants';
|
||||
import {
|
||||
INSTALL_AGENT_MODAL_ID,
|
||||
I18N_AGENT_MODAL,
|
||||
KAS_DISABLED_ERROR,
|
||||
EVENT_LABEL_MODAL,
|
||||
EVENT_ACTIONS_OPEN,
|
||||
EVENT_ACTIONS_SELECT,
|
||||
EVENT_ACTIONS_CLICK,
|
||||
MODAL_TYPE_EMPTY,
|
||||
MODAL_TYPE_REGISTER,
|
||||
} from '../constants';
|
||||
import { addAgentToStore, addAgentConfigToStore } from '../graphql/cache_update';
|
||||
import createAgent from '../graphql/mutations/create_agent.mutation.graphql';
|
||||
import createAgentToken from '../graphql/mutations/create_agent_token.mutation.graphql';
|
||||
|
@ -20,8 +31,13 @@ import getAgentsQuery from '../graphql/queries/get_agents.query.graphql';
|
|||
import agentConfigurations from '../graphql/queries/agent_configurations.query.graphql';
|
||||
import AvailableAgentsDropdown from './available_agents_dropdown.vue';
|
||||
|
||||
const trackingMixin = Tracking.mixin({ label: EVENT_LABEL_MODAL });
|
||||
|
||||
export default {
|
||||
modalId: INSTALL_AGENT_MODAL_ID,
|
||||
EVENT_ACTIONS_OPEN,
|
||||
EVENT_ACTIONS_CLICK,
|
||||
EVENT_LABEL_MODAL,
|
||||
components: {
|
||||
AvailableAgentsDropdown,
|
||||
ClipboardButton,
|
||||
|
@ -34,6 +50,7 @@ export default {
|
|||
GlModal,
|
||||
GlSprintf,
|
||||
},
|
||||
mixins: [trackingMixin],
|
||||
inject: ['projectPath', 'kasAddress', 'emptyStateImage'],
|
||||
props: {
|
||||
defaultBranchName: {
|
||||
|
@ -81,7 +98,7 @@ export default {
|
|||
return !this.registering && this.agentName !== null;
|
||||
},
|
||||
canCancel() {
|
||||
return !this.registered && !this.registering && this.isRegisterModal;
|
||||
return !this.registered && !this.registering && this.isAgentRegistrationModal;
|
||||
},
|
||||
agentRegistrationCommand() {
|
||||
return generateAgentRegistrationCommand(this.agentToken, this.kasAddress);
|
||||
|
@ -117,21 +134,24 @@ export default {
|
|||
return `/${this.projectPath}`;
|
||||
},
|
||||
modalType() {
|
||||
return !this.availableAgents?.length && !this.registered ? 'install' : 'register';
|
||||
return !this.availableAgents?.length && !this.registered
|
||||
? MODAL_TYPE_EMPTY
|
||||
: MODAL_TYPE_REGISTER;
|
||||
},
|
||||
modalSize() {
|
||||
return this.isInstallModal ? 'sm' : 'md';
|
||||
return this.isEmptyStateModal ? 'sm' : 'md';
|
||||
},
|
||||
isInstallModal() {
|
||||
return this.modalType === 'install';
|
||||
isEmptyStateModal() {
|
||||
return this.modalType === MODAL_TYPE_EMPTY;
|
||||
},
|
||||
isRegisterModal() {
|
||||
return this.modalType === 'register';
|
||||
isAgentRegistrationModal() {
|
||||
return this.modalType === MODAL_TYPE_REGISTER;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
setAgentName(name) {
|
||||
this.agentName = name;
|
||||
this.track(EVENT_ACTIONS_SELECT);
|
||||
},
|
||||
closeModal() {
|
||||
this.$refs.modal.hide();
|
||||
|
@ -242,8 +262,9 @@ export default {
|
|||
static
|
||||
lazy
|
||||
@hidden="resetModal"
|
||||
@show="track($options.EVENT_ACTIONS_OPEN, { property: modalType })"
|
||||
>
|
||||
<template v-if="isRegisterModal">
|
||||
<template v-if="isAgentRegistrationModal">
|
||||
<template v-if="!registered">
|
||||
<p>
|
||||
<strong>{{ i18n.selectAgentTitle }}</strong>
|
||||
|
@ -347,23 +368,40 @@ export default {
|
|||
</template>
|
||||
|
||||
<template #modal-footer>
|
||||
<gl-button v-if="canCancel" @click="closeModal">{{ i18n.cancel }} </gl-button>
|
||||
<gl-button
|
||||
v-if="canCancel"
|
||||
:data-track-action="$options.EVENT_ACTIONS_CLICK"
|
||||
:data-track-label="$options.EVENT_LABEL_MODAL"
|
||||
data-track-property="cancel"
|
||||
@click="closeModal"
|
||||
>{{ i18n.cancel }}
|
||||
</gl-button>
|
||||
|
||||
<gl-button v-if="registered" variant="confirm" category="primary" @click="closeModal"
|
||||
<gl-button
|
||||
v-if="registered"
|
||||
variant="confirm"
|
||||
category="primary"
|
||||
:data-track-action="$options.EVENT_ACTIONS_CLICK"
|
||||
:data-track-label="$options.EVENT_LABEL_MODAL"
|
||||
data-track-property="close"
|
||||
@click="closeModal"
|
||||
>{{ i18n.close }}
|
||||
</gl-button>
|
||||
|
||||
<gl-button
|
||||
v-else-if="isRegisterModal"
|
||||
v-else-if="isAgentRegistrationModal"
|
||||
:disabled="!nextButtonDisabled"
|
||||
variant="confirm"
|
||||
category="primary"
|
||||
:data-track-action="$options.EVENT_ACTIONS_CLICK"
|
||||
:data-track-label="$options.EVENT_LABEL_MODAL"
|
||||
data-track-property="register"
|
||||
@click="registerAgent"
|
||||
>{{ i18n.registerAgentButton }}
|
||||
</gl-button>
|
||||
|
||||
<gl-button
|
||||
v-if="isInstallModal"
|
||||
v-if="isEmptyStateModal"
|
||||
:href="repositoryPath"
|
||||
variant="confirm"
|
||||
category="secondary"
|
||||
|
@ -371,7 +409,14 @@ export default {
|
|||
>{{ i18n.secondaryButton }}
|
||||
</gl-button>
|
||||
|
||||
<gl-button v-if="isInstallModal" variant="confirm" category="primary" @click="closeModal"
|
||||
<gl-button
|
||||
v-if="isEmptyStateModal"
|
||||
variant="confirm"
|
||||
category="primary"
|
||||
:data-track-action="$options.EVENT_ACTIONS_CLICK"
|
||||
:data-track-label="$options.EVENT_LABEL_MODAL"
|
||||
data-track-property="done"
|
||||
@click="closeModal"
|
||||
>{{ i18n.done }}
|
||||
</gl-button>
|
||||
</template>
|
||||
|
|
|
@ -65,7 +65,7 @@ export const STATUSES = {
|
|||
};
|
||||
|
||||
export const I18N_AGENT_MODAL = {
|
||||
register: {
|
||||
agent_registration: {
|
||||
registerAgentButton: s__('ClusterAgents|Register Agent'),
|
||||
close: __('Close'),
|
||||
cancel: __('Cancel'),
|
||||
|
@ -104,7 +104,7 @@ export const I18N_AGENT_MODAL = {
|
|||
registrationErrorTitle: __('Failed to register Agent'),
|
||||
unknownError: s__('ClusterAgents|An unknown error occurred. Please try again.'),
|
||||
},
|
||||
install: {
|
||||
empty_state: {
|
||||
modalTitle: s__('ClusterAgents|Install new Agent'),
|
||||
modalBody: s__(
|
||||
'ClusterAgents|To install an Agent you should create an agent directory in the Repository first. We recommend that you add the Agent configuration to the directory before you start the installation process.',
|
||||
|
@ -236,3 +236,13 @@ export const CLUSTERS_ACTIONS = {
|
|||
|
||||
export const AGENT = 'agent';
|
||||
export const CERTIFICATE_BASED = 'certificate_based';
|
||||
|
||||
export const EVENT_LABEL_MODAL = 'agent_registration_modal';
|
||||
export const EVENT_LABEL_TABS = 'kubernetes_section_tabs';
|
||||
export const EVENT_ACTIONS_OPEN = 'open_modal';
|
||||
export const EVENT_ACTIONS_SELECT = 'select_agent';
|
||||
export const EVENT_ACTIONS_CLICK = 'click_button';
|
||||
export const EVENT_ACTIONS_CHANGE = 'change_tab';
|
||||
|
||||
export const MODAL_TYPE_EMPTY = 'empty_state';
|
||||
export const MODAL_TYPE_REGISTER = 'agent_registration';
|
||||
|
|
|
@ -67,7 +67,7 @@ export default {
|
|||
data-qa-selector="dropdown_button"
|
||||
@click.stop="openDropdown()"
|
||||
>
|
||||
<gl-icon name="ellipsis_v" /> <gl-icon name="chevron-down" />
|
||||
<gl-icon name="ellipsis_v" />
|
||||
</button>
|
||||
<ul ref="dropdownMenu" class="dropdown-menu dropdown-menu-right">
|
||||
<template v-if="type === 'tree'">
|
||||
|
|
|
@ -2099,6 +2099,10 @@ This endpoint:
|
|||
|
||||
- Deletes a project including all associated resources (including issues and
|
||||
merge requests).
|
||||
- In [GitLab 12.6](https://gitlab.com/gitlab-org/gitlab/-/issues/32935) and later, on
|
||||
[Premium or higher](https://about.gitlab.com/pricing/) tiers,
|
||||
[delayed project deletion](../user/project/settings/index.md#delayed-project-deletion)
|
||||
is applied if enabled.
|
||||
- From [GitLab 13.2](https://gitlab.com/gitlab-org/gitlab/-/issues/220382) on
|
||||
[Premium or higher](https://about.gitlab.com/pricing/) tiers, group
|
||||
administrators can [configure](../user/group/index.md#enable-delayed-project-deletion)
|
||||
|
|
|
@ -22,8 +22,7 @@ This tutorial assumes you are familiar with GitLab CI/CD and Vault.
|
|||
To follow along, you must have:
|
||||
|
||||
- An account on GitLab.
|
||||
- A running Vault server and access to it is required to configure authentication and create roles
|
||||
and policies. For HashiCorp Vaults, this can be the Open Source or Enterprise version.
|
||||
- Access to a running Vault server (at least v1.2.0) to configure authentication and to create roles and policies. For HashiCorp Vaults, this can be the Open Source or Enterprise version.
|
||||
|
||||
NOTE:
|
||||
You must replace the `vault.example.com` URL below with the URL of your Vault server, and `gitlab.example.com` with the URL of your GitLab instance.
|
||||
|
|
|
@ -53,6 +53,7 @@ and supports multiple secrets engines.
|
|||
|
||||
To configure your Vault server:
|
||||
|
||||
1. Ensure your Vault server is running on version 1.2.0 or higher.
|
||||
1. Enable the authentication method by running these commands. They provide your Vault
|
||||
server the [JSON Web Key Set](https://tools.ietf.org/html/rfc7517) (JWKS) endpoint for your GitLab instance, so Vault
|
||||
can fetch the public signing key and verify the JSON Web Token (JWT) when authenticating:
|
||||
|
|
|
@ -97,8 +97,8 @@ delete a project. To allow only users with the Administrator role to delete proj
|
|||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/255449) in GitLab 14.2 for groups created after August 12, 2021.
|
||||
|
||||
Projects in a group (but not a personal namespace) can be deleted after a delayed period.
|
||||
You can [configure it in group settings](../../group/index.md#enable-delayed-project-deletion).
|
||||
[Delayed project deletion](../../project/settings/index.md#delayed-project-deletion) allows projects in a group (not a personal namespace)
|
||||
to be deleted after a period of delay.
|
||||
|
||||
To enable delayed project deletion by default in new groups:
|
||||
|
||||
|
@ -110,14 +110,13 @@ To enable delayed project deletion by default in new groups:
|
|||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/32935) in GitLab 12.6.
|
||||
|
||||
By default, a project marked for deletion is permanently removed with immediate effect.
|
||||
See [delayed project deletion](../../project/settings/index.md#delayed-project-deletion) to learn more.
|
||||
By default, a group marked for deletion is permanently removed after seven days.
|
||||
|
||||
WARNING:
|
||||
The default behavior of [Delayed Project deletion](https://gitlab.com/gitlab-org/gitlab/-/issues/32935) in GitLab 12.6 was changed to
|
||||
[Immediate deletion](https://gitlab.com/gitlab-org/gitlab/-/issues/220382) in GitLab 13.2.
|
||||
|
||||
Projects in a group (but not a personal namespace) can be deleted after a delayed period, by
|
||||
[configuring in Group Settings](../../group/index.md#enable-delayed-project-deletion).
|
||||
The default period is seven days, and can be changed. Setting this period to `0` enables immediate removal
|
||||
of projects or groups.
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
INFO:
|
||||
Want to try out container scanning?
|
||||
[Get a free 30-day trial GitLab Ultimate](https://about.gitlab.com/free-trial?glm_source=docs.gitlab.com&glm_content=u-container-scanning-docs).
|
||||
[Get a free 30-day trial of GitLab Ultimate](https://about.gitlab.com/free-trial?glm_source=docs.gitlab.com&glm_content=u-container-scanning-docs).
|
||||
|
||||
Your application's Docker image may itself be based on Docker images that contain known
|
||||
vulnerabilities. By including an extra job in your pipeline that scans for those vulnerabilities and
|
||||
|
@ -135,6 +135,7 @@ You can [configure](#customizing-the-container-scanning-settings) analyzers by u
|
|||
| `CI_APPLICATION_TAG` | `$CI_COMMIT_SHA` | Docker repository tag for the image to be scanned. | All |
|
||||
| `CS_ANALYZER_IMAGE` | `registry.gitlab.com/security-products/container-scanning:4` | Docker image of the analyzer. | All |
|
||||
| `CS_DEFAULT_BRANCH_IMAGE` | `""` | The name of the `DOCKER_IMAGE` on the default branch. See [Setting the default branch image](#setting-the-default-branch-image) for more details. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/338877) in GitLab 14.5. | All |
|
||||
| `CS_DISABLE_DEPENDENCY_SCAN` | `"true"` | Disable Dependency Scanning for packages installed in the scanned image. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/345434) in GitLab 14.6. | All |
|
||||
| `CS_DOCKER_INSECURE` | `"false"` | Allow access to secure Docker registries using HTTPS without validating the certificates. | All |
|
||||
| `CS_REGISTRY_INSECURE` | `"false"` | Allow access to insecure registries (HTTP only). Should only be set to `true` when testing the image locally. Works with all scanners, but the registry must listen on port `80/tcp` for Trivy to work. | All |
|
||||
| `CS_SEVERITY_THRESHOLD` | `UNKNOWN` | Severity level threshold. The scanner outputs vulnerabilities with severity level higher than or equal to this threshold. Supported levels are Unknown, Low, Medium, High, and Critical. | Trivy |
|
||||
|
|
|
@ -672,12 +672,9 @@ To disable group mentions:
|
|||
> - [Inheritance and enforcement added](https://gitlab.com/gitlab-org/gitlab/-/issues/321724) in GitLab 13.11.
|
||||
> - [Instance setting to enable by default added](https://gitlab.com/gitlab-org/gitlab/-/issues/255449) in GitLab 14.2.
|
||||
|
||||
Projects can be configured to be deleted either:
|
||||
|
||||
- Immediately.
|
||||
- After a delayed interval. During this interval period, the projects are in a read-only state
|
||||
and can be restored. The default interval period is seven days but
|
||||
[is configurable](../admin_area/settings/visibility_and_access_controls.md#default-deletion-delay).
|
||||
[Delayed project deletion](../project/settings/index.md#delayed-project-deletion) can be enabled for groups. When enabled, projects in
|
||||
the group are deleted after a period of delay. During this period, projects are in a read-only state and can be restored. The default
|
||||
period is seven days but [is configurable at the instance level](../admin_area/settings/visibility_and_access_controls.md#default-deletion-delay).
|
||||
|
||||
On self-managed GitLab, projects are deleted immediately by default.
|
||||
In GitLab 14.2 and later, an administrator can
|
||||
|
|
|
@ -248,7 +248,7 @@ To delete a project, first navigate to the home page for that project.
|
|||
1. Click **Delete project**
|
||||
1. Confirm this action by typing in the expected text.
|
||||
|
||||
Projects in personal namespaces are deleted immediately on request. For information on delayed deletion of projects in a group, please see [Enable delayed project deletion](../group/index.md#enable-delayed-project-deletion).
|
||||
Projects in personal namespaces are deleted immediately on request. For information on delayed deletion of projects in a group, please see [delayed project deletion](settings/index.md#delayed-project-deletion).
|
||||
|
||||
## Project settings
|
||||
|
||||
|
|
|
@ -38,7 +38,8 @@ container_scanning:
|
|||
artifacts:
|
||||
reports:
|
||||
container_scanning: gl-container-scanning-report.json
|
||||
paths: [gl-container-scanning-report.json]
|
||||
dependency_scanning: gl-dependency-scanning-report.json
|
||||
paths: [gl-container-scanning-report.json, gl-dependency-scanning-report.json]
|
||||
dependencies: []
|
||||
script:
|
||||
- gtcs scan
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { GlTabs, GlTab } from '@gitlab/ui';
|
||||
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import { mockTracking } from 'helpers/tracking_helper';
|
||||
import ClustersMainView from '~/clusters_list/components/clusters_main_view.vue';
|
||||
import InstallAgentModal from '~/clusters_list/components/install_agent_modal.vue';
|
||||
import {
|
||||
|
@ -8,12 +9,15 @@ import {
|
|||
CLUSTERS_TABS,
|
||||
MAX_CLUSTERS_LIST,
|
||||
MAX_LIST_COUNT,
|
||||
EVENT_LABEL_TABS,
|
||||
EVENT_ACTIONS_CHANGE,
|
||||
} from '~/clusters_list/constants';
|
||||
|
||||
const defaultBranchName = 'default-branch';
|
||||
|
||||
describe('ClustersMainViewComponent', () => {
|
||||
let wrapper;
|
||||
let trackingSpy;
|
||||
|
||||
const propsData = {
|
||||
defaultBranchName,
|
||||
|
@ -23,6 +27,7 @@ describe('ClustersMainViewComponent', () => {
|
|||
wrapper = shallowMountExtended(ClustersMainView, {
|
||||
propsData,
|
||||
});
|
||||
trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
@ -71,6 +76,7 @@ describe('ClustersMainViewComponent', () => {
|
|||
beforeEach(() => {
|
||||
findComponent().vm.$emit('changeTab', AGENT);
|
||||
});
|
||||
|
||||
it('changes the tab', () => {
|
||||
expect(findTabs().attributes('value')).toBe('1');
|
||||
});
|
||||
|
@ -78,5 +84,13 @@ describe('ClustersMainViewComponent', () => {
|
|||
it('passes correct max-agents param to the modal', () => {
|
||||
expect(findModal().props('maxAgents')).toBe(MAX_LIST_COUNT);
|
||||
});
|
||||
|
||||
it('sends the correct tracking event', () => {
|
||||
findTabs().vm.$emit('input', 1);
|
||||
expect(trackingSpy).toHaveBeenCalledWith(undefined, EVENT_ACTIONS_CHANGE, {
|
||||
label: EVENT_LABEL_TABS,
|
||||
property: AGENT,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,9 +2,18 @@ import { GlAlert, GlButton, GlFormInputGroup } from '@gitlab/ui';
|
|||
import { createLocalVue } from '@vue/test-utils';
|
||||
import VueApollo from 'vue-apollo';
|
||||
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import { mockTracking } from 'helpers/tracking_helper';
|
||||
import AvailableAgentsDropdown from '~/clusters_list/components/available_agents_dropdown.vue';
|
||||
import InstallAgentModal from '~/clusters_list/components/install_agent_modal.vue';
|
||||
import { I18N_AGENT_MODAL, MAX_LIST_COUNT } from '~/clusters_list/constants';
|
||||
import {
|
||||
I18N_AGENT_MODAL,
|
||||
MAX_LIST_COUNT,
|
||||
EVENT_LABEL_MODAL,
|
||||
EVENT_ACTIONS_OPEN,
|
||||
EVENT_ACTIONS_SELECT,
|
||||
MODAL_TYPE_EMPTY,
|
||||
MODAL_TYPE_REGISTER,
|
||||
} from '~/clusters_list/constants';
|
||||
import getAgentsQuery from '~/clusters_list/graphql/queries/get_agents.query.graphql';
|
||||
import getAgentConfigurations from '~/clusters_list/graphql/queries/agent_configurations.query.graphql';
|
||||
import createAgentMutation from '~/clusters_list/graphql/mutations/create_agent.mutation.graphql';
|
||||
|
@ -34,6 +43,7 @@ const maxAgents = MAX_LIST_COUNT;
|
|||
describe('InstallAgentModal', () => {
|
||||
let wrapper;
|
||||
let apolloProvider;
|
||||
let trackingSpy;
|
||||
|
||||
const configurations = [{ agentName: 'agent-name' }];
|
||||
const apolloQueryResponse = {
|
||||
|
@ -56,7 +66,7 @@ describe('InstallAgentModal', () => {
|
|||
const findActionButton = () => findButtonByVariant('confirm');
|
||||
const findCancelButton = () => findButtonByVariant('default');
|
||||
const findSecondaryButton = () => wrapper.findByTestId('agent-secondary-button');
|
||||
const findImage = () => wrapper.findByRole('img', { alt: I18N_AGENT_MODAL.install.altText });
|
||||
const findImage = () => wrapper.findByRole('img', { alt: I18N_AGENT_MODAL.empty_state.altText });
|
||||
|
||||
const expectDisabledAttribute = (element, disabled) => {
|
||||
if (disabled) {
|
||||
|
@ -121,6 +131,7 @@ describe('InstallAgentModal', () => {
|
|||
[getAgentConfigurations, jest.fn().mockResolvedValue(apolloQueryResponse)],
|
||||
]);
|
||||
createWrapper();
|
||||
trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
@ -129,7 +140,7 @@ describe('InstallAgentModal', () => {
|
|||
});
|
||||
|
||||
describe('when agent configurations are present', () => {
|
||||
const i18n = I18N_AGENT_MODAL.register;
|
||||
const i18n = I18N_AGENT_MODAL.agent_registration;
|
||||
|
||||
describe('initial state', () => {
|
||||
it('renders the dropdown for available agents', () => {
|
||||
|
@ -150,6 +161,14 @@ describe('InstallAgentModal', () => {
|
|||
expect(findActionButton().text()).toBe(i18n.registerAgentButton);
|
||||
expectDisabledAttribute(findActionButton(), true);
|
||||
});
|
||||
|
||||
it('sends the event with the modalType', () => {
|
||||
findModal().vm.$emit('show');
|
||||
expect(trackingSpy).toHaveBeenCalledWith(undefined, EVENT_ACTIONS_OPEN, {
|
||||
label: EVENT_LABEL_MODAL,
|
||||
property: MODAL_TYPE_REGISTER,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('an agent is selected', () => {
|
||||
|
@ -161,6 +180,12 @@ describe('InstallAgentModal', () => {
|
|||
expect(findActionButton().isVisible()).toBe(true);
|
||||
expectDisabledAttribute(findActionButton(), false);
|
||||
});
|
||||
|
||||
it('sends the correct tracking event', () => {
|
||||
expect(trackingSpy).toHaveBeenCalledWith(undefined, EVENT_ACTIONS_SELECT, {
|
||||
label: EVENT_LABEL_MODAL,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('registering an agent', () => {
|
||||
|
@ -247,7 +272,7 @@ describe('InstallAgentModal', () => {
|
|||
});
|
||||
|
||||
describe('when there are no agent configurations present', () => {
|
||||
const i18n = I18N_AGENT_MODAL.install;
|
||||
const i18n = I18N_AGENT_MODAL.empty_state;
|
||||
const apolloQueryEmptyResponse = {
|
||||
data: {
|
||||
project: {
|
||||
|
@ -272,5 +297,13 @@ describe('InstallAgentModal', () => {
|
|||
expect(findSecondaryButton().isVisible()).toBe(true);
|
||||
expect(findSecondaryButton().text()).toBe(i18n.secondaryButton);
|
||||
});
|
||||
|
||||
it('sends the event with the modalType', () => {
|
||||
findModal().vm.$emit('show');
|
||||
expect(trackingSpy).toHaveBeenCalledWith(undefined, EVENT_ACTIONS_OPEN, {
|
||||
label: EVENT_LABEL_MODAL,
|
||||
property: MODAL_TYPE_EMPTY,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -31,9 +31,13 @@ module Database
|
|||
# See https://gitlab.com/gitlab-org/gitlab/-/issues/339396
|
||||
return if sql.include?("DISABLE TRIGGER") || sql.include?("ENABLE TRIGGER")
|
||||
|
||||
# PgQuery might fail in some cases due to limited nesting:
|
||||
# https://github.com/pganalyze/pg_query/issues/209
|
||||
tables = PgQuery.parse(sql).tables
|
||||
tables = begin
|
||||
PgQuery.parse(sql).tables
|
||||
rescue PgQuery::ParseError
|
||||
# PgQuery might fail in some cases due to limited nesting:
|
||||
# https://github.com/pganalyze/pg_query/issues/209
|
||||
return
|
||||
end
|
||||
|
||||
schemas = ::Gitlab::Database::GitlabSchema.table_schemas(tables)
|
||||
|
||||
|
|
|
@ -39,6 +39,15 @@ RSpec.describe Database::PreventCrossJoins do
|
|||
expect { main_and_ci_query_allowlist_nested }.not_to raise_error
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there is a parser error' do
|
||||
it 'does not raise parse PGQuery::ParseError' do
|
||||
# Since this is in an invalid query it still raises from ActiveRecord
|
||||
# but this tests that we rescue the PGQuery::ParseError which would
|
||||
# have otherwise raised first
|
||||
expect { ApplicationRecord.connection.execute('SELECT SELECT FROM SELECT') }.to raise_error(ActiveRecord::StatementInvalid)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue