Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
5431dbfffc
commit
2578890510
|
@ -198,7 +198,7 @@ export default {
|
|||
<gl-badge
|
||||
v-if="isInternalNote"
|
||||
v-gl-tooltip:tooltipcontainer.bottom
|
||||
data-testid="internalNoteIndicator"
|
||||
data-testid="internal-note-indicator"
|
||||
variant="warning"
|
||||
size="sm"
|
||||
class="gl-ml-2"
|
||||
|
|
|
@ -60,7 +60,6 @@ module IssuableCollectionsAction
|
|||
|
||||
def finder_options
|
||||
issue_types = Issue::TYPES_FOR_LIST
|
||||
issue_types = issue_types.excluding('task') unless Feature.enabled?(:work_items)
|
||||
|
||||
super.merge(
|
||||
non_archived: true,
|
||||
|
|
|
@ -405,7 +405,6 @@ class Projects::IssuesController < Projects::ApplicationController
|
|||
options = super
|
||||
|
||||
options[:issue_types] = Issue::TYPES_FOR_LIST
|
||||
options[:issue_types] = options[:issue_types].excluding('task') unless project.work_items_feature_flag_enabled?
|
||||
|
||||
if service_desk?
|
||||
options.reject! { |key| key == 'author_username' || key == 'author_id' }
|
||||
|
@ -432,7 +431,6 @@ class Projects::IssuesController < Projects::ApplicationController
|
|||
def create_vulnerability_issue_feedback(issue); end
|
||||
|
||||
def redirect_if_task
|
||||
return render_404 if issue.task? && !project.work_items_feature_flag_enabled?
|
||||
return unless issue.task?
|
||||
|
||||
if Feature.enabled?(:use_iid_in_work_items_path, project.group)
|
||||
|
|
|
@ -9,8 +9,4 @@ class Projects::WorkItemsController < Projects::ApplicationController
|
|||
|
||||
feature_category :team_planning
|
||||
urgency :low
|
||||
|
||||
def index
|
||||
render_404 unless project&.work_items_feature_flag_enabled?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,7 +9,7 @@ module Mutations
|
|||
include FindsProject
|
||||
include Mutations::WorkItems::Widgetable
|
||||
|
||||
description "Creates a work item. Available only when feature flag `work_items` is enabled."
|
||||
description "Creates a work item."
|
||||
|
||||
authorize :create_work_item
|
||||
|
||||
|
@ -42,10 +42,6 @@ module Mutations
|
|||
def resolve(project_path:, **attributes)
|
||||
project = authorized_find!(project_path)
|
||||
|
||||
unless project.work_items_feature_flag_enabled?
|
||||
return { errors: ['`work_items` feature flag disabled for this project'] }
|
||||
end
|
||||
|
||||
spam_params = ::Spam::SpamParams.new_from_request(request: context[:request])
|
||||
params = global_id_compatibility_params(attributes).merge(author_id: current_user.id)
|
||||
type = ::WorkItems::Type.find(attributes[:work_item_type_id])
|
||||
|
|
|
@ -7,8 +7,7 @@ module Mutations
|
|||
|
||||
include Mutations::SpamProtection
|
||||
|
||||
description "Creates a work item from a task in another work item's description." \
|
||||
" Available only when feature flag `work_items` is enabled."
|
||||
description "Creates a work item from a task in another work item's description."
|
||||
|
||||
authorize :update_work_item
|
||||
|
||||
|
@ -31,10 +30,6 @@ module Mutations
|
|||
def resolve(id:, work_item_data:)
|
||||
work_item = authorized_find!(id: id)
|
||||
|
||||
unless work_item.project.work_items_feature_flag_enabled?
|
||||
return { errors: ['`work_items` feature flag disabled for this project'] }
|
||||
end
|
||||
|
||||
spam_params = ::Spam::SpamParams.new_from_request(request: context[:request])
|
||||
|
||||
result = ::WorkItems::CreateFromTaskService.new(
|
||||
|
|
|
@ -4,8 +4,7 @@ module Mutations
|
|||
module WorkItems
|
||||
class Delete < BaseMutation
|
||||
graphql_name 'WorkItemDelete'
|
||||
description "Deletes a work item." \
|
||||
" Available only when feature flag `work_items` is enabled."
|
||||
description "Deletes a work item."
|
||||
|
||||
authorize :delete_work_item
|
||||
|
||||
|
@ -20,10 +19,6 @@ module Mutations
|
|||
def resolve(id:)
|
||||
work_item = authorized_find!(id: id)
|
||||
|
||||
unless work_item.project.work_items_feature_flag_enabled?
|
||||
return { errors: ['`work_items` feature flag disabled for this project'] }
|
||||
end
|
||||
|
||||
result = ::WorkItems::DeleteService.new(
|
||||
project: work_item.project,
|
||||
current_user: current_user
|
||||
|
|
|
@ -5,8 +5,7 @@ module Mutations
|
|||
class DeleteTask < BaseMutation
|
||||
graphql_name 'WorkItemDeleteTask'
|
||||
|
||||
description "Deletes a task in a work item's description." \
|
||||
' Available only when feature flag `work_items` is enabled.'
|
||||
description "Deletes a task in a work item's description."
|
||||
|
||||
authorize :update_work_item
|
||||
|
||||
|
@ -29,10 +28,6 @@ module Mutations
|
|||
work_item = authorized_find!(id: id)
|
||||
task_data[:task] = authorized_find_task!(task_data[:id])
|
||||
|
||||
unless work_item.project.work_items_feature_flag_enabled?
|
||||
return { errors: ['`work_items` feature flag disabled for this project'] }
|
||||
end
|
||||
|
||||
result = ::WorkItems::DeleteTaskService.new(
|
||||
work_item: work_item,
|
||||
current_user: current_user,
|
||||
|
|
|
@ -4,8 +4,7 @@ module Mutations
|
|||
module WorkItems
|
||||
class Update < BaseMutation
|
||||
graphql_name 'WorkItemUpdate'
|
||||
description "Updates a work item by Global ID." \
|
||||
" Available only when feature flag `work_items` is enabled."
|
||||
description "Updates a work item by Global ID."
|
||||
|
||||
include Mutations::SpamProtection
|
||||
include Mutations::WorkItems::UpdateArguments
|
||||
|
@ -20,10 +19,6 @@ module Mutations
|
|||
def resolve(id:, **attributes)
|
||||
work_item = authorized_find!(id: id)
|
||||
|
||||
unless work_item.project.work_items_feature_flag_enabled?
|
||||
return { errors: ['`work_items` feature flag disabled for this project'] }
|
||||
end
|
||||
|
||||
spam_params = ::Spam::SpamParams.new_from_request(request: context[:request])
|
||||
widget_params = extract_widget_params!(work_item.work_item_type, attributes)
|
||||
|
||||
|
|
|
@ -4,8 +4,7 @@ module Mutations
|
|||
module WorkItems
|
||||
class UpdateTask < BaseMutation
|
||||
graphql_name 'WorkItemUpdateTask'
|
||||
description "Updates a work item's task by Global ID." \
|
||||
" Available only when feature flag `work_items` is enabled."
|
||||
description "Updates a work item's task by Global ID."
|
||||
|
||||
include Mutations::SpamProtection
|
||||
|
||||
|
@ -30,10 +29,6 @@ module Mutations
|
|||
work_item = authorized_find!(id: id)
|
||||
task = authorized_find_task!(task_data_hash[:id])
|
||||
|
||||
unless work_item.project.work_items_feature_flag_enabled?
|
||||
return { errors: ['`work_items` feature flag disabled for this project'] }
|
||||
end
|
||||
|
||||
spam_params = ::Spam::SpamParams.new_from_request(request: context[:request])
|
||||
|
||||
::WorkItems::UpdateService.new(
|
||||
|
|
|
@ -11,10 +11,7 @@ module Resolvers
|
|||
argument :id, ::Types::GlobalIDType[::WorkItem], required: true, description: 'Global ID of the work item.'
|
||||
|
||||
def resolve(id:)
|
||||
work_item = authorized_find!(id: id)
|
||||
return unless work_item.project.work_items_feature_flag_enabled?
|
||||
|
||||
work_item
|
||||
authorized_find!(id: id)
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -11,8 +11,6 @@ module Resolvers
|
|||
' Argument is experimental and can be removed in the future without notice.'
|
||||
|
||||
def resolve(taskable: nil)
|
||||
return unless feature_flag_enabled_for_parent?(object)
|
||||
|
||||
# This will require a finder in the future when groups/projects get their work item types
|
||||
# All groups/projects use the default types for now
|
||||
base_scope = ::WorkItems::Type.default
|
||||
|
@ -20,14 +18,6 @@ module Resolvers
|
|||
|
||||
base_scope.order_by_name_asc
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def feature_flag_enabled_for_parent?(parent)
|
||||
return false unless parent.is_a?(::Project) || parent.is_a?(::Group)
|
||||
|
||||
parent.work_items_feature_flag_enabled?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -26,7 +26,7 @@ module Resolvers
|
|||
required: false
|
||||
|
||||
def resolve_with_lookahead(**args)
|
||||
return WorkItem.none if resource_parent.nil? || !resource_parent.work_items_feature_flag_enabled?
|
||||
return WorkItem.none if resource_parent.nil?
|
||||
|
||||
finder = ::WorkItems::WorkItemsFinder.new(current_user, prepare_finder_params(args))
|
||||
|
||||
|
|
|
@ -231,9 +231,7 @@ module Types
|
|||
|
||||
field :work_item_types, Types::WorkItems::TypeType.connection_type,
|
||||
resolver: Resolvers::WorkItems::TypesResolver,
|
||||
description: 'Work item types available to the group.' \
|
||||
' Returns `null` if `work_items` feature flag is disabled.' \
|
||||
' This flag is disabled by default, because the feature is experimental and is subject to change without notice.'
|
||||
description: 'Work item types available to the group.'
|
||||
|
||||
def label(title:)
|
||||
BatchLoader::GraphQL.for(title).batch(key: group) do |titles, loader, args|
|
||||
|
|
|
@ -10,7 +10,7 @@ module Types
|
|||
end
|
||||
|
||||
value 'TASK', value: 'task',
|
||||
description: 'Task issue type. Available only when feature flag `work_items` is enabled.',
|
||||
description: 'Task issue type.',
|
||||
alpha: { milestone: '15.2' }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -513,9 +513,7 @@ module Types
|
|||
|
||||
field :work_item_types, Types::WorkItems::TypeType.connection_type,
|
||||
resolver: Resolvers::WorkItems::TypesResolver,
|
||||
description: 'Work item types available to the project.' \
|
||||
' Returns `null` if `work_items` feature flag is disabled.' \
|
||||
' This flag is disabled by default, because the feature is experimental and is subject to change without notice.'
|
||||
description: 'Work item types available to the project.'
|
||||
|
||||
field :timelog_categories, Types::TimeTracking::TimelogCategoryType.connection_type,
|
||||
null: true,
|
||||
|
|
|
@ -92,7 +92,7 @@ module Types
|
|||
null: true,
|
||||
resolver: Resolvers::WorkItemResolver,
|
||||
alpha: { milestone: '15.1' },
|
||||
description: 'Find a work item. Returns `null` if `work_items` feature flag is disabled.'
|
||||
description: 'Find a work item.'
|
||||
|
||||
field :merge_request, Types::MergeRequestType,
|
||||
null: true,
|
||||
|
|
|
@ -96,7 +96,7 @@ module Routing
|
|||
private
|
||||
|
||||
def use_work_items_path?(issue)
|
||||
issue.issue_type == 'task' && issue.project.work_items_feature_flag_enabled?
|
||||
issue.issue_type == 'task'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,6 +6,16 @@ class Appearance < ApplicationRecord
|
|||
include ObjectStorage::BackgroundMove
|
||||
include WithUploads
|
||||
|
||||
attribute :title, default: ''
|
||||
attribute :description, default: ''
|
||||
attribute :new_project_guidelines, default: ''
|
||||
attribute :profile_image_guidelines, default: ''
|
||||
attribute :header_message, default: ''
|
||||
attribute :footer_message, default: ''
|
||||
attribute :message_background_color, default: '#E75E40'
|
||||
attribute :message_font_color, default: '#FFFFFF'
|
||||
attribute :email_header_and_footer_enabled, default: false
|
||||
|
||||
cache_markdown_field :description
|
||||
cache_markdown_field :new_project_guidelines
|
||||
cache_markdown_field :profile_image_guidelines
|
||||
|
@ -20,16 +30,6 @@ class Appearance < ApplicationRecord
|
|||
|
||||
validate :single_appearance_row, on: :create
|
||||
|
||||
default_value_for :title, ''
|
||||
default_value_for :description, ''
|
||||
default_value_for :new_project_guidelines, ''
|
||||
default_value_for :profile_image_guidelines, ''
|
||||
default_value_for :header_message, ''
|
||||
default_value_for :footer_message, ''
|
||||
default_value_for :message_background_color, '#E75E40'
|
||||
default_value_for :message_font_color, '#FFFFFF'
|
||||
default_value_for :email_header_and_footer_enabled, false
|
||||
|
||||
mount_uploader :logo, AttachmentUploader
|
||||
mount_uploader :header_logo, AttachmentUploader
|
||||
mount_uploader :favicon, FaviconUploader
|
||||
|
|
|
@ -75,9 +75,9 @@ class ApplicationSetting < ApplicationRecord
|
|||
cache_markdown_field :shared_runners_text, pipeline: :plain_markdown
|
||||
cache_markdown_field :after_sign_up_text
|
||||
|
||||
default_value_for :id, 1
|
||||
default_value_for :repository_storages_weighted, {}
|
||||
default_value_for :kroki_formats, {}
|
||||
attribute :id, default: 1
|
||||
attribute :repository_storages_weighted, default: -> { {} }
|
||||
attribute :kroki_formats, default: -> { {} }
|
||||
|
||||
chronic_duration_attr_writer :archive_builds_in_human_readable, :archive_builds_in_seconds
|
||||
|
||||
|
|
|
@ -23,8 +23,8 @@ class BroadcastMessage < ApplicationRecord
|
|||
validates :color, allow_blank: true, color: true
|
||||
validates :font, allow_blank: true, color: true
|
||||
|
||||
default_value_for :color, '#E75E40'
|
||||
default_value_for :font, '#FFFFFF'
|
||||
attribute :color, default: '#E75E40'
|
||||
attribute :font, default: '#FFFFFF'
|
||||
|
||||
CACHE_KEY = 'broadcast_message_current_json'
|
||||
BANNER_CACHE_KEY = 'broadcast_message_current_banner_json'
|
||||
|
|
|
@ -4,8 +4,8 @@ module TtlExpirable
|
|||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
attribute :read_at, default: -> { Time.zone.now }
|
||||
validates :status, presence: true
|
||||
default_value_for :read_at, Time.zone.now
|
||||
|
||||
enum status: { default: 0, pending_destruction: 1, processing: 2, error: 3 }
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
class DependencyProxy::GroupSetting < ApplicationRecord
|
||||
belongs_to :group
|
||||
|
||||
validates :group, presence: true
|
||||
attribute :enabled, default: true
|
||||
|
||||
default_value_for :enabled, true
|
||||
validates :group, presence: true
|
||||
end
|
||||
|
|
|
@ -3006,7 +3006,7 @@ class Project < ApplicationRecord
|
|||
end
|
||||
|
||||
def work_items_create_from_markdown_feature_flag_enabled?
|
||||
work_items_feature_flag_enabled? && (group&.work_items_create_from_markdown_feature_flag_enabled? || Feature.enabled?(:work_items_create_from_markdown))
|
||||
group&.work_items_create_from_markdown_feature_flag_enabled? || Feature.enabled?(:work_items_create_from_markdown)
|
||||
end
|
||||
|
||||
def enqueue_record_project_target_platforms
|
||||
|
|
|
@ -4,14 +4,10 @@ module WorkItems
|
|||
module Widgets
|
||||
class Hierarchy < Base
|
||||
def parent
|
||||
return unless work_item.project.work_items_feature_flag_enabled?
|
||||
|
||||
work_item.work_item_parent
|
||||
end
|
||||
|
||||
def children
|
||||
return WorkItem.none unless work_item.project.work_items_feature_flag_enabled?
|
||||
|
||||
work_item.work_item_children
|
||||
end
|
||||
end
|
||||
|
|
|
@ -195,8 +195,6 @@ class ProjectPolicy < BasePolicy
|
|||
with_scope :subject
|
||||
condition(:packages_disabled) { !@subject.packages_enabled }
|
||||
|
||||
condition(:work_items_enabled, scope: :subject) { project&.work_items_feature_flag_enabled? }
|
||||
|
||||
features = %w[
|
||||
merge_requests
|
||||
issues
|
||||
|
@ -304,7 +302,7 @@ class ProjectPolicy < BasePolicy
|
|||
|
||||
rule { can?(:create_issue) }.enable :create_work_item
|
||||
|
||||
rule { can?(:create_issue) & work_items_enabled }.enable :create_task
|
||||
rule { can?(:create_issue) }.enable :create_task
|
||||
|
||||
# These abilities are not allowed to admins that are not members of the project,
|
||||
# that's why they are defined separately.
|
||||
|
|
|
@ -10,7 +10,9 @@ value_type: number
|
|||
status: active
|
||||
time_frame: all
|
||||
data_source: database
|
||||
instrumentation_class: DistinctCountProjectsWithExpirationPolicyDisabledMetric
|
||||
instrumentation_class: DistinctCountProjectsWithExpirationPolicyMetric
|
||||
options:
|
||||
enabled: false
|
||||
distribution:
|
||||
- ee
|
||||
- ce
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
table_name: audit_events_streaming_event_type_filters
|
||||
classes:
|
||||
- AuditEvents::Streaming::EventTypeFilter
|
||||
feature_categories:
|
||||
- audit_events
|
||||
description: Represents a event type filter for audit event streaming
|
||||
introduced_by_url:
|
||||
milestone: '15.6'
|
|
@ -0,0 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class CreateAuditEventsStreamingEventTypeFilters < Gitlab::Database::Migration[2.0]
|
||||
UNIQ_INDEX_NAME = 'unique_streaming_event_type_filters_destination_id'
|
||||
|
||||
def change
|
||||
create_table :audit_events_streaming_event_type_filters do |t|
|
||||
t.timestamps_with_timezone null: false
|
||||
t.references :external_audit_event_destination,
|
||||
null: false,
|
||||
index: false,
|
||||
foreign_key: { to_table: 'audit_events_external_audit_event_destinations', on_delete: :cascade }
|
||||
t.text :audit_event_type, null: false, limit: 255
|
||||
|
||||
t.index [:external_audit_event_destination_id, :audit_event_type], unique: true, name: UNIQ_INDEX_NAME
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1 @@
|
|||
84b89419404d26f7d2783a3adf1fa7b7d89417d6533b393ae6e0de40a31e299a
|
|
@ -11858,6 +11858,24 @@ CREATE SEQUENCE audit_events_id_seq
|
|||
|
||||
ALTER SEQUENCE audit_events_id_seq OWNED BY audit_events.id;
|
||||
|
||||
CREATE TABLE audit_events_streaming_event_type_filters (
|
||||
id bigint NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
external_audit_event_destination_id bigint NOT NULL,
|
||||
audit_event_type text NOT NULL,
|
||||
CONSTRAINT check_d20c8e5a51 CHECK ((char_length(audit_event_type) <= 255))
|
||||
);
|
||||
|
||||
CREATE SEQUENCE audit_events_streaming_event_type_filters_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
ALTER SEQUENCE audit_events_streaming_event_type_filters_id_seq OWNED BY audit_events_streaming_event_type_filters.id;
|
||||
|
||||
CREATE TABLE audit_events_streaming_headers (
|
||||
id bigint NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
|
@ -23397,6 +23415,8 @@ ALTER TABLE ONLY audit_events ALTER COLUMN id SET DEFAULT nextval('audit_events_
|
|||
|
||||
ALTER TABLE ONLY audit_events_external_audit_event_destinations ALTER COLUMN id SET DEFAULT nextval('audit_events_external_audit_event_destinations_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY audit_events_streaming_event_type_filters ALTER COLUMN id SET DEFAULT nextval('audit_events_streaming_event_type_filters_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY audit_events_streaming_headers ALTER COLUMN id SET DEFAULT nextval('audit_events_streaming_headers_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY authentication_events ALTER COLUMN id SET DEFAULT nextval('authentication_events_id_seq'::regclass);
|
||||
|
@ -25066,6 +25086,9 @@ ALTER TABLE ONLY audit_events_external_audit_event_destinations
|
|||
ALTER TABLE ONLY audit_events
|
||||
ADD CONSTRAINT audit_events_pkey PRIMARY KEY (id, created_at);
|
||||
|
||||
ALTER TABLE ONLY audit_events_streaming_event_type_filters
|
||||
ADD CONSTRAINT audit_events_streaming_event_type_filters_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY audit_events_streaming_headers
|
||||
ADD CONSTRAINT audit_events_streaming_headers_pkey PRIMARY KEY (id);
|
||||
|
||||
|
@ -31162,6 +31185,8 @@ CREATE UNIQUE INDEX unique_merge_request_metrics_by_merge_request_id ON merge_re
|
|||
|
||||
CREATE UNIQUE INDEX unique_projects_on_name_namespace_id ON projects USING btree (name, namespace_id);
|
||||
|
||||
CREATE UNIQUE INDEX unique_streaming_event_type_filters_destination_id ON audit_events_streaming_event_type_filters USING btree (external_audit_event_destination_id, audit_event_type);
|
||||
|
||||
CREATE UNIQUE INDEX unique_vuln_merge_request_link_vuln_id_and_mr_id ON vulnerability_merge_request_links USING btree (vulnerability_id, merge_request_id);
|
||||
|
||||
CREATE INDEX user_follow_users_followee_id_idx ON user_follow_users USING btree (followee_id);
|
||||
|
@ -34949,6 +34974,9 @@ ALTER TABLE ONLY dast_site_tokens
|
|||
ALTER TABLE ONLY group_deploy_keys_groups
|
||||
ADD CONSTRAINT fk_rails_e87145115d FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY audit_events_streaming_event_type_filters
|
||||
ADD CONSTRAINT fk_rails_e8bd011129 FOREIGN KEY (external_audit_event_destination_id) REFERENCES audit_events_external_audit_event_destinations(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY description_versions
|
||||
ADD CONSTRAINT fk_rails_e8f4caf9c7 FOREIGN KEY (epic_id) REFERENCES epics(id) ON DELETE CASCADE;
|
||||
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
# Suggestion: gitlab.Admin
|
||||
#
|
||||
# Checks for "admin" and recommends using the full word instead. "Admin Area" is OK.
|
||||
#
|
||||
# For a list of all options, see https://vale.sh/docs/topics/styles/
|
||||
extends: substitution
|
||||
message: 'Verify this use of the word "admin". Can it be updated to "administration", "administrator", "administer", or "Admin Area"?'
|
||||
link: https://docs.gitlab.com/ee/development/documentation/styleguide/index.html
|
||||
level: suggestion
|
||||
ignorecase: false
|
||||
swap:
|
||||
'[Aa]dmin ?\w*': '(?:Admin( Area| Mode)?|[Aa]dminist(ration|rator|rators|er|rative|ering|ered))'
|
|
@ -595,7 +595,7 @@ Returns [`Vulnerability`](#vulnerability).
|
|||
|
||||
### `Query.workItem`
|
||||
|
||||
Find a work item. Returns `null` if `work_items` feature flag is disabled.
|
||||
Find a work item.
|
||||
|
||||
WARNING:
|
||||
**Introduced** in 15.1.
|
||||
|
@ -5777,7 +5777,7 @@ Input type: `VulnerabilityRevertToDetectedInput`
|
|||
|
||||
### `Mutation.workItemCreate`
|
||||
|
||||
Creates a work item. Available only when feature flag `work_items` is enabled.
|
||||
Creates a work item.
|
||||
|
||||
WARNING:
|
||||
**Introduced** in 15.1.
|
||||
|
@ -5808,7 +5808,7 @@ Input type: `WorkItemCreateInput`
|
|||
|
||||
### `Mutation.workItemCreateFromTask`
|
||||
|
||||
Creates a work item from a task in another work item's description. Available only when feature flag `work_items` is enabled.
|
||||
Creates a work item from a task in another work item's description.
|
||||
|
||||
WARNING:
|
||||
**Introduced** in 15.1.
|
||||
|
@ -5835,7 +5835,7 @@ Input type: `WorkItemCreateFromTaskInput`
|
|||
|
||||
### `Mutation.workItemDelete`
|
||||
|
||||
Deletes a work item. Available only when feature flag `work_items` is enabled.
|
||||
Deletes a work item.
|
||||
|
||||
WARNING:
|
||||
**Introduced** in 15.1.
|
||||
|
@ -5860,7 +5860,7 @@ Input type: `WorkItemDeleteInput`
|
|||
|
||||
### `Mutation.workItemDeleteTask`
|
||||
|
||||
Deletes a task in a work item's description. Available only when feature flag `work_items` is enabled.
|
||||
Deletes a task in a work item's description.
|
||||
|
||||
WARNING:
|
||||
**Introduced** in 15.1.
|
||||
|
@ -5887,7 +5887,7 @@ Input type: `WorkItemDeleteTaskInput`
|
|||
|
||||
### `Mutation.workItemUpdate`
|
||||
|
||||
Updates a work item by Global ID. Available only when feature flag `work_items` is enabled.
|
||||
Updates a work item by Global ID.
|
||||
|
||||
WARNING:
|
||||
**Introduced** in 15.1.
|
||||
|
@ -5924,7 +5924,7 @@ Input type: `WorkItemUpdateInput`
|
|||
|
||||
### `Mutation.workItemUpdateTask`
|
||||
|
||||
Updates a work item's task by Global ID. Available only when feature flag `work_items` is enabled.
|
||||
Updates a work item's task by Global ID.
|
||||
|
||||
WARNING:
|
||||
**Introduced** in 15.1.
|
||||
|
@ -13585,7 +13585,7 @@ Returns [`VulnerabilitySeveritiesCount`](#vulnerabilityseveritiescount).
|
|||
|
||||
##### `Group.workItemTypes`
|
||||
|
||||
Work item types available to the group. Returns `null` if `work_items` feature flag is disabled. This flag is disabled by default, because the feature is experimental and is subject to change without notice.
|
||||
Work item types available to the group.
|
||||
|
||||
Returns [`WorkItemTypeConnection`](#workitemtypeconnection).
|
||||
|
||||
|
@ -17521,7 +17521,7 @@ Returns [`VulnerabilitySeveritiesCount`](#vulnerabilityseveritiescount).
|
|||
|
||||
##### `Project.workItemTypes`
|
||||
|
||||
Work item types available to the project. Returns `null` if `work_items` feature flag is disabled. This flag is disabled by default, because the feature is experimental and is subject to change without notice.
|
||||
Work item types available to the project.
|
||||
|
||||
Returns [`WorkItemTypeConnection`](#workitemtypeconnection).
|
||||
|
||||
|
@ -21052,7 +21052,7 @@ Issue type.
|
|||
| <a id="issuetypeincident"></a>`INCIDENT` | Incident issue type. |
|
||||
| <a id="issuetypeissue"></a>`ISSUE` | Issue issue type. |
|
||||
| <a id="issuetyperequirement"></a>`REQUIREMENT` | Requirement issue type. |
|
||||
| <a id="issuetypetask"></a>`TASK` **{warning-solid}** | **Introduced** in 15.2. This feature is in Alpha. It can be changed or removed at any time. Task issue type. Available only when feature flag `work_items` is enabled. |
|
||||
| <a id="issuetypetask"></a>`TASK` **{warning-solid}** | **Introduced** in 15.2. This feature is in Alpha. It can be changed or removed at any time. Task issue type. |
|
||||
| <a id="issuetypetest_case"></a>`TEST_CASE` | Test Case issue type. |
|
||||
|
||||
### `IterationSearchableField`
|
||||
|
|
|
@ -120,24 +120,25 @@ To do so:
|
|||
|
||||
### Simulate a SaaS instance
|
||||
|
||||
If you're developing locally and need your instance to act like the SaaS version of the product,
|
||||
you can simulate SaaS by exporting an environment variable:
|
||||
If you're developing locally and need your instance to simulate the SaaS (GitLab.com)
|
||||
version of the product:
|
||||
|
||||
```shell
|
||||
export GITLAB_SIMULATE_SAAS=1
|
||||
```
|
||||
1. Export this environment variable:
|
||||
|
||||
There are many ways to pass an environment variable to your local GitLab instance.
|
||||
For example, you can create a `env.runit` file in the root of your GDK with the above snippet.
|
||||
```shell
|
||||
export GITLAB_SIMULATE_SAAS=1
|
||||
```
|
||||
|
||||
#### Enable plans per namespace
|
||||
There are many ways to pass an environment variable to your local GitLab instance.
|
||||
For example, you can create an `env.runit` file in the root of your GDK with the above snippet.
|
||||
|
||||
To enable plans per namespace turn on the `Allow use of licensed EE features` option from the settings page.
|
||||
This will make licensed EE features available to projects only if the project namespace's plan includes the feature
|
||||
or if the project is public. To enable it:
|
||||
1. Enable **Allow use of licensed EE features** to make licensed EE features available to projects
|
||||
only if the project namespace's plan includes the feature.
|
||||
|
||||
1. If you are developing locally, follow the steps in [Simulate a SaaS instance](#simulate-a-saas-instance) to make the option available.
|
||||
1. Visit Admin > Settings > General > "Account and limit" and enable "Allow use of licensed EE features".
|
||||
1. Visit **Admin > Settings > General**.
|
||||
1. Expand **Account and limit**.
|
||||
1. Select the **Allow use of licensed EE features** checkbox.
|
||||
1. Click **Save changes**.
|
||||
|
||||
### Run CI pipelines in a FOSS context
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ We have built a domain-specific language (DSL) to define the metrics instrumenta
|
|||
You can use database metrics to track data kept in the database, for example, a count of issues that exist on a given instance.
|
||||
|
||||
- `operation`: Operations for the given `relation`, one of `count`, `distinct_count`, `sum`, and `average`.
|
||||
- `relation`: `ActiveRecord::Relation` for the objects we want to perform the `operation`.
|
||||
- `relation`: Assigns lambda that returns the `ActiveRecord::Relation` for the objects we want to perform the `operation`. The assigned lambda can accept up to one parameter. The parameter is hashed and stored under the `options` key in the metric definition.
|
||||
- `start`: Specifies the start value of the batch counting, by default is `relation.minimum(:id)`.
|
||||
- `finish`: Specifies the end value of the batch counting, by default is `relation.maximum(:id)`.
|
||||
- `cache_start_and_finish_as`: Specifies the cache key for `start` and `finish` values and sets up caching them. Use this call when `start` and `finish` are expensive queries that should be reused between different metric calculations.
|
||||
|
@ -55,10 +55,10 @@ module Gitlab
|
|||
module Usage
|
||||
module Metrics
|
||||
module Instrumentations
|
||||
class CountBoardsMetric < DatabaseMetric
|
||||
class CountIssuesMetric < DatabaseMetric
|
||||
operation :count
|
||||
|
||||
relation { Board }
|
||||
relation ->(options) { Issue.where(confidential: options[:confidential]) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
||||
# This specific template is located at:
|
||||
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/DAST-On-Demand-API-Scan.gitlab-ci.yml
|
||||
# NOTE: This template is intended for internal GitLab use only and likely will not work properly
|
||||
# in any other project. Do not include it in your pipeline configuration.
|
||||
# For information on how to set up and use DAST, visit https://docs.gitlab.com/ee/user/application_security/dast/
|
||||
|
||||
stages:
|
||||
- build
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
||||
# This specific template is located at:
|
||||
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/DAST-On-Demand-Scan.gitlab-ci.yml
|
||||
# NOTE: This template is intended for internal GitLab use only and likely will not work properly
|
||||
# in any other project. Do not include it in your pipeline configuration.
|
||||
# For information on how to set up and use DAST, visit https://docs.gitlab.com/ee/user/application_security/dast/
|
||||
|
||||
stages:
|
||||
- build
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
# https://docs.gitlab.com/ee/development/cicd/templates.html
|
||||
# This specific template is located at:
|
||||
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/DAST-Runner-Validation.gitlab-ci.yml
|
||||
# NOTE: This template is intended for internal GitLab use only and likely will not work properly
|
||||
# in any other project. Do not include it in your pipeline configuration.
|
||||
# For information on how to set up and use DAST, visit https://docs.gitlab.com/ee/user/application_security/dast/
|
||||
|
||||
stages:
|
||||
- build
|
||||
|
|
|
@ -40,6 +40,7 @@ atlassian_identities: :gitlab_main
|
|||
audit_events_external_audit_event_destinations: :gitlab_main
|
||||
audit_events: :gitlab_main
|
||||
audit_events_streaming_headers: :gitlab_main
|
||||
audit_events_streaming_event_type_filters: :gitlab_main
|
||||
authentication_events: :gitlab_main
|
||||
award_emoji: :gitlab_main
|
||||
aws_roles: :gitlab_main
|
||||
|
|
|
@ -34,10 +34,10 @@ module Gitlab
|
|||
@metric_finish = block
|
||||
end
|
||||
|
||||
def relation(&block)
|
||||
return @metric_relation&.call unless block
|
||||
def relation(relation_proc = nil, &block)
|
||||
return unless relation_proc || block
|
||||
|
||||
@metric_relation = block
|
||||
@metric_relation = (relation_proc || block)
|
||||
end
|
||||
|
||||
def metric_options(&block)
|
||||
|
@ -106,7 +106,11 @@ module Gitlab
|
|||
end
|
||||
|
||||
def relation
|
||||
self.class.metric_relation.call.where(time_constraints)
|
||||
if self.class.metric_relation.arity == 1
|
||||
self.class.metric_relation.call(options)
|
||||
else
|
||||
self.class.metric_relation.call
|
||||
end.where(time_constraints)
|
||||
end
|
||||
|
||||
def time_constraints
|
||||
|
|
|
@ -4,7 +4,7 @@ module Gitlab
|
|||
module Usage
|
||||
module Metrics
|
||||
module Instrumentations
|
||||
class DistinctCountProjectsWithExpirationPolicyDisabledMetric < DatabaseMetric
|
||||
class DistinctCountProjectsWithExpirationPolicyMetric < DatabaseMetric
|
||||
operation :distinct_count, column: :project_id
|
||||
|
||||
start { Project.minimum(:id) }
|
||||
|
@ -12,7 +12,7 @@ module Gitlab
|
|||
|
||||
cache_start_and_finish_as :project_id
|
||||
|
||||
relation { ::ContainerExpirationPolicy.where(enabled: false) }
|
||||
relation ->(options) { ::ContainerExpirationPolicy.where(enabled: options[:enabled]) }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -41,20 +41,6 @@ RSpec.describe DashboardController do
|
|||
|
||||
expect(assigns[:issues].map(&:id)).to include(task.id)
|
||||
end
|
||||
|
||||
context 'when work_items is disabled' do
|
||||
before do
|
||||
stub_feature_flags(work_items: false)
|
||||
end
|
||||
|
||||
it 'does not include tasks in issue list' do
|
||||
task = create(:work_item, :task, project: project, author: user)
|
||||
|
||||
get :issues, params: { author_id: user.id }
|
||||
|
||||
expect(assigns[:issues].map(&:id)).not_to include(task.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET merge requests' do
|
||||
|
|
|
@ -168,94 +168,56 @@ RSpec.describe Projects::IssuesController do
|
|||
|
||||
let_it_be(:task) { create(:issue, :task, project: project) }
|
||||
|
||||
context 'when work_items feature flag is enabled' do
|
||||
shared_examples 'redirects to show work item page' do
|
||||
context 'when use_iid_in_work_items_path feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(use_iid_in_work_items_path: false)
|
||||
end
|
||||
|
||||
it 'redirects to work item page' do
|
||||
make_request
|
||||
|
||||
expect(response).to redirect_to(project_work_items_path(project, task.id, query))
|
||||
end
|
||||
shared_examples 'redirects to show work item page' do
|
||||
context 'when use_iid_in_work_items_path feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(use_iid_in_work_items_path: false)
|
||||
end
|
||||
|
||||
it 'redirects to work item page using iid' do
|
||||
it 'redirects to work item page' do
|
||||
make_request
|
||||
|
||||
expect(response).to redirect_to(project_work_items_path(project, task.iid, query.merge(iid_path: true)))
|
||||
expect(response).to redirect_to(project_work_items_path(project, task.id, query))
|
||||
end
|
||||
end
|
||||
|
||||
context 'show action' do
|
||||
let(:query) { { query: 'any' } }
|
||||
it 'redirects to work item page using iid' do
|
||||
make_request
|
||||
|
||||
it_behaves_like 'redirects to show work item page' do
|
||||
subject(:make_request) do
|
||||
get :show, params: { namespace_id: project.namespace, project_id: project, id: task.iid, **query }
|
||||
end
|
||||
end
|
||||
expect(response).to redirect_to(project_work_items_path(project, task.iid, query.merge(iid_path: true)))
|
||||
end
|
||||
end
|
||||
|
||||
context 'edit action' do
|
||||
let(:query) { { query: 'any' } }
|
||||
context 'show action' do
|
||||
let(:query) { { query: 'any' } }
|
||||
|
||||
it_behaves_like 'redirects to show work item page' do
|
||||
subject(:make_request) do
|
||||
get :edit, params: { namespace_id: project.namespace, project_id: project, id: task.iid, **query }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'update action' do
|
||||
it_behaves_like 'redirects to show work item page' do
|
||||
subject(:make_request) do
|
||||
put :update, params: {
|
||||
namespace_id: project.namespace,
|
||||
project_id: project,
|
||||
id: task.iid,
|
||||
issue: { title: 'New title' }
|
||||
}
|
||||
end
|
||||
it_behaves_like 'redirects to show work item page' do
|
||||
subject(:make_request) do
|
||||
get :show, params: { namespace_id: project.namespace, project_id: project, id: task.iid, **query }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when work_items feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(work_items: false)
|
||||
end
|
||||
context 'edit action' do
|
||||
let(:query) { { query: 'any' } }
|
||||
|
||||
shared_examples 'renders 404' do
|
||||
it 'renders 404 for show action' do
|
||||
expect(response).to have_gitlab_http_status(:not_found)
|
||||
it_behaves_like 'redirects to show work item page' do
|
||||
subject(:make_request) do
|
||||
get :edit, params: { namespace_id: project.namespace, project_id: project, id: task.iid, **query }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'show action' do
|
||||
before do
|
||||
get :show, params: { namespace_id: project.namespace, project_id: project, id: task.iid }
|
||||
context 'update action' do
|
||||
it_behaves_like 'redirects to show work item page' do
|
||||
subject(:make_request) do
|
||||
put :update, params: {
|
||||
namespace_id: project.namespace,
|
||||
project_id: project,
|
||||
id: task.iid,
|
||||
issue: { title: 'New title' }
|
||||
}
|
||||
end
|
||||
|
||||
it_behaves_like 'renders 404'
|
||||
end
|
||||
|
||||
context 'edit action' do
|
||||
before do
|
||||
get :edit, params: { namespace_id: project.namespace, project_id: project, id: task.iid }
|
||||
end
|
||||
|
||||
it_behaves_like 'renders 404'
|
||||
end
|
||||
|
||||
context 'update action' do
|
||||
before do
|
||||
put :update, params: { namespace_id: project.namespace, project_id: project, id: task.iid, issue: { title: 'New title' } }
|
||||
end
|
||||
|
||||
it_behaves_like 'renders 404'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1728,19 +1690,6 @@ RSpec.describe Projects::IssuesController do
|
|||
expect(response).to redirect_to(project_issues_path(project))
|
||||
expect(controller).to set_flash[:notice].to match(/\AYour CSV export has started/i)
|
||||
end
|
||||
|
||||
context 'when work_items is disabled' do
|
||||
before do
|
||||
stub_feature_flags(work_items: false)
|
||||
end
|
||||
|
||||
it 'does not include tasks in CSV export' do
|
||||
expect(IssuableExportCsvWorker).to receive(:perform_async)
|
||||
.with(:issue, viewer.id, project.id, hash_including('issue_types' => Issue::TYPES_FOR_LIST.excluding('task')))
|
||||
|
||||
request_csv
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when not logged in' do
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "spec_helper"
|
||||
|
||||
RSpec.describe "Confidential notes on issues", :js do
|
||||
it_behaves_like 'confidential notes on issuables' do
|
||||
let_it_be(:issuable_parent) { create(:project) }
|
||||
let_it_be(:issuable) { create(:issue, project: issuable_parent) }
|
||||
let_it_be(:user) { create(:user) }
|
||||
|
||||
let(:issuable_path) { project_issue_path(issuable_parent, issuable) }
|
||||
end
|
||||
end
|
|
@ -5,9 +5,9 @@ require "spec_helper"
|
|||
RSpec.describe "User comments on issue", :js do
|
||||
include Spec::Support::Helpers::Features::NotesHelpers
|
||||
|
||||
let(:project) { create(:project_empty_repo, :public) }
|
||||
let(:issue) { create(:issue, project: project) }
|
||||
let(:user) { create(:user) }
|
||||
let_it_be(:project) { create(:project, :public) }
|
||||
let_it_be(:issue) { create(:issue, project: project) }
|
||||
let_it_be(:user) { create(:user) }
|
||||
|
||||
before do
|
||||
project.add_guest(user)
|
||||
|
|
|
@ -18,7 +18,7 @@ describe('NoteHeader component', () => {
|
|||
const findActionText = () => wrapper.findComponent({ ref: 'actionText' });
|
||||
const findTimestampLink = () => wrapper.findComponent({ ref: 'noteTimestampLink' });
|
||||
const findTimestamp = () => wrapper.findComponent({ ref: 'noteTimestamp' });
|
||||
const findInternalNoteIndicator = () => wrapper.findByTestId('internalNoteIndicator');
|
||||
const findInternalNoteIndicator = () => wrapper.findByTestId('internal-note-indicator');
|
||||
const findSpinner = () => wrapper.findComponent({ ref: 'spinner' });
|
||||
|
||||
const statusHtml =
|
||||
|
|
|
@ -27,14 +27,6 @@ RSpec.describe Resolvers::WorkItemResolver do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the work_items feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(work_items: false)
|
||||
end
|
||||
|
||||
it { is_expected.to be_nil }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -29,16 +29,6 @@ RSpec.describe Resolvers::WorkItems::TypesResolver do
|
|||
expect(result.to_a).to contain_exactly(WorkItems::Type.default_by_type(:task))
|
||||
end
|
||||
end
|
||||
|
||||
context 'when work_items feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(work_items: false)
|
||||
end
|
||||
|
||||
it 'returns nil' do
|
||||
expect(result).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#resolve' do
|
||||
|
@ -53,15 +43,5 @@ RSpec.describe Resolvers::WorkItems::TypesResolver do
|
|||
|
||||
it_behaves_like 'a work item type resolver'
|
||||
end
|
||||
|
||||
context 'when parent is not a group or project' do
|
||||
let(:object) { 'not a project/group' }
|
||||
|
||||
it 'returns nil because of feature flag check' do
|
||||
result = resolve(described_class, obj: object, args: {})
|
||||
|
||||
expect(result).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -72,18 +72,6 @@ RSpec.describe Gitlab::UrlBuilder do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when work_items feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(work_items: false)
|
||||
end
|
||||
|
||||
it 'returns an issue path for an issue of type task' do
|
||||
task = create(:issue, :task)
|
||||
|
||||
expect(subject.build(task, only_path: true)).to eq("/#{task.project.full_path}/-/issues/#{task.iid}")
|
||||
end
|
||||
end
|
||||
|
||||
context 'when passing a compare' do
|
||||
# NOTE: The Compare requires an actual repository, which isn't available
|
||||
# with the `build_stubbed` strategy used by the table tests above
|
||||
|
|
|
@ -7,8 +7,8 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DatabaseMetric do
|
|||
described_class.tap do |metric_class|
|
||||
metric_class.relation { Issue }
|
||||
metric_class.operation :count
|
||||
metric_class.start { metric_class.relation.minimum(:id) }
|
||||
metric_class.finish { metric_class.relation.maximum(:id) }
|
||||
metric_class.start { Issue.minimum(:id) }
|
||||
metric_class.finish { Issue.maximum(:id) }
|
||||
end.new(time_frame: 'all')
|
||||
end
|
||||
|
||||
|
@ -41,8 +41,8 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DatabaseMetric do
|
|||
described_class.tap do |metric_class|
|
||||
metric_class.relation { Issue }
|
||||
metric_class.operation :count
|
||||
metric_class.start { metric_class.relation.minimum(:id) }
|
||||
metric_class.finish { metric_class.relation.maximum(:id) }
|
||||
metric_class.start { Issue.minimum(:id) }
|
||||
metric_class.finish { Issue.maximum(:id) }
|
||||
metric_class.metric_options { { batch_size: 12345 } }
|
||||
end.new(time_frame: 'all')
|
||||
end
|
||||
|
@ -103,8 +103,8 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DatabaseMetric do
|
|||
described_class.tap do |metric_class|
|
||||
metric_class.relation { Issue }
|
||||
metric_class.operation :count
|
||||
metric_class.start { metric_class.relation.minimum(:id) }
|
||||
metric_class.finish { metric_class.relation.maximum(:id) }
|
||||
metric_class.start { Issue.minimum(:id) }
|
||||
metric_class.finish { Issue.maximum(:id) }
|
||||
metric_class.cache_start_and_finish_as :special_issue_count
|
||||
end.new(time_frame: 'all')
|
||||
end
|
||||
|
@ -126,8 +126,8 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DatabaseMetric do
|
|||
described_class.tap do |metric_class|
|
||||
metric_class.relation { Issue }
|
||||
metric_class.operation(:estimate_batch_distinct_count)
|
||||
metric_class.start { metric_class.relation.minimum(:id) }
|
||||
metric_class.finish { metric_class.relation.maximum(:id) }
|
||||
metric_class.start { Issue.minimum(:id) }
|
||||
metric_class.finish { Issue.maximum(:id) }
|
||||
end.new(time_frame: 'all')
|
||||
end
|
||||
|
||||
|
@ -144,8 +144,8 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DatabaseMetric do
|
|||
metric_class.operation(:estimate_batch_distinct_count) do |result|
|
||||
result.foo
|
||||
end
|
||||
metric_class.start { metric_class.relation.minimum(:id) }
|
||||
metric_class.finish { metric_class.relation.maximum(:id) }
|
||||
metric_class.start { Issue.minimum(:id) }
|
||||
metric_class.finish { Issue.maximum(:id) }
|
||||
end.new(time_frame: 'all')
|
||||
end
|
||||
|
||||
|
@ -192,6 +192,22 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DatabaseMetric do
|
|||
expect(subject.value).to eq(1)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with additional parameters passed via options' do
|
||||
subject do
|
||||
described_class.tap do |metric_class|
|
||||
metric_class.relation ->(options) { Issue.where(confidential: options[:confidential]) }
|
||||
metric_class.operation :count
|
||||
end.new(time_frame: '28d', options: { confidential: true })
|
||||
end
|
||||
|
||||
it 'calculates a correct result' do
|
||||
create(:issue, last_edited_at: 5.days.ago, confidential: true)
|
||||
create(:issue, last_edited_at: 5.days.ago, confidential: false)
|
||||
|
||||
expect(subject.value).to eq(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with unimplemented operation method used' do
|
||||
|
|
|
@ -2,18 +2,18 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DistinctCountProjectsWithExpirationPolicyDisabledMetric do
|
||||
RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DistinctCountProjectsWithExpirationPolicyMetric do
|
||||
before_all do
|
||||
create(:container_expiration_policy, enabled: false)
|
||||
create(:container_expiration_policy, enabled: false, created_at: 29.days.ago)
|
||||
create(:container_expiration_policy, enabled: true)
|
||||
end
|
||||
|
||||
it_behaves_like 'a correct instrumented metric value', { time_frame: '28d' } do
|
||||
it_behaves_like 'a correct instrumented metric value', { time_frame: '28d', options: { enabled: false } } do
|
||||
let(:expected_value) { 1 }
|
||||
end
|
||||
|
||||
it_behaves_like 'a correct instrumented metric value', { time_frame: 'all' } do
|
||||
it_behaves_like 'a correct instrumented metric value', { time_frame: 'all', options: { enabled: false } } do
|
||||
let(:expected_value) { 2 }
|
||||
end
|
||||
end
|
|
@ -10,6 +10,20 @@ RSpec.describe Appearance do
|
|||
|
||||
it { is_expected.to have_many(:uploads) }
|
||||
|
||||
describe 'default values' do
|
||||
subject(:appearance) { described_class.new }
|
||||
|
||||
it { expect(appearance.title).to eq('') }
|
||||
it { expect(appearance.description).to eq('') }
|
||||
it { expect(appearance.new_project_guidelines).to eq('') }
|
||||
it { expect(appearance.profile_image_guidelines).to eq('') }
|
||||
it { expect(appearance.header_message).to eq('') }
|
||||
it { expect(appearance.footer_message).to eq('') }
|
||||
it { expect(appearance.message_background_color).to eq('#E75E40') }
|
||||
it { expect(appearance.message_font_color).to eq('#FFFFFF') }
|
||||
it { expect(appearance.email_header_and_footer_enabled).to eq(false) }
|
||||
end
|
||||
|
||||
describe '#single_appearance_row' do
|
||||
it 'adds an error when more than 1 row exists' do
|
||||
create(:appearance)
|
||||
|
|
|
@ -17,6 +17,14 @@ RSpec.describe ApplicationSetting do
|
|||
it { expect(setting.uuid).to be_present }
|
||||
it { expect(setting).to have_db_column(:auto_devops_enabled) }
|
||||
|
||||
describe 'default values' do
|
||||
subject(:setting) { described_class.new }
|
||||
|
||||
it { expect(setting.id).to eq(1) }
|
||||
it { expect(setting.repository_storages_weighted).to eq({}) }
|
||||
it { expect(setting.kroki_formats).to eq({}) }
|
||||
end
|
||||
|
||||
describe 'validations' do
|
||||
let(:http) { 'http://example.com' }
|
||||
let(:https) { 'https://example.com' }
|
||||
|
|
|
@ -27,6 +27,13 @@ RSpec.describe BroadcastMessage do
|
|||
it { is_expected.to validate_inclusion_of(:target_access_levels).in_array(described_class::ALLOWED_TARGET_ACCESS_LEVELS) }
|
||||
end
|
||||
|
||||
describe 'default values' do
|
||||
subject(:message) { described_class.new }
|
||||
|
||||
it { expect(message.color).to eq('#E75E40') }
|
||||
it { expect(message.font).to eq('#FFFFFF') }
|
||||
end
|
||||
|
||||
shared_examples 'time constrainted' do |broadcast_type|
|
||||
it 'returns message if time match' do
|
||||
message = create(:broadcast_message, broadcast_type: broadcast_type)
|
||||
|
|
|
@ -7,6 +7,11 @@ RSpec.describe DependencyProxy::GroupSetting, type: :model do
|
|||
it { is_expected.to belong_to(:group) }
|
||||
end
|
||||
|
||||
describe 'default values' do
|
||||
it { is_expected.to be_enabled }
|
||||
it { expect(described_class.new(enabled: false)).not_to be_enabled }
|
||||
end
|
||||
|
||||
describe 'validations' do
|
||||
it { is_expected.to validate_presence_of(:group) }
|
||||
end
|
||||
|
|
|
@ -26,22 +26,6 @@ RSpec.describe WorkItems::Widgets::Hierarchy do
|
|||
subject { described_class.new(parent_link.work_item).parent }
|
||||
|
||||
it { is_expected.to eq(parent_link.work_item_parent) }
|
||||
|
||||
context 'when work_items flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(work_items: false)
|
||||
end
|
||||
|
||||
it { is_expected.to be_nil }
|
||||
end
|
||||
|
||||
context 'when work_items flag is enabled for the parent group' do
|
||||
before do
|
||||
stub_feature_flags(work_items: group)
|
||||
end
|
||||
|
||||
it { is_expected.to eq(parent_link.work_item_parent) }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#children' do
|
||||
|
@ -51,21 +35,5 @@ RSpec.describe WorkItems::Widgets::Hierarchy do
|
|||
subject { described_class.new(work_item_parent).children }
|
||||
|
||||
it { is_expected.to contain_exactly(parent_link1.work_item, parent_link2.work_item) }
|
||||
|
||||
context 'when work_items flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(work_items: false)
|
||||
end
|
||||
|
||||
it { is_expected.to be_empty }
|
||||
end
|
||||
|
||||
context 'when work_items flag is enabled for the parent group' do
|
||||
before do
|
||||
stub_feature_flags(work_items: group)
|
||||
end
|
||||
|
||||
it { is_expected.to contain_exactly(parent_link1.work_item, parent_link2.work_item) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -629,17 +629,7 @@ RSpec.describe ProjectPolicy do
|
|||
context 'when user is member of the project' do
|
||||
let(:current_user) { developer }
|
||||
|
||||
context 'when work_items feature flag is enabled' do
|
||||
it { expect_allowed(:create_task) }
|
||||
end
|
||||
|
||||
context 'when work_items feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(work_items: false)
|
||||
end
|
||||
|
||||
it { expect_disallowed(:create_task) }
|
||||
end
|
||||
it { expect_allowed(:create_task) }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -26,32 +26,20 @@ RSpec.describe IssuePresenter do
|
|||
context 'when issue type is task' do
|
||||
let(:presented_issue) { task }
|
||||
|
||||
context 'when work_items feature flag is enabled' do
|
||||
context 'when use_iid_in_work_items_path feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(use_iid_in_work_items_path: false)
|
||||
end
|
||||
|
||||
it 'returns a work item url for the task' do
|
||||
expect(presenter.web_url).to eq(project_work_items_url(project, work_items_path: presented_issue.id))
|
||||
end
|
||||
context 'when use_iid_in_work_items_path feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(use_iid_in_work_items_path: false)
|
||||
end
|
||||
|
||||
it 'returns a work item url using iid for the task' do
|
||||
expect(presenter.web_url).to eq(
|
||||
project_work_items_url(project, work_items_path: presented_issue.iid, iid_path: true)
|
||||
)
|
||||
it 'returns a work item url for the task' do
|
||||
expect(presenter.web_url).to eq(project_work_items_url(project, work_items_path: presented_issue.id))
|
||||
end
|
||||
end
|
||||
|
||||
context 'when work_items feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(work_items: false)
|
||||
end
|
||||
|
||||
it 'returns an issue url for the task' do
|
||||
expect(presenter.web_url).to eq("http://localhost/#{group.name}/#{project.name}/-/issues/#{presented_issue.iid}")
|
||||
end
|
||||
it 'returns a work item url using iid for the task' do
|
||||
expect(presenter.web_url).to eq(
|
||||
project_work_items_url(project, work_items_path: presented_issue.iid, iid_path: true)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -78,32 +66,20 @@ RSpec.describe IssuePresenter do
|
|||
context 'when issue type is task' do
|
||||
let(:presented_issue) { task }
|
||||
|
||||
context 'when work_items feature flag is enabled' do
|
||||
context 'when use_iid_in_work_items_path feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(use_iid_in_work_items_path: false)
|
||||
end
|
||||
|
||||
it 'returns a work item path for the task' do
|
||||
expect(presenter.issue_path).to eq(project_work_items_path(project, work_items_path: presented_issue.id))
|
||||
end
|
||||
context 'when use_iid_in_work_items_path feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(use_iid_in_work_items_path: false)
|
||||
end
|
||||
|
||||
it 'returns a work item path using iid for the task' do
|
||||
expect(presenter.issue_path).to eq(
|
||||
project_work_items_path(project, work_items_path: presented_issue.iid, iid_path: true)
|
||||
)
|
||||
it 'returns a work item path for the task' do
|
||||
expect(presenter.issue_path).to eq(project_work_items_path(project, work_items_path: presented_issue.id))
|
||||
end
|
||||
end
|
||||
|
||||
context 'when work_items feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(work_items: false)
|
||||
end
|
||||
|
||||
it 'returns an issue path for the task' do
|
||||
expect(presenter.issue_path).to eq("/#{group.name}/#{project.name}/-/issues/#{presented_issue.iid}")
|
||||
end
|
||||
it 'returns a work item path using iid for the task' do
|
||||
expect(presenter.issue_path).to eq(
|
||||
project_work_items_path(project, work_items_path: presented_issue.iid, iid_path: true)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -57,15 +57,4 @@ RSpec.describe 'getting a list of work item types for a group' do
|
|||
expect(graphql_data).to eq('group' => nil)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the work_items feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(work_items: false)
|
||||
post_graphql(query, current_user: current_user)
|
||||
end
|
||||
|
||||
it 'returns null' do
|
||||
expect(graphql_data.dig('group', 'workItemTypes')).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -58,34 +58,15 @@ RSpec.describe 'Create an issue' do
|
|||
input['type'] = 'TASK'
|
||||
end
|
||||
|
||||
context 'when work_items feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(work_items: false)
|
||||
end
|
||||
it 'creates an issue with TASK type' do
|
||||
expect do
|
||||
post_graphql_mutation(mutation, current_user: current_user)
|
||||
end.to change(Issue, :count).by(1)
|
||||
|
||||
it 'creates an issue with the default ISSUE type' do
|
||||
expect do
|
||||
post_graphql_mutation(mutation, current_user: current_user)
|
||||
end.to change(Issue, :count).by(1)
|
||||
created_issue = Issue.last
|
||||
|
||||
created_issue = Issue.last
|
||||
|
||||
expect(created_issue.work_item_type.base_type).to eq('issue')
|
||||
expect(created_issue.issue_type).to eq('issue')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when work_items feature flag is enabled' do
|
||||
it 'creates an issue with TASK type' do
|
||||
expect do
|
||||
post_graphql_mutation(mutation, current_user: current_user)
|
||||
end.to change(Issue, :count).by(1)
|
||||
|
||||
created_issue = Issue.last
|
||||
|
||||
expect(created_issue.work_item_type.base_type).to eq('task')
|
||||
expect(created_issue.issue_type).to eq('task')
|
||||
end
|
||||
expect(created_issue.work_item_type.base_type).to eq('task')
|
||||
expect(created_issue.issue_type).to eq('task')
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -71,19 +71,5 @@ RSpec.describe "Create a work item from a task in a work item's description" do
|
|||
it_behaves_like 'has spam protection' do
|
||||
let(:mutation_class) { ::Mutations::WorkItems::CreateFromTask }
|
||||
end
|
||||
|
||||
context 'when the work_items feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(work_items: false)
|
||||
end
|
||||
|
||||
it 'does nothing and returns and error' do
|
||||
expect do
|
||||
post_graphql_mutation(mutation, current_user: current_user)
|
||||
end.to not_change(WorkItem, :count)
|
||||
|
||||
expect(mutation_response['errors']).to contain_exactly('`work_items` feature flag disabled for this project')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -215,19 +215,5 @@ RSpec.describe 'Create a work item' do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the work_items feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(work_items: false)
|
||||
end
|
||||
|
||||
it 'does not create the work item and returns an error' do
|
||||
expect do
|
||||
post_graphql_mutation(mutation, current_user: current_user)
|
||||
end.to not_change(WorkItem, :count)
|
||||
|
||||
expect(mutation_response['errors']).to contain_exactly('`work_items` feature flag disabled for this project')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -31,19 +31,5 @@ RSpec.describe 'Delete a work item' do
|
|||
expect(response).to have_gitlab_http_status(:success)
|
||||
expect(mutation_response['project']).to include('id' => work_item.project.to_global_id.to_s)
|
||||
end
|
||||
|
||||
context 'when the work_items feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(work_items: false)
|
||||
end
|
||||
|
||||
it 'does not delete the work item' do
|
||||
expect do
|
||||
post_graphql_mutation(mutation, current_user: current_user)
|
||||
end.to not_change(WorkItem, :count)
|
||||
|
||||
expect(mutation_response['errors']).to contain_exactly('`work_items` feature flag disabled for this project')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -75,19 +75,5 @@ RSpec.describe "Delete a task in a work item's description" do
|
|||
expect(mutation_response['errors']).to contain_exactly('Stale work item. Check lock version')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the work_items feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(work_items: false)
|
||||
end
|
||||
|
||||
it 'does nothing and returns and error' do
|
||||
expect do
|
||||
post_graphql_mutation(mutation, current_user: current_user)
|
||||
end.to not_change(WorkItem, :count)
|
||||
|
||||
expect(mutation_response['errors']).to contain_exactly('`work_items` feature flag disabled for this project')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -644,20 +644,5 @@ RSpec.describe 'Update a work item' do
|
|||
it_behaves_like 'a mutation that returns top-level errors',
|
||||
errors: ["Following widget keys are not supported by some_test_case_name type: [:hierarchy_widget]"]
|
||||
end
|
||||
|
||||
context 'when the work_items feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(work_items: false)
|
||||
end
|
||||
|
||||
it 'does not update the work item and returns and error' do
|
||||
expect do
|
||||
post_graphql_mutation(mutation, current_user: current_user)
|
||||
work_item.reload
|
||||
end.to not_change(work_item, :title)
|
||||
|
||||
expect(mutation_response['errors']).to contain_exactly('`work_items` feature flag disabled for this project')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -74,22 +74,6 @@ RSpec.describe 'Update a work item task' do
|
|||
it_behaves_like 'has spam protection' do
|
||||
let(:mutation_class) { ::Mutations::WorkItems::UpdateTask }
|
||||
end
|
||||
|
||||
context 'when the work_items feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(work_items: false)
|
||||
end
|
||||
|
||||
it 'does not update the task item and returns and error' do
|
||||
expect do
|
||||
post_graphql_mutation(mutation, current_user: current_user)
|
||||
work_item.reload
|
||||
task.reload
|
||||
end.to not_change(task, :title)
|
||||
|
||||
expect(mutation_response['errors']).to contain_exactly('`work_items` feature flag disabled for this project')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user does not have permissions to update a work item' do
|
||||
|
|
|
@ -57,15 +57,4 @@ RSpec.describe 'getting a list of work item types for a project' do
|
|||
expect(graphql_data).to eq('project' => nil)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the work_items feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(work_items: false)
|
||||
post_graphql(query, current_user: current_user)
|
||||
end
|
||||
|
||||
it 'returns null' do
|
||||
expect(graphql_data.dig('project', 'workItemTypes')).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -130,18 +130,6 @@ RSpec.describe 'getting a work item list for a project' do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when work_items flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(work_items: false)
|
||||
end
|
||||
|
||||
it 'returns an empty list' do
|
||||
post_graphql(query)
|
||||
|
||||
expect(items_data).to eq([])
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns only items visible to user' do
|
||||
post_graphql(query, current_user: current_user)
|
||||
|
||||
|
|
|
@ -357,16 +357,4 @@ RSpec.describe 'Query.work_item(id)' do
|
|||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the work_items feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(work_items: false)
|
||||
end
|
||||
|
||||
it 'returns nil' do
|
||||
post_graphql(query)
|
||||
|
||||
expect(work_item_data).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,24 +15,10 @@ RSpec.describe 'Work Items' do
|
|||
sign_in(developer)
|
||||
end
|
||||
|
||||
context 'when the work_items feature flag is enabled' do
|
||||
it 'renders index' do
|
||||
get project_work_items_url(work_item.project, work_items_path: work_item.id)
|
||||
it 'renders index' do
|
||||
get project_work_items_url(work_item.project, work_items_path: work_item.id)
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the work_items feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(work_items: false)
|
||||
end
|
||||
|
||||
it 'returns 404' do
|
||||
get project_work_items_url(work_item.project, work_items_path: work_item.id)
|
||||
|
||||
expect(response).to have_gitlab_http_status(:not_found)
|
||||
end
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,8 +10,8 @@ RSpec.shared_examples 'a correct instrumented metric value' do |params|
|
|||
end
|
||||
|
||||
before do
|
||||
if described_class.respond_to?(:relation) && described_class.relation.respond_to?(:connection)
|
||||
allow(described_class.relation.connection).to receive(:transaction_open?).and_return(false)
|
||||
if metric.respond_to?(:relation, true) && metric.send(:relation).respond_to?(:connection)
|
||||
allow(metric.send(:relation).connection).to receive(:transaction_open?).and_return(false)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "spec_helper"
|
||||
|
||||
RSpec.shared_examples 'confidential notes on issuables' do
|
||||
include Spec::Support::Helpers::Features::NotesHelpers
|
||||
|
||||
context 'when user does not have permissions' do
|
||||
it 'does not show confidential note checkbox' do
|
||||
issuable_parent.add_guest(user)
|
||||
sign_in(user)
|
||||
visit(issuable_path)
|
||||
|
||||
page.within('.new-note') do
|
||||
expect(page).not_to have_selector('[data-testid="internal-note-checkbox"]')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user has permissions' do
|
||||
it 'creates confidential note' do
|
||||
issuable_parent.add_reporter(user)
|
||||
sign_in(user)
|
||||
visit(issuable_path)
|
||||
|
||||
find('[data-testid="internal-note-checkbox"]').click
|
||||
add_note('Confidential note')
|
||||
|
||||
page.within('.note-header') do
|
||||
expect(page).to have_selector('[data-testid="internal-note-indicator"]')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -7,6 +7,11 @@ RSpec.shared_examples 'ttl_expirable' do
|
|||
|
||||
it_behaves_like 'having unique enum values'
|
||||
|
||||
describe 'default values', :freeze_time do
|
||||
it { expect(described_class.new.read_at).to be_like_time(Time.zone.now) }
|
||||
it { expect(described_class.new(read_at: 1.day.ago).read_at).to be_like_time(1.day.ago) }
|
||||
end
|
||||
|
||||
describe 'validations' do
|
||||
it { is_expected.to validate_presence_of(:status) }
|
||||
end
|
||||
|
@ -38,7 +43,7 @@ RSpec.shared_examples 'ttl_expirable' do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#read', :freeze_time do
|
||||
describe '#read!', :freeze_time do
|
||||
let_it_be(:old_read_at) { 1.day.ago }
|
||||
let_it_be(:item1) { create(class_symbol, read_at: old_read_at) }
|
||||
|
||||
|
|
|
@ -226,7 +226,7 @@ func TestUploadHandlerSendingToExternalStorageAndSupportRequestTimeout(t *testin
|
|||
RemoteObject: api.RemoteObject{
|
||||
StoreURL: storeServer.URL + "/url/put",
|
||||
ID: "store-id",
|
||||
Timeout: 0.001,
|
||||
Timeout: 0.1,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue