Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-11-24 00:12:33 +00:00
parent abd24a801e
commit 1c27dcaf69
54 changed files with 259 additions and 138 deletions

View file

@ -3,7 +3,7 @@ export const loadViewer = (type) => {
case 'empty':
return () => import(/* webpackChunkName: 'blob_empty_viewer' */ './empty_viewer.vue');
case 'text':
return gon.features.refactorTextViewer
return gon.features.highlightJs
? () => import(/* webpackChunkName: 'blob_text_viewer' */ './text_viewer.vue')
: null;
case 'download':

View file

@ -92,7 +92,6 @@ class GroupsController < Groups::ApplicationController
if @group.import_state&.in_progress?
redirect_to group_import_path(@group)
else
publish_invite_members_for_task_experiment
render_show_html
end
end
@ -380,13 +379,6 @@ class GroupsController < Groups::ApplicationController
def captcha_required?
captcha_enabled? && !params[:parent_id]
end
def publish_invite_members_for_task_experiment
return unless params[:open_modal] == 'invite_members_for_task'
return unless current_user&.can?(:admin_group_member, @group)
experiment(:invite_members_for_task, namespace: @group).publish_to_client
end
end
GroupsController.prepend_mod_with('GroupsController')

View file

@ -44,7 +44,7 @@ class Projects::BlobController < Projects::ApplicationController
before_action do
push_frontend_feature_flag(:refactor_blob_viewer, @project, default_enabled: :yaml)
push_frontend_feature_flag(:refactor_text_viewer, @project, default_enabled: :yaml)
push_frontend_feature_flag(:highlight_js, @project, default_enabled: :yaml)
push_frontend_feature_flag(:consolidated_edit_button, @project, default_enabled: :yaml)
push_licensed_feature(:file_locks) if @project.licensed_feature_available?(:file_locks)
end

View file

@ -35,7 +35,7 @@ class ProjectsController < Projects::ApplicationController
before_action do
push_frontend_feature_flag(:lazy_load_commits, @project, default_enabled: :yaml)
push_frontend_feature_flag(:refactor_blob_viewer, @project, default_enabled: :yaml)
push_frontend_feature_flag(:refactor_text_viewer, @project, default_enabled: :yaml)
push_frontend_feature_flag(:highlight_js, @project, default_enabled: :yaml)
push_frontend_feature_flag(:increase_page_size_exponentially, @project, default_enabled: :yaml)
push_frontend_feature_flag(:new_dir_modal, @project, default_enabled: :yaml)
end

View file

@ -72,8 +72,6 @@ module Registrations
end
def show_tasks_to_be_done?
return unless experiment(:invite_members_for_task).enabled?
MemberTask.for_members(current_user.members).exists?
end

View file

@ -83,9 +83,8 @@ module InviteMembersHelper
def show_invite_members_for_task?(source)
return unless current_user
invite_members_for_task_experiment = experiment(:invite_members_for_task).enabled? && params[:open_modal] == 'invite_members_for_task'
invite_for_help_continuous_onboarding = source.is_a?(Project) && experiment(:invite_for_help_continuous_onboarding, namespace: source.namespace).variant.name == 'candidate'
invite_members_for_task_experiment || invite_for_help_continuous_onboarding
params[:open_modal] == 'invite_members_for_task' || invite_for_help_continuous_onboarding
end
def tasks_to_be_done_options

View file

@ -405,6 +405,16 @@ module ProjectsHelper
project.path_with_namespace
end
def fork_button_disabled_tooltip(project)
return unless current_user
if !current_user.can?(:fork_project, project)
s_("ProjectOverview|You don't have permission to fork this project")
elsif !current_user.can?(:create_fork)
s_('ProjectOverview|You have reached your project limit')
end
end
private
def tab_ability_map

View file

@ -417,11 +417,9 @@ class Member < ApplicationRecord
def after_accept_invite
post_create_hook
if experiment(:invite_members_for_task).enabled?
run_after_commit_or_now do
if member_task
TasksToBeDone::CreateWorker.perform_async(member_task.id, created_by_id, [user_id.to_i])
end
run_after_commit_or_now do
if member_task
TasksToBeDone::CreateWorker.perform_async(member_task.id, created_by_id, [user_id.to_i])
end
end
end

View file

@ -51,9 +51,7 @@ class Namespace < ApplicationRecord
# This should _not_ be `inverse_of: :namespace`, because that would also set
# `user.namespace` when this user creates a group with themselves as `owner`.
# TODO: can this be moved into the UserNamespace class?
# evaluate in issue https://gitlab.com/gitlab-org/gitlab/-/issues/341070
belongs_to :owner, class_name: "User"
belongs_to :owner, class_name: 'User'
belongs_to :parent, class_name: "Namespace"
has_many :children, -> { where(type: Group.sti_name) }, class_name: "Namespace", foreign_key: :parent_id

View file

@ -1,7 +1,5 @@
# frozen_string_literal: true
# TODO: currently not created/mapped in the database, will be done in another issue
# https://gitlab.com/gitlab-org/gitlab/-/issues/341070
module Namespaces
####################################################################
# PLEASE DO NOT OVERRIDE METHODS IN THIS CLASS!

View file

@ -117,7 +117,6 @@ module Members
end
def create_tasks_to_be_done
return unless experiment(:invite_members_for_task).enabled?
return if params[:tasks_to_be_done].blank? || params[:tasks_project_id].blank?
valid_members = members.select { |member| member.valid? && member.member_task.valid? }

View file

@ -65,7 +65,6 @@ module Members
end
def create_member_task
return unless experiment(:invite_members_for_task).enabled?
return unless member.persisted?
return if member_task_attributes.value?(nil)

View file

@ -1,16 +1,18 @@
- unless @project.empty_repo?
- if current_user && can?(current_user, :fork_project, @project)
- if current_user
.count-badge.btn-group
- if current_user.already_forked?(@project) && current_user.manageable_namespaces.size < 2
= link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: s_('ProjectOverview|Go to your fork'), class: 'gl-button btn btn-default btn-sm has-tooltip fork-btn' do
= sprite_icon('fork', css_class: 'icon')
%span= s_('ProjectOverview|Fork')
- else
- can_create_fork = current_user.can?(:create_fork)
- disabled_fork_tooltip = s_('ProjectOverview|You have reached your project limit')
%span.btn-group.has-tooltip{ title: (disabled_fork_tooltip unless can_create_fork) }
= link_to new_project_fork_path(@project), class: "gl-button btn btn-default btn-sm fork-btn #{' disabled' unless can_create_fork }", 'aria-label' => (disabled_fork_tooltip unless can_create_fork) do
- disabled_tooltip = fork_button_disabled_tooltip(@project)
- count_class = 'disabled' unless can?(current_user, :download_code, @project)
- button_class = 'disabled' if disabled_tooltip
%span.btn-group{ class: ('has-tooltip' if disabled_tooltip), title: disabled_tooltip }
= link_to new_project_fork_path(@project), class: "gl-button btn btn-default btn-sm fork-btn #{button_class}" do
= sprite_icon('fork', css_class: 'icon')
%span= s_('ProjectOverview|Fork')
= link_to project_forks_path(@project), title: n_(s_('ProjectOverview|Forks'), s_('ProjectOverview|Forks'), @project.forks_count), class: 'gl-button btn btn-default btn-sm count has-tooltip' do
= link_to project_forks_path(@project), title: n_(s_('ProjectOverview|Forks'), s_('ProjectOverview|Forks'), @project.forks_count), class: "gl-button btn btn-default btn-sm count has-tooltip #{count_class}" do
= @project.forks_count

View file

@ -1,8 +1,8 @@
---
name: invite_members_for_task
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69299
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/339747
milestone: '14.5'
type: experiment
group: group::activation
name: highlight_js
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75005
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/346257
milestone: '14.6'
type: development
group: group::source code
default_enabled: false

View file

@ -1,8 +0,0 @@
---
name: refactor_text_viewer
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70909
rollout_issue_url:
milestone: '14.4'
type: development
group: 'group::source code'
default_enabled: false

View file

@ -0,0 +1,9 @@
# frozen_string_literal: true
class ChangeDefaultValueOfLooseFkDeletedRecordsPartition < Gitlab::Database::Migration[1.0]
enable_lock_retries!
def change
change_column_default(:loose_foreign_keys_deleted_records, :partition, from: nil, to: 1)
end
end

View file

@ -0,0 +1,40 @@
# frozen_string_literal: true
class RemoveHardcodedPartitionFromLooseFkTriggerFunction < Gitlab::Database::Migration[1.0]
include Gitlab::Database::MigrationHelpers::LooseForeignKeyHelpers
enable_lock_retries!
def up
execute(<<~SQL)
CREATE OR REPLACE FUNCTION #{DELETED_RECORDS_INSERT_FUNCTION_NAME}()
RETURNS TRIGGER AS
$$
BEGIN
INSERT INTO loose_foreign_keys_deleted_records
(fully_qualified_table_name, primary_key_value)
SELECT TG_TABLE_SCHEMA || '.' || TG_TABLE_NAME, old_table.id FROM old_table;
RETURN NULL;
END
$$ LANGUAGE PLPGSQL
SQL
end
def down
execute(<<~SQL)
CREATE OR REPLACE FUNCTION #{DELETED_RECORDS_INSERT_FUNCTION_NAME}()
RETURNS TRIGGER AS
$$
BEGIN
INSERT INTO loose_foreign_keys_deleted_records
(partition, fully_qualified_table_name, primary_key_value)
SELECT 1, TG_TABLE_SCHEMA || '.' || TG_TABLE_NAME, old_table.id FROM old_table
ON CONFLICT DO NOTHING;
RETURN NULL;
END
$$ LANGUAGE PLPGSQL
SQL
end
end

View file

@ -0,0 +1 @@
8b1bb9758150151518f16307d3f145431000b7edf946fd44e54cf7301087b002

View file

@ -0,0 +1 @@
721f1ada9fe5a3d7e5da3750a43d5021a85a26e8adc4d649e7f0fff8cdf68344

View file

@ -27,9 +27,8 @@ CREATE FUNCTION insert_into_loose_foreign_keys_deleted_records() RETURNS trigger
AS $$
BEGIN
INSERT INTO loose_foreign_keys_deleted_records
(partition, fully_qualified_table_name, primary_key_value)
SELECT 1, TG_TABLE_SCHEMA || '.' || TG_TABLE_NAME, old_table.id FROM old_table
ON CONFLICT DO NOTHING;
(fully_qualified_table_name, primary_key_value)
SELECT TG_TABLE_SCHEMA || '.' || TG_TABLE_NAME, old_table.id FROM old_table;
RETURN NULL;
END
@ -1016,7 +1015,7 @@ ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PAR
CREATE TABLE loose_foreign_keys_deleted_records (
id bigint NOT NULL,
partition bigint NOT NULL,
partition bigint DEFAULT 1 NOT NULL,
primary_key_value bigint NOT NULL,
status smallint DEFAULT 1 NOT NULL,
created_at timestamp with time zone DEFAULT now() NOT NULL,
@ -1037,7 +1036,7 @@ ALTER SEQUENCE loose_foreign_keys_deleted_records_id_seq OWNED BY loose_foreign_
CREATE TABLE gitlab_partitions_static.loose_foreign_keys_deleted_records_1 (
id bigint DEFAULT nextval('loose_foreign_keys_deleted_records_id_seq'::regclass) NOT NULL,
partition bigint NOT NULL,
partition bigint DEFAULT 1 NOT NULL,
primary_key_value bigint NOT NULL,
status smallint DEFAULT 1 NOT NULL,
created_at timestamp with time zone DEFAULT now() NOT NULL,

View file

@ -595,7 +595,7 @@ User.active.count
User.billable.count
# The historical max on the instance as of the past year
::HistoricalData.max_historical_user_count
::HistoricalData.max_historical_user_count(from: 1.year.ago.beginning_of_day, to: Time.current.end_of_day)
```
Using cURL and jq (up to a max 100, see the [pagination docs](../../api/index.md#pagination)):

View file

@ -43,8 +43,8 @@ POST /projects/:id/invitations
| `expires_at` | string | no | A date string in the format YEAR-MONTH-DAY |
| `invite_source` | string | no | The source of the invitation that starts the member creation process. See [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/327120). |
| `areas_of_focus` | string | no | Areas the inviter wants the member to focus upon. |
| `tasks_to_be_done` | array of strings | no | Tasks the inviter wants the member to focus on. The tasks are added as issues to a specified project. The possible values are: `ci`, `code` and `issues`. If specified, requires `tasks_project_id`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69299) in GitLab 14.5 [with a flag](../administration/feature_flags.md) named `invite_members_for_task`. Disabled by default. |
| `tasks_project_id` | integer | no | The project ID in which to create the task issues. If specified, requires `tasks_to_be_done`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69299) in GitLab 14.5 [with a flag](../administration/feature_flags.md) named `invite_members_for_task`. Disabled by default. |
| `tasks_to_be_done` | array of strings | no | Tasks the inviter wants the member to focus on. The tasks are added as issues to a specified project. The possible values are: `ci`, `code` and `issues`. If specified, requires `tasks_project_id`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69299) in GitLab 14.6 |
| `tasks_project_id` | integer | no | The project ID in which to create the task issues. If specified, requires `tasks_to_be_done`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69299) in GitLab 14.6 |
```shell
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \

View file

@ -148,6 +148,13 @@ If you must refer to the checkbox, you can say it is selected or cleared. For ex
- Ensure the **Protect environment** checkbox is cleared.
- Ensure the **Protect environment** checkbox is selected.
## checkout, check out
Use **check out** as a verb. For the Git command, use `checkout`.
- Use `git checkout` to check out a branch locally.
- Check out the files you want to edit.
## CI/CD
CI/CD is always uppercase. No need to spell it out on first use.
@ -478,6 +485,19 @@ The word **once** means **one time**. Don't use it to mean **after** or **when**
- Do: When the process is complete...
- Do not: Once the process is complete...
## only
Put the word **only** next to the word it modifies.
- You can create only private projects.
In this example, **only** modifies the noun **projects**. The sentence means you can create one type of project--a private project.
- You can only create private projects.
In this example, **only** modifies the verb **create**. This sentence means that you can't perform other actions,
like deleting private projects, or adding users to them.
## Owner
When writing about the Owner role:

View file

@ -133,11 +133,9 @@ You can mark that content for translation with:
The `~/locale` module exports the following key functions for externalization:
- `__()` (double underscore parenthesis)
- `s__()` (namespaced double underscore parenthesis)
- `__()` Mark content for translation (note the double underscore).
- `s__()` Mark namespaced content for translation
- `n__()` Mark pluralized content for translation
- `__()` Mark content for translation (double underscore parenthesis).
- `s__()` Mark namespaced content for translation (s double underscore parenthesis).
- `n__()` Mark pluralized content for translation (n double underscore parenthesis).
```javascript
import { __, s__, n__ } from '~/locale';

View file

@ -135,6 +135,27 @@ with the following differences:
## Remove the GitLab Kubernetes Agent
1. Get the `<cluster-agent-id>` and the `<cluster-agent-token-id>` from a query in the interactive GraphQL explorer.
For GitLab.com, go to <https://gitlab.com/-/graphql-explorer> to open GraphQL Explorer.
For self-managed GitLab instances, go to `https://gitlab.example.com/-/graphql-explorer`, replacing `gitlab.example.com` with your own instance's URL.
```graphql
query{
project(fullPath: "<full-path-to-agent-configuration-project>") {
clusterAgent(name: "<agent-name>") {
id
tokens {
edges {
node {
id
}
}
}
}
}
}
```
1. Remove an Agent record with GraphQL by deleting the `clusterAgent` and the `clusterAgentToken`.
```graphql

View file

@ -12,7 +12,7 @@ type: howto
GitLab lists all devices that have logged into your account. You can
review the sessions, and revoke any you don't recognize.
## Listing all active sessions
## List all active sessions
To list all active sessions:
@ -29,7 +29,7 @@ To list all active sessions:
GitLab allows users to have up to 100 active sessions at once. If the number of active sessions
exceeds 100, the oldest ones are deleted.
## Revoking a session
## Revoke a session
To revoke an active session:
@ -40,7 +40,7 @@ To revoke an active session:
NOTE:
When any session is revoked all **Remember me** tokens for all
devices are revoked. See ['Why do I keep getting signed out?'](index.md#why-do-i-keep-getting-signed-out)
devices are revoked. See [Why do I keep getting signed out?](index.md#why-do-i-keep-getting-signed-out)
for more information about the **Remember me** feature.
<!-- ## Troubleshooting

View file

@ -260,6 +260,20 @@ To change your commit email:
1. In the **Commit email** dropdown list, select an email address.
1. Select **Update profile settings**.
## Change your primary email
Your primary email:
- Is the default email address for your login, commit email, and notification email.
- Must be already [linked to your user profile](#add-emails-to-your-user-profile).
To change your primary email:
1. In the top-right corner, select your avatar.
1. Select **Edit profile**.
1. In the **Email** field, enter your new email address.
1. Select **Update profile settings**.
### Use an automatically-generated private commit email
GitLab provides an automatically-generated private commit email address,

View file

@ -10,7 +10,12 @@ module BulkImports
ndjson_pipeline!
def transform(context, data)
return unless data
relation_hash, relation_index = data
return unless relation_hash
relation_definition = import_export_config.top_relation_tree(relation)
relation_object = deep_transform_relation!(relation_hash, relation, relation_definition) do |key, hash|

View file

@ -21,6 +21,7 @@ module Gitlab
from_union([failed_jobs, self.stuck])
}
scope :except_succeeded, -> { where(status: self.statuses.except(:succeeded).values) }
enum status: {
pending: 0,

View file

@ -18,6 +18,8 @@ module Gitlab
scope: [:job_class_name, :table_name, :column_name]
}
validate :validate_batched_jobs_status, if: -> { status_changed? && finished? }
scope :queue_order, -> { order(id: :asc) }
scope :queued, -> { where(status: [:active, :paused]) }
scope :for_configuration, ->(job_class_name, table_name, column_name, job_arguments) do
@ -133,6 +135,12 @@ module Gitlab
def optimize!
BatchOptimizer.new(self).optimize!
end
private
def validate_batched_jobs_status
errors.add(:batched_jobs, 'jobs need to be succeeded') if batched_jobs.except_succeeded.exists?
end
end
end
end

View file

@ -38,7 +38,7 @@ module Gitlab
end
def invite_members?
invite_members_for_task_experiment_enabled?
user.can?(:admin_group_member, group)
end
end
end

View file

@ -166,16 +166,6 @@ module Gitlab
link(s_('InProductMarketing|update your preferences'), preference_link)
end
def invite_members_for_task_experiment_enabled?
return unless user.can?(:admin_group_member, group)
experiment(:invite_members_for_task, namespace: group) do |e|
e.candidate { true }
e.record!
e.run
end
end
def validate_series!
raise ArgumentError, "Only #{total_series} series available for this track." unless @series.between?(0, total_series - 1)
end

View file

@ -62,7 +62,7 @@ module Gitlab
end
def invite_members?
invite_members_for_task_experiment_enabled?
user.can?(:admin_group_member, group)
end
private

View file

@ -66,7 +66,7 @@ module Gitlab
end
def invite_members?
invite_members_for_task_experiment_enabled?
user.can?(:admin_group_member, group)
end
private

View file

@ -27032,6 +27032,9 @@ msgstr ""
msgid "ProjectOverview|Unstar"
msgstr ""
msgid "ProjectOverview|You don't have permission to fork this project"
msgstr ""
msgid "ProjectOverview|You have reached your project limit"
msgstr ""

View file

@ -82,16 +82,6 @@ RSpec.describe GroupsController, factory_default: :keep do
expect(subject).to redirect_to group_import_path(group)
end
end
context 'publishing the invite_members_for_task experiment' do
it 'publishes the experiment data to the client' do
wrapped_experiment(experiment(:invite_members_for_task)) do |e|
expect(e).to receive(:publish_to_client)
end
get :show, params: { id: group.to_param, open_modal: 'invite_members_for_task' }, format: format
end
end
end
describe 'GET #details' do

View file

@ -101,10 +101,6 @@ RSpec.describe Registrations::WelcomeController do
context 'when tasks to be done are assigned' do
let!(:member1) { create(:group_member, user: user, tasks_to_be_done: %w(ci code)) }
before do
stub_experiments(invite_members_for_task: true)
end
it { is_expected.to redirect_to(issues_dashboard_path(assignee_username: user.username)) }
end
end

View file

@ -5,8 +5,6 @@ FactoryBot.define do
sequence(:name) { |n| "namespace#{n}" }
path { name.downcase.gsub(/\s/, '_') }
# TODO: can this be moved into the :user_namespace factory?
# evaluate in issue https://gitlab.com/gitlab-org/gitlab/-/issues/341070
owner { association(:user, strategy: :build, namespace: instance, username: path) }
trait :with_aggregation_schedule do

View file

@ -146,7 +146,7 @@ RSpec.describe "Issues > User edits issue", :js do
fill_in 'Comment', with: '/label ~syzygy'
click_button 'Comment'
expect(page).to have_text('added syzygy label just now')
expect(page).to have_text('added syzygy label just now', wait: 300)
page.within '.block.labels' do
# Remove `verisimilitude` label

View file

@ -59,10 +59,11 @@ RSpec.describe 'Project fork' do
context 'forking is disabled' do
let(:forking_access_level) { ProjectFeature::DISABLED }
it 'does not render fork button' do
it 'render a disabled fork button' do
visit project_path(project)
expect(page).not_to have_css('a', text: 'Fork')
expect(page).to have_css('a.disabled', text: 'Fork')
expect(page).to have_css('a.count', text: '0')
end
it 'does not render new project fork page' do
@ -80,10 +81,11 @@ RSpec.describe 'Project fork' do
end
context 'user is not a team member' do
it 'does not render fork button' do
it 'render a disabled fork button' do
visit project_path(project)
expect(page).not_to have_css('a', text: 'Fork')
expect(page).to have_css('a.disabled', text: 'Fork')
expect(page).to have_css('a.count', text: '0')
end
it 'does not render new project fork page' do
@ -102,6 +104,7 @@ RSpec.describe 'Project fork' do
visit project_path(project)
expect(page).to have_css('a', text: 'Fork')
expect(page).to have_css('a.count', text: '0')
expect(page).not_to have_css('a.disabled', text: 'Fork')
end

View file

@ -98,7 +98,7 @@ describe('Blob content viewer component', () => {
const findForkSuggestion = () => wrapper.findComponent(ForkSuggestion);
beforeEach(() => {
gon.features = { refactorTextViewer: true };
gon.features = { highlightJs: true };
isLoggedIn.mockReturnValue(true);
});

View file

@ -93,22 +93,17 @@ RSpec.describe InviteMembersHelper do
end
end
context 'the invite_members_for_task experiment' do
where(:invite_members_for_task_enabled?, :open_modal_param_present?, :logged_in?, :expected?) do
true | true | true | true
true | true | false | false
true | false | true | false
true | false | false | false
false | true | true | false
false | true | false | false
false | false | true | false
false | false | false | false
context 'inviting members for tasks' do
where(:open_modal_param_present?, :logged_in?, :expected?) do
true | true | true
true | false | false
false | true | false
false | false | false
end
with_them do
before do
allow(helper).to receive(:current_user).and_return(developer) if logged_in?
stub_experiments(invite_members_for_task: true) if invite_members_for_task_enabled?
allow(helper).to receive(:params).and_return({ open_modal: 'invite_members_for_task' }) if open_modal_param_present?
end

View file

@ -991,4 +991,31 @@ RSpec.describe ProjectsHelper do
expect(subject).to eq(project.path_with_namespace)
end
end
describe '#fork_button_disabled_tooltip' do
using RSpec::Parameterized::TableSyntax
subject { helper.fork_button_disabled_tooltip(project) }
where(:has_user, :can_fork_project, :can_create_fork, :expected) do
false | false | false | nil
true | true | true | nil
true | false | true | 'You don\'t have permission to fork this project'
true | true | false | 'You have reached your project limit'
end
with_them do
before do
current_user = user if has_user
allow(helper).to receive(:current_user).and_return(current_user)
allow(user).to receive(:can?).with(:fork_project, project).and_return(can_fork_project)
allow(user).to receive(:can?).with(:create_fork).and_return(can_create_fork)
end
it 'returns tooltip text when user lacks privilege' do
expect(subject).to eq(expected)
end
end
end
end

View file

@ -130,6 +130,22 @@ RSpec.describe BulkImports::NdjsonPipeline do
subject.transform(context, data)
end
context 'when data is nil' do
before do
expect(Gitlab::ImportExport::Group::RelationFactory).not_to receive(:create)
end
it 'returns' do
expect(subject.transform(nil, nil)).to be_nil
end
context 'when relation hash is nil' do
it 'returns' do
expect(subject.transform(nil, [nil, 0])).to be_nil
end
end
end
end
describe '#load' do

View file

@ -17,15 +17,19 @@ RSpec.describe Gitlab::Database::BackgroundMigration::BatchedJob, type: :model d
let_it_be(:stuck_job) { create(:batched_background_migration_job, status: :pending, updated_at: fixed_time - described_class::STUCK_JOBS_TIMEOUT) }
let_it_be(:failed_job) { create(:batched_background_migration_job, status: :failed, attempts: 1) }
before_all do
create(:batched_background_migration_job, status: :failed, attempts: described_class::MAX_ATTEMPTS)
create(:batched_background_migration_job, status: :succeeded)
end
let!(:max_attempts_failed_job) { create(:batched_background_migration_job, status: :failed, attempts: described_class::MAX_ATTEMPTS) }
let!(:succeeded_job) { create(:batched_background_migration_job, status: :succeeded) }
before do
travel_to fixed_time
end
describe '.except_succeeded' do
it 'returns not succeeded jobs' do
expect(described_class.except_succeeded).to contain_exactly(pending_job, running_job, stuck_job, failed_job, max_attempts_failed_job)
end
end
describe '.active' do
it 'returns active jobs' do
expect(described_class.active).to contain_exactly(pending_job, running_job, stuck_job)

View file

@ -23,6 +23,28 @@ RSpec.describe Gitlab::Database::BackgroundMigration::BatchedMigration, type: :m
subject { build(:batched_background_migration) }
it { is_expected.to validate_uniqueness_of(:job_arguments).scoped_to(:job_class_name, :table_name, :column_name) }
context 'when there are failed jobs' do
let(:batched_migration) { create(:batched_background_migration, status: :active, total_tuple_count: 100) }
let!(:batched_job) { create(:batched_background_migration_job, batched_migration: batched_migration, status: :failed) }
it 'raises an exception' do
expect { batched_migration.finished! }.to raise_error(ActiveRecord::RecordInvalid)
expect(batched_migration.reload.status).to eql 'active'
end
end
context 'when the jobs are completed' do
let(:batched_migration) { create(:batched_background_migration, status: :active, total_tuple_count: 100) }
let!(:batched_job) { create(:batched_background_migration_job, batched_migration: batched_migration, status: :succeeded) }
it 'finishes the migration' do
batched_migration.finished!
expect(batched_migration.status).to eql 'finished'
end
end
end
describe '.queue_order' do

View file

@ -68,7 +68,6 @@ RSpec.describe Emails::InProductMarketing do
with_them do
before do
stub_experiments(invite_members_for_task: :candidate)
group.add_owner(user)
end

View file

@ -742,7 +742,6 @@ RSpec.describe Group do
let!(:project) { create(:project, group: group) }
before do
stub_experiments(invite_members_for_task: true)
group.add_users([create(:user)], :developer, tasks_to_be_done: %w(ci code), tasks_project_id: project.id)
end

View file

@ -681,8 +681,6 @@ RSpec.describe Member do
end
it 'schedules a TasksToBeDone::CreateWorker task' do
stub_experiments(invite_members_for_task: true)
member_task = create(:member_task, member: member, project: member.project)
expect(TasksToBeDone::CreateWorker)

View file

@ -237,7 +237,6 @@ RSpec.describe ProjectTeam do
context 'when `tasks_to_be_done` and `tasks_project_id` are passed' do
before do
stub_experiments(invite_members_for_task: true)
project.team.add_users([user1], :developer, tasks_to_be_done: %w(ci code), tasks_project_id: project.id)
end

View file

@ -167,10 +167,6 @@ RSpec.describe API::Invitations do
end
context 'with tasks_to_be_done and tasks_project_id in the params' do
before do
stub_experiments(invite_members_for_task: true)
end
let(:project_id) { source_type == 'project' ? source.id : create(:project, namespace: source).id }
context 'when there is 1 invitation' do

View file

@ -415,10 +415,6 @@ RSpec.describe API::Members do
end
context 'with tasks_to_be_done and tasks_project_id in the params' do
before do
stub_experiments(invite_members_for_task: true)
end
let(:project_id) { source_type == 'project' ? source.id : create(:project, namespace: source).id }
context 'when there is 1 user to add' do

View file

@ -202,10 +202,6 @@ RSpec.describe Members::CreateService, :aggregate_failures, :clean_gitlab_redis_
{ invite_source: '_invite_source_', tasks_to_be_done: %w(ci code), tasks_project_id: source.id }
end
before do
stub_experiments(invite_members_for_task: true)
end
it 'creates 2 task issues', :aggregate_failures do
expect(TasksToBeDone::CreateWorker)
.to receive(:perform_async)

View file

@ -301,10 +301,6 @@ RSpec.shared_examples_for "member creation" do
end
context 'when `tasks_to_be_done` and `tasks_project_id` are passed' do
before do
stub_experiments(invite_members_for_task: true)
end
it 'creates a member_task with the correct attributes', :aggregate_failures do
task_project = source.is_a?(Group) ? create(:project, group: source) : source
described_class.new(source, user, :developer, tasks_to_be_done: %w(ci code), tasks_project_id: task_project.id).execute
@ -397,10 +393,6 @@ RSpec.shared_examples_for "bulk member creation" do
end
context 'when `tasks_to_be_done` and `tasks_project_id` are passed' do
before do
stub_experiments(invite_members_for_task: true)
end
it 'creates a member_task with the correct attributes', :aggregate_failures do
task_project = source.is_a?(Group) ? create(:project, group: source) : source
members = described_class.add_users(source, [user1], :developer, tasks_to_be_done: %w(ci code), tasks_project_id: task_project.id)