Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
1d9c7ebdad
commit
5add825158
|
|
@ -52,6 +52,8 @@ export default {
|
|||
return tabName === this.activeTab;
|
||||
},
|
||||
navigateTo(tabName) {
|
||||
if (this.isActive(tabName)) return;
|
||||
|
||||
this.$router.push({ name: tabName });
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,7 +1,12 @@
|
|||
import * as Sentry from '@sentry/browser';
|
||||
import { pickBy } from 'lodash';
|
||||
import { parseUrlPathname } from '~/lib/utils/url_utility';
|
||||
import { NEEDS_PROPERTY, SUPPORTED_FILTER_PARAMETERS, validPipelineTabNames } from './constants';
|
||||
import {
|
||||
NEEDS_PROPERTY,
|
||||
SUPPORTED_FILTER_PARAMETERS,
|
||||
validPipelineTabNames,
|
||||
pipelineTabName,
|
||||
} from './constants';
|
||||
/*
|
||||
The following functions are the main engine in transforming the data as
|
||||
received from the endpoint into the format the d3 graph expects.
|
||||
|
|
@ -144,9 +149,8 @@ export const getPipelineDefaultTab = (url) => {
|
|||
const regexp = /\w*$/;
|
||||
const [tabName] = strippedUrl.match(regexp);
|
||||
|
||||
if (tabName && validPipelineTabNames.includes(tabName)) {
|
||||
return tabName;
|
||||
}
|
||||
if (tabName && validPipelineTabNames.includes(tabName)) return tabName;
|
||||
if (tabName === '') return pipelineTabName;
|
||||
|
||||
return null;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ module TimeTrackable
|
|||
|
||||
attribute :time_estimate, default: 0
|
||||
|
||||
validates :time_estimate, numericality: { message: 'has an invalid format' }, allow_nil: false
|
||||
validate :check_negative_time_spent
|
||||
validate :check_time_estimate
|
||||
validate :check_negative_time_spent
|
||||
|
||||
has_many :timelogs, dependent: :destroy, autosave: true # rubocop:disable Cop/ActiveRecordDependent
|
||||
after_initialize :set_time_estimate_default_value
|
||||
|
|
@ -106,4 +106,11 @@ module TimeTrackable
|
|||
def original_total_time_spent
|
||||
@original_total_time_spent ||= total_time_spent
|
||||
end
|
||||
|
||||
def check_time_estimate
|
||||
return unless new_record? || time_estimate_changed?
|
||||
return if time_estimate.is_a?(Numeric) && time_estimate >= 0
|
||||
|
||||
errors.add(:time_estimate, _('must have a valid format and be greater than or equal to zero.'))
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -397,7 +397,7 @@ class Group < Namespace
|
|||
end
|
||||
|
||||
def visibility_level_allowed_by_projects?(level = self.visibility_level)
|
||||
!projects.where('visibility_level > ?', level).exists?
|
||||
!projects.without_deleted.where('visibility_level > ?', level).exists?
|
||||
end
|
||||
|
||||
def visibility_level_allowed_by_sub_groups?(level = self.visibility_level)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class SentNotification < ApplicationRecord
|
||||
include IgnorableColumns
|
||||
|
||||
ignore_column %i[line_code note_type position], remove_with: '16.3', remove_after: '2023-07-22'
|
||||
|
||||
belongs_to :project
|
||||
belongs_to :noteable, polymorphic: true # rubocop:disable Cop/PolymorphicAssociations
|
||||
belongs_to :recipient, class_name: "User"
|
||||
|
|
|
|||
|
|
@ -114,7 +114,11 @@ module Projects
|
|||
# It's possible that the project was destroyed, but some after_commit
|
||||
# hook failed and caused us to end up here. A destroyed model will be a frozen hash,
|
||||
# which cannot be altered.
|
||||
project.update(delete_error: message, pending_delete: false) unless project.destroyed?
|
||||
unless project.destroyed?
|
||||
# Restrict project visibility if the parent group visibility was made more restrictive while the project was scheduled for deletion.
|
||||
visibility_level = project.visibility_level_allowed_by_group? ? project.visibility_level : project.group.visibility_level
|
||||
project.update(delete_error: message, pending_delete: false, visibility_level: visibility_level)
|
||||
end
|
||||
|
||||
log_error("Deletion failed on #{project.full_path} with the following message: #{message}")
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,5 +5,7 @@
|
|||
dismissible: false,
|
||||
alert_options: { class: 'project-deletion-failed-message' }) do |c|
|
||||
- c.with_body do
|
||||
This project was scheduled for deletion, but failed with the following message:
|
||||
= _('This project was scheduled for deletion, but failed with the following message:')
|
||||
= project.delete_error
|
||||
%br
|
||||
= _('The project visibility may have been made more restrictive if the parent group\'s visibility changed while the deletion was scheduled.')
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#
|
||||
---
|
||||
- advisory_database
|
||||
- ai_abstraction_layer
|
||||
- api
|
||||
- api_security
|
||||
- application_instrumentation
|
||||
|
|
@ -67,6 +68,7 @@
|
|||
- gitaly
|
||||
- gitlab_cli
|
||||
- gitlab_docs
|
||||
- gitlab_duo_chat
|
||||
- global_search
|
||||
- groups_and_projects
|
||||
- helm_chart_registry
|
||||
|
|
@ -96,7 +98,8 @@
|
|||
- pages
|
||||
- pipeline_composition
|
||||
- portfolio_management
|
||||
- product_analytics
|
||||
- product_analytics_data_management
|
||||
- product_analytics_visualization
|
||||
- pubsec_services
|
||||
- purchase
|
||||
- quality_management
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ table_name: product_analytics_events_experimental
|
|||
classes:
|
||||
- ProductAnalyticsEvent
|
||||
feature_categories:
|
||||
- product_analytics
|
||||
- product_analytics_data_management
|
||||
description: Product analytic events, experimental feature.
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/fc6c53e6f7b47dc22c8619a5a6fe491d29778d3f
|
||||
milestone: '13.2'
|
||||
|
|
|
|||
|
|
@ -12,10 +12,11 @@ General development guidelines and tips for the [Import/Export feature](../user/
|
|||
|
||||
## Security
|
||||
|
||||
The Import/Export feature is constantly updated (adding new things to export), however
|
||||
the code hasn't been refactored in a long time. We should perform a code audit (see
|
||||
[confidential issue](../user/project/issues/confidential_issues.md) `https://gitlab.com/gitlab-org/gitlab/-/issues/20720`).
|
||||
The Import/Export feature is constantly updated (adding new things to export). However,
|
||||
the code hasn't been refactored in a long time. We should perform a code audit
|
||||
to make sure its dynamic nature does not increase the number of security concerns.
|
||||
GitLab team members can view more information in this confidential issue:
|
||||
`https://gitlab.com/gitlab-org/gitlab/-/issues/20720`.
|
||||
|
||||
### Security in the code
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ To install the GitLab for Jira Cloud app:
|
|||
1. In Jira, on the top bar, select **Apps > Explore more apps** and search for `GitLab for Jira Cloud`.
|
||||
1. Select **GitLab for Jira Cloud**, then select **Get it now**.
|
||||
|
||||
Alternatively, [get the app directly from the Atlassian Marketplace](https://marketplace.atlassian.com/apps/1221011/gitlab-com-for-jira-cloud?tab=overview&hosting=cloud).
|
||||
Alternatively, [get the app directly from the Atlassian Marketplace](https://marketplace.atlassian.com/apps/1221011/gitlab-com-for-jira-cloud?tab=overview&hosting=cloud).
|
||||
|
||||
You can now [configure the GitLab for Jira Cloud app](#configure-the-gitlab-for-jira-cloud-app).
|
||||
|
||||
|
|
@ -75,6 +75,7 @@ The following data is synced:
|
|||
|
||||
Most updates to the app are automatic. For more information, see the
|
||||
[Atlassian documentation](https://developer.atlassian.com/platform/marketplace/upgrading-and-versioning-cloud-apps/).
|
||||
|
||||
If the app requires additional permissions, [you must manually approve the update in Jira](https://developer.atlassian.com/platform/marketplace/upgrading-and-versioning-cloud-apps/#changes-that-require-manual-customer-approval).
|
||||
|
||||
## Set up OAuth authentication for self-managed instances **(FREE SELF)**
|
||||
|
|
@ -382,6 +383,6 @@ Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remot
|
|||
A `403` status code is returned if:
|
||||
|
||||
- The user information cannot be fetched from Jira.
|
||||
- The authenticated Jira user does not have administrator access.
|
||||
- The authenticated Jira user does not have [site administrator](https://support.atlassian.com/user-management/docs/give-users-admin-permissions/#Make-someone-a-site-admin) access.
|
||||
|
||||
To resolve this issue, ensure the authenticated user is a Jira site administrator and try again.
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ To create Jira credentials, here's what we're going to do:
|
|||
|
||||
Prerequisite:
|
||||
|
||||
- You must have administrator access to the Jira instance.
|
||||
- You must have [site administrator](https://support.atlassian.com/user-management/docs/give-users-admin-permissions/#Make-someone-a-site-admin) access to the Jira instance.
|
||||
|
||||
## Create a Jira user
|
||||
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ example, no additional storage has yet been purchased.
|
|||
To remove the read-only state from the Red and Green projects, 50 GB additional storage is purchased.
|
||||
|
||||
Assuming the Green and Red projects' repositories and LFS grow past the 10 GB quota, the purchased storage
|
||||
available decreases. All projects remain read-only because 40 GB purchased storage is available:
|
||||
available decreases. All projects no longer have the read-only status because 40 GB purchased storage is available:
|
||||
50 GB (purchased storage) - 10 GB (total excess storage used).
|
||||
|
||||
| Repository | Storage used | Excess storage | Quota | Status |
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ module Gitlab
|
|||
init_commit = objects.last
|
||||
|
||||
diff_tree = Gitlab::Git::DiffTree.from_commit(init_commit)
|
||||
objects.prepend(diff_tree) if diff_tree
|
||||
return [diff_tree] + objects if diff_tree
|
||||
|
||||
objects
|
||||
end
|
||||
|
|
|
|||
|
|
@ -159,12 +159,10 @@ module Gitlab
|
|||
current_user.can?(:"admin_#{quick_action_target.to_ability_name}", project)
|
||||
end
|
||||
parse_params do |raw_duration|
|
||||
Gitlab::TimeTrackingFormatter.parse(raw_duration)
|
||||
Gitlab::TimeTrackingFormatter.parse(raw_duration, keep_zero: true)
|
||||
end
|
||||
command :estimate, :estimate_time do |time_estimate|
|
||||
if time_estimate
|
||||
@updates[:time_estimate] = time_estimate
|
||||
end
|
||||
@updates[:time_estimate] = time_estimate
|
||||
end
|
||||
|
||||
desc { _('Add or subtract spent time') }
|
||||
|
|
|
|||
|
|
@ -13164,6 +13164,9 @@ msgstr ""
|
|||
msgid "Could not restore the group"
|
||||
msgstr ""
|
||||
|
||||
msgid "Could not retrieve the list of branches. Use the YAML editor mode, or refresh this page later. To view the list of branches, go to %{boldStart}Code - Branches%{boldEnd}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Could not retrieve the list of protected branches. Use the YAML editor mode, or refresh this page later. To view the list of protected branches, go to %{boldStart}Settings - Branches%{boldEnd} and expand %{boldStart}Protected branches%{boldEnd}."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -46720,6 +46723,9 @@ msgstr ""
|
|||
msgid "The project size exceeds the export limit."
|
||||
msgstr ""
|
||||
|
||||
msgid "The project visibility may have been made more restrictive if the parent group's visibility changed while the deletion was scheduled."
|
||||
msgstr ""
|
||||
|
||||
msgid "The project was successfully forked."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -47815,6 +47821,9 @@ msgstr ""
|
|||
msgid "This project reached the limit of custom domains. (Max %d)"
|
||||
msgstr ""
|
||||
|
||||
msgid "This project was scheduled for deletion, but failed with the following message:"
|
||||
msgstr ""
|
||||
|
||||
msgid "This project will be deleted on %{date}"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -55681,6 +55690,9 @@ msgstr ""
|
|||
msgid "must have a repository"
|
||||
msgstr ""
|
||||
|
||||
msgid "must have a valid format and be greater than or equal to zero."
|
||||
msgstr ""
|
||||
|
||||
msgid "must match %{association}.project_id"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require "spec_helper"
|
||||
|
||||
RSpec.describe ProductAnalyticsTracking, :snowplow, feature_category: :product_analytics do
|
||||
RSpec.describe ProductAnalyticsTracking, :snowplow, feature_category: :product_analytics_data_management do
|
||||
include TrackingHelpers
|
||||
include SnowplowHelpers
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { createJobsHash, generateJobNeedsDict, getPipelineDefaultTab } from '~/pipelines/utils';
|
||||
import { validPipelineTabNames } from '~/pipelines/constants';
|
||||
import { validPipelineTabNames, pipelineTabName } from '~/pipelines/constants';
|
||||
|
||||
describe('utils functions', () => {
|
||||
const jobName1 = 'build_1';
|
||||
|
|
@ -173,8 +173,8 @@ describe('utils functions', () => {
|
|||
|
||||
describe('getPipelineDefaultTab', () => {
|
||||
const baseUrl = 'http://gitlab.com/user/multi-projects-small/-/pipelines/332/';
|
||||
it('returns null if there is only the base url', () => {
|
||||
expect(getPipelineDefaultTab(baseUrl)).toBe(null);
|
||||
it('returns pipeline tab name if there is only the base url', () => {
|
||||
expect(getPipelineDefaultTab(baseUrl)).toBe(pipelineTabName);
|
||||
});
|
||||
|
||||
it('returns null if there was no valid last url part', () => {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::SnowplowEventDefinitionGenerator, :silence_stdout, feature_category: :product_analytics do
|
||||
RSpec.describe Gitlab::SnowplowEventDefinitionGenerator, :silence_stdout, feature_category: :product_analytics_data_management do
|
||||
let(:ce_temp_dir) { Dir.mktmpdir }
|
||||
let(:ee_temp_dir) { Dir.mktmpdir }
|
||||
let(:timestamp) { Time.now.utc.strftime('%Y%m%d%H%M%S') }
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Analytics::CycleAnalytics::StageEvents::StageEvent, feature_category: :product_analytics do
|
||||
RSpec.describe Gitlab::Analytics::CycleAnalytics::StageEvents::StageEvent, feature_category: :product_analytics_data_management do
|
||||
let(:instance) { described_class.new({}) }
|
||||
|
||||
it { expect(described_class).to respond_to(:name) }
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require "spec_helper"
|
||||
|
||||
RSpec.describe Gitlab::InternalEvents::EventDefinitions, feature_category: :product_analytics do
|
||||
RSpec.describe Gitlab::InternalEvents::EventDefinitions, feature_category: :product_analytics_data_management do
|
||||
after(:all) do
|
||||
described_class.instance_variable_set(:@events, nil)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require "spec_helper"
|
||||
|
||||
RSpec.describe Gitlab::InternalEvents, :snowplow, feature_category: :product_analytics do
|
||||
RSpec.describe Gitlab::InternalEvents, :snowplow, feature_category: :product_analytics_data_management do
|
||||
include TrackingHelpers
|
||||
include SnowplowHelpers
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe ProductAnalytics::Settings, feature_category: :product_analytics do
|
||||
RSpec.describe ProductAnalytics::Settings, feature_category: :product_analytics_data_management do
|
||||
let_it_be(:project) { create(:project) }
|
||||
|
||||
subject { described_class.for_project(project) }
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
require 'spec_helper'
|
||||
require_migration!
|
||||
|
||||
RSpec.describe CopyClickhouseConnectionStringToEncryptedVar, feature_category: :product_analytics do
|
||||
RSpec.describe CopyClickhouseConnectionStringToEncryptedVar, feature_category: :product_analytics_data_management do
|
||||
let!(:migration) { described_class.new }
|
||||
let(:setting) { table(:application_settings).create!(clickhouse_connection_string: 'https://example.com/test') }
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
require "spec_helper"
|
||||
require_migration!
|
||||
|
||||
RSpec.describe BackfillProductAnalyticsDataCollectorHost, feature_category: :product_analytics do
|
||||
RSpec.describe BackfillProductAnalyticsDataCollectorHost, feature_category: :product_analytics_data_management do
|
||||
let!(:application_settings) { table(:application_settings) }
|
||||
|
||||
describe '#up' do
|
||||
|
|
|
|||
|
|
@ -390,6 +390,13 @@ RSpec.describe Group, feature_category: :groups_and_projects do
|
|||
expect(internal_group).to be_invalid
|
||||
expect(internal_group.errors[:visibility_level]).to include('private is not allowed since this group contains projects with higher visibility.')
|
||||
end
|
||||
|
||||
it 'is valid if higher visibility project is deleted' do
|
||||
internal_project.update_attribute(:pending_delete, true)
|
||||
internal_group.visibility_level = Gitlab::VisibilityLevel::PRIVATE
|
||||
|
||||
expect(internal_group).to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
context 'when group has a higher visibility' do
|
||||
|
|
|
|||
|
|
@ -132,13 +132,59 @@ RSpec.describe Notes::QuickActionsService, feature_category: :team_planning do
|
|||
end
|
||||
|
||||
describe '/estimate' do
|
||||
let(:note_text) { '/estimate 1h' }
|
||||
before do
|
||||
# reset to 10 minutes before each test
|
||||
note.noteable.update!(time_estimate: 600)
|
||||
end
|
||||
|
||||
it 'adds time estimate to noteable' do
|
||||
content = execute(note)
|
||||
shared_examples 'does not update time_estimate and displays the correct error message' do
|
||||
it 'shows validation error message' do
|
||||
content = execute(note)
|
||||
|
||||
expect(content).to be_empty
|
||||
expect(note.noteable.time_estimate).to eq(3600)
|
||||
expect(content).to be_empty
|
||||
expect(note.noteable.errors[:time_estimate]).to include('must have a valid format and be greater than or equal to zero.')
|
||||
expect(note.noteable.reload.time_estimate).to eq(600)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the time estimate is valid' do
|
||||
let(:note_text) { '/estimate 1h' }
|
||||
|
||||
it 'adds time estimate to noteable' do
|
||||
content = execute(note)
|
||||
|
||||
expect(content).to be_empty
|
||||
expect(note.noteable.reload.time_estimate).to eq(3600)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the time estimate is 0' do
|
||||
let(:note_text) { '/estimate 0' }
|
||||
|
||||
it 'adds time estimate to noteable' do
|
||||
content = execute(note)
|
||||
|
||||
expect(content).to be_empty
|
||||
expect(note.noteable.reload.time_estimate).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the time estimate is invalid' do
|
||||
let(:note_text) { '/estimate a' }
|
||||
|
||||
include_examples "does not update time_estimate and displays the correct error message"
|
||||
end
|
||||
|
||||
context 'when the time estimate is partially invalid' do
|
||||
let(:note_text) { '/estimate 1d 3id' }
|
||||
|
||||
include_examples "does not update time_estimate and displays the correct error message"
|
||||
end
|
||||
|
||||
context 'when the time estimate is negative' do
|
||||
let(:note_text) { '/estimate -1h' }
|
||||
|
||||
include_examples "does not update time_estimate and displays the correct error message"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe ProductAnalytics::BuildActivityGraphService, feature_category: :product_analytics do
|
||||
RSpec.describe ProductAnalytics::BuildActivityGraphService, feature_category: :product_analytics_data_management do
|
||||
let_it_be(:project) { create(:project) }
|
||||
let_it_be(:time_now) { Time.zone.now }
|
||||
let_it_be(:time_ago) { Time.zone.now - 5.days }
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe ProductAnalytics::BuildGraphService, feature_category: :product_analytics do
|
||||
RSpec.describe ProductAnalytics::BuildGraphService, feature_category: :product_analytics_data_management do
|
||||
let_it_be(:project) { create(:project) }
|
||||
|
||||
let_it_be(:events) do
|
||||
|
|
|
|||
|
|
@ -115,6 +115,23 @@ RSpec.describe Projects::DestroyService, :aggregate_failures, :event_store_publi
|
|||
expect(project.reload.delete_error).to be_present
|
||||
expect(project.delete_error).to match(error_message)
|
||||
end
|
||||
|
||||
context 'when parent group visibility was made more restrictive while project was marked "pending deletion"' do
|
||||
let!(:group) { create(:group, :public) }
|
||||
let!(:project) { create(:project, :repository, :public, namespace: group) }
|
||||
|
||||
it 'sets the project visibility level to that of the parent group' do
|
||||
group.add_owner(user)
|
||||
project.group.update_attribute(:visibility_level, Gitlab::VisibilityLevel::INTERNAL)
|
||||
|
||||
expect(project.reload.visibility_level).to be(Gitlab::VisibilityLevel::PUBLIC)
|
||||
expect(project.group.visibility_level).to be(Gitlab::VisibilityLevel::INTERNAL)
|
||||
|
||||
destroy_project(project, user, {})
|
||||
|
||||
expect(project.reload.visibility_level).to be(Gitlab::VisibilityLevel::INTERNAL)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "deleting a project with merge requests" do
|
||||
|
|
|
|||
|
|
@ -1454,9 +1454,21 @@ RSpec.describe QuickActions::InterpretService, feature_category: :team_planning
|
|||
let(:issuable) { issue }
|
||||
end
|
||||
|
||||
it_behaves_like 'failed command' do
|
||||
context 'when provided an invalid estimate' do
|
||||
let(:content) { '/estimate abc' }
|
||||
let(:issuable) { issue }
|
||||
|
||||
it 'populates {} if content contains an unsupported command' do
|
||||
_, updates, _ = service.execute(content, issuable)
|
||||
|
||||
expect(updates[:time_estimate]).to be_nil
|
||||
end
|
||||
|
||||
it "returns empty message" do
|
||||
_, _, message = service.execute(content, issuable)
|
||||
|
||||
expect(message).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'spend command' do
|
||||
|
|
|
|||
Loading…
Reference in New Issue