Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2020-10-28 00:08:34 +00:00
parent d440531cf8
commit d690a8d62b
39 changed files with 270 additions and 230 deletions

View File

@ -117,6 +117,7 @@ export default {
v-if="displayFilters"
id="discussion-filter-dropdown"
class="gl-mr-3 full-width-mobile discussion-filter-container js-discussion-filter-container qa-discussion-filter"
data-qa-selector="discussion_filter_dropdown"
:text="currentFilter.title"
>
<div v-for="filter in filters" :key="filter.value" class="dropdown-item-wrapper">
@ -125,7 +126,7 @@ export default {
:is-checked="filter.value === currentValue"
:class="{ 'is-active': filter.value === currentValue }"
:data-filter-type="filterType(filter.value)"
class="qa-filter-options"
data-qa-selector="filter_menu_item"
@click.prevent="selectFilter(filter.value)"
>
{{ filter.title }}

View File

@ -33,7 +33,10 @@ export default {
</script>
<template>
<li class="timeline-entry note note-wrapper discussion-filter-note js-discussion-filter-note">
<li
class="timeline-entry note note-wrapper discussion-filter-note js-discussion-filter-note"
data-qa-selector="discussion_filter_container"
>
<div class="timeline-icon d-none d-lg-flex">
<gl-icon name="comment" />
</div>

View File

@ -170,7 +170,9 @@ export default {
</template>
<span v-else>{{ __('A deleted user') }}</span>
<span class="note-headline-light note-headline-meta">
<span class="system-note-message"> <slot></slot> </span>
<span class="system-note-message" data-qa-selector="system_note_content">
<slot></slot>
</span>
<template v-if="createdAt">
<span ref="actionText" class="system-note-separator">
<template v-if="actionText">{{ actionText }}</template>

View File

@ -353,7 +353,8 @@ export default {
:class="classNameBindings"
:data-award-url="note.toggle_award_path"
:data-note-id="note.id"
class="note note-wrapper qa-noteable-note-item"
class="note note-wrapper"
data-qa-selector="noteable_note_container"
>
<div
v-if="showMultiLineComment"

View File

@ -117,8 +117,9 @@ export default {
const errorMessage = data?.updateContainerExpirationPolicy?.errors[0];
if (errorMessage) {
this.$toast.show(errorMessage, { type: 'error' });
} else {
this.$toast.show(UPDATE_SETTINGS_SUCCESS_MESSAGE, { type: 'success' });
}
this.$toast.show(UPDATE_SETTINGS_SUCCESS_MESSAGE, { type: 'success' });
})
.catch(error => {
this.setApiErrors(error);

View File

@ -32,7 +32,7 @@ export const KEEP_N_LABEL = s__('ContainerRegistry|Number of tags to retain:');
export const NAME_REGEX_LABEL = s__(
'ContainerRegistry|Tags with names matching this regex pattern will %{italicStart}expire:%{italicEnd}',
);
export const NAME_REGEX_PLACEHOLDER = '.*';
export const NAME_REGEX_PLACEHOLDER = '';
export const NAME_REGEX_DESCRIPTION = s__(
'ContainerRegistry|Wildcards such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}',
);

View File

@ -97,7 +97,11 @@ export default {
class="related-issues-token-body bordered-box bg-white"
:class="{ 'sortable-container': canReorder }"
>
<div v-if="isFetching" class="related-issues-loading-icon qa-related-issues-loading-icon">
<div
v-if="isFetching"
class="related-issues-loading-icon"
data-qa-selector="related_issues_loading_placeholder"
>
<gl-loading-icon ref="loadingIcon" label="Fetching linked issues" class="gl-mt-2" />
</div>
<ul ref="list" :class="{ 'content-list': !canReorder }" class="related-items-list">
@ -132,7 +136,7 @@ export default {
:is-locked="issue.lockIssueRemoval"
:locked-message="issue.lockedMessage"
event-namespace="relatedIssue"
class="qa-related-issuable-item"
data-qa-selector="related_issuable_content"
@relatedIssueRemoveRequest="$emit('relatedIssueRemoveRequest', $event)"
/>
</li>

View File

@ -6,7 +6,6 @@ class Admin::UsersController < Admin::ApplicationController
before_action :user, except: [:index, :new, :create]
before_action :check_impersonation_availability, only: :impersonate
before_action :ensure_destroy_prerequisites_met, only: [:destroy]
before_action :check_admin_approval_feature_available!, only: [:approve]
feature_category :users
@ -298,10 +297,6 @@ class Admin::UsersController < Admin::ApplicationController
def log_impersonation_event
Gitlab::AppLogger.info(_("User %{current_user_username} has started impersonating %{username}") % { current_user_username: current_user.username, username: user.username })
end
def check_admin_approval_feature_available!
access_denied! unless Feature.enabled?(:admin_approval_for_new_user_signups, default_enabled: true)
end
end
Admin::UsersController.prepend_if_ee('EE::Admin::UsersController')

View File

@ -218,7 +218,6 @@ class RegistrationsController < Devise::RegistrationsController
end
def set_user_state
return unless Feature.enabled?(:admin_approval_for_new_user_signups, default_enabled: true)
return unless Gitlab::CurrentSettings.require_admin_approval_after_user_signup
resource.state = BLOCKED_PENDING_APPROVAL_STATE

View File

@ -21,6 +21,7 @@ class ContainerExpirationPolicy < ApplicationRecord
validates :cadence, presence: true, inclusion: { in: ->(_) { self.cadence_options.stringify_keys } }
validates :older_than, inclusion: { in: ->(_) { self.older_than_options.stringify_keys } }, allow_nil: true
validates :keep_n, inclusion: { in: ->(_) { self.keep_n_options.keys } }, allow_nil: true
validates :name_regex, presence: true, if: :enabled?
validates :name_regex, untrusted_regexp: true, if: :enabled?
validates :name_regex_keep, untrusted_regexp: true, if: :enabled?

View File

@ -9,14 +9,13 @@
Sign-up enabled
.form-text.text-muted
= _("When enabled, any user visiting %{host} will be able to create an account.") % { host: "#{new_user_session_url(host: Gitlab.config.gitlab.host)}" }
- if Feature.enabled?(:admin_approval_for_new_user_signups, default_enabled: true)
.form-group
.form-check
= f.check_box :require_admin_approval_after_user_signup, class: 'form-check-input'
= f.label :require_admin_approval_after_user_signup, class: 'form-check-label' do
= _('Require admin approval for new sign-ups')
.form-text.text-muted
= _("When enabled, any user visiting %{host} and creating an account will have to be explicitly approved by an admin before they can sign in. This setting is effective only if sign-ups are enabled.") % { host: "#{new_user_session_url(host: Gitlab.config.gitlab.host)}" }
.form-group
.form-check
= f.check_box :require_admin_approval_after_user_signup, class: 'form-check-input'
= f.label :require_admin_approval_after_user_signup, class: 'form-check-label' do
= _('Require admin approval for new sign-ups')
.form-text.text-muted
= _("When enabled, any user visiting %{host} and creating an account will have to be explicitly approved by an admin before they can sign in. This setting is effective only if sign-ups are enabled.") % { host: "#{new_user_session_url(host: Gitlab.config.gitlab.host)}" }
.form-group
.form-check
= f.check_box :send_user_confirmation_email, class: 'form-check-input'

View File

@ -30,11 +30,10 @@
= link_to admin_users_path(filter: "blocked") do
= s_('AdminUsers|Blocked')
%small.badge.badge-pill= limited_counter_with_delimiter(User.blocked)
- if Feature.enabled?(:admin_approval_for_new_user_signups, default_enabled: true)
= nav_link(html_options: { class: "#{active_when(params[:filter] == 'blocked_pending_approval')} filter-blocked-pending-approval" }) do
= link_to admin_users_path(filter: "blocked_pending_approval") do
= s_('AdminUsers|Pending approval')
%small.badge.badge-pill= limited_counter_with_delimiter(User.blocked_pending_approval)
= nav_link(html_options: { class: "#{active_when(params[:filter] == 'blocked_pending_approval')} filter-blocked-pending-approval" }) do
= link_to admin_users_path(filter: "blocked_pending_approval") do
= s_('AdminUsers|Pending approval')
%small.badge.badge-pill= limited_counter_with_delimiter(User.blocked_pending_approval)
= nav_link(html_options: { class: active_when(params[:filter] == 'deactivated') }) do
= link_to admin_users_path(filter: "deactivated") do
= s_('AdminUsers|Deactivated')

View File

@ -0,0 +1,5 @@
---
title: Remove admin_approval_for_new_user_signups feature flag
merge_request: 46051
author:
type: changed

View File

@ -0,0 +1,5 @@
---
title: Add default regexes and prevent blank regexes for container cleanup policies
merge_request: 44757
author:
type: changed

View File

@ -0,0 +1,21 @@
# frozen_string_literal: true
class SetRegexDefaultsOnContainerExpirationPolicies < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
def up
with_lock_retries do
change_column_default :container_expiration_policies, :name_regex, '.*'
change_column_default :container_expiration_policies, :enabled, false
end
end
def down
with_lock_retries do
change_column_default :container_expiration_policies, :name_regex, nil
change_column_default :container_expiration_policies, :enabled, true
end
end
end

View File

@ -0,0 +1 @@
250785e18682cc10afb4f04546e5ff6dff9ab6c6673df84692c8221d6fe820ac

View File

@ -11235,11 +11235,11 @@ CREATE TABLE container_expiration_policies (
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
next_run_at timestamp with time zone,
name_regex character varying(255),
name_regex character varying(255) DEFAULT '.*'::character varying,
cadence character varying(12) DEFAULT '1d'::character varying NOT NULL,
older_than character varying(12) DEFAULT '90d'::character varying,
keep_n integer DEFAULT 10,
enabled boolean DEFAULT true NOT NULL,
enabled boolean DEFAULT false NOT NULL,
name_regex_keep text,
CONSTRAINT container_expiration_policies_name_regex_keep CHECK ((char_length(name_regex_keep) <= 255))
);

View File

@ -582,6 +582,12 @@ This file lives in `/var/log/gitlab/gitaly/current` and is produced by [runit](h
This file lives in `/var/log/gitlab/gitlab-rails/grpc.log` for Omnibus GitLab packages. Native [gRPC](https://grpc.io/) logging used by Gitaly.
### `gitaly_ruby_json.log`
> [Introduced](https://gitlab.com/gitlab-org/gitaly/-/merge_requests/2678) in GitLab 13.6.
This file lives in `/var/log/gitlab/gitaly/gitaly_ruby_json.log` and is produced by [`gitaly-ruby`](gitaly/reference.md#gitaly-ruby). It contains an access log of gRPC calls made by Gitaly to `gitaly-ruby`.
## Puma Logs
### `puma_stdout.log`

View File

@ -16,7 +16,16 @@ POST /import/github
| `target_namespace` | string | yes | Namespace to import repository into. Supports subgroups like `/namespace/subgroup`. |
```shell
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --data "personal_access_token=abc123&repo_id=12345&target_namespace=group/subgroup" "https://gitlab.example.com/api/v4/import/github"
curl --request POST \
--url "https://gitlab.example.com/api/v4/import/github" \
--header "content-type: application/json" \
--header "PRIVATE-TOKEN: <your_access_token>" \
--data '{
"personal_access_token": "aBc123abC12aBc123abC12abC123+_A/c123",
"repo_id": "12345",
"target_namespace": "group/subgroup",
"new_name": "NEW-NAME"
}'
```
Example response:

View File

@ -24,6 +24,10 @@ of `state` are:
- `replicated`
- `cleanup_failed`
To ensure data integrity, projects are put in a temporary read-only state for the
duration of the move. During this time, users receive a `The repository is temporarily
read-only. Please try again later.` message if they try to push new commits.
This API requires you to [authenticate yourself](README.md#authentication) as an administrator.
## Retrieve all project repository storage moves

View File

@ -90,25 +90,6 @@ explain what falls under each type label.
The GitLab handbook documents [when something is a bug](https://about.gitlab.com/handbook/product/product-processes/#bug-issues) and [when it is a feature request](https://about.gitlab.com/handbook/product/product-processes/#feature-issues).
### Facet labels
Sometimes it's useful to refine the type of an issue. In those cases, you can
add facet labels.
Following is a non-exhaustive list of facet labels:
- ~enhancement: This label can refine an issue that has the ~feature label.
- ~"master:broken": This label can refine an issue that has the ~bug label.
- ~"failure::flaky-test": This label can refine an issue that has the ~bug label.
- ~"technical debt": This label can refine an issue that has the ~tooling label.
- ~"static analysis": This label can refine an issue that has the ~tooling label.
- ~"ci-build": This label can refine an issue that has the ~tooling label.
- ~performance: A performance issue could describe a ~bug or a ~feature.
- ~security: A security issue could describe a ~bug or a ~feature.
- ~database: A database issue could describe a ~bug or a ~feature.
- ~customer: This relates to an issue that was created by a customer, or that is of interest for a customer.
- ~"UI text": Issues that add or modify any text within the UI such as user-assistance microcopy, button/menu labels, or error messages.
### Stage labels
Stage labels specify which [stage](https://about.gitlab.com/handbook/product/product-categories/#hierarchy) the issue belongs to.

View File

@ -13,12 +13,13 @@ See already supported package types in [Packages documentation](../administratio
Since GitLab packages' UI is pretty generic, it is possible to add basic new
package system support with solely backend changes. This guide is superficial and does
not cover the way the code should be written. However, you can find a good example
by looking at merge requests with Maven and NPM support:
by looking at the following merge requests:
- [NPM registry support](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/8673).
- [Conan repository](https://gitlab.com/gitlab-org/gitlab/-/issues/8248).
- [Maven repository](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/6607).
- [Instance level endpoint for Maven repository](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/8757)
- [Composer repository for PHP dependencies](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/22415).
- [Terraform modules registry](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/18834).
- [Instance-level endpoint for Maven repository](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/8757).
## General information

View File

@ -522,7 +522,7 @@ To create a cleanup policy in the UI:
| **Expiration interval** | How long tags are exempt from being deleted. |
| **Expiration schedule** | How often the policy should run. |
| **Number of tags to retain** | How many tags to _always_ keep for each image. |
| **Tags with names matching this regex pattern expire:** | The regex pattern that determines which tags to remove. For all tags, use `.*`. See other [regex pattern examples](#regex-pattern-examples). |
| **Tags with names matching this regex pattern expire:** | The regex pattern that determines which tags to remove. This value cannot be blank. For all tags, use `.*`. See other [regex pattern examples](#regex-pattern-examples). |
| **Tags with names matching this regex pattern are preserved:** | The regex pattern that determines which tags to preserve. The `latest` tag is always preserved. For all tags, use `.*`. See other [regex pattern examples](#regex-pattern-examples). |
1. Click **Set cleanup policy**.
@ -544,6 +544,8 @@ Here are examples of regex patterns you may want to use:
.*
```
This is the default value for the expiration regex.
- Match tags that start with `v`:
```plaintext

View File

@ -33,8 +33,7 @@ You can also use the [API](../../api/packages.md) to administer the Package Regi
## Accepting contributions
The below table lists formats that are not supported, but are accepting Community contributions for. Consider contributing to GitLab. This [development documentation](../../development/packages.md) will
guide you through the process. Or check out how other members of the community
are adding support for [PHP](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/17417) or [Terraform](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/18834).
guide you through the process.
| Format | Status |
| ------ | ------ |

View File

@ -41,7 +41,7 @@ Note the following:
- Group members are exported as project members, as long as the user has
maintainer or admin access to the group where the exported project lives.
- Project members with owner access will be imported as maintainers.
- Using an admin account to import will map users by primary email address (self-managed only).
- Imported users can be mapped by their primary email on self-managed instances, if an administrative user (not an owner) does the import.
Otherwise, a supplementary comment is left to mention that the original author and
the MRs, notes, or issues will be owned by the importer.
- If an imported project contains merge requests originating from forks,

View File

@ -16,12 +16,20 @@ module QA
end
view 'app/assets/javascripts/notes/components/discussion_filter.vue' do
element :discussion_filter, required: true
element :filter_options
element :discussion_filter_dropdown, required: true
element :filter_menu_item
end
view 'app/assets/javascripts/notes/components/discussion_filter_note.vue' do
element :discussion_filter_container
end
view 'app/assets/javascripts/notes/components/noteable_note.vue' do
element :noteable_note_item
element :noteable_note_container
end
view 'app/assets/javascripts/notes/components/note_header.vue' do
element :system_note_content
end
view 'app/assets/javascripts/vue_shared/components/issue/related_issuable_item.vue' do
@ -51,8 +59,8 @@ module QA
end
view 'app/assets/javascripts/related_issues/components/related_issues_list.vue' do
element :related_issuable_item
element :related_issues_loading_icon
element :related_issuable_content
element :related_issues_loading_placeholder
end
def relate_issue(issue)
@ -62,11 +70,11 @@ module QA
end
def related_issuable_item
find_element(:related_issuable_item)
find_element(:related_issuable_content)
end
def wait_for_related_issues_to_load
has_no_element?(:related_issues_loading_icon, wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME)
has_no_element?(:related_issues_loading_placeholder, wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME)
end
def click_remove_related_issue_button
@ -95,11 +103,15 @@ module QA
end
def has_comment?(comment_text)
has_element?(:noteable_note_item, text: comment_text, wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME)
has_element?(:noteable_note_container, text: comment_text, wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME)
end
def has_system_note?(note_text)
has_element?(:system_note_content, text: note_text, wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME)
end
def noteable_note_item
find_element(:noteable_note_item)
find_element(:noteable_note_container)
end
def select_all_activities_filter
@ -108,10 +120,18 @@ module QA
def select_comments_only_filter
select_filter_with_text('Show comments only')
wait_until do
has_no_element?(:system_note_content)
end
end
def select_history_only_filter
select_filter_with_text('Show history only')
wait_until do
has_element?(:discussion_filter_container) && has_no_element?(:noteable_note_container)
end
end
def has_metrics_unfurled?
@ -123,8 +143,8 @@ module QA
def select_filter_with_text(text)
retry_on_exception do
click_element(:title)
click_element :discussion_filter
find_element(:filter_options, text: text).click
click_element :discussion_filter_dropdown
find_element(:filter_menu_item, text: text).click
wait_for_loading
end

View File

@ -18,16 +18,16 @@ module QA
show.comment(my_own_comment, filter: :comments_only)
expect(show).not_to have_content(made_the_issue_confidential)
expect(show).to have_content(my_own_comment)
expect(show).to have_comment(my_own_comment)
show.select_all_activities_filter
expect(show).to have_content(made_the_issue_confidential)
expect(show).to have_content(my_own_comment)
expect(show).to have_system_note(made_the_issue_confidential)
expect(show).to have_comment(my_own_comment)
show.select_history_only_filter
expect(show).to have_content(made_the_issue_confidential)
expect(show).to have_system_note(made_the_issue_confidential)
expect(show).not_to have_content(my_own_comment)
end
end

View File

@ -107,49 +107,31 @@ RSpec.describe Admin::UsersController do
subject { put :approve, params: { id: user.username } }
context 'when feature is disabled' do
before do
stub_feature_flags(admin_approval_for_new_user_signups: false)
end
it 'responds with access denied' do
context 'when successful' do
it 'activates the user' do
subject
expect(response).to have_gitlab_http_status(:not_found)
user.reload
expect(user).to be_active
expect(flash[:notice]).to eq('Successfully approved')
end
end
context 'when feature is enabled' do
before do
stub_feature_flags(admin_approval_for_new_user_signups: true)
context 'when unsuccessful' do
let(:user) { create(:user, :blocked) }
it 'displays the error' do
subject
expect(flash[:alert]).to eq('The user you are trying to approve is not pending an approval')
end
context 'when successful' do
it 'activates the user' do
subject
it 'does not activate the user' do
subject
user.reload
expect(user).to be_active
expect(flash[:notice]).to eq('Successfully approved')
end
end
context 'when unsuccessful' do
let(:user) { create(:user, :blocked) }
it 'displays the error' do
subject
expect(flash[:alert]).to eq('The user you are trying to approve is not pending an approval')
end
it 'does not activate the user' do
subject
user.reload
expect(user).not_to be_active
end
user.reload
expect(user).not_to be_active
end
end
end

View File

@ -46,102 +46,76 @@ RSpec.describe RegistrationsController do
subject { post(:create, params: user_params) }
context '`blocked_pending_approval` state' do
context 'when the feature is enabled' do
context 'when the `require_admin_approval_after_user_signup` setting is turned on' do
before do
stub_feature_flags(admin_approval_for_new_user_signups: true)
stub_application_setting(require_admin_approval_after_user_signup: true)
end
context 'when the `require_admin_approval_after_user_signup` setting is turned on' do
before do
stub_application_setting(require_admin_approval_after_user_signup: true)
end
it 'signs up the user in `blocked_pending_approval` state' do
subject
created_user = User.find_by(email: 'new@user.com')
it 'signs up the user in `blocked_pending_approval` state' do
subject
created_user = User.find_by(email: 'new@user.com')
expect(created_user).to be_present
expect(created_user.blocked_pending_approval?).to eq(true)
end
expect(created_user).to be_present
expect(created_user.blocked_pending_approval?).to eq(true)
end
it 'does not log in the user after sign up' do
subject
it 'does not log in the user after sign up' do
subject
expect(controller.current_user).to be_nil
end
expect(controller.current_user).to be_nil
end
it 'shows flash message after signing up' do
subject
it 'shows flash message after signing up' do
subject
expect(response).to redirect_to(new_user_session_path(anchor: 'login-pane'))
expect(flash[:notice])
.to eq('You have signed up successfully. However, we could not sign you in because your account is awaiting approval from your GitLab administrator.')
end
expect(response).to redirect_to(new_user_session_path(anchor: 'login-pane'))
expect(flash[:notice])
.to eq('You have signed up successfully. However, we could not sign you in because your account is awaiting approval from your GitLab administrator.')
end
context 'email confirmation' do
context 'when `send_user_confirmation_email` is true' do
before do
stub_application_setting(send_user_confirmation_email: true)
end
it 'does not send a confirmation email' do
expect { subject }
.not_to have_enqueued_mail(DeviseMailer, :confirmation_instructions)
end
context 'email confirmation' do
context 'when `send_user_confirmation_email` is true' do
before do
stub_application_setting(send_user_confirmation_email: true)
end
end
end
context 'when the `require_admin_approval_after_user_signup` setting is turned off' do
before do
stub_application_setting(require_admin_approval_after_user_signup: false)
end
it 'signs up the user in `active` state' do
subject
created_user = User.find_by(email: 'new@user.com')
expect(created_user).to be_present
expect(created_user.active?).to eq(true)
end
it 'does not show any flash message after signing up' do
subject
expect(flash[:notice]).to be_nil
end
context 'email confirmation' do
context 'when `send_user_confirmation_email` is true' do
before do
stub_application_setting(send_user_confirmation_email: true)
end
it 'sends a confirmation email' do
expect { subject }
.to have_enqueued_mail(DeviseMailer, :confirmation_instructions)
end
it 'does not send a confirmation email' do
expect { subject }
.not_to have_enqueued_mail(DeviseMailer, :confirmation_instructions)
end
end
end
end
context 'when the feature is disabled' do
context 'when the `require_admin_approval_after_user_signup` setting is turned off' do
before do
stub_feature_flags(admin_approval_for_new_user_signups: false)
stub_application_setting(require_admin_approval_after_user_signup: false)
end
context 'when the `require_admin_approval_after_user_signup` setting is turned on' do
before do
stub_application_setting(require_admin_approval_after_user_signup: true)
end
it 'signs up the user in `active` state' do
subject
created_user = User.find_by(email: 'new@user.com')
it 'signs up the user in `active` state' do
subject
expect(created_user).to be_present
expect(created_user.active?).to eq(true)
end
created_user = User.find_by(email: 'new@user.com')
expect(created_user).to be_present
expect(created_user.active?).to eq(true)
it 'does not show any flash message after signing up' do
subject
expect(flash[:notice]).to be_nil
end
context 'email confirmation' do
context 'when `send_user_confirmation_email` is true' do
before do
stub_application_setting(send_user_confirmation_email: true)
end
it 'sends a confirmation email' do
expect { subject }
.to have_enqueued_mail(DeviseMailer, :confirmation_instructions)
end
end
end
end

View File

@ -132,32 +132,14 @@ RSpec.describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_n
context 'Change Sign-up restrictions' do
context 'Require Admin approval for new signup setting' do
context 'when feature is enabled' do
before do
stub_feature_flags(admin_approval_for_new_user_signups: true)
it 'changes the setting' do
page.within('.as-signup') do
check 'Require admin approval for new sign-ups'
click_button 'Save changes'
end
it 'changes the setting' do
page.within('.as-signup') do
check 'Require admin approval for new sign-ups'
click_button 'Save changes'
end
expect(current_settings.require_admin_approval_after_user_signup).to be_truthy
expect(page).to have_content "Application settings saved successfully"
end
end
context 'when feature is disabled' do
before do
stub_feature_flags(admin_approval_for_new_user_signups: false)
end
it 'does not show the the setting' do
page.within('.as-signup') do
expect(page).not_to have_selector('.application_setting_require_admin_approval_after_user_signup')
end
end
expect(current_settings.require_admin_approval_after_user_signup).to be_truthy
expect(page).to have_content "Application settings saved successfully"
end
end
end

View File

@ -75,26 +75,12 @@ RSpec.describe "Admin::Users" do
end
context '`Pending approval` tab' do
context 'feature is enabled' do
before do
stub_feature_flags(admin_approval_for_new_user_signups: true)
visit admin_users_path
end
it 'shows the `Pending approval` tab' do
expect(page).to have_link('Pending approval', href: admin_users_path(filter: 'blocked_pending_approval'))
end
before do
visit admin_users_path
end
context 'feature is disabled' do
before do
stub_feature_flags(admin_approval_for_new_user_signups: false)
visit admin_users_path
end
it 'does not show the `Pending approval` tab' do
expect(page).not_to have_link('Pending approval', href: admin_users_path(filter: 'blocked_pending_approval'))
end
it 'shows the `Pending approval` tab' do
expect(page).to have_link('Pending approval', href: admin_users_path(filter: 'blocked_pending_approval'))
end
end
end

View File

@ -15,6 +15,7 @@ RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration p
before do
project.update!(container_registry_enabled: container_registry_enabled_on_project)
project.container_expiration_policy.update!(enabled: true)
sign_in(user)
stub_container_registry_config(enabled: container_registry_enabled)

View File

@ -123,7 +123,7 @@ exports[`Expiration Policy Form renders 1`] = `
disabled="true"
id="expiration-policy-name-matching"
noresize="true"
placeholder=".*"
placeholder=""
trim=""
value=""
/>

View File

@ -35,7 +35,7 @@ RSpec.describe Mutations::ContainerExpirationPolicies::Update do
it_behaves_like 'not creating the container expiration policy'
it "doesn't update the cadence" do
it 'doesn\'t update the cadence' do
expect { subject }
.not_to change { container_expiration_policy.reload.cadence }
end
@ -47,6 +47,24 @@ RSpec.describe Mutations::ContainerExpirationPolicies::Update do
)
end
end
context 'with blank regex' do
let_it_be(:params) { { project_path: project.full_path, name_regex: '', enabled: true } }
it_behaves_like 'not creating the container expiration policy'
it "doesn't update the cadence" do
expect { subject }
.not_to change { container_expiration_policy.reload.cadence }
end
it 'returns an error' do
expect(subject).to eq(
container_expiration_policy: nil,
errors: ['Name regex can\'t be blank']
)
end
end
end
RSpec.shared_examples 'denying access to container expiration policy' do

View File

@ -546,13 +546,13 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
subject { described_class.data[:counts] }
it 'gathers usage data' do
expect(subject[:projects_with_expiration_policy_enabled]).to eq 22
expect(subject[:projects_with_expiration_policy_disabled]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled]).to eq 18
expect(subject[:projects_with_expiration_policy_disabled]).to eq 5
expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_unset]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_1]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_5]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_10]).to eq 16
expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_10]).to eq 12
expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_25]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_50]).to eq 1
@ -560,9 +560,9 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
expect(subject[:projects_with_expiration_policy_enabled_with_older_than_set_to_7d]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_older_than_set_to_14d]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_older_than_set_to_30d]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_older_than_set_to_90d]).to eq 18
expect(subject[:projects_with_expiration_policy_enabled_with_older_than_set_to_90d]).to eq 14
expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_1d]).to eq 18
expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_1d]).to eq 14
expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_7d]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_14d]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_1month]).to eq 1

View File

@ -66,9 +66,15 @@ RSpec.describe ContainerExpirationPolicy, type: :model do
end
context 'with a set of regexps' do
let_it_be(:container_expiration_policy) { create(:container_expiration_policy) }
subject { container_expiration_policy }
valid_regexps = %w[master .* v.+ v10.1.* (?:v.+|master|release)]
invalid_regexps = ['[', '(?:v.+|master|release']
it { is_expected.to validate_presence_of(:name_regex) }
valid_regexps.each do |valid_regexp|
it { is_expected.to allow_value(valid_regexp).for(:name_regex) }
it { is_expected.to allow_value(valid_regexp).for(:name_regex_keep) }
@ -84,6 +90,8 @@ RSpec.describe ContainerExpirationPolicy, type: :model do
subject { container_expiration_policy }
it { is_expected.not_to validate_presence_of(:name_regex) }
valid_regexps.each do |valid_regexp|
it { is_expected.to allow_value(valid_regexp).for(:name_regex) }
it { is_expected.to allow_value(valid_regexp).for(:name_regex_keep) }

View File

@ -73,6 +73,29 @@ RSpec.describe 'Updating the container expiration policy' do
end
end
RSpec.shared_examples 'rejecting blank name_regex when enabled' do
context "for blank name_regex" do
let(:params) do
{
project_path: project.full_path,
name_regex: '',
enabled: true
}
end
it_behaves_like 'returning response status', :success
it_behaves_like 'not creating the container expiration policy'
it 'returns an error' do
subject
expect(graphql_data['updateContainerExpirationPolicy']['errors'].size).to eq(1)
expect(graphql_data['updateContainerExpirationPolicy']['errors']).to include("Name regex can't be blank")
end
end
end
RSpec.shared_examples 'accepting the mutation request updating the container expiration policy' do
it_behaves_like 'updating the container expiration policy attributes', mode: :update, from: { cadence: '1d', keep_n: 10, older_than: '90d' }, to: { cadence: '3month', keep_n: 100, older_than: '14d' }
@ -80,6 +103,7 @@ RSpec.describe 'Updating the container expiration policy' do
it_behaves_like 'rejecting invalid regex for', :name_regex
it_behaves_like 'rejecting invalid regex for', :name_regex_keep
it_behaves_like 'rejecting blank name_regex when enabled'
end
RSpec.shared_examples 'accepting the mutation request creating the container expiration policy' do
@ -89,6 +113,7 @@ RSpec.describe 'Updating the container expiration policy' do
it_behaves_like 'rejecting invalid regex for', :name_regex
it_behaves_like 'rejecting invalid regex for', :name_regex_keep
it_behaves_like 'rejecting blank name_regex when enabled'
end
RSpec.shared_examples 'denying the mutation request' do

View File

@ -2659,6 +2659,7 @@ RSpec.describe API::Projects do
project_param = {
container_expiration_policy_attributes: {
cadence: '1month',
enabled: true,
keep_n: 1,
name_regex_keep: '['
}

View File

@ -13,6 +13,10 @@ RSpec.describe ContainerExpirationPolicies::CleanupContainerRepositoryWorker do
describe '#perform_work' do
subject { worker.perform_work }
before do
policy.update_column(:enabled, true)
end
RSpec.shared_examples 'handling all repository conditions' do
it 'sends the repository for cleaning' do
expect(ContainerExpirationPolicies::CleanupService)