Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-12-06 21:09:08 +00:00
parent 5a73318262
commit f2143c9986
38 changed files with 142 additions and 518 deletions

View File

@ -1,11 +0,0 @@
---
# Cop supports --autocorrect.
RSpec/ExampleWording:
Details: grace period
Exclude:
- 'ee/spec/graphql/types/global_id_type_spec.rb'
- 'spec/features/markdown/copy_as_gfm_spec.rb'
- 'spec/lib/gitlab/auth/ldap/config_spec.rb'
- 'spec/models/concerns/schedulable_spec.rb'
- 'spec/models/container_repository_spec.rb'
- 'spec/scripts/lib/glfm/shared_spec.rb'

View File

@ -413,7 +413,7 @@
{"name":"pact-mock_service","version":"3.10.0","platform":"ruby","checksum":"898ec3b8d96f1934d15941c701ca7d5fef5ccff32022d9a196fb82073cd95e27"},
{"name":"pact-support","version":"1.18.1","platform":"ruby","checksum":"4a25961c8b1c4132e433a8eaa838b1e6914c6d3aae48eee705b9860a5e8b0476"},
{"name":"parallel","version":"1.22.1","platform":"ruby","checksum":"ebdf1f0c51f182df38522f70ba770214940bef998cdb6e00f36492b29699761f"},
{"name":"parser","version":"3.1.2.1","platform":"ruby","checksum":"57e49821b52d5fe7baffaca44ed77e9754688c9bbc68443b5293a722fdb161e0"},
{"name":"parser","version":"3.1.3.0","platform":"ruby","checksum":"4593da6a6c0dc1b0a0b47b68aa79c36655e19b9d8636f7c27d02a76cb7840e9f"},
{"name":"parslet","version":"1.8.2","platform":"ruby","checksum":"08d1ab3721cd3f175bfbee8788b2ddff71f92038f2d69bd65454c22bb9fbd98a"},
{"name":"pastel","version":"0.8.0","platform":"ruby","checksum":"481da9fb7d2f6e6b1a08faf11fa10363172dc40fd47848f096ae21209f805a75"},
{"name":"peek","version":"1.1.0","platform":"ruby","checksum":"d6501ead8cde46d8d8ed0d59eb6f0ba713d0a41c11a2c4a81447b2dce37b3ecc"},

View File

@ -1058,7 +1058,7 @@ GEM
expgen (~> 0.1)
rainbow (~> 3.1.1)
parallel (1.22.1)
parser (3.1.2.1)
parser (3.1.3.0)
ast (~> 2.4.1)
parslet (1.8.2)
pastel (0.8.0)

View File

@ -7,7 +7,6 @@ import PipelinesList from '../pipelines/list.vue';
import Clientside from '../preview/clientside.vue';
import ResizablePanel from '../resizable_panel.vue';
import TerminalView from '../terminal/view.vue';
import SwitchEditorsView from '../switch_editors/switch_editors_view.vue';
import CollapsibleSidebar from './collapsible_sidebar.vue';
// Need to add the width of the nav buttons since the resizable container contains those as well
@ -21,7 +20,7 @@ export default {
},
computed: {
...mapState('terminal', { isTerminalVisible: 'isVisible' }),
...mapState(['currentMergeRequestId', 'clientsidePreviewEnabled', 'canUseNewWebIde']),
...mapState(['currentMergeRequestId', 'clientsidePreviewEnabled']),
...mapGetters(['packageJson']),
...mapState('rightPane', ['isOpen']),
showLivePreview() {
@ -29,12 +28,6 @@ export default {
},
rightExtensionTabs() {
return [
{
show: this.canUseNewWebIde,
title: __('Switch editors'),
views: [{ component: SwitchEditorsView, ...rightSidebarViews.switchEditors }],
icon: 'bullhorn',
},
{
show: true,
title: __('Pipelines'),
@ -60,7 +53,6 @@ export default {
},
},
WIDTH,
SWITCH_EDITORS_VIEW_NAME: rightSidebarViews.switchEditors.name,
};
</script>
@ -72,11 +64,6 @@ export default {
:min-size="$options.WIDTH"
:resizable="isOpen"
>
<collapsible-sidebar
class="gl-w-full"
:extension-tabs="rightExtensionTabs"
:init-open-view="$options.SWITCH_EDITORS_VIEW_NAME"
side="right"
/>
<collapsible-sidebar class="gl-w-full" :extension-tabs="rightExtensionTabs" side="right" />
</resizable-panel>
</template>

View File

@ -1,103 +0,0 @@
<script>
import { GlButton, GlEmptyState, GlLink } from '@gitlab/ui';
import { mapState } from 'vuex';
import { createAlert } from '~/flash';
import { logError } from '~/lib/logger';
import axios from '~/lib/utils/axios_utils';
import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal';
import { ignoreWhilePending } from '~/lib/utils/ignore_while_pending';
import { s__, __ } from '~/locale';
import eventHub from '../../eventhub';
export const MSG_DESCRIPTION = s__('WebIDE|You are invited to experience the new Web IDE.');
export const MSG_BUTTON_TEXT = s__('WebIDE|Switch to new Web IDE');
export const MSG_LEARN_MORE = __('Learn more');
export const MSG_TITLE = s__('WebIDE|Ready for something new?');
export const MSG_CONFIRM = s__(
'WebIDE|Are you sure you want to switch editors? You will lose any unsaved changes.',
);
export const MSG_ERROR_ALERT = s__(
'WebIDE|Something went wrong while updating the user preferences. Please see developer console for details.',
);
export default {
components: {
GlButton,
GlEmptyState,
GlLink,
},
data() {
return {
loading: false,
};
},
computed: {
...mapState(['switchEditorSvgPath', 'links', 'userPreferencesPath']),
},
methods: {
async submitSwitch() {
const confirmed = await confirmAction(MSG_CONFIRM, {
primaryBtnText: __('Switch editors'),
cancelBtnText: __('Cancel'),
});
if (!confirmed) {
return;
}
try {
await axios.put(this.userPreferencesPath, {
user: { use_legacy_web_ide: false },
});
} catch (e) {
// why: We do not want to translate console logs
// eslint-disable-next-line @gitlab/require-i18n-strings
logError('Error while updating user preferences', e);
createAlert({
message: MSG_ERROR_ALERT,
});
return;
}
eventHub.$emit('skip-beforeunload');
window.location.reload();
},
// what: ignoreWhilePending prevents double confirmation boxes
onSwitchClicked: ignoreWhilePending(async function onSwitchClicked() {
this.loading = true;
try {
await this.submitSwitch();
} finally {
this.loading = false;
}
}),
},
MSG_TITLE,
MSG_DESCRIPTION,
MSG_BUTTON_TEXT,
MSG_LEARN_MORE,
};
</script>
<template>
<div class="gl-h-full gl-display-flex gl-flex-direction-column gl-justify-content-center">
<gl-empty-state :svg-path="switchEditorSvgPath" :svg-height="150" :title="$options.MSG_TITLE">
<template #description>
<span>{{ $options.MSG_DESCRIPTION }}</span>
<gl-link :href="links.newWebIDEHelpPagePath">{{ $options.MSG_LEARN_MORE }}</gl-link
>.
</template>
<template #actions>
<gl-button
category="primary"
variant="confirm"
:loading="loading"
@click="onSwitchClicked"
>{{ $options.MSG_BUTTON_TEXT }}</gl-button
>
</template>
</gl-empty-state>
</div>
</template>

View File

@ -61,7 +61,6 @@ export const leftSidebarViews = {
};
export const rightSidebarViews = {
switchEditors: { name: 'switch-editors', keepAlive: true },
pipelines: { name: 'pipelines-list', keepAlive: true },
jobsDetail: { name: 'jobs-detail', keepAlive: false },
mergeRequestInfo: { name: 'merge-request-info', keepAlive: true },

View File

@ -73,7 +73,6 @@ export const initLegacyWebIDE = (el, options = {}) => {
codesandboxBundlerUrl: el.dataset.codesandboxBundlerUrl,
environmentsGuidanceAlertDismissed: !parseBoolean(el.dataset.enableEnvironmentsGuidance),
previewMarkdownPath: el.dataset.previewMarkdownPath,
canUseNewWebIde: parseBoolean(el.dataset.canUseNewWebIde),
userPreferencesPath: el.dataset.userPreferencesPath,
});
},

View File

@ -34,5 +34,4 @@ export default () => ({
environmentsGuidanceAlertDetected: false,
previewMarkdownPath: '',
userPreferencesPath: '',
canUseNewWebIde: false,
});

View File

@ -34,10 +34,6 @@ module Ci
false
end
def background_upload_enabled?
false
end
def default_store
object_store_enabled? ? ObjectStorage::Store::REMOTE : ObjectStorage::Store::LOCAL
end

View File

@ -111,10 +111,6 @@ module ObjectStorage
object_store_options&.direct_upload
end
def background_upload_enabled?
object_store_options.background_upload
end
def proxy_download_enabled?
object_store_options.proxy_download
end
@ -352,12 +348,6 @@ module ObjectStorage
private
def schedule_background_upload?
self.class.object_store_enabled? &&
self.class.background_upload_enabled? &&
self.file_storage?
end
def cache_remote_file!(remote_object_id, original_filename)
file_path = File.join(TMP_UPLOAD_PATH, remote_object_id)
file_path = Pathname.new(file_path).cleanpath.to_s

View File

@ -36,13 +36,6 @@ module Pages
false
end
# we don't need background uploads because we upload files
# to the right store right away, and we already do that in
# the background job
def background_upload_enabled?
false
end
def default_store
object_store_enabled? ? ObjectStorage::Store::REMOTE : ObjectStorage::Store::LOCAL
end

View File

@ -48,10 +48,6 @@ module Terraform
false
end
def background_upload_enabled?
false
end
def proxy_download_enabled?
true
end

View File

@ -27,7 +27,6 @@ class ObjectStoreSettings
)
object_store['direct_upload'] = true
object_store['background_upload'] = false
object_store['proxy_download'] = false if object_store['proxy_download'].nil?
object_store['storage_options'] ||= {}
@ -97,7 +96,6 @@ class ObjectStoreSettings
# "server_side_encryption" => "AES256"
# },
# "direct_upload" => true,
# "background_upload" => false,
# "proxy_download" => false,
# "remote_directory" => "artifacts"
# }
@ -116,7 +114,6 @@ class ObjectStoreSettings
# "server_side_encryption" => "AES256"
# },
# "direct_upload" => true,
# "background_upload" => false,
# "proxy_download" => true,
# "remote_directory" => "lfs-objects"
# }
@ -128,7 +125,7 @@ class ObjectStoreSettings
# 2. However, a bucket has to be specified for each object
# type. Reusing buckets is not really supported, but we don't
# enforce that yet.
# 3. direct_upload and background_upload cannot be configured anymore.
# 3. direct_upload cannot be configured anymore.
def parse!
return unless use_consolidated_settings?
@ -138,7 +135,6 @@ class ObjectStoreSettings
common_config['connection']&.deep_stringify_keys!
# These are no longer configurable if common config is used
common_config['direct_upload'] = true
common_config['background_upload'] = false
common_config['storage_options'] ||= {}
SUPPORTED_TYPES.each do |store_type|

View File

@ -1361,25 +1361,25 @@ PUT /groups/:id/hooks/:hook_id
| Attribute | Type | Required | Description |
| ---------------------------- | -------------- | -------- | ----------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](index.md#namespaced-path-encoding) |
| `hook_id` | integer | yes | The ID of the group hook |
| `url` | string | yes | The hook URL |
| `push_events` | boolean | no | Trigger hook on push events |
| `id` | integer or string | yes | The ID or [URL-encoded path of the group](index.md#namespaced-path-encoding). |
| `hook_id` | integer | yes | The ID of the group hook. |
| `url` | string | yes | The hook URL. |
| `push_events` | boolean | no | Trigger hook on push events. |
| `push_events_branch_filter` | string | No | Trigger hook on push events for matching branches only. |
| `issues_events` | boolean | no | Trigger hook on issues events |
| `confidential_issues_events` | boolean | no | Trigger hook on confidential issues events |
| `merge_requests_events` | boolean | no | Trigger hook on merge requests events |
| `tag_push_events` | boolean | no | Trigger hook on tag push events |
| `note_events` | boolean | no | Trigger hook on note events |
| `confidential_note_events` | boolean | no | Trigger hook on confidential note events |
| `job_events` | boolean | no | Trigger hook on job events |
| `pipeline_events` | boolean | no | Trigger hook on pipeline events |
| `wiki_page_events` | boolean | no | Trigger hook on wiki page events |
| `deployment_events` | boolean | no | Trigger hook on deployment events |
| `releases_events` | boolean | no | Trigger hook on release events |
| `subgroup_events` | boolean | no | Trigger hook on subgroup events |
| `enable_ssl_verification` | boolean | no | Do SSL verification when triggering the hook |
| `token` | string | no | Secret token to validate received payloads; not returned in the response |
| `issues_events` | boolean | no | Trigger hook on issues events. |
| `confidential_issues_events` | boolean | no | Trigger hook on confidential issues events. |
| `merge_requests_events` | boolean | no | Trigger hook on merge requests events. |
| `tag_push_events` | boolean | no | Trigger hook on tag push events. |
| `note_events` | boolean | no | Trigger hook on note events. |
| `confidential_note_events` | boolean | no | Trigger hook on confidential note events. |
| `job_events` | boolean | no | Trigger hook on job events. |
| `pipeline_events` | boolean | no | Trigger hook on pipeline events. |
| `wiki_page_events` | boolean | no | Trigger hook on wiki page events. |
| `deployment_events` | boolean | no | Trigger hook on deployment events. |
| `releases_events` | boolean | no | Trigger hook on release events. |
| `subgroup_events` | boolean | no | Trigger hook on subgroup events. |
| `enable_ssl_verification` | boolean | no | Do SSL verification when triggering the hook. |
| `token` | string | no | Secret token to validate received payloads. Not returned in the response. When you change the webhook URL, the secret token is reset and not retained. |
### Delete group hook

View File

@ -2462,7 +2462,7 @@ PUT /projects/:id/hooks/:hook_id
| `push_events` | boolean | **{dotted-circle}** No | Trigger hook on push events. |
| `releases_events` | boolean | **{dotted-circle}** No | Trigger hook on release events. |
| `tag_push_events` | boolean | **{dotted-circle}** No | Trigger hook on tag push events. |
| `token` | string | **{dotted-circle}** No | Secret token to validate received payloads; this isn't returned in the response. |
| `token` | string | **{dotted-circle}** No | Secret token to validate received payloads. Not returned in the response. When you change the webhook URL, the secret token is reset and not retained. |
| `wiki_page_events` | boolean | **{dotted-circle}** No | Trigger hook on wiki page events. |
### Delete project hook

View File

@ -328,7 +328,7 @@ DRIs:
| Leadership | Mark Nuzzo |
| Product | Dov Hershkovitch |
| Engineering | Fabio Pitino |
| UX | Kevin Comoli |
| UX | Kevin Comoli (interim), Sunjung Park |
Domain experts:

View File

@ -16,6 +16,8 @@ module Gitlab
end
def run_report(report)
return false unless report.active?
@logger.info(
log_labels(
message: 'started',
@ -65,13 +67,31 @@ module Gitlab
report_file = file_name(report)
tmp_file_path = File.join(tmp_dir, report_file)
File.open(tmp_file_path, 'wb') do |io|
report.run(io)
io_r, io_w = IO.pipe
pid = nil
File.open(tmp_file_path, 'wb') do |file|
extras = {
in: io_r,
out: file,
err: $stderr
}
pid = Process.spawn('gzip', '--fast', **extras)
io_r.close
report.run(io_w)
io_w.close
Process.waitpid(pid)
end
File.join(@reports_path, report_file).tap do |report_file_path|
FileUtils.mv(tmp_file_path, report_file_path)
end
ensure
[io_r, io_w].each(&:close)
# Make sure we don't leave any running processes behind.
Gitlab::ProcessManagement.signal(pid, :KILL) if pid
end
def log_labels(**extra_labels)
@ -87,7 +107,7 @@ module Gitlab
report_id = [@worker_id, @worker_uuid].join(".")
[report.name, timestamp, report_id].reject(&:blank?).join('.')
[report.name, timestamp, report_id, 'gz'].compact_blank.join('.')
end
def file_size(file_path)

View File

@ -18,6 +18,11 @@ module Gitlab
'heap_dump'
end
# This will be enabled once https://gitlab.com/gitlab-org/gitlab/-/issues/370077 is done.
def active?
false
end
# This is a no-op currently and will be implemented at a later time in
# https://gitlab.com/gitlab-org/gitlab/-/issues/370077
def run(writer)

View File

@ -26938,6 +26938,9 @@ msgstr ""
msgid "NamespaceStorage|Buy more storage"
msgstr ""
msgid "NamespaceStorage|Uploads are not counted in namespace storage quotas."
msgstr ""
msgid "NamespaceStorage|We recommend that you buy additional storage to ensure your service is not interrupted."
msgstr ""
@ -29470,6 +29473,9 @@ msgstr ""
msgid "PackageRegistry|published by %{author}"
msgstr ""
msgid "Packages"
msgstr ""
msgid "Packages and registries"
msgstr ""
@ -40241,9 +40247,6 @@ msgstr ""
msgid "Switch branch/tag"
msgstr ""
msgid "Switch editors"
msgstr ""
msgid "Switch to GitLab Next"
msgstr ""
@ -44092,6 +44095,9 @@ msgstr ""
msgid "Uploading..."
msgstr ""
msgid "Uploads"
msgstr ""
msgid "Upstream"
msgstr ""
@ -45978,9 +45984,6 @@ msgstr ""
msgid "WebAuthn only works with HTTPS-enabled websites. Contact your administrator for more details."
msgstr ""
msgid "WebIDE|Are you sure you want to switch editors? You will lose any unsaved changes."
msgstr ""
msgid "WebIDE|Fork project"
msgstr ""
@ -45996,24 +45999,12 @@ msgstr ""
msgid "WebIDE|Quickly and easily edit multiple files in your project. Press . to open"
msgstr ""
msgid "WebIDE|Ready for something new?"
msgstr ""
msgid "WebIDE|Something went wrong while updating the user preferences. Please see developer console for details."
msgstr ""
msgid "WebIDE|Switch to new Web IDE"
msgstr ""
msgid "WebIDE|This project does not accept unsigned commits."
msgstr ""
msgid "WebIDE|This project does not accept unsigned commits. You cant commit changes through the Web IDE."
msgstr ""
msgid "WebIDE|You are invited to experience the new Web IDE."
msgstr ""
msgid "WebIDE|You cant edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""

View File

@ -70,7 +70,6 @@ RSpec.describe ObjectStoreSettings, feature_category: :not_owned do
expect(settings.artifacts['object_store']['enabled']).to be true
expect(settings.artifacts['object_store']['connection']).to eq(connection)
expect(settings.artifacts['object_store']['direct_upload']).to be true
expect(settings.artifacts['object_store']['background_upload']).to be false
expect(settings.artifacts['object_store']['proxy_download']).to be false
expect(settings.artifacts['object_store']['remote_directory']).to eq('artifacts')
expect(settings.artifacts['object_store']['bucket_prefix']).to eq(nil)
@ -81,7 +80,6 @@ RSpec.describe ObjectStoreSettings, feature_category: :not_owned do
expect(settings.lfs['object_store']['enabled']).to be true
expect(settings.lfs['object_store']['connection']).to eq(connection)
expect(settings.lfs['object_store']['direct_upload']).to be true
expect(settings.lfs['object_store']['background_upload']).to be false
expect(settings.lfs['object_store']['proxy_download']).to be true
expect(settings.lfs['object_store']['remote_directory']).to eq('lfs-objects')
expect(settings.lfs['object_store']['bucket_prefix']).to eq(nil)
@ -200,7 +198,6 @@ RSpec.describe ObjectStoreSettings, feature_category: :not_owned do
'enabled' => true,
'remote_directory' => 'some-bucket',
'direct_upload' => false,
'background_upload' => true,
'proxy_download' => false
}
end
@ -215,9 +212,7 @@ RSpec.describe ObjectStoreSettings, feature_category: :not_owned do
expect(settings.artifacts['object_store']).to be_nil
expect(settings.lfs['object_store']['remote_directory']).to eq('some-bucket')
expect(settings.lfs['object_store']['bucket_prefix']).to eq(nil)
# Disable background_upload, regardless of the input config
expect(settings.lfs['object_store']['direct_upload']).to eq(true)
expect(settings.lfs['object_store']['background_upload']).to eq(false)
expect(settings.external_diffs['object_store']).to be_nil
end
end
@ -230,7 +225,6 @@ RSpec.describe ObjectStoreSettings, feature_category: :not_owned do
expect(settings['enabled']).to be false
expect(settings['direct_upload']).to be true
expect(settings['background_upload']).to be false
expect(settings['remote_directory']).to be nil
expect(settings['bucket_prefix']).to be nil
end
@ -245,7 +239,6 @@ RSpec.describe ObjectStoreSettings, feature_category: :not_owned do
expect(settings['enabled']).to be true
expect(settings['direct_upload']).to be true
expect(settings['background_upload']).to be false
expect(settings['remote_directory']).to eq 'artifacts'
expect(settings['bucket_prefix']).to be nil
end

View File

@ -147,7 +147,7 @@ RSpec.describe 'Edit group settings', feature_category: :subgroups do
selected_group.add_owner(user)
end
it 'can successfully transfer the group' do
it 'can successfully transfer the group', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/384966' do
visit edit_group_path(selected_group)
page.within('[data-testid="transfer-locations-dropdown"]') do

View File

@ -46,10 +46,6 @@ RSpec.describe 'IDE', :js, feature_category: :web_ide do
end
it_behaves_like 'legacy Web IDE'
it 'does not show switch button' do
expect(page).not_to have_button('Switch to new Web IDE')
end
end
context 'with vscode feature flag on and use_legacy_web_ide=true' do
@ -61,19 +57,6 @@ RSpec.describe 'IDE', :js, feature_category: :web_ide do
end
it_behaves_like 'legacy Web IDE'
describe 'when user switches to new Web IDE' do
before do
click_button('Switch to new Web IDE')
# Confirm modal
page.within('#confirmationModal') do
click_button('Switch editors')
end
end
it_behaves_like 'new Web IDE'
end
end
describe 'sub-groups' do

View File

@ -26,7 +26,7 @@ RSpec.describe 'Copy as GFM', :js, feature_category: :team_planning do
# by verifying (`html_to_gfm(gfm_to_html(gfm)) == gfm`) for a number of examples of GFM for every filter, using the `verify` helper.
# These are all in a single `it` for performance reasons.
it 'works', :aggregate_failures do
it 'transforms HTML to GFM', :aggregate_failures do
verify(
'nesting',
'> 1. [x] **[$`2 + 2`$ {-=-}{+=+} 2^2 ~~:thumbsup:~~](http://google.com)**'

View File

@ -3,16 +3,12 @@ import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import CollapsibleSidebar from '~/ide/components/panes/collapsible_sidebar.vue';
import RightPane from '~/ide/components/panes/right.vue';
import SwitchEditorsView from '~/ide/components/switch_editors/switch_editors_view.vue';
import { rightSidebarViews } from '~/ide/constants';
import { createStore } from '~/ide/stores';
import extendStore from '~/ide/stores/extend';
import { __ } from '~/locale';
Vue.use(Vuex);
const SWITCH_EDITORS_VIEW_NAME = 'switch-editors';
describe('ide/components/panes/right.vue', () => {
let wrapper;
let store;
@ -45,7 +41,6 @@ describe('ide/components/panes/right.vue', () => {
it('renders collapsible-sidebar', () => {
expect(wrapper.findComponent(CollapsibleSidebar).props()).toMatchObject({
side: 'right',
initOpenView: SWITCH_EDITORS_VIEW_NAME,
});
});
});
@ -130,32 +125,4 @@ describe('ide/components/panes/right.vue', () => {
);
});
});
describe('switch editors tab', () => {
beforeEach(() => {
createComponent();
});
it.each`
desc | canUseNewWebIde | expectedShow
${'is shown'} | ${true} | ${true}
${'is not shown'} | ${false} | ${false}
`('with canUseNewWebIde=$canUseNewWebIde, $desc', async ({ canUseNewWebIde, expectedShow }) => {
Object.assign(store.state, { canUseNewWebIde });
await nextTick();
expect(wrapper.findComponent(CollapsibleSidebar).props('extensionTabs')).toEqual(
expect.arrayContaining([
expect.objectContaining({
show: expectedShow,
title: __('Switch editors'),
views: [
{ component: SwitchEditorsView, name: SWITCH_EDITORS_VIEW_NAME, keepAlive: true },
],
}),
]),
);
});
});
});

View File

@ -1,214 +0,0 @@
import { GlButton, GlEmptyState, GlLink } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import waitForPromises from 'helpers/wait_for_promises';
import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
import { createAlert } from '~/flash';
import axios from '~/lib/utils/axios_utils';
import { logError } from '~/lib/logger';
import { __ } from '~/locale';
import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal';
import SwitchEditorsView, {
MSG_ERROR_ALERT,
MSG_CONFIRM,
MSG_TITLE,
MSG_LEARN_MORE,
MSG_DESCRIPTION,
} from '~/ide/components/switch_editors/switch_editors_view.vue';
import eventHub from '~/ide/eventhub';
import { createStore } from '~/ide/stores';
jest.mock('~/flash');
jest.mock('~/lib/logger');
jest.mock('~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal');
const TEST_USER_PREFERENCES_PATH = '/test/user-pref/path';
const TEST_SWITCH_EDITOR_SVG_PATH = '/test/switch/editor/path.svg';
const TEST_HREF = '/test/new/web/ide/href';
describe('~/ide/components/switch_editors/switch_editors_view.vue', () => {
useMockLocationHelper();
let store;
let wrapper;
let confirmResolve;
let requestSpy;
let skipBeforeunloadSpy;
let axiosMock;
// region: finders ------------------
const findButton = () => wrapper.findComponent(GlButton);
const findEmptyState = () => wrapper.findComponent(GlEmptyState);
// region: actions ------------------
const triggerSwitchPreference = () => findButton().vm.$emit('click');
const submitConfirm = async (val) => {
confirmResolve(val);
// why: We need to wait for promises for the immediate next lines to be executed
await waitForPromises();
};
const createComponent = () => {
wrapper = shallowMount(SwitchEditorsView, {
store,
stubs: {
GlEmptyState,
},
});
};
// region: test setup ------------------
beforeEach(() => {
// Setup skip-beforeunload side-effect
skipBeforeunloadSpy = jest.fn();
eventHub.$on('skip-beforeunload', skipBeforeunloadSpy);
// Setup request side-effect
requestSpy = jest.fn().mockImplementation(() => new Promise(() => {}));
axiosMock = new MockAdapter(axios);
axiosMock.onPut(TEST_USER_PREFERENCES_PATH).reply(({ data }) => requestSpy(data));
// Setup store
store = createStore();
store.state.userPreferencesPath = TEST_USER_PREFERENCES_PATH;
store.state.switchEditorSvgPath = TEST_SWITCH_EDITOR_SVG_PATH;
store.state.links = {
newWebIDEHelpPagePath: TEST_HREF,
};
// Setup user confirm side-effect
confirmAction.mockImplementation(
() =>
new Promise((resolve) => {
confirmResolve = resolve;
}),
);
});
afterEach(() => {
eventHub.$off('skip-beforeunload', skipBeforeunloadSpy);
axiosMock.restore();
});
// region: tests ------------------
describe('default', () => {
beforeEach(() => {
createComponent();
});
it('render empty state', () => {
expect(findEmptyState().props()).toMatchObject({
svgPath: TEST_SWITCH_EDITOR_SVG_PATH,
svgHeight: 150,
title: MSG_TITLE,
});
});
it('render link', () => {
expect(wrapper.findComponent(GlLink).attributes('href')).toBe(TEST_HREF);
expect(wrapper.findComponent(GlLink).text()).toBe(MSG_LEARN_MORE);
});
it('renders description', () => {
expect(findEmptyState().text()).toContain(MSG_DESCRIPTION);
});
it('is not loading', () => {
expect(findButton().props('loading')).toBe(false);
});
});
describe('when user triggers switch preference', () => {
beforeEach(() => {
createComponent();
triggerSwitchPreference();
});
it('creates a single confirm', () => {
// Call again to ensure that we only show 1 confirm action
triggerSwitchPreference();
expect(confirmAction).toHaveBeenCalledTimes(1);
expect(confirmAction).toHaveBeenCalledWith(MSG_CONFIRM, {
primaryBtnText: __('Switch editors'),
cancelBtnText: __('Cancel'),
});
});
it('starts loading', () => {
expect(findButton().props('loading')).toBe(true);
});
describe('when user cancels confirm', () => {
beforeEach(async () => {
await submitConfirm(false);
});
it('does not make request', () => {
expect(requestSpy).not.toHaveBeenCalled();
});
it('can be triggered again', () => {
triggerSwitchPreference();
expect(confirmAction).toHaveBeenCalledTimes(2);
});
});
describe('when user accepts confirm and response success', () => {
beforeEach(async () => {
requestSpy.mockReturnValue([200, {}]);
await submitConfirm(true);
});
it('does not handle error', () => {
expect(logError).not.toHaveBeenCalled();
expect(createAlert).not.toHaveBeenCalled();
});
it('emits "skip-beforeunload" and reloads', () => {
expect(skipBeforeunloadSpy).toHaveBeenCalledTimes(1);
expect(window.location.reload).toHaveBeenCalledTimes(1);
});
it('calls request', () => {
expect(requestSpy).toHaveBeenCalledTimes(1);
expect(requestSpy).toHaveBeenCalledWith(
JSON.stringify({ user: { use_legacy_web_ide: false } }),
);
});
it('is not loading', () => {
expect(findButton().props('loading')).toBe(false);
});
});
describe('when user accepts confirm and response fails', () => {
beforeEach(async () => {
requestSpy.mockReturnValue([400, {}]);
await submitConfirm(true);
});
it('handles error', () => {
expect(logError).toHaveBeenCalledTimes(1);
expect(logError).toHaveBeenCalledWith(
'Error while updating user preferences',
expect.any(Error),
);
expect(createAlert).toHaveBeenCalledTimes(1);
expect(createAlert).toHaveBeenCalledWith({
message: MSG_ERROR_ALERT,
});
});
it('does not reload', () => {
expect(skipBeforeunloadSpy).not.toHaveBeenCalled();
expect(window.location.reload).not.toHaveBeenCalled();
});
});
});
});

View File

@ -99,7 +99,7 @@ AtlErSqafbECNDSwS5BX8yDpu5yRBJ4xegO/rNlmb8ICRYkuJapD1xXicFOsmfUK
expect { described_class.new }.to raise_error ArgumentError
end
it 'works' do
it 'returns an instance of Gitlab::Auth::Ldap::Config' do
expect(config).to be_a described_class
end

View File

@ -75,15 +75,6 @@ RSpec.describe Gitlab::Ci::Trace::Archive do
include_context 'with FIPS'
end
context 'with background_upload enabled' do
before do
stub_artifacts_object_storage(background_upload: true)
end
it_behaves_like 'skips validations'
include_context 'with FIPS'
end
context 'with direct_upload enabled' do
before do
stub_artifacts_object_storage(direct_upload: true)

View File

@ -2,13 +2,17 @@
require 'spec_helper'
RSpec.describe Gitlab::Memory::Reporter, :aggregate_failures do
RSpec.describe Gitlab::Memory::Reporter, :aggregate_failures, feature_category: :application_performance do
let(:fake_report) do
Class.new do
def name
'fake_report'
end
def active?
true
end
def run(writer)
writer << 'I ran'
end
@ -25,7 +29,10 @@ RSpec.describe Gitlab::Memory::Reporter, :aggregate_failures do
describe '#run_report', time_travel_to: '2020-02-02 10:30:45 0000' do
let(:report_duration_counter) { instance_double(::Prometheus::Client::Counter) }
let(:file_size) { 1_000_000 }
let(:report_file) { "#{reports_path}/fake_report.2020-02-02.10:30:45:000.worker_1.abc123" }
let(:report_file) { "#{reports_path}/fake_report.2020-02-02.10:30:45:000.worker_1.abc123.gz" }
let(:input) { StringIO.new }
let(:output) { StringIO.new }
before do
allow(SecureRandom).to receive(:uuid).and_return('abc123')
@ -37,13 +44,22 @@ RSpec.describe Gitlab::Memory::Reporter, :aggregate_failures do
allow(File).to receive(:size).with(report_file).and_return(file_size)
allow(logger).to receive(:info)
stub_gzip
end
shared_examples 'runs and stores reports' do
it 'runs the given report and returns true' do
expect(reporter.run_report(report)).to be(true)
expect(File.read(report_file)).to eq('I ran')
expect(output.string).to eq('I ran')
end
it 'closes read and write streams' do
expect(input).to receive(:close).ordered.at_least(:once)
expect(output).to receive(:close).ordered.at_least(:once)
reporter.run_report(report)
end
it 'logs start and finish event' do
@ -108,6 +124,38 @@ RSpec.describe Gitlab::Memory::Reporter, :aggregate_failures do
expect(reporter.run_report(report)).to be(false)
end
it 'closes read and write streams' do
allow(logger).to receive(:info)
allow(logger).to receive(:error)
expect(input).to receive(:close).ordered.at_least(:once)
expect(output).to receive(:close).ordered.at_least(:once)
reporter.run_report(report)
end
context 'when compression process is still running' do
it 'terminates the process' do
allow(logger).to receive(:info)
allow(logger).to receive(:error)
expect(Gitlab::ProcessManagement).to receive(:signal).with(an_instance_of(Integer), :KILL)
reporter.run_report(report)
end
end
end
context 'when a report is disabled' do
it 'does nothing and returns false' do
expect(report).to receive(:active?).and_return(false)
expect(report).not_to receive(:run)
expect(logger).not_to receive(:info)
expect(report_duration_counter).not_to receive(:increment)
reporter.run_report(report)
end
end
end
@ -143,4 +191,16 @@ RSpec.describe Gitlab::Memory::Reporter, :aggregate_failures do
it_behaves_like 'runs and stores reports'
end
end
# We need to stub out the call into gzip. We do this by intercepting the write
# end of the pipe and replacing it with a StringIO instead, which we can
# easily inspect for contents.
def stub_gzip
pid = 42
allow(IO).to receive(:pipe).and_return([input, output])
allow(Process).to receive(:spawn).with(
"gzip", "--fast", in: input, out: an_instance_of(File), err: an_instance_of(IO)
).and_return(pid)
allow(Process).to receive(:waitpid).with(pid)
end
end

View File

@ -15,6 +15,13 @@ RSpec.describe Gitlab::Memory::Reports::HeapDump do
end
end
describe '#active?' do
# This will be enabled once https://gitlab.com/gitlab-org/gitlab/-/issues/370077 is done.
it 'is false' do
expect(report).not_to be_active
end
end
describe '#run' do
subject(:run) { report.run(writer) }

View File

@ -835,7 +835,6 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
'direct_upload' => true,
'connection' =>
{ 'provider' => 'AWS', 'aws_access_key_id' => 'minio', 'aws_secret_access_key' => 'gdk-minio', 'region' => 'gdk', 'endpoint' => 'http://127.0.0.1:9000', 'path_style' => true },
'background_upload' => false,
'proxy_download' => false } })
expect(subject).to eq(

View File

@ -77,7 +77,7 @@ RSpec.describe Schedulable do
end.new
end
it 'works' do
it 'raises a NotImplementedError' do
expect { schedulable_instance.set_next_run_at }.to raise_error(NotImplementedError)
end
end

View File

@ -1654,7 +1654,7 @@ RSpec.describe ContainerRepository, :aggregate_failures do
stub_application_setting(container_registry_import_target_plan: valid_container_repository.migration_plan)
end
it 'works' do
it 'returns valid container repositories' do
expect(subject).to contain_exactly(valid_container_repository, valid_container_repository2)
end
end

View File

@ -10,7 +10,7 @@ RSpec.describe Glfm::Shared do
end
describe '#write_file' do
it 'works' do
it 'creates the file' do
filename = Dir::Tmpname.create('basename') do |path|
instance.write_file(path, 'test')
end
@ -20,7 +20,7 @@ RSpec.describe Glfm::Shared do
end
describe '#run_external_cmd' do
it 'works' do
it 'runs the external command' do
expect(instance.run_external_cmd('echo "hello"')).to eq("hello\n")
end
@ -35,7 +35,7 @@ RSpec.describe Glfm::Shared do
end
describe '#dump_yaml_with_formatting' do
it 'works' do
it 'returns formatted yaml' do
hash = { a: 'b' }
yaml = instance.dump_yaml_with_formatting(hash, literal_scalars: true)
expect(yaml).to eq("---\na: |-\n b\n")

View File

@ -12,7 +12,6 @@ module StubObjectStorage
uploader:,
enabled: true,
proxy_download: false,
background_upload: false,
direct_upload: false,
cdn: {}
)
@ -20,7 +19,6 @@ module StubObjectStorage
new_config = config.to_h.deep_symbolize_keys.merge({
enabled: enabled,
proxy_download: proxy_download,
background_upload: background_upload,
direct_upload: direct_upload,
cdn: cdn
})
@ -30,7 +28,6 @@ module StubObjectStorage
allow(config).to receive(:to_h).and_return(new_config)
allow(config).to receive(:enabled) { enabled }
allow(config).to receive(:proxy_download) { proxy_download }
allow(config).to receive(:background_upload) { background_upload }
allow(config).to receive(:direct_upload) { direct_upload }
uploader_config = Settingslogic.new(new_config.deep_stringify_keys)

View File

@ -156,7 +156,6 @@ module UsageDataHelpers
'direct_upload' => true,
'connection' =>
{ 'provider' => 'AWS', 'aws_access_key_id' => 'minio', 'aws_secret_access_key' => 'gdk-minio', 'region' => 'gdk', 'endpoint' => 'http://127.0.0.1:9000', 'path_style' => true },
'background_upload' => false,
'proxy_download' => false } }
)
@ -171,7 +170,6 @@ module UsageDataHelpers
'direct_upload' => true,
'connection' =>
{ 'provider' => 'AWS', 'aws_access_key_id' => 'minio', 'aws_secret_access_key' => 'gdk-minio', 'region' => 'gdk', 'endpoint' => 'http://127.0.0.1:9000', 'path_style' => true },
'background_upload' => false,
'proxy_download' => false } }
)
allow(Settings).to receive(:[]).with('uploads')
@ -182,7 +180,6 @@ module UsageDataHelpers
'direct_upload' => true,
'connection' =>
{ 'provider' => 'AWS', 'aws_access_key_id' => 'minio', 'aws_secret_access_key' => 'gdk-minio', 'region' => 'gdk', 'endpoint' => 'http://127.0.0.1:9000', 'path_style' => true },
'background_upload' => false,
'proxy_download' => false } }
)
allow(Settings).to receive(:[]).with('packages')
@ -194,7 +191,6 @@ module UsageDataHelpers
'direct_upload' => false,
'connection' =>
{ 'provider' => 'AWS', 'aws_access_key_id' => 'minio', 'aws_secret_access_key' => 'gdk-minio', 'region' => 'gdk', 'endpoint' => 'http://127.0.0.1:9000', 'path_style' => true },
'background_upload' => true,
'proxy_download' => false } }
)
end

View File

@ -12,7 +12,7 @@ RSpec.describe 'gitlab:lfs namespace rake task', :silence_stdout do
let(:remote) { ObjectStorage::Store::REMOTE }
before do
stub_lfs_object_storage(background_upload: false, direct_upload: false)
stub_lfs_object_storage(direct_upload: false)
end
describe 'migrate' do
@ -43,7 +43,7 @@ RSpec.describe 'gitlab:lfs namespace rake task', :silence_stdout do
let(:lfs_object) { create(:lfs_object, :with_file, :object_storage) }
before do
stub_lfs_object_storage(background_upload: false, direct_upload: true)
stub_lfs_object_storage(direct_upload: true)
end
context 'object storage enabled' do

View File

@ -46,12 +46,6 @@ RSpec.describe Ci::SecureFileUploader do
end
end
describe '.background_upload_enabled?' do
it 'returns false' do
expect(described_class.background_upload_enabled?).to eq(false)
end
end
describe '.default_store' do
context 'when object storage is enabled' do
it 'returns REMOTE' do

View File

@ -72,12 +72,6 @@ RSpec.describe Terraform::StateUploader do
end
end
describe '.background_upload_enabled?' do
it 'returns false' do
expect(described_class.background_upload_enabled?).to eq(false)
end
end
describe '.proxy_download_enabled?' do
it 'returns true' do
expect(described_class.proxy_download_enabled?).to eq(true)