Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
71a67d17b0
commit
4a882000a9
|
|
@ -156,7 +156,7 @@ eslint-as-if-foss:
|
|||
needs: []
|
||||
script:
|
||||
- *yarn-install
|
||||
- run_timed_command "yarn run eslint"
|
||||
- run_timed_command "yarn run lint:eslint:all"
|
||||
|
||||
.karma-base:
|
||||
extends: .frontend-test-base
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
55f05e10c18669ba920243bfef46ae9bb5f53c72
|
||||
1be74fe6af19847eec28665da39ef03865329acb
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ export default {
|
|||
|
||||
<template #cell(commit)="{ item }">
|
||||
<gl-link
|
||||
v-if="item.pipeline && item.pipeline.project"
|
||||
:href="item.pipeline.project.commit_url"
|
||||
class="gl-text-gray-500"
|
||||
data-testid="commit-link"
|
||||
|
|
|
|||
|
|
@ -237,11 +237,6 @@
|
|||
line-height: 34px;
|
||||
margin: 0;
|
||||
|
||||
> li + li::before {
|
||||
padding: 0 3px;
|
||||
color: $gray-300;
|
||||
}
|
||||
|
||||
a {
|
||||
color: $gl-text-color;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -106,6 +106,10 @@ class ApplicationController < ActionController::Base
|
|||
redirect_back(fallback_location: default, **options)
|
||||
end
|
||||
|
||||
def check_if_gl_com_or_dev
|
||||
render_404 unless ::Gitlab.dev_env_or_com?
|
||||
end
|
||||
|
||||
def not_found
|
||||
render_404
|
||||
end
|
||||
|
|
|
|||
|
|
@ -86,7 +86,18 @@ class InvitesController < ApplicationController
|
|||
if user_sign_up?
|
||||
set_session_invite_params
|
||||
|
||||
redirect_to new_user_registration_path(invite_email: member.invite_email), notice: _("To accept this invitation, create an account or sign in.")
|
||||
experiment(:invite_signup_page_interaction, actor: member) do |experiment_instance|
|
||||
set_originating_member_id if experiment_instance.enabled?
|
||||
|
||||
experiment_instance.use do
|
||||
redirect_to new_user_registration_path(invite_email: member.invite_email), notice: _("To accept this invitation, create an account or sign in.")
|
||||
end
|
||||
experiment_instance.try do
|
||||
redirect_to new_users_sign_up_invite_path(invite_email: member.invite_email)
|
||||
end
|
||||
|
||||
experiment_instance.track(:view)
|
||||
end
|
||||
else
|
||||
redirect_to new_user_session_path(sign_in_redirect_params), notice: sign_in_notice
|
||||
end
|
||||
|
|
@ -95,7 +106,11 @@ class InvitesController < ApplicationController
|
|||
def set_session_invite_params
|
||||
session[:invite_email] = member.invite_email
|
||||
|
||||
session[:originating_member_id] = member.id if Members::InviteEmailExperiment.initial_invite_email?(params[:invite_type])
|
||||
set_originating_member_id if Members::InviteEmailExperiment.initial_invite_email?(params[:invite_type])
|
||||
end
|
||||
|
||||
def set_originating_member_id
|
||||
session[:originating_member_id] = member.id
|
||||
end
|
||||
|
||||
def sign_in_redirect_params
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Registrations
|
||||
class InvitesController < RegistrationsController
|
||||
layout 'simple_registration'
|
||||
|
||||
before_action :check_if_gl_com_or_dev
|
||||
end
|
||||
end
|
||||
|
|
@ -199,6 +199,7 @@ class RegistrationsController < Devise::RegistrationsController
|
|||
|
||||
return unless member
|
||||
|
||||
experiment(:invite_signup_page_interaction, actor: member).track(:form_submission)
|
||||
experiment('members/invite_email', actor: member).track(:accepted)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ module AuthHelper
|
|||
twitter
|
||||
).freeze
|
||||
LDAP_PROVIDER = /\Aldap/.freeze
|
||||
TRIAL_REGISTRATION_PROVIDERS = %w(google_oauth2 github).freeze
|
||||
POPULAR_PROVIDERS = %w(google_oauth2 github).freeze
|
||||
|
||||
def ldap_enabled?
|
||||
Gitlab::Auth::Ldap::Config.enabled?
|
||||
|
|
@ -116,19 +116,12 @@ module AuthHelper
|
|||
|
||||
providers = button_based_providers.map(&:to_s) - disabled_providers
|
||||
providers.sort_by do |provider|
|
||||
case provider
|
||||
when 'google_oauth2'
|
||||
0
|
||||
when 'github'
|
||||
1
|
||||
else
|
||||
2
|
||||
end
|
||||
POPULAR_PROVIDERS.index(provider) || POPULAR_PROVIDERS.length
|
||||
end
|
||||
end
|
||||
|
||||
def trial_enabled_button_based_providers
|
||||
enabled_button_based_providers & TRIAL_REGISTRATION_PROVIDERS
|
||||
def popular_enabled_button_based_providers
|
||||
enabled_button_based_providers & POPULAR_PROVIDERS
|
||||
end
|
||||
|
||||
def button_based_providers_enabled?
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module RegistrationsHelper
|
||||
def social_signin_enabled?
|
||||
::Gitlab.dev_env_or_com? &&
|
||||
omniauth_enabled? &&
|
||||
devise_mapping.omniauthable? &&
|
||||
button_based_providers_enabled?
|
||||
end
|
||||
end
|
||||
|
||||
RegistrationsHelper.prepend_mod_with('RegistrationsHelper')
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
= render 'devise/shared/signup_omniauth_provider_list', providers: trial_enabled_button_based_providers
|
||||
= render 'devise/shared/signup_omniauth_provider_list', providers: popular_enabled_button_based_providers
|
||||
.omniauth-divider.d-flex.align-items-center.text-center
|
||||
= _("or")
|
||||
|
|
|
|||
|
|
@ -6,10 +6,8 @@
|
|||
%p= s_('Check the %{docs_link_start}documentation%{docs_link_end}.').html_safe % { docs_link_start: docs_link_start, docs_link_end: '</a>'.html_safe }
|
||||
|
||||
.form-group.gl-mb-3
|
||||
.form-check
|
||||
= f.check_box :lfs_enabled, checked: @group.lfs_enabled?, class: 'form-check-input', data: { qa_selector: 'lfs_checkbox' }
|
||||
= f.label :lfs_enabled, class: 'form-check-label' do
|
||||
%span
|
||||
= _('Allow projects within this group to use Git LFS')
|
||||
%br/
|
||||
%span.text-muted= _('This setting can be overridden in each project.')
|
||||
.gl-form-checkbox.custom-control.custom-checkbox
|
||||
= f.check_box :lfs_enabled, checked: @group.lfs_enabled?, class: 'custom-control-input', data: { qa_selector: 'lfs_checkbox' }
|
||||
= f.label :lfs_enabled, class: 'custom-control-label' do
|
||||
= _('Allow projects within this group to use Git LFS')
|
||||
%p.help-text= _('This setting can be overridden in each project.')
|
||||
|
|
|
|||
|
|
@ -7,17 +7,17 @@
|
|||
%p= s_('Check the %{docs_link_start}documentation%{docs_link_end}.').html_safe % { docs_link_start: docs_link_start, docs_link_end: '</a>'.html_safe }
|
||||
|
||||
.form-group
|
||||
.form-check
|
||||
= f.check_box :require_two_factor_authentication, class: 'form-check-input', data: { qa_selector: 'require_2fa_checkbox' }
|
||||
= f.label :require_two_factor_authentication, class: 'form-check-label' do
|
||||
%span= _('Require all users in this group to setup two-factor authentication')
|
||||
.gl-form-checkbox.custom-control.custom-checkbox
|
||||
= f.check_box :require_two_factor_authentication, class: 'custom-control-input', data: { qa_selector: 'require_2fa_checkbox' }
|
||||
= f.label :require_two_factor_authentication, class: 'custom-control-label' do
|
||||
= _('Require all users in this group to setup two-factor authentication')
|
||||
.form-group
|
||||
= f.label :two_factor_grace_period, _('Time before enforced'), class: 'label-bold'
|
||||
= f.text_field :two_factor_grace_period, class: 'form-control form-control-sm w-auto'
|
||||
.form-text.text-muted= _('Amount of time (in hours) that users are allowed to skip forced configuration of two-factor authentication')
|
||||
- unless group.has_parent?
|
||||
.form-group
|
||||
.form-check
|
||||
= f.check_box :allow_mfa_for_subgroups, class: 'form-check-input', checked: group.namespace_settings&.allow_mfa_for_subgroups
|
||||
= f.label :allow_mfa_for_subgroups, class: 'form-check-label' do
|
||||
.gl-form-checkbox.custom-control.custom-checkbox
|
||||
= f.check_box :allow_mfa_for_subgroups, class: 'custom-control-input', checked: group.namespace_settings&.allow_mfa_for_subgroups
|
||||
= f.label :allow_mfa_for_subgroups, class: 'custom-control-label' do
|
||||
= _('Allow subgroups to set up their own two-factor authentication rules')
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
!!! 5
|
||||
%html{ lang: "en" }
|
||||
= render "layouts/head"
|
||||
%body.login-page.application.navless{ class: user_application_theme, data: { page: body_data_page } }
|
||||
= render "layouts/header/logo_with_title"
|
||||
= render "layouts/broadcast"
|
||||
.container.navless-container.pt-0
|
||||
.content.mw-460.mx-auto
|
||||
= render "layouts/flash"
|
||||
= yield
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
- page_title _('Join your team')
|
||||
- add_page_specific_style 'page_bundles/signup'
|
||||
- content_for :page_specific_javascripts do
|
||||
= render "layouts/google_tag_manager_head"
|
||||
= render "layouts/google_tag_manager_body"
|
||||
|
||||
%h2.center.pt-6.pb-3.gl-mb-0
|
||||
= _('Join your team')
|
||||
%p.gl-text-center= _('Create your own profile to collaborate with your teammates in issues, merge requests, and more.')
|
||||
|
||||
.signup-page
|
||||
= render 'devise/shared/signup_box',
|
||||
url: users_sign_up_invites_path,
|
||||
button_text: _('Continue'),
|
||||
show_omniauth_providers: social_signin_enabled?,
|
||||
omniauth_providers_placement: :top,
|
||||
suggestion_path: nil
|
||||
= render 'devise/shared/sign_in_link'
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
- label_class = local_assigns.fetch(:bold_label, false) ? 'font-weight-bold' : ''
|
||||
|
||||
.form-check
|
||||
= form.check_box :request_access_enabled, class: 'form-check-input', data: { qa_selector: 'request_access_checkbox' }
|
||||
= form.label :request_access_enabled, class: 'form-check-label' do
|
||||
.gl-form-checkbox.custom-control.custom-checkbox
|
||||
= form.check_box :request_access_enabled, class: 'custom-control-input', data: { qa_selector: 'request_access_checkbox' }
|
||||
= form.label :request_access_enabled, class: 'custom-control-label' do
|
||||
%span{ class: label_class }= _('Allow users to request access (if visibility is public or internal)')
|
||||
|
|
|
|||
|
|
@ -2786,7 +2786,7 @@
|
|||
:tags: []
|
||||
- :name: service_desk_email_receiver
|
||||
:worker_name: ServiceDeskEmailReceiverWorker
|
||||
:feature_category: :issue_tracking
|
||||
:feature_category: :service_desk
|
||||
:has_external_dependencies:
|
||||
:urgency: :low
|
||||
:resource_boundary: :unknown
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
class ServiceDeskEmailReceiverWorker < EmailReceiverWorker # rubocop:disable Scalability/IdempotentWorker
|
||||
include ApplicationWorker
|
||||
|
||||
feature_category :service_desk
|
||||
sidekiq_options retry: 3
|
||||
|
||||
def should_perform?
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
title: Update checkbox styles in "Group" -> "Settings" -> "General" -> "Permissions,
|
||||
LFS, 2FA"
|
||||
merge_request: 61294
|
||||
author:
|
||||
type: other
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Hide commit msg for package files without pipeline
|
||||
merge_request: 61571
|
||||
author:
|
||||
type: fixed
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Allow disabling build stage for Auto Devops
|
||||
merge_request: 48638
|
||||
author: Shane Davidson @shanekdavidson
|
||||
type: added
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: api_caching_branches
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61157
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/330371
|
||||
milestone: '13.12'
|
||||
type: development
|
||||
group: group::source code
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: invite_signup_page_interaction
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60939
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/growth/team-tasks/-/issues/379
|
||||
milestone: '13.12'
|
||||
type: experiment
|
||||
group: group::expansion
|
||||
default_enabled: false
|
||||
|
|
@ -56,6 +56,7 @@ Rails.application.routes.draw do
|
|||
end
|
||||
|
||||
resource :experience_level, only: [:show, :update]
|
||||
resources :invites, only: [:new, :create]
|
||||
|
||||
Gitlab.ee do
|
||||
resources :groups, only: [:new, :create]
|
||||
|
|
|
|||
|
|
@ -853,9 +853,9 @@ Parameters for all comments:
|
|||
| `position[start_sha]` | string | yes | SHA referencing commit in target branch |
|
||||
| `position[head_sha]` | string | yes | SHA referencing HEAD of this merge request |
|
||||
| `position[position_type]` | string | yes | Type of the position reference', allowed values: `text` or `image` |
|
||||
| `position[new_path]` | string | no | File path after change |
|
||||
| `position[new_path]` | string | yes (if the position type is `text`) | File path after change |
|
||||
| `position[new_line]` | integer | no | Line number after change (for `text` diff notes) |
|
||||
| `position[old_path]` | string | no | File path before change |
|
||||
| `position[old_path]` | string | yes (if the position type is `text`) | File path before change |
|
||||
| `position[old_line]` | integer | no | Line number before change (for `text` diff notes) |
|
||||
| `position[line_range]` | hash | no | Line range for a multi-line diff note |
|
||||
| `position[width]` | integer | no | Width of the image (for `image` diff notes) |
|
||||
|
|
@ -863,10 +863,63 @@ Parameters for all comments:
|
|||
| `position[x]` | float | no | X coordinate (for `image` diff notes) |
|
||||
| `position[y]` | float | no | Y coordinate (for `image` diff notes) |
|
||||
|
||||
#### Create a new thread on the overview page
|
||||
|
||||
```shell
|
||||
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/discussions?body=comment"
|
||||
```
|
||||
|
||||
#### Create a new thread in the merge request diff
|
||||
|
||||
- Both `position[old_path]` and `position[new_path]` are required and must refer to the file path before and after the change.
|
||||
- To create a thread on an added line (highlighted in green in the merge request diff), use `position[new_line]` and don't include `position[old_line]`.
|
||||
- To create a thread on a removed line (highlighted in red in the merge request diff), use `position[old_line]` and don't include `position[new_line]`.
|
||||
- To create a thread on an unchanged line, include both `position[new_line]` and `position[old_line]` for the line. These positions might not be the same if earlier changes in the file changed the line number. This is a bug that we plan to fix in [GraphQL `createDiffNote` forces clients to compute redundant information (#325161)](https://gitlab.com/gitlab-org/gitlab/-/issues/325161).
|
||||
- If you specify incorrect `base`/`head`/`start` `SHA` parameters, you might run into the following bug: [Merge request comments receive "download" link instead of inline code (#296829)](https://gitlab.com/gitlab-org/gitlab/-/issues/296829).
|
||||
|
||||
To create a new thread:
|
||||
|
||||
1. [Get the latest merge request version](merge_requests.md#get-mr-diff-versions):
|
||||
|
||||
```shell
|
||||
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/merge_requests/11/versions"
|
||||
````
|
||||
|
||||
1. Note the details of the latest version, which is listed first in the response array.
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": 164560414,
|
||||
"head_commit_sha": "f9ce7e16e56c162edbc9e480108041cf6b0291fe",
|
||||
"base_commit_sha": "5e6dffa282c5129aa67cd227a0429be21bfdaf80",
|
||||
"start_commit_sha": "5e6dffa282c5129aa67cd227a0429be21bfdaf80",
|
||||
"created_at": "2021-03-30T09:18:27.351Z",
|
||||
"merge_request_id": 93958054,
|
||||
"state": "collected",
|
||||
"real_size": "2"
|
||||
},
|
||||
"previous versions are here"
|
||||
]
|
||||
```
|
||||
|
||||
1. Create a new diff thread. This example creates a thread on an added line:
|
||||
|
||||
```shell
|
||||
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>"\
|
||||
--form 'position[position_type]=text'\
|
||||
--form 'position[base_sha]=<use base_commit_sha from the versions response>'\
|
||||
--form 'position[head_sha]=<use head_commit_sha from the versions response>'\
|
||||
--form 'position[start_sha]=<use start_commit_sha from the versions response>'\
|
||||
--form 'position[new_path]=file.js'\
|
||||
--form 'position[old_path]=file.js'\
|
||||
--form 'position[new_line]=18'\
|
||||
--form 'body=test comment body'\
|
||||
"https://gitlab.example.com/api/v4/projects/5/merge_requests/11/discussions"
|
||||
```
|
||||
|
||||
#### Parameters for multiline comments
|
||||
|
||||
Parameters for multiline comments only:
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ When requested across groups or projects, it's expected to be the same as the `f
|
|||
|
||||
## List issues
|
||||
|
||||
> Moved `weight` to [GitLab Premium](https://about.gitlab.com/pricing/) due to Starter/Bronze being [discontinued](https://about.gitlab.com/blog/2021/01/26/new-gitlab-product-subscription-model/) in 13.9.
|
||||
> Moved `weight` to GitLab Premium in 13.9.
|
||||
|
||||
Get all issues the authenticated user has access to. By default it
|
||||
returns only issues created by the current user. To get all issues,
|
||||
|
|
@ -233,7 +233,7 @@ that closed the issue still exists.
|
|||
|
||||
## List group issues
|
||||
|
||||
> Moved `weight` to [GitLab Premium](https://about.gitlab.com/pricing/) due to Starter/Bronze being [discontinued](https://about.gitlab.com/blog/2021/01/26/new-gitlab-product-subscription-model/) in 13.9.
|
||||
> Moved `weight` to GitLab Premium in 13.9.
|
||||
|
||||
Get a list of a group's issues.
|
||||
|
||||
|
|
@ -437,7 +437,7 @@ the issue still exists.
|
|||
|
||||
## List project issues
|
||||
|
||||
> Moved `weight` to [GitLab Premium](https://about.gitlab.com/pricing/) due to Starter/Bronze being [discontinued](https://about.gitlab.com/blog/2021/01/26/new-gitlab-product-subscription-model/) in 13.9.
|
||||
> Moved `weight` to GitLab Premium in 13.9.
|
||||
|
||||
Get a list of a project's issues.
|
||||
|
||||
|
|
@ -972,7 +972,7 @@ the issue still exists.
|
|||
|
||||
## New issue
|
||||
|
||||
> Moved `weight` to [GitLab Premium](https://about.gitlab.com/pricing/) due to Starter/Bronze being [discontinued](https://about.gitlab.com/blog/2021/01/26/new-gitlab-product-subscription-model/) in 13.9.
|
||||
> Moved `weight` to GitLab Premium in 13.9.
|
||||
|
||||
Creates a new project issue.
|
||||
|
||||
|
|
@ -1127,7 +1127,7 @@ See [Issues rate limits](../user/admin_area/settings/rate_limit_on_issues_creati
|
|||
|
||||
## Edit issue
|
||||
|
||||
> Moved `weight` to [GitLab Premium](https://about.gitlab.com/pricing/) due to Starter/Bronze being [discontinued](https://about.gitlab.com/blog/2021/01/26/new-gitlab-product-subscription-model/) in 13.9.
|
||||
> Moved `weight` to GitLab Premium in 13.9.
|
||||
|
||||
Updates an existing project issue. This call is also used to mark an issue as
|
||||
closed.
|
||||
|
|
|
|||
|
|
@ -387,6 +387,8 @@ The following table lists variables used to disable jobs.
|
|||
|----------------------------------------|---------------------------------|-----------------------|-----------------|
|
||||
| `.fuzz_base` | `COVFUZZ_DISABLED` | [From GitLab 13.2](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/34984) | [Read more](../../user/application_security/coverage_fuzzing/) about how `.fuzz_base` provide capability for your own jobs. If the variable is present, your jobs aren't created. |
|
||||
| `apifuzzer_fuzz` | `API_FUZZING_DISABLED` | [From GitLab 13.3](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/39135) | If the variable is present, the job isn't created. |
|
||||
| `build` | `BUILD_DISABLED` | | If the variable is present, the job isn't created. |
|
||||
| `build_artifact` | `BUILD_DISABLED` | | If the variable is present, the job isn't created. |
|
||||
| `bandit-sast` | `SAST_DISABLED` | | If the variable is present, the job isn't created. |
|
||||
| `brakeman-sast` | `SAST_DISABLED` | | If the variable is present, the job isn't created. |
|
||||
| `bundler-audit-dependency_scanning` | `DEPENDENCY_SCANNING_DISABLED` | | If the variable is present, the job isn't created. |
|
||||
|
|
|
|||
|
|
@ -6,8 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
---
|
||||
# Contribution Analytics **(PREMIUM)**
|
||||
|
||||
> - Introduced in [GitLab Starter](https://about.gitlab.com/pricing/) 8.3.
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3090) for subgroups in GitLab 12.2.
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3090) in GitLab 12.2 for subgroups.
|
||||
|
||||
With Contribution Analytics you can get an overview of the following activity in your
|
||||
group:
|
||||
|
|
@ -16,8 +15,7 @@ group:
|
|||
- Merge requests
|
||||
- Push events
|
||||
|
||||
To view the Contribution Analytics, go to your group's **Analytics > Contribution Analytics**
|
||||
page.
|
||||
To view the Contribution Analytics, go to your group and select **Analytics > Contribution**.
|
||||
|
||||
## Use cases
|
||||
|
||||
|
|
|
|||
|
|
@ -6,9 +6,11 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
# Group DevOps Adoption **(ULTIMATE)**
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/321083) as a [Beta feature](https://about.gitlab.com/handbook/product/gitlab-the-product/#beta) in GitLab 13.11.
|
||||
> - [Deployed behind a feature flag](../../../user/feature_flags.md), enabled by default.
|
||||
> - Not recommended for production use.
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/321083) in GitLab 13.11 as a [Beta feature](https://about.gitlab.com/handbook/product/gitlab-the-product/#beta).
|
||||
> - [Deployed behind a feature flag](../../../user/feature_flags.md), disabled by default.
|
||||
> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/323159) in GitLab 13.12.
|
||||
> - Enabled on GitLab.com.
|
||||
> - For GitLab self-managed instances, GitLab administrators can opt to [disable it](#enable-or-disable-group-devops-adoption). **(ULTIMATE SELF)**
|
||||
|
||||
This in-development feature might not be available for your use. There can be
|
||||
[risks when enabling features still in development](../../feature_flags.md#risks-when-enabling-features-still-in-development).
|
||||
|
|
@ -41,7 +43,65 @@ With DevOps Adoption you can:
|
|||
|
||||

|
||||
|
||||
## Enable or disable Group DevOps Adoption **(ULTIMATE)**
|
||||
## Enable data processing
|
||||
|
||||
Group DevOps Adoption relies on data that has been gathered by a weekly data processing task.
|
||||
This task is disabled by default.
|
||||
|
||||
To begin using Group DevOps Adoption, access the feature for the first time. GitLab automatically
|
||||
enables the data processing for that group. The group data doesn't appear immediately, because
|
||||
GitLab requires around a minute to process it.
|
||||
|
||||
## What is displayed
|
||||
|
||||
DevOps Adoption displays feature adoption data for the given group
|
||||
and any added sub-groups for the current calendar month.
|
||||
Each group appears as a separate row in the table.
|
||||
For each row, a feature is considered "adopted" if it has been used in a project in the given group
|
||||
during the time period (including projects in any sub-groups of the given group).
|
||||
|
||||
You should expect adoption to be lower at the beginning of the month,
|
||||
before you have had an opportunity to use all the features listed in the table.
|
||||
|
||||
In the future [we plan to implement](https://gitlab.com/gitlab-org/gitlab/-/issues/329708)
|
||||
a rolling 30-day perspective instead.
|
||||
|
||||
## When is a feature considered adopted
|
||||
|
||||
A feature is considered "adopted" if it has been used anywhere in the group in the specified time.
|
||||
For example, if an issue was created in one project in a group, the group is considered to have
|
||||
"adopted" issues in that time.
|
||||
|
||||
## No penalties for common adoption patterns
|
||||
|
||||
DevOps Adoption is designed not to penalize for any circumstances or practices that are common in DevOps.
|
||||
Following this guideline, GitLab doesn't penalize for:
|
||||
|
||||
1. Having dormant projects. It's common for groups to have a mix of active and dormant projects,
|
||||
so we should not consider adoption to be low if there are relatively many dormant projects.
|
||||
This means we should not measure adoption by how many projects in the group have used a feature,
|
||||
only by whether a feature was used anywhere in the group.
|
||||
1. GitLab adding new features over time. It's common for group feature usage to be consistent
|
||||
over time, so we should not consider adoption to have decreased if GitLab adds features.
|
||||
This means we should not measure adoption by percentages, only total counts.
|
||||
|
||||
## Add a sub-group
|
||||
|
||||
DevOps Adoption can also display data for sub-groups within the given group,
|
||||
to show you differences in adoption across the group.
|
||||
To add a sub-group to your Group DevOps Adoption report:
|
||||
|
||||
1. Select **Add/remove sub-groups**.
|
||||
1. Select the sub-group you want to add and select **Save changes**.
|
||||
|
||||
The sub-group data might not appear immediately, because GitLab requires around a minute to collect
|
||||
the data.
|
||||
|
||||
Please note that the sub-group data might not appear immediately,
|
||||
because GitLab requires a few moments to collect the data.
|
||||
Generally the data will be visible in less than one minute.
|
||||
|
||||
## Enable or disable Group DevOps Adoption **(ULTIMATE SELF)**
|
||||
|
||||
Group DevOps Adoption is under development and not ready for production use. It is
|
||||
deployed behind a feature flag that is **enabled by default**.
|
||||
|
|
|
|||
|
|
@ -47,13 +47,25 @@ module API
|
|||
|
||||
merged_branch_names = repository.merged_branch_names(branches.map(&:name))
|
||||
|
||||
present(
|
||||
branches,
|
||||
with: Entities::Branch,
|
||||
current_user: current_user,
|
||||
project: user_project,
|
||||
merged_branch_names: merged_branch_names
|
||||
)
|
||||
if Feature.enabled?(:api_caching_branches, user_project, type: :development, default_enabled: :yaml)
|
||||
present_cached(
|
||||
branches,
|
||||
with: Entities::Branch,
|
||||
current_user: current_user,
|
||||
project: user_project,
|
||||
merged_branch_names: merged_branch_names,
|
||||
expires_in: 10.minutes,
|
||||
cache_context: -> (branch) { [current_user&.cache_key, merged_branch_names.include?(branch.name)] }
|
||||
)
|
||||
else
|
||||
present(
|
||||
branches,
|
||||
with: Entities::Branch,
|
||||
current_user: current_user,
|
||||
project: user_project,
|
||||
merged_branch_names: merged_branch_names
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
resource ':id/repository/branches/:branch', requirements: BRANCH_ENDPOINT_REQUIREMENTS do
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ build:
|
|||
fi
|
||||
- /build/build.sh
|
||||
rules:
|
||||
- if: '$BUILD_DISABLED'
|
||||
when: never
|
||||
- if: '$AUTO_DEVOPS_PLATFORM_TARGET == "EC2"'
|
||||
when: never
|
||||
- if: '$CI_COMMIT_TAG || $CI_COMMIT_BRANCH'
|
||||
|
|
@ -26,4 +28,6 @@ build_artifact:
|
|||
- printf "To build your project, please create a build_artifact job into your .gitlab-ci.yml file.\nMore information at https://docs.gitlab.com/ee/ci/cloud_deployment\n"
|
||||
- exit 1
|
||||
rules:
|
||||
- if: '$BUILD_DISABLED'
|
||||
when: never
|
||||
- if: '$AUTO_DEVOPS_PLATFORM_TARGET == "EC2"'
|
||||
|
|
|
|||
|
|
@ -28,6 +28,10 @@ module Gitlab
|
|||
def state
|
||||
active? ? :active : :stale
|
||||
end
|
||||
|
||||
def cache_key
|
||||
"branch:" + Digest::SHA1.hexdigest([name, target, dereferenced_target&.sha].join(':'))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1520,9 +1520,15 @@ msgstr ""
|
|||
msgid "APIFuzzing|$VariableWithUsername"
|
||||
msgstr ""
|
||||
|
||||
msgid "APIFuzzing|/folder/example_file.har"
|
||||
msgstr ""
|
||||
|
||||
msgid "APIFuzzing|/folder/example_file.json"
|
||||
msgstr ""
|
||||
|
||||
msgid "APIFuzzing|/folder/example_file.postman_collection.json"
|
||||
msgstr ""
|
||||
|
||||
msgid "APIFuzzing|API Fuzzing Configuration"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -1562,19 +1568,16 @@ msgstr ""
|
|||
msgid "APIFuzzing|Enter the name of the variable containing the username. For example, $VariableWithUsername."
|
||||
msgstr ""
|
||||
|
||||
msgid "APIFuzzing|Ex: Project_Test/File/example_fuzz"
|
||||
msgstr ""
|
||||
|
||||
msgid "APIFuzzing|Ex: Project_Test/File/example_fuzz.har"
|
||||
msgid "APIFuzzing|File path containing APIs to be tested. For example, /folder/example_file.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
|
||||
msgstr ""
|
||||
|
||||
msgid "APIFuzzing|File path containing APIs to be tested. For example, /folder/example_file.json."
|
||||
msgstr ""
|
||||
|
||||
msgid "APIFuzzing|Generate code snippet"
|
||||
msgid "APIFuzzing|File path containing requests to be tested. For example, /folder/example_file.postman_collection.json."
|
||||
msgstr ""
|
||||
|
||||
msgid "APIFuzzing|HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
|
||||
msgid "APIFuzzing|Generate code snippet"
|
||||
msgstr ""
|
||||
|
||||
msgid "APIFuzzing|Make sure your credentials are secured"
|
||||
|
|
@ -1583,9 +1586,6 @@ msgstr ""
|
|||
msgid "APIFuzzing|Password for basic authentication"
|
||||
msgstr ""
|
||||
|
||||
msgid "APIFuzzing|Postman collections are a group of saved requests you can organize into folders."
|
||||
msgstr ""
|
||||
|
||||
msgid "APIFuzzing|Predefined profiles"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -9427,6 +9427,9 @@ msgstr ""
|
|||
msgid "Create your group"
|
||||
msgstr ""
|
||||
|
||||
msgid "Create your own profile to collaborate with your teammates in issues, merge requests, and more."
|
||||
msgstr ""
|
||||
|
||||
msgid "Create/import your first project"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -18384,6 +18387,9 @@ msgstr ""
|
|||
msgid "Iterations|Duration"
|
||||
msgstr ""
|
||||
|
||||
msgid "Iterations|Error loading iteration cadences."
|
||||
msgstr ""
|
||||
|
||||
msgid "Iterations|Future iterations"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -18393,6 +18399,9 @@ msgstr ""
|
|||
msgid "Iterations|New iteration cadence"
|
||||
msgstr ""
|
||||
|
||||
msgid "Iterations|No iteration cadences to show."
|
||||
msgstr ""
|
||||
|
||||
msgid "Iterations|Number of future iterations you would like to have scheduled"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -18807,6 +18816,9 @@ msgstr ""
|
|||
msgid "Join Zoom meeting"
|
||||
msgstr ""
|
||||
|
||||
msgid "Join your team"
|
||||
msgstr ""
|
||||
|
||||
msgid "Joined %{time_ago}"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -59,37 +59,37 @@ module QA
|
|||
|
||||
def set_lfs_enabled
|
||||
expand_content(:permission_lfs_2fa_content)
|
||||
check_element(:lfs_checkbox)
|
||||
check_element(:lfs_checkbox, true)
|
||||
click_element(:save_permissions_changes_button)
|
||||
end
|
||||
|
||||
def set_lfs_disabled
|
||||
expand_content(:permission_lfs_2fa_content)
|
||||
uncheck_element(:lfs_checkbox)
|
||||
uncheck_element(:lfs_checkbox, true)
|
||||
click_element(:save_permissions_changes_button)
|
||||
end
|
||||
|
||||
def set_request_access_enabled
|
||||
expand_content(:permission_lfs_2fa_content)
|
||||
check_element(:request_access_checkbox)
|
||||
check_element(:request_access_checkbox, true)
|
||||
click_element(:save_permissions_changes_button)
|
||||
end
|
||||
|
||||
def set_request_access_disabled
|
||||
expand_content(:permission_lfs_2fa_content)
|
||||
uncheck_element(:request_access_checkbox)
|
||||
uncheck_element(:request_access_checkbox, true)
|
||||
click_element(:save_permissions_changes_button)
|
||||
end
|
||||
|
||||
def set_require_2fa_enabled
|
||||
expand_content(:permission_lfs_2fa_content)
|
||||
check_element(:require_2fa_checkbox)
|
||||
check_element(:require_2fa_checkbox, true)
|
||||
click_element(:save_permissions_changes_button)
|
||||
end
|
||||
|
||||
def set_require_2fa_disabled
|
||||
expand_content(:permission_lfs_2fa_content)
|
||||
uncheck_element(:require_2fa_checkbox)
|
||||
uncheck_element(:require_2fa_checkbox, true)
|
||||
click_element(:save_permissions_changes_button)
|
||||
end
|
||||
|
||||
|
|
@ -102,10 +102,10 @@ module QA
|
|||
def toggle_request_access
|
||||
expand_content(:permission_lfs_2fa_content)
|
||||
|
||||
if find_element(:request_access_checkbox).checked?
|
||||
uncheck_element(:request_access_checkbox)
|
||||
if find_element(:request_access_checkbox, visible: false).checked?
|
||||
uncheck_element(:request_access_checkbox, true)
|
||||
else
|
||||
check_element(:request_access_checkbox)
|
||||
check_element(:request_access_checkbox, true)
|
||||
end
|
||||
|
||||
click_element(:save_permissions_changes_button)
|
||||
|
|
|
|||
|
|
@ -127,10 +127,38 @@ RSpec.describe InvitesController do
|
|||
expect(flash[:notice]).to include('create an account or sign in')
|
||||
end
|
||||
|
||||
it 'is redirected to a new registration with invite email param' do
|
||||
request
|
||||
context 'when it is part of our invite email experiment', :experiment, :aggregate_failures do
|
||||
let(:experience) { :control }
|
||||
|
||||
expect(response).to redirect_to(new_user_registration_path(invite_email: member.invite_email))
|
||||
before do
|
||||
stub_experiments(invite_signup_page_interaction: experience)
|
||||
end
|
||||
|
||||
it 'sets originating_member_id session key' do
|
||||
request
|
||||
|
||||
expect(session[:originating_member_id]).to eq(member.id)
|
||||
end
|
||||
|
||||
context 'with control experience' do
|
||||
it 'is redirected to a new registration with invite email param and flash message' do
|
||||
request
|
||||
|
||||
expect(response).to redirect_to(new_user_registration_path(invite_email: member.invite_email))
|
||||
expect(flash[:notice]).to eq 'To accept this invitation, create an account or sign in.'
|
||||
end
|
||||
end
|
||||
|
||||
context 'with candidate experience' do
|
||||
let(:experience) { :candidate }
|
||||
|
||||
it 'is redirected to a new invite registration with invite email param and no flash message' do
|
||||
request
|
||||
|
||||
expect(response).to redirect_to(new_users_sign_up_invite_path(invite_email: member.invite_email))
|
||||
expect(flash[:notice]).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'sets session keys for auto email confirmation on sign up' do
|
||||
|
|
|
|||
|
|
@ -187,6 +187,38 @@ RSpec.describe RegistrationsController do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when it is part of our invite_signup_page_interaction experiment', :experiment do
|
||||
let_it_be(:member) { create(:project_member, :invited, invite_email: user_params.dig(:user, :email)) }
|
||||
|
||||
let(:originating_member_id) { member.id }
|
||||
let(:session_params) do
|
||||
{
|
||||
invite_email: user_params.dig(:user, :email),
|
||||
originating_member_id: originating_member_id
|
||||
}
|
||||
end
|
||||
|
||||
context 'when member exists from the session key value' do
|
||||
it 'tracks the experiment' do
|
||||
expect(experiment(:invite_signup_page_interaction)).to track(:form_submission)
|
||||
.with_context(actor: member)
|
||||
.on_next_instance
|
||||
|
||||
subject
|
||||
end
|
||||
end
|
||||
|
||||
context 'when member does not exist from the session key value' do
|
||||
let(:originating_member_id) { -1 }
|
||||
|
||||
it 'tracks the experiment' do
|
||||
expect(experiment(:invite_signup_page_interaction)).not_to track(:form_submission)
|
||||
|
||||
subject
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when invite email matches email used on registration' do
|
||||
let(:session_params) { { invite_email: user_params.dig(:user, :email) } }
|
||||
|
||||
|
|
|
|||
|
|
@ -24,13 +24,13 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
|
|||
visit user_confirmation_path(confirmation_token: new_user_token)
|
||||
end
|
||||
|
||||
def fill_in_sign_up_form(new_user)
|
||||
def fill_in_sign_up_form(new_user, submit_button_text = 'Register')
|
||||
fill_in 'new_user_first_name', with: new_user.first_name
|
||||
fill_in 'new_user_last_name', with: new_user.last_name
|
||||
fill_in 'new_user_username', with: new_user.username
|
||||
fill_in 'new_user_email', with: new_user.email
|
||||
fill_in 'new_user_password', with: new_user.password
|
||||
click_button 'Register'
|
||||
click_button submit_button_text
|
||||
end
|
||||
|
||||
def fill_in_sign_in_form(user)
|
||||
|
|
@ -50,7 +50,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
|
|||
visit invite_path(group_invite.raw_invite_token)
|
||||
end
|
||||
|
||||
it 'renders sign in page with sign in notice' do
|
||||
it 'renders sign up page with sign up notice' do
|
||||
expect(current_path).to eq(new_user_registration_path)
|
||||
expect(page).to have_content('To accept this invitation, create an account or sign in')
|
||||
end
|
||||
|
|
@ -149,30 +149,11 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when soft email confirmation is not enabled' do
|
||||
before do
|
||||
allow(User).to receive(:allow_unconfirmed_access_for).and_return 0
|
||||
end
|
||||
it 'signs up and redirects to the group activity page with all the project/groups invitation automatically accepted' do
|
||||
fill_in_sign_up_form(new_user)
|
||||
fill_in_welcome_form
|
||||
|
||||
it 'signs up and redirects to the group activity page with all the project/groups invitation automatically accepted' do
|
||||
fill_in_sign_up_form(new_user)
|
||||
fill_in_welcome_form
|
||||
|
||||
expect(current_path).to eq(activity_group_path(group))
|
||||
end
|
||||
end
|
||||
|
||||
context 'when soft email confirmation is enabled' do
|
||||
before do
|
||||
allow(User).to receive(:allow_unconfirmed_access_for).and_return 2.days
|
||||
end
|
||||
|
||||
it 'signs up and redirects to to the group activity page with all the project/groups invitation automatically accepted' do
|
||||
fill_in_sign_up_form(new_user)
|
||||
fill_in_welcome_form
|
||||
|
||||
expect(current_path).to eq(activity_group_path(group))
|
||||
end
|
||||
expect(current_path).to eq(activity_group_path(group))
|
||||
end
|
||||
|
||||
context 'the user sign-up using a different email address' do
|
||||
|
|
@ -211,6 +192,57 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
|
|||
end
|
||||
end
|
||||
|
||||
context 'with invite_signup_page_interaction experiment on', :experiment do
|
||||
context 'with control experience' do
|
||||
before do
|
||||
stub_experiments(invite_signup_page_interaction: :control)
|
||||
end
|
||||
|
||||
it 'lands on invite sign up page and tracks the accepted invite' do
|
||||
expect(experiment(:invite_signup_page_interaction)).to track(:view)
|
||||
.with_context(actor: group_invite)
|
||||
.on_next_instance
|
||||
|
||||
visit invite_path(group_invite.raw_invite_token)
|
||||
|
||||
expect(current_path).to eq(new_user_registration_path)
|
||||
|
||||
expect(experiment(:invite_signup_page_interaction)).to track(:form_submission)
|
||||
.with_context(actor: group_invite)
|
||||
.on_next_instance
|
||||
|
||||
fill_in_sign_up_form(new_user, 'Register')
|
||||
|
||||
expect(current_path).to eq(users_sign_up_welcome_path)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with candidate experience on .com' do
|
||||
before do
|
||||
allow(Gitlab).to receive(:dev_env_or_com?).and_return(true)
|
||||
stub_experiments(invite_signup_page_interaction: :candidate)
|
||||
end
|
||||
|
||||
it 'lands on invite sign up page and tracks the accepted invite' do
|
||||
expect(experiment(:invite_signup_page_interaction)).to track(:view)
|
||||
.with_context(actor: group_invite)
|
||||
.on_next_instance
|
||||
|
||||
visit invite_path(group_invite.raw_invite_token)
|
||||
|
||||
expect(current_path).to eq(new_users_sign_up_invite_path)
|
||||
|
||||
expect(experiment(:invite_signup_page_interaction)).to track(:form_submission)
|
||||
.with_context(actor: group_invite)
|
||||
.on_next_instance
|
||||
|
||||
fill_in_sign_up_form(new_user, 'Continue')
|
||||
|
||||
expect(current_path).to eq(users_sign_up_welcome_path)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when declining the invitation' do
|
||||
context 'as an existing user' do
|
||||
let(:group_invite) { create(:group_member, user: user, group: group, created_by: owner) }
|
||||
|
|
|
|||
|
|
@ -11,8 +11,10 @@ describe('Package Files', () => {
|
|||
|
||||
const findAllRows = () => wrapper.findAll('[data-testid="file-row"');
|
||||
const findFirstRow = () => findAllRows().at(0);
|
||||
const findSecondRow = () => findAllRows().at(1);
|
||||
const findFirstRowDownloadLink = () => findFirstRow().find('[data-testid="download-link"');
|
||||
const findFirstRowCommitLink = () => findFirstRow().find('[data-testid="commit-link"');
|
||||
const findSecondRowCommitLink = () => findSecondRow().find('[data-testid="commit-link"');
|
||||
const findFirstRowFileIcon = () => findFirstRow().find(FileIcon);
|
||||
const findFirstRowCreatedAt = () => findFirstRow().find(TimeAgoTooltip);
|
||||
|
||||
|
|
@ -126,5 +128,14 @@ describe('Package Files', () => {
|
|||
expect(findFirstRowCommitLink().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when only one file lacks an associated pipeline', () => {
|
||||
it('renders the commit when it exists and not otherwise', () => {
|
||||
createComponent([npmFiles[0], mavenFiles[0]]);
|
||||
|
||||
expect(findFirstRowCommitLink().exists()).toBe(true);
|
||||
expect(findSecondRowCommitLink().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -77,8 +77,8 @@ RSpec.describe AuthHelper do
|
|||
end
|
||||
|
||||
context 'all providers are enabled to sign in' do
|
||||
it 'returns all the enabled providers from settings' do
|
||||
expect(helper.enabled_button_based_providers).to include('twitter', 'github', 'google_oauth2', 'openid_connect')
|
||||
it 'returns all the enabled providers from settings in expected order' do
|
||||
expect(helper.enabled_button_based_providers).to match(%w[google_oauth2 github twitter openid_connect])
|
||||
end
|
||||
|
||||
it 'puts google and github in the beginning' do
|
||||
|
|
@ -99,19 +99,19 @@ RSpec.describe AuthHelper do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'trial_enabled_button_based_providers' do
|
||||
it 'returns the intersection set of github & google_oauth2 with enabled providers' do
|
||||
describe 'popular_enabled_button_based_providers' do
|
||||
it 'returns the intersection set of popular & enabled providers', :aggregate_failures do
|
||||
allow(helper).to receive(:enabled_button_based_providers) { %w(twitter github google_oauth2) }
|
||||
|
||||
expect(helper.trial_enabled_button_based_providers).to eq(%w(github google_oauth2))
|
||||
expect(helper.popular_enabled_button_based_providers).to eq(%w(github google_oauth2))
|
||||
|
||||
allow(helper).to receive(:enabled_button_based_providers) { %w(google_oauth2 bitbucket) }
|
||||
|
||||
expect(helper.trial_enabled_button_based_providers).to eq(%w(google_oauth2))
|
||||
expect(helper.popular_enabled_button_based_providers).to eq(%w(google_oauth2))
|
||||
|
||||
allow(helper).to receive(:enabled_button_based_providers) { %w(bitbucket) }
|
||||
|
||||
expect(helper.trial_enabled_button_based_providers).to be_empty
|
||||
expect(helper.popular_enabled_button_based_providers).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe RegistrationsHelper do
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
|
||||
describe '#social_signin_enabled?' do
|
||||
before do
|
||||
allow(::Gitlab).to receive(:dev_env_or_com?).and_return(com)
|
||||
allow(view).to receive(:omniauth_enabled?).and_return(omniauth_enabled)
|
||||
allow(view).to receive(:button_based_providers_enabled?).and_return(button_based_providers_enabled)
|
||||
allow(view).to receive(:devise_mapping).and_return(double(omniauthable?: omniauthable))
|
||||
end
|
||||
|
||||
subject { helper.social_signin_enabled? }
|
||||
|
||||
where com: [true, false],
|
||||
omniauth_enabled: [true, false],
|
||||
omniauthable: [true, false],
|
||||
button_based_providers_enabled: [true, false]
|
||||
|
||||
with_them do
|
||||
let(:result) { com && omniauth_enabled && button_based_providers_enabled && omniauthable }
|
||||
|
||||
it { is_expected.to eq(result) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -44,6 +44,16 @@ RSpec.describe Gitlab::Git::Branch, :seed_helper do
|
|||
end
|
||||
end
|
||||
|
||||
describe "#cache_key" do
|
||||
subject { repository.branches.first }
|
||||
|
||||
it "returns a cache key that changes based on changeable values" do
|
||||
digest = Digest::SHA1.hexdigest([subject.name, subject.target, subject.dereferenced_target.sha].join(":"))
|
||||
|
||||
expect(subject.cache_key).to eq("branch:#{digest}")
|
||||
end
|
||||
end
|
||||
|
||||
describe '#size' do
|
||||
subject { super().size }
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ RSpec.describe API::Branches do
|
|||
end
|
||||
|
||||
it 'determines only a limited number of merged branch names' do
|
||||
expect(API::Entities::Branch).to receive(:represent).with(anything, has_up_to_merged_branch_names_count(2)).and_call_original
|
||||
expect(API::Entities::Branch).to receive(:represent).with(anything, has_up_to_merged_branch_names_count(2)).at_least(:once).and_call_original
|
||||
|
||||
get api(route, current_user), params: base_params.merge(per_page: 2)
|
||||
|
||||
|
|
@ -111,7 +111,7 @@ RSpec.describe API::Branches do
|
|||
end
|
||||
|
||||
it 'determines only a limited number of merged branch names' do
|
||||
expect(API::Entities::Branch).to receive(:represent).with(anything, has_up_to_merged_branch_names_count(2)).and_call_original
|
||||
expect(API::Entities::Branch).to receive(:represent).with(anything, has_up_to_merged_branch_names_count(2)).at_least(:once).and_call_original
|
||||
|
||||
get api(route, current_user), params: base_params.merge(per_page: 2)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe 'Registering from an invite' do
|
||||
let(:com) { true }
|
||||
|
||||
before do
|
||||
allow(Gitlab).to receive(:dev_env_or_com?).and_return(com)
|
||||
end
|
||||
|
||||
describe 'GET /users/sign_up/invites/new' do
|
||||
subject(:request) { get '/users/sign_up/invites/new' }
|
||||
|
||||
context 'when on .com' do
|
||||
it 'renders the template with expected text', :aggregate_failures do
|
||||
request
|
||||
|
||||
expect(response).to render_template('layouts/simple_registration')
|
||||
expect(response).to render_template(:new)
|
||||
expect(response.body).to include('Join your team')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when not on .com' do
|
||||
let(:com) { false }
|
||||
|
||||
it 'returns not found' do
|
||||
request
|
||||
|
||||
expect(response).to have_gitlab_http_status(:not_found)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST /users/sign_up/invites' do
|
||||
subject(:request) do
|
||||
post '/users/sign_up/invites',
|
||||
params: {
|
||||
user: {
|
||||
first_name: 'first',
|
||||
last_name: 'last',
|
||||
username: 'new_username',
|
||||
email: 'new@user.com',
|
||||
password: 'Any_password'
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
context 'when on .com' do
|
||||
it 'creates a user' do
|
||||
expect { request }.to change(User, :count).by(1)
|
||||
|
||||
expect(response).to have_gitlab_http_status(:found)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when not on .com' do
|
||||
let(:com) { false }
|
||||
|
||||
it 'returns not found' do
|
||||
request
|
||||
|
||||
expect(response).to have_gitlab_http_status(:not_found)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Reference in New Issue