Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-05-26 03:09:21 +00:00
parent eb90b0642d
commit 47ef8c6c53
33 changed files with 285 additions and 85 deletions

View File

@ -632,7 +632,7 @@ class Namespace < ApplicationRecord
return
end
if parent.project_namespace?
if parent&.project_namespace?
errors.add(:parent_id, _('project namespace cannot be the parent of another namespace'))
end

View File

@ -2,6 +2,13 @@
module Namespaces
class ProjectNamespace < Namespace
# These aliases are added to make it easier to sync parent/parent_id attribute with
# project.namespace/project.namespace_id attribute.
#
# TODO: we can remove these attribute aliases when we no longer need to sync these with project model,
# see project#sync_attributes
alias_attribute :namespace, :parent
alias_attribute :namespace_id, :parent_id
has_one :project, foreign_key: :project_namespace_id, inverse_of: :project_namespace
def self.sti_name

View File

@ -3104,7 +3104,6 @@ class Project < ApplicationRecord
# create project_namespace when project is created
build_project_namespace if project_namespace_creation_enabled?
# we need to keep project and project namespace in sync if there is one
sync_attributes(project_namespace) if sync_project_namespace?
end
@ -3117,11 +3116,24 @@ class Project < ApplicationRecord
end
def sync_attributes(project_namespace)
project_namespace.name = name
project_namespace.path = path
project_namespace.parent = namespace
project_namespace.shared_runners_enabled = shared_runners_enabled
project_namespace.visibility_level = visibility_level
attributes_to_sync = changes.slice(*%w(name path namespace_id namespace visibility_level shared_runners_enabled))
.transform_values { |val| val[1] }
# if visibility_level is not set explicitly for project, it defaults to 0,
# but for namespace visibility_level defaults to 20,
# so it gets out of sync right away if we do not set it explicitly when creating the project namespace
attributes_to_sync['visibility_level'] ||= visibility_level if new_record?
# when a project is associated with a group while the group is created we need to ensure we associate the new
# group with the project namespace as well.
# E.g.
# project = create(:project) <- project is saved
# create(:group, projects: [project]) <- associate project with a group that is not yet created.
if attributes_to_sync.has_key?('namespace_id') && attributes_to_sync['namespace_id'].blank? && namespace.present?
attributes_to_sync['parent'] = namespace
end
project_namespace.assign_attributes(attributes_to_sync)
end
# SyncEvents are created by PG triggers (with the function `insert_projects_sync_event`)

View File

@ -8,7 +8,11 @@ class ProtectedTag < ApplicationRecord
protected_ref_access_levels :create
def self.protected?(project, ref_name)
refs = project.protected_tags.select(:name)
return false if ref_name.blank?
refs = Gitlab::SafeRequestStore.fetch("protected-tag:#{project.cache_key}:refs") do
project.protected_tags.select(:name)
end
self.matching(ref_name, protected_refs: refs).present?
end

View File

@ -3,6 +3,10 @@
class LinkedIssueEntity < Grape::Entity
include RequestAwareEntity
format_with(:upcase) do |item|
item.try(:upcase)
end
expose :id, :confidential, :title
expose :assignees, using: UserEntity
@ -21,6 +25,11 @@ class LinkedIssueEntity < Grape::Entity
Gitlab::UrlBuilder.build(link, only_path: true)
end
expose :issue_type,
as: :type,
format_with: :upcase,
documentation: { type: "String", desc: "One of #{::WorkItems::Type.base_types.keys.map(&:upcase)}" }
expose :relation_path
expose :due_date, :created_at, :closed_at

View File

@ -1172,7 +1172,7 @@ production: &base
# keep_time: 604800 # default: 0 (forever) (in seconds)
# pg_schema: public # default: nil, it means that all schemas will be backed up
# upload:
# # Fog storage connection settings, see http://fog.io/storage/ .
# # Fog storage connection settings, see https://fog.io/storage/ .
# connection:
# provider: AWS
# region: eu-west-1

View File

@ -71,9 +71,9 @@ POST /groups/:id/access_requests
POST /projects/:id/access_requests
```
| Attribute | Type | Required | Description |
| --------- | -------------- | -------- | ----------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
| Attribute | Type | Required | Description |
| --------- | -------------- | -------- |-----------------------------------------------------------------------------------------|
| `id` | integer/string | yes | The ID or [URL-encoded path of the group or project](index.md#namespaced-path-encoding) |
Example request:

View File

@ -389,9 +389,9 @@ Example response:
"tag_list":[], //deprecated, use `topics` instead
"topics":[],
"ssh_url_to_repo":"ssh://git@gitlab.com/h5bp/html5-boilerplate.git",
"http_url_to_repo":"http://gitlab.com/h5bp/html5-boilerplate.git",
"web_url":"http://gitlab.com/h5bp/html5-boilerplate",
"readme_url":"http://gitlab.com/h5bp/html5-boilerplate/-/blob/master/README.md",
"http_url_to_repo":"https://gitlab.com/h5bp/html5-boilerplate.git",
"web_url":"https://gitlab.com/h5bp/html5-boilerplate",
"readme_url":"https://gitlab.com/h5bp/html5-boilerplate/-/blob/master/README.md",
"avatar_url":null,
"star_count":0,
"forks_count":4,
@ -404,16 +404,16 @@ Example response:
"full_path":"h5bp",
"parent_id":null,
"avatar_url":null,
"web_url":"http://gitlab.com/groups/h5bp"
"web_url":"https://gitlab.com/groups/h5bp"
},
"_links":{
"self":"http://gitlab.com/api/v4/projects/8",
"issues":"http://gitlab.com/api/v4/projects/8/issues",
"merge_requests":"http://gitlab.com/api/v4/projects/8/merge_requests",
"repo_branches":"http://gitlab.com/api/v4/projects/8/repository/branches",
"labels":"http://gitlab.com/api/v4/projects/8/labels",
"events":"http://gitlab.com/api/v4/projects/8/events",
"members":"http://gitlab.com/api/v4/projects/8/members"
"self":"https://gitlab.com/api/v4/projects/8",
"issues":"https://gitlab.com/api/v4/projects/8/issues",
"merge_requests":"https://gitlab.com/api/v4/projects/8/merge_requests",
"repo_branches":"https://gitlab.com/api/v4/projects/8/repository/branches",
"labels":"https://gitlab.com/api/v4/projects/8/labels",
"events":"https://gitlab.com/api/v4/projects/8/events",
"members":"https://gitlab.com/api/v4/projects/8/members"
},
"empty_repo":false,
"archived":false,

View File

@ -227,7 +227,7 @@ Issues created by users on GitLab Premium or higher include the `iteration` prop
"updated_at":"2022-03-14T05:21:11.929Z",
"start_date":"2022-03-08",
"due_date":"2022-03-14",
"web_url":"http://gitlab.com/groups/my-group/-/iterations/90"
"web_url":"https://gitlab.com/groups/my-group/-/iterations/90"
}
...
}

View File

@ -135,7 +135,7 @@ Example response:
```json
{
"name": "Ruby",
"content": "# This file is a template, and might need editing before it works on your project.\n# To contribute improvements to CI/CD templates, please follow the Development guide at:\n# https://docs.gitlab.com/ee/development/cicd/templates.html\n# This specific template is located at:\n# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Ruby.gitlab-ci.yml\n\n# Official language image. Look for the different tagged releases at:\n# https://hub.docker.com/r/library/ruby/tags/\nimage: ruby:latest\n\n# Pick zero or more services to be used on all builds.\n# Only needed when using a docker container to run your tests in.\n# Check out: http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service\nservices:\n - mysql:latest\n - redis:latest\n - postgres:latest\n\nvariables:\n POSTGRES_DB: database_name\n\n# Cache gems in between builds\ncache:\n paths:\n - vendor/ruby\n\n# This is a basic example for a gem or script which doesn't use\n# services such as redis or postgres\nbefore_script:\n - ruby -v # Print out ruby version for debugging\n # Uncomment next line if your rails app needs a JS runtime:\n # - apt-get update -q && apt-get install nodejs -yqq\n - bundle config set path 'vendor' # Install dependencies into ./vendor/ruby\n - bundle install -j $(nproc)\n\n# Optional - Delete if not using `rubocop`\nrubocop:\n script:\n - rubocop\n\nrspec:\n script:\n - rspec spec\n\nrails:\n variables:\n DATABASE_URL: \"postgresql://postgres:postgres@postgres:5432/$POSTGRES_DB\"\n script:\n - rails db:migrate\n - rails db:seed\n - rails test\n\n# This deploy job uses a simple deploy flow to Heroku, other providers, e.g. AWS Elastic Beanstalk\n# are supported too: https://github.com/travis-ci/dpl\ndeploy:\n stage: deploy\n environment: production\n script:\n - gem install dpl\n - dpl --provider=heroku --app=$HEROKU_APP_NAME --api-key=$HEROKU_PRODUCTION_KEY\n"
"content": "# This file is a template, and might need editing before it works on your project.\n# To contribute improvements to CI/CD templates, please follow the Development guide at:\n# https://docs.gitlab.com/ee/development/cicd/templates.html\n# This specific template is located at:\n# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Ruby.gitlab-ci.yml\n\n# Official language image. Look for the different tagged releases at:\n# https://hub.docker.com/r/library/ruby/tags/\nimage: ruby:latest\n\n# Pick zero or more services to be used on all builds.\n# Only needed when using a docker container to run your tests in.\n# Check out: https://docs.gitlab.com/ee/ci/services/index.html\nservices:\n - mysql:latest\n - redis:latest\n - postgres:latest\n\nvariables:\n POSTGRES_DB: database_name\n\n# Cache gems in between builds\ncache:\n paths:\n - vendor/ruby\n\n# This is a basic example for a gem or script which doesn't use\n# services such as redis or postgres\nbefore_script:\n - ruby -v # Print out ruby version for debugging\n # Uncomment next line if your rails app needs a JS runtime:\n # - apt-get update -q \u0026\u0026 apt-get install nodejs -yqq\n - bundle config set --local deployment true # Install dependencies into ./vendor/ruby\n - bundle install -j $(nproc)\n\n# Optional - Delete if not using `rubocop`\nrubocop:\n script:\n - rubocop\n\nrspec:\n script:\n - rspec spec\n\nrails:\n variables:\n DATABASE_URL: \"postgresql://postgres:postgres@postgres:5432/$POSTGRES_DB\"\n script:\n - rails db:migrate\n - rails db:seed\n - rails test\n\n# This deploy job uses a simple deploy flow to Heroku, other providers, e.g. AWS Elastic Beanstalk\n# are supported too: https://github.com/travis-ci/dpl\ndeploy:\n stage: deploy\n environment: production\n script:\n - gem install dpl\n - dpl --provider=heroku --app=$HEROKU_APP_NAME --api-key=$HEROKU_PRODUCTION_KEY\n"
}
```

View File

@ -273,7 +273,7 @@ Use this regex for commonly used test tools.
<!-- vale gitlab.Spelling = NO -->
- Simplecov (Ruby). Example: `\(\d+.\d+\%\) covered`.
- pytest-cov (Python). Example: `^TOTAL.+?(\d+\%)$`.
- pytest-cov (Python). Example: `(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$`.
- Scoverage (Scala). Example: `Statement coverage[A-Za-z\.*]\s*:\s*([^%]+)`.
- `phpunit --coverage-text --colors=never` (PHP). Example: `^\s*Lines:\s*\d+.\d+\%`.
- gcovr (C/C++). Example: `^TOTAL.*\s+(\d+\%)$`.

View File

@ -71,7 +71,7 @@ expect(cleanForSnapshot(wrapper.element)).toMatchSnapshot();
### Resources
[Unofficial wiki explanation](http://wiki.c2.com/?PinningTests)
[Unofficial wiki explanation](https://wiki.c2.com/?PinningTests)
### Examples

View File

@ -17,7 +17,7 @@ These guidelines are meant to make your code more reliable _and_ secure.
## Use File and FileUtils instead of shell commands
Sometimes we invoke basic Unix commands via the shell when there is also a Ruby API for doing it. Use the Ruby API if it exists. <http://www.ruby-doc.org/stdlib-2.0.0/libdoc/fileutils/rdoc/FileUtils.html#module-FileUtils-label-Module+Functions>
Sometimes we invoke basic Unix commands via the shell when there is also a Ruby API for doing it. Use the Ruby API if it exists. <https://www.ruby-doc.org/stdlib-2.0.0/libdoc/fileutils/rdoc/FileUtils.html#module-FileUtils-label-Module+Functions>
```ruby
# Wrong

View File

@ -155,7 +155,7 @@ to assign a descriptive DNS name to the VM:
1. Enter a descriptive DNS name for your instance in the **DNS name label** field,
for example `gitlab-prod`. This makes the VM accessible at
`gitlab-prod.eastus.cloudapp.azure.com`.
1. Select **Save** for the changes to take effect.
1. Select **Save**.
Eventually, most users want to use their own domain name. For you to do this, you need to add a DNS `A` record
with your domain registrar that points to the public IP address of your Azure VM.

View File

@ -54,10 +54,11 @@ You can [disable comments](#disable-comments-on-jira-issues) on issues.
You can prevent merge requests from being merged if they do not refer to a Jira issue.
To enforce this:
1. Navigate to your project's **Settings > General** page.
1. Expand the **Merge requests** section.
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Settings > General**.
1. Expand **Merge requests**.
1. Under **Merge checks**, select the **Require an associated issue from Jira** checkbox.
1. Select **Save** for the changes to take effect.
1. Select **Save**.
After you enable this feature, a merge request that doesn't reference an associated
Jira issue can't be merged. The merge request displays the message

View File

@ -791,7 +791,6 @@ Examples:
- [ADFS (Active Directory Federation Services)](https://docs.microsoft.com/en-us/windows-server/identity/ad-fs/operations/create-a-relying-party-trust)
- [Auth0](https://auth0.com/docs/authenticate/protocols/saml/saml-sso-integrations/configure-auth0-saml-identity-provider)
- [PingOne by Ping Identity](http://docs.pingidentity.com/bundle/pingoneforenterprise/page/xsh1564020480660-1.html)
GitLab provides the following setup notes for guidance only.
If you have any questions on configuring the SAML app, please contact your provider's support.

View File

@ -561,7 +561,7 @@ For installations from source:
backup:
# snip
upload:
# Fog storage connection settings, see http://fog.io/storage/ .
# Fog storage connection settings, see https://fog.io/storage/ .
connection:
provider: AWS
region: eu-west-1
@ -811,7 +811,7 @@ For installations from source:
```yaml
backup:
upload:
# Fog storage connection settings, see http://fog.io/storage/ .
# Fog storage connection settings, see https://fog.io/storage/ .
connection:
provider: Local
local_root: '/mnt/backups'

View File

@ -96,6 +96,106 @@ A finding's location fingerprint is a text value that's unique for each location
surface. Each Secure product defines this according to its type of attack surface. For example, SAST
incorporates file path and line number.
### Package managers
A Package manager is a system that manages your project dependencies.
The package manager provides a method to install new dependencies (also referred to as "packages"), manage where packages are stored on your file system, and offer capabilities for you to publish your own packages.
### Package types
Each package manager, platform, type, or ecosystem has its own conventions and protocols to identify, locate, and provision software packages.
The following table is a non-exhaustive list of some of the package managers and types referenced in GitLab documentation and software tools.
<style>
table.package-managers-and-types tr:nth-child(even) {
background-color: transparent;
}
table.package-managers-and-types td {
border-left: 1px solid #dbdbdb;
border-right: 1px solid #dbdbdb;
border-bottom: 1px solid #dbdbdb;
}
table.package-managers-and-types tr td:first-child {
border-left: 0;
}
table.package-managers-and-types tr td:last-child {
border-right: 0;
}
table.package-managers-and-types ul {
font-size: 1em;
list-style-type: none;
padding-left: 0px;
margin-bottom: 0px;
}
</style>
<table class="package-managers-and-types">
<thead>
<tr>
<th>Package Type</th>
<th>Package Manager</th>
</tr>
</thead>
<tbody>
<tr>
<td>gem</td>
<td><a href="https://bundler.io/">bundler</a></td>
</tr>
<tr>
<td>packagist</td>
<td><a href="https://getcomposer.org/">composer</a></td>
</tr>
<tr>
<td>conan</td>
<td><a href="https://conan.io/">conan</a></td>
</tr>
<tr>
<td>go</td>
<td><a href="https://go.dev/blog/using-go-modules">go</a></td>
</tr>
<tr>
<td rowspan="3">maven</td>
<td><a href="https://gradle.org/">gradle</a></td>
</tr>
<tr>
<td><a href="https://maven.apache.org/">maven</a></td>
</tr>
<tr>
<td><a href="https://www.scala-sbt.org">sbt</a></td>
</tr>
<tr>
<td rowspan="2">npm</td>
<td><a href="https://www.npmjs.com">npm</a></td>
</tr>
<tr>
<td><a href="https://classic.yarnpkg.com/en">yarn</a></td>
</tr>
<tr>
<td>nuget</td>
<td><a href="https://www.nuget.org/">nuget</a></td>
</tr>
<tr>
<td rowspan="4">pypi</td>
<td><a href="https://setuptools.pypa.io/en/latest/">setuptools</a></td>
</tr>
<tr>
<td><a href="https://pip.pypa.io/en/stable">pip</a></td>
</tr>
<tr>
<td><a href="https://pipenv.pypa.io/en/latest">Pipenv</a></td>
</tr>
<tr>
<td><a href="https://python-poetry.org/">Poetry</a></td>
</tr>
</tbody>
</table>
### Pipeline Security tab
A page that displays findings discovered in the associated CI pipeline.

View File

@ -56,10 +56,11 @@ As a result, [disabling GitLab CI/CD pipelines](../../../ci/enable_or_disable_ci
does not disable this feature, as it is possible to use pipelines from external
CI providers with this feature. To enable it, you must:
1. Navigate to your project's **Settings > General** page.
1. Expand the **Merge requests** section.
1. In the **Merge checks** subsection, select the **Pipelines must succeed** checkbox.
1. Press **Save** for the changes to take effect.
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Settings > General**.
1. Expand **Merge requests**.
1. Under **Merge checks**, select the **Pipelines must succeed** checkbox.
1. Select **Save**.
This setting also prevents merge requests from being merged if there is no pipeline.
You should be careful to configure CI/CD so that pipelines run for every merge request.
@ -104,11 +105,13 @@ for details on avoiding two pipelines for a single merge request.
When the **Pipelines must succeed** checkbox is checked, [skipped pipelines](../../../ci/pipelines/index.md#skip-a-pipeline) prevent
merge requests from being merged. To change this behavior:
1. Navigate to your project's **Settings > General** page.
1. Expand the **Merge requests** section.
1. In the **Merge checks** subsection, ensure **Pipelines must succeed** is checked.
1. In the **Merge checks** subsection, select the **Skipped pipelines are considered successful** checkbox.
1. Press **Save** for the changes to take effect.
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Settings > General**.
1. Expand **Merge requests**.
1. Under **Merge checks**:
- Ensure **Pipelines must succeed** is selected.
- Select the **Skipped pipelines are considered successful** checkbox.
1. Select **Save**.
## From the command line

View File

@ -255,7 +255,7 @@ run tests:
- coverage run -m pytest
- coverage report
- coverage xml
coverage: '/TOTAL.*\s([.\d]+)%/'
coverage: '/(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$/'
artifacts:
reports:
coverage_report:

View File

@ -9,7 +9,7 @@ image: "crystallang/crystal:latest"
# Pick zero or more services to be used on all builds.
# Only needed when using a docker container to run your tests in.
# Check out: http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service
# Check out: https://docs.gitlab.com/ee/ci/services/index.html
# services:
# - mysql:latest
# - redis:latest

View File

@ -41,7 +41,7 @@ default:
#
# Pick zero or more services to be used on all builds.
# Only needed when using a docker container to run your tests in.
# Check out: http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service
# Check out: https://docs.gitlab.com/ee/ci/services/index.html
services:
- mysql:8.0
#

View File

@ -7,7 +7,7 @@ image: elixir:latest
# Pick zero or more services to be used on all builds.
# Only needed when using a docker container to run your tests in.
# Check out: http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service
# Check out: https://docs.gitlab.com/ee/ci/services/index.html
services:
- mysql:latest
- redis:latest

View File

@ -9,7 +9,7 @@ image: php:latest
# Pick zero or more services to be used on all builds.
# Only needed when using a docker container to run your tests in.
# Check out: http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service
# Check out: https://docs.gitlab.com/ee/ci/services/index.html
services:
- mysql:latest

View File

@ -9,7 +9,7 @@ image: node:latest
# Pick zero or more services to be used on all builds.
# Only needed when using a docker container to run your tests in.
# Check out: http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service
# Check out: https://docs.gitlab.com/ee/ci/services/index.html
services:
- mysql:latest
- redis:latest

View File

@ -23,7 +23,7 @@ before_script:
- curl -sS https://getcomposer.org/installer | php
- php composer.phar install
# Bring in any services we need http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service
# Bring in any services we need https://docs.gitlab.com/ee/ci/services/index.html
# See http://docs.gitlab.com/ee/ci/services/README.html for examples.
services:
- mysql:5.7

View File

@ -9,7 +9,7 @@ image: ruby:latest
# Pick zero or more services to be used on all builds.
# Only needed when using a docker container to run your tests in.
# Check out: http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service
# Check out: https://docs.gitlab.com/ee/ci/services/index.html
services:
- mysql:latest
- redis:latest

View File

@ -9,7 +9,7 @@ image: "rust:latest"
# Optional: Pick zero or more services to be used on all builds.
# Only needed when using a docker container to run your tests in.
# Check out: http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service
# Check out: https://docs.gitlab.com/ee/ci/services/index.html
# services:
# - mysql:latest
# - redis:latest

View File

@ -112,7 +112,7 @@ module Sidebars
::Sidebars::MenuItem.new(
title: _('Packages & Registries'),
link: project_settings_packages_and_registries_path(context.project),
active_routes: { path: 'packages_and_registries#index' },
active_routes: { path: 'packages_and_registries#show' },
item_id: :packages_and_registries
)
end

View File

@ -288,41 +288,35 @@ RSpec.describe Project, factory_default: :keep do
end
context 'updating a project' do
shared_examples 'project update' do
let_it_be(:project_namespace) { create(:project_namespace) }
let_it_be(:project) { project_namespace.project }
let_it_be(:project_namespace) { create(:project_namespace) }
let_it_be(:project) { project_namespace.project }
context 'when project namespace is not set' do
before do
project.update_column(:project_namespace_id, nil)
project.reload
end
context 'when project has an associated project namespace' do
# when FF is disabled creating a project does not create a project_namespace, so we create one
it 'project is INVALID when trying to remove project namespace' do
project.reload
# check that project actually has an associated project namespace
expect(project.project_namespace_id).to eq(project_namespace.id)
it 'updates the project successfully' do
# pre-check that project does not have a project namespace
expect(project.project_namespace).to be_nil
project.update!(path: 'hopefully-valid-path2')
expect(project).to be_persisted
expect(project).to be_valid
expect(project.path).to eq('hopefully-valid-path2')
expect(project.project_namespace).to be_nil
end
expect do
project.update!(project_namespace_id: nil, path: 'hopefully-valid-path1')
end.to raise_error(ActiveRecord::RecordInvalid)
expect(project).to be_invalid
expect(project.errors.full_messages).to include("Project namespace can't be blank")
expect(project.reload.project_namespace).to be_in_sync_with_project(project)
end
context 'when project has an associated project namespace' do
# when FF is disabled creating a project does not create a project_namespace, so we create one
it 'project is INVALID when trying to remove project namespace' do
project.reload
# check that project actually has an associated project namespace
expect(project.project_namespace_id).to eq(project_namespace.id)
context 'when same project is being updated in 2 instances' do
it 'syncs only changed attributes' do
project1 = Project.last
project2 = Project.last
project_name = project1.name
project_path = project1.path
project1.update!(name: project_name + "-1")
project2.update!(path: project_path + "-1")
expect do
project.update!(project_namespace_id: nil, path: 'hopefully-valid-path1')
end.to raise_error(ActiveRecord::RecordInvalid)
expect(project).to be_invalid
expect(project.errors.full_messages).to include("Project namespace can't be blank")
expect(project.reload.project_namespace).to be_in_sync_with_project(project)
end
end

View File

@ -11,4 +11,56 @@ RSpec.describe ProtectedTag do
it { is_expected.to validate_presence_of(:project) }
it { is_expected.to validate_presence_of(:name) }
end
describe '#protected?' do
let(:project) { create(:project, :repository) }
it 'returns true when the tag matches a protected tag via direct match' do
create(:protected_tag, project: project, name: 'foo')
expect(described_class.protected?(project, 'foo')).to eq(true)
end
it 'returns true when the tag matches a protected tag via wildcard match' do
create(:protected_tag, project: project, name: 'production/*')
expect(described_class.protected?(project, 'production/some-tag')).to eq(true)
end
it 'returns false when the tag does not match a protected tag via direct match' do
expect(described_class.protected?(project, 'foo')).to eq(false)
end
it 'returns false when the tag does not match a protected tag via wildcard match' do
create(:protected_tag, project: project, name: 'production/*')
expect(described_class.protected?(project, 'staging/some-tag')).to eq(false)
end
it 'returns false when tag name is nil' do
expect(described_class.protected?(project, nil)).to eq(false)
end
context 'with caching', :request_store do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:protected_tag) { create(:protected_tag, project: project, name: 'foo') }
it 'correctly invalidates a cache' do
expect(described_class.protected?(project, 'foo')).to eq(true)
expect(described_class.protected?(project, 'bar')).to eq(false)
create(:protected_tag, project: project, name: 'bar')
expect(described_class.protected?(project, 'bar')).to eq(true)
end
it 'correctly uses the cached version' do
expect(project).to receive(:protected_tags).once.and_call_original
2.times do
expect(described_class.protected?(project, protected_tag.name)).to eq(true)
end
end
end
end
end

View File

@ -32,7 +32,10 @@ RSpec.describe Projects::IssueLinksController do
get namespace_project_issue_links_path(issue_links_params)
expect(json_response.count).to eq(1)
expect(json_response.first).to include('path' => project_work_items_path(issue_b.project, issue_b.id))
expect(json_response.first).to include(
'path' => project_work_items_path(issue_b.project, issue_b.id),
'type' => 'TASK'
)
end
end
end

View File

@ -25,6 +25,22 @@ RSpec.describe LinkedProjectIssueEntity do
it { is_expected.to include(link_type: 'relates_to') }
end
describe 'type' do
it 'returns the issue type' do
expect(serialized_entity).to include(type: 'ISSUE')
end
context 'when related issue is a task' do
before do
related_issue.update!(issue_type: :task, work_item_type: WorkItems::Type.default_by_type(:task))
end
it 'returns a work item issue type' do
expect(serialized_entity).to include(type: 'TASK')
end
end
end
describe 'path' do
it 'returns an issue path' do
expect(serialized_entity).to include(path: project_issue_path(related_issue.project, related_issue.iid))