Commit 56dca689 authored by Vasilii Iakliushin's avatar Vasilii Iakliushin

Merge branch '342640-add-context-to-project-deletion-modal' into 'master'

Add additional project details to the user before deleting

See merge request gitlab-org/gitlab!71961
parents 704701cb 10541d3b
...@@ -18,12 +18,36 @@ export default { ...@@ -18,12 +18,36 @@ export default {
type: String, type: String,
required: true, required: true,
}, },
isFork: {
type: Boolean,
required: true,
},
issuesCount: {
type: Number,
required: true,
},
mergeRequestsCount: {
type: Number,
required: true,
},
forksCount: {
type: Number,
required: true,
},
starsCount: {
type: Number,
required: true,
},
}, },
strings: { strings: {
alertTitle: __('You are about to permanently delete this project'), alertTitle: __('You are about to permanently delete this project'),
alertBody: __( alertBody: __(
'Once a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc.', 'Once a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc.',
), ),
isNotForkMessage: __(
'This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:',
),
isForkMessage: __('This forked project has the following:'),
}, },
}; };
</script> </script>
...@@ -37,6 +61,38 @@ export default { ...@@ -37,6 +61,38 @@ export default {
:title="$options.strings.alertTitle" :title="$options.strings.alertTitle"
:dismissible="false" :dismissible="false"
> >
<p>
<gl-sprintf v-if="isFork" :message="$options.strings.isForkMessage" />
<gl-sprintf v-else :message="$options.strings.isNotForkMessage">
<template #strong="{ content }">
<strong>{{ content }}</strong>
</template>
</gl-sprintf>
</p>
<ul>
<li>
<gl-sprintf :message="n__('%d issue', '%d issues', issuesCount)">
<template #issuesCount>{{ issuesCount }}</template>
</gl-sprintf>
</li>
<li>
<gl-sprintf
:message="n__('%d merge requests', '%d merge requests', mergeRequestsCount)"
>
<template #mergeRequestsCount>{{ mergeRequestsCount }}</template>
</gl-sprintf>
</li>
<li>
<gl-sprintf :message="n__('%d fork', '%d forks', forksCount)">
<template #forksCount>{{ forksCount }}</template>
</gl-sprintf>
</li>
<li>
<gl-sprintf :message="n__('%d star', '%d stars', starsCount)">
<template #starsCount>{{ starsCount }}</template>
</gl-sprintf>
</li>
</ul>
<gl-sprintf :message="$options.strings.alertBody"> <gl-sprintf :message="$options.strings.alertBody">
<template #strong="{ content }"> <template #strong="{ content }">
<strong>{{ content }}</strong> <strong>{{ content }}</strong>
......
import Vue from 'vue'; import Vue from 'vue';
import { parseBoolean } from '~/lib/utils/common_utils';
import ProjectDeleteButton from './components/project_delete_button.vue'; import ProjectDeleteButton from './components/project_delete_button.vue';
export default (selector = '#js-project-delete-button') => { export default (selector = '#js-project-delete-button') => {
...@@ -6,7 +7,15 @@ export default (selector = '#js-project-delete-button') => { ...@@ -6,7 +7,15 @@ export default (selector = '#js-project-delete-button') => {
if (!el) return; if (!el) return;
const { confirmPhrase, formPath } = el.dataset; const {
confirmPhrase,
formPath,
isFork,
issuesCount,
mergeRequestsCount,
forksCount,
starsCount,
} = el.dataset;
// eslint-disable-next-line no-new // eslint-disable-next-line no-new
new Vue({ new Vue({
...@@ -16,6 +25,11 @@ export default (selector = '#js-project-delete-button') => { ...@@ -16,6 +25,11 @@ export default (selector = '#js-project-delete-button') => {
props: { props: {
confirmPhrase, confirmPhrase,
formPath, formPath,
isFork: parseBoolean(isFork),
issuesCount: parseInt(issuesCount, 10),
mergeRequestsCount: parseInt(mergeRequestsCount, 10),
forksCount: parseInt(forksCount, 10),
starsCount: parseInt(starsCount, 10),
}, },
}); });
}, },
......
# frozen_string_literal: true
module Projects
# Service class for counting and caching the number of all issues of a
# project.
class AllIssuesCountService < Projects::CountService
def relation_for_count
@project.issues
end
def cache_key_name
'all_issues_count'
end
end
end
# frozen_string_literal: true
module Projects
# Service class for counting and caching the number of all merge requests of
# a project.
class AllMergeRequestsCountService < Projects::CountService
def relation_for_count
@project.merge_requests
end
def cache_key_name
'all_merge_requests_count'
end
end
end
- return unless can?(current_user, :remove_project, project) - return unless can?(current_user, :remove_project, project)
- merge_requests_count = Projects::AllMergeRequestsCountService.new(project).count
- issues_count = Projects::AllIssuesCountService.new(project).count
.sub-section .sub-section
%h4.danger-title= _('Delete project') %h4.danger-title= _('Delete project')
...@@ -7,4 +9,4 @@ ...@@ -7,4 +9,4 @@
= link_to _('Learn more.'), help_page_path('user/project/settings/index', anchor: 'removing-a-fork-relationship'), target: '_blank', rel: 'noopener noreferrer' = link_to _('Learn more.'), help_page_path('user/project/settings/index', anchor: 'removing-a-fork-relationship'), target: '_blank', rel: 'noopener noreferrer'
%p %p
%strong= _('Deleted projects cannot be restored!') %strong= _('Deleted projects cannot be restored!')
#js-project-delete-button{ data: { form_path: project_path(project), confirm_phrase: delete_confirm_phrase(project) } } #js-project-delete-button{ data: { form_path: project_path(project), confirm_phrase: delete_confirm_phrase(project), is_fork: project.forked?.to_s, issues_count: number_with_delimiter(issues_count), merge_requests_count: number_with_delimiter(merge_requests_count), forks_count: number_with_delimiter(project.forks_count), stars_count: number_with_delimiter(project.star_count) } }
<script> <script>
import { GlLink, GlIcon, GlSprintf } from '@gitlab/ui'; import { GlAlert, GlLink, GlIcon, GlSprintf } from '@gitlab/ui';
import { __ } from '~/locale'; import { __ } from '~/locale';
import SharedDeleteButton from '~/projects/components/shared/delete_button.vue'; import SharedDeleteButton from '~/projects/components/shared/delete_button.vue';
export default { export default {
components: { components: {
GlAlert,
GlSprintf, GlSprintf,
GlIcon, GlIcon,
GlLink, GlLink,
...@@ -27,13 +28,38 @@ export default { ...@@ -27,13 +28,38 @@ export default {
type: String, type: String,
required: true, required: true,
}, },
isFork: {
type: Boolean,
required: true,
},
issuesCount: {
type: Number,
required: true,
},
mergeRequestsCount: {
type: Number,
required: true,
},
forksCount: {
type: Number,
required: true,
},
starsCount: {
type: Number,
required: true,
},
}, },
strings: { strings: {
modalBody: __( alertTitle: __('You are about to permanently delete this project'),
"Once a project is permanently deleted, it cannot be recovered. You will lose this project's repository and all related resources, including issues and merge requests.", alertBody: __(
"Once a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests.",
), ),
helpLabel: __('Recovering projects'), helpLabel: __('Recovering projects'),
recoveryMessage: __('You can recover this project until %{date}'), recoveryMessage: __('You can recover this project until %{date}'),
isNotForkMessage: __(
'This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:',
),
isForkMessage: __('This forked project has the following:'),
}, },
}; };
</script> </script>
...@@ -41,7 +67,50 @@ export default { ...@@ -41,7 +67,50 @@ export default {
<template> <template>
<shared-delete-button v-bind="{ confirmPhrase, formPath }"> <shared-delete-button v-bind="{ confirmPhrase, formPath }">
<template #modal-body> <template #modal-body>
<p>{{ $options.strings.modalBody }}</p> <gl-alert
class="gl-mb-5"
variant="danger"
:title="$options.strings.alertTitle"
:dismissible="false"
>
<p>
<gl-sprintf v-if="isFork" :message="$options.strings.isForkMessage" />
<gl-sprintf v-else :message="$options.strings.isNotForkMessage">
<template #strong="{ content }">
<strong>{{ content }}</strong>
</template>
</gl-sprintf>
</p>
<ul>
<li>
<gl-sprintf :message="n__('%d issue', '%d issues', issuesCount)">
<template #issuesCount>{{ issuesCount }}</template>
</gl-sprintf>
</li>
<li>
<gl-sprintf
:message="n__('%d merge requests', '%d merge requests', mergeRequestsCount)"
>
<template #mergeRequestsCount>{{ mergeRequestsCount }}</template>
</gl-sprintf>
</li>
<li>
<gl-sprintf :message="n__('%d fork', '%d forks', forksCount)">
<template #forksCount>{{ forksCount }}</template>
</gl-sprintf>
</li>
<li>
<gl-sprintf :message="n__('%d star', '%d stars', starsCount)">
<template #starsCount>{{ starsCount }}</template>
</gl-sprintf>
</li>
</ul>
<gl-sprintf :message="$options.strings.alertBody">
<template #strong="{ content }">
<strong>{{ content }}</strong>
</template>
</gl-sprintf>
</gl-alert>
</template> </template>
<template #modal-footer> <template #modal-footer>
<p <p
......
import Vue from 'vue'; import Vue from 'vue';
import { parseBoolean } from '~/lib/utils/common_utils';
import ProjectAdjournedDeleteButton from './components/project_adjourned_delete_button.vue'; import ProjectAdjournedDeleteButton from './components/project_adjourned_delete_button.vue';
export default (selector = '#js-project-adjourned-delete-button') => { export default (selector = '#js-project-adjourned-delete-button') => {
...@@ -6,7 +7,17 @@ export default (selector = '#js-project-adjourned-delete-button') => { ...@@ -6,7 +7,17 @@ export default (selector = '#js-project-adjourned-delete-button') => {
if (!el) return; if (!el) return;
const { adjournedRemovalDate, confirmPhrase, formPath, recoveryHelpPath } = el.dataset; const {
adjournedRemovalDate,
confirmPhrase,
formPath,
recoveryHelpPath,
isFork,
issuesCount,
mergeRequestsCount,
forksCount,
starsCount,
} = el.dataset;
// eslint-disable-next-line no-new // eslint-disable-next-line no-new
new Vue({ new Vue({
...@@ -18,6 +29,11 @@ export default (selector = '#js-project-adjourned-delete-button') => { ...@@ -18,6 +29,11 @@ export default (selector = '#js-project-adjourned-delete-button') => {
confirmPhrase, confirmPhrase,
formPath, formPath,
recoveryHelpPath, recoveryHelpPath,
isFork: parseBoolean(isFork),
issuesCount: parseInt(issuesCount, 10),
mergeRequestsCount: parseInt(mergeRequestsCount, 10),
forksCount: parseInt(forksCount, 10),
starsCount: parseInt(starsCount, 10),
}, },
}); });
}, },
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
- adjourned_date = adjourned_deletion ? permanent_deletion_date(Time.now.utc).to_s : nil - adjourned_date = adjourned_deletion ? permanent_deletion_date(Time.now.utc).to_s : nil
- admin_help_path = help_page_path('user/admin_area/settings/visibility_and_access_controls', anchor: 'default-deletion-delay') - admin_help_path = help_page_path('user/admin_area/settings/visibility_and_access_controls', anchor: 'default-deletion-delay')
- recovery_help_path = help_page_path('user/project/settings/index', anchor: 'delete-a-project') - recovery_help_path = help_page_path('user/project/settings/index', anchor: 'delete-a-project')
- merge_requests_count = Projects::AllMergeRequestsCountService.new(project).count
- issues_count = Projects::AllIssuesCountService.new(project).count
- unless project.marked_for_deletion? - unless project.marked_for_deletion?
.sub-section .sub-section
...@@ -11,7 +13,7 @@ ...@@ -11,7 +13,7 @@
%strong= s_('Delayed Project Deletion (%{adjourned_deletion})') % { adjourned_deletion: adjourned_deletion ? 'Enabled' : 'Disabled' } %strong= s_('Delayed Project Deletion (%{adjourned_deletion})') % { adjourned_deletion: adjourned_deletion ? 'Enabled' : 'Disabled' }
- if adjourned_deletion - if adjourned_deletion
= render 'projects/settings/marked_for_removal' = render 'projects/settings/marked_for_removal'
#js-project-adjourned-delete-button{ data: { recovery_help_path: recovery_help_path, adjourned_removal_date: adjourned_date, form_path: project_path(project), confirm_phrase: delete_confirm_phrase(project) } } #js-project-adjourned-delete-button{ data: { recovery_help_path: recovery_help_path, adjourned_removal_date: adjourned_date, form_path: project_path(project), confirm_phrase: delete_confirm_phrase(project), is_fork: project.forked?.to_s, issues_count: number_with_delimiter(issues_count), merge_requests_count: number_with_delimiter(merge_requests_count), forks_count: number_with_delimiter(project.forks_count), stars_count: number_with_delimiter(project.star_count) } }
- else - else
%p %p
%span.gl-text-gray-500= _('Projects will be permanently deleted immediately.') %span.gl-text-gray-500= _('Projects will be permanently deleted immediately.')
...@@ -19,8 +21,7 @@ ...@@ -19,8 +21,7 @@
%p= permanent_delete_message(project) %p= permanent_delete_message(project)
%p %p
%strong= _('Are you ABSOLUTELY SURE you wish to delete this project?') %strong= _('Are you ABSOLUTELY SURE you wish to delete this project?')
#js-project-delete-button{ data: { form_path: project_path(project), confirm_phrase: delete_confirm_phrase(project) } } #js-project-delete-button{ data: { form_path: project_path(project), confirm_phrase: delete_confirm_phrase(project), is_fork: project.forked?.to_s, issues_count: number_with_delimiter(issues_count), merge_requests_count: number_with_delimiter(merge_requests_count), forks_count: number_with_delimiter(project.forks_count), stars_count: number_with_delimiter(project.star_count) } }
- else - else
= render 'projects/settings/restore', project: project = render 'projects/settings/restore', project: project
= render 'projects/settings/permanently_delete', project: project = render 'projects/settings/permanently_delete', project: project
- merge_requests_count = Projects::AllMergeRequestsCountService.new(project).count
- issues_count = Projects::AllIssuesCountService.new(project).count
.sub-section .sub-section
%h4.danger-title= _('Permanently delete project') %h4.danger-title= _('Permanently delete project')
%p %p
...@@ -5,4 +8,4 @@ ...@@ -5,4 +8,4 @@
%p= permanent_delete_message(project) %p= permanent_delete_message(project)
%p %p
%strong= _('Are you ABSOLUTELY SURE you wish to delete this project?') %strong= _('Are you ABSOLUTELY SURE you wish to delete this project?')
#js-project-delete-button{ data: { form_path: project_path(project, permanently_delete: true), confirm_phrase: delete_confirm_phrase(project) } } #js-project-delete-button{ data: { form_path: project_path(project, permanently_delete: true), confirm_phrase: delete_confirm_phrase(project), is_fork: project.forked?.to_s, issues_count: number_with_delimiter(issues_count), merge_requests_count: number_with_delimiter(merge_requests_count), forks_count: number_with_delimiter(project.forks_count), stars_count: number_with_delimiter(project.star_count) } }
...@@ -42,9 +42,51 @@ exports[`Project remove modal initialized matches the snapshot 1`] = ` ...@@ -42,9 +42,51 @@ exports[`Project remove modal initialized matches the snapshot 1`] = `
> >
<div> <div>
<p> <gl-alert-stub
Once a project is permanently deleted, it cannot be recovered. You will lose this project's repository and all related resources, including issues and merge requests. class="gl-mb-5"
</p> dismisslabel="Dismiss"
primarybuttonlink=""
primarybuttontext=""
secondarybuttonlink=""
secondarybuttontext=""
title="You are about to permanently delete this project"
variant="danger"
>
<p>
This project is
<strong>
NOT
</strong>
a fork, and has the following:
</p>
<ul>
<li>
1 issue
</li>
<li>
2 merge requests
</li>
<li>
3 forks
</li>
<li>
4 stars
</li>
</ul>
Once a project is permanently deleted, it
<strong>
cannot be recovered
</strong>
. You will lose this project's repository and
<strong>
all related resources
</strong>
, including issues and merge requests.
</gl-alert-stub>
<p <p
class="gl-mb-1" class="gl-mb-1"
...@@ -69,9 +111,8 @@ exports[`Project remove modal initialized matches the snapshot 1`] = ` ...@@ -69,9 +111,8 @@ exports[`Project remove modal initialized matches the snapshot 1`] = `
<p <p
class="gl-display-flex gl-display-flex gl-align-items-center gl-mt-3 gl-mb-0 gl-text-gray-500" class="gl-display-flex gl-display-flex gl-align-items-center gl-mt-3 gl-mb-0 gl-text-gray-500"
> >
<gl-sprintf-stub You can recover this project until
message="You can recover this project until %{date}" 2020-12-12
/>
<gl-link-stub <gl-link-stub
aria-label="Recovering projects" aria-label="Recovering projects"
......
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { GlSprintf } from '@gitlab/ui';
import ProjectAdjournedDeleteButton from 'ee/projects/components/project_adjourned_delete_button.vue'; import ProjectAdjournedDeleteButton from 'ee/projects/components/project_adjourned_delete_button.vue';
import SharedDeleteButton from '~/projects/components/shared/delete_button.vue'; import SharedDeleteButton from '~/projects/components/shared/delete_button.vue';
...@@ -14,6 +15,11 @@ describe('Project remove modal', () => { ...@@ -14,6 +15,11 @@ describe('Project remove modal', () => {
confirmPhrase: 'foo', confirmPhrase: 'foo',
formPath: 'some/path', formPath: 'some/path',
recoveryHelpPath: 'recovery/help/path', recoveryHelpPath: 'recovery/help/path',
isFork: false,
issuesCount: 1,
mergeRequestsCount: 2,
forksCount: 3,
starsCount: 4,
}; };
const createComponent = (props = {}) => { const createComponent = (props = {}) => {
...@@ -23,6 +29,7 @@ describe('Project remove modal', () => { ...@@ -23,6 +29,7 @@ describe('Project remove modal', () => {
...props, ...props,
}, },
stubs: { stubs: {
GlSprintf,
SharedDeleteButton, SharedDeleteButton,
}, },
}); });
......
...@@ -236,6 +236,11 @@ msgid_plural "%d fixed test results" ...@@ -236,6 +236,11 @@ msgid_plural "%d fixed test results"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
msgid "%d fork"
msgid_plural "%d forks"
msgstr[0] ""
msgstr[1] ""
msgid "%d group" msgid "%d group"
msgid_plural "%d groups" msgid_plural "%d groups"
msgstr[0] "" msgstr[0] ""
...@@ -286,6 +291,11 @@ msgid_plural "%d merge requests that you don't have access to." ...@@ -286,6 +291,11 @@ msgid_plural "%d merge requests that you don't have access to."
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
msgid "%d merge requests"
msgid_plural "%d merge requests"
msgstr[0] ""
msgstr[1] ""
msgid "%d metric" msgid "%d metric"
msgid_plural "%d metrics" msgid_plural "%d metrics"
msgstr[0] "" msgstr[0] ""
...@@ -351,6 +361,11 @@ msgid_plural "%d shards selected" ...@@ -351,6 +361,11 @@ msgid_plural "%d shards selected"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
msgid "%d star"
msgid_plural "%d stars"
msgstr[0] ""
msgstr[1] ""
msgid "%d tag" msgid "%d tag"
msgid_plural "%d tags" msgid_plural "%d tags"
msgstr[0] "" msgstr[0] ""
...@@ -24173,7 +24188,7 @@ msgstr "" ...@@ -24173,7 +24188,7 @@ msgstr ""
msgid "Once a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc." msgid "Once a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
msgstr "" msgstr ""
msgid "Once a project is permanently deleted, it cannot be recovered. You will lose this project's repository and all related resources, including issues and merge requests." msgid "Once a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
msgstr "" msgstr ""
msgid "Once imported, repositories can be mirrored over SSH. Read more %{link_start}here%{link_end}." msgid "Once imported, repositories can be mirrored over SSH. Read more %{link_start}here%{link_end}."
...@@ -35292,6 +35307,9 @@ msgstr "" ...@@ -35292,6 +35307,9 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly." msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr "" msgstr ""
msgid "This forked project has the following:"
msgstr ""
msgid "This form is disabled in preview" msgid "This form is disabled in preview"
msgstr "" msgstr ""
...@@ -35544,6 +35562,9 @@ msgstr "" ...@@ -35544,6 +35562,9 @@ msgstr ""
msgid "This project has no active access tokens." msgid "This project has no active access tokens."
msgstr "" msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
msgid "This project is archived and cannot be commented on." msgid "This project is archived and cannot be commented on."
msgstr "" msgstr ""
......
...@@ -52,9 +52,44 @@ exports[`Project remove modal initialized matches the snapshot 1`] = ` ...@@ -52,9 +52,44 @@ exports[`Project remove modal initialized matches the snapshot 1`] = `
title="You are about to permanently delete this project" title="You are about to permanently delete this project"
variant="danger" variant="danger"
> >
<gl-sprintf-stub <p>
message="Once a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc." This project is
/> <strong>
NOT
</strong>
a fork, and has the following:
</p>
<ul>
<li>
1 issue
</li>
<li>
2 merge requests
</li>
<li>
3 forks
</li>
<li>
4 stars
</li>
</ul>
Once a project is permanently deleted, it
<strong>
cannot be recovered
</strong>
. Permanently deleting this project will
<strong>
immediately delete
</strong>
its repositories and
<strong>
all related resources
</strong>
, including issues, merge requests etc.
</gl-alert-stub> </gl-alert-stub>
<p <p
......
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { GlSprintf } from '@gitlab/ui';
import ProjectDeleteButton from '~/projects/components/project_delete_button.vue'; import ProjectDeleteButton from '~/projects/components/project_delete_button.vue';
import SharedDeleteButton from '~/projects/components/shared/delete_button.vue'; import SharedDeleteButton from '~/projects/components/shared/delete_button.vue';
...@@ -12,6 +13,11 @@ describe('Project remove modal', () => { ...@@ -12,6 +13,11 @@ describe('Project remove modal', () => {
const defaultProps = { const defaultProps = {
confirmPhrase: 'foo', confirmPhrase: 'foo',
formPath: 'some/path', formPath: 'some/path',
isFork: false,
issuesCount: 1,
mergeRequestsCount: 2,
forksCount: 3,
starsCount: 4,
}; };
const createComponent = (props = {}) => { const createComponent = (props = {}) => {
...@@ -21,6 +27,7 @@ describe('Project remove modal', () => { ...@@ -21,6 +27,7 @@ describe('Project remove modal', () => {
...props, ...props,
}, },
stubs: { stubs: {
GlSprintf,
SharedDeleteButton, SharedDeleteButton,
}, },
}); });
...@@ -41,7 +48,10 @@ describe('Project remove modal', () => { ...@@ -41,7 +48,10 @@ describe('Project remove modal', () => {
}); });
it('passes confirmPhrase and formPath props to the shared delete button', () => { it('passes confirmPhrase and formPath props to the shared delete button', () => {
expect(findSharedDeleteButton().props()).toEqual(defaultProps); expect(findSharedDeleteButton().props()).toEqual({
confirmPhrase: defaultProps.confirmPhrase,
formPath: defaultProps.formPath,
});
}); });
}); });
}); });
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Projects::AllIssuesCountService, :use_clean_rails_memory_store_caching do
let_it_be(:group) { create(:group, :public) }
let_it_be(:project) { create(:project, :public, namespace: group) }
let_it_be(:banned_user) { create(:user, :banned) }
subject { described_class.new(project) }
it_behaves_like 'a counter caching service'
describe '#count' do
it 'returns the number of all issues' do
create(:issue, :opened, project: project)
create(:issue, :opened, confidential: true, project: project)
create(:issue, :opened, author: banned_user, project: project)
create(:issue, :closed, project: project)
expect(subject.count).to eq(4)
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Projects::AllMergeRequestsCountService, :use_clean_rails_memory_store_caching do
let_it_be(:project) { create(:project) }
subject { described_class.new(project) }
it_behaves_like 'a counter caching service'
describe '#count' do
it 'returns the number of all merge requests' do
create(:merge_request,
:opened,
source_project: project,
target_project: project)
create(:merge_request,
:closed,
source_project: project,
target_project: project)
create(:merge_request,
:merged,
source_project: project,
target_project: project)
expect(subject.count).to eq(3)
end
end
end
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