Commit 3dc2ee49 authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents 89e85996 f363da8a
......@@ -38,7 +38,7 @@ export default {
<div
v-for="panel in panels"
:key="panel.name"
class="new-namespace-panel-wrapper gl-display-inline-block gl-px-3 gl-mb-5"
class="new-namespace-panel-wrapper gl-display-inline-block gl-float-left gl-px-3 gl-mb-5"
>
<a
:href="`#${panel.name}`"
......
......@@ -8,10 +8,11 @@ $new-namespace-panel-height: 240px;
}
.new-namespace-panel-wrapper {
@include media-breakpoint-down(md) {
width: 50%;
@include media-breakpoint-down(lg) {
width: 100%;
}
width: 50%;
}
.new-namespace-panel {
......
......@@ -14,8 +14,7 @@ module WikiActions
before_action { respond_to :html }
before_action :authorize_read_wiki!
before_action :authorize_create_wiki!, only: [:edit, :create]
before_action :authorize_admin_wiki!, only: :destroy
before_action :authorize_create_wiki!, only: [:edit, :create, :destroy]
before_action :wiki
before_action :page, only: [:show, :edit, :update, :history, :destroy, :diff]
......
......@@ -30,7 +30,7 @@ module BulkImports
end
def portable_relations
import_export_config.dig(:tree, portable_class_sym).keys.map(&:to_s)
import_export_config.dig(:tree, portable_class_sym).keys.map(&:to_s) - skipped_relations
end
private
......@@ -66,6 +66,10 @@ module BulkImports
def base_export_path
raise NotImplementedError
end
def skipped_relations
[]
end
end
end
end
......@@ -10,6 +10,10 @@ module BulkImports
def import_export_yaml
::Gitlab::ImportExport.group_config_file
end
def skipped_relations
@skipped_relations ||= %w(members)
end
end
end
end
......@@ -10,6 +10,10 @@ module BulkImports
def import_export_yaml
::Gitlab::ImportExport.config_file
end
def skipped_relations
@skipped_relations ||= %w(project_members group_members)
end
end
end
end
- attribute = local_assigns.fetch(:attribute, nil)
- group = local_assigns.fetch(:group, nil)
- form = local_assigns.fetch(:form, nil)
- setting_locked = local_assigns.fetch(:setting_locked, false)
- help_text = local_assigns.fetch(:help_text, s_('CascadingSettings|Subgroups cannot change this setting.'))
......
- attribute = local_assigns.fetch(:attribute, nil)
- group = local_assigns.fetch(:group, nil)
- settings_path_helper = local_assigns.fetch(:settings_path_helper, nil)
- form = local_assigns.fetch(:form, nil)
- setting_locked = local_assigns.fetch(:setting_locked, false)
- help_text = local_assigns.fetch(:help_text, nil)
- return unless attribute && form && settings_path_helper
- return unless attribute && group && form && settings_path_helper
= form.label attribute, class: 'custom-control-label', aria: { disabled: setting_locked } do
= render 'shared/namespaces/cascading_settings/setting_label_container' do
......
- attribute = local_assigns.fetch(:attribute, nil)
- group = local_assigns.fetch(:group, nil)
- settings_path_helper = local_assigns.fetch(:settings_path_helper, nil)
- setting_locked = local_assigns.fetch(:setting_locked, false)
- help_text = local_assigns.fetch(:help_text, nil)
- return unless attribute && settings_path_helper
- return unless attribute && group && settings_path_helper
%legend.h5.gl-border-none.gl-m-0
= render 'shared/namespaces/cascading_settings/setting_label_container' do
......
......@@ -18,7 +18,7 @@
.nav-controls.pb-md-3.pb-lg-0
- if @page.persisted?
- if can?(current_user, :admin_wiki, @wiki.container)
- if can?(current_user, :create_wiki, @wiki.container)
#delete-wiki-modal-wrapper{ data: { delete_wiki_url: wiki_page_path(@wiki, @page), page_title: @page.human_title } }
= render 'shared/wikis/form', uploads_path: wiki_attachment_upload_url
......
......@@ -47,11 +47,36 @@ module ApplicationWorker
end
class_methods do
extend ::Gitlab::Utils::Override
def inherited(subclass)
subclass.set_queue
subclass.after_set_class_attribute { subclass.set_queue }
end
override :validate_worker_attributes!
def validate_worker_attributes!
super
# Since the delayed data_consistency will use sidekiq built in retry mechanism, it is required that this mechanism
# is not disabled.
if retry_disabled? && get_data_consistency == :delayed
raise ArgumentError, "Retry support cannot be disabled if data_consistency is set to :delayed"
end
end
# Checks if sidekiq retry support is disabled
def retry_disabled?
get_sidekiq_options['retry'] == 0 || get_sidekiq_options['retry'] == false
end
override :sidekiq_options
def sidekiq_options(opts = {})
super.tap do
validate_worker_attributes!
end
end
def perform_async(*args)
# Worker execution for workers with data_consistency set to :delayed or :sticky
# will be delayed to give replication enough time to complete
......
---
data_category: Optional
key_path: active_user_count
description: The number of active users existing in the instance. This is named the instance_user_count in the Versions application.
product_section: growth
......@@ -8,6 +7,7 @@ product_group: group::product intelligence
product_category: collection
value_type: string
status: data_available
data_category: Subscription
time_frame: none
data_source: database
distribution:
......
......@@ -131,6 +131,7 @@ Renders the enforcement checkbox.
| Local | Description | Type | Required (default value) |
|:-----------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------|:------------------------------------------------|
| `attribute` | Name of the setting. For example, `:delayed_project_removal`. | `String` or `Symbol` | `true` |
| `group` | Current group. | [`Group`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/models/group.rb) | `true` |
| `form` | [Rails FormBuilder object](https://apidock.com/rails/ActionView/Helpers/FormBuilder). | [`ActionView::Helpers::FormBuilder`](https://apidock.com/rails/ActionView/Helpers/FormBuilder) | `true` |
| `setting_locked` | If the setting is locked by an ancestor group or admin setting. Can be calculated with [`cascading_namespace_setting_locked?`](https://gitlab.com/gitlab-org/gitlab/-/blob/c2736823b8e922e26fd35df4f0cd77019243c858/app/helpers/namespaces_helper.rb#L86). | `Boolean` | `true` |
| `help_text` | Text shown below the checkbox. | `String` | `false` (Subgroups cannot change this setting.) |
......@@ -142,6 +143,7 @@ Renders the label for a checkbox setting.
| Local | Description | Type | Required (default value) |
|:-----------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------|:-------------------------|
| `attribute` | Name of the setting. For example, `:delayed_project_removal`. | `String` or `Symbol` | `true` |
| `group` | Current group. | [`Group`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/models/group.rb) | `true` |
| `form` | [Rails FormBuilder object](https://apidock.com/rails/ActionView/Helpers/FormBuilder). | [`ActionView::Helpers::FormBuilder`](https://apidock.com/rails/ActionView/Helpers/FormBuilder) | `true` |
| `setting_locked` | If the setting is locked by an ancestor group or admin setting. Can be calculated with [`cascading_namespace_setting_locked?`](https://gitlab.com/gitlab-org/gitlab/-/blob/c2736823b8e922e26fd35df4f0cd77019243c858/app/helpers/namespaces_helper.rb#L86). | `Boolean` | `true` |
| `settings_path_helper` | Lambda function that generates a path to the ancestor setting. For example, `settings_path_helper: -> (locked_ancestor) { edit_group_path(locked_ancestor, anchor: 'js-permissions-settings') }` | `Lambda` | `true` |
......@@ -154,6 +156,7 @@ Renders the label for a fieldset setting.
| Local | Description | Type | Required (default value) |
|:-----------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------|:-------------------------|
| `attribute` | Name of the setting. For example, `:delayed_project_removal`. | `String` or `Symbol` | `true` |
| `group` | Current group. | [`Group`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/models/group.rb) | `true` |
| `setting_locked` | If the setting is locked. Can be calculated with [`cascading_namespace_setting_locked?`](https://gitlab.com/gitlab-org/gitlab/-/blob/c2736823b8e922e26fd35df4f0cd77019243c858/app/helpers/namespaces_helper.rb#L86). | `Boolean` | `true` |
| `settings_path_helper` | Lambda function that generates a path to the ancestor setting. For example, `-> (locked_ancestor) { edit_group_path(locked_ancestor, anchor: 'js-permissions-settings') }` | `Lambda` | `true` |
| `help_text` | Text shown below the checkbox. | `String` | `false` (`nil`) |
......
......@@ -42,7 +42,7 @@ The number of active users existing in the instance. This is named the instance_
Group: `group::product intelligence`
Data Category: `Optional`
Data Category: `Subscription`
Status: `data_available`
......@@ -3836,7 +3836,7 @@ Count of License Scanning jobs run
Group: `group::composition analysis`
Data Category: `Optional`
Data Category: `Subscription`
Status: `data_available`
......@@ -8288,7 +8288,7 @@ The peak active user count. Active is defined in UsersStatistics model.
Group: `group::license`
Data Category: `Optional`
Data Category: `Subscription`
Status: `data_available`
......@@ -8386,7 +8386,7 @@ The date the license ends
Group: `group::license`
Data Category: `Optional`
Data Category: `Subscription`
Status: `data_available`
......@@ -8400,7 +8400,7 @@ The ID of the license
Group: `group::license`
Data Category: `Optional`
Data Category: `Subscription`
Status: `data_available`
......@@ -8428,7 +8428,7 @@ The plan of the GitLab license
Group: `group::license`
Data Category: `Optional`
Data Category: `Subscription`
Status: `data_available`
......@@ -8442,7 +8442,7 @@ The date the license starts
Group: `group::license`
Data Category: `Optional`
Data Category: `Subscription`
Status: `data_available`
......@@ -8470,7 +8470,7 @@ Whether this is a trial license or not
Group: `group::license`
Data Category: `Optional`
Data Category: `Subscription`
Status: `data_available`
......@@ -8484,7 +8484,7 @@ Date the trial license ends on
Group: `group::license`
Data Category: `Optional`
Data Category: `Subscription`
Status: `data_available`
......@@ -8498,7 +8498,7 @@ The number of seats included in the license
Group: `group::license`
Data Category: `Optional`
Data Category: `Subscription`
Status: `data_available`
......@@ -8512,7 +8512,7 @@ Company on the GitLab license
Group: `group::license`
Data Category: `Optional`
Data Category: `Subscription`
Status: `data_available`
......@@ -8526,7 +8526,7 @@ Email on the GitLab license
Group: `group::license`
Data Category: `Optional`
Data Category: `Subscription`
Status: `data_available`
......@@ -8540,7 +8540,7 @@ Name on the GitLab license
Group: `group::license`
Data Category: `Optional`
Data Category: `Subscription`
Status: `data_available`
......@@ -9002,7 +9002,7 @@ When the EE-specific features were computed
Group: `group::product intelligence`
Data Category: `Optional`
Data Category: `Subscription`
Status: `data_available`
......
......@@ -712,115 +712,116 @@ Implemented using Redis methods [PFADD](https://redis.io/commands/pfadd) and [PF
Aggregation on a `daily` basis does not pull more fine grained data.
- `feature_flag`: optional `default_enabled: :yaml`. If no feature flag is set then the tracking is enabled. One feature flag can be used for multiple events. For details, see our [GitLab internal Feature flags](../feature_flags/index.md) documentation. The feature flags are owned by the group adding the event tracking.
Use one of the following methods to track events:
1. Use one of the following methods to track the event:
1. Track event in controller using `RedisTracking` module with `track_redis_hll_event(*controller_actions, name:, if: nil, &block)`.
- In the controller using the `RedisTracking` module and the following format:
Arguments:
- `controller_actions`: controller actions we want to track.
- `name`: event name.
- `if`: optional custom conditions, using the same format as with Rails callbacks.
- `&block`: optional block that computes and returns the `custom_id` that we want to track. This will override the `visitor_id`.
```ruby
track_redis_hll_event(*controller_actions, name:, if: nil, &block)
```
Example usage:
Arguments:
```ruby
# controller
class ProjectsController < Projects::ApplicationController
include RedisTracking
- `controller_actions`: the controller actions to track.
- `name`: the event name.
- `if`: optional custom conditions. Uses the same format as Rails callbacks.
- `&block`: optional block that computes and returns the `custom_id` that we want to track. This overrides the `visitor_id`.
skip_before_action :authenticate_user!, only: :show
track_redis_hll_event :index, :show, name: 'users_visiting_projects'
Example:
def index
render html: 'index'
end
def new
render html: 'new'
end
```ruby
# controller
class ProjectsController < Projects::ApplicationController
include RedisTracking
def show
render html: 'show'
end
end
```
skip_before_action :authenticate_user!, only: :show
track_redis_hll_event :index, :show, name: 'users_visiting_projects'
1. Track event in API using `increment_unique_values(event_name, values)` helper method.
def index
render html: 'index'
end
Arguments:
def new
render html: 'new'
end
- `event_name`: event name.
- `values`: values counted, one value or array of values.
def show
render html: 'show'
end
end
```
Example usage:
- In the API using the `increment_unique_values(event_name, values)` helper method.
```ruby
get ':id/registry/repositories' do
repositories = ContainerRepositoriesFinder.new(
user: current_user, subject: user_group
).execute
Arguments:
increment_unique_values('users_listing_repositories', current_user.id)
- `event_name`: the event name.
- `values`: the values counted. Can be one value or an array of values.
present paginate(repositories), with: Entities::ContainerRegistry::Repository, tags: params[:tags], tags_count: params[:tags_count]
end
```
Example:
1. Track event using `track_usage_event(event_name, values)` in services and GraphQL
```ruby
get ':id/registry/repositories' do
repositories = ContainerRepositoriesFinder.new(
user: current_user, subject: user_group
).execute
Increment unique values count using Redis HLL, for given event name.
increment_unique_values('users_listing_repositories', current_user.id)
Example:
present paginate(repositories), with: Entities::ContainerRegistry::Repository, tags: params[:tags], tags_count: params[:tags_count]
end
```
[Track usage event for incident created in service](https://gitlab.com/gitlab-org/gitlab/-/blob/v13.8.3-ee/app/services/issues/update_service.rb#L66)
- Using `track_usage_event(event_name, values)` in services and GraphQL.
[Track usage event for incident created in GraphQL](https://gitlab.com/gitlab-org/gitlab/-/blob/v13.8.3-ee/app/graphql/mutations/alert_management/update_alert_status.rb#L16)
Increment unique values count using Redis HLL, for a given event name.
```ruby
track_usage_event(:incident_management_incident_created, current_user.id)
```
Examples:
<!-- There's nearly identical content in `##### UsageData API Tracking`. If you find / fix errors here, you may need to fix errors in that section too. -->
- [Track usage event for an incident in a service](https://gitlab.com/gitlab-org/gitlab/-/blob/v13.8.3-ee/app/services/issues/update_service.rb#L66)
- [Track usage event for an incident in GraphQL](https://gitlab.com/gitlab-org/gitlab/-/blob/v13.8.3-ee/app/graphql/mutations/alert_management/update_alert_status.rb#L16)
1. Track event using `UsageData` API
```ruby
track_usage_event(:incident_management_incident_created, current_user.id)
```
Increment unique users count using Redis HLL, for given event name.
- Using the `UsageData` API.
<!-- There's nearly identical content in `##### UsageData API Tracking`. If you find / fix errors here, you may need to fix errors in that section too. -->
Tracking events using the `UsageData` API requires the `usage_data_api` feature flag to be enabled, which is enabled by default.
Increment unique users count using Redis HLL, for a given event name.
API requests are protected by checking for a valid CSRF token.
To track events using the `UsageData` API, ensure the `usage_data_api` feature flag
is set to `default_enabled: true`. Enabled by default in GitLab 13.7 and later.
```plaintext
POST /usage_data/increment_unique_users
```
API requests are protected by checking for a valid CSRF token.
| Attribute | Type | Required | Description |
| :-------- | :--- | :------- | :---------- |
| `event` | string | yes | The event name it should be tracked |
```plaintext
POST /usage_data/increment_unique_users
```
Response
| Attribute | Type | Required | Description |
| :-------- | :--- | :------- | :---------- |
| `event` | string | yes | The event name to track |
Return 200 if tracking failed for any reason.
Response:
- `200` if event was tracked or any errors
- `400 Bad request` if event parameter is missing
- `401 Unauthorized` if user is not authenticated
- `403 Forbidden` for invalid CSRF token provided
- `200` if the event was tracked, or if tracking failed for any reason.
- `400 Bad request` if an event parameter is missing.
- `401 Unauthorized` if the user is not authenticated.
- `403 Forbidden` if an invalid CSRF token is provided.
1. Track events using JavaScript/Vue API helper which calls the API above
- Using the JavaScript/Vue API helper, which calls the `UsageData` API.
Example usage for an existing event already defined in [known events](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data_counters/known_events/):
To track events using the `UsageData` API, ensure the `usage_data_api` feature flag
is set to `default_enabled: true`. Enabled by default in GitLab 13.7 and later.
Usage Data API is behind `usage_data_api` feature flag which, as of GitLab 13.7, is
now set to `default_enabled: true`.
Example for an existing event already defined in [known events](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data_counters/known_events/):
```javascript
import api from '~/api';
```javascript
import api from '~/api';
api.trackRedisHllUserEvent('my_already_defined_event_name'),
```
api.trackRedisHllUserEvent('my_already_defined_event_name'),
```
1. Get event data using `Gitlab::UsageDataCounters::HLLRedisCounter.unique_events(event_names:, start_date:, end_date:, context: '')`.
......
......@@ -6,8 +6,6 @@ module Elastic
included do
include ApplicationWorker
sidekiq_options retry: 3
include Gitlab::ExclusiveLeaseHelpers
# There is no onward scheduling and this cron handles work from across the
# application, so there's no useful context to add.
......
......@@ -7,7 +7,7 @@ class ElasticIndexBulkCronWorker # rubocop:disable Scalability/IdempotentWorker
urgency :throttled
# Even though this worker is idempotent, until https://gitlab.com/gitlab-org/gitlab/-/issues/325291 is done
# we can't use it with read-only database replicas
data_consistency :delayed
data_consistency :sticky
private
......
......@@ -7,7 +7,7 @@ class ElasticIndexInitialBulkCronWorker # rubocop:disable Scalability/Idempotent
urgency :throttled
# Even though this worker is idempotent, until https://gitlab.com/gitlab-org/gitlab/-/issues/325291 is done
# we can't use it with read-only database replicas
data_consistency :delayed
data_consistency :sticky
private
......
---
data_category: Optional
key_path: counts.license_management_jobs
description: Count of License Scanning jobs run
product_section: sec
......@@ -10,6 +9,7 @@ value_type: number
status: data_available
time_frame: all
data_source: database
data_category: Subscription
distribution:
- ee
tier:
......
---
data_category: Optional
key_path: license_id
description: The ID of the license
product_section: fulfillment
......@@ -10,6 +9,7 @@ value_type: number
status: data_available
time_frame: none
data_source: license
data_category: Subscription
distribution:
- ee
tier:
......
---
data_category: Optional
key_path: historical_max_users
description: The peak active user count. Active is defined in UsersStatistics model.
product_section: fulfillment
......@@ -10,6 +9,7 @@ value_type: number
status: data_available
time_frame: none
data_source: database
data_category: Subscription
distribution:
- ee
tier:
......
---
data_category: Optional
key_path: licensee.Name
description: Name on the GitLab license
product_section: fulfillment
......@@ -10,6 +9,7 @@ value_type: string
status: data_available
time_frame: none
data_source: license
data_category: Subscription
distribution:
- ee
tier:
......
---
data_category: Optional
key_path: licensee.Email
description: Email on the GitLab license
product_section: fulfillment
......@@ -10,6 +9,7 @@ value_type: string
status: data_available
time_frame: none
data_source: license
data_category: Subscription
distribution:
- ee
tier:
......
---
data_category: Optional
key_path: licensee.Company
description: Company on the GitLab license
product_section: fulfillment
......@@ -10,6 +9,7 @@ value_type: string
status: data_available
time_frame: none
data_source: license
data_category: Subscription
distribution:
- ee
tier:
......
---
data_category: Optional
key_path: license_user_count
description: The number of seats included in the license
product_section: fulfillment
......@@ -10,6 +9,7 @@ value_type: number
status: data_available
time_frame: none
data_source: license
data_category: Subscription
distribution:
- ee
tier:
......
---
data_category: Optional
key_path: license_starts_at
description: The date the license starts
product_section: fulfillment
......@@ -10,6 +9,7 @@ value_type: string
status: data_available
time_frame: none
data_source: license
data_category: Subscription
distribution:
- ee
tier:
......
---
data_category: Optional
key_path: license_expires_at
description: The date the license ends
product_section: fulfillment
......@@ -8,6 +7,7 @@ product_group: group::license
product_category: license
value_type: string
status: data_available
data_category: Subscription
time_frame: none
data_source: license
distribution:
......
---
data_category: Optional
key_path: license_plan
description: The plan of the GitLab license
product_section: fulfillment
......@@ -10,6 +9,7 @@ value_type: string
status: data_available
time_frame: none
data_source: license
data_category: Subscription
distribution:
- ee
tier:
......
---
data_category: Optional
key_path: license_trial
description: Whether this is a trial license or not
product_section: fulfillment
......@@ -10,6 +9,7 @@ value_type: boolean
status: data_available
time_frame: none
data_source: license
data_category: Subscription
distribution:
- ee
tier:
......
---
data_category: Optional
key_path: license_trial_ends_on
description: Date the trial license ends on
product_section: fulfillment
......@@ -10,6 +9,7 @@ value_type: string
status: data_available
time_frame: none
data_source: database
data_category: Subscription
distribution:
- ee
tier:
......
---
data_category: Optional
key_path: recording_ee_finished_at
description: When the EE-specific features were computed
product_section: growth
......@@ -10,6 +9,7 @@ value_type: string
status: data_available
time_frame: none
data_source: system
data_category: Subscription
distribution:
- ee
tier:
......
......@@ -50,5 +50,5 @@ RSpec.describe ElasticIndexBulkCronWorker do
it_behaves_like 'worker with data consistency',
described_class,
data_consistency: :delayed
data_consistency: :sticky
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe ElasticIndexInitialBulkCronWorker do
it_behaves_like 'worker with data consistency',
described_class,
data_consistency: :sticky
end
......@@ -78,7 +78,7 @@ module QA
end
def wait_for_license_compliance_report
has_no_text?('Loading License Compliance report', wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME)
has_text?('License Compliance detected', wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME)
end
def approvals_required_from
......
......@@ -101,7 +101,11 @@ module QA
@merge_request.visit!
Page::MergeRequest::Show.perform do |show|
show.wait_for_license_compliance_report
# Give time for the runner to complete pipeline
show.has_pipeline_status?('passed')
Support::Retrier.retry_until(max_attempts: 5, sleep_interval: 5) do
show.wait_for_license_compliance_report
end
show.click_manage_licenses_button
end
......
......@@ -34,6 +34,10 @@ RSpec.describe BulkImports::FileTransfer::GroupConfig do
it 'returns a list of top level exportable relations' do
expect(subject.portable_relations).to include('milestones', 'badges', 'boards', 'labels')
end
it 'does not include skipped relations' do
expect(subject.portable_relations).not_to include('members')
end
end
describe '#top_relation_tree' do
......
......@@ -34,6 +34,10 @@ RSpec.describe BulkImports::FileTransfer::ProjectConfig do
it 'returns a list of top level exportable relations' do
expect(subject.portable_relations).to include('issues', 'labels', 'milestones', 'merge_requests')
end
it 'does not include skipped relations' do
expect(subject.portable_relations).not_to include('project_members', 'group_members')
end
end
describe '#top_relation_tree' do
......
# frozen_string_literal: true
RSpec.shared_examples 'wiki controller actions' do
let_it_be(:user) { create(:user) }
let_it_be(:other_user) { create(:user) }
let(:container) { raise NotImplementedError }
let(:routing_params) { raise NotImplementedError }
let_it_be(:user) { create(:user) }
let(:wiki) { Wiki.for_container(container, user) }
let(:wiki_title) { 'page title test' }
......@@ -458,6 +459,7 @@ RSpec.shared_examples 'wiki controller actions' do
describe 'DELETE #destroy' do
let(:id_param) { wiki_title }
let(:delete_user) { user }
subject(:request) do
delete(:destroy,
......@@ -466,13 +468,21 @@ RSpec.shared_examples 'wiki controller actions' do
))
end
before do
sign_in(delete_user)
end
context 'when page exists' do
it 'deletes the page' do
expect do
request
end.to change { wiki.list_pages.size }.by(-1)
shared_examples 'deletes the page' do
specify do
expect do
request
end.to change { wiki.list_pages.size }.by(-1)
end
end
it_behaves_like 'deletes the page'
context 'but page cannot be deleted' do
before do
allow_next_instance_of(WikiPage) do |page|
......@@ -489,6 +499,28 @@ RSpec.shared_examples 'wiki controller actions' do
expect(assigns(:error)).to eq('Could not delete wiki page')
end
end
context 'when user is a developer' do
let(:delete_user) { other_user }
before do
container.add_developer(other_user)
end
it_behaves_like 'deletes the page'
end
context 'when user is a reporter' do
let(:delete_user) { other_user }
before do
container.add_reporter(other_user)
end
it 'returns 404' do
is_expected.to have_gitlab_http_status(:not_found)
end
end
end
context 'when page does not exist' do
......
......@@ -7,18 +7,34 @@
RSpec.shared_examples 'User deletes wiki page' do
include WikiHelpers
let_it_be(:developer) { create(:user) }
let(:wiki_page) { create(:wiki_page, wiki: wiki) }
before do
wiki.container.add_developer(developer)
sign_in(user)
visit wiki_page_path(wiki, wiki_page)
end
it 'deletes a page', :js do
click_on('Edit')
click_on('Delete')
find('[data-testid="confirm_deletion_button"]').click
shared_examples 'deletes a wiki page' do
specify 'deletes a page', :js do
click_on('Edit')
click_on('Delete')
find('[data-testid="confirm_deletion_button"]').click
expect(page).to have_content('Wiki page was successfully deleted.')
end
end
context 'when user is the owner or maintainer' do
it_behaves_like 'deletes a wiki page'
end
context 'when user is a developer' do
let(:user) { developer }
expect(page).to have_content('Wiki page was successfully deleted.')
it_behaves_like 'deletes a wiki page'
end
end
......@@ -176,6 +176,77 @@ RSpec.describe ApplicationWorker do
end
end
describe '.data_consistency' do
using RSpec::Parameterized::TableSyntax
where(:data_consistency, :sidekiq_option_retry, :expect_error) do
:delayed | false | true
:delayed | 0 | true
:delayed | 3 | false
:delayed | nil | false
:sticky | false | false
:sticky | 0 | false
:sticky | 3 | false
:sticky | nil | false
:always | false | false
:always | 0 | false
:always | 3 | false
:always | nil | false
end
with_them do
before do
worker.sidekiq_options retry: sidekiq_option_retry unless sidekiq_option_retry.nil?
end
context "when workers data consistency is #{params['data_consistency']}" do
it "#{params['expect_error'] ? '' : 'not to '}raise an exception" do
if expect_error
expect { worker.data_consistency data_consistency }
.to raise_error("Retry support cannot be disabled if data_consistency is set to :delayed")
else
expect { worker.data_consistency data_consistency }
.not_to raise_error
end
end
end
end
end
describe '.retry' do
using RSpec::Parameterized::TableSyntax
where(:data_consistency, :sidekiq_option_retry, :expect_error) do
:delayed | false | true
:delayed | 0 | true
:delayed | 3 | false
:sticky | false | false
:sticky | 0 | false
:sticky | 3 | false
:always | false | false
:always | 0 | false
:always | 3 | false
end
with_them do
before do
worker.data_consistency(data_consistency)
end
context "when retry sidekiq option is #{params['sidekiq_option_retry']}" do
it "#{params['expect_error'] ? '' : 'not to '}raise an exception" do
if expect_error
expect { worker.sidekiq_options retry: sidekiq_option_retry }
.to raise_error("Retry support cannot be disabled if data_consistency is set to :delayed")
else
expect { worker.sidekiq_options retry: sidekiq_option_retry }
.not_to raise_error
end
end
end
end
end
describe '.perform_async' do
shared_examples_for 'worker utilizes load balancing capabilities' do |data_consistency|
before do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment