Add latest changes from gitlab-org/gitlab@master
|
@ -1,12 +1,17 @@
|
|||
<script>
|
||||
import { GlAvatarLink, GlAvatarLabeled, GlBadge } from '@gitlab/ui';
|
||||
import { USER_AVATAR_SIZE } from '../constants';
|
||||
import { GlAvatarLink, GlAvatarLabeled, GlBadge, GlIcon, GlTooltipDirective } from '@gitlab/ui';
|
||||
import { truncate } from '~/lib/utils/text_utility';
|
||||
import { USER_AVATAR_SIZE, LENGTH_OF_USER_NOTE_TOOLTIP } from '../constants';
|
||||
|
||||
export default {
|
||||
directives: {
|
||||
GlTooltip: GlTooltipDirective,
|
||||
},
|
||||
components: {
|
||||
GlAvatarLink,
|
||||
GlAvatarLabeled,
|
||||
GlBadge,
|
||||
GlIcon,
|
||||
},
|
||||
props: {
|
||||
user: {
|
||||
|
@ -22,6 +27,9 @@ export default {
|
|||
adminUserHref() {
|
||||
return this.adminUserPath.replace('id', this.user.username);
|
||||
},
|
||||
userNoteShort() {
|
||||
return truncate(this.user.note, LENGTH_OF_USER_NOTE_TOOLTIP);
|
||||
},
|
||||
},
|
||||
USER_AVATAR_SIZE,
|
||||
};
|
||||
|
@ -42,6 +50,9 @@ export default {
|
|||
:sub-label="user.email"
|
||||
>
|
||||
<template #meta>
|
||||
<div v-if="user.note" class="gl-text-gray-500 gl-p-1">
|
||||
<gl-icon v-gl-tooltip="userNoteShort" name="document" />
|
||||
</div>
|
||||
<div v-for="(badge, idx) in user.badges" :key="idx" class="gl-p-1">
|
||||
<gl-badge class="gl-display-flex!" size="sm" :variant="badge.variant">{{
|
||||
badge.text
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
export const USER_AVATAR_SIZE = 32;
|
||||
|
||||
export const SHORT_DATE_FORMAT = 'd mmm, yyyy';
|
||||
|
||||
export const LENGTH_OF_USER_NOTE_TOOLTIP = 100;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { isEmpty, isString } from 'lodash';
|
||||
import { isScrolledToBottom } from '~/lib/utils/scroll_utils';
|
||||
|
||||
export const headerTime = (state) => (state.job.started ? state.job.started : state.job.created_at);
|
||||
export const headerTime = (state) => state.job.started ?? state.job.created_at;
|
||||
|
||||
export const hasForwardDeploymentFailure = (state) =>
|
||||
state?.job?.failure_reason === 'forward_deployment_failure';
|
||||
|
@ -28,11 +28,9 @@ export const hasEnvironment = (state) => !isEmpty(state.job.deployment_status);
|
|||
export const hasTrace = (state) =>
|
||||
state.job.has_trace || (!isEmpty(state.job.status) && state.job.status.group === 'running');
|
||||
|
||||
export const emptyStateIllustration = (state) =>
|
||||
(state.job && state.job.status && state.job.status.illustration) || {};
|
||||
export const emptyStateIllustration = (state) => state?.job?.status?.illustration || {};
|
||||
|
||||
export const emptyStateAction = (state) =>
|
||||
(state.job && state.job.status && state.job.status.action) || null;
|
||||
export const emptyStateAction = (state) => state?.job?.status?.action || null;
|
||||
|
||||
/**
|
||||
* Shared runners limit is only rendered when
|
||||
|
@ -48,4 +46,4 @@ export const shouldRenderSharedRunnerLimitWarning = (state) =>
|
|||
export const isScrollingDown = (state) => isScrolledToBottom() && !state.isTraceComplete;
|
||||
|
||||
export const hasRunnersForProject = (state) =>
|
||||
state.job.runners.available && !state.job.runners.online;
|
||||
state?.job?.runners?.available && !state?.job?.runners?.online;
|
||||
|
|
|
@ -15,7 +15,7 @@ module Registrations
|
|||
if current_user.save
|
||||
hide_advanced_issues
|
||||
|
||||
if experiment_enabled?(:default_to_issues_board) && learn_gitlab.available?
|
||||
if learn_gitlab.available?
|
||||
redirect_to namespace_project_board_path(params[:namespace_path], learn_gitlab.project, learn_gitlab.board)
|
||||
else
|
||||
redirect_to group_path(params[:namespace_path])
|
||||
|
|
|
@ -26,42 +26,23 @@ class UserRecentEventsFinder
|
|||
@params = params
|
||||
end
|
||||
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
def execute
|
||||
return Event.none unless can?(current_user, :read_user_profile, target_user)
|
||||
|
||||
recent_events(params[:offset] || 0)
|
||||
.joins(:project)
|
||||
target_events
|
||||
.with_associations
|
||||
.limit_recent(limit, params[:offset])
|
||||
.order_created_desc
|
||||
end
|
||||
# rubocop: enable CodeReuse/ActiveRecord
|
||||
|
||||
private
|
||||
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
def recent_events(offset)
|
||||
sql = <<~SQL
|
||||
(#{projects}) AS projects_for_join
|
||||
JOIN (#{target_events.to_sql}) AS #{Event.table_name}
|
||||
ON #{Event.table_name}.project_id = projects_for_join.id
|
||||
SQL
|
||||
|
||||
# Workaround for https://github.com/rails/rails/issues/24193
|
||||
Event.from([Arel.sql(sql)])
|
||||
end
|
||||
# rubocop: enable CodeReuse/ActiveRecord
|
||||
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
def target_events
|
||||
Event.where(author: target_user)
|
||||
end
|
||||
# rubocop: enable CodeReuse/ActiveRecord
|
||||
|
||||
def projects
|
||||
target_user.project_interactions.to_sql
|
||||
end
|
||||
|
||||
def limit
|
||||
return DEFAULT_LIMIT unless params[:limit].present?
|
||||
|
||||
|
|
|
@ -7,19 +7,19 @@ class UserCallout < ApplicationRecord
|
|||
gke_cluster_integration: 1,
|
||||
gcp_signup_offer: 2,
|
||||
cluster_security_warning: 3,
|
||||
gold_trial: 4, # EE-only
|
||||
geo_enable_hashed_storage: 5, # EE-only
|
||||
geo_migrate_hashed_storage: 6, # EE-only
|
||||
canary_deployment: 7, # EE-only
|
||||
gold_trial_billings: 8, # EE-only
|
||||
gold_trial: 4, # EE-only
|
||||
geo_enable_hashed_storage: 5, # EE-only
|
||||
geo_migrate_hashed_storage: 6, # EE-only
|
||||
canary_deployment: 7, # EE-only
|
||||
gold_trial_billings: 8, # EE-only
|
||||
suggest_popover_dismissed: 9,
|
||||
tabs_position_highlight: 10,
|
||||
threat_monitoring_info: 11, # EE-only
|
||||
account_recovery_regular_check: 12, # EE-only
|
||||
threat_monitoring_info: 11, # EE-only
|
||||
account_recovery_regular_check: 12, # EE-only
|
||||
webhooks_moved: 13,
|
||||
service_templates_deprecated: 14,
|
||||
admin_integrations_moved: 15,
|
||||
web_ide_alert_dismissed: 16, # no longer in use
|
||||
web_ide_alert_dismissed: 16, # no longer in use
|
||||
active_user_count_threshold: 18, # EE-only
|
||||
buy_pipeline_minutes_notification_dot: 19, # EE-only
|
||||
personal_access_token_expiry: 21, # EE-only
|
||||
|
@ -27,8 +27,9 @@ class UserCallout < ApplicationRecord
|
|||
customize_homepage: 23,
|
||||
feature_flags_new_version: 24,
|
||||
registration_enabled_callout: 25,
|
||||
new_user_signups_cap_reached: 26, # EE-only
|
||||
unfinished_tag_cleanup_callout: 27
|
||||
new_user_signups_cap_reached: 26, # EE-only
|
||||
unfinished_tag_cleanup_callout: 27,
|
||||
eoa_bronze_plan_banner: 28 # EE-only
|
||||
}
|
||||
|
||||
validates :user, presence: true
|
||||
|
|
|
@ -10,6 +10,7 @@ module Admin
|
|||
expose :email
|
||||
expose :last_activity_on
|
||||
expose :avatar_url
|
||||
expose :note
|
||||
expose :badges do |user|
|
||||
user_badges_in_admin_section(user)
|
||||
end
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
|
||||
module Admin
|
||||
class UserSerializer < BaseSerializer
|
||||
entity UserEntity
|
||||
entity Admin::UserEntity
|
||||
end
|
||||
end
|
||||
|
|
5
changelogs/unreleased/196835-fix-epic-feed.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Display epic related events on user activity feed
|
||||
merge_request: 52611
|
||||
author:
|
||||
type: added
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: default_to_issues_board_experiment_percentage
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/43939
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/268298
|
||||
milestone: '13.5'
|
||||
type: experiment
|
||||
group: group::conversion
|
||||
default_enabled: true
|
Before Width: | Height: | Size: 44 KiB |
BIN
doc/user/discussions/img/apply_suggestion_v13_9.png
Normal file
After Width: | Height: | Size: 136 KiB |
BIN
doc/user/discussions/img/custom_commit_v13_9.png
Normal file
After Width: | Height: | Size: 150 KiB |
Before Width: | Height: | Size: 32 KiB |
BIN
doc/user/discussions/img/make_suggestion_v13_9.png
Normal file
After Width: | Height: | Size: 116 KiB |
Before Width: | Height: | Size: 28 KiB |
BIN
doc/user/discussions/img/suggestion_button_v13_9.png
Normal file
After Width: | Height: | Size: 101 KiB |
|
@ -376,7 +376,11 @@ from any device you're logged into.
|
|||
|
||||
## Suggest Changes
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/18008) in GitLab 11.6.
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/18008) in GitLab 11.6.
|
||||
> - Custom commit messages for suggestions were [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/25381) in GitLab 13.9.
|
||||
> - Custom commit messages for suggestions is disabled on GitLab.com and not recommended for production use.
|
||||
> - Custom commit messages for suggestions was deployed behind a [feature flag](../feature_flags.md), disabled by default.
|
||||
> - To use custom commit messages for suggestions in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-custom-commit-messages-for-suggestions). **(FREE SELF)**
|
||||
|
||||
As a reviewer, you're able to suggest code changes with a simple
|
||||
Markdown syntax in Merge Request Diff threads. Then, the
|
||||
|
@ -388,24 +392,50 @@ the merge request authored by the user that applied them.
|
|||
1. Choose a line of code to be changed, add a new comment, then click
|
||||
on the **Insert suggestion** icon in the toolbar:
|
||||
|
||||
![Add a new comment](img/suggestion_button_v12_7.png)
|
||||
![Add a new comment](img/suggestion_button_v13_9.png)
|
||||
|
||||
1. In the comment, add your suggestion to the pre-populated code block:
|
||||
|
||||
![Add a suggestion into a code block tagged properly](img/make_suggestion_v12_7.png)
|
||||
![Add a suggestion into a code block tagged properly](img/make_suggestion_v13_9.png)
|
||||
|
||||
1. Click either **Start a review** or **Add to review** to add your comment to a [review](#merge-request-reviews), or **Add comment now** to add the comment to the thread immediately.
|
||||
|
||||
The Suggestion in the comment can be applied by the merge request author
|
||||
directly from the merge request:
|
||||
|
||||
![Apply suggestions](img/apply_suggestion_v12_7.png)
|
||||
![Apply suggestions](img/apply_suggestion_v13_9.png)
|
||||
|
||||
1. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/25381) in GitLab 13.9,
|
||||
you can opt to add a custom commit message to describe your change. If you don't
|
||||
specify it, the default commit message will be used. Note that [this feature may not be available to you](#enable-or-disable-custom-commit-messages-for-suggestions).
|
||||
Also, it is not supported for [batch suggestions](#batch-suggestions).
|
||||
|
||||
![Custom commit](img/custom_commit_v13_9.png)
|
||||
|
||||
After the author applies a Suggestion, it will be marked with the **Applied** label,
|
||||
the thread will be automatically resolved, and GitLab will create a new commit
|
||||
and push the suggested change directly into the codebase in the merge request's
|
||||
branch. [Developer permission](../permissions.md) is required to do so.
|
||||
|
||||
### Enable or disable Custom commit messages for suggestions **(FREE SELF)**
|
||||
|
||||
Custom commit messages for suggestions is under development and not ready for production use. It is
|
||||
deployed behind a feature flag that is **disabled by default**.
|
||||
[GitLab administrators with access to the GitLab Rails console](../../administration/feature_flags.md)
|
||||
can enable it.
|
||||
|
||||
To enable custom commit messages for suggestions:
|
||||
|
||||
```ruby
|
||||
Feature.enable(:suggestions_custom_commit)
|
||||
```
|
||||
|
||||
To disable custom commit messages for suggestions:
|
||||
|
||||
```ruby
|
||||
Feature.disable(:suggestions_custom_commit)
|
||||
```
|
||||
|
||||
### Multi-line Suggestions
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/53310) in GitLab 11.10.
|
||||
|
|
|
@ -70,10 +70,6 @@ module Gitlab
|
|||
tracking_category: 'Growth::Conversion::Experiment::GroupOnlyTrials',
|
||||
use_backwards_compatible_subject_index: true
|
||||
},
|
||||
default_to_issues_board: {
|
||||
tracking_category: 'Growth::Conversion::Experiment::DefaultToIssuesBoard',
|
||||
use_backwards_compatible_subject_index: true
|
||||
},
|
||||
jobs_empty_state: {
|
||||
tracking_category: 'Growth::Activation::Experiment::JobsEmptyState'
|
||||
},
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
# redis_usage_data { ::Gitlab::UsageCounters::PodLogs.usage_totals[:total] }
|
||||
module Gitlab
|
||||
class UsageData
|
||||
DEPRECATED_VALUE = -1000
|
||||
|
||||
CE_MEMOIZED_VALUES = %i(
|
||||
issue_minimum_id
|
||||
issue_maximum_id
|
||||
|
@ -584,26 +586,33 @@ module Gitlab
|
|||
user_auth_by_provider: distinct_count_user_auth_by_provider(time_period),
|
||||
unique_users_all_imports: unique_users_all_imports(time_period),
|
||||
bulk_imports: {
|
||||
gitlab: distinct_count(::BulkImport.where(time_period, source_type: :gitlab), :user_id)
|
||||
gitlab: DEPRECATED_VALUE,
|
||||
gitlab_v1: count(::BulkImport.where(time_period, source_type: :gitlab))
|
||||
},
|
||||
project_imports: project_imports(time_period),
|
||||
issue_imports: issue_imports(time_period),
|
||||
group_imports: group_imports(time_period),
|
||||
|
||||
# Deprecated data to be removed
|
||||
projects_imported: {
|
||||
total: distinct_count(::Project.where(time_period).where.not(import_type: nil), :creator_id),
|
||||
gitlab_project: projects_imported_count('gitlab_project', time_period),
|
||||
gitlab: projects_imported_count('gitlab', time_period),
|
||||
github: projects_imported_count('github', time_period),
|
||||
bitbucket: projects_imported_count('bitbucket', time_period),
|
||||
bitbucket_server: projects_imported_count('bitbucket_server', time_period),
|
||||
gitea: projects_imported_count('gitea', time_period),
|
||||
git: projects_imported_count('git', time_period),
|
||||
manifest: projects_imported_count('manifest', time_period)
|
||||
total: DEPRECATED_VALUE,
|
||||
gitlab_project: DEPRECATED_VALUE,
|
||||
gitlab: DEPRECATED_VALUE,
|
||||
github: DEPRECATED_VALUE,
|
||||
bitbucket: DEPRECATED_VALUE,
|
||||
bitbucket_server: DEPRECATED_VALUE,
|
||||
gitea: DEPRECATED_VALUE,
|
||||
git: DEPRECATED_VALUE,
|
||||
manifest: DEPRECATED_VALUE
|
||||
},
|
||||
issues_imported: {
|
||||
jira: distinct_count(::JiraImportState.where(time_period), :user_id),
|
||||
fogbugz: projects_imported_count('fogbugz', time_period),
|
||||
phabricator: projects_imported_count('phabricator', time_period),
|
||||
csv: distinct_count(Issues::CsvImport.where(time_period), :user_id)
|
||||
jira: DEPRECATED_VALUE,
|
||||
fogbugz: DEPRECATED_VALUE,
|
||||
phabricator: DEPRECATED_VALUE,
|
||||
csv: DEPRECATED_VALUE
|
||||
},
|
||||
groups_imported: distinct_count(::GroupImportState.where(time_period), :user_id)
|
||||
groups_imported: DEPRECATED_VALUE
|
||||
# End of deprecated keys
|
||||
}
|
||||
end
|
||||
# rubocop: enable CodeReuse/ActiveRecord
|
||||
|
@ -900,8 +909,38 @@ module Gitlab
|
|||
count relation, start: deployment_minimum_id, finish: deployment_maximum_id
|
||||
end
|
||||
|
||||
def project_imports(time_period)
|
||||
{
|
||||
gitlab_project: projects_imported_count('gitlab_project', time_period),
|
||||
gitlab: projects_imported_count('gitlab', time_period),
|
||||
github: projects_imported_count('github', time_period),
|
||||
bitbucket: projects_imported_count('bitbucket', time_period),
|
||||
bitbucket_server: projects_imported_count('bitbucket_server', time_period),
|
||||
gitea: projects_imported_count('gitea', time_period),
|
||||
git: projects_imported_count('git', time_period),
|
||||
manifest: projects_imported_count('manifest', time_period),
|
||||
gitlab_migration: count(::BulkImports::Entity.where(time_period).project_entity) # rubocop: disable CodeReuse/ActiveRecord
|
||||
}
|
||||
end
|
||||
|
||||
def projects_imported_count(from, time_period)
|
||||
distinct_count(::Project.imported_from(from).where(time_period).where.not(import_type: nil), :creator_id) # rubocop: disable CodeReuse/ActiveRecord
|
||||
count(::Project.imported_from(from).where(time_period).where.not(import_type: nil)) # rubocop: disable CodeReuse/ActiveRecord
|
||||
end
|
||||
|
||||
def issue_imports(time_period)
|
||||
{
|
||||
jira: count(::JiraImportState.where(time_period)), # rubocop: disable CodeReuse/ActiveRecord
|
||||
fogbugz: projects_imported_count('fogbugz', time_period),
|
||||
phabricator: projects_imported_count('phabricator', time_period),
|
||||
csv: count(Issues::CsvImport.where(time_period)) # rubocop: disable CodeReuse/ActiveRecord
|
||||
}
|
||||
end
|
||||
|
||||
def group_imports(time_period)
|
||||
{
|
||||
group_import: count(::GroupImportState.where(time_period)), # rubocop: disable CodeReuse/ActiveRecord
|
||||
gitlab_migration: count(::BulkImports::Entity.where(time_period).group_entity) # rubocop: disable CodeReuse/ActiveRecord
|
||||
}
|
||||
end
|
||||
|
||||
# rubocop:disable CodeReuse/ActiveRecord
|
||||
|
|
|
@ -10125,9 +10125,6 @@ msgstr ""
|
|||
msgid "DevopsAdoption|Filter by name"
|
||||
msgstr ""
|
||||
|
||||
msgid "DevopsAdoption|Group data pending until the start of next month"
|
||||
msgstr ""
|
||||
|
||||
msgid "DevopsAdoption|Issues"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Registrations::ExperienceLevelsController do
|
||||
include AfterNextHelpers
|
||||
|
||||
let_it_be(:namespace) { create(:group, path: 'group-path' ) }
|
||||
let_it_be(:user) { create(:user) }
|
||||
|
||||
|
@ -45,6 +47,9 @@ RSpec.describe Registrations::ExperienceLevelsController do
|
|||
end
|
||||
|
||||
context 'with an authenticated user' do
|
||||
let_it_be(:project) { build(:project, namespace: namespace, creator: user, path: 'project-path') }
|
||||
let_it_be(:issues_board) { build(:board, id: 123, project: project) }
|
||||
|
||||
before do
|
||||
sign_in(user)
|
||||
stub_experiment_for_subject(onboarding_issues: true)
|
||||
|
@ -85,91 +90,57 @@ RSpec.describe Registrations::ExperienceLevelsController do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'redirection' do
|
||||
let(:project) { build(:project, namespace: namespace, creator: user, path: 'project-path') }
|
||||
let(:issues_board) { build(:board, id: 123, project: project) }
|
||||
context 'when "Learn GitLab" project exists' do
|
||||
let(:learn_gitlab_available?) { true }
|
||||
|
||||
before do
|
||||
stub_experiment_for_subject(
|
||||
onboarding_issues: true,
|
||||
default_to_issues_board: default_to_issues_board_xp?
|
||||
)
|
||||
allow_next_instance_of(LearnGitlab) do |learn_gitlab|
|
||||
allow(learn_gitlab).to receive(:available?).and_return(learn_gitlab_available?)
|
||||
allow(learn_gitlab).to receive(:project).and_return(project)
|
||||
allow(learn_gitlab).to receive(:board).and_return(issues_board)
|
||||
allow(learn_gitlab).to receive(:label).and_return(double(id: 1))
|
||||
end
|
||||
end
|
||||
|
||||
context 'when namespace_path param is missing' do
|
||||
let(:params) { super().merge(namespace_path: nil) }
|
||||
context 'redirection' do
|
||||
context 'when namespace_path param is missing' do
|
||||
let(:params) { super().merge(namespace_path: nil) }
|
||||
|
||||
where(
|
||||
default_to_issues_board_xp?: [true, false],
|
||||
learn_gitlab_available?: [true, false]
|
||||
)
|
||||
where(
|
||||
learn_gitlab_available?: [true, false]
|
||||
)
|
||||
|
||||
with_them do
|
||||
it { is_expected.to redirect_to('/') }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when we have a namespace_path param' do
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
|
||||
where(:default_to_issues_board_xp?, :learn_gitlab_available?, :path) do
|
||||
true | true | '/group-path/project-path/-/boards/123'
|
||||
true | false | '/group-path'
|
||||
false | true | '/group-path'
|
||||
false | false | '/group-path'
|
||||
end
|
||||
|
||||
with_them do
|
||||
it { is_expected.to redirect_to(path) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'applying the chosen level' do
|
||||
context 'when a "Learn GitLab" project is available' do
|
||||
before do
|
||||
allow_next_instance_of(LearnGitlab) do |learn_gitlab|
|
||||
allow(learn_gitlab).to receive(:available?).and_return(true)
|
||||
allow(learn_gitlab).to receive(:label).and_return(double(id: 1))
|
||||
with_them do
|
||||
it { is_expected.to redirect_to('/') }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when novice' do
|
||||
let(:params) { super().merge(experience_level: :novice) }
|
||||
context 'when we have a namespace_path param' do
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
|
||||
it 'adds a BoardLabel' do
|
||||
expect_next_instance_of(Boards::UpdateService) do |service|
|
||||
expect(service).to receive(:execute)
|
||||
end
|
||||
|
||||
subject
|
||||
where(:learn_gitlab_available?, :path) do
|
||||
true | '/group-path/project-path/-/boards/123'
|
||||
false | '/group-path'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when experienced' do
|
||||
let(:params) { super().merge(experience_level: :experienced) }
|
||||
|
||||
it 'does not add a BoardLabel' do
|
||||
expect(Boards::UpdateService).not_to receive(:new)
|
||||
|
||||
subject
|
||||
with_them do
|
||||
it { is_expected.to redirect_to(path) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when no "Learn GitLab" project exists' do
|
||||
context 'when novice' do
|
||||
let(:params) { super().merge(experience_level: :novice) }
|
||||
|
||||
before do
|
||||
allow_next_instance_of(LearnGitlab) do |learn_gitlab|
|
||||
allow(learn_gitlab).to receive(:available?).and_return(false)
|
||||
end
|
||||
it 'adds a BoardLabel' do
|
||||
expect_next(Boards::UpdateService).to receive(:execute)
|
||||
|
||||
subject
|
||||
end
|
||||
end
|
||||
|
||||
context 'when experienced' do
|
||||
let(:params) { super().merge(experience_level: :experienced) }
|
||||
|
||||
it 'does not add a BoardLabel' do
|
||||
expect(Boards::UpdateService).not_to receive(:new)
|
||||
|
@ -178,6 +149,20 @@ RSpec.describe Registrations::ExperienceLevelsController do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when no "Learn GitLab" project exists' do
|
||||
let(:params) { super().merge(experience_level: :novice) }
|
||||
|
||||
before do
|
||||
allow_next(LearnGitlab).to receive(:available?).and_return(false)
|
||||
end
|
||||
|
||||
it 'does not add a BoardLabel' do
|
||||
expect(Boards::UpdateService).not_to receive(:new)
|
||||
|
||||
subject
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user update fails' do
|
||||
|
|
|
@ -308,12 +308,6 @@ FactoryBot.define do
|
|||
end
|
||||
end
|
||||
|
||||
trait :codequality_report do
|
||||
after(:build) do |build|
|
||||
build.job_artifacts << create(:ci_job_artifact, :codequality, job: build)
|
||||
end
|
||||
end
|
||||
|
||||
trait :test_reports do
|
||||
after(:build) do |build|
|
||||
build.job_artifacts << create(:ci_job_artifact, :junit, job: build)
|
||||
|
|
|
@ -4,18 +4,30 @@ FactoryBot.define do
|
|||
factory :ci_pipeline_artifact, class: 'Ci::PipelineArtifact' do
|
||||
pipeline factory: :ci_pipeline
|
||||
project { pipeline.project }
|
||||
file_type { :code_coverage }
|
||||
file_format { :raw }
|
||||
file_store { ObjectStorage::SUPPORTED_STORES.first }
|
||||
size { 1.megabytes }
|
||||
|
||||
size { 1.megabyte }
|
||||
file_type { :code_coverage }
|
||||
after(:build) do |artifact, _evaluator|
|
||||
artifact.file = fixture_file_upload(
|
||||
Rails.root.join('spec/fixtures/pipeline_artifacts/code_coverage.json'), 'application/json')
|
||||
end
|
||||
|
||||
trait :with_multibyte_characters do
|
||||
trait :with_coverage_report do
|
||||
file_type { :code_coverage }
|
||||
|
||||
after(:build) do |artifact, _evaluator|
|
||||
artifact.file = fixture_file_upload(
|
||||
Rails.root.join('spec/fixtures/pipeline_artifacts/code_coverage.json'), 'application/json')
|
||||
end
|
||||
|
||||
size { file.size }
|
||||
end
|
||||
|
||||
trait :with_coverage_multibyte_characters do
|
||||
file_type { :code_coverage }
|
||||
size { { "utf8" => "✓" }.to_json.bytesize }
|
||||
|
||||
after(:build) do |artifact, _evaluator|
|
||||
artifact.file = CarrierWaveStringFile.new_file(
|
||||
file_content: { "utf8" => "✓" }.to_json,
|
||||
|
@ -26,23 +38,26 @@ FactoryBot.define do
|
|||
end
|
||||
|
||||
trait :with_code_coverage_with_multiple_files do
|
||||
file_type { :code_coverage }
|
||||
|
||||
after(:build) do |artifact, _evaluator|
|
||||
artifact.file = fixture_file_upload(
|
||||
Rails.root.join('spec/fixtures/pipeline_artifacts/code_coverage_with_multiple_files.json'), 'application/json'
|
||||
)
|
||||
end
|
||||
|
||||
size { file.size }
|
||||
size { 1.megabyte }
|
||||
end
|
||||
|
||||
trait :codequality_report do
|
||||
trait :with_codequality_report do
|
||||
file_type { :code_quality }
|
||||
size { 2.megabytes }
|
||||
|
||||
after(:build) do |artifact, _evaluator|
|
||||
artifact.file = fixture_file_upload(
|
||||
Rails.root.join('spec/fixtures/pipeline_artifacts/code_quality.json'), 'application/json')
|
||||
end
|
||||
|
||||
size { file.size }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -93,14 +93,6 @@ FactoryBot.define do
|
|||
end
|
||||
end
|
||||
|
||||
trait :with_codequality_report do
|
||||
status { :success }
|
||||
|
||||
after(:build) do |pipeline, evaluator|
|
||||
pipeline.builds << build(:ci_build, :codequality_report, pipeline: pipeline, project: pipeline.project)
|
||||
end
|
||||
end
|
||||
|
||||
trait :with_test_reports do
|
||||
status { :success }
|
||||
|
||||
|
@ -159,13 +151,13 @@ FactoryBot.define do
|
|||
|
||||
trait :with_coverage_report_artifact do
|
||||
after(:build) do |pipeline, evaluator|
|
||||
pipeline.pipeline_artifacts << build(:ci_pipeline_artifact, pipeline: pipeline, project: pipeline.project)
|
||||
pipeline.pipeline_artifacts << build(:ci_pipeline_artifact, :with_coverage_report, pipeline: pipeline, project: pipeline.project)
|
||||
end
|
||||
end
|
||||
|
||||
trait :with_codequality_report_artifact do
|
||||
trait :with_quality_report_artifact do
|
||||
after(:build) do |pipeline, evaluator|
|
||||
pipeline.pipeline_artifacts << build(:ci_pipeline_artifact, :codequality_report, pipeline: pipeline, project: pipeline.project)
|
||||
pipeline.pipeline_artifacts << build(:ci_pipeline_artifact, :with_codequality_report, pipeline: pipeline, project: pipeline.project)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -51,6 +51,20 @@ RSpec.describe UserRecentEventsFinder do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'issue activity events' do
|
||||
let(:issue) { create(:issue, project: public_project) }
|
||||
let(:note) { create(:note_on_issue, noteable: issue, project: public_project) }
|
||||
let!(:event_a) { create(:event, :commented, target: note, author: project_owner) }
|
||||
let!(:event_b) { create(:event, :closed, target: issue, author: project_owner) }
|
||||
|
||||
it 'includes all issue related events', :aggregate_failures do
|
||||
events = finder.execute
|
||||
|
||||
expect(events).to include(event_a)
|
||||
expect(events).to include(event_b)
|
||||
end
|
||||
end
|
||||
|
||||
context 'limits' do
|
||||
before do
|
||||
stub_const("#{described_class}::DEFAULT_LIMIT", 1)
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
import { GlAvatarLink, GlAvatarLabeled, GlBadge } from '@gitlab/ui';
|
||||
import { mount } from '@vue/test-utils';
|
||||
import { GlAvatarLink, GlAvatarLabeled, GlBadge, GlIcon } from '@gitlab/ui';
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
|
||||
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
|
||||
import AdminUserAvatar from '~/admin/users/components/user_avatar.vue';
|
||||
import { LENGTH_OF_USER_NOTE_TOOLTIP } from '~/admin/users/constants';
|
||||
import { truncate } from '~/lib/utils/text_utility';
|
||||
import { users, paths } from '../mock_data';
|
||||
|
||||
describe('AdminUserAvatar component', () => {
|
||||
|
@ -9,17 +12,25 @@ describe('AdminUserAvatar component', () => {
|
|||
const user = users[0];
|
||||
const adminUserPath = paths.adminUser;
|
||||
|
||||
const findNote = () => wrapper.find(GlIcon);
|
||||
const findAvatar = () => wrapper.find(GlAvatarLabeled);
|
||||
const findAvatarLink = () => wrapper.find(GlAvatarLink);
|
||||
const findAllBadges = () => wrapper.findAll(GlBadge);
|
||||
const findTooltip = () => getBinding(findNote().element, 'gl-tooltip');
|
||||
|
||||
const initComponent = (props = {}) => {
|
||||
wrapper = mount(AdminUserAvatar, {
|
||||
wrapper = shallowMount(AdminUserAvatar, {
|
||||
propsData: {
|
||||
user,
|
||||
adminUserPath,
|
||||
...props,
|
||||
},
|
||||
directives: {
|
||||
GlTooltip: createMockDirective(),
|
||||
},
|
||||
stubs: {
|
||||
GlAvatarLabeled,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -53,11 +64,58 @@ describe('AdminUserAvatar component', () => {
|
|||
expect(findAvatar().attributes('src')).toBe(user.avatarUrl);
|
||||
});
|
||||
|
||||
it('renders a user note icon', () => {
|
||||
expect(findNote().exists()).toBe(true);
|
||||
expect(findNote().props('name')).toBe('document');
|
||||
});
|
||||
|
||||
it("renders the user's note tooltip", () => {
|
||||
const tooltip = findTooltip();
|
||||
|
||||
expect(tooltip).toBeDefined();
|
||||
expect(tooltip.value).toBe(user.note);
|
||||
});
|
||||
|
||||
it("renders the user's badges", () => {
|
||||
findAllBadges().wrappers.forEach((badge, idx) => {
|
||||
expect(badge.text()).toBe(user.badges[idx].text);
|
||||
expect(badge.props('variant')).toBe(user.badges[idx].variant);
|
||||
});
|
||||
});
|
||||
|
||||
describe('and the user note is very long', () => {
|
||||
const noteText = new Array(LENGTH_OF_USER_NOTE_TOOLTIP + 1).join('a');
|
||||
|
||||
beforeEach(() => {
|
||||
initComponent({
|
||||
user: {
|
||||
...user,
|
||||
note: noteText,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("renders a truncated user's note tooltip", () => {
|
||||
const tooltip = findTooltip();
|
||||
|
||||
expect(tooltip).toBeDefined();
|
||||
expect(tooltip.value).toBe(truncate(noteText, LENGTH_OF_USER_NOTE_TOOLTIP));
|
||||
});
|
||||
});
|
||||
|
||||
describe('and the user does not have a note', () => {
|
||||
beforeEach(() => {
|
||||
initComponent({
|
||||
user: {
|
||||
...user,
|
||||
note: null,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('does not render a user note', () => {
|
||||
expect(findNote().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -14,6 +14,7 @@ export const users = [
|
|||
],
|
||||
projectsCount: 0,
|
||||
actions: [],
|
||||
note: 'Create per issue #999',
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
@ -15,8 +15,7 @@ RSpec.describe Gitlab::Experimentation::EXPERIMENTS do
|
|||
:invite_members_empty_group_version_a,
|
||||
:contact_sales_btn_in_app,
|
||||
:customize_homepage,
|
||||
:group_only_trials,
|
||||
:default_to_issues_board
|
||||
:group_only_trials
|
||||
]
|
||||
|
||||
backwards_compatible_experiment_keys = described_class.filter { |_, v| v[:use_backwards_compatible_subject_index] }.keys
|
||||
|
|
|
@ -255,8 +255,6 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
|
|||
for_defined_days_back do
|
||||
user = create(:user)
|
||||
|
||||
create(:bulk_import, user: user)
|
||||
|
||||
%w(gitlab_project gitlab github bitbucket bitbucket_server gitea git manifest fogbugz phabricator).each do |type|
|
||||
create(:project, import_type: type, creator_id: user.id)
|
||||
end
|
||||
|
@ -265,72 +263,113 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
|
|||
create(:jira_import_state, :finished, project: jira_project)
|
||||
|
||||
create(:issue_csv_import, user: user)
|
||||
|
||||
group = create(:group)
|
||||
group.add_owner(user)
|
||||
create(:group_import_state, group: group, user: user)
|
||||
|
||||
bulk_import = create(:bulk_import, user: user)
|
||||
create(:bulk_import_entity, :group_entity, bulk_import: bulk_import)
|
||||
create(:bulk_import_entity, :project_entity, bulk_import: bulk_import)
|
||||
end
|
||||
|
||||
expect(described_class.usage_activity_by_stage_manage({})).to include(
|
||||
{
|
||||
bulk_imports: {
|
||||
gitlab: 2
|
||||
gitlab_v1: 2,
|
||||
gitlab: Gitlab::UsageData::DEPRECATED_VALUE
|
||||
},
|
||||
projects_imported: {
|
||||
total: 2,
|
||||
gitlab_project: 2,
|
||||
gitlab: 2,
|
||||
github: 2,
|
||||
project_imports: {
|
||||
bitbucket: 2,
|
||||
bitbucket_server: 2,
|
||||
gitea: 2,
|
||||
git: 2,
|
||||
gitea: 2,
|
||||
github: 2,
|
||||
gitlab: 2,
|
||||
gitlab_migration: 2,
|
||||
gitlab_project: 2,
|
||||
manifest: 2
|
||||
},
|
||||
issues_imported: {
|
||||
issue_imports: {
|
||||
jira: 2,
|
||||
fogbugz: 2,
|
||||
phabricator: 2,
|
||||
csv: 2
|
||||
}
|
||||
},
|
||||
group_imports: {
|
||||
group_import: 2,
|
||||
gitlab_migration: 2
|
||||
},
|
||||
projects_imported: {
|
||||
total: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
gitlab_project: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
gitlab: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
github: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
bitbucket: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
bitbucket_server: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
gitea: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
git: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
manifest: Gitlab::UsageData::DEPRECATED_VALUE
|
||||
},
|
||||
issues_imported: {
|
||||
jira: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
fogbugz: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
phabricator: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
csv: Gitlab::UsageData::DEPRECATED_VALUE
|
||||
},
|
||||
groups_imported: Gitlab::UsageData::DEPRECATED_VALUE
|
||||
}
|
||||
)
|
||||
expect(described_class.usage_activity_by_stage_manage(described_class.last_28_days_time_period)).to include(
|
||||
{
|
||||
bulk_imports: {
|
||||
gitlab: 1
|
||||
gitlab_v1: 1,
|
||||
gitlab: Gitlab::UsageData::DEPRECATED_VALUE
|
||||
},
|
||||
projects_imported: {
|
||||
total: 1,
|
||||
gitlab_project: 1,
|
||||
gitlab: 1,
|
||||
github: 1,
|
||||
project_imports: {
|
||||
bitbucket: 1,
|
||||
bitbucket_server: 1,
|
||||
gitea: 1,
|
||||
git: 1,
|
||||
gitea: 1,
|
||||
github: 1,
|
||||
gitlab: 1,
|
||||
gitlab_migration: 1,
|
||||
gitlab_project: 1,
|
||||
manifest: 1
|
||||
},
|
||||
issues_imported: {
|
||||
issue_imports: {
|
||||
jira: 1,
|
||||
fogbugz: 1,
|
||||
phabricator: 1,
|
||||
csv: 1
|
||||
}
|
||||
},
|
||||
group_imports: {
|
||||
group_import: 1,
|
||||
gitlab_migration: 1
|
||||
},
|
||||
projects_imported: {
|
||||
total: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
gitlab_project: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
gitlab: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
github: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
bitbucket: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
bitbucket_server: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
gitea: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
git: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
manifest: Gitlab::UsageData::DEPRECATED_VALUE
|
||||
},
|
||||
issues_imported: {
|
||||
jira: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
fogbugz: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
phabricator: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
csv: Gitlab::UsageData::DEPRECATED_VALUE
|
||||
},
|
||||
groups_imported: Gitlab::UsageData::DEPRECATED_VALUE
|
||||
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
it 'includes group imports usage data' do
|
||||
for_defined_days_back do
|
||||
user = create(:user)
|
||||
group = create(:group)
|
||||
group.add_owner(user)
|
||||
create(:group_import_state, group: group, user: user)
|
||||
end
|
||||
|
||||
expect(described_class.usage_activity_by_stage_manage({}))
|
||||
.to include(groups_imported: 2)
|
||||
expect(described_class.usage_activity_by_stage_manage(described_class.last_28_days_time_period))
|
||||
.to include(groups_imported: 1)
|
||||
end
|
||||
|
||||
def omniauth_providers
|
||||
[
|
||||
OpenStruct.new(name: 'google_oauth2'),
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Ci::PipelineArtifact, type: :model do
|
||||
let(:coverage_report) { create(:ci_pipeline_artifact) }
|
||||
let(:coverage_report) { create(:ci_pipeline_artifact, :with_coverage_report) }
|
||||
|
||||
describe 'associations' do
|
||||
it { is_expected.to belong_to(:pipeline) }
|
||||
|
@ -15,7 +15,7 @@ RSpec.describe Ci::PipelineArtifact, type: :model do
|
|||
it_behaves_like 'UpdateProjectStatistics' do
|
||||
let_it_be(:pipeline, reload: true) { create(:ci_pipeline) }
|
||||
|
||||
subject { build(:ci_pipeline_artifact, pipeline: pipeline) }
|
||||
subject { build(:ci_pipeline_artifact, :with_code_coverage_with_multiple_files, pipeline: pipeline) }
|
||||
end
|
||||
|
||||
describe 'validations' do
|
||||
|
@ -51,7 +51,7 @@ RSpec.describe Ci::PipelineArtifact, type: :model do
|
|||
end
|
||||
|
||||
describe 'file is being stored' do
|
||||
subject { create(:ci_pipeline_artifact) }
|
||||
subject { create(:ci_pipeline_artifact, :with_coverage_report) }
|
||||
|
||||
context 'when existing object has local store' do
|
||||
it_behaves_like 'mounted file in local store'
|
||||
|
@ -68,7 +68,7 @@ RSpec.describe Ci::PipelineArtifact, type: :model do
|
|||
end
|
||||
|
||||
context 'when file contains multi-byte characters' do
|
||||
let(:coverage_report_multibyte) { create(:ci_pipeline_artifact, :with_multibyte_characters) }
|
||||
let(:coverage_report_multibyte) { create(:ci_pipeline_artifact, :with_coverage_multibyte_characters) }
|
||||
|
||||
it 'sets the size in bytesize' do
|
||||
expect(coverage_report_multibyte.size).to eq(14)
|
||||
|
@ -83,7 +83,7 @@ RSpec.describe Ci::PipelineArtifact, type: :model do
|
|||
let(:file_type) { :code_coverage }
|
||||
|
||||
context 'when pipeline artifact has a coverage report' do
|
||||
let!(:pipeline_artifact) { create(:ci_pipeline_artifact) }
|
||||
let!(:pipeline_artifact) { create(:ci_pipeline_artifact, :with_coverage_report) }
|
||||
|
||||
it 'returns true' do
|
||||
expect(pipeline_artifact).to be_truthy
|
||||
|
@ -101,7 +101,7 @@ RSpec.describe Ci::PipelineArtifact, type: :model do
|
|||
let(:file_type) { :code_quality }
|
||||
|
||||
context 'when pipeline artifact has a quality report' do
|
||||
let!(:pipeline_artifact) { create(:ci_pipeline_artifact, :codequality_report) }
|
||||
let!(:pipeline_artifact) { create(:ci_pipeline_artifact, :with_codequality_report) }
|
||||
|
||||
it 'returns true' do
|
||||
expect(pipeline_artifact).to be_truthy
|
||||
|
@ -131,7 +131,7 @@ RSpec.describe Ci::PipelineArtifact, type: :model do
|
|||
let(:file_type) { :code_coverage }
|
||||
|
||||
context 'when pipeline artifact has a coverage report' do
|
||||
let!(:coverage_report) { create(:ci_pipeline_artifact) }
|
||||
let!(:coverage_report) { create(:ci_pipeline_artifact, :with_coverage_report) }
|
||||
|
||||
it 'returns a pipeline artifact with a coverage report' do
|
||||
expect(pipeline_artifact.file_type).to eq('code_coverage')
|
||||
|
@ -149,7 +149,7 @@ RSpec.describe Ci::PipelineArtifact, type: :model do
|
|||
let(:file_type) { :code_quality }
|
||||
|
||||
context 'when pipeline artifact has a quality report' do
|
||||
let!(:coverage_report) { create(:ci_pipeline_artifact, :codequality_report) }
|
||||
let!(:coverage_report) { create(:ci_pipeline_artifact, :with_codequality_report) }
|
||||
|
||||
it 'returns a pipeline artifact with a quality report' do
|
||||
expect(pipeline_artifact.file_type).to eq('code_quality')
|
||||
|
|
|
@ -3388,7 +3388,7 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
|
|||
|
||||
describe '#batch_lookup_report_artifact_for_file_type' do
|
||||
context 'with code quality report artifact' do
|
||||
let(:pipeline) { create(:ci_pipeline, :with_codequality_report, project: project) }
|
||||
let(:pipeline) { create(:ci_pipeline, :with_codequality_reports, project: project) }
|
||||
|
||||
it "returns the code quality artifact" do
|
||||
expect(pipeline.batch_lookup_report_artifact_for_file_type(:codequality)).to eq(pipeline.job_artifacts.sample)
|
||||
|
@ -3514,7 +3514,7 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
|
|||
subject { pipeline.has_codequality_reports? }
|
||||
|
||||
context 'when pipeline has a codequality artifact' do
|
||||
let(:pipeline) { create(:ci_pipeline, :with_codequality_report_artifact, :running, project: project) }
|
||||
let(:pipeline) { create(:ci_pipeline, :with_quality_report_artifact, :running, project: project) }
|
||||
|
||||
it { expect(subject).to be_truthy }
|
||||
end
|
||||
|
|
|
@ -22,6 +22,7 @@ RSpec.describe Admin::UserEntity do
|
|||
:username,
|
||||
:last_activity_on,
|
||||
:avatar_url,
|
||||
:note,
|
||||
:badges,
|
||||
:projects_count,
|
||||
:actions
|
||||
|
|
|
@ -17,6 +17,7 @@ RSpec.describe Admin::UserSerializer do
|
|||
:username,
|
||||
:last_activity_on,
|
||||
:avatar_url,
|
||||
:note,
|
||||
:badges,
|
||||
:projects_count,
|
||||
:actions
|
||||
|
|
|
@ -77,7 +77,7 @@ RSpec.describe MergeRequestWidgetEntity do
|
|||
end
|
||||
|
||||
describe 'codequality report artifacts', :request_store do
|
||||
let(:merge_base_pipeline) { create(:ci_pipeline, :with_codequality_report, project: project) }
|
||||
let(:merge_base_pipeline) { create(:ci_pipeline, :with_codequality_reports, project: project) }
|
||||
|
||||
before do
|
||||
project.add_developer(user)
|
||||
|
@ -90,7 +90,7 @@ RSpec.describe MergeRequestWidgetEntity do
|
|||
end
|
||||
|
||||
context 'with report artifacts' do
|
||||
let(:pipeline) { create(:ci_pipeline, :with_codequality_report, project: project) }
|
||||
let(:pipeline) { create(:ci_pipeline, :with_codequality_reports, project: project) }
|
||||
let(:generic_job_id) { pipeline.builds.first.id }
|
||||
let(:merge_base_job_id) { merge_base_pipeline.builds.first.id }
|
||||
|
||||
|
@ -100,7 +100,7 @@ RSpec.describe MergeRequestWidgetEntity do
|
|||
end
|
||||
|
||||
context 'on pipelines for merged results' do
|
||||
let(:pipeline) { create(:ci_pipeline, :merged_result_pipeline, :with_codequality_report, project: project) }
|
||||
let(:pipeline) { create(:ci_pipeline, :merged_result_pipeline, :with_codequality_reports, project: project) }
|
||||
|
||||
it 'returns URLs from the head_pipeline and merge_base_pipeline' do
|
||||
expect(subject[:codeclimate][:head_path]).to include("/jobs/#{generic_job_id}/artifacts/download?file_type=codequality")
|
||||
|
|
|
@ -7,7 +7,7 @@ RSpec.describe Ci::PipelineArtifacts::ExpireArtifactsWorker do
|
|||
|
||||
describe '#perform' do
|
||||
let_it_be(:pipeline_artifact) do
|
||||
create(:ci_pipeline_artifact, expire_at: 1.week.ago)
|
||||
create(:ci_pipeline_artifact, :with_coverage_report, expire_at: 1.week.ago)
|
||||
end
|
||||
|
||||
it 'executes a service' do
|
||||
|
|