Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
56b3925584
commit
8cd9a01379
|
@ -77,7 +77,7 @@ review-build-cng:
|
||||||
variables:
|
variables:
|
||||||
HOST_SUFFIX: "${CI_ENVIRONMENT_SLUG}"
|
HOST_SUFFIX: "${CI_ENVIRONMENT_SLUG}"
|
||||||
DOMAIN: "-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}"
|
DOMAIN: "-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}"
|
||||||
GITLAB_HELM_CHART_REF: "v5.10.0"
|
GITLAB_HELM_CHART_REF: "41d7632d9eba84f5816d808b98ccf3f5623e9fb5"
|
||||||
environment:
|
environment:
|
||||||
name: review/${CI_COMMIT_REF_SLUG}${FREQUENCY}
|
name: review/${CI_COMMIT_REF_SLUG}${FREQUENCY}
|
||||||
url: https://gitlab-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}
|
url: https://gitlab-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}
|
||||||
|
|
|
@ -76,7 +76,7 @@
|
||||||
.if-merge-request-labels-jh-contribution: &if-merge-request-labels-jh-contribution
|
.if-merge-request-labels-jh-contribution: &if-merge-request-labels-jh-contribution
|
||||||
if: '$CI_MERGE_REQUEST_LABELS =~ /JiHu contribution/'
|
if: '$CI_MERGE_REQUEST_LABELS =~ /JiHu contribution/'
|
||||||
|
|
||||||
.if-merge-request-labels-run-search-tests: &if-merge-request-labels-run-search-tests
|
.if-merge-request-labels-group-global-search: &if-merge-request-labels-group-global-search
|
||||||
if: '$CI_MERGE_REQUEST_LABELS =~ /group::global search/'
|
if: '$CI_MERGE_REQUEST_LABELS =~ /group::global search/'
|
||||||
|
|
||||||
.if-security-merge-request: &if-security-merge-request
|
.if-security-merge-request: &if-security-merge-request
|
||||||
|
@ -263,7 +263,7 @@
|
||||||
- "config.ru"
|
- "config.ru"
|
||||||
# List explicitly all the app/ dirs that are backend (i.e. all except app/assets).
|
# List explicitly all the app/ dirs that are backend (i.e. all except app/assets).
|
||||||
- "{,ee/,jh/}{app/channels,app/controllers,app/finders,app/graphql,app/helpers,app/mailers,app/models,app/policies,app/presenters,app/serializers,app/services,app/uploaders,app/validators,app/views,app/workers}/**/*"
|
- "{,ee/,jh/}{app/channels,app/controllers,app/finders,app/graphql,app/helpers,app/mailers,app/models,app/policies,app/presenters,app/serializers,app/services,app/uploaders,app/validators,app/views,app/workers}/**/*"
|
||||||
- "{,ee/,jh/}{bin,cable,config,db,generator_templates,lib}/**/*"
|
- "{,ee/,jh/}{bin,config,db,generator_templates,lib}/**/*"
|
||||||
- "{,ee/,jh/}spec/**/*"
|
- "{,ee/,jh/}spec/**/*"
|
||||||
# CI changes
|
# CI changes
|
||||||
- ".gitlab-ci.yml"
|
- ".gitlab-ci.yml"
|
||||||
|
@ -273,6 +273,14 @@
|
||||||
# Mapped patterns (see tests.yml)
|
# Mapped patterns (see tests.yml)
|
||||||
- "data/whats_new/*.yml"
|
- "data/whats_new/*.yml"
|
||||||
|
|
||||||
|
.search-backend-patterns: &search-backend-patterns
|
||||||
|
- "{,jh/}Gemfile.lock"
|
||||||
|
- "GITLAB_ELASTICSEARCH_INDEXER_VERSION"
|
||||||
|
# List explicitly all the app/ dirs that are backend (i.e. all except app/assets).
|
||||||
|
- "{,ee/,jh/}{app/channels,app/controllers,app/finders,app/graphql,app/helpers,app/mailers,app/models,app/policies,app/presenters,app/serializers,app/services,app/uploaders,app/validators,app/views,app/workers}/**/*"
|
||||||
|
- "{,ee/,jh/}{bin,config,db,generator_templates,lib}/**/*"
|
||||||
|
- "{,ee/,jh/}spec/**/*"
|
||||||
|
|
||||||
# DB patterns + .ci-patterns
|
# DB patterns + .ci-patterns
|
||||||
.db-patterns: &db-patterns
|
.db-patterns: &db-patterns
|
||||||
- "{,ee/,jh/}{,spec/}{db,migrations}/**/*"
|
- "{,ee/,jh/}{,spec/}{db,migrations}/**/*"
|
||||||
|
@ -521,7 +529,8 @@
|
||||||
|
|
||||||
.rails:rules:run-search-tests:
|
.rails:rules:run-search-tests:
|
||||||
rules:
|
rules:
|
||||||
- <<: *if-merge-request-labels-run-search-tests
|
- <<: *if-merge-request-labels-group-global-search
|
||||||
|
changes: *search-backend-patterns
|
||||||
|
|
||||||
.rails:rules:ee-and-foss-default-rules:
|
.rails:rules:ee-and-foss-default-rules:
|
||||||
rules:
|
rules:
|
||||||
|
|
|
@ -208,7 +208,6 @@ Layout/FirstHashElementIndentation:
|
||||||
- 'ee/spec/serializers/issues/linked_issue_feature_flag_entity_spec.rb'
|
- 'ee/spec/serializers/issues/linked_issue_feature_flag_entity_spec.rb'
|
||||||
- 'ee/spec/serializers/license_entity_spec.rb'
|
- 'ee/spec/serializers/license_entity_spec.rb'
|
||||||
- 'ee/spec/serializers/linked_feature_flag_issue_entity_spec.rb'
|
- 'ee/spec/serializers/linked_feature_flag_issue_entity_spec.rb'
|
||||||
- 'ee/spec/services/alert_management/network_alert_service_spec.rb'
|
|
||||||
- 'ee/spec/services/analytics/cycle_analytics/data_loader_service_spec.rb'
|
- 'ee/spec/services/analytics/cycle_analytics/data_loader_service_spec.rb'
|
||||||
- 'ee/spec/services/app_sec/dast/profile_schedules/audit/update_service_spec.rb'
|
- 'ee/spec/services/app_sec/dast/profile_schedules/audit/update_service_spec.rb'
|
||||||
- 'ee/spec/services/app_sec/dast/profiles/audit/update_service_spec.rb'
|
- 'ee/spec/services/app_sec/dast/profiles/audit/update_service_spec.rb'
|
||||||
|
|
|
@ -426,7 +426,6 @@ Layout/HashAlignment:
|
||||||
- 'ee/spec/requests/projects/security/dast_site_profiles_controller_spec.rb'
|
- 'ee/spec/requests/projects/security/dast_site_profiles_controller_spec.rb'
|
||||||
- 'ee/spec/requests/rack_attack_global_spec.rb'
|
- 'ee/spec/requests/rack_attack_global_spec.rb'
|
||||||
- 'ee/spec/serializers/integrations/zentao_serializers/issue_entity_spec.rb'
|
- 'ee/spec/serializers/integrations/zentao_serializers/issue_entity_spec.rb'
|
||||||
- 'ee/spec/services/alert_management/network_alert_service_spec.rb'
|
|
||||||
- 'ee/spec/services/app_sec/dast/profiles/create_associations_service_spec.rb'
|
- 'ee/spec/services/app_sec/dast/profiles/create_associations_service_spec.rb'
|
||||||
- 'ee/spec/services/audit_events/protected_branch_audit_event_service_spec.rb'
|
- 'ee/spec/services/audit_events/protected_branch_audit_event_service_spec.rb'
|
||||||
- 'ee/spec/services/ci/create_pipeline_service/cross_needs_artifacts_spec.rb'
|
- 'ee/spec/services/ci/create_pipeline_service/cross_needs_artifacts_spec.rb'
|
||||||
|
|
|
@ -2776,7 +2776,6 @@ Layout/LineLength:
|
||||||
- 'ee/spec/serializers/vulnerabilities/finding_reports_comparer_entity_spec.rb'
|
- 'ee/spec/serializers/vulnerabilities/finding_reports_comparer_entity_spec.rb'
|
||||||
- 'ee/spec/serializers/vulnerabilities/finding_serializer_spec.rb'
|
- 'ee/spec/serializers/vulnerabilities/finding_serializer_spec.rb'
|
||||||
- 'ee/spec/services/alert_management/metric_images/upload_service_spec.rb'
|
- 'ee/spec/services/alert_management/metric_images/upload_service_spec.rb'
|
||||||
- 'ee/spec/services/alert_management/network_alert_service_spec.rb'
|
|
||||||
- 'ee/spec/services/alert_management/process_prometheus_alert_service_spec.rb'
|
- 'ee/spec/services/alert_management/process_prometheus_alert_service_spec.rb'
|
||||||
- 'ee/spec/services/analytics/cycle_analytics/consistency_check_service_spec.rb'
|
- 'ee/spec/services/analytics/cycle_analytics/consistency_check_service_spec.rb'
|
||||||
- 'ee/spec/services/analytics/cycle_analytics/data_loader_service_spec.rb'
|
- 'ee/spec/services/analytics/cycle_analytics/data_loader_service_spec.rb'
|
||||||
|
|
|
@ -85,7 +85,6 @@ RSpec/AnyInstanceOf:
|
||||||
- ee/spec/requests/groups_controller_spec.rb
|
- ee/spec/requests/groups_controller_spec.rb
|
||||||
- ee/spec/requests/omniauth_kerberos_spnego_spec.rb
|
- ee/spec/requests/omniauth_kerberos_spnego_spec.rb
|
||||||
- ee/spec/requests/repositories/git_http_controller_spec.rb
|
- ee/spec/requests/repositories/git_http_controller_spec.rb
|
||||||
- ee/spec/services/alert_management/network_alert_service_spec.rb
|
|
||||||
- ee/spec/services/ci/expire_pipeline_cache_service_spec.rb
|
- ee/spec/services/ci/expire_pipeline_cache_service_spec.rb
|
||||||
- ee/spec/services/ci/run_dast_scan_service_spec.rb
|
- ee/spec/services/ci/run_dast_scan_service_spec.rb
|
||||||
- ee/spec/services/ee/git/branch_push_service_spec.rb
|
- ee/spec/services/ee/git/branch_push_service_spec.rb
|
||||||
|
|
|
@ -7,7 +7,7 @@ module Mutations
|
||||||
|
|
||||||
include FindsProject
|
include FindsProject
|
||||||
|
|
||||||
authorize :destroy_container_image
|
authorize :admin_container_image
|
||||||
|
|
||||||
argument :project_path,
|
argument :project_path,
|
||||||
GraphQL::Types::ID,
|
GraphQL::Types::ID,
|
||||||
|
|
|
@ -26,6 +26,7 @@ module Mutations
|
||||||
def resolve(note:, position:)
|
def resolve(note:, position:)
|
||||||
authorize!(note)
|
authorize!(note)
|
||||||
|
|
||||||
|
position = position.to_h.compact
|
||||||
pre_update_checks!(note, position)
|
pre_update_checks!(note, position)
|
||||||
|
|
||||||
updated_note = ::Notes::UpdateService.new(
|
updated_note = ::Notes::UpdateService.new(
|
||||||
|
@ -46,7 +47,7 @@ module Mutations
|
||||||
# just a `DiffNote` with a particular kind of `Gitlab::Diff::Position`.
|
# just a `DiffNote` with a particular kind of `Gitlab::Diff::Position`.
|
||||||
# In addition to accepting a `DiffNote` Global ID we also need to
|
# In addition to accepting a `DiffNote` Global ID we also need to
|
||||||
# perform this check.
|
# perform this check.
|
||||||
def pre_update_checks!(note, position)
|
def pre_update_checks!(note, _position)
|
||||||
unless note.position&.on_image?
|
unless note.position&.on_image?
|
||||||
raise Gitlab::Graphql::Errors::ResourceNotAvailable,
|
raise Gitlab::Graphql::Errors::ResourceNotAvailable,
|
||||||
'Resource is not an ImageDiffNote'
|
'Resource is not an ImageDiffNote'
|
||||||
|
|
|
@ -54,7 +54,7 @@ module Mutations
|
||||||
|
|
||||||
original_position = note.position.to_h
|
original_position = note.position.to_h
|
||||||
|
|
||||||
Gitlab::Diff::Position.new(original_position.merge(args[:position]))
|
Gitlab::Diff::Position.new(original_position.merge(args[:position].to_h))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -24,10 +24,13 @@ module TimeFrameArguments
|
||||||
# TODO: remove when the start_date and end_date arguments are removed
|
# TODO: remove when the start_date and end_date arguments are removed
|
||||||
def validate_timeframe_params!(args)
|
def validate_timeframe_params!(args)
|
||||||
return unless %i[start_date end_date timeframe].any? { |k| args[k].present? }
|
return unless %i[start_date end_date timeframe].any? { |k| args[k].present? }
|
||||||
return if args[:timeframe] && %i[start_date end_date].all? { |k| args[k].nil? }
|
|
||||||
|
# the timeframe is passed in as a TimeframeInputType
|
||||||
|
timeframe = args[:timeframe].to_h if args[:timeframe]
|
||||||
|
return if timeframe && %i[start_date end_date].all? { |k| args[k].nil? }
|
||||||
|
|
||||||
error_message =
|
error_message =
|
||||||
if args[:timeframe].present?
|
if timeframe.present?
|
||||||
"startDate and endDate are deprecated in favor of timeframe. Please use only timeframe."
|
"startDate and endDate are deprecated in favor of timeframe. Please use only timeframe."
|
||||||
elsif args[:start_date].nil? || args[:end_date].nil?
|
elsif args[:start_date].nil? || args[:end_date].nil?
|
||||||
"Both startDate and endDate must be present."
|
"Both startDate and endDate must be present."
|
||||||
|
@ -42,7 +45,7 @@ module TimeFrameArguments
|
||||||
|
|
||||||
def transform_timeframe_parameters(args)
|
def transform_timeframe_parameters(args)
|
||||||
if args[:timeframe]
|
if args[:timeframe]
|
||||||
args[:timeframe].transform_keys { |k| :"#{k}_date" }
|
args[:timeframe].to_h.transform_keys { |k| :"#{k}_date" }
|
||||||
else
|
else
|
||||||
args.slice(:start_date, :end_date)
|
args.slice(:start_date, :end_date)
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,7 +7,6 @@ module Types
|
||||||
|
|
||||||
argument :not, NegatedBoardIssueInputType,
|
argument :not, NegatedBoardIssueInputType,
|
||||||
required: false,
|
required: false,
|
||||||
prepare: ->(negated_args, ctx) { negated_args.to_h },
|
|
||||||
description: 'List of negated arguments.'
|
description: 'List of negated arguments.'
|
||||||
|
|
||||||
argument :search, GraphQL::Types::String,
|
argument :search, GraphQL::Types::String,
|
||||||
|
|
|
@ -6,7 +6,7 @@ module Types
|
||||||
|
|
||||||
description 'A tag expiration policy designed to keep only the images that matter most'
|
description 'A tag expiration policy designed to keep only the images that matter most'
|
||||||
|
|
||||||
authorize :destroy_container_image
|
authorize :admin_container_image
|
||||||
|
|
||||||
field :cadence, Types::ContainerExpirationPolicyCadenceEnum, null: false, description: 'This container expiration policy schedule.'
|
field :cadence, Types::ContainerExpirationPolicyCadenceEnum, null: false, description: 'This container expiration policy schedule.'
|
||||||
field :created_at, Types::TimeType, null: false, description: 'Timestamp of when the container expiration policy was created.'
|
field :created_at, Types::TimeType, null: false, description: 'Timestamp of when the container expiration policy was created.'
|
||||||
|
|
|
@ -28,6 +28,8 @@ module Types
|
||||||
raise GraphQL::ExecutionError, "At least one property of `#{self.class.graphql_name}` must be set"
|
raise GraphQL::ExecutionError, "At least one property of `#{self.class.graphql_name}` must be set"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
super
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -21,7 +21,7 @@ module Types
|
||||||
raise ::Gitlab::Graphql::Errors::ArgumentError, 'start must be before end'
|
raise ::Gitlab::Graphql::Errors::ArgumentError, 'start must be before end'
|
||||||
end
|
end
|
||||||
|
|
||||||
to_h
|
super
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -28,7 +28,7 @@ module ContainerExpirationPolicies
|
||||||
end
|
end
|
||||||
|
|
||||||
def allowed?
|
def allowed?
|
||||||
Ability.allowed?(current_user, :destroy_container_image, @container)
|
Ability.allowed?(current_user, :admin_container_image, @container)
|
||||||
end
|
end
|
||||||
|
|
||||||
def container_expiration_policy_params
|
def container_expiration_policy_params
|
||||||
|
|
|
@ -478,28 +478,6 @@ curl --request POST --header "Gitlab-Kas-Api-Request: <JWT token>" --header "Con
|
||||||
--data '{"gitops_sync_count":1}' "http://localhost:3000/api/v4/internal/kubernetes/usage_metrics"
|
--data '{"gitops_sync_count":1}' "http://localhost:3000/api/v4/internal/kubernetes/usage_metrics"
|
||||||
```
|
```
|
||||||
|
|
||||||
### GitLab agent alert metrics
|
|
||||||
|
|
||||||
Called from GitLab agent server (KAS) to save alerts derived from Cilium on Kubernetes
|
|
||||||
Cluster.
|
|
||||||
|
|
||||||
| Attribute | Type | Required | Description |
|
|
||||||
|:----------|:-------|:---------|:------------|
|
|
||||||
| `alert` | Hash | yes | Alerts detail. Same format as [3rd party alert](../../operations/incident_management/integrations.md#customize-the-alert-payload-outside-of-gitlab). |
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
POST internal/kubernetes/modules/cilium_alert
|
|
||||||
```
|
|
||||||
|
|
||||||
Example Request:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
curl --request POST --header "Gitlab-Kas-Api-Request: <JWT token>" \
|
|
||||||
--header "Authorization: Bearer <agent token>" --header "Content-Type: application/json" \
|
|
||||||
--data '"{\"alert\":{\"title\":\"minimal\",\"message\":\"network problem\",\"evalMatches\":[{\"value\":1,\"metric\":\"Count\",\"tags\":{}}]}}"' \
|
|
||||||
"http://localhost:3000/api/v4/internal/kubernetes/modules/cilium_alert"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Create Starboard vulnerability
|
### Create Starboard vulnerability
|
||||||
|
|
||||||
Called from the GitLab agent server (`kas`) to create a security vulnerability
|
Called from the GitLab agent server (`kas`) to create a security vulnerability
|
||||||
|
|
|
@ -24,6 +24,7 @@ which doesn't include the Container Registry. To track work on this, see the epi
|
||||||
|
|
||||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15398) in GitLab 12.8.
|
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15398) in GitLab 12.8.
|
||||||
> - [Renamed](https://gitlab.com/gitlab-org/gitlab/-/issues/218737) from "expiration policy" to "cleanup policy" in GitLab 13.2.
|
> - [Renamed](https://gitlab.com/gitlab-org/gitlab/-/issues/218737) from "expiration policy" to "cleanup policy" in GitLab 13.2.
|
||||||
|
> - [Required permissions](https://gitlab.com/gitlab-org/gitlab/-/issues/350682) changed from developer to maintainer in GitLab 15.0.
|
||||||
|
|
||||||
The cleanup policy is a scheduled job you can use to remove tags from the Container Registry.
|
The cleanup policy is a scheduled job you can use to remove tags from the Container Registry.
|
||||||
For the project where it's defined, tags matching the regex pattern are removed.
|
For the project where it's defined, tags matching the regex pattern are removed.
|
||||||
|
|
|
@ -72,7 +72,7 @@ The following table lists project permissions available for each role:
|
||||||
| [Clusters](infrastructure/clusters/index.md):<br>View [pod logs](project/clusters/kubernetes_pod_logs.md) | | | ✓ | ✓ | ✓ |
|
| [Clusters](infrastructure/clusters/index.md):<br>View [pod logs](project/clusters/kubernetes_pod_logs.md) | | | ✓ | ✓ | ✓ |
|
||||||
| [Clusters](infrastructure/clusters/index.md):<br>View clusters | | | ✓ | ✓ | ✓ |
|
| [Clusters](infrastructure/clusters/index.md):<br>View clusters | | | ✓ | ✓ | ✓ |
|
||||||
| [Clusters](infrastructure/clusters/index.md):<br>Manage clusters | | | | ✓ | ✓ |
|
| [Clusters](infrastructure/clusters/index.md):<br>Manage clusters | | | | ✓ | ✓ |
|
||||||
| [Container Registry](packages/container_registry/index.md):<br>Create, edit, delete [cleanup policies](packages/container_registry/index.md#delete-images-by-using-a-cleanup-policy) | | | ✓ | ✓ | ✓ |
|
| [Container Registry](packages/container_registry/index.md):<br>Create, edit, delete [cleanup policies](packages/container_registry/index.md#delete-images-by-using-a-cleanup-policy) | | | | ✓ | ✓ |
|
||||||
| [Container Registry](packages/container_registry/index.md):<br>Push an image to the Container Registry | | | ✓ | ✓ | ✓ |
|
| [Container Registry](packages/container_registry/index.md):<br>Push an image to the Container Registry | | | ✓ | ✓ | ✓ |
|
||||||
| [Container Registry](packages/container_registry/index.md):<br>Pull an image from the Container Registry | ✓ (*20*) | ✓ (*20*) | ✓ | ✓ | ✓ |
|
| [Container Registry](packages/container_registry/index.md):<br>Pull an image from the Container Registry | ✓ (*20*) | ✓ (*20*) | ✓ | ✓ | ✓ |
|
||||||
| [Container Registry](packages/container_registry/index.md):<br>Remove a Container Registry image | | | ✓ | ✓ | ✓ |
|
| [Container Registry](packages/container_registry/index.md):<br>Remove a Container Registry image | | | ✓ | ✓ | ✓ |
|
||||||
|
|
|
@ -40,7 +40,6 @@ namespace :tw do
|
||||||
CodeOwnerRule.new('Infrastructure', '@sselhorn'),
|
CodeOwnerRule.new('Infrastructure', '@sselhorn'),
|
||||||
CodeOwnerRule.new('Integrations', '@kpaizee'),
|
CodeOwnerRule.new('Integrations', '@kpaizee'),
|
||||||
CodeOwnerRule.new('Knowledge', '@aqualls'),
|
CodeOwnerRule.new('Knowledge', '@aqualls'),
|
||||||
CodeOwnerRule.new('License', '@sselhorn'),
|
|
||||||
CodeOwnerRule.new('Memory', '@sselhorn'),
|
CodeOwnerRule.new('Memory', '@sselhorn'),
|
||||||
CodeOwnerRule.new('Monitor', '@msedlakjakubowski'),
|
CodeOwnerRule.new('Monitor', '@msedlakjakubowski'),
|
||||||
CodeOwnerRule.new('Observability', 'msedlakjakubowski'),
|
CodeOwnerRule.new('Observability', 'msedlakjakubowski'),
|
||||||
|
@ -53,8 +52,8 @@ namespace :tw do
|
||||||
CodeOwnerRule.new('Product Intelligence', '@claytoncornell'),
|
CodeOwnerRule.new('Product Intelligence', '@claytoncornell'),
|
||||||
CodeOwnerRule.new('Product Planning', '@msedlakjakubowski'),
|
CodeOwnerRule.new('Product Planning', '@msedlakjakubowski'),
|
||||||
CodeOwnerRule.new('Project Management', '@msedlakjakubowski'),
|
CodeOwnerRule.new('Project Management', '@msedlakjakubowski'),
|
||||||
CodeOwnerRule.new('Provision', '@sselhorn'),
|
CodeOwnerRule.new('Provision', '@fneill'),
|
||||||
CodeOwnerRule.new('Purchase', '@sselhorn'),
|
CodeOwnerRule.new('Purchase', '@fneill'),
|
||||||
CodeOwnerRule.new('Redirect', 'Redirect'),
|
CodeOwnerRule.new('Redirect', 'Redirect'),
|
||||||
CodeOwnerRule.new('Release', '@rdickenson'),
|
CodeOwnerRule.new('Release', '@rdickenson'),
|
||||||
CodeOwnerRule.new('Respond', '@msedlakjakubowski'),
|
CodeOwnerRule.new('Respond', '@msedlakjakubowski'),
|
||||||
|
@ -66,7 +65,7 @@ namespace :tw do
|
||||||
CodeOwnerRule.new('Style Guide', '@sselhorn'),
|
CodeOwnerRule.new('Style Guide', '@sselhorn'),
|
||||||
CodeOwnerRule.new('Testing', '@eread'),
|
CodeOwnerRule.new('Testing', '@eread'),
|
||||||
CodeOwnerRule.new('Threat Insights', '@claytoncornell'),
|
CodeOwnerRule.new('Threat Insights', '@claytoncornell'),
|
||||||
CodeOwnerRule.new('Utilization', '@sselhorn'),
|
CodeOwnerRule.new('Utilization', '@fneill'),
|
||||||
CodeOwnerRule.new('Vulnerability Research', '@claytoncornell'),
|
CodeOwnerRule.new('Vulnerability Research', '@claytoncornell'),
|
||||||
CodeOwnerRule.new('Workspace', '@fneill')
|
CodeOwnerRule.new('Workspace', '@fneill')
|
||||||
].freeze
|
].freeze
|
||||||
|
|
|
@ -6,13 +6,8 @@ RSpec.describe 'Filter issues', :js do
|
||||||
include FilteredSearchHelpers
|
include FilteredSearchHelpers
|
||||||
|
|
||||||
let(:project) { create(:project) }
|
let(:project) { create(:project) }
|
||||||
|
let(:user) { create(:user) }
|
||||||
# NOTE: The short name here is actually important
|
let(:user2) { create(:user) }
|
||||||
#
|
|
||||||
# When the name is longer, the filtered search input can end up scrolling
|
|
||||||
# horizontally, and PhantomJS can't handle it.
|
|
||||||
let(:user) { create(:user, name: 'Ann') }
|
|
||||||
let(:user2) { create(:user, name: 'jane') }
|
|
||||||
|
|
||||||
let!(:bug_label) { create(:label, project: project, title: 'bug') }
|
let!(:bug_label) { create(:label, project: project, title: 'bug') }
|
||||||
let!(:caps_sensitive_label) { create(:label, project: project, title: 'CaPs') }
|
let!(:caps_sensitive_label) { create(:label, project: project, title: 'CaPs') }
|
||||||
|
@ -24,6 +19,7 @@ RSpec.describe 'Filter issues', :js do
|
||||||
end
|
end
|
||||||
|
|
||||||
before do
|
before do
|
||||||
|
stub_feature_flags(vue_issues_list: true)
|
||||||
project.add_maintainer(user)
|
project.add_maintainer(user)
|
||||||
|
|
||||||
create(:issue, project: project, author: user2, title: "Bug report 1")
|
create(:issue, project: project, author: user2, title: "Bug report 1")
|
||||||
|
@ -64,31 +60,25 @@ RSpec.describe 'Filter issues', :js do
|
||||||
|
|
||||||
it 'filters by all available tokens' do
|
it 'filters by all available tokens' do
|
||||||
search_term = 'issue'
|
search_term = 'issue'
|
||||||
|
select_tokens 'Assignee', '=', user.username, 'Author', '=', user.username, 'Label', '=', caps_sensitive_label.title, 'Milestone', '=', milestone.title
|
||||||
|
send_keys search_term, :enter
|
||||||
|
|
||||||
input_filtered_search("assignee:=@#{user.username} author:=@#{user.username} label:=~#{caps_sensitive_label.title} milestone:=%#{milestone.title} #{search_term}")
|
expect_assignee_token(user.name)
|
||||||
|
expect_author_token(user.name)
|
||||||
wait_for_requests
|
expect_label_token(caps_sensitive_label.title)
|
||||||
|
expect_milestone_token(milestone.title)
|
||||||
expect_tokens([
|
|
||||||
assignee_token(user.name),
|
|
||||||
author_token(user.name),
|
|
||||||
label_token(caps_sensitive_label.title),
|
|
||||||
milestone_token(milestone.title)
|
|
||||||
])
|
|
||||||
expect_issues_list_count(1)
|
expect_issues_list_count(1)
|
||||||
expect_filtered_search_input(search_term)
|
expect_search_term(search_term)
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'filter issues by author' do
|
describe 'filter issues by author' do
|
||||||
context 'only author' do
|
context 'only author' do
|
||||||
it 'filters issues by searched author' do
|
it 'filters issues by searched author' do
|
||||||
input_filtered_search("author:=@#{user.username}")
|
select_tokens 'Author', '=', user.username, submit: true
|
||||||
|
|
||||||
wait_for_requests
|
expect_author_token(user.name)
|
||||||
|
|
||||||
expect_tokens([author_token(user.name)])
|
|
||||||
expect_issues_list_count(5)
|
expect_issues_list_count(5)
|
||||||
expect_filtered_search_input_empty
|
expect_empty_search_term
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -96,46 +86,30 @@ RSpec.describe 'Filter issues', :js do
|
||||||
describe 'filter issues by assignee' do
|
describe 'filter issues by assignee' do
|
||||||
context 'only assignee' do
|
context 'only assignee' do
|
||||||
it 'filters issues by searched assignee' do
|
it 'filters issues by searched assignee' do
|
||||||
input_filtered_search("assignee:=@#{user.username}")
|
select_tokens 'Assignee', '=', user.username, submit: true
|
||||||
|
|
||||||
wait_for_requests
|
expect_assignee_token(user.name)
|
||||||
|
|
||||||
expect_tokens([assignee_token(user.name)])
|
|
||||||
expect_issues_list_count(5)
|
expect_issues_list_count(5)
|
||||||
expect_filtered_search_input_empty
|
expect_empty_search_term
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'filters issues by no assignee' do
|
it 'filters issues by no assignee' do
|
||||||
input_filtered_search('assignee:=none')
|
select_tokens 'Assignee', '=', 'None', submit: true
|
||||||
|
|
||||||
expect_tokens([assignee_token('None')])
|
expect_assignee_token 'None'
|
||||||
expect_issues_list_count(3)
|
expect_issues_list_count(3)
|
||||||
expect_filtered_search_input_empty
|
expect_empty_search_term
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'filters issues by invalid assignee' do
|
it 'filters issues by invalid assignee' do
|
||||||
skip('to be tested, issue #26546')
|
skip('to be tested, issue #26546')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'filters issues by multiple assignees' do
|
|
||||||
create(:issue, project: project, author: user, assignees: [user2, user])
|
|
||||||
|
|
||||||
input_filtered_search("assignee:=@#{user.username} assignee:=@#{user2.username}")
|
|
||||||
|
|
||||||
expect_tokens([
|
|
||||||
assignee_token(user.name),
|
|
||||||
assignee_token(user2.name)
|
|
||||||
])
|
|
||||||
|
|
||||||
expect_issues_list_count(1)
|
|
||||||
expect_filtered_search_input_empty
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'filter by reviewer' do
|
describe 'filter by reviewer' do
|
||||||
it 'does not allow filtering by reviewer' do
|
it 'does not allow filtering by reviewer' do
|
||||||
find('.filtered-search').click
|
click_filtered_search_bar
|
||||||
|
|
||||||
expect(page).not_to have_button('Reviewer')
|
expect(page).not_to have_button('Reviewer')
|
||||||
end
|
end
|
||||||
|
@ -144,57 +118,53 @@ RSpec.describe 'Filter issues', :js do
|
||||||
describe 'filter issues by label' do
|
describe 'filter issues by label' do
|
||||||
context 'only label' do
|
context 'only label' do
|
||||||
it 'filters issues by searched label' do
|
it 'filters issues by searched label' do
|
||||||
input_filtered_search("label:=~#{bug_label.title}")
|
select_tokens 'Label', '=', bug_label.title, submit: true
|
||||||
|
|
||||||
expect_tokens([label_token(bug_label.title)])
|
expect_label_token(bug_label.title)
|
||||||
expect_issues_list_count(2)
|
expect_issues_list_count(2)
|
||||||
expect_filtered_search_input_empty
|
expect_empty_search_term
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'filters issues not containing searched label' do
|
it 'filters issues not containing searched label' do
|
||||||
input_filtered_search("label:!=~#{bug_label.title}")
|
select_tokens 'Label', '!=', bug_label.title, submit: true
|
||||||
|
|
||||||
expect_tokens([label_token(bug_label.title)])
|
expect_negated_label_token(bug_label.title)
|
||||||
expect_issues_list_count(6)
|
expect_issues_list_count(6)
|
||||||
expect_filtered_search_input_empty
|
expect_empty_search_term
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'filters issues by any label' do
|
it 'filters issues by any label' do
|
||||||
input_filtered_search('label:=any')
|
select_tokens 'Label', '=', 'Any', submit: true
|
||||||
|
|
||||||
expect_tokens([label_token('Any', false)])
|
expect_label_token 'Any'
|
||||||
expect_issues_list_count(4)
|
expect_issues_list_count(4)
|
||||||
expect_filtered_search_input_empty
|
expect_empty_search_term
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'filters issues by no label' do
|
it 'filters issues by no label' do
|
||||||
input_filtered_search('label:=none')
|
select_tokens 'Label', '=', 'None', submit: true
|
||||||
|
|
||||||
expect_tokens([label_token('None', false)])
|
expect_label_token 'None'
|
||||||
expect_issues_list_count(4)
|
expect_issues_list_count(4)
|
||||||
expect_filtered_search_input_empty
|
expect_empty_search_term
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'filters issues by multiple labels' do
|
it 'filters issues by multiple labels' do
|
||||||
input_filtered_search("label:=~#{bug_label.title} label:=~#{caps_sensitive_label.title}")
|
select_tokens 'Label', '=', bug_label.title, 'Label', '=', caps_sensitive_label.title, submit: true
|
||||||
|
|
||||||
expect_tokens([
|
expect_label_token(bug_label.title)
|
||||||
label_token(bug_label.title),
|
expect_label_token(caps_sensitive_label.title)
|
||||||
label_token(caps_sensitive_label.title)
|
|
||||||
])
|
|
||||||
expect_issues_list_count(1)
|
expect_issues_list_count(1)
|
||||||
expect_filtered_search_input_empty
|
expect_empty_search_term
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'filters issues by multiple labels with not operator' do
|
it 'filters issues by multiple labels with not operator' do
|
||||||
input_filtered_search("label:!=~#{bug_label.title} label:=~#{caps_sensitive_label.title}")
|
select_tokens 'Label', '!=', bug_label.title, 'Label', '=', caps_sensitive_label.title, submit: true
|
||||||
|
|
||||||
expect_tokens([
|
expect_negated_label_token(bug_label.title)
|
||||||
label_token(bug_label.title),
|
expect_label_token(caps_sensitive_label.title)
|
||||||
label_token(caps_sensitive_label.title)
|
|
||||||
])
|
|
||||||
expect_issues_list_count(1)
|
expect_issues_list_count(1)
|
||||||
expect_filtered_search_input_empty
|
expect_empty_search_term
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'filters issues by label containing special characters' do
|
it 'filters issues by label containing special characters' do
|
||||||
|
@ -202,11 +172,11 @@ RSpec.describe 'Filter issues', :js do
|
||||||
special_issue = create(:issue, title: "Issue with special character label", project: project)
|
special_issue = create(:issue, title: "Issue with special character label", project: project)
|
||||||
special_issue.labels << special_label
|
special_issue.labels << special_label
|
||||||
|
|
||||||
input_filtered_search("label:=~#{special_label.title}")
|
select_tokens 'Label', '=', special_label.title, submit: true
|
||||||
|
|
||||||
expect_tokens([label_token(special_label.title)])
|
expect_label_token(special_label.title)
|
||||||
expect_issues_list_count(1)
|
expect_issues_list_count(1)
|
||||||
expect_filtered_search_input_empty
|
expect_empty_search_term
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'filters issues by label not containing special characters' do
|
it 'filters issues by label not containing special characters' do
|
||||||
|
@ -214,21 +184,21 @@ RSpec.describe 'Filter issues', :js do
|
||||||
special_issue = create(:issue, title: "Issue with special character label", project: project)
|
special_issue = create(:issue, title: "Issue with special character label", project: project)
|
||||||
special_issue.labels << special_label
|
special_issue.labels << special_label
|
||||||
|
|
||||||
input_filtered_search("label:!=~#{special_label.title}")
|
select_tokens 'Label', '!=', special_label.title, submit: true
|
||||||
|
|
||||||
expect_tokens([label_token(special_label.title)])
|
expect_negated_label_token(special_label.title)
|
||||||
expect_issues_list_count(8)
|
expect_issues_list_count(8)
|
||||||
expect_filtered_search_input_empty
|
expect_empty_search_term
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not show issues for unused labels' do
|
it 'does not show issues for unused labels' do
|
||||||
new_label = create(:label, project: project, title: 'new_label')
|
new_label = create(:label, project: project, title: 'new_label')
|
||||||
|
|
||||||
input_filtered_search("label:=~#{new_label.title}")
|
select_tokens 'Label', '=', new_label.title, submit: true
|
||||||
|
|
||||||
expect_tokens([label_token(new_label.title)])
|
expect_label_token(new_label.title)
|
||||||
expect_no_issues_list
|
expect_no_issues_list
|
||||||
expect_filtered_search_input_empty
|
expect_empty_search_term
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -238,31 +208,28 @@ RSpec.describe 'Filter issues', :js do
|
||||||
special_multiple_issue = create(:issue, title: "Issue with special character multiple words label", project: project)
|
special_multiple_issue = create(:issue, title: "Issue with special character multiple words label", project: project)
|
||||||
special_multiple_issue.labels << special_multiple_label
|
special_multiple_issue.labels << special_multiple_label
|
||||||
|
|
||||||
input_filtered_search("label:=~'#{special_multiple_label.title}'")
|
select_tokens 'Label', '=', special_multiple_label.title, submit: true
|
||||||
|
|
||||||
# Check for search results (which makes sure that the page has changed)
|
# Check for search results (which makes sure that the page has changed)
|
||||||
expect_issues_list_count(1)
|
expect_issues_list_count(1)
|
||||||
|
expect_label_token(special_multiple_label.title)
|
||||||
# filtered search defaults quotations to double quotes
|
expect_empty_search_term
|
||||||
expect_tokens([label_token("\"#{special_multiple_label.title}\"")])
|
|
||||||
|
|
||||||
expect_filtered_search_input_empty
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'single quotes' do
|
it 'single quotes' do
|
||||||
input_filtered_search("label:=~'#{multiple_words_label.title}'")
|
select_tokens 'Label', '=', multiple_words_label.title, submit: true
|
||||||
|
|
||||||
expect_issues_list_count(1)
|
expect_issues_list_count(1)
|
||||||
expect_tokens([label_token("\"#{multiple_words_label.title}\"")])
|
expect_label_token(multiple_words_label.title)
|
||||||
expect_filtered_search_input_empty
|
expect_empty_search_term
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'double quotes' do
|
it 'double quotes' do
|
||||||
input_filtered_search("label:=~\"#{multiple_words_label.title}\"")
|
select_tokens 'Label', '=', multiple_words_label.title, submit: true
|
||||||
|
|
||||||
expect_tokens([label_token("\"#{multiple_words_label.title}\"")])
|
expect_label_token(multiple_words_label.title)
|
||||||
expect_issues_list_count(1)
|
expect_issues_list_count(1)
|
||||||
expect_filtered_search_input_empty
|
expect_empty_search_term
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'single quotes containing double quotes' do
|
it 'single quotes containing double quotes' do
|
||||||
|
@ -270,11 +237,11 @@ RSpec.describe 'Filter issues', :js do
|
||||||
double_quotes_label_issue = create(:issue, title: "Issue with double quotes label", project: project)
|
double_quotes_label_issue = create(:issue, title: "Issue with double quotes label", project: project)
|
||||||
double_quotes_label_issue.labels << double_quotes_label
|
double_quotes_label_issue.labels << double_quotes_label
|
||||||
|
|
||||||
input_filtered_search("label:=~'#{double_quotes_label.title}'")
|
select_tokens 'Label', '=', double_quotes_label.title, submit: true
|
||||||
|
|
||||||
expect_tokens([label_token("'#{double_quotes_label.title}'")])
|
expect_label_token(double_quotes_label.title)
|
||||||
expect_issues_list_count(1)
|
expect_issues_list_count(1)
|
||||||
expect_filtered_search_input_empty
|
expect_empty_search_term
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'double quotes containing single quotes' do
|
it 'double quotes containing single quotes' do
|
||||||
|
@ -282,49 +249,41 @@ RSpec.describe 'Filter issues', :js do
|
||||||
single_quotes_label_issue = create(:issue, title: "Issue with single quotes label", project: project)
|
single_quotes_label_issue = create(:issue, title: "Issue with single quotes label", project: project)
|
||||||
single_quotes_label_issue.labels << single_quotes_label
|
single_quotes_label_issue.labels << single_quotes_label
|
||||||
|
|
||||||
input_filtered_search("label:=~\"#{single_quotes_label.title}\"")
|
select_tokens 'Label', '=', single_quotes_label.title, submit: true
|
||||||
|
|
||||||
expect_tokens([label_token("\"#{single_quotes_label.title}\"")])
|
expect_label_token(single_quotes_label.title)
|
||||||
expect_issues_list_count(1)
|
expect_issues_list_count(1)
|
||||||
expect_filtered_search_input_empty
|
expect_empty_search_term
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'multiple labels with other filters' do
|
context 'multiple labels with other filters' do
|
||||||
it 'filters issues by searched label, label2, author, assignee, milestone and text' do
|
it 'filters issues by searched label, label2, author, assignee, milestone and text' do
|
||||||
search_term = 'bug'
|
search_term = 'bug'
|
||||||
|
select_tokens 'Label', '=', bug_label.title, 'Label', '=', caps_sensitive_label.title, 'Author', '=', user.username, 'Assignee', '=', user.username, 'Milestone', '=', milestone.title
|
||||||
|
send_keys search_term, :enter
|
||||||
|
|
||||||
input_filtered_search("label:=~#{bug_label.title} label:=~#{caps_sensitive_label.title} author:=@#{user.username} assignee:=@#{user.username} milestone:=%#{milestone.title} #{search_term}")
|
expect_label_token(bug_label.title)
|
||||||
|
expect_label_token(caps_sensitive_label.title)
|
||||||
wait_for_requests
|
expect_author_token(user.name)
|
||||||
|
expect_assignee_token(user.name)
|
||||||
expect_tokens([
|
expect_milestone_token(milestone.title)
|
||||||
label_token(bug_label.title),
|
|
||||||
label_token(caps_sensitive_label.title),
|
|
||||||
author_token(user.name),
|
|
||||||
assignee_token(user.name),
|
|
||||||
milestone_token(milestone.title)
|
|
||||||
])
|
|
||||||
expect_issues_list_count(1)
|
expect_issues_list_count(1)
|
||||||
expect_filtered_search_input(search_term)
|
expect_search_term(search_term)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'filters issues by searched label, label2, author, assignee, not included in a milestone' do
|
it 'filters issues by searched label, label2, author, assignee, not included in a milestone' do
|
||||||
search_term = 'bug'
|
search_term = 'bug'
|
||||||
|
select_tokens 'Label', '=', bug_label.title, 'Label', '=', caps_sensitive_label.title, 'Author', '=', user.username, 'Assignee', '=', user.username, 'Milestone', '!=', milestone.title
|
||||||
|
send_keys search_term, :enter
|
||||||
|
|
||||||
input_filtered_search("label:=~#{bug_label.title} label:=~#{caps_sensitive_label.title} author:=@#{user.username} assignee:=@#{user.username} milestone:!=%#{milestone.title} #{search_term}")
|
expect_label_token(bug_label.title)
|
||||||
|
expect_label_token(caps_sensitive_label.title)
|
||||||
wait_for_requests
|
expect_author_token(user.name)
|
||||||
|
expect_assignee_token(user.name)
|
||||||
expect_tokens([
|
expect_negated_milestone_token(milestone.title)
|
||||||
label_token(bug_label.title),
|
|
||||||
label_token(caps_sensitive_label.title),
|
|
||||||
author_token(user.name),
|
|
||||||
assignee_token(user.name),
|
|
||||||
milestone_token(milestone.title, false, '!=')
|
|
||||||
])
|
|
||||||
expect_issues_list_count(0)
|
expect_issues_list_count(0)
|
||||||
expect_filtered_search_input(search_term)
|
expect_search_term(search_term)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -333,8 +292,8 @@ RSpec.describe 'Filter issues', :js do
|
||||||
click_link multiple_words_label.title
|
click_link multiple_words_label.title
|
||||||
|
|
||||||
expect_issues_list_count(1)
|
expect_issues_list_count(1)
|
||||||
expect_tokens([label_token("\"#{multiple_words_label.title}\"")])
|
expect_label_token(multiple_words_label.title)
|
||||||
expect_filtered_search_input_empty
|
expect_empty_search_term
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -342,19 +301,19 @@ RSpec.describe 'Filter issues', :js do
|
||||||
describe 'filter issues by milestone' do
|
describe 'filter issues by milestone' do
|
||||||
context 'only milestone' do
|
context 'only milestone' do
|
||||||
it 'filters issues by searched milestone' do
|
it 'filters issues by searched milestone' do
|
||||||
input_filtered_search("milestone:=%#{milestone.title}")
|
select_tokens 'Milestone', '=', milestone.title, submit: true
|
||||||
|
|
||||||
expect_tokens([milestone_token(milestone.title)])
|
expect_milestone_token(milestone.title)
|
||||||
expect_issues_list_count(5)
|
expect_issues_list_count(5)
|
||||||
expect_filtered_search_input_empty
|
expect_empty_search_term
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'filters issues by no milestone' do
|
it 'filters issues by no milestone' do
|
||||||
input_filtered_search("milestone:=none")
|
select_tokens 'Milestone', '=', 'None', submit: true
|
||||||
|
|
||||||
expect_tokens([milestone_token('None', false)])
|
expect_milestone_token 'None'
|
||||||
expect_issues_list_count(3)
|
expect_issues_list_count(3)
|
||||||
expect_filtered_search_input_empty
|
expect_empty_search_term
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'filters issues by upcoming milestones' do
|
it 'filters issues by upcoming milestones' do
|
||||||
|
@ -362,11 +321,11 @@ RSpec.describe 'Filter issues', :js do
|
||||||
create(:issue, project: project, milestone: future_milestone, author: user)
|
create(:issue, project: project, milestone: future_milestone, author: user)
|
||||||
end
|
end
|
||||||
|
|
||||||
input_filtered_search("milestone:=upcoming")
|
select_tokens 'Milestone', '=', 'Upcoming', submit: true
|
||||||
|
|
||||||
expect_tokens([milestone_token('Upcoming', false)])
|
expect_milestone_token 'Upcoming'
|
||||||
expect_issues_list_count(1)
|
expect_issues_list_count(1)
|
||||||
expect_filtered_search_input_empty
|
expect_empty_search_term
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'filters issues by negation of upcoming milestones' do
|
it 'filters issues by negation of upcoming milestones' do
|
||||||
|
@ -378,72 +337,72 @@ RSpec.describe 'Filter issues', :js do
|
||||||
create(:issue, project: project, milestone: past_milestone, author: user)
|
create(:issue, project: project, milestone: past_milestone, author: user)
|
||||||
end
|
end
|
||||||
|
|
||||||
input_filtered_search("milestone:!=upcoming")
|
select_tokens 'Milestone', '!=', 'Upcoming', submit: true
|
||||||
|
|
||||||
expect_tokens([milestone_token('Upcoming', false, '!=')])
|
expect_negated_milestone_token 'Upcoming'
|
||||||
expect_issues_list_count(1)
|
expect_issues_list_count(1)
|
||||||
expect_filtered_search_input_empty
|
expect_empty_search_term
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'filters issues by started milestones' do
|
it 'filters issues by started milestones' do
|
||||||
input_filtered_search("milestone:=started")
|
select_tokens 'Milestone', '=', 'Started', submit: true
|
||||||
|
|
||||||
expect_tokens([milestone_token('Started', false)])
|
expect_milestone_token 'Started'
|
||||||
expect_issues_list_count(5)
|
expect_issues_list_count(5)
|
||||||
expect_filtered_search_input_empty
|
expect_empty_search_term
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'filters issues by negation of started milestones' do
|
it 'filters issues by negation of started milestones' do
|
||||||
milestone2 = create(:milestone, title: "9", project: project, start_date: 2.weeks.from_now)
|
milestone2 = create(:milestone, title: "9", project: project, start_date: 2.weeks.from_now)
|
||||||
create(:issue, project: project, author: user, title: "something else", milestone: milestone2)
|
create(:issue, project: project, author: user, title: "something else", milestone: milestone2)
|
||||||
|
|
||||||
input_filtered_search("milestone:!=started")
|
select_tokens 'Milestone', '!=', 'Started', submit: true
|
||||||
|
|
||||||
expect_tokens([milestone_token('Started', false, '!=')])
|
expect_negated_milestone_token 'Started'
|
||||||
expect_issues_list_count(1)
|
expect_issues_list_count(1)
|
||||||
expect_filtered_search_input_empty
|
expect_empty_search_term
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'filters issues by milestone containing special characters' do
|
it 'filters issues by milestone containing special characters' do
|
||||||
special_milestone = create(:milestone, title: '!@\#{$%^&*()}', project: project)
|
special_milestone = create(:milestone, title: '!@\#{$%^&*()}', project: project)
|
||||||
create(:issue, project: project, milestone: special_milestone)
|
create(:issue, project: project, milestone: special_milestone)
|
||||||
|
|
||||||
input_filtered_search("milestone:=%#{special_milestone.title}")
|
select_tokens 'Milestone', '=', special_milestone.title, submit: true
|
||||||
|
|
||||||
expect_tokens([milestone_token(special_milestone.title)])
|
expect_milestone_token(special_milestone.title)
|
||||||
expect_issues_list_count(1)
|
expect_issues_list_count(1)
|
||||||
expect_filtered_search_input_empty
|
expect_empty_search_term
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'filters issues by milestone not containing special characters' do
|
it 'filters issues by milestone not containing special characters' do
|
||||||
special_milestone = create(:milestone, title: '!@\#{$%^&*()}', project: project)
|
special_milestone = create(:milestone, title: '!@\#{$%^&*()}', project: project)
|
||||||
create(:issue, project: project, milestone: special_milestone)
|
create(:issue, project: project, milestone: special_milestone)
|
||||||
|
|
||||||
input_filtered_search("milestone:!=%#{special_milestone.title}")
|
select_tokens 'Milestone', '!=', special_milestone.title, submit: true
|
||||||
|
|
||||||
expect_tokens([milestone_token(special_milestone.title, false, '!=')])
|
expect_negated_milestone_token(special_milestone.title)
|
||||||
expect_issues_list_count(8)
|
expect_issues_list_count(8)
|
||||||
expect_filtered_search_input_empty
|
expect_empty_search_term
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not show issues for unused milestones' do
|
it 'does not show issues for unused milestones' do
|
||||||
new_milestone = create(:milestone, title: 'new', project: project)
|
new_milestone = create(:milestone, title: 'new', project: project)
|
||||||
|
|
||||||
input_filtered_search("milestone:=%#{new_milestone.title}")
|
select_tokens 'Milestone', '=', new_milestone.title, submit: true
|
||||||
|
|
||||||
expect_tokens([milestone_token(new_milestone.title)])
|
expect_milestone_token(new_milestone.title)
|
||||||
expect_no_issues_list
|
expect_no_issues_list
|
||||||
expect_filtered_search_input_empty
|
expect_empty_search_term
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'show issues for unused milestones' do
|
it 'show issues for unused milestones' do
|
||||||
new_milestone = create(:milestone, title: 'new', project: project)
|
new_milestone = create(:milestone, title: 'new', project: project)
|
||||||
|
|
||||||
input_filtered_search("milestone:!=%#{new_milestone.title}")
|
select_tokens 'Milestone', '!=', new_milestone.title, submit: true
|
||||||
|
|
||||||
expect_tokens([milestone_token(new_milestone.title, false, '!=')])
|
expect_negated_milestone_token(new_milestone.title)
|
||||||
expect_issues_list_count(8)
|
expect_issues_list_count(8)
|
||||||
expect_filtered_search_input_empty
|
expect_empty_search_term
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -452,47 +411,47 @@ RSpec.describe 'Filter issues', :js do
|
||||||
context 'only text' do
|
context 'only text' do
|
||||||
it 'filters issues by searched text' do
|
it 'filters issues by searched text' do
|
||||||
search = 'Bug'
|
search = 'Bug'
|
||||||
input_filtered_search(search)
|
submit_search_term(search)
|
||||||
|
|
||||||
expect_issues_list_count(4)
|
expect_issues_list_count(4)
|
||||||
expect_filtered_search_input(search)
|
expect_search_term(search)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'filters issues by multiple searched text' do
|
it 'filters issues by multiple searched text' do
|
||||||
search = 'Bug report'
|
search = 'Bug report'
|
||||||
input_filtered_search(search)
|
submit_search_term(search)
|
||||||
|
|
||||||
expect_issues_list_count(3)
|
expect_issues_list_count(3)
|
||||||
expect_filtered_search_input(search)
|
expect_search_term(search)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'filters issues by case insensitive searched text' do
|
it 'filters issues by case insensitive searched text' do
|
||||||
search = 'bug report'
|
search = 'bug report'
|
||||||
input_filtered_search(search)
|
submit_search_term(search)
|
||||||
|
|
||||||
expect_issues_list_count(3)
|
expect_issues_list_count(3)
|
||||||
expect_filtered_search_input(search)
|
expect_search_term(search)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'filters issues by searched text containing single quotes' do
|
it 'filters issues by searched text containing single quotes' do
|
||||||
issue = create(:issue, project: project, author: user, title: "issue with 'single quotes'")
|
issue = create(:issue, project: project, author: user, title: "issue with 'single quotes'")
|
||||||
|
|
||||||
search = "'single quotes'"
|
search = 'single quotes'
|
||||||
input_filtered_search(search)
|
submit_search_term "'#{search}'"
|
||||||
|
|
||||||
expect_issues_list_count(1)
|
expect_issues_list_count(1)
|
||||||
expect_filtered_search_input(search)
|
expect_search_term(search)
|
||||||
expect(page).to have_content(issue.title)
|
expect(page).to have_content(issue.title)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'filters issues by searched text containing double quotes' do
|
it 'filters issues by searched text containing double quotes' do
|
||||||
issue = create(:issue, project: project, author: user, title: "issue with \"double quotes\"")
|
issue = create(:issue, project: project, author: user, title: "issue with \"double quotes\"")
|
||||||
|
|
||||||
search = '"double quotes"'
|
search = 'double quotes'
|
||||||
input_filtered_search(search)
|
submit_search_term "\"#{search}\""
|
||||||
|
|
||||||
expect_issues_list_count(1)
|
expect_issues_list_count(1)
|
||||||
expect_filtered_search_input(search)
|
expect_search_term(search)
|
||||||
expect(page).to have_content(issue.title)
|
expect(page).to have_content(issue.title)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -502,36 +461,43 @@ RSpec.describe 'Filter issues', :js do
|
||||||
issue = create(:issue, project: project, author: user, title: "issue with !@\#{$%^&*()-+")
|
issue = create(:issue, project: project, author: user, title: "issue with !@\#{$%^&*()-+")
|
||||||
|
|
||||||
search = '!@#{$%^&*()-+'
|
search = '!@#{$%^&*()-+'
|
||||||
input_filtered_search(search)
|
submit_search_term(search)
|
||||||
|
|
||||||
expect_issues_list_count(1)
|
expect_issues_list_count(1)
|
||||||
expect_filtered_search_input(search)
|
expect_search_term(search)
|
||||||
expect(page).to have_content(issue.title)
|
expect(page).to have_content(issue.title)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not show any issues' do
|
it 'does not show any issues' do
|
||||||
search = 'testing'
|
search = 'testing'
|
||||||
input_filtered_search(search)
|
submit_search_term(search)
|
||||||
|
|
||||||
expect_no_issues_list
|
expect_no_issues_list
|
||||||
expect_filtered_search_input(search)
|
expect_search_term(search)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'filters issues by issue reference' do
|
it 'filters issues by issue reference' do
|
||||||
search = '#1'
|
search = '#1'
|
||||||
input_filtered_search(search)
|
submit_search_term(search)
|
||||||
|
|
||||||
expect_issues_list_count(1)
|
expect_issues_list_count(1)
|
||||||
expect_filtered_search_input(search)
|
expect_search_term(search)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'searched text with other filters' do
|
context 'searched text with other filters' do
|
||||||
it 'filters issues by searched text, author, text, assignee, text, label1, text, label2, text, milestone and text' do
|
it 'filters issues by searched text, author, text, assignee, text, label1, text, label2, text, milestone and text' do
|
||||||
input_filtered_search("bug author:=@#{user.username} report label:=~#{bug_label.title} label:=~#{caps_sensitive_label.title} milestone:=%#{milestone.title} foo")
|
click_filtered_search_bar
|
||||||
|
send_keys 'bug '
|
||||||
|
select_tokens 'Author', '=', user.username
|
||||||
|
send_keys 'report '
|
||||||
|
select_tokens 'Label', '=', bug_label.title
|
||||||
|
select_tokens 'Label', '=', caps_sensitive_label.title
|
||||||
|
select_tokens 'Milestone', '=', milestone.title
|
||||||
|
send_keys 'foo', :enter
|
||||||
|
|
||||||
expect_issues_list_count(1)
|
expect_issues_list_count(1)
|
||||||
expect_filtered_search_input('bug report foo')
|
expect_search_term('bug report foo')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -549,17 +515,11 @@ RSpec.describe 'Filter issues', :js do
|
||||||
author: user,
|
author: user,
|
||||||
created_at: 5.days.ago)
|
created_at: 5.days.ago)
|
||||||
|
|
||||||
input_filtered_search('days ago')
|
submit_search_term 'days ago'
|
||||||
|
|
||||||
expect_issues_list_count(2)
|
expect_issues_list_count(2)
|
||||||
|
expect(page).to have_button 'Created date'
|
||||||
sort_toggle = find('.filter-dropdown-container .dropdown')
|
expect(page).to have_css('.issue:first-of-type .issue-title', text: new_issue.title)
|
||||||
sort_toggle.click
|
|
||||||
|
|
||||||
find('.filter-dropdown-container .dropdown-menu li a', text: 'Created date').click
|
|
||||||
wait_for_requests
|
|
||||||
|
|
||||||
expect(find('.issues-list .issue:first-of-type .issue-title-text a')).to have_content(new_issue.title)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -568,7 +528,7 @@ RSpec.describe 'Filter issues', :js do
|
||||||
let!(:closed_issue) { create(:issue, :closed, project: project, title: 'closed bug') }
|
let!(:closed_issue) { create(:issue, :closed, project: project, title: 'closed bug') }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
input_filtered_search('bug')
|
submit_search_term 'bug'
|
||||||
|
|
||||||
# This ensures that the search is performed
|
# This ensures that the search is performed
|
||||||
expect_issues_list_count(4, 1)
|
expect_issues_list_count(4, 1)
|
||||||
|
@ -599,19 +559,17 @@ RSpec.describe 'Filter issues', :js do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'milestone dropdown loads milestones' do
|
it 'milestone dropdown loads milestones' do
|
||||||
input_filtered_search("milestone:=", submit: false)
|
select_tokens 'Milestone', '='
|
||||||
|
|
||||||
within('#js-dropdown-milestone') do
|
# Expect None, Any, Upcoming, Started, 8
|
||||||
expect(page).to have_selector('.filter-dropdown .filter-dropdown-item', count: 1)
|
expect_suggestion_count 5
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'label dropdown load labels' do
|
it 'label dropdown load labels' do
|
||||||
input_filtered_search("label:=", submit: false)
|
select_tokens 'Label', '='
|
||||||
|
|
||||||
within('#js-dropdown-label') do
|
# Dropdown shows None, Any, and 3 labels
|
||||||
expect(page).to have_selector('.filter-dropdown .filter-dropdown-item', count: 3)
|
expect_suggestion_count 5
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,7 +11,7 @@ RSpec.describe Mutations::ContainerExpirationPolicies::Update do
|
||||||
let(:container_expiration_policy) { project.container_expiration_policy }
|
let(:container_expiration_policy) { project.container_expiration_policy }
|
||||||
let(:params) { { project_path: project.full_path, cadence: '3month', keep_n: 100, older_than: '14d' } }
|
let(:params) { { project_path: project.full_path, cadence: '3month', keep_n: 100, older_than: '14d' } }
|
||||||
|
|
||||||
specify { expect(described_class).to require_graphql_authorizations(:destroy_container_image) }
|
specify { expect(described_class).to require_graphql_authorizations(:admin_container_image) }
|
||||||
|
|
||||||
describe '#resolve' do
|
describe '#resolve' do
|
||||||
subject { described_class.new(object: project, context: { current_user: user }, field: nil).resolve(**params) }
|
subject { described_class.new(object: project, context: { current_user: user }, field: nil).resolve(**params) }
|
||||||
|
@ -76,7 +76,7 @@ RSpec.describe Mutations::ContainerExpirationPolicies::Update do
|
||||||
context 'with existing container expiration policy' do
|
context 'with existing container expiration policy' do
|
||||||
where(:user_role, :shared_examples_name) do
|
where(:user_role, :shared_examples_name) do
|
||||||
:maintainer | 'updating the container expiration policy'
|
:maintainer | 'updating the container expiration policy'
|
||||||
:developer | 'updating the container expiration policy'
|
:developer | 'denying access to container expiration policy'
|
||||||
:reporter | 'denying access to container expiration policy'
|
:reporter | 'denying access to container expiration policy'
|
||||||
:guest | 'denying access to container expiration policy'
|
:guest | 'denying access to container expiration policy'
|
||||||
:anonymous | 'denying access to container expiration policy'
|
:anonymous | 'denying access to container expiration policy'
|
||||||
|
@ -96,7 +96,7 @@ RSpec.describe Mutations::ContainerExpirationPolicies::Update do
|
||||||
|
|
||||||
where(:user_role, :shared_examples_name) do
|
where(:user_role, :shared_examples_name) do
|
||||||
:maintainer | 'creating the container expiration policy'
|
:maintainer | 'creating the container expiration policy'
|
||||||
:developer | 'creating the container expiration policy'
|
:developer | 'denying access to container expiration policy'
|
||||||
:reporter | 'denying access to container expiration policy'
|
:reporter | 'denying access to container expiration policy'
|
||||||
:guest | 'denying access to container expiration policy'
|
:guest | 'denying access to container expiration policy'
|
||||||
:anonymous | 'denying access to container expiration policy'
|
:anonymous | 'denying access to container expiration policy'
|
||||||
|
|
|
@ -26,7 +26,7 @@ RSpec.describe Mutations::Issues::SetDueDate do
|
||||||
|
|
||||||
it 'returns the issue with updated due date', :aggregate_failures do
|
it 'returns the issue with updated due date', :aggregate_failures do
|
||||||
expect(mutated_issue).to eq(issue)
|
expect(mutated_issue).to eq(issue)
|
||||||
expect(mutated_issue.due_date).to eq(Date.today + 2.days)
|
expect(mutated_issue.due_date).to eq(due_date.to_date)
|
||||||
expect(subject[:errors]).to be_empty
|
expect(subject[:errors]).to be_empty
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ RSpec.describe GitlabSchema.types['ContainerExpirationPolicy'] do
|
||||||
|
|
||||||
specify { expect(described_class.description).to eq('A tag expiration policy designed to keep only the images that matter most') }
|
specify { expect(described_class.description).to eq('A tag expiration policy designed to keep only the images that matter most') }
|
||||||
|
|
||||||
specify { expect(described_class).to require_graphql_authorizations(:destroy_container_image) }
|
specify { expect(described_class).to require_graphql_authorizations(:admin_container_image) }
|
||||||
|
|
||||||
describe 'older_than field' do
|
describe 'older_than field' do
|
||||||
subject { described_class.fields['olderThan'] }
|
subject { described_class.fields['olderThan'] }
|
||||||
|
|
|
@ -12,7 +12,7 @@ RSpec.describe ::Types::RangeInputType do
|
||||||
input = { start: 1, end: 10 }
|
input = { start: 1, end: 10 }
|
||||||
output = { start: 1, end: 10 }
|
output = { start: 1, end: 10 }
|
||||||
|
|
||||||
expect(type.coerce_isolated_input(input)).to eq(output)
|
expect(type.coerce_isolated_input(input).to_h).to eq(output)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'rejects inverted ranges' do
|
it 'rejects inverted ranges' do
|
||||||
|
|
|
@ -7,7 +7,7 @@ RSpec.describe GitlabSchema.types['Timeframe'] do
|
||||||
let(:output) { { start: Date.parse(input[:start]), end: Date.parse(input[:end]) } }
|
let(:output) { { start: Date.parse(input[:start]), end: Date.parse(input[:end]) } }
|
||||||
|
|
||||||
it 'coerces ISO-dates into Time objects' do
|
it 'coerces ISO-dates into Time objects' do
|
||||||
expect(described_class.coerce_isolated_input(input)).to eq(output)
|
expect(described_class.coerce_isolated_input(input).to_h).to eq(output)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'rejects invalid input' do
|
it 'rejects invalid input' do
|
||||||
|
@ -20,7 +20,7 @@ RSpec.describe GitlabSchema.types['Timeframe'] do
|
||||||
it 'accepts times as input' do
|
it 'accepts times as input' do
|
||||||
with_time = input.merge(start: '2018-06-04T13:48:14Z')
|
with_time = input.merge(start: '2018-06-04T13:48:14Z')
|
||||||
|
|
||||||
expect(described_class.coerce_isolated_input(with_time)).to eq(output)
|
expect(described_class.coerce_isolated_input(with_time).to_h).to eq(output)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'requires both ends of the range' do
|
it 'requires both ends of the range' do
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
RSpec.describe ContainerExpirationPolicyPolicy do
|
||||||
|
using RSpec::Parameterized::TableSyntax
|
||||||
|
|
||||||
|
let_it_be(:user) { create(:user) }
|
||||||
|
let_it_be(:project, reload: true) { create(:project) }
|
||||||
|
|
||||||
|
subject { described_class.new(user, project.container_expiration_policy) }
|
||||||
|
|
||||||
|
where(:user_type, :allowed_to_destroy_container_image) do
|
||||||
|
:anonymous | false
|
||||||
|
:guest | false
|
||||||
|
:developer | false
|
||||||
|
:maintainer | true
|
||||||
|
end
|
||||||
|
|
||||||
|
with_them do
|
||||||
|
context "for user type #{params[:user_type]}" do
|
||||||
|
before do
|
||||||
|
project.public_send("add_#{user_type}", user) unless user_type == :anonymous
|
||||||
|
end
|
||||||
|
|
||||||
|
if params[:allowed_to_destroy_container_image]
|
||||||
|
it { is_expected.to be_allowed(:admin_container_image) }
|
||||||
|
else
|
||||||
|
it { is_expected.not_to be_allowed(:admin_container_image) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -135,7 +135,7 @@ RSpec.describe 'Updating the container expiration policy' do
|
||||||
context 'with existing container expiration policy' do
|
context 'with existing container expiration policy' do
|
||||||
where(:user_role, :shared_examples_name) do
|
where(:user_role, :shared_examples_name) do
|
||||||
:maintainer | 'accepting the mutation request updating the container expiration policy'
|
:maintainer | 'accepting the mutation request updating the container expiration policy'
|
||||||
:developer | 'accepting the mutation request updating the container expiration policy'
|
:developer | 'denying the mutation request'
|
||||||
:reporter | 'denying the mutation request'
|
:reporter | 'denying the mutation request'
|
||||||
:guest | 'denying the mutation request'
|
:guest | 'denying the mutation request'
|
||||||
:anonymous | 'denying the mutation request'
|
:anonymous | 'denying the mutation request'
|
||||||
|
@ -155,7 +155,7 @@ RSpec.describe 'Updating the container expiration policy' do
|
||||||
|
|
||||||
where(:user_role, :shared_examples_name) do
|
where(:user_role, :shared_examples_name) do
|
||||||
:maintainer | 'accepting the mutation request creating the container expiration policy'
|
:maintainer | 'accepting the mutation request creating the container expiration policy'
|
||||||
:developer | 'accepting the mutation request creating the container expiration policy'
|
:developer | 'denying the mutation request'
|
||||||
:reporter | 'denying the mutation request'
|
:reporter | 'denying the mutation request'
|
||||||
:guest | 'denying the mutation request'
|
:guest | 'denying the mutation request'
|
||||||
:anonymous | 'denying the mutation request'
|
:anonymous | 'denying the mutation request'
|
||||||
|
|
|
@ -63,7 +63,7 @@ RSpec.describe ContainerExpirationPolicies::UpdateService do
|
||||||
context 'with existing container expiration policy' do
|
context 'with existing container expiration policy' do
|
||||||
where(:user_role, :shared_examples_name) do
|
where(:user_role, :shared_examples_name) do
|
||||||
:maintainer | 'updating the container expiration policy'
|
:maintainer | 'updating the container expiration policy'
|
||||||
:developer | 'updating the container expiration policy'
|
:developer | 'denying access to container expiration policy'
|
||||||
:reporter | 'denying access to container expiration policy'
|
:reporter | 'denying access to container expiration policy'
|
||||||
:guest | 'denying access to container expiration policy'
|
:guest | 'denying access to container expiration policy'
|
||||||
:anonymous | 'denying access to container expiration policy'
|
:anonymous | 'denying access to container expiration policy'
|
||||||
|
@ -83,7 +83,7 @@ RSpec.describe ContainerExpirationPolicies::UpdateService do
|
||||||
|
|
||||||
where(:user_role, :shared_examples_name) do
|
where(:user_role, :shared_examples_name) do
|
||||||
:maintainer | 'creating the container expiration policy'
|
:maintainer | 'creating the container expiration policy'
|
||||||
:developer | 'creating the container expiration policy'
|
:developer | 'denying access to container expiration policy'
|
||||||
:reporter | 'denying access to container expiration policy'
|
:reporter | 'denying access to container expiration policy'
|
||||||
:guest | 'denying access to container expiration policy'
|
:guest | 'denying access to container expiration policy'
|
||||||
:anonymous | 'denying access to container expiration policy'
|
:anonymous | 'denying access to container expiration policy'
|
||||||
|
|
|
@ -217,6 +217,11 @@ module FilteredSearchHelpers
|
||||||
all('.gl-filtered-search-suggestion').size
|
all('.gl-filtered-search-suggestion').size
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def submit_search_term(value)
|
||||||
|
click_filtered_search_bar
|
||||||
|
send_keys(value, :enter)
|
||||||
|
end
|
||||||
|
|
||||||
def click_filtered_search_bar
|
def click_filtered_search_bar
|
||||||
find('.gl-filtered-search-last-item').click
|
find('.gl-filtered-search-last-item').click
|
||||||
end
|
end
|
||||||
|
@ -253,6 +258,22 @@ module FilteredSearchHelpers
|
||||||
expect(page).to have_css '.gl-filtered-search-token', text: "Author = #{value}"
|
expect(page).to have_css '.gl-filtered-search-token', text: "Author = #{value}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def expect_label_token(value)
|
||||||
|
expect(page).to have_css '.gl-filtered-search-token', text: "Label = ~#{value}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def expect_negated_label_token(value)
|
||||||
|
expect(page).to have_css '.gl-filtered-search-token', text: "Label != ~#{value}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def expect_milestone_token(value)
|
||||||
|
expect(page).to have_css '.gl-filtered-search-token', text: "Milestone = %#{value}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def expect_negated_milestone_token(value)
|
||||||
|
expect(page).to have_css '.gl-filtered-search-token', text: "Milestone != %#{value}"
|
||||||
|
end
|
||||||
|
|
||||||
def expect_search_term(value)
|
def expect_search_term(value)
|
||||||
value.split(' ').each do |term|
|
value.split(' ').each do |term|
|
||||||
expect(page).to have_css '.gl-filtered-search-term', text: term
|
expect(page).to have_css '.gl-filtered-search-term', text: term
|
||||||
|
|
Loading…
Reference in New Issue