Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
c64b892786
commit
325318e2dd
|
@ -324,6 +324,12 @@ export default {
|
||||||
</div>
|
</div>
|
||||||
<div class="gl-pl-2" data-testid="service">{{ alert.service }}</div>
|
<div class="gl-pl-2" data-testid="service">{{ alert.service }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="alert.runbook" class="gl-my-5 gl-display-flex">
|
||||||
|
<div class="bold gl-w-13 gl-text-right gl-pr-3">
|
||||||
|
{{ s__('AlertManagement|Runbook') }}:
|
||||||
|
</div>
|
||||||
|
<div class="gl-pl-2" data-testid="runbook">{{ alert.runbook }}</div>
|
||||||
|
</div>
|
||||||
<template>
|
<template>
|
||||||
<div v-if="alert.notes.nodes" class="issuable-discussion py-5">
|
<div v-if="alert.notes.nodes" class="issuable-discussion py-5">
|
||||||
<ul class="notes main-notes-list timeline">
|
<ul class="notes main-notes-list timeline">
|
||||||
|
|
|
@ -11,6 +11,7 @@ fragment AlertDetailItem on AlertManagementAlert {
|
||||||
updatedAt
|
updatedAt
|
||||||
endedAt
|
endedAt
|
||||||
details
|
details
|
||||||
|
runbook
|
||||||
todos {
|
todos {
|
||||||
nodes {
|
nodes {
|
||||||
id
|
id
|
||||||
|
|
|
@ -93,10 +93,6 @@ const createPipelineHeaderApp = mediator => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const createTestDetails = () => {
|
const createTestDetails = () => {
|
||||||
if (!window.gon?.features?.junitPipelineView) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const el = document.querySelector('#js-pipeline-tests-detail');
|
const el = document.querySelector('#js-pipeline-tests-detail');
|
||||||
const { summaryEndpoint, suiteEndpoint } = el?.dataset || {};
|
const { summaryEndpoint, suiteEndpoint } = el?.dataset || {};
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ export default {
|
||||||
return `${this.pipelinePath}/test_report`;
|
return `${this.pipelinePath}/test_report`;
|
||||||
},
|
},
|
||||||
showViewFullReport() {
|
showViewFullReport() {
|
||||||
return Boolean(this.glFeatures.junitPipelineView) && this.pipelinePath.length;
|
return this.pipelinePath.length;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
@ -116,6 +116,7 @@ export default {
|
||||||
<template v-if="showViewFullReport" #actionButtons>
|
<template v-if="showViewFullReport" #actionButtons>
|
||||||
<gl-button
|
<gl-button
|
||||||
:href="testTabURL"
|
:href="testTabURL"
|
||||||
|
target="_blank"
|
||||||
icon="external-link"
|
icon="external-link"
|
||||||
data-testid="group-test-reports-full-link"
|
data-testid="group-test-reports-full-link"
|
||||||
class="gl-mr-3"
|
class="gl-mr-3"
|
||||||
|
|
|
@ -43,7 +43,6 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
|
||||||
|
|
||||||
before_action do
|
before_action do
|
||||||
push_frontend_feature_flag(:vue_issuable_sidebar, @project.group)
|
push_frontend_feature_flag(:vue_issuable_sidebar, @project.group)
|
||||||
push_frontend_feature_flag(:junit_pipeline_view, @project.group)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
around_action :allow_gitaly_ref_name_caching, only: [:index, :show, :discussions]
|
around_action :allow_gitaly_ref_name_caching, only: [:index, :show, :discussions]
|
||||||
|
|
|
@ -12,7 +12,6 @@ class Projects::PipelinesController < Projects::ApplicationController
|
||||||
before_action :authorize_create_pipeline!, only: [:new, :create]
|
before_action :authorize_create_pipeline!, only: [:new, :create]
|
||||||
before_action :authorize_update_pipeline!, only: [:retry, :cancel]
|
before_action :authorize_update_pipeline!, only: [:retry, :cancel]
|
||||||
before_action do
|
before_action do
|
||||||
push_frontend_feature_flag(:junit_pipeline_view, project)
|
|
||||||
push_frontend_feature_flag(:filter_pipelines_search, project, default_enabled: true)
|
push_frontend_feature_flag(:filter_pipelines_search, project, default_enabled: true)
|
||||||
push_frontend_feature_flag(:dag_pipeline_tab, project, default_enabled: true)
|
push_frontend_feature_flag(:dag_pipeline_tab, project, default_enabled: true)
|
||||||
push_frontend_feature_flag(:pipelines_security_report_summary, project)
|
push_frontend_feature_flag(:pipelines_security_report_summary, project)
|
||||||
|
@ -177,8 +176,6 @@ class Projects::PipelinesController < Projects::ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_report
|
def test_report
|
||||||
return unless Feature.enabled?(:junit_pipeline_view, project)
|
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html do
|
format.html do
|
||||||
render 'show'
|
render 'show'
|
||||||
|
|
|
@ -17,7 +17,7 @@ module HasWiki
|
||||||
|
|
||||||
def wiki
|
def wiki
|
||||||
strong_memoize(:wiki) do
|
strong_memoize(:wiki) do
|
||||||
Wiki.for_container(self, self.owner)
|
Wiki.for_container(self, self.default_owner)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -563,6 +563,10 @@ class Group < Namespace
|
||||||
all_projects.update_all(shared_runners_enabled: false)
|
all_projects.update_all(shared_runners_enabled: false)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def default_owner
|
||||||
|
owners.first || parent&.default_owner || owner
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def update_two_factor_requirement
|
def update_two_factor_requirement
|
||||||
|
|
|
@ -1395,6 +1395,16 @@ class Project < ApplicationRecord
|
||||||
group || namespace.try(:owner)
|
group || namespace.try(:owner)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def default_owner
|
||||||
|
obj = owner
|
||||||
|
|
||||||
|
if obj.respond_to?(:default_owner)
|
||||||
|
obj.default_owner
|
||||||
|
else
|
||||||
|
obj
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def to_ability_name
|
def to_ability_name
|
||||||
model_name.singular
|
model_name.singular
|
||||||
end
|
end
|
||||||
|
|
|
@ -35,6 +35,7 @@ class Wiki
|
||||||
def initialize(container, user = nil)
|
def initialize(container, user = nil)
|
||||||
@container = container
|
@container = container
|
||||||
@user = user
|
@user = user
|
||||||
|
raise ArgumentError, "user must be a User, got #{user.class}" if user && !user.is_a?(User)
|
||||||
end
|
end
|
||||||
|
|
||||||
def path
|
def path
|
||||||
|
|
|
@ -96,12 +96,12 @@ module AlertManagement
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_assignement(old_assignees)
|
def handle_assignement(old_assignees)
|
||||||
assign_todo
|
assign_todo(old_assignees)
|
||||||
add_assignee_system_note(old_assignees)
|
add_assignee_system_note(old_assignees)
|
||||||
end
|
end
|
||||||
|
|
||||||
def assign_todo
|
def assign_todo(old_assignees)
|
||||||
todo_service.assign_alert(alert, current_user)
|
todo_service.reassigned_assignable(alert, current_user, old_assignees)
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_assignee_system_note(old_assignees)
|
def add_assignee_system_note(old_assignees)
|
||||||
|
|
|
@ -109,7 +109,7 @@ class EventCreateService
|
||||||
def wiki_event(wiki_page_meta, author, action, fingerprint)
|
def wiki_event(wiki_page_meta, author, action, fingerprint)
|
||||||
raise IllegalActionError, action unless Event::WIKI_ACTIONS.include?(action)
|
raise IllegalActionError, action unless Event::WIKI_ACTIONS.include?(action)
|
||||||
|
|
||||||
Gitlab::UsageDataCounters::TrackUniqueActions.track_action(event_action: action, event_target: wiki_page_meta.class, author_id: author.id)
|
Gitlab::UsageDataCounters::TrackUniqueActions.track_event(event_action: action, event_target: wiki_page_meta.class, author_id: author.id)
|
||||||
|
|
||||||
duplicate = Event.for_wiki_meta(wiki_page_meta).for_fingerprint(fingerprint).first
|
duplicate = Event.for_wiki_meta(wiki_page_meta).for_fingerprint(fingerprint).first
|
||||||
return duplicate if duplicate.present?
|
return duplicate if duplicate.present?
|
||||||
|
@ -154,7 +154,7 @@ class EventCreateService
|
||||||
result = Event.insert_all(attribute_sets, returning: %w[id])
|
result = Event.insert_all(attribute_sets, returning: %w[id])
|
||||||
|
|
||||||
tuples.each do |record, status, _|
|
tuples.each do |record, status, _|
|
||||||
Gitlab::UsageDataCounters::TrackUniqueActions.track_action(event_action: status, event_target: record.class, author_id: current_user.id)
|
Gitlab::UsageDataCounters::TrackUniqueActions.track_event(event_action: status, event_target: record.class, author_id: current_user.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
result
|
result
|
||||||
|
@ -172,7 +172,7 @@ class EventCreateService
|
||||||
new_event
|
new_event
|
||||||
end
|
end
|
||||||
|
|
||||||
Gitlab::UsageDataCounters::TrackUniqueActions.track_action(event_action: :pushed, event_target: Project, author_id: current_user.id)
|
Gitlab::UsageDataCounters::TrackUniqueActions.track_event(event_action: :pushed, event_target: Project, author_id: current_user.id)
|
||||||
|
|
||||||
Users::LastPushEventService.new(current_user)
|
Users::LastPushEventService.new(current_user)
|
||||||
.cache_last_push_event(event)
|
.cache_last_push_event(event)
|
||||||
|
|
|
@ -43,7 +43,7 @@ module Issues
|
||||||
if issue.assignees != old_assignees
|
if issue.assignees != old_assignees
|
||||||
create_assignee_note(issue, old_assignees)
|
create_assignee_note(issue, old_assignees)
|
||||||
notification_service.async.reassigned_issue(issue, current_user, old_assignees)
|
notification_service.async.reassigned_issue(issue, current_user, old_assignees)
|
||||||
todo_service.reassigned_issuable(issue, current_user, old_assignees)
|
todo_service.reassigned_assignable(issue, current_user, old_assignees)
|
||||||
end
|
end
|
||||||
|
|
||||||
if issue.previous_changes.include?('confidential')
|
if issue.previous_changes.include?('confidential')
|
||||||
|
|
|
@ -105,7 +105,7 @@ module MergeRequests
|
||||||
def handle_assignees_change(merge_request, old_assignees)
|
def handle_assignees_change(merge_request, old_assignees)
|
||||||
create_assignee_note(merge_request, old_assignees)
|
create_assignee_note(merge_request, old_assignees)
|
||||||
notification_service.async.reassigned_merge_request(merge_request, current_user, old_assignees)
|
notification_service.async.reassigned_merge_request(merge_request, current_user, old_assignees)
|
||||||
todo_service.reassigned_issuable(merge_request, current_user, old_assignees)
|
todo_service.reassigned_assignable(merge_request, current_user, old_assignees)
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_branch_change_note(issuable, branch_type, old_branch, new_branch)
|
def create_branch_change_note(issuable, branch_type, old_branch, new_branch)
|
||||||
|
|
|
@ -32,6 +32,8 @@ module ResourceAccessTokens
|
||||||
attr_reader :resource_type, :resource
|
attr_reader :resource_type, :resource
|
||||||
|
|
||||||
def feature_enabled?
|
def feature_enabled?
|
||||||
|
return false if ::Gitlab.com?
|
||||||
|
|
||||||
::Feature.enabled?(:resource_access_token, resource, default_enabled: true)
|
::Feature.enabled?(:resource_access_token, resource, default_enabled: true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -49,11 +49,11 @@ class TodoService
|
||||||
todo_users.each(&:update_todos_count_cache)
|
todo_users.each(&:update_todos_count_cache)
|
||||||
end
|
end
|
||||||
|
|
||||||
# When we reassign an issuable we should:
|
# When we reassign an assignable object (issuable, alert) we should:
|
||||||
#
|
#
|
||||||
# * create a pending todo for new assignee if issuable is assigned
|
# * create a pending todo for new assignee if object is assigned
|
||||||
#
|
#
|
||||||
def reassigned_issuable(issuable, current_user, old_assignees = [])
|
def reassigned_assignable(issuable, current_user, old_assignees = [])
|
||||||
create_assignment_todo(issuable, current_user, old_assignees)
|
create_assignment_todo(issuable, current_user, old_assignees)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -154,14 +154,6 @@ class TodoService
|
||||||
resolve_todos_for_target(awardable, current_user)
|
resolve_todos_for_target(awardable, current_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
# When assigning an alert we should:
|
|
||||||
#
|
|
||||||
# * create a pending todo for new assignee if alert is assigned
|
|
||||||
#
|
|
||||||
def assign_alert(alert, current_user)
|
|
||||||
create_assignment_todo(alert, current_user, [])
|
|
||||||
end
|
|
||||||
|
|
||||||
# When user marks a target as todo
|
# When user marks a target as todo
|
||||||
def mark_todo(target, current_user)
|
def mark_todo(target, current_user)
|
||||||
attributes = attributes_for_todo(target.project, target, current_user, Todo::MARKED)
|
attributes = attributes_for_todo(target.project, target, current_user, Todo::MARKED)
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
- return if pipeline_has_errors
|
- return if pipeline_has_errors
|
||||||
- test_reports_enabled = Feature.enabled?(:junit_pipeline_view, @project)
|
|
||||||
- dag_pipeline_tab_enabled = Feature.enabled?(:dag_pipeline_tab, @project, default_enabled: true)
|
- dag_pipeline_tab_enabled = Feature.enabled?(:dag_pipeline_tab, @project, default_enabled: true)
|
||||||
|
|
||||||
.tabs-holder
|
.tabs-holder
|
||||||
|
@ -20,7 +19,6 @@
|
||||||
= link_to failures_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-failures', action: 'failures', toggle: 'tab' }, class: 'failures-tab' do
|
= link_to failures_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-failures', action: 'failures', toggle: 'tab' }, class: 'failures-tab' do
|
||||||
= _('Failed Jobs')
|
= _('Failed Jobs')
|
||||||
%span.badge.badge-pill.js-failures-counter= @pipeline.failed_builds.count
|
%span.badge.badge-pill.js-failures-counter= @pipeline.failed_builds.count
|
||||||
- if test_reports_enabled
|
|
||||||
%li.js-tests-tab-link
|
%li.js-tests-tab-link
|
||||||
= link_to test_report_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-tests', action: 'test_report', toggle: 'tab' }, class: 'test-tab' do
|
= link_to test_report_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-tests', action: 'test_report', toggle: 'tab' }, class: 'test-tab' do
|
||||||
= s_('TestReports|Tests')
|
= s_('TestReports|Tests')
|
||||||
|
|
|
@ -10,8 +10,9 @@
|
||||||
= page_title
|
= page_title
|
||||||
%p
|
%p
|
||||||
= _('You can generate an access token scoped to this project for each application to use the GitLab API.')
|
= _('You can generate an access token scoped to this project for each application to use the GitLab API.')
|
||||||
%p
|
-# Commented out until https://gitlab.com/gitlab-org/gitlab/-/issues/219551 is fixed
|
||||||
= _('You can also use project access tokens to authenticate against Git over HTTP.')
|
-# %p
|
||||||
|
-# = _('You can also use project access tokens to authenticate against Git over HTTP.')
|
||||||
|
|
||||||
.col-lg-8
|
.col-lg-8
|
||||||
- if @new_project_access_token
|
- if @new_project_access_token
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: JUnit test report on pipeline detail page
|
||||||
|
merge_request: 39260
|
||||||
|
author:
|
||||||
|
type: added
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Make View full report button open link in new tab
|
||||||
|
merge_request: 39501
|
||||||
|
author:
|
||||||
|
type: changed
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Show runbook for alert in detail view
|
||||||
|
merge_request: 39477
|
||||||
|
author:
|
||||||
|
type: added
|
|
@ -575,6 +575,9 @@ Gitlab.ee do
|
||||||
Settings.cron_jobs['elastic_cluster_reindexing_cron_worker'] ||= Settingslogic.new({})
|
Settings.cron_jobs['elastic_cluster_reindexing_cron_worker'] ||= Settingslogic.new({})
|
||||||
Settings.cron_jobs['elastic_cluster_reindexing_cron_worker']['cron'] ||= '*/10 * * * *'
|
Settings.cron_jobs['elastic_cluster_reindexing_cron_worker']['cron'] ||= '*/10 * * * *'
|
||||||
Settings.cron_jobs['elastic_cluster_reindexing_cron_worker']['job_class'] ||= 'ElasticClusterReindexingCronWorker'
|
Settings.cron_jobs['elastic_cluster_reindexing_cron_worker']['job_class'] ||= 'ElasticClusterReindexingCronWorker'
|
||||||
|
Settings.cron_jobs['elastic_remove_expired_namespace_subscriptions_from_index_cron_worker'] ||= Settingslogic.new({})
|
||||||
|
Settings.cron_jobs['elastic_remove_expired_namespace_subscriptions_from_index_cron_worker']['cron'] ||= '10 3 * * *'
|
||||||
|
Settings.cron_jobs['elastic_remove_expired_namespace_subscriptions_from_index_cron_worker']['job_class'] ||= 'ElasticRemoveExpiredNamespaceSubscriptionsFromIndexCronWorker'
|
||||||
Settings.cron_jobs['sync_seat_link_worker'] ||= Settingslogic.new({})
|
Settings.cron_jobs['sync_seat_link_worker'] ||= Settingslogic.new({})
|
||||||
Settings.cron_jobs['sync_seat_link_worker']['cron'] ||= "#{rand(60)} 0 * * *"
|
Settings.cron_jobs['sync_seat_link_worker']['cron'] ||= "#{rand(60)} 0 * * *"
|
||||||
Settings.cron_jobs['sync_seat_link_worker']['job_class'] = 'SyncSeatLinkWorker'
|
Settings.cron_jobs['sync_seat_link_worker']['job_class'] = 'SyncSeatLinkWorker'
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class AddIndexOnEndDateAndNamespaceIdToGitlabSubscriptions < ActiveRecord::Migration[6.0]
|
||||||
|
include Gitlab::Database::MigrationHelpers
|
||||||
|
|
||||||
|
DOWNTIME = false
|
||||||
|
|
||||||
|
disable_ddl_transaction!
|
||||||
|
|
||||||
|
def up
|
||||||
|
add_concurrent_index :gitlab_subscriptions, [:end_date, :namespace_id]
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
remove_concurrent_index :gitlab_subscriptions, [:end_date, :namespace_id]
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1 @@
|
||||||
|
432ef9d45c8242ab8db954ceeb6a68a75ef46181dd868a30d68fef0ed6058caf
|
|
@ -19710,6 +19710,8 @@ CREATE INDEX index_geo_upload_deleted_events_on_upload_id ON public.geo_upload_d
|
||||||
|
|
||||||
CREATE INDEX index_gitlab_subscription_histories_on_gitlab_subscription_id ON public.gitlab_subscription_histories USING btree (gitlab_subscription_id);
|
CREATE INDEX index_gitlab_subscription_histories_on_gitlab_subscription_id ON public.gitlab_subscription_histories USING btree (gitlab_subscription_id);
|
||||||
|
|
||||||
|
CREATE INDEX index_gitlab_subscriptions_on_end_date_and_namespace_id ON public.gitlab_subscriptions USING btree (end_date, namespace_id);
|
||||||
|
|
||||||
CREATE INDEX index_gitlab_subscriptions_on_hosted_plan_id ON public.gitlab_subscriptions USING btree (hosted_plan_id);
|
CREATE INDEX index_gitlab_subscriptions_on_hosted_plan_id ON public.gitlab_subscriptions USING btree (hosted_plan_id);
|
||||||
|
|
||||||
CREATE UNIQUE INDEX index_gitlab_subscriptions_on_namespace_id ON public.gitlab_subscriptions USING btree (namespace_id);
|
CREATE UNIQUE INDEX index_gitlab_subscriptions_on_namespace_id ON public.gitlab_subscriptions USING btree (namespace_id);
|
||||||
|
|
|
@ -103,10 +103,10 @@ Some feature flags can be enabled or disabled on a per project basis:
|
||||||
Feature.enable(:<feature flag>, Project.find(<project id>))
|
Feature.enable(:<feature flag>, Project.find(<project id>))
|
||||||
```
|
```
|
||||||
|
|
||||||
For example, to enable the [`:junit_pipeline_view`](../ci/junit_test_reports.md#enabling-the-junit-test-reports-feature-core-only) feature flag for project `1234`:
|
For example, to enable the [`:product_analytics`](../operations/product_analytics.md#enable-or-disable-product-analytics) feature flag for project `1234`:
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
Feature.enable(:junit_pipeline_view, Project.find(1234))
|
Feature.enable(:product_analytics, Project.find(1234))
|
||||||
```
|
```
|
||||||
|
|
||||||
`Feature.enable` and `Feature.disable` always return `nil`, this is not an indication that the command failed:
|
`Feature.enable` and `Feature.disable` always return `nil`, this is not an indication that the command failed:
|
||||||
|
|
|
@ -1135,42 +1135,47 @@ type BoardEdge {
|
||||||
|
|
||||||
input BoardEpicIssueInput {
|
input BoardEpicIssueInput {
|
||||||
"""
|
"""
|
||||||
Username of a user assigned to issues
|
Filter by assignee username
|
||||||
"""
|
"""
|
||||||
assigneeUsername: [String]
|
assigneeUsername: [String]
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Username of the issues author
|
Filter by author username
|
||||||
"""
|
"""
|
||||||
authorUsername: String
|
authorUsername: String
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Epic ID applied to issues
|
Filter by epic ID
|
||||||
"""
|
"""
|
||||||
epicId: String
|
epicId: String
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Label applied to issues
|
Filter by label name
|
||||||
"""
|
"""
|
||||||
labelName: [String]
|
labelName: [String]
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Milestone applied to issues
|
Filter by milestone title
|
||||||
"""
|
"""
|
||||||
milestoneTitle: String
|
milestoneTitle: String
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Reaction emoji applied to issues
|
Filter by reaction emoji
|
||||||
"""
|
"""
|
||||||
myReactionEmoji: String
|
myReactionEmoji: String
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Release applied to issues
|
List of negated params. Warning: this argument is experimental and a subject to change in future
|
||||||
|
"""
|
||||||
|
not: NegatedBoardEpicIssueInput
|
||||||
|
|
||||||
|
"""
|
||||||
|
Filter by release tag
|
||||||
"""
|
"""
|
||||||
releaseTag: String
|
releaseTag: String
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Weight applied to issues
|
Filter by weight
|
||||||
"""
|
"""
|
||||||
weight: String
|
weight: String
|
||||||
}
|
}
|
||||||
|
@ -9795,6 +9800,48 @@ type NamespaceIncreaseStorageTemporarilyPayload {
|
||||||
namespace: Namespace
|
namespace: Namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input NegatedBoardEpicIssueInput {
|
||||||
|
"""
|
||||||
|
Filter by assignee username
|
||||||
|
"""
|
||||||
|
assigneeUsername: [String]
|
||||||
|
|
||||||
|
"""
|
||||||
|
Filter by author username
|
||||||
|
"""
|
||||||
|
authorUsername: String
|
||||||
|
|
||||||
|
"""
|
||||||
|
Filter by epic ID
|
||||||
|
"""
|
||||||
|
epicId: String
|
||||||
|
|
||||||
|
"""
|
||||||
|
Filter by label name
|
||||||
|
"""
|
||||||
|
labelName: [String]
|
||||||
|
|
||||||
|
"""
|
||||||
|
Filter by milestone title
|
||||||
|
"""
|
||||||
|
milestoneTitle: String
|
||||||
|
|
||||||
|
"""
|
||||||
|
Filter by reaction emoji
|
||||||
|
"""
|
||||||
|
myReactionEmoji: String
|
||||||
|
|
||||||
|
"""
|
||||||
|
Filter by release tag
|
||||||
|
"""
|
||||||
|
releaseTag: String
|
||||||
|
|
||||||
|
"""
|
||||||
|
Filter by weight
|
||||||
|
"""
|
||||||
|
weight: String
|
||||||
|
}
|
||||||
|
|
||||||
type Note implements ResolvableInterface {
|
type Note implements ResolvableInterface {
|
||||||
"""
|
"""
|
||||||
User who wrote this note
|
User who wrote this note
|
||||||
|
|
|
@ -3049,7 +3049,7 @@
|
||||||
"inputFields": [
|
"inputFields": [
|
||||||
{
|
{
|
||||||
"name": "labelName",
|
"name": "labelName",
|
||||||
"description": "Label applied to issues",
|
"description": "Filter by label name",
|
||||||
"type": {
|
"type": {
|
||||||
"kind": "LIST",
|
"kind": "LIST",
|
||||||
"name": null,
|
"name": null,
|
||||||
|
@ -3063,7 +3063,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "milestoneTitle",
|
"name": "milestoneTitle",
|
||||||
"description": "Milestone applied to issues",
|
"description": "Filter by milestone title",
|
||||||
"type": {
|
"type": {
|
||||||
"kind": "SCALAR",
|
"kind": "SCALAR",
|
||||||
"name": "String",
|
"name": "String",
|
||||||
|
@ -3073,7 +3073,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "assigneeUsername",
|
"name": "assigneeUsername",
|
||||||
"description": "Username of a user assigned to issues",
|
"description": "Filter by assignee username",
|
||||||
"type": {
|
"type": {
|
||||||
"kind": "LIST",
|
"kind": "LIST",
|
||||||
"name": null,
|
"name": null,
|
||||||
|
@ -3087,7 +3087,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "authorUsername",
|
"name": "authorUsername",
|
||||||
"description": "Username of the issues author",
|
"description": "Filter by author username",
|
||||||
"type": {
|
"type": {
|
||||||
"kind": "SCALAR",
|
"kind": "SCALAR",
|
||||||
"name": "String",
|
"name": "String",
|
||||||
|
@ -3097,7 +3097,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "releaseTag",
|
"name": "releaseTag",
|
||||||
"description": "Release applied to issues",
|
"description": "Filter by release tag",
|
||||||
"type": {
|
"type": {
|
||||||
"kind": "SCALAR",
|
"kind": "SCALAR",
|
||||||
"name": "String",
|
"name": "String",
|
||||||
|
@ -3107,7 +3107,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "epicId",
|
"name": "epicId",
|
||||||
"description": "Epic ID applied to issues",
|
"description": "Filter by epic ID",
|
||||||
"type": {
|
"type": {
|
||||||
"kind": "SCALAR",
|
"kind": "SCALAR",
|
||||||
"name": "String",
|
"name": "String",
|
||||||
|
@ -3117,7 +3117,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "myReactionEmoji",
|
"name": "myReactionEmoji",
|
||||||
"description": "Reaction emoji applied to issues",
|
"description": "Filter by reaction emoji",
|
||||||
"type": {
|
"type": {
|
||||||
"kind": "SCALAR",
|
"kind": "SCALAR",
|
||||||
"name": "String",
|
"name": "String",
|
||||||
|
@ -3127,13 +3127,23 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "weight",
|
"name": "weight",
|
||||||
"description": "Weight applied to issues",
|
"description": "Filter by weight",
|
||||||
"type": {
|
"type": {
|
||||||
"kind": "SCALAR",
|
"kind": "SCALAR",
|
||||||
"name": "String",
|
"name": "String",
|
||||||
"ofType": null
|
"ofType": null
|
||||||
},
|
},
|
||||||
"defaultValue": null
|
"defaultValue": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "not",
|
||||||
|
"description": "List of negated params. Warning: this argument is experimental and a subject to change in future",
|
||||||
|
"type": {
|
||||||
|
"kind": "INPUT_OBJECT",
|
||||||
|
"name": "NegatedBoardEpicIssueInput",
|
||||||
|
"ofType": null
|
||||||
|
},
|
||||||
|
"defaultValue": null
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"interfaces": null,
|
"interfaces": null,
|
||||||
|
@ -29245,6 +29255,105 @@
|
||||||
"enumValues": null,
|
"enumValues": null,
|
||||||
"possibleTypes": null
|
"possibleTypes": null
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"kind": "INPUT_OBJECT",
|
||||||
|
"name": "NegatedBoardEpicIssueInput",
|
||||||
|
"description": null,
|
||||||
|
"fields": null,
|
||||||
|
"inputFields": [
|
||||||
|
{
|
||||||
|
"name": "labelName",
|
||||||
|
"description": "Filter by label name",
|
||||||
|
"type": {
|
||||||
|
"kind": "LIST",
|
||||||
|
"name": null,
|
||||||
|
"ofType": {
|
||||||
|
"kind": "SCALAR",
|
||||||
|
"name": "String",
|
||||||
|
"ofType": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"defaultValue": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "milestoneTitle",
|
||||||
|
"description": "Filter by milestone title",
|
||||||
|
"type": {
|
||||||
|
"kind": "SCALAR",
|
||||||
|
"name": "String",
|
||||||
|
"ofType": null
|
||||||
|
},
|
||||||
|
"defaultValue": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "assigneeUsername",
|
||||||
|
"description": "Filter by assignee username",
|
||||||
|
"type": {
|
||||||
|
"kind": "LIST",
|
||||||
|
"name": null,
|
||||||
|
"ofType": {
|
||||||
|
"kind": "SCALAR",
|
||||||
|
"name": "String",
|
||||||
|
"ofType": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"defaultValue": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "authorUsername",
|
||||||
|
"description": "Filter by author username",
|
||||||
|
"type": {
|
||||||
|
"kind": "SCALAR",
|
||||||
|
"name": "String",
|
||||||
|
"ofType": null
|
||||||
|
},
|
||||||
|
"defaultValue": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "releaseTag",
|
||||||
|
"description": "Filter by release tag",
|
||||||
|
"type": {
|
||||||
|
"kind": "SCALAR",
|
||||||
|
"name": "String",
|
||||||
|
"ofType": null
|
||||||
|
},
|
||||||
|
"defaultValue": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "epicId",
|
||||||
|
"description": "Filter by epic ID",
|
||||||
|
"type": {
|
||||||
|
"kind": "SCALAR",
|
||||||
|
"name": "String",
|
||||||
|
"ofType": null
|
||||||
|
},
|
||||||
|
"defaultValue": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "myReactionEmoji",
|
||||||
|
"description": "Filter by reaction emoji",
|
||||||
|
"type": {
|
||||||
|
"kind": "SCALAR",
|
||||||
|
"name": "String",
|
||||||
|
"ofType": null
|
||||||
|
},
|
||||||
|
"defaultValue": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "weight",
|
||||||
|
"description": "Filter by weight",
|
||||||
|
"type": {
|
||||||
|
"kind": "SCALAR",
|
||||||
|
"name": "String",
|
||||||
|
"ofType": null
|
||||||
|
},
|
||||||
|
"defaultValue": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"interfaces": null,
|
||||||
|
"enumValues": null,
|
||||||
|
"possibleTypes": null
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"kind": "OBJECT",
|
"kind": "OBJECT",
|
||||||
"name": "Note",
|
"name": "Note",
|
||||||
|
|
|
@ -239,9 +239,8 @@ Test:
|
||||||
|
|
||||||
## Viewing JUnit test reports on GitLab
|
## Viewing JUnit test reports on GitLab
|
||||||
|
|
||||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/24792) in GitLab 12.5.
|
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/24792) in GitLab 12.5 behind a feature flag (`junit_pipeline_view`), disabled by default.
|
||||||
> - It's deployed behind a feature flag, disabled by default.
|
> - The feature flag was removed and the feature was [made generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/216478) in GitLab 13.3.
|
||||||
> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enabling-the-junit-test-reports-feature-core-only). **(CORE ONLY)**
|
|
||||||
|
|
||||||
If JUnit XML files are generated and uploaded as part of a pipeline, these reports
|
If JUnit XML files are generated and uploaded as part of a pipeline, these reports
|
||||||
can be viewed inside the pipelines details page. The **Tests** tab on this page will
|
can be viewed inside the pipelines details page. The **Tests** tab on this page will
|
||||||
|
@ -254,22 +253,6 @@ details, including the cases that make up the suite.
|
||||||
|
|
||||||
You can also retrieve the reports via the [GitLab API](../api/pipelines.md#get-a-pipelines-test-report).
|
You can also retrieve the reports via the [GitLab API](../api/pipelines.md#get-a-pipelines-test-report).
|
||||||
|
|
||||||
### Enabling the JUnit test reports feature **(CORE ONLY)**
|
|
||||||
|
|
||||||
This feature comes with the `:junit_pipeline_view` feature flag disabled by default. This
|
|
||||||
feature is disabled due to some performance issues with very large data sets.
|
|
||||||
When [the performance is improved](https://gitlab.com/groups/gitlab-org/-/epics/2854), the feature will be enabled by default.
|
|
||||||
|
|
||||||
To enable this feature, ask a GitLab administrator with [Rails console access](../administration/feature_flags.md#how-to-enable-and-disable-features-behind-flags) to run the
|
|
||||||
following command:
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
Feature.enable(:junit_pipeline_view)
|
|
||||||
|
|
||||||
# Enable the feature for a specific project, GitLab 13.0 and above only.
|
|
||||||
Feature.enable(:junit_pipeline_view, Project.find(<your-project-id-here>))
|
|
||||||
```
|
|
||||||
|
|
||||||
## Viewing JUnit screenshots on GitLab
|
## Viewing JUnit screenshots on GitLab
|
||||||
|
|
||||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/202114) in GitLab 13.0.
|
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/202114) in GitLab 13.0.
|
||||||
|
|
|
@ -5,20 +5,20 @@ info: "To determine the technical writer assigned to the Stage/Group associated
|
||||||
type: reference, howto
|
type: reference, howto
|
||||||
---
|
---
|
||||||
|
|
||||||
# Project access tokens (Alpha) **(CORE ONLY)**
|
# Project access tokens **(CORE ONLY)**
|
||||||
|
|
||||||
CAUTION: **Warning:**
|
|
||||||
This is an [Alpha](https://about.gitlab.com/handbook/product/#alpha) feature, and it is subject to change at any time without
|
|
||||||
prior notice.
|
|
||||||
|
|
||||||
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2587) in GitLab 13.0.
|
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2587) in GitLab 13.0.
|
||||||
> - It's deployed behind a feature flag, disabled by default.
|
> - It was [deployed](https://gitlab.com/groups/gitlab-org/-/epics/2587) behind a feature flag, disabled by default.
|
||||||
|
> - [Became enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/218722) in GitLab 13.3.
|
||||||
> - It's disabled on GitLab.com.
|
> - It's disabled on GitLab.com.
|
||||||
> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-project-access-tokens).
|
> - It can be enabled or disabled by project.
|
||||||
|
> - It's recommended for production use.
|
||||||
|
> - For GitLab self-managed instances, GitLab administrators can [disable it](#enable-or-disable-project-access-tokens).
|
||||||
|
|
||||||
Project access tokens are scoped to a project and can be used to authenticate with the [GitLab API](../../../api/README.md#personalproject-access-tokens).
|
Project access tokens are scoped to a project and can be used to authenticate with the [GitLab API](../../../api/README.md#personalproject-access-tokens).
|
||||||
|
|
||||||
You can also use project access tokens with Git to authenticate over HTTP or SSH.
|
<!-- Commented out until https://gitlab.com/gitlab-org/gitlab/-/issues/219551 is fixed -->
|
||||||
|
<!-- You can also use project access tokens with Git to authenticate over HTTP or SSH. -->
|
||||||
|
|
||||||
Project access tokens expire on the date you define, at midnight UTC.
|
Project access tokens expire on the date you define, at midnight UTC.
|
||||||
|
|
||||||
|
@ -78,19 +78,30 @@ the following table.
|
||||||
|
|
||||||
### Enable or disable project access tokens
|
### Enable or disable project access tokens
|
||||||
|
|
||||||
Project access tokens is an [Alpha](https://about.gitlab.com/handbook/product/#alpha) feature and is not recommended for production use.
|
Project access tokens are deployed behind a feature flag that is **enabled by default**.
|
||||||
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)
|
[GitLab administrators with access to the GitLab Rails console](../../../administration/feature_flags.md)
|
||||||
can enable it for your instance.
|
can disable it for your instance, globally or by project.
|
||||||
|
|
||||||
To enable it:
|
To disable it globally:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
Feature.disable(:resource_access_token)
|
||||||
|
```
|
||||||
|
|
||||||
|
To disable it for a specific project:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
Feature.disable(:resource_access_token, project)
|
||||||
|
```
|
||||||
|
|
||||||
|
To enable it globally:
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
Feature.enable(:resource_access_token)
|
Feature.enable(:resource_access_token)
|
||||||
```
|
```
|
||||||
|
|
||||||
To disable it:
|
To enable it for a specific project:
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
Feature.disable(:resource_access_token)
|
Feature.enable(:resource_access_token, project)
|
||||||
```
|
```
|
||||||
|
|
|
@ -110,15 +110,13 @@ module API
|
||||||
end
|
end
|
||||||
|
|
||||||
desc 'Gets the test report for a given pipeline' do
|
desc 'Gets the test report for a given pipeline' do
|
||||||
detail 'This feature was introduced in GitLab 13.0. Disabled by default behind feature flag `junit_pipeline_view`'
|
detail 'This feature was introduced in GitLab 13.0.'
|
||||||
success TestReportEntity
|
success TestReportEntity
|
||||||
end
|
end
|
||||||
params do
|
params do
|
||||||
requires :pipeline_id, type: Integer, desc: 'The pipeline ID'
|
requires :pipeline_id, type: Integer, desc: 'The pipeline ID'
|
||||||
end
|
end
|
||||||
get ':id/pipelines/:pipeline_id/test_report' do
|
get ':id/pipelines/:pipeline_id/test_report' do
|
||||||
not_found! unless Feature.enabled?(:junit_pipeline_view, user_project)
|
|
||||||
|
|
||||||
authorize! :read_build, pipeline
|
authorize! :read_build, pipeline
|
||||||
|
|
||||||
present pipeline.test_reports, with: TestReportEntity, details: true
|
present pipeline.test_reports, with: TestReportEntity, details: true
|
||||||
|
|
|
@ -607,7 +607,7 @@ module Gitlab
|
||||||
counter = Gitlab::UsageDataCounters::TrackUniqueActions
|
counter = Gitlab::UsageDataCounters::TrackUniqueActions
|
||||||
|
|
||||||
project_count = redis_usage_data do
|
project_count = redis_usage_data do
|
||||||
counter.count_unique_events(
|
counter.count_unique(
|
||||||
event_action: Gitlab::UsageDataCounters::TrackUniqueActions::PUSH_ACTION,
|
event_action: Gitlab::UsageDataCounters::TrackUniqueActions::PUSH_ACTION,
|
||||||
date_from: time_period[:created_at].first,
|
date_from: time_period[:created_at].first,
|
||||||
date_to: time_period[:created_at].last
|
date_to: time_period[:created_at].last
|
||||||
|
@ -615,7 +615,7 @@ module Gitlab
|
||||||
end
|
end
|
||||||
|
|
||||||
design_count = redis_usage_data do
|
design_count = redis_usage_data do
|
||||||
counter.count_unique_events(
|
counter.count_unique(
|
||||||
event_action: Gitlab::UsageDataCounters::TrackUniqueActions::DESIGN_ACTION,
|
event_action: Gitlab::UsageDataCounters::TrackUniqueActions::DESIGN_ACTION,
|
||||||
date_from: time_period[:created_at].first,
|
date_from: time_period[:created_at].first,
|
||||||
date_to: time_period[:created_at].last
|
date_to: time_period[:created_at].last
|
||||||
|
@ -623,7 +623,7 @@ module Gitlab
|
||||||
end
|
end
|
||||||
|
|
||||||
wiki_count = redis_usage_data do
|
wiki_count = redis_usage_data do
|
||||||
counter.count_unique_events(
|
counter.count_unique(
|
||||||
event_action: Gitlab::UsageDataCounters::TrackUniqueActions::WIKI_ACTION,
|
event_action: Gitlab::UsageDataCounters::TrackUniqueActions::WIKI_ACTION,
|
||||||
date_from: time_period[:created_at].first,
|
date_from: time_period[:created_at].first,
|
||||||
date_to: time_period[:created_at].last
|
date_to: time_period[:created_at].last
|
||||||
|
|
|
@ -27,7 +27,7 @@ module Gitlab
|
||||||
}).freeze
|
}).freeze
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
def track_action(event_action:, event_target:, author_id:, time: Time.zone.now)
|
def track_event(event_action:, event_target:, author_id:, time: Time.zone.now)
|
||||||
return unless Gitlab::CurrentSettings.usage_ping_enabled
|
return unless Gitlab::CurrentSettings.usage_ping_enabled
|
||||||
return unless Feature.enabled?(FEATURE_FLAG)
|
return unless Feature.enabled?(FEATURE_FLAG)
|
||||||
return unless valid_target?(event_target)
|
return unless valid_target?(event_target)
|
||||||
|
@ -40,7 +40,7 @@ module Gitlab
|
||||||
Gitlab::Redis::HLL.add(key: target_key, value: author_id, expiry: KEY_EXPIRY_LENGTH)
|
Gitlab::Redis::HLL.add(key: target_key, value: author_id, expiry: KEY_EXPIRY_LENGTH)
|
||||||
end
|
end
|
||||||
|
|
||||||
def count_unique_events(event_action:, date_from:, date_to:)
|
def count_unique(event_action:, date_from:, date_to:)
|
||||||
keys = (date_from.to_date..date_to.to_date).map { |date| key(event_action, date) }
|
keys = (date_from.to_date..date_to.to_date).map { |date| key(event_action, date) }
|
||||||
|
|
||||||
Gitlab::Redis::HLL.count(keys: keys)
|
Gitlab::Redis::HLL.count(keys: keys)
|
||||||
|
|
|
@ -2180,6 +2180,9 @@ msgstr ""
|
||||||
msgid "AlertManagement|Resolved"
|
msgid "AlertManagement|Resolved"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "AlertManagement|Runbook"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "AlertManagement|Service"
|
msgid "AlertManagement|Service"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -27831,9 +27834,6 @@ msgstr ""
|
||||||
msgid "You can also upload existing files from your computer using the instructions below."
|
msgid "You can also upload existing files from your computer using the instructions below."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You can also use project access tokens to authenticate against Git over HTTP."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "You can always edit this later"
|
msgid "You can always edit this later"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -859,11 +859,6 @@ RSpec.describe Projects::PipelinesController do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when feature is enabled' do
|
|
||||||
before do
|
|
||||||
stub_feature_flags(junit_pipeline_view: project)
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when pipeline does not have a test report' do
|
context 'when pipeline does not have a test report' do
|
||||||
it 'renders an empty test report' do
|
it 'renders an empty test report' do
|
||||||
get_test_report_json
|
get_test_report_json
|
||||||
|
@ -875,9 +870,7 @@ RSpec.describe Projects::PipelinesController do
|
||||||
|
|
||||||
context 'when pipeline has a test report' do
|
context 'when pipeline has a test report' do
|
||||||
before do
|
before do
|
||||||
create(:ci_build, name: 'rspec', pipeline: pipeline).tap do |build|
|
create(:ci_build, :test_reports, name: 'rspec', pipeline: pipeline)
|
||||||
create(:ci_job_artifact, :junit, job: build)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'renders the test report' do
|
it 'renders the test report' do
|
||||||
|
@ -890,9 +883,7 @@ RSpec.describe Projects::PipelinesController do
|
||||||
|
|
||||||
context 'when pipeline has a corrupt test report artifact' do
|
context 'when pipeline has a corrupt test report artifact' do
|
||||||
before do
|
before do
|
||||||
create(:ci_build, name: 'rspec', pipeline: pipeline).tap do |build|
|
create(:ci_build, :broken_test_reports, name: 'rspec', pipeline: pipeline)
|
||||||
create(:ci_job_artifact, :junit_with_corrupted_data, job: build)
|
|
||||||
end
|
|
||||||
|
|
||||||
get_test_report_json
|
get_test_report_json
|
||||||
end
|
end
|
||||||
|
@ -952,22 +943,6 @@ RSpec.describe Projects::PipelinesController do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
context 'when feature is disabled' do
|
|
||||||
let(:pipeline) { create(:ci_empty_pipeline, project: project) }
|
|
||||||
|
|
||||||
before do
|
|
||||||
stub_feature_flags(junit_pipeline_view: false)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'renders empty response' do
|
|
||||||
get_test_report_json
|
|
||||||
|
|
||||||
expect(response).to have_gitlab_http_status(:no_content)
|
|
||||||
expect(response.body).to be_empty
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_test_report_json(**args)
|
def get_test_report_json(**args)
|
||||||
params = {
|
params = {
|
||||||
|
|
|
@ -118,6 +118,8 @@ describe('AlertDetails', () => {
|
||||||
${'monitoringTool'} | ${undefined} | ${false}
|
${'monitoringTool'} | ${undefined} | ${false}
|
||||||
${'service'} | ${'Prometheus'} | ${true}
|
${'service'} | ${'Prometheus'} | ${true}
|
||||||
${'service'} | ${undefined} | ${false}
|
${'service'} | ${undefined} | ${false}
|
||||||
|
${'runbook'} | ${undefined} | ${false}
|
||||||
|
${'runbook'} | ${'run.com'} | ${true}
|
||||||
`(`$desc`, ({ field, data, isShown }) => {
|
`(`$desc`, ({ field, data, isShown }) => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mountComponent({ data: { alert: { ...mockAlert, [field]: data } } });
|
mountComponent({ data: { alert: { ...mockAlert, [field]: data } } });
|
||||||
|
|
|
@ -15,7 +15,6 @@ RSpec.describe Projects::PipelinesController, "(JavaScript fixtures)", type: :co
|
||||||
|
|
||||||
before do
|
before do
|
||||||
sign_in(user)
|
sign_in(user)
|
||||||
stub_feature_flags(junit_pipeline_view: project)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "pipelines/test_report.json" do
|
it "pipelines/test_report.json" do
|
||||||
|
|
|
@ -20,10 +20,7 @@ describe('Grouped test reports app', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
let mockStore;
|
let mockStore;
|
||||||
|
|
||||||
const mountComponent = ({
|
const mountComponent = ({ props = { pipelinePath } } = {}) => {
|
||||||
glFeatures = { junitPipelineView: false },
|
|
||||||
props = { pipelinePath },
|
|
||||||
} = {}) => {
|
|
||||||
wrapper = mount(Component, {
|
wrapper = mount(Component, {
|
||||||
store: mockStore,
|
store: mockStore,
|
||||||
localVue,
|
localVue,
|
||||||
|
@ -35,9 +32,6 @@ describe('Grouped test reports app', () => {
|
||||||
methods: {
|
methods: {
|
||||||
fetchReports: () => {},
|
fetchReports: () => {},
|
||||||
},
|
},
|
||||||
provide: {
|
|
||||||
glFeatures,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -78,15 +72,6 @@ describe('Grouped test reports app', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('`View full report` button', () => {
|
describe('`View full report` button', () => {
|
||||||
it('should not render the full test report link', () => {
|
|
||||||
expect(findFullTestReportLink().exists()).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('With junitPipelineView feature flag enabled', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
mountComponent({ glFeatures: { junitPipelineView: true } });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render the full test report link', () => {
|
it('should render the full test report link', () => {
|
||||||
const fullTestReportLink = findFullTestReportLink();
|
const fullTestReportLink = findFullTestReportLink();
|
||||||
|
|
||||||
|
@ -94,12 +79,10 @@ describe('Grouped test reports app', () => {
|
||||||
expect(pipelinePath).not.toBe('');
|
expect(pipelinePath).not.toBe('');
|
||||||
expect(fullTestReportLink.attributes('href')).toBe(`${pipelinePath}/test_report`);
|
expect(fullTestReportLink.attributes('href')).toBe(`${pipelinePath}/test_report`);
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
describe('Without a pipelinePath', () => {
|
describe('Without a pipelinePath', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mountComponent({
|
mountComponent({
|
||||||
glFeatures: { junitPipelineView: true },
|
|
||||||
props: { pipelinePath: '' },
|
props: { pipelinePath: '' },
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,8 +6,7 @@ RSpec.describe Banzai::Filter::GollumTagsFilter do
|
||||||
include FilterSpecHelper
|
include FilterSpecHelper
|
||||||
|
|
||||||
let(:project) { create(:project) }
|
let(:project) { create(:project) }
|
||||||
let(:user) { double }
|
let(:wiki) { ProjectWiki.new(project, nil) }
|
||||||
let(:wiki) { ProjectWiki.new(project, user) }
|
|
||||||
|
|
||||||
describe 'validation' do
|
describe 'validation' do
|
||||||
it 'ensure that a :wiki key exists in context' do
|
it 'ensure that a :wiki key exists in context' do
|
||||||
|
|
|
@ -7,8 +7,7 @@ RSpec.describe Banzai::Filter::WikiLinkFilter do
|
||||||
|
|
||||||
let(:namespace) { build_stubbed(:namespace, name: "wiki_link_ns") }
|
let(:namespace) { build_stubbed(:namespace, name: "wiki_link_ns") }
|
||||||
let(:project) { build_stubbed(:project, :public, name: "wiki_link_project", namespace: namespace) }
|
let(:project) { build_stubbed(:project, :public, name: "wiki_link_project", namespace: namespace) }
|
||||||
let(:user) { double }
|
let(:wiki) { ProjectWiki.new(project, nil) }
|
||||||
let(:wiki) { ProjectWiki.new(project, user) }
|
|
||||||
let(:repository_upload_folder) { Wikis::CreateAttachmentService::ATTACHMENT_PATH }
|
let(:repository_upload_folder) { Wikis::CreateAttachmentService::ATTACHMENT_PATH }
|
||||||
|
|
||||||
it "doesn't rewrite absolute links" do
|
it "doesn't rewrite absolute links" do
|
||||||
|
|
|
@ -5,7 +5,7 @@ require 'spec_helper'
|
||||||
RSpec.describe Banzai::Pipeline::WikiPipeline do
|
RSpec.describe Banzai::Pipeline::WikiPipeline do
|
||||||
let_it_be(:namespace) { create(:namespace, name: "wiki_link_ns") }
|
let_it_be(:namespace) { create(:namespace, name: "wiki_link_ns") }
|
||||||
let_it_be(:project) { create(:project, :public, name: "wiki_link_project", namespace: namespace) }
|
let_it_be(:project) { create(:project, :public, name: "wiki_link_project", namespace: namespace) }
|
||||||
let_it_be(:wiki) { ProjectWiki.new(project, double(:user)) }
|
let_it_be(:wiki) { ProjectWiki.new(project, nil) }
|
||||||
let_it_be(:page) { build(:wiki_page, wiki: wiki, title: 'nested/twice/start-page') }
|
let_it_be(:page) { build(:wiki_page, wiki: wiki, title: 'nested/twice/start-page') }
|
||||||
|
|
||||||
describe 'TableOfContents' do
|
describe 'TableOfContents' do
|
||||||
|
|
|
@ -7,12 +7,12 @@ RSpec.describe Gitlab::UsageDataCounters::TrackUniqueActions, :clean_gitlab_redi
|
||||||
|
|
||||||
let(:time) { Time.zone.now }
|
let(:time) { Time.zone.now }
|
||||||
|
|
||||||
def track_action(params)
|
def track_event(params)
|
||||||
track_unique_events.track_action(params)
|
track_unique_events.track_event(params)
|
||||||
end
|
end
|
||||||
|
|
||||||
def count_unique_events(params)
|
def count_unique(params)
|
||||||
track_unique_events.count_unique_events(params)
|
track_unique_events.count_unique(params)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'tracking an event' do
|
context 'tracking an event' do
|
||||||
|
@ -29,28 +29,28 @@ RSpec.describe Gitlab::UsageDataCounters::TrackUniqueActions, :clean_gitlab_redi
|
||||||
design = Event::TARGET_TYPES[:design]
|
design = Event::TARGET_TYPES[:design]
|
||||||
wiki = Event::TARGET_TYPES[:wiki]
|
wiki = Event::TARGET_TYPES[:wiki]
|
||||||
|
|
||||||
expect(track_action(event_action: :pushed, event_target: project, author_id: 1)).to be_truthy
|
expect(track_event(event_action: :pushed, event_target: project, author_id: 1)).to be_truthy
|
||||||
expect(track_action(event_action: :pushed, event_target: project, author_id: 1)).to be_truthy
|
expect(track_event(event_action: :pushed, event_target: project, author_id: 1)).to be_truthy
|
||||||
expect(track_action(event_action: :pushed, event_target: project, author_id: 2)).to be_truthy
|
expect(track_event(event_action: :pushed, event_target: project, author_id: 2)).to be_truthy
|
||||||
expect(track_action(event_action: :pushed, event_target: project, author_id: 3)).to be_truthy
|
expect(track_event(event_action: :pushed, event_target: project, author_id: 3)).to be_truthy
|
||||||
expect(track_action(event_action: :pushed, event_target: project, author_id: 4, time: time - 3.days)).to be_truthy
|
expect(track_event(event_action: :pushed, event_target: project, author_id: 4, time: time - 3.days)).to be_truthy
|
||||||
expect(track_action(event_action: :created, event_target: project, author_id: 5, time: time - 3.days)).to be_truthy
|
expect(track_event(event_action: :created, event_target: project, author_id: 5, time: time - 3.days)).to be_truthy
|
||||||
|
|
||||||
expect(track_action(event_action: :destroyed, event_target: design, author_id: 3)).to be_truthy
|
expect(track_event(event_action: :destroyed, event_target: design, author_id: 3)).to be_truthy
|
||||||
expect(track_action(event_action: :created, event_target: design, author_id: 4)).to be_truthy
|
expect(track_event(event_action: :created, event_target: design, author_id: 4)).to be_truthy
|
||||||
expect(track_action(event_action: :updated, event_target: design, author_id: 5)).to be_truthy
|
expect(track_event(event_action: :updated, event_target: design, author_id: 5)).to be_truthy
|
||||||
expect(track_action(event_action: :pushed, event_target: design, author_id: 6)).to be_truthy
|
expect(track_event(event_action: :pushed, event_target: design, author_id: 6)).to be_truthy
|
||||||
|
|
||||||
expect(track_action(event_action: :destroyed, event_target: wiki, author_id: 5)).to be_truthy
|
expect(track_event(event_action: :destroyed, event_target: wiki, author_id: 5)).to be_truthy
|
||||||
expect(track_action(event_action: :created, event_target: wiki, author_id: 3)).to be_truthy
|
expect(track_event(event_action: :created, event_target: wiki, author_id: 3)).to be_truthy
|
||||||
expect(track_action(event_action: :updated, event_target: wiki, author_id: 4)).to be_truthy
|
expect(track_event(event_action: :updated, event_target: wiki, author_id: 4)).to be_truthy
|
||||||
expect(track_action(event_action: :pushed, event_target: wiki, author_id: 6)).to be_truthy
|
expect(track_event(event_action: :pushed, event_target: wiki, author_id: 6)).to be_truthy
|
||||||
|
|
||||||
expect(count_unique_events(event_action: described_class::PUSH_ACTION, date_from: time, date_to: Date.today)).to eq(3)
|
expect(count_unique(event_action: described_class::PUSH_ACTION, date_from: time, date_to: Date.today)).to eq(3)
|
||||||
expect(count_unique_events(event_action: described_class::PUSH_ACTION, date_from: time - 5.days, date_to: Date.tomorrow)).to eq(4)
|
expect(count_unique(event_action: described_class::PUSH_ACTION, date_from: time - 5.days, date_to: Date.tomorrow)).to eq(4)
|
||||||
expect(count_unique_events(event_action: described_class::DESIGN_ACTION, date_from: time - 5.days, date_to: Date.today)).to eq(3)
|
expect(count_unique(event_action: described_class::DESIGN_ACTION, date_from: time - 5.days, date_to: Date.today)).to eq(3)
|
||||||
expect(count_unique_events(event_action: described_class::WIKI_ACTION, date_from: time - 5.days, date_to: Date.today)).to eq(3)
|
expect(count_unique(event_action: described_class::WIKI_ACTION, date_from: time - 5.days, date_to: Date.today)).to eq(3)
|
||||||
expect(count_unique_events(event_action: described_class::PUSH_ACTION, date_from: time - 5.days, date_to: time - 2.days)).to eq(1)
|
expect(count_unique(event_action: described_class::PUSH_ACTION, date_from: time - 5.days, date_to: time - 2.days)).to eq(1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -73,8 +73,8 @@ RSpec.describe Gitlab::UsageDataCounters::TrackUniqueActions, :clean_gitlab_redi
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns the expected values' do
|
it 'returns the expected values' do
|
||||||
expect(track_action(event_action: action, event_target: target, author_id: 2)).to be_nil
|
expect(track_event(event_action: action, event_target: target, author_id: 2)).to be_nil
|
||||||
expect(count_unique_events(event_action: described_class::PUSH_ACTION, date_from: time, date_to: Date.today)).to eq(0)
|
expect(count_unique(event_action: described_class::PUSH_ACTION, date_from: time, date_to: Date.today)).to eq(0)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -924,14 +924,14 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
|
||||||
wiki = Event::TARGET_TYPES[:wiki]
|
wiki = Event::TARGET_TYPES[:wiki]
|
||||||
design = Event::TARGET_TYPES[:design]
|
design = Event::TARGET_TYPES[:design]
|
||||||
|
|
||||||
counter.track_action(event_action: :pushed, event_target: project, author_id: 1)
|
counter.track_event(event_action: :pushed, event_target: project, author_id: 1)
|
||||||
counter.track_action(event_action: :pushed, event_target: project, author_id: 1)
|
counter.track_event(event_action: :pushed, event_target: project, author_id: 1)
|
||||||
counter.track_action(event_action: :pushed, event_target: project, author_id: 2)
|
counter.track_event(event_action: :pushed, event_target: project, author_id: 2)
|
||||||
counter.track_action(event_action: :pushed, event_target: project, author_id: 3)
|
counter.track_event(event_action: :pushed, event_target: project, author_id: 3)
|
||||||
counter.track_action(event_action: :pushed, event_target: project, author_id: 4, time: time - 3.days)
|
counter.track_event(event_action: :pushed, event_target: project, author_id: 4, time: time - 3.days)
|
||||||
counter.track_action(event_action: :created, event_target: project, author_id: 5, time: time - 3.days)
|
counter.track_event(event_action: :created, event_target: project, author_id: 5, time: time - 3.days)
|
||||||
counter.track_action(event_action: :created, event_target: wiki, author_id: 3)
|
counter.track_event(event_action: :created, event_target: wiki, author_id: 3)
|
||||||
counter.track_action(event_action: :created, event_target: design, author_id: 3)
|
counter.track_event(event_action: :created, event_target: design, author_id: 3)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns the distinct count of user actions within the specified time period' do
|
it 'returns the distinct count of user actions within the specified time period' do
|
||||||
|
|
|
@ -1541,4 +1541,48 @@ RSpec.describe Group do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#default_owner' do
|
||||||
|
let(:group) { build(:group) }
|
||||||
|
|
||||||
|
context 'the group has owners' do
|
||||||
|
before do
|
||||||
|
group.add_owner(create(:user))
|
||||||
|
group.add_owner(create(:user))
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'is the first owner' do
|
||||||
|
expect(group.default_owner)
|
||||||
|
.to eq(group.owners.first)
|
||||||
|
.and be_a(User)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'the group has a parent' do
|
||||||
|
let(:parent) { build(:group) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
group.parent = parent
|
||||||
|
parent.add_owner(create(:user))
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'is the first owner of the parent' do
|
||||||
|
expect(group.default_owner)
|
||||||
|
.to eq(parent.default_owner)
|
||||||
|
.and be_a(User)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'we fallback to group.owner' do
|
||||||
|
before do
|
||||||
|
group.owner = build(:user)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'is the group.owner' do
|
||||||
|
expect(group.default_owner)
|
||||||
|
.to eq(group.owner)
|
||||||
|
.and be_a(User)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1090,6 +1090,30 @@ RSpec.describe Project do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#default_owner' do
|
||||||
|
let_it_be(:owner) { create(:user) }
|
||||||
|
let_it_be(:namespace) { create(:namespace, owner: owner) }
|
||||||
|
|
||||||
|
context 'the project does not have a group' do
|
||||||
|
let(:project) { build(:project, namespace: namespace) }
|
||||||
|
|
||||||
|
it 'is the namespace owner' do
|
||||||
|
expect(project.default_owner).to eq(owner)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'the project is in a group' do
|
||||||
|
let(:group) { build(:group) }
|
||||||
|
let(:project) { build(:project, group: group, namespace: namespace) }
|
||||||
|
|
||||||
|
it 'is the group owner' do
|
||||||
|
allow(group).to receive(:default_owner).and_return(Object.new)
|
||||||
|
|
||||||
|
expect(project.default_owner).to eq(group.default_owner)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe '#external_wiki' do
|
describe '#external_wiki' do
|
||||||
let(:project) { create(:project) }
|
let(:project) { create(:project) }
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "spec_helper"
|
||||||
|
|
||||||
|
RSpec.describe Wiki do
|
||||||
|
describe '.new' do
|
||||||
|
it 'verifies that the user is a User' do
|
||||||
|
expect { described_class.new(double, 1) }.to raise_error(ArgumentError)
|
||||||
|
expect { described_class.new(double, build(:group)) }.to raise_error(ArgumentError)
|
||||||
|
expect { described_class.new(double, build(:user)) }.not_to raise_error
|
||||||
|
expect { described_class.new(double, nil) }.not_to raise_error
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -735,11 +735,6 @@ RSpec.describe API::Ci::Pipelines do
|
||||||
|
|
||||||
let(:pipeline) { create(:ci_pipeline, project: project) }
|
let(:pipeline) { create(:ci_pipeline, project: project) }
|
||||||
|
|
||||||
context 'when feature is enabled' do
|
|
||||||
before do
|
|
||||||
stub_feature_flags(junit_pipeline_view: true)
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when pipeline does not have a test report' do
|
context 'when pipeline does not have a test report' do
|
||||||
it 'returns an empty test report' do
|
it 'returns an empty test report' do
|
||||||
subject
|
subject
|
||||||
|
@ -762,8 +757,7 @@ RSpec.describe API::Ci::Pipelines do
|
||||||
|
|
||||||
context 'when pipeline has corrupt test reports' do
|
context 'when pipeline has corrupt test reports' do
|
||||||
before do
|
before do
|
||||||
job = create(:ci_build, pipeline: pipeline)
|
create(:ci_build, :broken_test_reports, name: 'rspec', pipeline: pipeline)
|
||||||
create(:ci_job_artifact, :junit_with_corrupted_data, job: job, project: project)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns a suite_error' do
|
it 'returns a suite_error' do
|
||||||
|
@ -775,19 +769,6 @@ RSpec.describe API::Ci::Pipelines do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when feature is disabled' do
|
|
||||||
before do
|
|
||||||
stub_feature_flags(junit_pipeline_view: false)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'renders empty response' do
|
|
||||||
subject
|
|
||||||
|
|
||||||
expect(response).to have_gitlab_http_status(:not_found)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'unauthorized user' do
|
context 'unauthorized user' do
|
||||||
it 'does not return project pipelines' do
|
it 'does not return project pipelines' do
|
||||||
get api("/projects/#{project.id}/pipelines/#{pipeline.id}/test_report", non_member)
|
get api("/projects/#{project.id}/pipelines/#{pipeline.id}/test_report", non_member)
|
||||||
|
|
|
@ -147,8 +147,7 @@ RSpec.describe AlertManagement::Alerts::UpdateService do
|
||||||
end
|
end
|
||||||
|
|
||||||
it_behaves_like 'does not add a system note'
|
it_behaves_like 'does not add a system note'
|
||||||
# TODO: We should not add another todo in this scenario
|
it_behaves_like 'does not add a todo'
|
||||||
it_behaves_like 'adds a todo'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with multiple users included' do
|
context 'with multiple users included' do
|
||||||
|
|
|
@ -207,7 +207,7 @@ RSpec.describe EventCreateService do
|
||||||
tracking_params = { event_action: counter_class::WIKI_ACTION, date_from: Date.yesterday, date_to: Date.today }
|
tracking_params = { event_action: counter_class::WIKI_ACTION, date_from: Date.yesterday, date_to: Date.today }
|
||||||
|
|
||||||
expect { create_event }
|
expect { create_event }
|
||||||
.to change { counter_class.count_unique_events(tracking_params) }
|
.to change { counter_class.count_unique(tracking_params) }
|
||||||
.by(1)
|
.by(1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -249,7 +249,7 @@ RSpec.describe EventCreateService do
|
||||||
tracking_params = { event_action: counter_class::PUSH_ACTION, date_from: Date.yesterday, date_to: Date.today }
|
tracking_params = { event_action: counter_class::PUSH_ACTION, date_from: Date.yesterday, date_to: Date.today }
|
||||||
|
|
||||||
expect { subject }
|
expect { subject }
|
||||||
.to change { counter_class.count_unique_events(tracking_params) }
|
.to change { counter_class.count_unique(tracking_params) }
|
||||||
.from(0).to(1)
|
.from(0).to(1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -273,7 +273,7 @@ RSpec.describe EventCreateService do
|
||||||
tracking_params = { event_action: counter_class::PUSH_ACTION, date_from: Date.yesterday, date_to: Date.today }
|
tracking_params = { event_action: counter_class::PUSH_ACTION, date_from: Date.yesterday, date_to: Date.today }
|
||||||
|
|
||||||
expect { subject }
|
expect { subject }
|
||||||
.to change { counter_class.count_unique_events(tracking_params) }
|
.to change { counter_class.count_unique(tracking_params) }
|
||||||
.from(0).to(1)
|
.from(0).to(1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -328,7 +328,7 @@ RSpec.describe EventCreateService do
|
||||||
tracking_params = { event_action: counter_class::DESIGN_ACTION, date_from: Date.yesterday, date_to: Date.today }
|
tracking_params = { event_action: counter_class::DESIGN_ACTION, date_from: Date.yesterday, date_to: Date.today }
|
||||||
|
|
||||||
expect { result }
|
expect { result }
|
||||||
.to change { counter_class.count_unique_events(tracking_params) }
|
.to change { counter_class.count_unique(tracking_params) }
|
||||||
.from(0).to(1)
|
.from(0).to(1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -356,7 +356,7 @@ RSpec.describe EventCreateService do
|
||||||
tracking_params = { event_action: counter_class::DESIGN_ACTION, date_from: Date.yesterday, date_to: Date.today }
|
tracking_params = { event_action: counter_class::DESIGN_ACTION, date_from: Date.yesterday, date_to: Date.today }
|
||||||
|
|
||||||
expect { result }
|
expect { result }
|
||||||
.to change { counter_class.count_unique_events(tracking_params) }
|
.to change { counter_class.count_unique(tracking_params) }
|
||||||
.from(0).to(1)
|
.from(0).to(1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -34,6 +34,16 @@ RSpec.describe ResourceAccessTokens::CreateService do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
shared_examples 'fails on gitlab.com' do
|
||||||
|
before do
|
||||||
|
allow(Gitlab).to receive(:com?) { true }
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns nil' do
|
||||||
|
expect(subject).to be nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
shared_examples 'allows creation of bot with valid params' do
|
shared_examples 'allows creation of bot with valid params' do
|
||||||
it { expect { subject }.to change { User.count }.by(1) }
|
it { expect { subject }.to change { User.count }.by(1) }
|
||||||
|
|
||||||
|
@ -171,6 +181,7 @@ RSpec.describe ResourceAccessTokens::CreateService do
|
||||||
|
|
||||||
it_behaves_like 'fails when user does not have the permission to create a Resource Bot'
|
it_behaves_like 'fails when user does not have the permission to create a Resource Bot'
|
||||||
it_behaves_like 'fails when flag is disabled'
|
it_behaves_like 'fails when flag is disabled'
|
||||||
|
it_behaves_like 'fails on gitlab.com'
|
||||||
|
|
||||||
context 'user with valid permission' do
|
context 'user with valid permission' do
|
||||||
before_all do
|
before_all do
|
||||||
|
|
|
@ -59,6 +59,10 @@ RSpec.describe TodoService do
|
||||||
|
|
||||||
should_not_create_todo(user: guest, target: addressed_target_assigned, action: Todo::DIRECTLY_ADDRESSED)
|
should_not_create_todo(user: guest, target: addressed_target_assigned, action: Todo::DIRECTLY_ADDRESSED)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'does not create a todo if already assigned' do
|
||||||
|
should_not_create_any_todo { service.send(described_method, target_assigned, author, [john_doe]) }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'Issues' do
|
describe 'Issues' do
|
||||||
|
@ -573,10 +577,10 @@ RSpec.describe TodoService do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#reassigned_issuable' do
|
describe '#reassigned_assignable' do
|
||||||
let(:described_method) { :reassigned_issuable }
|
let(:described_method) { :reassigned_assignable }
|
||||||
|
|
||||||
context 'issuable is a merge request' do
|
context 'assignable is a merge request' do
|
||||||
it_behaves_like 'reassigned target' do
|
it_behaves_like 'reassigned target' do
|
||||||
let(:target_assigned) { create(:merge_request, source_project: project, author: author, assignees: [john_doe], description: "- [ ] Task 1\n- [ ] Task 2 #{mentions}") }
|
let(:target_assigned) { create(:merge_request, source_project: project, author: author, assignees: [john_doe], description: "- [ ] Task 1\n- [ ] Task 2 #{mentions}") }
|
||||||
let(:addressed_target_assigned) { create(:merge_request, source_project: project, author: author, assignees: [john_doe], description: "#{directly_addressed}\n- [ ] Task 1\n- [ ] Task 2") }
|
let(:addressed_target_assigned) { create(:merge_request, source_project: project, author: author, assignees: [john_doe], description: "#{directly_addressed}\n- [ ] Task 1\n- [ ] Task 2") }
|
||||||
|
@ -584,13 +588,21 @@ RSpec.describe TodoService do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'issuable is an issue' do
|
context 'assignable is an issue' do
|
||||||
it_behaves_like 'reassigned target' do
|
it_behaves_like 'reassigned target' do
|
||||||
let(:target_assigned) { create(:issue, project: project, author: author, assignees: [john_doe], description: "- [ ] Task 1\n- [ ] Task 2 #{mentions}") }
|
let(:target_assigned) { create(:issue, project: project, author: author, assignees: [john_doe], description: "- [ ] Task 1\n- [ ] Task 2 #{mentions}") }
|
||||||
let(:addressed_target_assigned) { create(:issue, project: project, author: author, assignees: [john_doe], description: "#{directly_addressed}\n- [ ] Task 1\n- [ ] Task 2") }
|
let(:addressed_target_assigned) { create(:issue, project: project, author: author, assignees: [john_doe], description: "#{directly_addressed}\n- [ ] Task 1\n- [ ] Task 2") }
|
||||||
let(:target_unassigned) { create(:issue, project: project, author: author, assignees: []) }
|
let(:target_unassigned) { create(:issue, project: project, author: author, assignees: []) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'assignable is an alert' do
|
||||||
|
it_behaves_like 'reassigned target' do
|
||||||
|
let(:target_assigned) { create(:alert_management_alert, project: project, assignees: [john_doe]) }
|
||||||
|
let(:addressed_target_assigned) { create(:alert_management_alert, project: project, assignees: [john_doe]) }
|
||||||
|
let(:target_unassigned) { create(:alert_management_alert, project: project, assignees: []) }
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'Merge Requests' do
|
describe 'Merge Requests' do
|
||||||
|
@ -778,16 +790,6 @@ RSpec.describe TodoService do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#assign_alert' do
|
|
||||||
let(:described_method) { :assign_alert }
|
|
||||||
|
|
||||||
it_behaves_like 'reassigned target' do
|
|
||||||
let(:target_assigned) { create(:alert_management_alert, project: project, assignees: [john_doe]) }
|
|
||||||
let(:addressed_target_assigned) { create(:alert_management_alert, project: project, assignees: [john_doe]) }
|
|
||||||
let(:target_unassigned) { create(:alert_management_alert, project: project, assignees: []) }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#merge_request_build_failed' do
|
describe '#merge_request_build_failed' do
|
||||||
let(:merge_participants) { [mr_unassigned.author, admin] }
|
let(:merge_participants) { [mr_unassigned.author, admin] }
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue