summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-02-17 12:09:26 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-02-17 12:09:26 +0000
commit75a4eaade04ee758bb3b253f27bf1c20c67991f0 (patch)
tree779b3011793bf35770774dbaa51eec55efd320cd
parent839e879bcf197a283da8481ddcb15b177172784d (diff)
downloadgitlab-ce-75a4eaade04ee758bb3b253f27bf1c20c67991f0.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/assets/javascripts/diffs/components/app.vue2
-rw-r--r--app/assets/javascripts/ide/components/branches/search_list.vue5
-rw-r--r--app/assets/javascripts/ide/components/merge_requests/list.vue5
-rw-r--r--app/assets/javascripts/ide/components/nav_form.vue25
-rw-r--r--app/assets/javascripts/vue_shared/components/tabs/tab.vue47
-rw-r--r--app/assets/javascripts/vue_shared/components/tabs/tabs.js76
-rw-r--r--app/assets/stylesheets/page_bundles/ide.scss3
-rw-r--r--app/finders/concerns/packages/finder_helper.rb33
-rw-r--r--app/finders/packages/group_packages_finder.rb30
-rw-r--r--app/finders/packages/packages_finder.rb21
-rw-r--r--app/models/packages/package.rb4
-rw-r--r--app/services/packages/create_package_service.rb7
-rw-r--r--app/services/packages/generic/create_package_file_service.rb5
-rw-r--r--app/services/packages/maven/find_or_create_package_service.rb1
-rw-r--r--changelogs/unreleased/290741-packages-hidden-status.yml5
-rw-r--r--changelogs/unreleased/cngo-convert-tab-to-gl-tab.yml5
-rw-r--r--db/migrate/20210204152257_add_status_to_packages_packages.rb9
-rw-r--r--db/migrate/20210209171525_add_status_index_to_packages_packages.rb19
-rw-r--r--db/schema_migrations/202102041522571
-rw-r--r--db/schema_migrations/202102091715251
-rw-r--r--db/structure.sql5
-rw-r--r--doc/api/packages.md8
-rw-r--r--doc/user/group/roadmap/index.md2
-rw-r--r--doc/user/packages/generic_packages/index.md1
-rw-r--r--lib/api/generic_packages.rb4
-rw-r--r--lib/api/group_packages.rb4
-rw-r--r--lib/api/project_packages.rb4
-rw-r--r--lib/gitlab/url_blocker.rb5
-rw-r--r--locale/gitlab.pot3
-rw-r--r--spec/factories/packages.rb9
-rw-r--r--spec/finders/packages/group_packages_finder_spec.rb1
-rw-r--r--spec/finders/packages/packages_finder_spec.rb1
-rw-r--r--spec/frontend/vue_shared/components/tabs/tab_spec.js32
-rw-r--r--spec/frontend/vue_shared/components/tabs/tabs_spec.js61
-rw-r--r--spec/lib/gitlab/url_blocker_spec.rb28
-rw-r--r--spec/models/packages/package_spec.rb24
-rw-r--r--spec/requests/api/generic_packages_spec.rb34
-rw-r--r--spec/requests/api/group_packages_spec.rb1
-rw-r--r--spec/requests/api/project_packages_spec.rb1
-rw-r--r--spec/services/packages/composer/create_package_service_spec.rb2
-rw-r--r--spec/services/packages/conan/create_package_service_spec.rb1
-rw-r--r--spec/services/packages/generic/create_package_file_service_spec.rb40
-rw-r--r--spec/services/packages/maven/find_or_create_package_service_spec.rb3
-rw-r--r--spec/services/packages/npm/create_package_service_spec.rb1
-rw-r--r--spec/services/packages/nuget/create_package_service_spec.rb1
-rw-r--r--spec/services/packages/pypi/create_package_service_spec.rb1
-rw-r--r--spec/support/helpers/dns_helpers.rb35
-rw-r--r--spec/support/helpers/stub_requests.rb19
-rw-r--r--spec/support/shared_examples/finders/packages_shared_examples.rb20
-rw-r--r--spec/support/shared_examples/services/packages_shared_examples.rb51
50 files changed, 343 insertions, 363 deletions
diff --git a/app/assets/javascripts/diffs/components/app.vue b/app/assets/javascripts/diffs/components/app.vue
index bb311148627..4323499ef1f 100644
--- a/app/assets/javascripts/diffs/components/app.vue
+++ b/app/assets/javascripts/diffs/components/app.vue
@@ -522,7 +522,7 @@ export default {
:file="file"
:reviewed="fileReviews[index]"
:is-first-file="index === 0"
- :is-last-file="index === diffs.length - 1"
+ :is-last-file="index === diffFilesLength - 1"
:help-page-path="helpPagePath"
:can-current-user-fork="canCurrentUserFork"
:view-diffs-file-by-file="viewDiffsFileByFile"
diff --git a/app/assets/javascripts/ide/components/branches/search_list.vue b/app/assets/javascripts/ide/components/branches/search_list.vue
index 1ae7cf9339d..62e93335a20 100644
--- a/app/assets/javascripts/ide/components/branches/search_list.vue
+++ b/app/assets/javascripts/ide/components/branches/search_list.vue
@@ -57,7 +57,10 @@ export default {
<template>
<div>
- <label class="dropdown-input pt-3 pb-3 mb-0 border-bottom block position-relative" @click.stop>
+ <label
+ class="dropdown-input gl-pt-3 gl-pb-5 gl-mb-0 gl-border-b-1 gl-border-b-solid gl-display-block"
+ @click.stop
+ >
<input
ref="searchInput"
v-model="search"
diff --git a/app/assets/javascripts/ide/components/merge_requests/list.vue b/app/assets/javascripts/ide/components/merge_requests/list.vue
index 680e8841a1f..7cb6d4d3dac 100644
--- a/app/assets/javascripts/ide/components/merge_requests/list.vue
+++ b/app/assets/javascripts/ide/components/merge_requests/list.vue
@@ -75,7 +75,10 @@ export default {
<template>
<div>
- <label class="dropdown-input pt-3 pb-3 mb-0 border-bottom block" @click.stop>
+ <label
+ class="dropdown-input gl-pt-3 gl-pb-5 gl-mb-0 gl-border-b-1 gl-border-b-solid gl-display-block"
+ @click.stop
+ >
<tokened-input
v-model="search"
:tokens="searchTokens"
diff --git a/app/assets/javascripts/ide/components/nav_form.vue b/app/assets/javascripts/ide/components/nav_form.vue
index 62bb4841760..98f0504298b 100644
--- a/app/assets/javascripts/ide/components/nav_form.vue
+++ b/app/assets/javascripts/ide/components/nav_form.vue
@@ -1,13 +1,12 @@
<script>
-import Tab from '~/vue_shared/components/tabs/tab.vue';
-import Tabs from '~/vue_shared/components/tabs/tabs';
+import { GlTab, GlTabs } from '@gitlab/ui';
import BranchesSearchList from './branches/search_list.vue';
import MergeRequestSearchList from './merge_requests/list.vue';
export default {
components: {
- Tabs,
- Tab,
+ GlTab,
+ GlTabs,
BranchesSearchList,
MergeRequestSearchList,
},
@@ -23,20 +22,14 @@ export default {
<template>
<div class="ide-nav-form p-0">
- <tabs v-if="showMergeRequests" stop-propagation>
- <tab active>
- <template #title>
- {{ __('Branches') }}
- </template>
+ <gl-tabs v-if="showMergeRequests">
+ <gl-tab :title="__('Branches')">
<branches-search-list />
- </tab>
- <tab>
- <template #title>
- {{ __('Merge Requests') }}
- </template>
+ </gl-tab>
+ <gl-tab :title="__('Merge Requests')">
<merge-request-search-list />
- </tab>
- </tabs>
+ </gl-tab>
+ </gl-tabs>
<branches-search-list v-else />
</div>
</template>
diff --git a/app/assets/javascripts/vue_shared/components/tabs/tab.vue b/app/assets/javascripts/vue_shared/components/tabs/tab.vue
deleted file mode 100644
index d24c27cfcc3..00000000000
--- a/app/assets/javascripts/vue_shared/components/tabs/tab.vue
+++ /dev/null
@@ -1,47 +0,0 @@
-<script>
-export default {
- props: {
- title: {
- type: String,
- required: false,
- default: '',
- },
- active: {
- type: Boolean,
- required: false,
- default: false,
- },
- },
- data() {
- return {
- // props can't be updated, so we map it to data where we can
- localActive: this.active,
- };
- },
- watch: {
- active() {
- this.localActive = this.active;
- },
- },
- created() {
- this.isTab = true;
- },
- updated() {
- if (this.$parent) {
- this.$parent.$forceUpdate();
- }
- },
-};
-</script>
-
-<template>
- <div
- :class="{
- active: localActive,
- }"
- class="tab-pane"
- role="tabpanel"
- >
- <slot></slot>
- </div>
-</template>
diff --git a/app/assets/javascripts/vue_shared/components/tabs/tabs.js b/app/assets/javascripts/vue_shared/components/tabs/tabs.js
deleted file mode 100644
index 233df96a520..00000000000
--- a/app/assets/javascripts/vue_shared/components/tabs/tabs.js
+++ /dev/null
@@ -1,76 +0,0 @@
-export default {
- props: {
- stopPropagation: {
- type: Boolean,
- required: false,
- default: false,
- },
- },
- data() {
- return {
- currentIndex: 0,
- tabs: [],
- };
- },
- mounted() {
- this.updateTabs();
- },
- methods: {
- updateTabs() {
- this.tabs = this.$children.filter((child) => child.isTab);
- this.currentIndex = this.tabs.findIndex((tab) => tab.localActive);
- },
- setTab(e, index) {
- if (this.stopPropagation) {
- e.stopPropagation();
- e.preventDefault();
- }
-
- this.tabs[this.currentIndex].localActive = false;
- this.tabs[index].localActive = true;
-
- this.currentIndex = index;
- },
- },
- render(h) {
- const navItems = this.tabs.map((tab, i) =>
- h(
- 'li',
- {
- key: i,
- },
- [
- h(
- 'a',
- {
- class: tab.localActive ? 'active' : null,
- attrs: {
- href: '#',
- },
- on: {
- click: (e) => this.setTab(e, i),
- },
- },
- tab.$slots.title || tab.title,
- ),
- ],
- ),
- );
- const nav = h(
- 'ul',
- {
- class: 'nav-links tab-links',
- },
- [navItems],
- );
- const content = h(
- 'div',
- {
- class: ['tab-content'],
- },
- [this.$slots.default],
- );
-
- return h('div', {}, [[nav], content]);
- },
-};
diff --git a/app/assets/stylesheets/page_bundles/ide.scss b/app/assets/stylesheets/page_bundles/ide.scss
index 7c4d51ab677..009019a45d9 100644
--- a/app/assets/stylesheets/page_bundles/ide.scss
+++ b/app/assets/stylesheets/page_bundles/ide.scss
@@ -1043,8 +1043,7 @@ $ide-commit-header-height: 48px;
.input-icon {
right: auto;
left: 10px;
- top: 50%;
- transform: translateY(-50%);
+ top: 1rem;
}
}
diff --git a/app/finders/concerns/packages/finder_helper.rb b/app/finders/concerns/packages/finder_helper.rb
index 524e7aa7ff9..30bc0ff7909 100644
--- a/app/finders/concerns/packages/finder_helper.rb
+++ b/app/finders/concerns/packages/finder_helper.rb
@@ -4,6 +4,9 @@ module Packages
module FinderHelper
extend ActiveSupport::Concern
+ InvalidPackageTypeError = Class.new(StandardError)
+ InvalidStatusError = Class.new(StandardError)
+
private
def packages_visible_to_user(user, within_group:)
@@ -25,5 +28,35 @@ module Packages
::Project.in_namespace(namespace_ids)
.public_or_visible_to_user(user, ::Gitlab::Access::REPORTER)
end
+
+ def package_type
+ params[:package_type].presence
+ end
+
+ def filter_by_package_type(packages)
+ return packages unless package_type
+ raise InvalidPackageTypeError unless ::Packages::Package.package_types.key?(package_type)
+
+ packages.with_package_type(package_type)
+ end
+
+ def filter_by_package_name(packages)
+ return packages unless params[:package_name].present?
+
+ packages.search_by_name(params[:package_name])
+ end
+
+ def filter_with_version(packages)
+ return packages if params[:include_versionless].present?
+
+ packages.has_version
+ end
+
+ def filter_by_status(packages)
+ return packages.displayable unless params[:status].present?
+ raise InvalidStatusError unless Package.statuses.key?(params[:status])
+
+ packages.with_status(params[:status])
+ end
end
end
diff --git a/app/finders/packages/group_packages_finder.rb b/app/finders/packages/group_packages_finder.rb
index 860c4068b31..db5161d6e16 100644
--- a/app/finders/packages/group_packages_finder.rb
+++ b/app/finders/packages/group_packages_finder.rb
@@ -2,9 +2,7 @@
module Packages
class GroupPackagesFinder
- attr_reader :current_user, :group, :params
-
- InvalidPackageTypeError = Class.new(StandardError)
+ include ::Packages::FinderHelper
def initialize(current_user, group, params = { exclude_subgroups: false, order_by: 'created_at', sort: 'asc' })
@current_user = current_user
@@ -20,6 +18,8 @@ module Packages
private
+ attr_reader :current_user, :group, :params
+
def packages_for_group_projects
packages = ::Packages::Package
.including_build_info
@@ -32,6 +32,7 @@ module Packages
packages = filter_with_version(packages)
packages = filter_by_package_type(packages)
packages = filter_by_package_name(packages)
+ packages = filter_by_status(packages)
packages
end
@@ -46,10 +47,6 @@ module Packages
.with_feature_available_for_user(:repository, current_user)
end
- def package_type
- params[:package_type].presence
- end
-
def groups
return [group] if exclude_subgroups?
@@ -59,24 +56,5 @@ module Packages
def exclude_subgroups?
params[:exclude_subgroups]
end
-
- def filter_by_package_type(packages)
- return packages unless package_type
- raise InvalidPackageTypeError unless Package.package_types.key?(package_type)
-
- packages.with_package_type(package_type)
- end
-
- def filter_by_package_name(packages)
- return packages unless params[:package_name].present?
-
- packages.search_by_name(params[:package_name])
- end
-
- def filter_with_version(packages)
- return packages if params[:include_versionless].present?
-
- packages.has_version
- end
end
end
diff --git a/app/finders/packages/packages_finder.rb b/app/finders/packages/packages_finder.rb
index 72a63224d2f..bd9e62e3f2a 100644
--- a/app/finders/packages/packages_finder.rb
+++ b/app/finders/packages/packages_finder.rb
@@ -2,7 +2,7 @@
module Packages
class PackagesFinder
- attr_reader :params, :project
+ include ::Packages::FinderHelper
def initialize(project, params = {})
@project = project
@@ -21,29 +21,14 @@ module Packages
packages = filter_with_version(packages)
packages = filter_by_package_type(packages)
packages = filter_by_package_name(packages)
+ packages = filter_by_status(packages)
packages = order_packages(packages)
packages
end
private
- def filter_with_version(packages)
- return packages if params[:include_versionless].present?
-
- packages.has_version
- end
-
- def filter_by_package_type(packages)
- return packages unless params[:package_type]
-
- packages.with_package_type(params[:package_type])
- end
-
- def filter_by_package_name(packages)
- return packages unless params[:package_name]
-
- packages.search_by_name(params[:package_name])
- end
+ attr_reader :params, :project
def order_packages(packages)
packages.sort_by_attribute("#{params[:order_by]}_#{params[:sort]}")
diff --git a/app/models/packages/package.rb b/app/models/packages/package.rb
index 7bc74e0db74..391540634be 100644
--- a/app/models/packages/package.rb
+++ b/app/models/packages/package.rb
@@ -69,6 +69,8 @@ class Packages::Package < ApplicationRecord
composer: 6, generic: 7, golang: 8, debian: 9,
rubygems: 10 }
+ enum status: { default: 0, hidden: 1, processing: 2 }
+
scope :with_name, ->(name) { where(name: name) }
scope :with_name_like, ->(name) { where(arel_table[:name].matches(name)) }
scope :with_normalized_pypi_name, ->(name) { where("LOWER(regexp_replace(name, '[-_.]+', '-', 'g')) = ?", name.downcase) }
@@ -76,6 +78,8 @@ class Packages::Package < ApplicationRecord
scope :with_version, ->(version) { where(version: version) }
scope :without_version_like, -> (version) { where.not(arel_table[:version].matches(version)) }
scope :with_package_type, ->(package_type) { where(package_type: package_type) }
+ scope :with_status, ->(status) { where(status: status) }
+ scope :displayable, -> { with_status(:default) }
scope :including_build_info, -> { includes(pipelines: :user) }
scope :including_project_route, -> { includes(project: { namespace: :route }) }
scope :including_tags, -> { includes(:tags) }
diff --git a/app/services/packages/create_package_service.rb b/app/services/packages/create_package_service.rb
index fcf252cf971..3dc06497d9f 100644
--- a/app/services/packages/create_package_service.rb
+++ b/app/services/packages/create_package_service.rb
@@ -9,7 +9,9 @@ module Packages
.packages
.with_package_type(package_type)
.safe_find_or_create_by!(name: name, version: version) do |package|
+ package.status = params[:status] if params[:status]
package.creator = package_creator
+
add_build_info(package)
end
end
@@ -29,8 +31,9 @@ module Packages
{
creator: package_creator,
name: params[:name],
- version: params[:version]
- }.merge(attrs)
+ version: params[:version],
+ status: params[:status]
+ }.compact.merge(attrs)
end
def package_creator
diff --git a/app/services/packages/generic/create_package_file_service.rb b/app/services/packages/generic/create_package_file_service.rb
index b14b1c193ec..1451a022a39 100644
--- a/app/services/packages/generic/create_package_file_service.rb
+++ b/app/services/packages/generic/create_package_file_service.rb
@@ -15,13 +15,16 @@ module Packages
package_params = {
name: params[:package_name],
version: params[:package_version],
- build: params[:build]
+ build: params[:build],
+ status: params[:status]
}
package = ::Packages::Generic::FindOrCreatePackageService
.new(project, current_user, package_params)
.execute
+ package.update_column(:status, params[:status]) if params[:status] && params[:status] != package.status
+
package.build_infos.safe_find_or_create_by!(pipeline: params[:build].pipeline) if params[:build].present?
package
end
diff --git a/app/services/packages/maven/find_or_create_package_service.rb b/app/services/packages/maven/find_or_create_package_service.rb
index 6e0346058e8..4c916d264a7 100644
--- a/app/services/packages/maven/find_or_create_package_service.rb
+++ b/app/services/packages/maven/find_or_create_package_service.rb
@@ -42,6 +42,7 @@ module Packages
package_params = {
name: package_name,
path: params[:path],
+ status: params[:status],
version: version
}
diff --git a/changelogs/unreleased/290741-packages-hidden-status.yml b/changelogs/unreleased/290741-packages-hidden-status.yml
new file mode 100644
index 00000000000..03c5fd0f4eb
--- /dev/null
+++ b/changelogs/unreleased/290741-packages-hidden-status.yml
@@ -0,0 +1,5 @@
+---
+title: Add status attribute to packages and ability to set 'hidden' for generic packages
+merge_request: 53385
+author:
+type: added
diff --git a/changelogs/unreleased/cngo-convert-tab-to-gl-tab.yml b/changelogs/unreleased/cngo-convert-tab-to-gl-tab.yml
new file mode 100644
index 00000000000..f4a843ea6dc
--- /dev/null
+++ b/changelogs/unreleased/cngo-convert-tab-to-gl-tab.yml
@@ -0,0 +1,5 @@
+---
+title: Convert IDE nav form tab to GlTab
+merge_request: 54274
+author:
+type: changed
diff --git a/db/migrate/20210204152257_add_status_to_packages_packages.rb b/db/migrate/20210204152257_add_status_to_packages_packages.rb
new file mode 100644
index 00000000000..4fd441048c6
--- /dev/null
+++ b/db/migrate/20210204152257_add_status_to_packages_packages.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddStatusToPackagesPackages < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ def change
+ add_column :packages_packages, :status, :smallint, default: 0, null: false
+ end
+end
diff --git a/db/migrate/20210209171525_add_status_index_to_packages_packages.rb b/db/migrate/20210209171525_add_status_index_to_packages_packages.rb
new file mode 100644
index 00000000000..cb956165d6e
--- /dev/null
+++ b/db/migrate/20210209171525_add_status_index_to_packages_packages.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddStatusIndexToPackagesPackages < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_packages_packages_on_project_id_and_status'
+
+ def up
+ add_concurrent_index :packages_packages, [:project_id, :status], name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :packages_packages, name: INDEX_NAME
+ end
+end
diff --git a/db/schema_migrations/20210204152257 b/db/schema_migrations/20210204152257
new file mode 100644
index 00000000000..c98d4637d05
--- /dev/null
+++ b/db/schema_migrations/20210204152257
@@ -0,0 +1 @@
+cb9f4b4e627cbc163653fc01c0542ef0ce87139b376c55bbaa4d7ab23e9b8973 \ No newline at end of file
diff --git a/db/schema_migrations/20210209171525 b/db/schema_migrations/20210209171525
new file mode 100644
index 00000000000..0c421b99a39
--- /dev/null
+++ b/db/schema_migrations/20210209171525
@@ -0,0 +1 @@
+5c661c453922181b350b8551d9a8f9b097e568459a2c2d128e41d9aefb026ab5 \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index d582c343e73..97a2850fd5c 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -15244,7 +15244,8 @@ CREATE TABLE packages_packages (
name character varying NOT NULL,
version character varying,
package_type smallint NOT NULL,
- creator_id integer
+ creator_id integer,
+ status smallint DEFAULT 0 NOT NULL
);
CREATE SEQUENCE packages_packages_id_seq
@@ -22886,6 +22887,8 @@ CREATE INDEX index_packages_packages_on_project_id_and_created_at ON packages_pa
CREATE INDEX index_packages_packages_on_project_id_and_package_type ON packages_packages USING btree (project_id, package_type);
+CREATE INDEX index_packages_packages_on_project_id_and_status ON packages_packages USING btree (project_id, status);
+
CREATE INDEX index_packages_packages_on_project_id_and_version ON packages_packages USING btree (project_id, version);
CREATE INDEX index_packages_project_id_name_partial_for_nuget ON packages_packages USING btree (project_id, name) WHERE (((name)::text <> 'NuGet.Temporary.Package'::text) AND (version IS NOT NULL) AND (package_type = 4));
diff --git a/doc/api/packages.md b/doc/api/packages.md
index 516f171e851..112c7ef2e61 100644
--- a/doc/api/packages.md
+++ b/doc/api/packages.md
@@ -29,6 +29,7 @@ GET /projects/:id/packages
| `package_type` | string | no | Filter the returned packages by type. One of `conan`, `maven`, `npm`, `pypi`, `composer`, `nuget`, or `golang`. (_Introduced in GitLab 12.9_)
| `package_name` | string | no | Filter the project packages with a fuzzy search by name. (_Introduced in GitLab 12.9_)
| `include_versionless` | boolean | no | When set to true, versionless packages are included in the response. (_Introduced in GitLab 13.8_)
+| `status` | string | no | Filter the returned packages by status. One of `default` (default), `hidden`, or `processing`. (_Introduced in GitLab 13.9_)
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/:id/packages"
@@ -70,6 +71,9 @@ Example response:
By default, the `GET` request returns 20 results, because the API is [paginated](README.md#pagination).
+Although you can filter packages by status, working with packages that have a `processing` status
+can result in malformed data or broken packages.
+
### Within a group
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/18871) in GitLab 12.5.
@@ -90,6 +94,7 @@ GET /groups/:id/packages
| `package_type` | string | no | Filter the returned packages by type. One of `conan`, `maven`, `npm`, `pypi`, `composer`, `nuget`, or `golang`. (_Introduced in GitLab 12.9_) |
| `package_name` | string | no | Filter the project packages with a fuzzy search by name. (_[Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30980) in GitLab 13.0_)
| `include_versionless` | boolean | no | When set to true, versionless packages are included in the response. (_Introduced in GitLab 13.8_)
+| `status` | string | no | Filter the returned packages by status. One of `default` (default), `hidden`, or `processing`. (_Introduced in GitLab 13.9_)
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/:id/packages?exclude_subgroups=false"
@@ -166,6 +171,9 @@ The `_links` object contains the following properties:
- `web_path`: The path which you can visit in GitLab and see the details of the package.
- `delete_api_path`: The API path to delete the package. Only available if the request user has permission to do so.
+Although you can filter packages by status, working with packages that have a `processing` status
+can result in malformed data or broken packages.
+
## Get a project package
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/9667) in GitLab 11.9.
diff --git a/doc/user/group/roadmap/index.md b/doc/user/group/roadmap/index.md
index e2c01987e36..9b3ae75b39c 100644
--- a/doc/user/group/roadmap/index.md
+++ b/doc/user/group/roadmap/index.md
@@ -41,7 +41,7 @@ toggle the list of the milestone bars.
> - Filtering roadmaps by milestone is enabled on GitLab.com.
> - Filtering roadmaps by milestone is recommended for production use.
> - For GitLab self-managed instances, GitLab administrators can opt to [disable it](#enable-or-disable-filtering-roadmaps-by-milestone). **(PREMIUM SELF)**
-> - Filtering by epic confidentiality [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/218624) in GitLab 13.8.
+> - Filtering by epic confidentiality [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/218624) in GitLab 13.9.
WARNING:
Filtering roadmaps by milestone might not be available to you. Check the **version history** note above for details.
diff --git a/doc/user/packages/generic_packages/index.md b/doc/user/packages/generic_packages/index.md
index 11af10bf8a0..73b84c04b6d 100644
--- a/doc/user/packages/generic_packages/index.md
+++ b/doc/user/packages/generic_packages/index.md
@@ -49,6 +49,7 @@ PUT /projects/:id/packages/generic/:package_name/:package_version/:file_name
| `package_name` | string | yes | The package name. It can contain only lowercase letters (`a-z`), uppercase letter (`A-Z`), numbers (`0-9`), dots (`.`), hyphens (`-`), or underscores (`_`).
| `package_version` | string | yes | The package version. It can contain only numbers (`0-9`), and dots (`.`). Must be in the format of `X.Y.Z`, i.e. should match `/\A\d+\.\d+\.\d+\z/` regular expression.
| `file_name` | string | yes | The filename. It can contain only lowercase letters (`a-z`), uppercase letter (`A-Z`), numbers (`0-9`), dots (`.`), hyphens (`-`), or underscores (`_`).
+| `status` | string | no | The package status. It can be `default` (default) or `hidden`. Hidden packages do not appear in the UI or [package API list endpoints](../../../api/packages.md).
Provide the file context in the request body.
diff --git a/lib/api/generic_packages.rb b/lib/api/generic_packages.rb
index 167531fdaec..24d726f4a41 100644
--- a/lib/api/generic_packages.rb
+++ b/lib/api/generic_packages.rb
@@ -7,6 +7,8 @@ module API
file_name: API::NO_SLASH_URL_PART_REGEX
}.freeze
+ ALLOWED_STATUSES = %w[default hidden].freeze
+
feature_category :package_registry
before do
@@ -35,6 +37,7 @@ module API
requires :package_name, type: String, desc: 'Package name', regexp: Gitlab::Regex.generic_package_name_regex, file_path: true
requires :package_version, type: String, desc: 'Package version', regexp: Gitlab::Regex.generic_package_version_regex
requires :file_name, type: String, desc: 'Package file name', regexp: Gitlab::Regex.generic_package_file_name_regex, file_path: true
+ optional :status, type: String, values: ALLOWED_STATUSES, desc: 'Package status'
end
put 'authorize' do
@@ -49,6 +52,7 @@ module API
requires :package_name, type: String, desc: 'Package name', regexp: Gitlab::Regex.generic_package_name_regex, file_path: true
requires :package_version, type: String, desc: 'Package version', regexp: Gitlab::Regex.generic_package_version_regex
requires :file_name, type: String, desc: 'Package file name', regexp: Gitlab::Regex.generic_package_file_name_regex, file_path: true
+ optional :status, type: String, values: ALLOWED_STATUSES, desc: 'Package status'
requires :file, type: ::API::Validations::Types::WorkhorseFile, desc: 'The package file to be published (generated by Multipart middleware)'
end
diff --git a/lib/api/group_packages.rb b/lib/api/group_packages.rb
index d482f4d0585..ab4e91ff925 100644
--- a/lib/api/group_packages.rb
+++ b/lib/api/group_packages.rb
@@ -33,12 +33,14 @@ module API
desc: 'Return packages with this name'
optional :include_versionless, type: Boolean,
desc: 'Returns packages without a version'
+ optional :status, type: String, values: Packages::Package.statuses.keys,
+ desc: 'Return packages with specified status'
end
get ':id/packages' do
packages = Packages::GroupPackagesFinder.new(
current_user,
user_group,
- declared(params).slice(:exclude_subgroups, :order_by, :sort, :package_type, :package_name, :include_versionless)
+ declared(params).slice(:exclude_subgroups, :order_by, :sort, :package_type, :package_name, :include_versionless, :status)
).execute
present paginate(packages), with: ::API::Entities::Package, user: current_user, group: true
diff --git a/lib/api/project_packages.rb b/lib/api/project_packages.rb
index 32636662987..0fdaa4b2656 100644
--- a/lib/api/project_packages.rb
+++ b/lib/api/project_packages.rb
@@ -32,11 +32,13 @@ module API
desc: 'Return packages with this name'
optional :include_versionless, type: Boolean,
desc: 'Returns packages without a version'
+ optional :status, type: String, values: Packages::Package.statuses.keys,
+ desc: 'Return packages with specified status'
end
get ':id/packages' do
packages = ::Packages::PackagesFinder.new(
user_project,
- declared_params.slice(:order_by, :sort, :package_type, :package_name, :include_versionless)
+ declared_params.slice(:order_by, :sort, :package_type, :package_name, :include_versionless, :status)
).execute
present paginate(packages), with: ::API::Entities::Package, user: current_user
diff --git a/lib/gitlab/url_blocker.rb b/lib/gitlab/url_blocker.rb
index 5403017d710..10822f943b6 100644
--- a/lib/gitlab/url_blocker.rb
+++ b/lib/gitlab/url_blocker.rb
@@ -7,9 +7,6 @@ module Gitlab
class UrlBlocker
BlockedUrlError = Class.new(StandardError)
- GETADDRINFO_TIMEOUT_SECONDS = 15
- private_constant :GETADDRINFO_TIMEOUT_SECONDS
-
class << self
# Validates the given url according to the constraints specified by arguments.
#
@@ -113,7 +110,7 @@ module Gitlab
end
def get_address_info(uri, dns_rebind_protection)
- Addrinfo.getaddrinfo(uri.hostname, get_port(uri), nil, :STREAM, timeout: GETADDRINFO_TIMEOUT_SECONDS).map do |addr|
+ Addrinfo.getaddrinfo(uri.hostname, get_port(uri), nil, :STREAM).map do |addr|
addr.ipv6_v4mapped? ? addr.ipv6_to_ipv4 : addr
end
rescue SocketError
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index e2a824b3299..1bcd85ca9e2 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -18536,6 +18536,9 @@ msgstr ""
msgid "Merge request (MR) approvals"
msgstr ""
+msgid "Merge request approval settings have been updated."
+msgstr ""
+
msgid "Merge request approvals"
msgstr ""
diff --git a/spec/factories/packages.rb b/spec/factories/packages.rb
index 7cf37db340d..2c64abefb01 100644
--- a/spec/factories/packages.rb
+++ b/spec/factories/packages.rb
@@ -6,6 +6,15 @@ FactoryBot.define do
name { 'my/company/app/my-app' }
sequence(:version) { |n| "1.#{n}-SNAPSHOT" }
package_type { :maven }
+ status { :default }
+
+ trait :hidden do
+ status { :hidden }
+ end
+
+ trait :processing do
+ status { :processing }
+ end
factory :maven_package do
maven_metadatum
diff --git a/spec/finders/packages/group_packages_finder_spec.rb b/spec/finders/packages/group_packages_finder_spec.rb
index 8dd53b9c3f9..445482a5a96 100644
--- a/spec/finders/packages/group_packages_finder_spec.rb
+++ b/spec/finders/packages/group_packages_finder_spec.rb
@@ -147,6 +147,7 @@ RSpec.describe Packages::GroupPackagesFinder do
end
it_behaves_like 'concerning versionless param'
+ it_behaves_like 'concerning package statuses'
end
context 'group has package of all types' do
diff --git a/spec/finders/packages/packages_finder_spec.rb b/spec/finders/packages/packages_finder_spec.rb
index 77a171db144..6e92616bafa 100644
--- a/spec/finders/packages/packages_finder_spec.rb
+++ b/spec/finders/packages/packages_finder_spec.rb
@@ -82,5 +82,6 @@ RSpec.describe ::Packages::PackagesFinder do
end
it_behaves_like 'concerning versionless param'
+ it_behaves_like 'concerning package statuses'
end
end
diff --git a/spec/frontend/vue_shared/components/tabs/tab_spec.js b/spec/frontend/vue_shared/components/tabs/tab_spec.js
deleted file mode 100644
index ee0c983c764..00000000000
--- a/spec/frontend/vue_shared/components/tabs/tab_spec.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import Vue from 'vue';
-import mountComponent from 'helpers/vue_mount_component_helper';
-import Tab from '~/vue_shared/components/tabs/tab.vue';
-
-describe('Tab component', () => {
- const Component = Vue.extend(Tab);
- let vm;
-
- beforeEach(() => {
- vm = mountComponent(Component);
- });
-
- it('sets localActive to equal active', (done) => {
- vm.active = true;
-
- vm.$nextTick(() => {
- expect(vm.localActive).toBe(true);
-
- done();
- });
- });
-
- it('sets active class', (done) => {
- vm.active = true;
-
- vm.$nextTick(() => {
- expect(vm.$el.classList).toContain('active');
-
- done();
- });
- });
-});
diff --git a/spec/frontend/vue_shared/components/tabs/tabs_spec.js b/spec/frontend/vue_shared/components/tabs/tabs_spec.js
deleted file mode 100644
index fe7be5be899..00000000000
--- a/spec/frontend/vue_shared/components/tabs/tabs_spec.js
+++ /dev/null
@@ -1,61 +0,0 @@
-import Vue from 'vue';
-import Tab from '~/vue_shared/components/tabs/tab.vue';
-import Tabs from '~/vue_shared/components/tabs/tabs';
-
-describe('Tabs component', () => {
- let vm;
-
- beforeEach(() => {
- vm = new Vue({
- components: {
- Tabs,
- Tab,
- },
- render(h) {
- return h('div', [
- h('tabs', [
- h('tab', { attrs: { title: 'Testing', active: true } }, 'First tab'),
- h('tab', [h('template', { slot: 'title' }, 'Test slot'), 'Second tab']),
- ]),
- ]);
- },
- }).$mount();
-
- return vm.$nextTick();
- });
-
- describe('tab links', () => {
- it('renders links for tabs', () => {
- expect(vm.$el.querySelectorAll('a').length).toBe(2);
- });
-
- it('renders link titles from props', () => {
- expect(vm.$el.querySelector('a').textContent).toContain('Testing');
- });
-
- it('renders link titles from slot', () => {
- expect(vm.$el.querySelectorAll('a')[1].textContent).toContain('Test slot');
- });
-
- it('renders active class', () => {
- expect(vm.$el.querySelector('a').classList).toContain('active');
- });
-
- it('updates active class on click', () => {
- vm.$el.querySelectorAll('a')[1].click();
-
- return vm.$nextTick(() => {
- expect(vm.$el.querySelector('a').classList).not.toContain('active');
- expect(vm.$el.querySelectorAll('a')[1].classList).toContain('active');
- });
- });
- });
-
- describe('content', () => {
- it('renders content panes', () => {
- expect(vm.$el.querySelectorAll('.tab-pane').length).toBe(2);
- expect(vm.$el.querySelectorAll('.tab-pane')[0].textContent).toContain('First tab');
- expect(vm.$el.querySelectorAll('.tab-pane')[1].textContent).toContain('Second tab');
- });
- });
-});
diff --git a/spec/lib/gitlab/url_blocker_spec.rb b/spec/lib/gitlab/url_blocker_spec.rb
index 4f274387195..fa01d4e48df 100644
--- a/spec/lib/gitlab/url_blocker_spec.rb
+++ b/spec/lib/gitlab/url_blocker_spec.rb
@@ -160,34 +160,6 @@ RSpec.describe Gitlab::UrlBlocker, :stub_invalid_dns_only do
end
end
end
-
- context 'when resolving runs into a timeout' do
- let(:import_url) { 'http://example.com' }
-
- subject { described_class.validate!(import_url, dns_rebind_protection: dns_rebind_protection) }
-
- before do
- stub_env('RSPEC_ALLOW_INVALID_URLS', 'false')
- allow(Addrinfo).to receive(:getaddrinfo).and_raise(SocketError)
- end
-
- context 'with dns rebinding enabled' do
- let(:dns_rebind_protection) { true }
-
- it 'raises an error due to DNS timeout' do
- expect { subject }.to raise_error(described_class::BlockedUrlError)
- end
- end
-
- context 'with dns rebinding disabled' do
- let(:dns_rebind_protection) { false }
-
- it_behaves_like 'validates URI and hostname' do
- let(:expected_uri) { import_url }
- let(:expected_hostname) { nil }
- end
- end
- end
end
describe '#blocked_url?' do
diff --git a/spec/models/packages/package_spec.rb b/spec/models/packages/package_spec.rb
index cdf03b3c958..6c55d37b95f 100644
--- a/spec/models/packages/package_spec.rb
+++ b/spec/models/packages/package_spec.rb
@@ -4,6 +4,8 @@ require 'spec_helper'
RSpec.describe Packages::Package, type: :model do
include SortingHelper
+ it_behaves_like 'having unique enum values'
+
describe 'relationships' do
it { is_expected.to belong_to(:project) }
it { is_expected.to belong_to(:creator) }
@@ -605,6 +607,28 @@ RSpec.describe Packages::Package, type: :model do
it { is_expected.to match_array([pypi_package]) }
end
+
+ describe '.displayable' do
+ let_it_be(:hidden_package) { create(:maven_package, :hidden) }
+ let_it_be(:processing_package) { create(:maven_package, :processing) }
+
+ subject { described_class.displayable }
+
+ it 'does not include hidden packages', :aggregate_failures do
+ is_expected.not_to include(hidden_package)
+ is_expected.not_to include(processing_package)
+ end
+ end
+
+ describe '.with_status' do
+ let_it_be(:hidden_package) { create(:maven_package, :hidden) }
+
+ subject { described_class.with_status(:hidden) }
+
+ it 'returns packages with specified status' do
+ is_expected.to match_array([hidden_package])
+ end
+ end
end
describe '.select_distinct_name' do
diff --git a/spec/requests/api/generic_packages_spec.rb b/spec/requests/api/generic_packages_spec.rb
index 430cea17170..a47be1ead9c 100644
--- a/spec/requests/api/generic_packages_spec.rb
+++ b/spec/requests/api/generic_packages_spec.rb
@@ -281,6 +281,7 @@ RSpec.describe API::GenericPackages do
package = project.packages.generic.last
expect(package.name).to eq('mypackage')
+ expect(package.status).to eq('default')
expect(package.version).to eq('0.0.1')
if should_set_build_info
@@ -293,6 +294,39 @@ RSpec.describe API::GenericPackages do
expect(package_file.file_name).to eq('myfile.tar.gz')
end
end
+
+ context 'with a status' do
+ context 'valid status' do
+ let(:params) { super().merge(status: 'hidden') }
+
+ it 'assigns the status to the package' do
+ headers = workhorse_headers.merge(auth_header)
+
+ upload_file(params, headers)
+
+ aggregate_failures do
+ expect(response).to have_gitlab_http_status(:created)
+
+ package = project.packages.find_by(name: 'mypackage')
+ expect(package).to be_hidden
+ end
+ end
+ end
+
+ context 'invalid status' do
+ let(:params) { super().merge(status: 'processing') }
+
+ it 'rejects the package' do
+ headers = workhorse_headers.merge(auth_header)
+
+ upload_file(params, headers)
+
+ aggregate_failures do
+ expect(response).to have_gitlab_http_status(:bad_request)
+ end
+ end
+ end
+ end
end
context 'when valid personal access token is used' do
diff --git a/spec/requests/api/group_packages_spec.rb b/spec/requests/api/group_packages_spec.rb
index 26895e473de..792aa2c1f20 100644
--- a/spec/requests/api/group_packages_spec.rb
+++ b/spec/requests/api/group_packages_spec.rb
@@ -144,6 +144,7 @@ RSpec.describe API::GroupPackages do
end
it_behaves_like 'with versionless packages'
+ it_behaves_like 'with status param'
it_behaves_like 'does not cause n^2 queries'
end
end
diff --git a/spec/requests/api/project_packages_spec.rb b/spec/requests/api/project_packages_spec.rb
index eb86df36dbb..1f3887cab8a 100644
--- a/spec/requests/api/project_packages_spec.rb
+++ b/spec/requests/api/project_packages_spec.rb
@@ -120,6 +120,7 @@ RSpec.describe API::ProjectPackages do
end
it_behaves_like 'with versionless packages'
+ it_behaves_like 'with status param'
it_behaves_like 'does not cause n^2 queries'
end
end
diff --git a/spec/services/packages/composer/create_package_service_spec.rb b/spec/services/packages/composer/create_package_service_spec.rb
index d10356cfda7..4f1a46e7e45 100644
--- a/spec/services/packages/composer/create_package_service_spec.rb
+++ b/spec/services/packages/composer/create_package_service_spec.rb
@@ -43,6 +43,7 @@ RSpec.describe Packages::Composer::CreatePackageService do
end
it_behaves_like 'assigns build to package'
+ it_behaves_like 'assigns status to package'
end
context 'with a tag' do
@@ -66,6 +67,7 @@ RSpec.describe Packages::Composer::CreatePackageService do
end
it_behaves_like 'assigns build to package'
+ it_behaves_like 'assigns status to package'
end
end
diff --git a/spec/services/packages/conan/create_package_service_spec.rb b/spec/services/packages/conan/create_package_service_spec.rb
index ca783475503..6f644f5ef95 100644
--- a/spec/services/packages/conan/create_package_service_spec.rb
+++ b/spec/services/packages/conan/create_package_service_spec.rb
@@ -31,6 +31,7 @@ RSpec.describe Packages::Conan::CreatePackageService do
it_behaves_like 'assigns the package creator'
it_behaves_like 'assigns build to package'
+ it_behaves_like 'assigns status to package'
end
context 'invalid params' do
diff --git a/spec/services/packages/generic/create_package_file_service_spec.rb b/spec/services/packages/generic/create_package_file_service_spec.rb
index 816e728c342..10c54369f26 100644
--- a/spec/services/packages/generic/create_package_file_service_spec.rb
+++ b/spec/services/packages/generic/create_package_file_service_spec.rb
@@ -13,6 +13,8 @@ RSpec.describe Packages::Generic::CreatePackageFileService do
let(:temp_file) { Tempfile.new("test") }
let(:file) { UploadedFile.new(temp_file.path, sha256: sha256) }
let(:package) { create(:generic_package, project: project) }
+ let(:package_service) { double }
+
let(:params) do
{
package_name: 'mypackage',
@@ -23,31 +25,34 @@ RSpec.describe Packages::Generic::CreatePackageFileService do
}
end
+ let(:package_params) do
+ {
+ name: params[:package_name],
+ version: params[:package_version],
+ build: params[:build],
+ status: nil
+ }
+ end
+
subject { described_class.new(project, user, params).execute }
before do
FileUtils.touch(temp_file)
+ expect(::Packages::Generic::FindOrCreatePackageService).to receive(:new).with(project, user, package_params).and_return(package_service)
+ expect(package_service).to receive(:execute).and_return(package)
end
after do
FileUtils.rm_f(temp_file)
end
- it 'creates package file' do
- package_service = double
- package_params = {
- name: params[:package_name],
- version: params[:package_version],
- build: params[:build]
- }
- expect(::Packages::Generic::FindOrCreatePackageService).to receive(:new).with(project, user, package_params).and_return(package_service)
- expect(package_service).to receive(:execute).and_return(package)
-
+ it 'creates package file', :aggregate_failures do
expect { subject }.to change { package.package_files.count }.by(1)
.and change { Packages::PackageFileBuildInfo.count }.by(1)
package_file = package.package_files.last
aggregate_failures do
+ expect(package_file.package.status).to eq('default')
expect(package_file.package).to eq(package)
expect(package_file.file_name).to eq('myfile.tar.gz.1')
expect(package_file.size).to eq(file.size)
@@ -55,6 +60,21 @@ RSpec.describe Packages::Generic::CreatePackageFileService do
end
end
+ context 'with a status' do
+ let(:params) { super().merge(status: 'hidden') }
+ let(:package_params) { super().merge(status: 'hidden') }
+
+ it 'updates an existing packages status' do
+ expect { subject }.to change { package.package_files.count }.by(1)
+ .and change { Packages::PackageFileBuildInfo.count }.by(1)
+
+ package_file = package.package_files.last
+ aggregate_failures do
+ expect(package_file.package.status).to eq('hidden')
+ end
+ end
+ end
+
it_behaves_like 'assigns build to package file'
end
end
diff --git a/spec/services/packages/maven/find_or_create_package_service_spec.rb b/spec/services/packages/maven/find_or_create_package_service_spec.rb
index 191a443a837..2543ab0c669 100644
--- a/spec/services/packages/maven/find_or_create_package_service_spec.rb
+++ b/spec/services/packages/maven/find_or_create_package_service_spec.rb
@@ -36,10 +36,11 @@ RSpec.describe Packages::Maven::FindOrCreatePackageService do
expect(pkg.version).to eq(version)
end
- context 'with a build' do
+ context 'with optional attributes' do
subject { service.execute.payload[:package] }
it_behaves_like 'assigns build to package'
+ it_behaves_like 'assigns status to package'
end
end
diff --git a/spec/services/packages/npm/create_package_service_spec.rb b/spec/services/packages/npm/create_package_service_spec.rb
index 6db3777cde8..10fce6c1651 100644
--- a/spec/services/packages/npm/create_package_service_spec.rb
+++ b/spec/services/packages/npm/create_package_service_spec.rb
@@ -53,6 +53,7 @@ RSpec.describe Packages::Npm::CreatePackageService do
let(:params) { super().merge(build: job) }
it_behaves_like 'assigns build to package'
+ it_behaves_like 'assigns status to package'
it 'creates a package file build info' do
expect { subject }.to change { Packages::PackageFileBuildInfo.count }.by(1)
diff --git a/spec/services/packages/nuget/create_package_service_spec.rb b/spec/services/packages/nuget/create_package_service_spec.rb
index 5289ad40d61..e338ac36fc3 100644
--- a/spec/services/packages/nuget/create_package_service_spec.rb
+++ b/spec/services/packages/nuget/create_package_service_spec.rb
@@ -32,5 +32,6 @@ RSpec.describe Packages::Nuget::CreatePackageService do
it_behaves_like 'assigns the package creator'
it_behaves_like 'assigns build to package'
+ it_behaves_like 'assigns status to package'
end
end
diff --git a/spec/services/packages/pypi/create_package_service_spec.rb b/spec/services/packages/pypi/create_package_service_spec.rb
index 28a727c4a09..a932cf73eb7 100644
--- a/spec/services/packages/pypi/create_package_service_spec.rb
+++ b/spec/services/packages/pypi/create_package_service_spec.rb
@@ -52,6 +52,7 @@ RSpec.describe Packages::Pypi::CreatePackageService do
end
it_behaves_like 'assigns build to package'
+ it_behaves_like 'assigns status to package'
context 'with an existing package' do
before do
diff --git a/spec/support/helpers/dns_helpers.rb b/spec/support/helpers/dns_helpers.rb
index 52c708e77a5..1795b0a9ac3 100644
--- a/spec/support/helpers/dns_helpers.rb
+++ b/spec/support/helpers/dns_helpers.rb
@@ -12,38 +12,19 @@ module DnsHelpers
end
def stub_all_dns!
- allow(Addrinfo).to receive(:getaddrinfo).and_return([])
+ allow(Addrinfo).to receive(:getaddrinfo).with(anything, anything, nil, :STREAM).and_return([])
+ allow(Addrinfo).to receive(:getaddrinfo).with(anything, anything, nil, :STREAM, anything, anything).and_return([])
end
def stub_invalid_dns!
- invalid_addresses = %r{
- \A
- (?:
- foobar\.\w |
- (?:\d{1,3}\.){4,}\d{1,3}
- )
- \z
- }ix
-
- allow(Addrinfo).to receive(:getaddrinfo)
- .with(invalid_addresses, any_args)
- .and_raise(SocketError, 'getaddrinfo: Name or service not known')
+ allow(Addrinfo).to receive(:getaddrinfo).with(/\Afoobar\.\w|(\d{1,3}\.){4,}\d{1,3}\z/i, anything, nil, :STREAM) do
+ raise SocketError.new("getaddrinfo: Name or service not known")
+ end
end
def permit_local_dns!
- local_addresses = %r{
- \A
- (?:
- (?:127|10)\.0\.0\.\d{1,3} |
- (?:192\.168|172\.16)\.\d{1,3}\.\d{1,3} |
- 0\.0\.0\.0 |
- localhost
- )
- \z
- }ix
-
- allow(Addrinfo).to receive(:getaddrinfo)
- .with(local_addresses, any_args)
- .and_call_original
+ local_addresses = /\A(127|10)\.0\.0\.\d{1,3}|(192\.168|172\.16)\.\d{1,3}\.\d{1,3}|0\.0\.0\.0|localhost\z/i
+ allow(Addrinfo).to receive(:getaddrinfo).with(local_addresses, anything, nil, :STREAM).and_call_original
+ allow(Addrinfo).to receive(:getaddrinfo).with(local_addresses, anything, nil, :STREAM, anything, anything, any_args).and_call_original
end
end
diff --git a/spec/support/helpers/stub_requests.rb b/spec/support/helpers/stub_requests.rb
index 81872b1c908..473f07dd413 100644
--- a/spec/support/helpers/stub_requests.rb
+++ b/spec/support/helpers/stub_requests.rb
@@ -18,13 +18,14 @@ module StubRequests
end
def stub_dns(url, ip_address:, port: 80)
- url = URI(url)
+ url = parse_url(url)
socket = Socket.sockaddr_in(port, ip_address)
addr = Addrinfo.new(socket)
+ # See Gitlab::UrlBlocker
allow(Addrinfo).to receive(:getaddrinfo)
- .with(url.hostname, url.port, any_args)
- .and_return([addr])
+ .with(url.hostname, url.port, nil, :STREAM)
+ .and_return([addr])
end
def stub_all_dns(url, ip_address:)
@@ -33,14 +34,22 @@ module StubRequests
socket = Socket.sockaddr_in(port, ip_address)
addr = Addrinfo.new(socket)
+ # See Gitlab::UrlBlocker
+ allow(Addrinfo).to receive(:getaddrinfo).and_call_original
allow(Addrinfo).to receive(:getaddrinfo)
- .with(url.hostname, any_args)
+ .with(url.hostname, anything, nil, :STREAM)
.and_return([addr])
end
def stubbed_hostname(url, hostname: IP_ADDRESS_STUB)
- url = URI(url)
+ url = parse_url(url)
url.hostname = hostname
url.to_s
end
+
+ private
+
+ def parse_url(url)
+ url.is_a?(URI) ? url : URI(url)
+ end
end
diff --git a/spec/support/shared_examples/finders/packages_shared_examples.rb b/spec/support/shared_examples/finders/packages_shared_examples.rb
index 52976565b21..2d4e8d0df1f 100644
--- a/spec/support/shared_examples/finders/packages_shared_examples.rb
+++ b/spec/support/shared_examples/finders/packages_shared_examples.rb
@@ -17,3 +17,23 @@ RSpec.shared_examples 'concerning versionless param' do
it { is_expected.not_to include(versionless_package) }
end
end
+
+RSpec.shared_examples 'concerning package statuses' do
+ let_it_be(:hidden_package) { create(:maven_package, :hidden, project: project) }
+
+ context 'hidden packages' do
+ it { is_expected.not_to include(hidden_package) }
+ end
+
+ context 'with status param' do
+ let(:params) { { status: :hidden } }
+
+ it { is_expected.to match_array([hidden_package]) }
+ end
+
+ context 'with invalid status param' do
+ let(:params) { { status: 'invalid_status' } }
+
+ it { expect { subject }.to raise_exception(described_class::InvalidStatusError) }
+ end
+end
diff --git a/spec/support/shared_examples/services/packages_shared_examples.rb b/spec/support/shared_examples/services/packages_shared_examples.rb
index ab6cd2109cb..4e34c191306 100644
--- a/spec/support/shared_examples/services/packages_shared_examples.rb
+++ b/spec/support/shared_examples/services/packages_shared_examples.rb
@@ -40,6 +40,19 @@ RSpec.shared_examples 'assigns the package creator' do
end
end
+RSpec.shared_examples 'assigns status to package' do
+ context 'with status param' do
+ let_it_be(:status) { 'hidden' }
+ let(:params) { super().merge(status: status) }
+
+ it 'assigns the status to the package' do
+ package = subject
+
+ expect(package.status).to eq(status)
+ end
+ end
+end
+
RSpec.shared_examples 'returns packages' do |container_type, user_type|
context "for #{user_type}" do
before do
@@ -263,3 +276,41 @@ RSpec.shared_examples 'with versionless packages' do
end
end
end
+
+RSpec.shared_examples 'with status param' do
+ context 'hidden packages' do
+ let!(:hidden_package) { create(:maven_package, :hidden, project: project) }
+
+ shared_examples 'not including the hidden package' do
+ it 'does not return the package' do
+ subject
+
+ expect(json_response.map { |package| package['id'] }).not_to include(hidden_package.id)
+ end
+ end
+
+ context 'no status param' do
+ it_behaves_like 'not including the hidden package'
+ end
+
+ context 'with hidden status param' do
+ let(:params) { super().merge(status: 'hidden') }
+
+ it 'returns the package' do
+ subject
+
+ expect(json_response.map { |package| package['id'] }).to include(hidden_package.id)
+ end
+ end
+ end
+
+ context 'bad status param' do
+ let(:params) { super().merge(status: 'invalid') }
+
+ it 'returns the package' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ end
+ end
+end