Commit 48c642f5 authored by Alex Kalderimis's avatar Alex Kalderimis

Merge branch...

Merge branch '331169-alert-project-admin-that-their-project-s-cleanup-policy-is-turned-on' into 'master'

Alert project admin that their project's cleanup policy is turned on

See merge request gitlab-org/gitlab!63496
parents 178d426b 17dda274
...@@ -9,17 +9,28 @@ import { ...@@ -9,17 +9,28 @@ import {
UNAVAILABLE_ADMIN_FEATURE_TEXT, UNAVAILABLE_ADMIN_FEATURE_TEXT,
} from '~/packages_and_registries/settings/project/constants'; } from '~/packages_and_registries/settings/project/constants';
import expirationPolicyQuery from '~/packages_and_registries/settings/project/graphql/queries/get_expiration_policy.query.graphql'; import expirationPolicyQuery from '~/packages_and_registries/settings/project/graphql/queries/get_expiration_policy.query.graphql';
import CleanupPolicyEnabledAlert from '~/packages_and_registries/shared/components/cleanup_policy_enabled_alert.vue';
import SettingsBlock from '~/vue_shared/components/settings/settings_block.vue';
import SettingsForm from './settings_form.vue'; import SettingsForm from './settings_form.vue';
export default { export default {
components: { components: {
SettingsBlock,
SettingsForm, SettingsForm,
CleanupPolicyEnabledAlert,
GlAlert, GlAlert,
GlSprintf, GlSprintf,
GlLink, GlLink,
}, },
inject: ['projectPath', 'isAdmin', 'adminSettingsPath', 'enableHistoricEntries'], inject: [
'projectPath',
'isAdmin',
'adminSettingsPath',
'enableHistoricEntries',
'helpPagePath',
'showCleanupPolicyOnAlert',
],
i18n: { i18n: {
UNAVAILABLE_FEATURE_TITLE, UNAVAILABLE_FEATURE_TITLE,
UNAVAILABLE_FEATURE_INTRO_TEXT, UNAVAILABLE_FEATURE_INTRO_TEXT,
...@@ -75,32 +86,53 @@ export default { ...@@ -75,32 +86,53 @@ export default {
</script> </script>
<template> <template>
<div> <section data-testid="registry-settings-app">
<settings-form <cleanup-policy-enabled-alert v-if="showCleanupPolicyOnAlert" :project-path="projectPath" />
v-if="!isDisabled" <settings-block default-expanded>
v-model="workingCopy" <template #title> {{ __('Clean up image tags') }}</template>
:is-loading="$apollo.queries.containerExpirationPolicy.loading" <template #description>
:is-edited="isEdited" <span data-testid="description">
@reset="restoreOriginal" <gl-sprintf
/> :message="
<template v-else> __(
<gl-alert 'Save space and find images in the container Registry. remove unneeded tags and keep only the ones you want. %{linkStart}How does cleanup work?%{linkEnd}',
v-if="showDisabledFormMessage" )
:dismissible="false" "
:title="$options.i18n.UNAVAILABLE_FEATURE_TITLE" >
variant="tip" <template #link="{ content }">
> <gl-link :href="helpPagePath" target="_blank">{{ content }}</gl-link>
{{ $options.i18n.UNAVAILABLE_FEATURE_INTRO_TEXT }} </template>
</gl-sprintf>
</span>
</template>
<template #default>
<settings-form
v-if="!isDisabled"
v-model="workingCopy"
:is-loading="$apollo.queries.containerExpirationPolicy.loading"
:is-edited="isEdited"
@reset="restoreOriginal"
/>
<template v-else>
<gl-alert
v-if="showDisabledFormMessage"
:dismissible="false"
:title="$options.i18n.UNAVAILABLE_FEATURE_TITLE"
variant="tip"
>
{{ $options.i18n.UNAVAILABLE_FEATURE_INTRO_TEXT }}
<gl-sprintf :message="unavailableFeatureMessage"> <gl-sprintf :message="unavailableFeatureMessage">
<template #link="{ content }"> <template #link="{ content }">
<gl-link :href="adminSettingsPath" target="_blank">{{ content }}</gl-link> <gl-link :href="adminSettingsPath" target="_blank">{{ content }}</gl-link>
</template> </template>
</gl-sprintf> </gl-sprintf>
</gl-alert> </gl-alert>
<gl-alert v-else-if="fetchSettingsError" variant="warning" :dismissible="false"> <gl-alert v-else-if="fetchSettingsError" variant="warning" :dismissible="false">
<gl-sprintf :message="$options.i18n.FETCH_SETTINGS_ERROR_MESSAGE" /> <gl-sprintf :message="$options.i18n.FETCH_SETTINGS_ERROR_MESSAGE" />
</gl-alert> </gl-alert>
</template> </template>
</div> </template>
</settings-block>
</section>
</template> </template>
...@@ -19,6 +19,8 @@ export default () => { ...@@ -19,6 +19,8 @@ export default () => {
projectPath, projectPath,
adminSettingsPath, adminSettingsPath,
tagsRegexHelpPagePath, tagsRegexHelpPagePath,
helpPagePath,
showCleanupPolicyOnAlert,
} = el.dataset; } = el.dataset;
return new Vue({ return new Vue({
el, el,
...@@ -32,6 +34,8 @@ export default () => { ...@@ -32,6 +34,8 @@ export default () => {
projectPath, projectPath,
adminSettingsPath, adminSettingsPath,
tagsRegexHelpPagePath, tagsRegexHelpPagePath,
helpPagePath,
showCleanupPolicyOnAlert: parseBoolean(showCleanupPolicyOnAlert),
}, },
render(createElement) { render(createElement) {
return createElement('registry-settings-app', {}); return createElement('registry-settings-app', {});
......
<script>
import { GlSprintf, GlAlert, GlLink } from '@gitlab/ui';
import { s__ } from '~/locale';
import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
export default {
components: {
GlAlert,
GlLink,
GlSprintf,
LocalStorageSync,
},
props: {
projectPath: {
type: String,
required: true,
},
cleanupPoliciesSettingsPath: {
type: String,
required: false,
default: '',
},
},
data() {
return {
dismissed: false,
};
},
computed: {
storageKey() {
return `cleanup_policy_enabled_for_project_${this.projectPath}`;
},
},
i18n: {
message: s__(
'ContainerRegistry|Cleanup policies are now available for this project. %{linkStart}Click here to get started.%{linkEnd}',
),
},
};
</script>
<template>
<local-storage-sync v-model="dismissed" :storage-key="storageKey">
<gl-alert v-if="!dismissed" class="gl-mt-2" dismissible @dismiss="dismissed = true">
<gl-sprintf :message="$options.i18n.message">
<template #link="{ content }">
<gl-link v-if="cleanupPoliciesSettingsPath" :href="cleanupPoliciesSettingsPath">{{
content
}}</gl-link>
</template>
</gl-sprintf>
</gl-alert>
</local-storage-sync>
</template>
...@@ -34,6 +34,7 @@ export default () => { ...@@ -34,6 +34,7 @@ export default () => {
expirationPolicy, expirationPolicy,
isGroupPage, isGroupPage,
isAdmin, isAdmin,
showCleanupPolicyOnAlert,
showUnfinishedTagCleanupCallout, showUnfinishedTagCleanupCallout,
...config ...config
} = el.dataset; } = el.dataset;
...@@ -64,6 +65,7 @@ export default () => { ...@@ -64,6 +65,7 @@ export default () => {
expirationPolicy: expirationPolicy ? JSON.parse(expirationPolicy) : undefined, expirationPolicy: expirationPolicy ? JSON.parse(expirationPolicy) : undefined,
isGroupPage: parseBoolean(isGroupPage), isGroupPage: parseBoolean(isGroupPage),
isAdmin: parseBoolean(isAdmin), isAdmin: parseBoolean(isAdmin),
showCleanupPolicyOnAlert: parseBoolean(showCleanupPolicyOnAlert),
showUnfinishedTagCleanupCallout: parseBoolean(showUnfinishedTagCleanupCallout), showUnfinishedTagCleanupCallout: parseBoolean(showUnfinishedTagCleanupCallout),
}, },
/* eslint-disable @gitlab/require-i18n-strings */ /* eslint-disable @gitlab/require-i18n-strings */
......
...@@ -11,6 +11,7 @@ import { ...@@ -11,6 +11,7 @@ import {
import { get } from 'lodash'; import { get } from 'lodash';
import getContainerRepositoriesQuery from 'shared_queries/container_registry/get_container_repositories.query.graphql'; import getContainerRepositoriesQuery from 'shared_queries/container_registry/get_container_repositories.query.graphql';
import createFlash from '~/flash'; import createFlash from '~/flash';
import CleanupPolicyEnabledAlert from '~/packages_and_registries/shared/components/cleanup_policy_enabled_alert.vue';
import { FILTERED_SEARCH_TERM } from '~/packages_and_registries/shared/constants'; import { FILTERED_SEARCH_TERM } from '~/packages_and_registries/shared/constants';
import { extractFilterAndSorting } from '~/packages_and_registries/shared/utils'; import { extractFilterAndSorting } from '~/packages_and_registries/shared/utils';
import Tracking from '~/tracking'; import Tracking from '~/tracking';
...@@ -61,6 +62,7 @@ export default { ...@@ -61,6 +62,7 @@ export default {
RegistryHeader, RegistryHeader,
DeleteImage, DeleteImage,
RegistrySearch, RegistrySearch,
CleanupPolicyEnabledAlert,
}, },
directives: { directives: {
GlTooltip: GlTooltipDirective, GlTooltip: GlTooltipDirective,
...@@ -283,6 +285,12 @@ export default { ...@@ -283,6 +285,12 @@ export default {
</gl-sprintf> </gl-sprintf>
</gl-alert> </gl-alert>
<cleanup-policy-enabled-alert
v-if="config.showCleanupPolicyOnAlert"
:project-path="config.projectPath"
:cleanup-policies-settings-path="config.cleanupPoliciesSettingsPath"
/>
<gl-empty-state <gl-empty-state
v-if="config.characterError" v-if="config.characterError"
:title="$options.i18n.CONNECTION_ERROR_TITLE" :title="$options.i18n.CONNECTION_ERROR_TITLE"
......
...@@ -53,4 +53,14 @@ module PackagesHelper ...@@ -53,4 +53,14 @@ module PackagesHelper
category = args.delete(:category) || self.class.name category = args.delete(:category) || self.class.name
::Gitlab::Tracking.event(category, event_name.to_s, **args) ::Gitlab::Tracking.event(category, event_name.to_s, **args)
end end
def show_cleanup_policy_on_alert(project)
Gitlab.com? &&
Gitlab.config.registry.enabled &&
project.container_registry_enabled &&
!Gitlab::CurrentSettings.container_expiration_policies_enable_historic_entries &&
Feature.enabled?(:container_expiration_policies_historic_entry, project) &&
project.container_expiration_policy.nil? &&
project.container_repositories.exists?
end
end end
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
"project_path": @project.full_path, "project_path": @project.full_path,
"gid_prefix": container_repository_gid_prefix, "gid_prefix": container_repository_gid_prefix,
"is_admin": current_user&.admin.to_s, "is_admin": current_user&.admin.to_s,
"show_cleanup_policy_on_alert": show_cleanup_policy_on_alert(@project).to_s,
"cleanup_policies_settings_path": project_settings_packages_and_registries_path(@project),
character_error: @character_error.to_s, character_error: @character_error.to_s,
user_callouts_path: user_callouts_path, user_callouts_path: user_callouts_path,
user_callout_id: UserCalloutsHelper::UNFINISHED_TAG_CLEANUP_CALLOUT, user_callout_id: UserCalloutsHelper::UNFINISHED_TAG_CLEANUP_CALLOUT,
......
...@@ -76,17 +76,7 @@ ...@@ -76,17 +76,7 @@
= render 'projects/triggers/index' = render 'projects/triggers/index'
- if settings_container_registry_expiration_policy_available?(@project) - if settings_container_registry_expiration_policy_available?(@project)
%section.settings.no-animate#js-registry-policies{ class: ('expanded' if expanded) } = render 'projects/registry/settings/index'
.settings-header
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
= _("Clean up image tags")
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded ? _('Collapse') : _('Expand')
%p
= _("Save space and find images in the Container Registry. Remove unneeded tags and keep only the ones you want.")
= link_to _('How does cleanup work?'), help_page_path('user/packages/container_registry/index', anchor: 'cleanup-policy'), target: '_blank', rel: 'noopener noreferrer'
.settings-content
= render 'projects/registry/settings/index'
= render_if_exists 'projects/settings/ci_cd/auto_rollback', expanded: expanded = render_if_exists 'projects/settings/ci_cd/auto_rollback', expanded: expanded
......
- breadcrumb_title _('Packages & Registries') - breadcrumb_title _('Packages & Registries')
- page_title _('Packages & Registries') - page_title _('Packages & Registries')
- @content_class = 'limit-container-width' unless fluid_layout - @content_class = 'limit-container-width' unless fluid_layout
- expanded = true
%section.settings.no-animate#js-registry-policies{ class: ('expanded' if expanded) } #js-registry-settings{ data: { project_id: @project.id,
.settings-header project_path: @project.full_path,
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only cadence_options: cadence_options.to_json,
= _("Clean up image tags") keep_n_options: keep_n_options.to_json,
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } older_than_options: older_than_options.to_json,
= expanded ? _('Collapse') : _('Expand') is_admin: current_user&.admin.to_s,
%p admin_settings_path: ci_cd_admin_application_settings_path(anchor: 'js-registry-settings'),
= _("Save space and find images in the Container Registry. Remove unneeded tags and keep only the ones you want.") enable_historic_entries: container_expiration_policies_historic_entry_enabled?(@project).to_s,
= link_to _('How does cleanup work?'), help_page_path('user/packages/container_registry/index', anchor: 'cleanup-policy'), target: '_blank', rel: 'noopener noreferrer' help_page_path: help_page_path('user/packages/container_registry/index', anchor: 'cleanup-policy'),
.settings-content show_cleanup_policy_on_alert: show_cleanup_policy_on_alert(@project).to_s,
= render 'projects/registry/settings/index' tags_regex_help_page_path: help_page_path('user/packages/container_registry/index', anchor: 'regex-pattern-examples') } }
...@@ -8563,6 +8563,9 @@ msgstr "" ...@@ -8563,6 +8563,9 @@ msgstr ""
msgid "ContainerRegistry|Cleanup pending" msgid "ContainerRegistry|Cleanup pending"
msgstr "" msgstr ""
msgid "ContainerRegistry|Cleanup policies are now available for this project. %{linkStart}Click here to get started.%{linkEnd}"
msgstr ""
msgid "ContainerRegistry|Cleanup policy for tags is disabled" msgid "ContainerRegistry|Cleanup policy for tags is disabled"
msgstr "" msgstr ""
...@@ -16358,9 +16361,6 @@ msgstr "" ...@@ -16358,9 +16361,6 @@ msgstr ""
msgid "How do I set up this service?" msgid "How do I set up this service?"
msgstr "" msgstr ""
msgid "How does cleanup work?"
msgstr ""
msgid "How it works" msgid "How it works"
msgstr "" msgstr ""
...@@ -28402,7 +28402,7 @@ msgstr "" ...@@ -28402,7 +28402,7 @@ msgstr ""
msgid "Save pipeline schedule" msgid "Save pipeline schedule"
msgstr "" msgstr ""
msgid "Save space and find images in the Container Registry. Remove unneeded tags and keep only the ones you want." msgid "Save space and find images in the container Registry. remove unneeded tags and keep only the ones you want. %{linkStart}How does cleanup work?%{linkEnd}"
msgstr "" msgstr ""
msgid "Saved scan settings and target site settings which are reusable." msgid "Saved scan settings and target site settings which are reusable."
......
...@@ -24,14 +24,14 @@ RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration p ...@@ -24,14 +24,14 @@ RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration p
it 'shows available section' do it 'shows available section' do
subject subject
settings_block = find('#js-registry-policies') settings_block = find('[data-testid="registry-settings-app"]')
expect(settings_block).to have_text 'Clean up image tags' expect(settings_block).to have_text 'Clean up image tags'
end end
it 'saves cleanup policy submit the form' do it 'saves cleanup policy submit the form' do
subject subject
within '#js-registry-policies' do within '[data-testid="registry-settings-app"]' do
select('Every day', from: 'Run cleanup') select('Every day', from: 'Run cleanup')
select('50 tags per image name', from: 'Keep the most recent:') select('50 tags per image name', from: 'Keep the most recent:')
fill_in('Keep tags matching:', with: 'stable') fill_in('Keep tags matching:', with: 'stable')
...@@ -49,7 +49,7 @@ RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration p ...@@ -49,7 +49,7 @@ RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration p
it 'does not save cleanup policy submit form with invalid regex' do it 'does not save cleanup policy submit form with invalid regex' do
subject subject
within '#js-registry-policies' do within '[data-testid="registry-settings-app"]' do
fill_in('Remove tags matching:', with: '*-production') fill_in('Remove tags matching:', with: '*-production')
submit_button = find('[data-testid="save-button"') submit_button = find('[data-testid="save-button"')
...@@ -80,7 +80,7 @@ RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration p ...@@ -80,7 +80,7 @@ RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration p
it 'displays the expected result' do it 'displays the expected result' do
subject subject
within '#js-registry-policies' do within '[data-testid="registry-settings-app"]' do
case result case result
when :available_section when :available_section
expect(find('[data-testid="enable-toggle"]')).to have_content('Disabled - Tags will not be automatically deleted.') expect(find('[data-testid="enable-toggle"]')).to have_content('Disabled - Tags will not be automatically deleted.')
...@@ -98,7 +98,7 @@ RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration p ...@@ -98,7 +98,7 @@ RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration p
it 'does not exists' do it 'does not exists' do
subject subject
expect(page).not_to have_selector('#js-registry-policies') expect(page).not_to have_selector('[data-testid="registry-settings-app"]')
end end
end end
...@@ -108,7 +108,7 @@ RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration p ...@@ -108,7 +108,7 @@ RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration p
it 'does not exists' do it 'does not exists' do
subject subject
expect(page).not_to have_selector('#js-registry-policies') expect(page).not_to have_selector('[data-testid="registry-settings-app"]')
end end
end end
end end
......
...@@ -10,6 +10,8 @@ import { ...@@ -10,6 +10,8 @@ import {
UNAVAILABLE_USER_FEATURE_TEXT, UNAVAILABLE_USER_FEATURE_TEXT,
} from '~/packages_and_registries/settings/project/constants'; } from '~/packages_and_registries/settings/project/constants';
import expirationPolicyQuery from '~/packages_and_registries/settings/project/graphql/queries/get_expiration_policy.query.graphql'; import expirationPolicyQuery from '~/packages_and_registries/settings/project/graphql/queries/get_expiration_policy.query.graphql';
import CleanupPolicyEnabledAlert from '~/packages_and_registries/shared/components/cleanup_policy_enabled_alert.vue';
import SettingsBlock from '~/vue_shared/components/settings/settings_block.vue';
import { import {
expirationPolicyPayload, expirationPolicyPayload,
...@@ -28,15 +30,19 @@ describe('Registry Settings App', () => { ...@@ -28,15 +30,19 @@ describe('Registry Settings App', () => {
isAdmin: false, isAdmin: false,
adminSettingsPath: 'settingsPath', adminSettingsPath: 'settingsPath',
enableHistoricEntries: false, enableHistoricEntries: false,
helpPagePath: 'helpPagePath',
showCleanupPolicyOnAlert: false,
}; };
const findSettingsComponent = () => wrapper.find(SettingsForm); const findSettingsComponent = () => wrapper.find(SettingsForm);
const findAlert = () => wrapper.find(GlAlert); const findAlert = () => wrapper.find(GlAlert);
const findCleanupAlert = () => wrapper.findComponent(CleanupPolicyEnabledAlert);
const mountComponent = (provide = defaultProvidedValues, config) => { const mountComponent = (provide = defaultProvidedValues, config) => {
wrapper = shallowMount(component, { wrapper = shallowMount(component, {
stubs: { stubs: {
GlSprintf, GlSprintf,
SettingsBlock,
}, },
mocks: { mocks: {
$toast: { $toast: {
...@@ -66,6 +72,26 @@ describe('Registry Settings App', () => { ...@@ -66,6 +72,26 @@ describe('Registry Settings App', () => {
wrapper.destroy(); wrapper.destroy();
}); });
describe('cleanup is on alert', () => {
it('exist when showCleanupPolicyOnAlert is true and has the correct props', () => {
mountComponent({
...defaultProvidedValues,
showCleanupPolicyOnAlert: true,
});
expect(findCleanupAlert().exists()).toBe(true);
expect(findCleanupAlert().props()).toMatchObject({
projectPath: 'path',
});
});
it('is hidden when showCleanupPolicyOnAlert is false', async () => {
mountComponent();
expect(findCleanupAlert().exists()).toBe(false);
});
});
describe('isEdited status', () => { describe('isEdited status', () => {
it.each` it.each`
description | apiResponse | workingCopy | result description | apiResponse | workingCopy | result
......
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`CleanupPolicyEnabledAlert renders 1`] = `
<gl-alert-stub
class="gl-mt-2"
dismissible="true"
dismisslabel="Dismiss"
primarybuttonlink=""
primarybuttontext=""
secondarybuttonlink=""
secondarybuttontext=""
title=""
variant="info"
>
<gl-sprintf-stub
message="Cleanup policies are now available for this project. %{linkStart}Click here to get started.%{linkEnd}"
/>
</gl-alert-stub>
`;
import { GlAlert } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import component from '~/packages_and_registries/shared/components/cleanup_policy_enabled_alert.vue';
import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
describe('CleanupPolicyEnabledAlert', () => {
let wrapper;
const defaultProps = {
projectPath: 'foo',
cleanupPoliciesSettingsPath: 'label-bar',
};
const findAlert = () => wrapper.findComponent(GlAlert);
const mountComponent = (props) => {
wrapper = shallowMount(component, {
stubs: {
LocalStorageSync,
},
propsData: {
...defaultProps,
...props,
},
});
};
afterEach(() => {
wrapper.destroy();
});
it('renders', () => {
mountComponent();
expect(wrapper.element).toMatchSnapshot();
});
it('when dismissed is not visible', async () => {
mountComponent();
expect(findAlert().exists()).toBe(true);
findAlert().vm.$emit('dismiss');
await nextTick();
expect(findAlert().exists()).toBe(false);
});
});
...@@ -5,6 +5,7 @@ import VueApollo from 'vue-apollo'; ...@@ -5,6 +5,7 @@ import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper'; import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
import getContainerRepositoriesQuery from 'shared_queries/container_registry/get_container_repositories.query.graphql'; import getContainerRepositoriesQuery from 'shared_queries/container_registry/get_container_repositories.query.graphql';
import CleanupPolicyEnabledAlert from '~/packages_and_registries/shared/components/cleanup_policy_enabled_alert.vue';
import { FILTERED_SEARCH_TERM } from '~/packages_and_registries/shared/constants'; import { FILTERED_SEARCH_TERM } from '~/packages_and_registries/shared/constants';
import DeleteImage from '~/registry/explorer/components/delete_image.vue'; import DeleteImage from '~/registry/explorer/components/delete_image.vue';
import CliCommands from '~/registry/explorer/components/list_page/cli_commands.vue'; import CliCommands from '~/registry/explorer/components/list_page/cli_commands.vue';
...@@ -43,21 +44,22 @@ describe('List Page', () => { ...@@ -43,21 +44,22 @@ describe('List Page', () => {
let wrapper; let wrapper;
let apolloProvider; let apolloProvider;
const findDeleteModal = () => wrapper.find(GlModal); const findDeleteModal = () => wrapper.findComponent(GlModal);
const findSkeletonLoader = () => wrapper.find(GlSkeletonLoader); const findSkeletonLoader = () => wrapper.findComponent(GlSkeletonLoader);
const findEmptyState = () => wrapper.find(GlEmptyState); const findEmptyState = () => wrapper.findComponent(GlEmptyState);
const findCliCommands = () => wrapper.find(CliCommands); const findCliCommands = () => wrapper.findComponent(CliCommands);
const findProjectEmptyState = () => wrapper.find(ProjectEmptyState); const findProjectEmptyState = () => wrapper.findComponent(ProjectEmptyState);
const findGroupEmptyState = () => wrapper.find(GroupEmptyState); const findGroupEmptyState = () => wrapper.findComponent(GroupEmptyState);
const findRegistryHeader = () => wrapper.find(RegistryHeader); const findRegistryHeader = () => wrapper.findComponent(RegistryHeader);
const findDeleteAlert = () => wrapper.find(GlAlert); const findDeleteAlert = () => wrapper.findComponent(GlAlert);
const findImageList = () => wrapper.find(ImageList); const findImageList = () => wrapper.findComponent(ImageList);
const findRegistrySearch = () => wrapper.find(RegistrySearch); const findRegistrySearch = () => wrapper.findComponent(RegistrySearch);
const findEmptySearchMessage = () => wrapper.find('[data-testid="emptySearch"]'); const findEmptySearchMessage = () => wrapper.find('[data-testid="emptySearch"]');
const findDeleteImage = () => wrapper.find(DeleteImage); const findDeleteImage = () => wrapper.findComponent(DeleteImage);
const findCleanupAlert = () => wrapper.findComponent(CleanupPolicyEnabledAlert);
const waitForApolloRequestRender = async () => { const waitForApolloRequestRender = async () => {
jest.runOnlyPendingTimers(); jest.runOnlyPendingTimers();
...@@ -560,4 +562,33 @@ describe('List Page', () => { ...@@ -560,4 +562,33 @@ describe('List Page', () => {
}, },
); );
}); });
describe('cleanup is on alert', () => {
it('exist when showCleanupPolicyOnAlert is true and has the correct props', async () => {
mountComponent({
config: {
showCleanupPolicyOnAlert: true,
projectPath: 'foo',
isGroupPage: false,
cleanupPoliciesSettingsPath: 'bar',
},
});
await waitForApolloRequestRender();
expect(findCleanupAlert().exists()).toBe(true);
expect(findCleanupAlert().props()).toMatchObject({
projectPath: 'foo',
cleanupPoliciesSettingsPath: 'bar',
});
});
it('is hidden when showCleanupPolicyOnAlert is false', async () => {
mountComponent();
await waitForApolloRequestRender();
expect(findCleanupAlert().exists()).toBe(false);
});
});
}); });
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment