Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
fb28ad5316
commit
762918f04a
|
|
@ -3368,7 +3368,6 @@ RSpec/FeatureCategory:
|
|||
- 'spec/lib/gitlab/etag_caching/router/rails_spec.rb'
|
||||
- 'spec/lib/gitlab/etag_caching/router_spec.rb'
|
||||
- 'spec/lib/gitlab/etag_caching/store_spec.rb'
|
||||
- 'spec/lib/gitlab/event_store/event_spec.rb'
|
||||
- 'spec/lib/gitlab/event_store/store_spec.rb'
|
||||
- 'spec/lib/gitlab/exception_log_formatter_spec.rb'
|
||||
- 'spec/lib/gitlab/exceptions_app_spec.rb'
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ module Onboarding
|
|||
def after_sign_up_path
|
||||
if onboarding_status.single_invite?
|
||||
flash[:notice] = helpers.invite_accepted_notice(onboarding_status.last_invited_member)
|
||||
onboarding_status.last_invited_member_source.activity_path
|
||||
polymorphic_path(onboarding_status.last_invited_member_source)
|
||||
else
|
||||
# Invites will come here if there is more than 1.
|
||||
path_for_signed_in_user
|
||||
|
|
@ -17,13 +17,13 @@ module Onboarding
|
|||
end
|
||||
|
||||
def path_for_signed_in_user
|
||||
stored_location_for(:user) || last_member_activity_path
|
||||
stored_location_for(:user) || last_member_source_path
|
||||
end
|
||||
|
||||
def last_member_activity_path
|
||||
def last_member_source_path
|
||||
return dashboard_projects_path unless onboarding_status.last_invited_member_source.present?
|
||||
|
||||
onboarding_status.last_invited_member_source.activity_path
|
||||
polymorphic_path(onboarding_status.last_invited_member_source)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -125,14 +125,14 @@ class InvitesController < ApplicationController
|
|||
name: member.source.full_name,
|
||||
url: project_url(member.source),
|
||||
title: _("project"),
|
||||
path: member.source.activity_path
|
||||
path: project_path(member.source)
|
||||
}
|
||||
when Group
|
||||
{
|
||||
name: member.source.name,
|
||||
url: group_url(member.source),
|
||||
title: _("group"),
|
||||
path: member.source.activity_path
|
||||
path: group_path(member.source)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ class SessionsController < Devise::SessionsController
|
|||
def after_pending_invitations_hook
|
||||
member = resource.members.last
|
||||
|
||||
store_location_for(:user, member.source.activity_path) if member
|
||||
store_location_for(:user, polymorphic_path(member.source)) if member
|
||||
end
|
||||
|
||||
def captcha_enabled?
|
||||
|
|
|
|||
|
|
@ -790,10 +790,6 @@ class Group < Namespace
|
|||
end
|
||||
strong_memoize_attr :has_project_with_service_desk_enabled?
|
||||
|
||||
def activity_path
|
||||
Gitlab::Routing.url_helpers.activity_group_path(self)
|
||||
end
|
||||
|
||||
# rubocop: disable CodeReuse/ServiceClass
|
||||
def open_issues_count(current_user = nil)
|
||||
Groups::OpenIssuesCountService.new(self, current_user).count
|
||||
|
|
|
|||
|
|
@ -2992,10 +2992,6 @@ class Project < ApplicationRecord
|
|||
Projects::GitGarbageCollectWorker
|
||||
end
|
||||
|
||||
def activity_path
|
||||
Gitlab::Routing.url_helpers.activity_project_path(self)
|
||||
end
|
||||
|
||||
def ci_forward_deployment_enabled?
|
||||
return false unless ci_cd_settings
|
||||
|
||||
|
|
|
|||
|
|
@ -27,16 +27,19 @@
|
|||
- docs_link = link_to('', help_page_path('user/group/import/index', anchor: 'migrated-group-items'), target: '_blank', rel: 'noopener noreferrer')
|
||||
= safe_format(s_('GroupsNew|Not all group items are migrated. %{docs_link_start}What items are migrated%{docs_link_end}?'), tag_pair(docs_link, :docs_link_start, :docs_link_end))
|
||||
|
||||
%p.gl-mt-3
|
||||
= s_('GroupsNew|Provide credentials for the source instance to import from. You can provide this instance as a source to move groups in this instance.')
|
||||
.form-group.gl-display-flex.gl-flex-direction-column
|
||||
= f.label :bulk_import_gitlab_url, s_('GroupsNew|GitLab source instance URL'), for: 'import_gitlab_url'
|
||||
%p.gl-mt-5.gl-mb-3
|
||||
- url_link = link_to('', help_page_path('user/group/import/index', anchor: 'connect-the-source-gitlab-instance'), target: '_blank', rel: 'noopener noreferrer')
|
||||
= safe_format(s_('GroupsNew|Provide credentials for the %{url_link_start}source instance%{url_link_end} to import from. You can provide this instance as a source to move groups within this instance.'), tag_pair(url_link, :url_link_start, :url_link_end))
|
||||
.form-group.gl-form-group.gl-display-flex.gl-flex-direction-column
|
||||
= f.label :bulk_import_gitlab_url, s_('GroupsNew|GitLab source instance base URL'), for: 'import_gitlab_url'
|
||||
= f.text_field :bulk_import_gitlab_url, disabled: bulk_imports_disabled, placeholder: 'https://gitlab.example.com', class: 'gl-form-input col-xs-12 col-sm-8',
|
||||
required: true,
|
||||
title: s_('GroupsNew|Enter the URL for the source instance.'),
|
||||
id: 'import_gitlab_url',
|
||||
data: { testid: 'import-gitlab-url' }
|
||||
.form-group.gl-display-flex.gl-flex-direction-column
|
||||
%small.form-text.text-gl-muted
|
||||
= s_('Import|Must only contain the base URL of the source GitLab instance.')
|
||||
.form-group.gl-form-group.gl-display-flex.gl-flex-direction-column
|
||||
= f.label :bulk_import_gitlab_access_token, s_('GroupsNew|Personal access token'), for: 'import_gitlab_token', class: 'col-form-label'
|
||||
.gl-font-weight-normal
|
||||
- pat_link = link_to('', help_page_path('user/profile/personal_access_tokens'), target: '_blank')
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: duo_chat_absolute_doc_links
|
||||
introduced_by_url: 'https://gitlab.com/gitlab-org/gitlab/-/merge_requests/136240'
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/431338
|
||||
milestone: '16.6'
|
||||
type: development
|
||||
group: group::ai framework
|
||||
default_enabled: false
|
||||
|
|
@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/415755
|
|||
milestone: '16.2'
|
||||
type: development
|
||||
group: group::source code
|
||||
default_enabled: false
|
||||
default_enabled: true
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddUniqueIdPartitionIdIndexToCiJobArtifact < Gitlab::Database::Migration[2.2]
|
||||
milestone '16.7'
|
||||
TABLE_NAME = :ci_job_artifacts
|
||||
INDEX_NAME = :index_ci_job_artifacts_on_id_partition_id_unique
|
||||
COLUMNS = %i[id partition_id]
|
||||
|
||||
def up
|
||||
prepare_async_index(TABLE_NAME, COLUMNS, unique: true, name: INDEX_NAME)
|
||||
end
|
||||
|
||||
def down
|
||||
unprepare_async_index(TABLE_NAME, COLUMNS, name: INDEX_NAME)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddUniqueJobIdFilteTypePartitionIdIndexToCiJobArtifact < Gitlab::Database::Migration[2.2]
|
||||
milestone '16.7'
|
||||
|
||||
TABLE_NAME = :ci_job_artifacts
|
||||
INDEX_NAME = :idx_ci_job_artifacts_on_job_id_file_type_and_partition_id_uniq
|
||||
COLUMNS = %i[job_id file_type partition_id]
|
||||
|
||||
def up
|
||||
prepare_async_index(TABLE_NAME, COLUMNS, unique: true, name: INDEX_NAME)
|
||||
end
|
||||
|
||||
def down
|
||||
unprepare_async_index(TABLE_NAME, COLUMNS, name: INDEX_NAME)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddAsyncIndexesWithPartitionIdForCiPipelineVariables < Gitlab::Database::Migration[2.2]
|
||||
milestone '16.7'
|
||||
|
||||
TABLE_NAME = :ci_pipeline_variables
|
||||
PK_INDEX_NAME = :index_ci_pipeline_variables_on_id_partition_id_unique
|
||||
UNIQUE_INDEX_NAME = :index_pipeline_variables_on_pipeline_id_key_partition_id_unique
|
||||
|
||||
def up
|
||||
prepare_async_index TABLE_NAME, %i[id partition_id], name: PK_INDEX_NAME, unique: true
|
||||
prepare_async_index TABLE_NAME, %i[pipeline_id key partition_id], name: UNIQUE_INDEX_NAME, unique: true
|
||||
end
|
||||
|
||||
def down
|
||||
unprepare_async_index TABLE_NAME, %i[id partition_id], name: PK_INDEX_NAME, unique: true
|
||||
unprepare_async_index TABLE_NAME, %i[pipeline_id key partition_id], name: UNIQUE_INDEX_NAME, unique: true
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
9cfcd48c86956f9f1a0429ab4a2b9f772b7cd6f2e7ac325bb8b1acbbe6ba4ed6
|
||||
|
|
@ -0,0 +1 @@
|
|||
856be6ee89a0e0c4042539ffff10aa410dbfb59bff43527482af5817a20e20cc
|
||||
|
|
@ -0,0 +1 @@
|
|||
a076623d4d7c2f475f1c712802288ef8bdd0c830798dd27d7397da63065b6639
|
||||
|
|
@ -157,7 +157,7 @@ For the storage-specific form,
|
|||
because it does not require a shared folder.
|
||||
|
||||
For configuring object storage in GitLab 13.1 and earlier, _or_ for storage types not
|
||||
For storage types not supported by the consolidated form, refer to the following guides:
|
||||
supported by the consolidated form, refer to the following guides:
|
||||
|
||||
| Object storage type | Supported by consolidated form? |
|
||||
|---------------------|------------------------------------------|
|
||||
|
|
|
|||
|
|
@ -72,6 +72,23 @@ four standard [pagination arguments](#connection-pagination-arguments):
|
|||
| ---- | ---- | ----------- |
|
||||
| <a id="queryabusereportlabelssearchterm"></a>`searchTerm` | [`String`](#string) | Search term to find labels with. |
|
||||
|
||||
### `Query.addOnPurchase`
|
||||
|
||||
Retrieve the active add-on purchase. This query can be used in GitLab SaaS and self-managed environments.
|
||||
|
||||
WARNING:
|
||||
**Introduced** in 16.7.
|
||||
This feature is an Experiment. It can be changed or removed at any time.
|
||||
|
||||
Returns [`AddOnPurchase`](#addonpurchase).
|
||||
|
||||
#### Arguments
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="queryaddonpurchaseaddontype"></a>`addOnType` | [`GitlabSubscriptionsAddOnType!`](#gitlabsubscriptionsaddontype) | Type of add-on for the add-on purchase. |
|
||||
| <a id="queryaddonpurchasenamespaceid"></a>`namespaceId` | [`NamespaceID`](#namespaceid) | ID of namespace that the add-on was purchased for. |
|
||||
|
||||
### `Query.aiMessages`
|
||||
|
||||
Find GitLab Duo Chat messages.
|
||||
|
|
|
|||
|
|
@ -36,11 +36,11 @@ GitLab SaaS provides a set of VM images for macOS.
|
|||
You can execute your build in one of the following images, which you specify
|
||||
in your `.gitlab-ci.yml` file. Each image runs a specific version of macOS and Xcode.
|
||||
|
||||
| VM image | Status |
|
||||
|----------------------------|--------|
|
||||
| `macos-12-xcode-14` | `GA` |
|
||||
| `macos-13-xcode-14` | `GA` |
|
||||
| `macos-14-xcode-15` | `Beta` |
|
||||
| VM image | Status | |
|
||||
|----------------------------|--------|--------------|
|
||||
| `macos-12-xcode-14` | `GA` | |
|
||||
| `macos-13-xcode-14` | `GA` | [Preinstalled Software](https://gitlab.com/gitlab-org/ci-cd/shared-runners/images/job-images/-/blob/main/toolchain/macos-13.yml) |
|
||||
| `macos-14-xcode-15` | `Beta` | [Preinstalled Software](https://gitlab.com/gitlab-org/ci-cd/shared-runners/images/job-images/-/blob/main/toolchain/macos-14.yml) |
|
||||
|
||||
If no image is specified, the macOS runner uses `macos-13-xcode-14`.
|
||||
|
||||
|
|
@ -48,7 +48,7 @@ If no image is specified, the macOS runner uses `macos-13-xcode-14`.
|
|||
|
||||
macOS and Xcode follow a yearly release cadence, during which GitLab increments its versions synchronously. GitLab typically supports multiple versions of preinstalled tools. For more information, see the [full list of preinstalled software](https://gitlab.com/gitlab-org/ci-cd/shared-runners/images/job-images/-/tree/main/toolchain).
|
||||
|
||||
When Apple releases a new macOS version, GitLab releases a new `stable` image based on the OS in the next release,
|
||||
When Apple releases a new macOS version, GitLab releases a new `stable` image based on the OS in the next release,
|
||||
which is in Beta.
|
||||
|
||||
With the release of the first patch to macOS, the `stable` image becomes Generally Available (GA). As only two GA images are supported at a time, the prior OS version becomes deprecated and is deleted after three months in accordance with the [supported image lifecycle](../index.md#supported-image-lifecycle).
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ In addition to recording to the database, we also write these events to
|
|||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/367847) in GitLab 15.4.
|
||||
|
||||
All new audit events must have a type definition stored in `config/audit_events/types/` that contains a single source of truth for every auditable event in GitLab.
|
||||
All new audit events must have a type definition stored in `config/audit_events/types/` or `ee/config/audit_events/types/` that contains a single source of truth for every auditable event in GitLab.
|
||||
|
||||
### Add a new audit event type
|
||||
|
||||
|
|
|
|||
|
|
@ -182,6 +182,7 @@ security dashboard.
|
|||
|
||||
To add a new ability to a custom role:
|
||||
|
||||
- Generate YAML file by running `./ee/bin/custom-ability` generator
|
||||
- Add a new column to `member_roles` table, for example in [this change in merge request 114734](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/114734/diffs#diff-content-5c53d6f1c29a272a87eecea3f62d017ab6635275).
|
||||
- Add the ability to the `MemberRole` model, `ALL_CUSTOMIZABLE_PERMISSIONS` hash, for example in [this change in merge request 121534](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/121534/diffs#ce5ec769500a53ce2b603467d9984fc2b33ca71d_8_8). There are following possible keys in the `ALL_CUSTOMIZABLE_PERMISSIONS` hash:
|
||||
|
||||
|
|
@ -200,6 +201,33 @@ Examples of merge requests adding new abilities to custom roles:
|
|||
|
||||
You should make sure a new custom roles ability is under a feature flag.
|
||||
|
||||
## Custom abilities definition
|
||||
|
||||
All new custom abilities must have a type definition stored in `ee/config/custom_abilities` that contains a single source of truth for every ability that is part of custom roles feature.
|
||||
|
||||
### Add a new custom ability definition
|
||||
|
||||
To add a new custom ability:
|
||||
|
||||
1. Create the YAML definition. You can either:
|
||||
- Use the `ee/bin/custom-ability` CLI to create the YAML definition automatically.
|
||||
- Perform manual steps to create a new file in `ee/config/custom_abilities/` with the filename matching the name of the ability name.
|
||||
1. Add contents to the file that conform to the [schema](#schema) defined in `ee/config/custom_abilities/types/type_schema.json`.
|
||||
|
||||
### Schema
|
||||
|
||||
| Field | Required | Description |
|
||||
| ----- | -------- |--------------|
|
||||
| `name` | yes | Unique, lowercase and underscored name describing the custom ability. Must match the filename. |
|
||||
| `description` | yes | Human-readable description of the custom ability. |
|
||||
| `feature_category` | yes | Name of the feature category. For example, `vulnerability_management`. |
|
||||
| `introduced_by_issue` | yes | Issue URL that proposed the addition of this custom ability. |
|
||||
| `introduced_by_mr` | yes | MR URL that added this custom ability. |
|
||||
| `milestone` | yes | Milestone in which this custom ability was added. |
|
||||
| `group_ability` | yes | Indicate whether this ability is checked on group level. |
|
||||
| `project_ability` | yes | Indicate whether this ability is checked on project level. |
|
||||
| `skip_seat_consumption` | yes | Indicate wheter this ability should be skiped when counting licensed users. |
|
||||
|
||||
### Privilege escalation consideration
|
||||
|
||||
A base role typically has permissions that allow creation or management of artifacts corresponding to the base role when interacting with that artifact. For example, when a `Developer` creates an access token for a project, it is created with `Developer` access encoded into that credential. It is important to keep in mind that as new custom permissions are created, there might be a risk of elevated privileges when interacting with GitLab artifacts, and appropriate safeguards or base role checks should be added.
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ Create the group you want to import to and connect the source GitLab instance:
|
|||
- A new subgroup. On existing group's page, either:
|
||||
- Select **New subgroup**.
|
||||
- On the left sidebar, at the top, select **Create new** (**{plus}**) and **New subgroup**. Then select the **import an existing group** link.
|
||||
1. Enter the URL of a GitLab instance running GitLab 14.0 or later.
|
||||
1. Enter the base URL of a GitLab instance running GitLab 14.0 or later.
|
||||
1. Enter the [personal access token](../../../user/profile/personal_access_tokens.md) for your source GitLab instance.
|
||||
1. Select **Connect instance**.
|
||||
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ module BulkImports
|
|||
|
||||
return true if response['scopes']&.include?('api')
|
||||
|
||||
raise ::BulkImports::Error.scope_validation_failure
|
||||
raise ::BulkImports::Error.scope_or_url_validation_failure
|
||||
end
|
||||
|
||||
def validate_instance_version!
|
||||
|
|
@ -110,7 +110,7 @@ module BulkImports
|
|||
rescue BulkImports::NetworkError => e
|
||||
case e&.response&.code
|
||||
when 401, 403
|
||||
raise ::BulkImports::Error.scope_validation_failure
|
||||
raise ::BulkImports::Error.scope_or_url_validation_failure
|
||||
when 404
|
||||
raise ::BulkImports::Error.invalid_url
|
||||
else
|
||||
|
|
|
|||
|
|
@ -3,35 +3,37 @@
|
|||
module BulkImports
|
||||
class Error < StandardError
|
||||
def self.unsupported_gitlab_version
|
||||
self.new("Unsupported GitLab version. Minimum supported version is #{BulkImport::MIN_MAJOR_VERSION}.")
|
||||
self.new(format(s_("BulkImport|Unsupported GitLab version. Minimum supported version is '%{version}'."),
|
||||
version: BulkImport::MIN_MAJOR_VERSION))
|
||||
end
|
||||
|
||||
def self.scope_validation_failure
|
||||
self.new("Personal access token does not have the required " \
|
||||
"'api' scope or is no longer valid.")
|
||||
def self.scope_or_url_validation_failure
|
||||
self.new(s_("BulkImport|Check that the source instance base URL and the personal access " \
|
||||
"token meet the necessary requirements."))
|
||||
end
|
||||
|
||||
def self.invalid_url
|
||||
self.new("Invalid source URL. Enter only the base URL of the source GitLab instance.")
|
||||
self.new(s_("BulkImport|Invalid source URL. Enter only the base URL of the source GitLab instance."))
|
||||
end
|
||||
|
||||
def self.destination_namespace_validation_failure(destination_namespace)
|
||||
self.new("Import failed. Destination '#{destination_namespace}' is invalid, or you don't have permission.")
|
||||
self.new(format(s_("BulkImport|Import failed. Destination '%{destination}' is invalid, " \
|
||||
"or you don't have permission."), destination: destination_namespace))
|
||||
end
|
||||
|
||||
def self.destination_slug_validation_failure
|
||||
self.new("Import failed. Destination URL " \
|
||||
"#{Gitlab::Regex.oci_repository_path_regex_message}")
|
||||
self.new(format(s_("BulkImport|Import failed. Destination URL %{url}"),
|
||||
url: Gitlab::Regex.oci_repository_path_regex_message))
|
||||
end
|
||||
|
||||
def self.destination_full_path_validation_failure(full_path)
|
||||
self.new("Import failed. '#{full_path}' already exists. Change the destination and try again.")
|
||||
self.new(format(s_("BulkImport|Import failed. '%{path}' already exists. Change the destination and try again."),
|
||||
path: full_path))
|
||||
end
|
||||
|
||||
def self.setting_not_enabled
|
||||
self.new("Group import disabled on source or destination instance. " \
|
||||
"Ask an administrator to enable it on both instances and try again."
|
||||
)
|
||||
self.new(s_("BulkImport|Group import disabled on source or destination instance. " \
|
||||
"Ask an administrator to enable it on both instances and try again."))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -29,8 +29,13 @@ module Gitlab
|
|||
class Event
|
||||
attr_reader :data
|
||||
|
||||
class << self
|
||||
attr_accessor :json_schema_valid
|
||||
end
|
||||
|
||||
def initialize(data:)
|
||||
validate_schema!(data)
|
||||
validate_schema!
|
||||
validate_data!(data)
|
||||
@data = data
|
||||
end
|
||||
|
||||
|
|
@ -40,7 +45,17 @@ module Gitlab
|
|||
|
||||
private
|
||||
|
||||
def validate_schema!(data)
|
||||
def validate_schema!
|
||||
if self.class.json_schema_valid.nil?
|
||||
self.class.json_schema_valid = JSONSchemer.schema(self.class.json_schema).valid?(schema)
|
||||
end
|
||||
|
||||
return if self.class.json_schema_valid == true
|
||||
|
||||
raise Gitlab::EventStore::InvalidEvent, "Schema for event #{self.class} is invalid"
|
||||
end
|
||||
|
||||
def validate_data!(data)
|
||||
unless data.is_a?(Hash)
|
||||
raise Gitlab::EventStore::InvalidEvent, "Event data must be a Hash"
|
||||
end
|
||||
|
|
@ -49,6 +64,10 @@ module Gitlab
|
|||
raise Gitlab::EventStore::InvalidEvent, "Data for event #{self.class} does not match the defined schema: #{schema}"
|
||||
end
|
||||
end
|
||||
|
||||
def self.json_schema
|
||||
@json_schema ||= Gitlab::Json.parse(File.read(File.join(__dir__, 'json_schema_draft07.json')))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,250 @@
|
|||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"$id": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "Core schema meta-schema",
|
||||
"definitions": {
|
||||
"schemaArray": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"$ref": "#"
|
||||
}
|
||||
},
|
||||
"nonNegativeInteger": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"nonNegativeIntegerDefault0": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/nonNegativeInteger"
|
||||
},
|
||||
{
|
||||
"default": 0
|
||||
}
|
||||
]
|
||||
},
|
||||
"simpleTypes": {
|
||||
"enum": [
|
||||
"array",
|
||||
"boolean",
|
||||
"integer",
|
||||
"null",
|
||||
"number",
|
||||
"object",
|
||||
"string"
|
||||
]
|
||||
},
|
||||
"stringArray": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"uniqueItems": true,
|
||||
"default": [
|
||||
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": [
|
||||
"object",
|
||||
"boolean"
|
||||
],
|
||||
"properties": {
|
||||
"$id": {
|
||||
"type": "string",
|
||||
"format": "uri-reference"
|
||||
},
|
||||
"$schema": {
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
"$ref": {
|
||||
"type": "string",
|
||||
"format": "uri-reference"
|
||||
},
|
||||
"$comment": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"default": true,
|
||||
"readOnly": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"writeOnly": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"examples": {
|
||||
"type": "array",
|
||||
"items": true
|
||||
},
|
||||
"multipleOf": {
|
||||
"type": "number",
|
||||
"exclusiveMinimum": 0
|
||||
},
|
||||
"maximum": {
|
||||
"type": "number"
|
||||
},
|
||||
"exclusiveMaximum": {
|
||||
"type": "number"
|
||||
},
|
||||
"minimum": {
|
||||
"type": "number"
|
||||
},
|
||||
"exclusiveMinimum": {
|
||||
"type": "number"
|
||||
},
|
||||
"maxLength": {
|
||||
"$ref": "#/definitions/nonNegativeInteger"
|
||||
},
|
||||
"minLength": {
|
||||
"$ref": "#/definitions/nonNegativeIntegerDefault0"
|
||||
},
|
||||
"pattern": {
|
||||
"type": "string",
|
||||
"format": "regex"
|
||||
},
|
||||
"additionalItems": {
|
||||
"$ref": "#"
|
||||
},
|
||||
"items": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/schemaArray"
|
||||
}
|
||||
],
|
||||
"default": true
|
||||
},
|
||||
"maxItems": {
|
||||
"$ref": "#/definitions/nonNegativeInteger"
|
||||
},
|
||||
"minItems": {
|
||||
"$ref": "#/definitions/nonNegativeIntegerDefault0"
|
||||
},
|
||||
"uniqueItems": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"contains": {
|
||||
"$ref": "#"
|
||||
},
|
||||
"maxProperties": {
|
||||
"$ref": "#/definitions/nonNegativeInteger"
|
||||
},
|
||||
"minProperties": {
|
||||
"$ref": "#/definitions/nonNegativeIntegerDefault0"
|
||||
},
|
||||
"required": {
|
||||
"$ref": "#/definitions/stringArray"
|
||||
},
|
||||
"additionalProperties": {
|
||||
"$ref": "#"
|
||||
},
|
||||
"definitions": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#"
|
||||
},
|
||||
"default": {
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#"
|
||||
},
|
||||
"default": {
|
||||
}
|
||||
},
|
||||
"patternProperties": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#"
|
||||
},
|
||||
"propertyNames": {
|
||||
"format": "regex"
|
||||
},
|
||||
"default": {
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/stringArray"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"propertyNames": {
|
||||
"$ref": "#"
|
||||
},
|
||||
"const": true,
|
||||
"enum": {
|
||||
"type": "array",
|
||||
"items": true,
|
||||
"minItems": 1,
|
||||
"uniqueItems": true
|
||||
},
|
||||
"type": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/simpleTypes"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/simpleTypes"
|
||||
},
|
||||
"minItems": 1,
|
||||
"uniqueItems": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"format": {
|
||||
"type": "string"
|
||||
},
|
||||
"contentMediaType": {
|
||||
"type": "string"
|
||||
},
|
||||
"contentEncoding": {
|
||||
"type": "string"
|
||||
},
|
||||
"if": {
|
||||
"$ref": "#"
|
||||
},
|
||||
"then": {
|
||||
"$ref": "#"
|
||||
},
|
||||
"else": {
|
||||
"$ref": "#"
|
||||
},
|
||||
"allOf": {
|
||||
"$ref": "#/definitions/schemaArray"
|
||||
},
|
||||
"anyOf": {
|
||||
"$ref": "#/definitions/schemaArray"
|
||||
},
|
||||
"oneOf": {
|
||||
"$ref": "#/definitions/schemaArray"
|
||||
},
|
||||
"not": {
|
||||
"$ref": "#"
|
||||
}
|
||||
},
|
||||
"default": true
|
||||
}
|
||||
|
|
@ -9020,6 +9020,9 @@ msgstr ""
|
|||
msgid "BulkImport|Be aware of %{linkStart}visibility rules%{linkEnd} when importing groups."
|
||||
msgstr ""
|
||||
|
||||
msgid "BulkImport|Check that the source instance base URL and the personal access token meet the necessary requirements."
|
||||
msgstr ""
|
||||
|
||||
msgid "BulkImport|Destination"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -9035,9 +9038,21 @@ msgstr ""
|
|||
msgid "BulkImport|GitLab Migration history"
|
||||
msgstr ""
|
||||
|
||||
msgid "BulkImport|Group import disabled on source or destination instance. Ask an administrator to enable it on both instances and try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "BulkImport|History"
|
||||
msgstr ""
|
||||
|
||||
msgid "BulkImport|Import failed. '%{path}' already exists. Change the destination and try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "BulkImport|Import failed. Destination '%{destination}' is invalid, or you don't have permission."
|
||||
msgstr ""
|
||||
|
||||
msgid "BulkImport|Import failed. Destination URL %{url}"
|
||||
msgstr ""
|
||||
|
||||
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -9059,6 +9074,9 @@ msgstr ""
|
|||
msgid "BulkImport|Importing the group failed."
|
||||
msgstr ""
|
||||
|
||||
msgid "BulkImport|Invalid source URL. Enter only the base URL of the source GitLab instance."
|
||||
msgstr ""
|
||||
|
||||
msgid "BulkImport|Last imported to %{link}"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -9116,6 +9134,9 @@ msgstr ""
|
|||
msgid "BulkImport|Template / File-based import / GitLab Migration"
|
||||
msgstr ""
|
||||
|
||||
msgid "BulkImport|Unsupported GitLab version. Minimum supported version is '%{version}'."
|
||||
msgstr ""
|
||||
|
||||
msgid "BulkImport|Update of import statuses with realtime changes failed"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -23555,7 +23576,7 @@ msgstr ""
|
|||
msgid "GroupsNew|Enter the URL for the source instance."
|
||||
msgstr ""
|
||||
|
||||
msgid "GroupsNew|GitLab source instance URL"
|
||||
msgid "GroupsNew|GitLab source instance base URL"
|
||||
msgstr ""
|
||||
|
||||
msgid "GroupsNew|Groups"
|
||||
|
|
@ -23597,7 +23618,7 @@ msgstr ""
|
|||
msgid "GroupsNew|Please fill in your personal access token."
|
||||
msgstr ""
|
||||
|
||||
msgid "GroupsNew|Provide credentials for the source instance to import from. You can provide this instance as a source to move groups in this instance."
|
||||
msgid "GroupsNew|Provide credentials for the %{url_link_start}source instance%{url_link_end} to import from. You can provide this instance as a source to move groups within this instance."
|
||||
msgstr ""
|
||||
|
||||
msgid "GroupsNew|Remember to enable it also on the instance you are migrating from."
|
||||
|
|
@ -24901,6 +24922,9 @@ msgstr ""
|
|||
msgid "Import|Maximum size of decompressed archive."
|
||||
msgstr ""
|
||||
|
||||
msgid "Import|Must only contain the base URL of the source GitLab instance."
|
||||
msgstr ""
|
||||
|
||||
msgid "Import|No import details"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -56317,6 +56341,9 @@ msgstr ""
|
|||
msgid "Your public email will be displayed on your public profile."
|
||||
msgstr ""
|
||||
|
||||
msgid "Your push to this repository has been rejected because it would exceed the namespace storage limit of %{size_limit}. Reduce your namespace storage or purchase additional storage.To manage storage, or purchase additional storage, see %{manage_storage_url}. To learn more about restricted actions, see %{restricted_actions_url}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Your request for access could not be processed: %{error_message}"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ RSpec.describe 'Import/Export - Connect to another instance', :js, feature_categ
|
|||
end
|
||||
|
||||
it 'renders fields and button disabled' do
|
||||
expect(page).to have_field('GitLab source instance URL', disabled: true)
|
||||
expect(page).to have_field('GitLab source instance base URL', disabled: true)
|
||||
expect(page).to have_field('Personal access token', disabled: true)
|
||||
expect(page).to have_button('Connect instance', disabled: true)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ require 'spec_helper'
|
|||
|
||||
RSpec.describe 'Group or Project invitations', :aggregate_failures, feature_category: :acquisition do
|
||||
let_it_be(:owner) { create(:user, name: 'John Doe') }
|
||||
# private will ensure we really have access to the group when we land on the activity page
|
||||
# private will ensure we really have access to the group when we land on the group page
|
||||
let_it_be(:group) { create(:group, :private, name: 'Owned') }
|
||||
let_it_be(:project) { create(:project, :repository, namespace: group) }
|
||||
|
||||
|
|
@ -60,12 +60,12 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures, feature_cate
|
|||
visit invite_path(group_invite.raw_invite_token, invite_type: Emails::Members::INITIAL_INVITE)
|
||||
end
|
||||
|
||||
it 'sign in, grants access and redirects to group activity page' do
|
||||
it 'sign in, grants access and redirects to group page' do
|
||||
click_link 'Sign in'
|
||||
|
||||
gitlab_sign_in(user, remember: true, visit: false)
|
||||
|
||||
expect_to_be_on_group_activity_page(group)
|
||||
expect_to_be_on_group_page(group)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -126,8 +126,8 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures, feature_cate
|
|||
end
|
||||
end
|
||||
|
||||
def expect_to_be_on_group_activity_page(group)
|
||||
expect(page).to have_current_path(activity_group_path(group))
|
||||
def expect_to_be_on_group_page(group)
|
||||
expect(page).to have_current_path(group_path(group))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -169,10 +169,10 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures, feature_cate
|
|||
end
|
||||
|
||||
context 'when the user signs up for an account with the invitation email address' do
|
||||
it 'redirects to the most recent membership activity page with all invitations automatically accepted' do
|
||||
it 'redirects to the most recent membership group page with all invitations automatically accepted' do
|
||||
fill_in_sign_up_form(new_user)
|
||||
|
||||
expect(page).to have_current_path(activity_group_path(group), ignore_query: true)
|
||||
expect(page).to have_current_path(group_path(group), ignore_query: true)
|
||||
expect(page).to have_content('You have been granted Owner access to group Owned.')
|
||||
end
|
||||
end
|
||||
|
|
@ -215,10 +215,10 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures, feature_cate
|
|||
end
|
||||
|
||||
context 'when the user signs up for an account with the invitation email address' do
|
||||
it 'redirects to the most recent membership activity page with all invitations automatically accepted' do
|
||||
it 'redirects to the most recent membership group page with all invitations automatically accepted' do
|
||||
fill_in_sign_up_form(new_user)
|
||||
|
||||
expect(page).to have_current_path(activity_group_path(group), ignore_query: true)
|
||||
expect(page).to have_current_path(group_path(group), ignore_query: true)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -271,7 +271,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures, feature_cate
|
|||
|
||||
fill_in_sign_up_form(new_user, 'Register')
|
||||
|
||||
expect(page).to have_current_path(activity_group_path(group))
|
||||
expect(page).to have_current_path(group_path(group))
|
||||
expect(page).to have_content('You have been granted Owner access to group Owned.')
|
||||
end
|
||||
end
|
||||
|
|
@ -295,16 +295,16 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures, feature_cate
|
|||
gitlab_sign_in(user)
|
||||
end
|
||||
|
||||
it 'does not accept the pending invitation and does not redirect to the groups activity path' do
|
||||
expect(page).not_to have_current_path(activity_group_path(group), ignore_query: true)
|
||||
it 'does not accept the pending invitation and does not redirect to the group path' do
|
||||
expect(page).not_to have_current_path(group_path(group), ignore_query: true)
|
||||
expect(group.reload.users).not_to include(user)
|
||||
end
|
||||
|
||||
context 'when the secondary email address is confirmed' do
|
||||
let(:secondary_email) { create(:email, :confirmed, user: user) }
|
||||
|
||||
it 'accepts the pending invitation and redirects to the groups activity path' do
|
||||
expect(page).to have_current_path(activity_group_path(group), ignore_query: true)
|
||||
it 'accepts the pending invitation and redirects to the group path' do
|
||||
expect(page).to have_current_path(group_path(group), ignore_query: true)
|
||||
expect(group.reload.users).to include(user)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -105,12 +105,12 @@ RSpec.describe 'OAuth Registration', :js, :allow_forgery_protection, feature_cat
|
|||
mock_auth_hash(provider, uid, invite_email, additional_info: additional_info)
|
||||
end
|
||||
|
||||
it 'redirects to the activity page with all the projects/groups invitations accepted' do
|
||||
it 'redirects to the group page with all the projects/groups invitations accepted' do
|
||||
visit invite_path(group_invite.raw_invite_token, extra_params)
|
||||
click_link_or_button "oauth-login-#{provider}"
|
||||
|
||||
expect(page).to have_content('You have been granted Owner access to group Owned.')
|
||||
expect(page).to have_current_path(activity_group_path(group), ignore_query: true)
|
||||
expect(page).to have_current_path(group_path(group), ignore_query: true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -250,9 +250,9 @@ RSpec.describe BulkImports::Clients::HTTP, feature_category: :importers do
|
|||
stub_request(:get, 'http://gitlab.example/api/v4/metadata?private_token=token')
|
||||
.to_return(status: 401, body: "", headers: { 'Content-Type' => 'application/json' })
|
||||
|
||||
expect { subject.instance_version }.to raise_exception(BulkImports::Error,
|
||||
"Personal access token does not have the required 'api' scope or " \
|
||||
"is no longer valid.")
|
||||
expect { subject.instance_version }
|
||||
.to raise_exception(BulkImports::Error,
|
||||
"Check that the source instance base URL and the personal access token meet the necessary requirements.")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -262,9 +262,9 @@ RSpec.describe BulkImports::Clients::HTTP, feature_category: :importers do
|
|||
stub_request(:get, 'http://gitlab.example/api/v4/metadata?private_token=token')
|
||||
.to_return(status: 403, body: "", headers: { 'Content-Type' => 'application/json' })
|
||||
|
||||
expect { subject.instance_version }.to raise_exception(BulkImports::Error,
|
||||
"Personal access token does not have the required 'api' scope or " \
|
||||
"is no longer valid.")
|
||||
expect { subject.instance_version }
|
||||
.to raise_exception(BulkImports::Error,
|
||||
"Check that the source instance base URL and the personal access token meet the necessary requirements.")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
require 'fast_spec_helper'
|
||||
require 'json_schemer'
|
||||
require 'oj'
|
||||
|
||||
RSpec.describe Gitlab::EventStore::Event do
|
||||
RSpec.describe Gitlab::EventStore::Event, feature_category: :shared do
|
||||
let(:event_class) { stub_const('TestEvent', Class.new(described_class)) }
|
||||
let(:event) { event_class.new(data: data) }
|
||||
let(:data) { { project_id: 123, project_path: 'org/the-project' } }
|
||||
|
|
@ -42,6 +44,14 @@ RSpec.describe Gitlab::EventStore::Event do
|
|||
it 'initializes the event correctly' do
|
||||
expect(event.data).to eq(data)
|
||||
end
|
||||
|
||||
it 'validates schema' do
|
||||
expect(event_class.json_schema_valid).to eq(nil)
|
||||
|
||||
event
|
||||
|
||||
expect(event_class.json_schema_valid).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when some properties are missing' do
|
||||
|
|
@ -59,6 +69,31 @@ RSpec.describe Gitlab::EventStore::Event do
|
|||
expect { event }.to raise_error(Gitlab::EventStore::InvalidEvent, 'Event data must be a Hash')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when schema is invalid' do
|
||||
before do
|
||||
event_class.class_eval do
|
||||
def schema
|
||||
{
|
||||
'required' => ['project_id'],
|
||||
'type' => 'object',
|
||||
'properties' => {
|
||||
'project_id' => { 'type' => 'int' },
|
||||
'project_path' => { 'type' => 'string ' }
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'raises an error' do
|
||||
expect(event_class.json_schema_valid).to eq(nil)
|
||||
|
||||
expect { event }.to raise_error(Gitlab::EventStore::InvalidEvent, 'Schema for event TestEvent is invalid')
|
||||
|
||||
expect(event_class.json_schema_valid).to eq(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3014,14 +3014,6 @@ RSpec.describe Group, feature_category: :groups_and_projects do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#activity_path' do
|
||||
it 'returns the group activity_path' do
|
||||
expected_path = "/groups/#{group.name}/-/activity"
|
||||
|
||||
expect(group.activity_path).to eq(expected_path)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with export' do
|
||||
let(:group) { create(:group, :with_export) }
|
||||
|
||||
|
|
|
|||
|
|
@ -7955,14 +7955,6 @@ RSpec.describe Project, factory_default: :keep, feature_category: :groups_and_pr
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#activity_path' do
|
||||
it 'returns the project activity_path' do
|
||||
expected_path = "/#{project.full_path}/activity"
|
||||
|
||||
expect(project.activity_path).to eq(expected_path)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#default_branch_or_main' do
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ RSpec.describe 'Sessions', feature_category: :system_access do
|
|||
|
||||
post user_session_path(user: { login: user.username, password: user.password })
|
||||
|
||||
expect(response).to redirect_to(activity_group_path(member.source))
|
||||
expect(response).to redirect_to(group_path(member.source))
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -123,7 +123,8 @@ RSpec.describe BulkImports::CreateService, feature_category: :importers do
|
|||
)
|
||||
|
||||
allow_next_instance_of(BulkImports::Clients::HTTP) do |client|
|
||||
allow(client).to receive(:validate_import_scopes!).and_raise(BulkImports::Error.scope_validation_failure)
|
||||
allow(client).to receive(:validate_import_scopes!)
|
||||
.and_raise(BulkImports::Error.scope_or_url_validation_failure)
|
||||
end
|
||||
|
||||
result = subject.execute
|
||||
|
|
@ -132,8 +133,7 @@ RSpec.describe BulkImports::CreateService, feature_category: :importers do
|
|||
expect(result).to be_error
|
||||
expect(result.message)
|
||||
.to eq(
|
||||
"Personal access token does not " \
|
||||
"have the required 'api' scope or is no longer valid."
|
||||
"Check that the source instance base URL and the personal access token meet the necessary requirements."
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
@ -546,7 +546,8 @@ RSpec.describe BulkImports::CreateService, feature_category: :importers do
|
|||
expect(result).to be_a(ServiceResponse)
|
||||
expect(result).to be_error
|
||||
expect(result.message)
|
||||
.to eq("Import failed. Destination 'destination-namespace' is invalid, or you don't have permission.")
|
||||
.to eq("Import failed. Destination 'destination-namespace' is invalid, " \
|
||||
"or you don't have permission.")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -571,7 +572,8 @@ RSpec.describe BulkImports::CreateService, feature_category: :importers do
|
|||
expect(result).to be_a(ServiceResponse)
|
||||
expect(result).to be_error
|
||||
expect(result.message)
|
||||
.to eq("Import failed. Destination '#{parent_group.path}' is invalid, or you don't have permission.")
|
||||
.to eq("Import failed. Destination '#{parent_group.path}' is invalid, " \
|
||||
"or you don't have permission.")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -596,7 +598,8 @@ RSpec.describe BulkImports::CreateService, feature_category: :importers do
|
|||
expect(result).to be_a(ServiceResponse)
|
||||
expect(result).to be_error
|
||||
expect(result.message)
|
||||
.to eq("Import failed. Destination '#{parent_group.path}' is invalid, or you don't have permission.")
|
||||
.to eq("Import failed. Destination '#{parent_group.path}' is invalid, " \
|
||||
"or you don't have permission.")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ RSpec.describe MergeRequests::CloseService, feature_category: :code_review_workf
|
|||
.with(@merge_request, 'close')
|
||||
end
|
||||
|
||||
it 'sends email to user2 about assign of new merge_request', :sidekiq_might_not_need_inline do
|
||||
it 'sends email to user2 about assign of new merge_request', :sidekiq_inline do
|
||||
email = ActionMailer::Base.deliveries.last
|
||||
expect(email.to.first).to eq(user2.email)
|
||||
expect(email.subject).to include(merge_request.title)
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ RSpec.describe MergeRequests::CreateService, :clean_gitlab_redis_shared_state, f
|
|||
end.to change { project.open_merge_requests_count }.from(0).to(1)
|
||||
end
|
||||
|
||||
it 'creates exactly 1 create MR event', :sidekiq_might_not_need_inline do
|
||||
it 'creates exactly 1 create MR event', :sidekiq_inline do
|
||||
attributes = {
|
||||
action: :created,
|
||||
target_id: merge_request.id,
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ RSpec.describe MergeRequests::ReopenService, feature_category: :code_review_work
|
|||
expect(Integrations::GroupMentionWorker).not_to receive(:perform_async)
|
||||
end
|
||||
|
||||
it 'sends email to user2 about reopen of merge_request', :sidekiq_might_not_need_inline do
|
||||
it 'sends email to user2 about reopen of merge_request', :sidekiq_inline do
|
||||
email = ActionMailer::Base.deliveries.last
|
||||
expect(email.to.first).to eq(user2.email)
|
||||
expect(email.subject).to include(merge_request.title)
|
||||
|
|
|
|||
|
|
@ -6027,7 +6027,6 @@
|
|||
- './spec/lib/gitlab/etag_caching/router/rails_spec.rb'
|
||||
- './spec/lib/gitlab/etag_caching/router_spec.rb'
|
||||
- './spec/lib/gitlab/etag_caching/store_spec.rb'
|
||||
- './spec/lib/gitlab/event_store/event_spec.rb'
|
||||
- './spec/lib/gitlab/event_store/store_spec.rb'
|
||||
- './spec/lib/gitlab/exception_log_formatter_spec.rb'
|
||||
- './spec/lib/gitlab/exceptions_app_spec.rb'
|
||||
|
|
|
|||
|
|
@ -6,20 +6,20 @@ RSpec.shared_examples Onboarding::Redirectable do
|
|||
context 'when the new user already has any accepted group membership' do
|
||||
let!(:single_member) { create(:group_member, invite_email: email) }
|
||||
|
||||
it 'redirects to activity group path with a flash message' do
|
||||
it 'redirects to the group path with a flash message' do
|
||||
post_create
|
||||
|
||||
expect(response).to redirect_to activity_group_path(single_member.source)
|
||||
expect(response).to redirect_to group_path(single_member.source)
|
||||
expect(controller).to set_flash[:notice].to(/You have been granted/)
|
||||
end
|
||||
|
||||
context 'when the new user already has more than 1 accepted group membership' do
|
||||
let!(:last_member) { create(:group_member, invite_email: email) }
|
||||
|
||||
it 'redirects to the last member activity group path without a flash message' do
|
||||
it 'redirects to the last member group path without a flash message' do
|
||||
post_create
|
||||
|
||||
expect(response).to redirect_to activity_group_path(last_member.source)
|
||||
expect(response).to redirect_to group_path(last_member.source)
|
||||
expect(controller).not_to set_flash[:notice].to(/You have been granted/)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in New Issue