Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-08-24 12:10:14 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-08-24 12:10:14 +0300
commit2f752481c2e727834216a93dee82df9f8e2acb2e (patch)
tree47899c8a7f2be92d4824d84c48e9cf5e0410196c
parent273d780f9ede8f6ed5ebbd4f81c8a391a55f882a (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/assets/javascripts/behaviors/shortcuts/shortcuts.js1
-rw-r--r--app/assets/javascripts/boards/filtered_search_boards.js5
-rw-r--r--app/assets/javascripts/boards/index.js16
-rw-r--r--app/assets/javascripts/boards/stores/actions.js5
-rw-r--r--app/assets/javascripts/boards/stores/boards_store.js4
-rw-r--r--app/assets/javascripts/boards/stores/mutation_types.js1
-rw-r--r--app/assets/javascripts/boards/stores/mutations.js4
-rw-r--r--app/assets/javascripts/boards/stores/state.js1
-rw-r--r--app/assets/javascripts/clusters/components/knative_domain_editor.vue15
-rw-r--r--app/graphql/mutations/concerns/mutations/authorizes_project.rb17
-rw-r--r--app/views/admin/runners/_runner.html.haml2
-rw-r--r--app/views/groups/runners/_runner.html.haml4
-rw-r--r--app/views/help/_shortcuts.html.haml2
-rw-r--r--app/views/projects/ci/builds/_build.html.haml2
-rw-r--r--changelogs/unreleased/205578-move-package-metrics-to-core.yml5
-rw-r--r--changelogs/unreleased/239195-slash-to-start-search-shortcut.yml5
-rw-r--r--doc/user/shortcuts.md2
-rw-r--r--lib/gitlab/middleware/multipart.rb10
-rw-r--r--lib/gitlab/usage_data.rb7
-rw-r--r--spec/factories/usage_data.rb4
-rw-r--r--spec/frontend/boards/stores/actions_spec.js19
-rw-r--r--spec/frontend/boards/stores/mutations_spec.js10
-rw-r--r--spec/frontend/clusters/components/knative_domain_editor_spec.js11
-rw-r--r--spec/lib/gitlab/usage_data_spec.rb17
24 files changed, 144 insertions, 25 deletions
diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts.js
index 85636f3e5d2..e4e5f16927b 100644
--- a/app/assets/javascripts/behaviors/shortcuts/shortcuts.js
+++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts.js
@@ -34,6 +34,7 @@ export default class Shortcuts {
Mousetrap.bind('?', this.onToggleHelp);
Mousetrap.bind('s', Shortcuts.focusSearch);
+ Mousetrap.bind('/', Shortcuts.focusSearch);
Mousetrap.bind('f', this.focusFilter.bind(this));
Mousetrap.bind('p b', Shortcuts.onTogglePerfBar);
diff --git a/app/assets/javascripts/boards/filtered_search_boards.js b/app/assets/javascripts/boards/filtered_search_boards.js
index b7966dd869d..f421faeb52d 100644
--- a/app/assets/javascripts/boards/filtered_search_boards.js
+++ b/app/assets/javascripts/boards/filtered_search_boards.js
@@ -27,6 +27,11 @@ export default class FilteredSearchBoards extends FilteredSearchManager {
updateObject(path) {
this.store.path = path.substr(1);
+ if (gon.features.boardsWithSwimlanes) {
+ boardsStore.updateFiltersUrl();
+ boardsStore.performSearch();
+ }
+
if (this.updateUrl) {
boardsStore.updateFiltersUrl();
}
diff --git a/app/assets/javascripts/boards/index.js b/app/assets/javascripts/boards/index.js
index 971edd71eec..21c362affbb 100644
--- a/app/assets/javascripts/boards/index.js
+++ b/app/assets/javascripts/boards/index.js
@@ -1,6 +1,6 @@
import $ from 'jquery';
import Vue from 'vue';
-import { mapActions } from 'vuex';
+import { mapActions, mapState } from 'vuex';
import 'ee_else_ce/boards/models/issue';
import 'ee_else_ce/boards/models/list';
@@ -42,6 +42,7 @@ import {
NavigationType,
convertObjectPropsToCamelCase,
parseBoolean,
+ urlParamsToObject,
} from '~/lib/utils/common_utils';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import mountMultipleBoardsSwitcher from './mount_multiple_boards_switcher';
@@ -104,6 +105,7 @@ export default () => {
};
},
computed: {
+ ...mapState(['isShowingEpicsSwimlanes']),
detailIssueVisible() {
return Object.keys(this.detailIssue.issue).length;
},
@@ -125,17 +127,21 @@ export default () => {
eventHub.$on('newDetailIssue', this.updateDetailIssue);
eventHub.$on('clearDetailIssue', this.clearDetailIssue);
sidebarEventHub.$on('toggleSubscription', this.toggleSubscription);
+ eventHub.$on('performSearch', this.performSearch);
},
beforeDestroy() {
eventHub.$off('updateTokens', this.updateTokens);
eventHub.$off('newDetailIssue', this.updateDetailIssue);
eventHub.$off('clearDetailIssue', this.clearDetailIssue);
sidebarEventHub.$off('toggleSubscription', this.toggleSubscription);
+ eventHub.$off('performSearch', this.performSearch);
},
mounted() {
this.filterManager = new FilteredSearchBoards(boardsStore.filter, true, boardsStore.cantEdit);
this.filterManager.setup();
+ this.performSearch();
+
boardsStore.disabled = this.disabled;
if (gon.features.graphqlBoardLists) {
@@ -189,10 +195,16 @@ export default () => {
}
},
methods: {
- ...mapActions(['setInitialBoardData']),
+ ...mapActions(['setInitialBoardData', 'setFilters', 'fetchEpicsSwimlanes']),
updateTokens() {
this.filterManager.updateTokens();
},
+ performSearch() {
+ this.setFilters(convertObjectPropsToCamelCase(urlParamsToObject(window.location.search)));
+ if (gon.features.boardsWithSwimlanes && this.isShowingEpicsSwimlanes) {
+ this.fetchEpicsSwimlanes(false);
+ }
+ },
updateDetailIssue(newIssue, multiSelect = false) {
const { sidebarInfoEndpoint } = newIssue;
if (sidebarInfoEndpoint && newIssue.subscribed === undefined) {
diff --git a/app/assets/javascripts/boards/stores/actions.js b/app/assets/javascripts/boards/stores/actions.js
index b4be7546252..cce36dc6a14 100644
--- a/app/assets/javascripts/boards/stores/actions.js
+++ b/app/assets/javascripts/boards/stores/actions.js
@@ -21,6 +21,11 @@ export default {
commit(types.SET_ACTIVE_ID, id);
},
+ setFilters: ({ commit }, filters) => {
+ const { scope, utf8, state, ...filterParams } = filters;
+ commit(types.SET_FILTERS, filterParams);
+ },
+
fetchLists: () => {
notImplemented();
},
diff --git a/app/assets/javascripts/boards/stores/boards_store.js b/app/assets/javascripts/boards/stores/boards_store.js
index 30c71d64085..002a8bee3dc 100644
--- a/app/assets/javascripts/boards/stores/boards_store.js
+++ b/app/assets/javascripts/boards/stores/boards_store.js
@@ -513,6 +513,10 @@ const boardsStore = {
eventHub.$emit('updateTokens');
},
+ performSearch() {
+ eventHub.$emit('performSearch');
+ },
+
setListDetail(newList) {
this.detail.list = newList;
},
diff --git a/app/assets/javascripts/boards/stores/mutation_types.js b/app/assets/javascripts/boards/stores/mutation_types.js
index 0f96dc2e287..0f9e93dec5c 100644
--- a/app/assets/javascripts/boards/stores/mutation_types.js
+++ b/app/assets/javascripts/boards/stores/mutation_types.js
@@ -1,4 +1,5 @@
export const SET_INITIAL_BOARD_DATA = 'SET_INITIAL_BOARD_DATA';
+export const SET_FILTERS = 'SET_FILTERS';
export const REQUEST_ADD_LIST = 'REQUEST_ADD_LIST';
export const RECEIVE_ADD_LIST_SUCCESS = 'RECEIVE_ADD_LIST_SUCCESS';
export const RECEIVE_ADD_LIST_ERROR = 'RECEIVE_ADD_LIST_ERROR';
diff --git a/app/assets/javascripts/boards/stores/mutations.js b/app/assets/javascripts/boards/stores/mutations.js
index 1644c118868..738c4aa841a 100644
--- a/app/assets/javascripts/boards/stores/mutations.js
+++ b/app/assets/javascripts/boards/stores/mutations.js
@@ -17,6 +17,10 @@ export default {
state.activeId = id;
},
+ [mutationTypes.SET_FILTERS](state, filterParams) {
+ state.filterParams = filterParams;
+ },
+
[mutationTypes.REQUEST_ADD_LIST]: () => {
notImplemented();
},
diff --git a/app/assets/javascripts/boards/stores/state.js b/app/assets/javascripts/boards/stores/state.js
index fde9e62149c..cf01e4fa0e3 100644
--- a/app/assets/javascripts/boards/stores/state.js
+++ b/app/assets/javascripts/boards/stores/state.js
@@ -8,6 +8,7 @@ export default () => ({
boardLists: [],
issuesByListId: {},
isLoadingIssues: false,
+ filterParams: {},
error: undefined,
// TODO: remove after ce/ee split of board_content.vue
isShowingEpicsSwimlanes: false,
diff --git a/app/assets/javascripts/clusters/components/knative_domain_editor.vue b/app/assets/javascripts/clusters/components/knative_domain_editor.vue
index 1236d2a46c9..0194a8e5ac1 100644
--- a/app/assets/javascripts/clusters/components/knative_domain_editor.vue
+++ b/app/assets/javascripts/clusters/components/knative_domain_editor.vue
@@ -6,8 +6,8 @@ import {
GlLoadingIcon,
GlSearchBoxByType,
GlSprintf,
+ GlButton,
} from '@gitlab/ui';
-import LoadingButton from '~/vue_shared/components/loading_button.vue';
import ClipboardButton from '../../vue_shared/components/clipboard_button.vue';
import { __, s__ } from '~/locale';
@@ -17,7 +17,7 @@ const { UPDATING, UNINSTALLING } = APPLICATION_STATUS;
export default {
components: {
- LoadingButton,
+ GlButton,
ClipboardButton,
GlLoadingIcon,
GlDeprecatedDropdown,
@@ -215,13 +215,16 @@ export default {
}}
</p>
- <loading-button
- class="btn-success js-knative-save-domain-button mt-3 ml-3"
+ <gl-button
+ class="js-knative-save-domain-button gl-mt-5 gl-ml-5"
+ variant="success"
+ category="primary"
:loading="saving"
:disabled="saveButtonDisabled"
- :label="saveButtonLabel"
@click="$emit('save')"
- />
+ >
+ {{ saveButtonLabel }}
+ </gl-button>
</template>
</div>
</template>
diff --git a/app/graphql/mutations/concerns/mutations/authorizes_project.rb b/app/graphql/mutations/concerns/mutations/authorizes_project.rb
new file mode 100644
index 00000000000..87341525d6c
--- /dev/null
+++ b/app/graphql/mutations/concerns/mutations/authorizes_project.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module Mutations
+ module AuthorizesProject
+ include ResolvesProject
+
+ def authorized_find_project!(full_path:)
+ authorized_find!(full_path: full_path)
+ end
+
+ private
+
+ def find_object(full_path:)
+ resolve_project(full_path: full_path)
+ end
+ end
+end
diff --git a/app/views/admin/runners/_runner.html.haml b/app/views/admin/runners/_runner.html.haml
index 0bbe73d6f7e..a2b736c332c 100644
--- a/app/views/admin/runners/_runner.html.haml
+++ b/app/views/admin/runners/_runner.html.haml
@@ -76,4 +76,4 @@
= sprite_icon('play')
.btn-group
= link_to [:admin, runner], method: :delete, class: 'btn btn-danger has-tooltip', title: _('Remove'), ref: 'tooltip', aria: { label: _('Remove') }, data: { placement: 'top', container: 'body', confirm: _('Are you sure?') } do
- = icon('remove')
+ = sprite_icon('close')
diff --git a/app/views/groups/runners/_runner.html.haml b/app/views/groups/runners/_runner.html.haml
index 07cbcd8401e..3fc50cc86d2 100644
--- a/app/views/groups/runners/_runner.html.haml
+++ b/app/views/groups/runners/_runner.html.haml
@@ -79,8 +79,8 @@
- if runner.belongs_to_more_than_one_project?
.btn-group
.btn.btn-danger.has-tooltip{ 'aria-label' => 'Remove', 'data-container' => 'body', 'data-original-title' => _('Multi-project Runners cannot be removed'), 'data-placement' => 'top', disabled: 'disabled' }
- = icon('remove')
+ = sprite_icon('close')
- else
.btn-group
= link_to group_runner_path(@group, runner), method: :delete, class: 'btn btn-danger has-tooltip', title: _('Remove'), ref: 'tooltip', aria: { label: _('Remove') }, data: { placement: 'top', container: 'body', confirm: _('Are you sure?') } do
- = icon('remove')
+ = sprite_icon('close')
diff --git a/app/views/help/_shortcuts.html.haml b/app/views/help/_shortcuts.html.haml
index 80df8581a9b..d252a279a45 100644
--- a/app/views/help/_shortcuts.html.haml
+++ b/app/views/help/_shortcuts.html.haml
@@ -40,6 +40,8 @@
%tr
%td.shortcut
%kbd s
+ \/
+ %kbd /
%td= _('Start search')
%tr
%td.shortcut
diff --git a/app/views/projects/ci/builds/_build.html.haml b/app/views/projects/ci/builds/_build.html.haml
index 23f9a6a8f6c..c7ab01a4ef7 100644
--- a/app/views/projects/ci/builds/_build.html.haml
+++ b/app/views/projects/ci/builds/_build.html.haml
@@ -102,7 +102,7 @@
- if can?(current_user, :update_build, job)
- if job.active?
= link_to cancel_project_job_path(job.project, job, continue: { to: request.fullpath }), method: :post, title: _('Cancel'), class: 'btn btn-build' do
- = icon('remove', class: 'cred')
+ = sprite_icon('close')
- elsif job.scheduled?
.btn-group
.btn.btn-default{ disabled: true }
diff --git a/changelogs/unreleased/205578-move-package-metrics-to-core.yml b/changelogs/unreleased/205578-move-package-metrics-to-core.yml
new file mode 100644
index 00000000000..a52c9c7a3c6
--- /dev/null
+++ b/changelogs/unreleased/205578-move-package-metrics-to-core.yml
@@ -0,0 +1,5 @@
+---
+title: Move package usage ping data to core
+merge_request: 40032
+author:
+type: changed
diff --git a/changelogs/unreleased/239195-slash-to-start-search-shortcut.yml b/changelogs/unreleased/239195-slash-to-start-search-shortcut.yml
new file mode 100644
index 00000000000..cfc02d2ad46
--- /dev/null
+++ b/changelogs/unreleased/239195-slash-to-start-search-shortcut.yml
@@ -0,0 +1,5 @@
+---
+title: Add `/` as keyboard shortcut for search
+merge_request: 40057
+author:
+type: added
diff --git a/doc/user/shortcuts.md b/doc/user/shortcuts.md
index 314fe367ca6..4d65cc61bd5 100644
--- a/doc/user/shortcuts.md
+++ b/doc/user/shortcuts.md
@@ -27,7 +27,7 @@ These shortcuts are available in most areas of GitLab
| <kbd>Shift</kbd> + <kbd>a</kbd> | Go to your Activity page. |
| <kbd>Shift</kbd> + <kbd>l</kbd> | Go to your Milestones page. |
| <kbd>Shift</kbd> + <kbd>s</kbd> | Go to your Snippets page. |
-| <kbd>s</kbd> | Put cursor in the issues/merge requests search. |
+| <kbd>s</kbd> / <kbd>/</kbd> | Put cursor in the search bar. |
| <kbd>Shift</kbd> + <kbd>i</kbd> | Go to your Issues page. |
| <kbd>Shift</kbd> + <kbd>m</kbd> | Go to your Merge requests page.|
| <kbd>Shift</kbd> + <kbd>t</kbd> | Go to your To-Do List page. |
diff --git a/lib/gitlab/middleware/multipart.rb b/lib/gitlab/middleware/multipart.rb
index c0b671abd44..733214a7cce 100644
--- a/lib/gitlab/middleware/multipart.rb
+++ b/lib/gitlab/middleware/multipart.rb
@@ -123,9 +123,9 @@ module Gitlab
def allowed_paths
[
::FileUploader.root,
- Gitlab.config.uploads.storage_path,
- JobArtifactUploader.workhorse_upload_path,
- LfsObjectUploader.workhorse_upload_path,
+ ::Gitlab.config.uploads.storage_path,
+ ::JobArtifactUploader.workhorse_upload_path,
+ ::LfsObjectUploader.workhorse_upload_path,
File.join(Rails.root, 'public/uploads/tmp')
] + package_allowed_paths
end
@@ -139,9 +139,9 @@ module Gitlab
encoded_message = env.delete(RACK_ENV_KEY)
return @app.call(env) if encoded_message.blank?
- message = Gitlab::Workhorse.decode_jwt(encoded_message)[0]
+ message = ::Gitlab::Workhorse.decode_jwt(encoded_message)[0]
- Handler.new(env, message).with_open_files do
+ ::Gitlab::Middleware::Multipart::Handler.new(env, message).with_open_files do
@app.call(env)
end
rescue UploadedFile::InvalidPathError => e
diff --git a/lib/gitlab/usage_data.rb b/lib/gitlab/usage_data.rb
index 42be49bdbd6..7f3025ff983 100644
--- a/lib/gitlab/usage_data.rb
+++ b/lib/gitlab/usage_data.rb
@@ -129,6 +129,7 @@ module Gitlab
lfs_objects: count(LfsObject),
milestone_lists: count(List.milestone),
milestones: count(Milestone),
+ projects_with_packages: distinct_count(::Packages::Package, :project_id),
pages_domains: count(PagesDomain),
pool_repositories: count(PoolRepository),
projects: count(Project),
@@ -527,9 +528,13 @@ module Gitlab
end
# rubocop: enable CodeReuse/ActiveRecord
+ # rubocop: disable CodeReuse/ActiveRecord
def usage_activity_by_stage_package(time_period)
- {}
+ {
+ projects_with_packages: distinct_count(::Project.with_packages.where(time_period), :creator_id)
+ }
end
+ # rubocop: enable CodeReuse/ActiveRecord
# Omitted because no user, creator or author associated: `boards`, `labels`, `milestones`, `uploads`
# Omitted because too expensive: `epics_deepest_relationship_level`
diff --git a/spec/factories/usage_data.rb b/spec/factories/usage_data.rb
index d2b8fd94aca..e5dd92e71cb 100644
--- a/spec/factories/usage_data.rb
+++ b/spec/factories/usage_data.rb
@@ -94,6 +94,10 @@ FactoryBot.define do
create(:grafana_integration, project: projects[1], enabled: true)
create(:grafana_integration, project: projects[2], enabled: false)
+ create(:package, project: projects[0])
+ create(:package, project: projects[0])
+ create(:package, project: projects[1])
+
ProjectFeature.first.update_attribute('repository_access_level', 0)
# Create fresh & a month (28-days SMAU) old data
diff --git a/spec/frontend/boards/stores/actions_spec.js b/spec/frontend/boards/stores/actions_spec.js
index d539cba76ca..71e62a4ac5d 100644
--- a/spec/frontend/boards/stores/actions_spec.js
+++ b/spec/frontend/boards/stores/actions_spec.js
@@ -26,6 +26,25 @@ describe('setInitialBoardData', () => {
});
});
+describe('setFilters', () => {
+ it('should commit mutation SET_FILTERS', done => {
+ const state = {
+ filters: {},
+ };
+
+ const filters = { labelName: 'label' };
+
+ testAction(
+ actions.setFilters,
+ filters,
+ state,
+ [{ type: types.SET_FILTERS, payload: filters }],
+ [],
+ done,
+ );
+ });
+});
+
describe('setActiveId', () => {
it('should commit mutation SET_ACTIVE_ID', done => {
const state = {
diff --git a/spec/frontend/boards/stores/mutations_spec.js b/spec/frontend/boards/stores/mutations_spec.js
index cf2f86f1e34..e5b26e9994e 100644
--- a/spec/frontend/boards/stores/mutations_spec.js
+++ b/spec/frontend/boards/stores/mutations_spec.js
@@ -44,6 +44,16 @@ describe('Board Store Mutations', () => {
});
});
+ describe('SET_FILTERS', () => {
+ it('updates filterParams to be the value that is passed', () => {
+ const filterParams = { labelName: 'label' };
+
+ mutations.SET_FILTERS(state, filterParams);
+
+ expect(state.filterParams).toBe(filterParams);
+ });
+ });
+
describe('REQUEST_ADD_LIST', () => {
expectNotImplemented(mutations.REQUEST_ADD_LIST);
});
diff --git a/spec/frontend/clusters/components/knative_domain_editor_spec.js b/spec/frontend/clusters/components/knative_domain_editor_spec.js
index a07258dcc69..11ebe1b5d61 100644
--- a/spec/frontend/clusters/components/knative_domain_editor_spec.js
+++ b/spec/frontend/clusters/components/knative_domain_editor_spec.js
@@ -1,7 +1,6 @@
import { shallowMount } from '@vue/test-utils';
-import { GlDeprecatedDropdownItem } from '@gitlab/ui';
+import { GlDeprecatedDropdownItem, GlButton } from '@gitlab/ui';
import KnativeDomainEditor from '~/clusters/components/knative_domain_editor.vue';
-import LoadingButton from '~/vue_shared/components/loading_button.vue';
import { APPLICATION_STATUS } from '~/clusters/constants';
const { UPDATING } = APPLICATION_STATUS;
@@ -79,7 +78,7 @@ describe('KnativeDomainEditor', () => {
});
it('triggers save event and pass current knative hostname', () => {
- wrapper.find(LoadingButton).vm.$emit('click');
+ wrapper.find(GlButton).vm.$emit('click');
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.emitted('save').length).toEqual(1);
});
@@ -166,15 +165,15 @@ describe('KnativeDomainEditor', () => {
});
it('renders loading spinner in save button', () => {
- expect(wrapper.find(LoadingButton).props('loading')).toBe(true);
+ expect(wrapper.find(GlButton).props('loading')).toBe(true);
});
it('renders disabled save button', () => {
- expect(wrapper.find(LoadingButton).props('disabled')).toBe(true);
+ expect(wrapper.find(GlButton).props('disabled')).toBe(true);
});
it('renders save button with "Saving" label', () => {
- expect(wrapper.find(LoadingButton).props('label')).toBe('Saving');
+ expect(wrapper.find(GlButton).text()).toBe('Saving');
});
});
});
diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb
index d38635292a5..45deec259f1 100644
--- a/spec/lib/gitlab/usage_data_spec.rb
+++ b/spec/lib/gitlab/usage_data_spec.rb
@@ -57,6 +57,21 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
end
end
+ describe 'usage_activity_by_stage_package' do
+ it 'includes accurate usage_activity_by_stage data' do
+ for_defined_days_back do
+ create(:project, packages: [create(:package)] )
+ end
+
+ expect(described_class.usage_activity_by_stage_package({})).to eq(
+ projects_with_packages: 2
+ )
+ expect(described_class.usage_activity_by_stage_package(described_class.last_28_days_time_period)).to eq(
+ projects_with_packages: 1
+ )
+ end
+ end
+
describe '.usage_activity_by_stage_configure' do
it 'includes accurate usage_activity_by_stage data' do
for_defined_days_back do
@@ -400,6 +415,8 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
expect(count_data[:snippets]).to eq(6)
expect(count_data[:personal_snippets]).to eq(2)
expect(count_data[:project_snippets]).to eq(4)
+
+ expect(count_data[:projects_with_packages]).to eq(2)
end
it 'gathers object store usage correctly' do