Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-10-09 21:07:58 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-10-09 21:07:58 +0300
commitb3986e06460cc2bff35c1c1e7902579b46c1d4c6 (patch)
tree3646975b83dd94a772a5a943ca1c5e7872646813 /spec
parentfa0535cda4c99da0ca078882c610fd3b3564f991 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/factories/pages_deployments.rb4
-rw-r--r--spec/features/groups/navbar_spec.rb13
-rw-r--r--spec/features/markdown/observability_spec.rb77
-rw-r--r--spec/frontend/behaviors/markdown/render_observability_spec.js43
-rw-r--r--spec/frontend/ide/init_gitlab_web_ide_spec.js36
-rw-r--r--spec/frontend/observability/index_spec.js64
-rw-r--r--spec/frontend/observability/observability_app_spec.js201
-rw-r--r--spec/frontend/observability/skeleton_spec.js86
-rw-r--r--spec/helpers/groups/observability_helper_spec.rb76
-rw-r--r--spec/helpers/ide_helper_spec.rb33
-rw-r--r--spec/lib/banzai/filter/inline_observability_filter_spec.rb101
-rw-r--r--spec/lib/gitlab/observability_spec.rb203
-rw-r--r--spec/lib/sidebars/groups/menus/observability_menu_spec.rb93
-rw-r--r--spec/lib/sidebars/groups/super_sidebar_menus/monitor_menu_spec.rb22
-rw-r--r--spec/lib/sidebars/groups/super_sidebar_panel_spec.rb1
-rw-r--r--spec/models/issue_spec.rb113
-rw-r--r--spec/models/pages/lookup_path_spec.rb19
-rw-r--r--spec/models/pages_deployment_spec.rb38
-rw-r--r--spec/models/project_pages_metadatum_spec.rb21
-rw-r--r--spec/models/project_spec.rb12
-rw-r--r--spec/policies/group_policy_spec.rb67
-rw-r--r--spec/requests/groups/observability_controller_spec.rb99
-rw-r--r--spec/requests/projects/issues_controller_spec.rb23
-rw-r--r--spec/requests/projects/merge_requests/creations_spec.rb12
-rw-r--r--spec/requests/projects/merge_requests_controller_spec.rb13
-rw-r--r--spec/routing/group_routing_spec.rb8
-rw-r--r--spec/services/pages/migrate_from_legacy_storage_service_spec.rb137
-rw-r--r--spec/services/pages/migrate_legacy_storage_to_deployment_service_spec.rb118
-rw-r--r--spec/services/pages/zip_directory_service_spec.rb280
-rw-r--r--spec/services/todo_service_spec.rb35
-rw-r--r--spec/support/ability_check_todo.yml2
-rw-r--r--spec/support/helpers/navbar_structure_helper.rb13
-rw-r--r--spec/support/rspec_order_todo.yml2
-rw-r--r--spec/support/shared_examples/observability/embed_observabilities_examples.rb61
-rw-r--r--spec/views/groups/observability/observability.html.haml_spec.rb18
35 files changed, 235 insertions, 1909 deletions
diff --git a/spec/factories/pages_deployments.rb b/spec/factories/pages_deployments.rb
index d3e2fefb4ae..eaa3a68770f 100644
--- a/spec/factories/pages_deployments.rb
+++ b/spec/factories/pages_deployments.rb
@@ -8,10 +8,6 @@ FactoryBot.define do
filename { nil }
end
- trait(:migrated) do
- filename { PagesDeployment::MIGRATED_FILE_NAME }
- end
-
after(:build) do |deployment, evaluator|
file = UploadedFile.new("spec/fixtures/pages.zip", filename: evaluator.filename)
diff --git a/spec/features/groups/navbar_spec.rb b/spec/features/groups/navbar_spec.rb
index 6a38f0c59a8..76e4e32d138 100644
--- a/spec/features/groups/navbar_spec.rb
+++ b/spec/features/groups/navbar_spec.rb
@@ -18,7 +18,6 @@ RSpec.describe 'Group navbar', :with_license, feature_category: :navigation do
stub_config(dependency_proxy: { enabled: false })
stub_config(registry: { enabled: false })
- stub_feature_flags(observability_group_tab: false)
stub_group_wikis(false)
group.add_maintainer(user)
sign_in(user)
@@ -93,16 +92,4 @@ RSpec.describe 'Group navbar', :with_license, feature_category: :navigation do
it_behaves_like 'verified navigation bar'
end
-
- context 'when observability tab is enabled' do
- before do
- stub_feature_flags(observability_group_tab: true)
-
- insert_observability_nav
-
- visit group_path(group)
- end
-
- it_behaves_like 'verified navigation bar'
- end
end
diff --git a/spec/features/markdown/observability_spec.rb b/spec/features/markdown/observability_spec.rb
deleted file mode 100644
index ec414d4396e..00000000000
--- a/spec/features/markdown/observability_spec.rb
+++ /dev/null
@@ -1,77 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe 'Observability rendering', :js, feature_category: :metrics do
- let_it_be(:group) { create(:group, :public) }
- let_it_be(:project) { create(:project, :repository, group: group) }
- let_it_be(:user) { create(:user) }
- let_it_be(:observable_url) { "https://www.gitlab.com/groups/#{group.path}/-/observability/explore?observability_path=/explore?foo=bar" }
- let_it_be(:expected_observable_url) { "https://observe.gitlab.com/-/#{group.id}/explore?foo=bar" }
-
- before do
- stub_config_setting(url: "https://www.gitlab.com")
- group.add_developer(user)
- sign_in(user)
- end
-
- context 'when user is a developer of the embedded group' do
- context 'when embedding in an issue' do
- let(:issue) do
- create(:issue, project: project, description: observable_url)
- end
-
- before do
- visit project_issue_path(project, issue)
- wait_for_requests
- end
-
- it_behaves_like 'embeds observability'
- end
-
- context 'when embedding in an MR' do
- let(:merge_request) do
- create(:merge_request, source_project: project, target_project: project, description: observable_url)
- end
-
- before do
- visit merge_request_path(merge_request)
- wait_for_requests
- end
-
- it_behaves_like 'embeds observability'
- end
- end
-
- context 'when feature flag is disabled' do
- before do
- stub_feature_flags(observability_group_tab: false)
- end
-
- context 'when embedding in an issue' do
- let(:issue) do
- create(:issue, project: project, description: observable_url)
- end
-
- before do
- visit project_issue_path(project, issue)
- wait_for_requests
- end
-
- it_behaves_like 'does not embed observability'
- end
-
- context 'when embedding in an MR' do
- let(:merge_request) do
- create(:merge_request, source_project: project, target_project: project, description: observable_url)
- end
-
- before do
- visit merge_request_path(merge_request)
- wait_for_requests
- end
-
- it_behaves_like 'does not embed observability'
- end
- end
-end
diff --git a/spec/frontend/behaviors/markdown/render_observability_spec.js b/spec/frontend/behaviors/markdown/render_observability_spec.js
deleted file mode 100644
index f464c01ac15..00000000000
--- a/spec/frontend/behaviors/markdown/render_observability_spec.js
+++ /dev/null
@@ -1,43 +0,0 @@
-import Vue from 'vue';
-import { createWrapper } from '@vue/test-utils';
-import renderObservability from '~/behaviors/markdown/render_observability';
-import { INLINE_EMBED_DIMENSIONS, SKELETON_VARIANT_EMBED } from '~/observability/constants';
-import ObservabilityApp from '~/observability/components/observability_app.vue';
-
-describe('renderObservability', () => {
- let subject;
-
- beforeEach(() => {
- subject = document.createElement('div');
- subject.classList.add('js-render-observability');
- subject.dataset.frameUrl = 'https://observe.gitlab.com/';
- document.body.appendChild(subject);
- });
-
- afterEach(() => {
- subject.remove();
- });
-
- it('should return an array of Vue instances', () => {
- const vueInstances = renderObservability([
- ...document.querySelectorAll('.js-render-observability'),
- ]);
- expect(vueInstances).toEqual([expect.any(Vue)]);
- });
-
- it('should correctly pass props to the ObservabilityApp component', () => {
- const vueInstances = renderObservability([
- ...document.querySelectorAll('.js-render-observability'),
- ]);
-
- const wrapper = createWrapper(vueInstances[0]);
-
- expect(wrapper.findComponent(ObservabilityApp).props()).toMatchObject({
- observabilityIframeSrc: 'https://observe.gitlab.com/',
- skeletonVariant: SKELETON_VARIANT_EMBED,
- inlineEmbed: true,
- height: INLINE_EMBED_DIMENSIONS.HEIGHT,
- width: INLINE_EMBED_DIMENSIONS.WIDTH,
- });
- });
-});
diff --git a/spec/frontend/ide/init_gitlab_web_ide_spec.js b/spec/frontend/ide/init_gitlab_web_ide_spec.js
index 73c8ad88aa3..6a5bedb0bbb 100644
--- a/spec/frontend/ide/init_gitlab_web_ide_spec.js
+++ b/spec/frontend/ide/init_gitlab_web_ide_spec.js
@@ -36,9 +36,9 @@ const TEST_START_REMOTE_PARAMS = {
remotePath: '/test/projects/f oo',
connectionToken: '123abc',
};
-const TEST_EDITOR_FONT_SRC_URL = 'http://gitlab.test/assets/jetbrains-mono/JetBrainsMono.woff2';
+const TEST_EDITOR_FONT_SRC_URL = 'http://gitlab.test/assets/gitlab-mono/GitLabMono.woff2';
const TEST_EDITOR_FONT_FORMAT = 'woff2';
-const TEST_EDITOR_FONT_FAMILY = 'JebBrains Mono';
+const TEST_EDITOR_FONT_FAMILY = 'GitLab Mono';
describe('ide/init_gitlab_web_ide', () => {
let resolveConfirm;
@@ -56,9 +56,20 @@ describe('ide/init_gitlab_web_ide', () => {
el.dataset.userPreferencesPath = TEST_USER_PREFERENCES_PATH;
el.dataset.mergeRequest = TEST_MR_ID;
el.dataset.filePath = TEST_FILE_PATH;
- el.dataset.editorFontSrcUrl = TEST_EDITOR_FONT_SRC_URL;
- el.dataset.editorFontFormat = TEST_EDITOR_FONT_FORMAT;
- el.dataset.editorFontFamily = TEST_EDITOR_FONT_FAMILY;
+ el.dataset.editorFont = JSON.stringify({
+ fallback_font_family: 'monospace',
+ font_faces: [
+ {
+ family: TEST_EDITOR_FONT_FAMILY,
+ src: [
+ {
+ url: TEST_EDITOR_FONT_SRC_URL,
+ format: TEST_EDITOR_FONT_FORMAT,
+ },
+ ],
+ },
+ ],
+ });
el.dataset.signInPath = TEST_SIGN_IN_PATH;
document.body.append(el);
@@ -121,9 +132,18 @@ describe('ide/init_gitlab_web_ide', () => {
signIn: TEST_SIGN_IN_PATH,
},
editorFont: {
- srcUrl: TEST_EDITOR_FONT_SRC_URL,
- fontFamily: TEST_EDITOR_FONT_FAMILY,
- format: TEST_EDITOR_FONT_FORMAT,
+ fallbackFontFamily: 'monospace',
+ fontFaces: [
+ {
+ family: TEST_EDITOR_FONT_FAMILY,
+ src: [
+ {
+ url: TEST_EDITOR_FONT_SRC_URL,
+ format: TEST_EDITOR_FONT_FORMAT,
+ },
+ ],
+ },
+ ],
},
handleStartRemote: expect.any(Function),
handleTracking,
diff --git a/spec/frontend/observability/index_spec.js b/spec/frontend/observability/index_spec.js
deleted file mode 100644
index 25eb048c62b..00000000000
--- a/spec/frontend/observability/index_spec.js
+++ /dev/null
@@ -1,64 +0,0 @@
-import { createWrapper } from '@vue/test-utils';
-import Vue, { nextTick } from 'vue';
-import renderObservability from '~/observability/index';
-import ObservabilityApp from '~/observability/components/observability_app.vue';
-import { SKELETON_VARIANTS_BY_ROUTE } from '~/observability/constants';
-
-describe('renderObservability', () => {
- let element;
- let vueInstance;
- let component;
-
- const OBSERVABILITY_ROUTES = Object.keys(SKELETON_VARIANTS_BY_ROUTE);
- const SKELETON_VARIANTS = Object.values(SKELETON_VARIANTS_BY_ROUTE);
-
- beforeEach(() => {
- element = document.createElement('div');
- element.setAttribute('id', 'js-observability-app');
- element.dataset.observabilityIframeSrc = 'https://observe.gitlab.com/';
- document.body.appendChild(element);
-
- vueInstance = renderObservability();
- component = createWrapper(vueInstance).findComponent(ObservabilityApp);
- });
-
- afterEach(() => {
- element.remove();
- });
-
- it('should return a Vue instance', () => {
- expect(vueInstance).toEqual(expect.any(Vue));
- });
-
- it('should render the ObservabilityApp component', () => {
- expect(component.props('observabilityIframeSrc')).toBe('https://observe.gitlab.com/');
- });
-
- describe('skeleton variant', () => {
- it.each`
- pathDescription | path | variant
- ${'dashboards'} | ${OBSERVABILITY_ROUTES[0]} | ${SKELETON_VARIANTS[0]}
- ${'explore'} | ${OBSERVABILITY_ROUTES[1]} | ${SKELETON_VARIANTS[1]}
- ${'manage dashboards'} | ${OBSERVABILITY_ROUTES[2]} | ${SKELETON_VARIANTS[2]}
- ${'any other'} | ${'unknown/route'} | ${SKELETON_VARIANTS[0]}
- `(
- 'renders the $variant skeleton variant for $pathDescription path',
- async ({ path, variant }) => {
- component.vm.$router.push(path);
- await nextTick();
-
- expect(component.props('skeletonVariant')).toBe(variant);
- },
- );
- });
-
- it('handle route-update events', () => {
- component.vm.$router.push('/something?foo=bar');
- component.vm.$emit('route-update', { url: '/some_path' });
- expect(component.vm.$router.currentRoute.path).toBe('/something');
- expect(component.vm.$router.currentRoute.query).toEqual({
- foo: 'bar',
- observability_path: '/some_path',
- });
- });
-});
diff --git a/spec/frontend/observability/observability_app_spec.js b/spec/frontend/observability/observability_app_spec.js
deleted file mode 100644
index 392992a5962..00000000000
--- a/spec/frontend/observability/observability_app_spec.js
+++ /dev/null
@@ -1,201 +0,0 @@
-import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
-import { stubComponent } from 'helpers/stub_component';
-import ObservabilityApp from '~/observability/components/observability_app.vue';
-import ObservabilitySkeleton from '~/observability/components/skeleton/index.vue';
-import {
- MESSAGE_EVENT_TYPE,
- INLINE_EMBED_DIMENSIONS,
- FULL_APP_DIMENSIONS,
- SKELETON_VARIANT_EMBED,
-} from '~/observability/constants';
-
-import { darkModeEnabled } from '~/lib/utils/color_utils';
-
-jest.mock('~/lib/utils/color_utils');
-
-describe('ObservabilityApp', () => {
- let wrapper;
-
- const $route = {
- pathname: 'https://gitlab.com/gitlab-org/',
- path: 'https://gitlab.com/gitlab-org/-/observability/dashboards',
- query: { otherQuery: 100 },
- };
-
- const mockSkeletonOnContentLoaded = jest.fn();
-
- const findIframe = () => wrapper.findByTestId('observability-ui-iframe');
-
- const TEST_IFRAME_SRC = 'https://observe.gitlab.com/9970/?groupId=14485840';
-
- const TEST_USERNAME = 'test-user';
-
- const mountComponent = (props) => {
- wrapper = shallowMountExtended(ObservabilityApp, {
- propsData: {
- observabilityIframeSrc: TEST_IFRAME_SRC,
- ...props,
- },
- stubs: {
- ObservabilitySkeleton: stubComponent(ObservabilitySkeleton, {
- methods: { onContentLoaded: mockSkeletonOnContentLoaded },
- }),
- },
- mocks: {
- $route,
- },
- });
- };
-
- const dispatchMessageEvent = (message) =>
- window.dispatchEvent(new MessageEvent('message', message));
-
- beforeEach(() => {
- gon.current_username = TEST_USERNAME;
- });
-
- describe('iframe src', () => {
- it('should render an iframe with observabilityIframeSrc, decorated with light theme and username', () => {
- darkModeEnabled.mockReturnValueOnce(false);
- mountComponent();
- const iframe = findIframe();
-
- expect(iframe.exists()).toBe(true);
- expect(iframe.attributes('src')).toBe(
- `${TEST_IFRAME_SRC}&theme=light&username=${TEST_USERNAME}`,
- );
- });
-
- it('should render an iframe with observabilityIframeSrc decorated with dark theme and username', () => {
- darkModeEnabled.mockReturnValueOnce(true);
- mountComponent();
- const iframe = findIframe();
-
- expect(iframe.exists()).toBe(true);
- expect(iframe.attributes('src')).toBe(
- `${TEST_IFRAME_SRC}&theme=dark&username=${TEST_USERNAME}`,
- );
- });
- });
-
- describe('iframe sandbox', () => {
- it('should render an iframe with sandbox attributes', () => {
- mountComponent();
- const iframe = findIframe();
-
- expect(iframe.exists()).toBe(true);
- expect(iframe.attributes('sandbox')).toBe('allow-same-origin allow-forms allow-scripts');
- });
- });
-
- describe('iframe kiosk query param', () => {
- it('when inlineEmbed, it should set the proper kiosk query parameter', () => {
- mountComponent({
- inlineEmbed: true,
- });
-
- const iframe = findIframe();
-
- expect(iframe.attributes('src')).toBe(
- `${TEST_IFRAME_SRC}&theme=light&username=${TEST_USERNAME}&kiosk=inline-embed`,
- );
- });
- });
-
- describe('iframe size', () => {
- it('should set the specified size', () => {
- mountComponent({
- height: INLINE_EMBED_DIMENSIONS.HEIGHT,
- width: INLINE_EMBED_DIMENSIONS.WIDTH,
- });
-
- const iframe = findIframe();
-
- expect(iframe.attributes('width')).toBe(INLINE_EMBED_DIMENSIONS.WIDTH);
- expect(iframe.attributes('height')).toBe(INLINE_EMBED_DIMENSIONS.HEIGHT);
- });
-
- it('should fallback to default size', () => {
- mountComponent({});
-
- const iframe = findIframe();
-
- expect(iframe.attributes('width')).toBe(FULL_APP_DIMENSIONS.WIDTH);
- expect(iframe.attributes('height')).toBe(FULL_APP_DIMENSIONS.HEIGHT);
- });
- });
-
- describe('skeleton variant', () => {
- it('sets the specified skeleton variant', () => {
- mountComponent({ skeletonVariant: SKELETON_VARIANT_EMBED });
- const props = wrapper.findComponent(ObservabilitySkeleton).props();
-
- expect(props.variant).toBe(SKELETON_VARIANT_EMBED);
- });
-
- it('should have a default skeleton variant', () => {
- mountComponent();
- const props = wrapper.findComponent(ObservabilitySkeleton).props();
-
- expect(props.variant).toBe('dashboards');
- });
- });
-
- describe('on GOUI_ROUTE_UPDATE', () => {
- it('should emit a route-update event', () => {
- mountComponent();
-
- const payload = { url: '/explore' };
- dispatchMessageEvent({
- data: { type: MESSAGE_EVENT_TYPE.GOUI_ROUTE_UPDATE, payload },
- origin: 'https://observe.gitlab.com',
- });
-
- expect(wrapper.emitted('route-update')[0]).toEqual([payload]);
- });
- });
-
- describe('on GOUI_LOADED', () => {
- beforeEach(() => {
- mountComponent();
- });
-
- it('should call onContentLoaded method', () => {
- dispatchMessageEvent({
- data: { type: MESSAGE_EVENT_TYPE.GOUI_LOADED },
- origin: 'https://observe.gitlab.com',
- });
- expect(mockSkeletonOnContentLoaded).toHaveBeenCalled();
- });
-
- it('should not call onContentLoaded method if origin is different', () => {
- dispatchMessageEvent({
- data: { type: MESSAGE_EVENT_TYPE.GOUI_LOADED },
- origin: 'https://example.com',
- });
- expect(mockSkeletonOnContentLoaded).not.toHaveBeenCalled();
- });
-
- it('should not call onContentLoaded method if event type is different', () => {
- dispatchMessageEvent({
- data: { type: 'UNKNOWN_EVENT' },
- origin: 'https://observe.gitlab.com',
- });
- expect(mockSkeletonOnContentLoaded).not.toHaveBeenCalled();
- });
- });
-
- describe('on unmount', () => {
- it('should not emit any even on route update', () => {
- mountComponent();
- wrapper.destroy();
-
- dispatchMessageEvent({
- data: { type: MESSAGE_EVENT_TYPE.GOUI_ROUTE_UPDATE, payload: { url: '/explore' } },
- origin: 'https://observe.gitlab.com',
- });
-
- expect(wrapper.emitted('route-update')).toBeUndefined();
- });
- });
-});
diff --git a/spec/frontend/observability/skeleton_spec.js b/spec/frontend/observability/skeleton_spec.js
index 979070cfb12..5501fa117e0 100644
--- a/spec/frontend/observability/skeleton_spec.js
+++ b/spec/frontend/observability/skeleton_spec.js
@@ -3,32 +3,16 @@ import { GlSkeletonLoader, GlAlert, GlLoadingIcon } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import Skeleton from '~/observability/components/skeleton/index.vue';
-import DashboardsSkeleton from '~/observability/components/skeleton/dashboards.vue';
-import ExploreSkeleton from '~/observability/components/skeleton/explore.vue';
-import ManageSkeleton from '~/observability/components/skeleton/manage.vue';
-import EmbedSkeleton from '~/observability/components/skeleton/embed.vue';
-import {
- SKELETON_VARIANTS_BY_ROUTE,
- DEFAULT_TIMERS,
- SKELETON_VARIANT_EMBED,
-} from '~/observability/constants';
+import { DEFAULT_TIMERS } from '~/observability/constants';
describe('Skeleton component', () => {
let wrapper;
- const SKELETON_VARIANTS = [...Object.values(SKELETON_VARIANTS_BY_ROUTE), 'spinner'];
+ const findSpinner = () => wrapper.findComponent(GlLoadingIcon);
const findContentWrapper = () => wrapper.findByTestId('content-wrapper');
- const findExploreSkeleton = () => wrapper.findComponent(ExploreSkeleton);
-
- const findDashboardsSkeleton = () => wrapper.findComponent(DashboardsSkeleton);
-
- const findManageSkeleton = () => wrapper.findComponent(ManageSkeleton);
-
- const findEmbedSkeleton = () => wrapper.findComponent(EmbedSkeleton);
-
const findAlert = () => wrapper.findComponent(GlAlert);
const mountComponent = ({ ...props } = {}) => {
@@ -39,39 +23,39 @@ describe('Skeleton component', () => {
describe('on mount', () => {
beforeEach(() => {
- mountComponent({ variant: 'explore' });
+ mountComponent({ variant: 'spinner' });
});
describe('showing content', () => {
it('shows the skeleton if content is not loaded within CONTENT_WAIT_MS', async () => {
- expect(findExploreSkeleton().exists()).toBe(false);
- expect(findContentWrapper().isVisible()).toBe(false);
+ expect(findSpinner().exists()).toBe(false);
+ expect(findContentWrapper().exists()).toBe(false);
jest.advanceTimersByTime(DEFAULT_TIMERS.CONTENT_WAIT_MS);
await nextTick();
- expect(findExploreSkeleton().exists()).toBe(true);
- expect(findContentWrapper().isVisible()).toBe(false);
+ expect(findSpinner().exists()).toBe(true);
+ expect(findContentWrapper().exists()).toBe(false);
});
it('does not show the skeleton if content loads within CONTENT_WAIT_MS', async () => {
- expect(findExploreSkeleton().exists()).toBe(false);
- expect(findContentWrapper().isVisible()).toBe(false);
+ expect(findSpinner().exists()).toBe(false);
+ expect(findContentWrapper().exists()).toBe(false);
wrapper.vm.onContentLoaded();
await nextTick();
- expect(findContentWrapper().isVisible()).toBe(true);
- expect(findExploreSkeleton().exists()).toBe(false);
+ expect(findContentWrapper().exists()).toBe(true);
+ expect(findSpinner().exists()).toBe(false);
jest.advanceTimersByTime(DEFAULT_TIMERS.CONTENT_WAIT_MS);
await nextTick();
- expect(findContentWrapper().isVisible()).toBe(true);
- expect(findExploreSkeleton().exists()).toBe(false);
+ expect(findContentWrapper().exists()).toBe(true);
+ expect(findSpinner().exists()).toBe(false);
});
it('hides the skeleton after content loads', async () => {
@@ -79,15 +63,15 @@ describe('Skeleton component', () => {
await nextTick();
- expect(findExploreSkeleton().exists()).toBe(true);
- expect(findContentWrapper().isVisible()).toBe(false);
+ expect(findSpinner().exists()).toBe(true);
+ expect(findContentWrapper().exists()).toBe(false);
wrapper.vm.onContentLoaded();
await nextTick();
- expect(findContentWrapper().isVisible()).toBe(true);
- expect(findExploreSkeleton().exists()).toBe(false);
+ expect(findContentWrapper().exists()).toBe(true);
+ expect(findSpinner().exists()).toBe(false);
});
});
@@ -99,7 +83,7 @@ describe('Skeleton component', () => {
await nextTick();
expect(findAlert().exists()).toBe(true);
- expect(findContentWrapper().isVisible()).toBe(false);
+ expect(findContentWrapper().exists()).toBe(false);
});
it('shows the error dialog if content fails to load', async () => {
@@ -110,7 +94,7 @@ describe('Skeleton component', () => {
await nextTick();
expect(findAlert().exists()).toBe(true);
- expect(findContentWrapper().isVisible()).toBe(false);
+ expect(findContentWrapper().exists()).toBe(false);
});
it('does not show the error dialog if content has loaded within TIMEOUT_MS', async () => {
@@ -120,36 +104,28 @@ describe('Skeleton component', () => {
await nextTick();
expect(findAlert().exists()).toBe(false);
- expect(findContentWrapper().isVisible()).toBe(true);
+ expect(findContentWrapper().exists()).toBe(true);
});
});
});
describe('skeleton variant', () => {
- it.each`
- skeletonType | condition | variant
- ${'dashboards'} | ${'variant is dashboards'} | ${SKELETON_VARIANTS[0]}
- ${'explore'} | ${'variant is explore'} | ${SKELETON_VARIANTS[1]}
- ${'manage'} | ${'variant is manage'} | ${SKELETON_VARIANTS[2]}
- ${'embed'} | ${'variant is embed'} | ${SKELETON_VARIANT_EMBED}
- ${'spinner'} | ${'variant is spinner'} | ${'spinner'}
- ${'default'} | ${'variant is not manage, dashboards or explore'} | ${'unknown'}
- `('should render $skeletonType skeleton if $condition', async ({ skeletonType, variant }) => {
- mountComponent({ variant });
+ it('shows only the spinner variant when variant is spinner', async () => {
+ mountComponent({ variant: 'spinner' });
jest.advanceTimersByTime(DEFAULT_TIMERS.CONTENT_WAIT_MS);
await nextTick();
- const showsDefaultSkeleton = ![...SKELETON_VARIANTS, SKELETON_VARIANT_EMBED].includes(
- variant,
- );
- expect(findDashboardsSkeleton().exists()).toBe(skeletonType === SKELETON_VARIANTS[0]);
- expect(findExploreSkeleton().exists()).toBe(skeletonType === SKELETON_VARIANTS[1]);
- expect(findManageSkeleton().exists()).toBe(skeletonType === SKELETON_VARIANTS[2]);
- expect(findEmbedSkeleton().exists()).toBe(skeletonType === SKELETON_VARIANT_EMBED);
+ expect(findSpinner().exists()).toBe(true);
+ expect(wrapper.findComponent(GlSkeletonLoader).exists()).toBe(false);
+ });
- expect(wrapper.findComponent(GlSkeletonLoader).exists()).toBe(showsDefaultSkeleton);
+ it('shows only the default variant when variant is not spinner', async () => {
+ mountComponent({ variant: 'unknown' });
+ jest.advanceTimersByTime(DEFAULT_TIMERS.CONTENT_WAIT_MS);
+ await nextTick();
- expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(variant === 'spinner');
+ expect(findSpinner().exists()).toBe(false);
+ expect(wrapper.findComponent(GlSkeletonLoader).exists()).toBe(true);
});
});
diff --git a/spec/helpers/groups/observability_helper_spec.rb b/spec/helpers/groups/observability_helper_spec.rb
deleted file mode 100644
index f0e6aa0998a..00000000000
--- a/spec/helpers/groups/observability_helper_spec.rb
+++ /dev/null
@@ -1,76 +0,0 @@
-# frozen_string_literal: true
-
-require "spec_helper"
-
-RSpec.describe Groups::ObservabilityHelper do
- let(:group) { build_stubbed(:group) }
-
- describe '#observability_iframe_src' do
- before do
- allow(Gitlab::Observability).to receive(:build_full_url).and_return('full-url')
- end
-
- it 'returns the iframe src for action: dashboards' do
- allow(helper).to receive(:params).and_return({ action: 'dashboards', observability_path: '/foo?bar=foobar' })
- expect(helper.observability_iframe_src(group)).to eq('full-url')
- expect(Gitlab::Observability).to have_received(:build_full_url).with(group, '/foo?bar=foobar', '/')
- end
-
- it 'returns the iframe src for action: manage' do
- allow(helper).to receive(:params).and_return({ action: 'manage', observability_path: '/foo?bar=foobar' })
- expect(helper.observability_iframe_src(group)).to eq('full-url')
- expect(Gitlab::Observability).to have_received(:build_full_url).with(group, '/foo?bar=foobar', '/dashboards')
- end
-
- it 'returns the iframe src for action: explore' do
- allow(helper).to receive(:params).and_return({ action: 'explore', observability_path: '/foo?bar=foobar' })
- expect(helper.observability_iframe_src(group)).to eq('full-url')
- expect(Gitlab::Observability).to have_received(:build_full_url).with(group, '/foo?bar=foobar', '/explore')
- end
-
- it 'returns the iframe src for action: datasources' do
- allow(helper).to receive(:params).and_return({ action: 'datasources', observability_path: '/foo?bar=foobar' })
- expect(helper.observability_iframe_src(group)).to eq('full-url')
- expect(Gitlab::Observability).to have_received(:build_full_url).with(group, '/foo?bar=foobar', '/datasources')
- end
-
- it 'returns the iframe src when action is not recognised' do
- allow(helper).to receive(:params).and_return({ action: 'unrecognised', observability_path: '/foo?bar=foobar' })
- expect(helper.observability_iframe_src(group)).to eq('full-url')
- expect(Gitlab::Observability).to have_received(:build_full_url).with(group, '/foo?bar=foobar', '/')
- end
-
- it 'returns the iframe src when observability_path is missing' do
- allow(helper).to receive(:params).and_return({ action: 'dashboards' })
- expect(helper.observability_iframe_src(group)).to eq('full-url')
- expect(Gitlab::Observability).to have_received(:build_full_url).with(group, nil, '/')
- end
- end
-
- describe '#observability_page_title' do
- it 'returns the title for action: dashboards' do
- allow(helper).to receive(:params).and_return({ action: 'dashboards' })
- expect(helper.observability_page_title).to eq("Dashboards")
- end
-
- it 'returns the title for action: manage' do
- allow(helper).to receive(:params).and_return({ action: 'manage' })
- expect(helper.observability_page_title).to eq("Manage dashboards")
- end
-
- it 'returns the title for action: explore' do
- allow(helper).to receive(:params).and_return({ action: 'explore' })
- expect(helper.observability_page_title).to eq("Explore telemetry data")
- end
-
- it 'returns the title for action: datasources' do
- allow(helper).to receive(:params).and_return({ action: 'datasources' })
- expect(helper.observability_page_title).to eq("Data sources")
- end
-
- it 'returns the default title for unknown action' do
- allow(helper).to receive(:params).and_return({ action: 'unknown' })
- expect(helper.observability_page_title).to eq("Dashboards")
- end
- end
-end
diff --git a/spec/helpers/ide_helper_spec.rb b/spec/helpers/ide_helper_spec.rb
index 7f657caa986..47500b8e21e 100644
--- a/spec/helpers/ide_helper_spec.rb
+++ b/spec/helpers/ide_helper_spec.rb
@@ -103,10 +103,7 @@ RSpec.describe IdeHelper, feature_category: :web_ide do
'new-web-ide-help-page-path' =>
help_page_path('user/project/web_ide/index.md', anchor: 'vscode-reimplementation'),
'csp-nonce' => 'test-csp-nonce',
- 'ide-remote-path' => ide_remote_path(remote_host: ':remote_host', remote_path: ':remote_path'),
- 'editor-font-family' => 'GitLab Mono',
- 'editor-font-format' => 'woff2',
- 'editor-font-src-url' => a_string_matching(%r{gitlab-mono/GitLabMono})
+ 'ide-remote-path' => ide_remote_path(remote_host: ':remote_host', remote_path: ':remote_path')
}
end
@@ -119,6 +116,34 @@ RSpec.describe IdeHelper, feature_category: :web_ide do
.to include(base_data)
end
+ it 'includes editor font configuration' do
+ ide_data = helper.ide_data(project: nil, fork_info: fork_info, params: params)
+ editor_font = ::Gitlab::Json.parse(ide_data.fetch('editor-font'), symbolize_names: true)
+
+ expect(editor_font).to include({
+ fallback_font_family: 'monospace',
+ font_faces: [
+ {
+ family: 'GitLab Mono',
+ display: 'block',
+ src: [{
+ url: a_string_matching(%r{gitlab-mono/GitLabMono-[^I]}),
+ format: 'woff2'
+ }]
+ },
+ {
+ family: 'GitLab Mono',
+ display: 'block',
+ style: 'italic',
+ src: [{
+ url: a_string_matching(%r{gitlab-mono/GitLabMono-Italic}),
+ format: 'woff2'
+ }]
+ }
+ ]
+ })
+ end
+
it 'does not use new web ide if feature flag is disabled' do
stub_feature_flags(vscode_web_ide: false)
diff --git a/spec/lib/banzai/filter/inline_observability_filter_spec.rb b/spec/lib/banzai/filter/inline_observability_filter_spec.rb
deleted file mode 100644
index 81896faced8..00000000000
--- a/spec/lib/banzai/filter/inline_observability_filter_spec.rb
+++ /dev/null
@@ -1,101 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Banzai::Filter::InlineObservabilityFilter, feature_category: :metrics do
- include FilterSpecHelper
-
- let(:input) { %(<a href="#{url}">example</a>) }
- let(:doc) { filter(input) }
-
- before do
- allow(Gitlab::Observability).to receive(:embeddable_url).and_return('embeddable-url')
- stub_config_setting(url: "https://www.gitlab.com")
- end
-
- describe '#filter?' do
- context 'when the document contains a valid observability link' do
- let(:url) { "https://www.gitlab.com/groups/some-group/-/observability/test" }
-
- it 'leaves the original link unchanged' do
- expect(doc.at_css('a').to_s).to eq(input)
- end
-
- it 'appends an observability charts placeholder' do
- node = doc.at_css('.js-render-observability')
-
- expect(node).to be_present
- expect(node.attribute('data-frame-url').to_s).to eq('embeddable-url')
- expect(Gitlab::Observability).to have_received(:embeddable_url).with(url).once
- end
- end
-
- context 'with duplicate URLs' do
- let(:url) { "https://www.gitlab.com/groups/some-group/-/observability/test" }
- let(:input) { %(<a href="#{url}">example1</a><a href="#{url}">example2</a>) }
-
- where(:embeddable_url) do
- [
- 'not-nil',
- nil
- ]
- end
-
- with_them do
- it 'calls Gitlab::Observability.embeddable_url only once' do
- allow(Gitlab::Observability).to receive(:embeddable_url).with(url).and_return(embeddable_url)
-
- filter(input)
-
- expect(Gitlab::Observability).to have_received(:embeddable_url).with(url).once
- end
- end
- end
-
- shared_examples 'does not embed observabilty' do
- it 'leaves the original link unchanged' do
- expect(doc.at_css('a').to_s).to eq(input)
- end
-
- it 'does not append an observability charts placeholder' do
- node = doc.at_css('.js-render-observability')
-
- expect(node).not_to be_present
- end
- end
-
- context 'when the embeddable url is nil' do
- let(:url) { "https://www.gitlab.com/groups/some-group/-/something-else/test" }
-
- before do
- allow(Gitlab::Observability).to receive(:embeddable_url).and_return(nil)
- end
-
- it_behaves_like 'does not embed observabilty'
- end
-
- context 'when the document has an unrecognised link' do
- let(:url) { "https://www.gitlab.com/groups/some-group/-/something-else/test" }
-
- it_behaves_like 'does not embed observabilty'
-
- it 'does not build the embeddable url' do
- expect(Gitlab::Observability).not_to have_received(:embeddable_url)
- end
- end
-
- context 'when feature flag is disabled' do
- let(:url) { "https://www.gitlab.com/groups/some-group/-/observability/test" }
-
- before do
- stub_feature_flags(observability_group_tab: false)
- end
-
- it_behaves_like 'does not embed observabilty'
-
- it 'does not build the embeddable url' do
- expect(Gitlab::Observability).not_to have_received(:embeddable_url)
- end
- end
- end
-end
diff --git a/spec/lib/gitlab/observability_spec.rb b/spec/lib/gitlab/observability_spec.rb
index 04c35f0ee3a..a6d0eafdd55 100644
--- a/spec/lib/gitlab/observability_spec.rb
+++ b/spec/lib/gitlab/observability_spec.rb
@@ -45,207 +45,4 @@ RSpec.describe Gitlab::Observability, feature_category: :error_tracking do
it { is_expected.to eq("#{described_class.observability_url}/v3/tenant/#{project.id}") }
end
-
- describe '.build_full_url' do
- let_it_be(:group) { build_stubbed(:group, id: 123) }
- let(:observability_url) { described_class.observability_url }
-
- it 'returns the full observability url for the given params' do
- url = described_class.build_full_url(group, '/foo?bar=baz', '/')
- expect(url).to eq("https://observe.gitlab.com/-/123/foo?bar=baz")
- end
-
- it 'handles missing / from observability_path' do
- url = described_class.build_full_url(group, 'foo?bar=baz', '/')
- expect(url).to eq("https://observe.gitlab.com/-/123/foo?bar=baz")
- end
-
- it 'sanitises observability_path' do
- url = described_class.build_full_url(group, "/test?groupId=<script>alert('attack!')</script>", '/')
- expect(url).to eq("https://observe.gitlab.com/-/123/test?groupId=alert('attack!')")
- end
-
- context 'when observability_path is missing' do
- it 'builds the url with the fallback_path' do
- url = described_class.build_full_url(group, nil, '/fallback')
- expect(url).to eq("https://observe.gitlab.com/-/123/fallback")
- end
-
- it 'defaults to / if fallback_path is also missing' do
- url = described_class.build_full_url(group, nil, nil)
- expect(url).to eq("https://observe.gitlab.com/-/123/")
- end
- end
- end
-
- describe '.embeddable_url' do
- before do
- stub_config_setting(url: "https://www.gitlab.com")
- # Can't use build/build_stubbed as we want the routes to be generated as well
- create(:group, path: 'test-path', id: 123)
- end
-
- context 'when URL is valid' do
- where(:input, :expected) do
- [
- [
- "https://www.gitlab.com/groups/test-path/-/observability/explore?observability_path=%2Fexplore%3FgroupId%3D14485840%26left%3D%255B%2522now-1h%2522,%2522now%2522,%2522new-sentry.gitlab.net%2522,%257B%257D%255D",
- "https://observe.gitlab.com/-/123/explore?groupId=14485840&left=%5B%22now-1h%22,%22now%22,%22new-sentry.gitlab.net%22,%7B%7D%5D"
- ],
- [
- "https://www.gitlab.com/groups/test-path/-/observability/explore?observability_path=/goto/foo",
- "https://observe.gitlab.com/-/123/goto/foo"
- ]
- ]
- end
-
- with_them do
- it 'returns an embeddable observability url' do
- expect(described_class.embeddable_url(input)).to eq(expected)
- end
- end
- end
-
- context 'when URL is invalid' do
- where(:input) do
- [
- # direct links to observe.gitlab.com
- "https://observe.gitlab.com/-/123/explore",
- 'https://observe.gitlab.com/v1/auth/start',
-
- # invalid GitLab URL
- "not a link",
- "https://foo.bar/groups/test-path/-/observability/explore?observability_path=/explore",
- "http://www.gitlab.com/groups/test-path/-/observability/explore?observability_path=/explore",
- "https://www.gitlab.com:123/groups/test-path/-/observability/explore?observability_path=/explore",
- "https://www.gitlab.com@example.com/groups/test-path/-/observability/explore?observability_path=/explore",
- "https://www.gitlab.com/groups/test-path/-/observability/explore?observability_path=@example.com",
-
- # invalid group/controller/actions
- "https://www.gitlab.com/groups/INVALID_GROUP/-/observability/explore?observability_path=/explore",
- "https://www.gitlab.com/groups/test-path/-/INVALID_CONTROLLER/explore?observability_path=/explore",
- "https://www.gitlab.com/groups/test-path/-/observability/INVALID_ACTION?observability_path=/explore",
-
- # invalid observablity path
- "https://www.gitlab.com/groups/test-path/-/observability/explore",
- "https://www.gitlab.com/groups/test-path/-/observability/explore?missing_observability_path=/explore",
- "https://www.gitlab.com/groups/test-path/-/observability/explore?observability_path=/not_embeddable",
- "https://www.gitlab.com/groups/test-path/-/observability/explore?observability_path=/datasources",
- "https://www.gitlab.com/groups/test-path/-/observability/explore?observability_path=not a valid path"
- ]
- end
-
- with_them do
- it 'returns nil' do
- expect(described_class.embeddable_url(input)).to be_nil
- end
- end
-
- it 'returns nil if the path detection throws an error' do
- test_url = "https://www.gitlab.com/groups/test-path/-/observability/explore"
- allow(Rails.application.routes).to receive(:recognize_path).with(test_url) {
- raise ActionController::RoutingError, 'test'
- }
- expect(described_class.embeddable_url(test_url)).to be_nil
- end
-
- it 'returns nil if parsing observaboility path throws an error' do
- observability_path = 'some-path'
- test_url = "https://www.gitlab.com/groups/test-path/-/observability/explore?observability_path=#{observability_path}"
-
- allow(URI).to receive(:parse).and_call_original
- allow(URI).to receive(:parse).with(observability_path) {
- raise URI::InvalidURIError, 'test'
- }
-
- expect(described_class.embeddable_url(test_url)).to be_nil
- end
- end
- end
-
- describe '.allowed_for_action?' do
- let(:group) { build_stubbed(:group) }
- let(:user) { build_stubbed(:user) }
-
- before do
- allow(described_class).to receive(:allowed?).and_call_original
- end
-
- it 'returns false if action is nil' do
- expect(described_class.allowed_for_action?(user, group, nil)).to eq(false)
- end
-
- describe 'allowed? calls' do
- using RSpec::Parameterized::TableSyntax
-
- where(:action, :permission) do
- :foo | :admin_observability
- :explore | :read_observability
- :datasources | :admin_observability
- :manage | :admin_observability
- :dashboards | :read_observability
- end
-
- with_them do
- it "calls allowed? with #{params[:permission]} when actions is #{params[:action]}" do
- described_class.allowed_for_action?(user, group, action)
- expect(described_class).to have_received(:allowed?).with(user, group, permission)
- end
- end
- end
- end
-
- describe '.allowed?' do
- let(:user) { build_stubbed(:user) }
- let(:group) { build_stubbed(:group) }
- let(:test_permission) { :read_observability }
-
- before do
- allow(Ability).to receive(:allowed?).and_return(false)
- end
-
- subject do
- described_class.allowed?(user, group, test_permission)
- end
-
- it 'checks if ability is allowed for the given user and group' do
- allow(Ability).to receive(:allowed?).and_return(true)
-
- subject
-
- expect(Ability).to have_received(:allowed?).with(user, test_permission, group)
- end
-
- it 'checks for admin_observability if permission is missing' do
- described_class.allowed?(user, group)
-
- expect(Ability).to have_received(:allowed?).with(user, :admin_observability, group)
- end
-
- it 'returns true if the ability is allowed' do
- allow(Ability).to receive(:allowed?).and_return(true)
-
- expect(subject).to eq(true)
- end
-
- it 'returns false if the ability is not allowed' do
- allow(Ability).to receive(:allowed?).and_return(false)
-
- expect(subject).to eq(false)
- end
-
- it 'returns false if observability url is missing' do
- allow(described_class).to receive(:observability_url).and_return("")
-
- expect(subject).to eq(false)
- end
-
- it 'returns false if group is missing' do
- expect(described_class.allowed?(user, nil, :read_observability)).to eq(false)
- end
-
- it 'returns false if user is missing' do
- expect(described_class.allowed?(nil, group, :read_observability)).to eq(false)
- end
- end
end
diff --git a/spec/lib/sidebars/groups/menus/observability_menu_spec.rb b/spec/lib/sidebars/groups/menus/observability_menu_spec.rb
deleted file mode 100644
index 573760cddb6..00000000000
--- a/spec/lib/sidebars/groups/menus/observability_menu_spec.rb
+++ /dev/null
@@ -1,93 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Sidebars::Groups::Menus::ObservabilityMenu, feature_category: :navigation do
- let(:owner) { build_stubbed(:user) }
- let(:root_group) do
- build(:group, :private).tap do |g|
- g.add_owner(owner)
- end
- end
-
- let(:group) { root_group }
- let(:user) { owner }
- let(:context) { Sidebars::Groups::Context.new(current_user: user, container: group) }
- let(:menu) { described_class.new(context) }
-
- describe '#render?' do
- before do
- allow(menu).to receive(:can?).and_call_original
- end
-
- context 'when observability#explore is allowed' do
- before do
- allow(Gitlab::Observability).to receive(:allowed_for_action?).with(user, group, :explore).and_return(true)
- end
-
- it 'returns true' do
- expect(menu.render?).to eq true
- expect(Gitlab::Observability).to have_received(:allowed_for_action?).with(user, group, :explore)
- end
- end
-
- context 'when observability#explore is not allowed' do
- before do
- allow(Gitlab::Observability).to receive(:allowed_for_action?).with(user, group, :explore).and_return(false)
- end
-
- it 'returns false' do
- expect(menu.render?).to eq false
- expect(Gitlab::Observability).to have_received(:allowed_for_action?).with(user, group, :explore)
- end
- end
- end
-
- describe "Menu items" do
- before do
- allow(Gitlab::Observability).to receive(:allowed_for_action?).and_return(false)
- end
-
- subject { find_menu(menu, item_id) }
-
- shared_examples 'observability menu entry' do
- context 'when action is allowed' do
- before do
- allow(Gitlab::Observability).to receive(:allowed_for_action?).with(user, group, item_id).and_return(true)
- end
-
- it 'the menu item is added to list of menu items' do
- is_expected.not_to be_nil
- end
- end
-
- context 'when action is not allowed' do
- before do
- allow(Gitlab::Observability).to receive(:allowed_for_action?).with(user, group, item_id).and_return(false)
- end
-
- it 'the menu item is added to list of menu items' do
- is_expected.to be_nil
- end
- end
- end
-
- describe 'Explore' do
- it_behaves_like 'observability menu entry' do
- let(:item_id) { :explore }
- end
- end
-
- describe 'Datasources' do
- it_behaves_like 'observability menu entry' do
- let(:item_id) { :datasources }
- end
- end
- end
-
- private
-
- def find_menu(menu, item)
- menu.renderable_items.find { |i| i.item_id == item }
- end
-end
diff --git a/spec/lib/sidebars/groups/super_sidebar_menus/monitor_menu_spec.rb b/spec/lib/sidebars/groups/super_sidebar_menus/monitor_menu_spec.rb
deleted file mode 100644
index 759975856b8..00000000000
--- a/spec/lib/sidebars/groups/super_sidebar_menus/monitor_menu_spec.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Sidebars::Groups::SuperSidebarMenus::MonitorMenu, feature_category: :navigation do
- subject { described_class.new({}) }
-
- let(:items) { subject.instance_variable_get(:@items) }
-
- it 'has title and sprite_icon' do
- expect(subject.title).to eq(s_("Navigation|Monitor"))
- expect(subject.sprite_icon).to eq("monitor")
- end
-
- it 'defines list of NilMenuItem placeholders' do
- expect(items.map(&:class).uniq).to eq([Sidebars::NilMenuItem])
- expect(items.map(&:item_id)).to eq([
- :explore,
- :datasources
- ])
- end
-end
diff --git a/spec/lib/sidebars/groups/super_sidebar_panel_spec.rb b/spec/lib/sidebars/groups/super_sidebar_panel_spec.rb
index c939dd870c4..fe1491a736e 100644
--- a/spec/lib/sidebars/groups/super_sidebar_panel_spec.rb
+++ b/spec/lib/sidebars/groups/super_sidebar_panel_spec.rb
@@ -34,7 +34,6 @@ RSpec.describe Sidebars::Groups::SuperSidebarPanel, feature_category: :navigatio
Sidebars::Groups::SuperSidebarMenus::SecureMenu,
Sidebars::Groups::SuperSidebarMenus::DeployMenu,
Sidebars::Groups::SuperSidebarMenus::OperationsMenu,
- Sidebars::Groups::SuperSidebarMenus::MonitorMenu,
Sidebars::Groups::SuperSidebarMenus::AnalyzeMenu,
Sidebars::UncategorizedMenu,
Sidebars::Groups::Menus::SettingsMenu
diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb
index 1b10a3048c7..e7a5a53c6a0 100644
--- a/spec/models/issue_spec.rb
+++ b/spec/models/issue_spec.rb
@@ -2077,4 +2077,117 @@ RSpec.describe Issue, feature_category: :team_planning do
expect(issue4.linked_items_count).to eq(0)
end
end
+
+ describe '#readable_by?' do
+ let_it_be(:admin_user) { create(:user, :admin) }
+
+ subject { issue_subject.readable_by?(user) }
+
+ context 'when issue belongs directly to a project' do
+ let_it_be_with_reload(:project_issue) { create(:issue, project: reusable_project) }
+ let_it_be(:project_reporter) { create(:user).tap { |u| reusable_project.add_reporter(u) } }
+ let_it_be(:project_guest) { create(:user).tap { |u| reusable_project.add_guest(u) } }
+
+ let(:issue_subject) { project_issue }
+
+ context 'when user is in admin mode', :enable_admin_mode do
+ let(:user) { admin_user }
+
+ it { is_expected.to be_truthy }
+ end
+
+ context 'when user is a reporter' do
+ let(:user) { project_reporter }
+
+ it { is_expected.to be_truthy }
+
+ context 'when issues project feature is not enabled' do
+ before do
+ reusable_project.project_feature.update!(issues_access_level: ProjectFeature::DISABLED)
+ end
+
+ it { is_expected.to be_falsey }
+ end
+
+ context 'when issue is hidden (banned author)' do
+ before do
+ issue_subject.author.ban!
+ end
+
+ it { is_expected.to be_falsey }
+ end
+ end
+
+ context 'when user is a guest' do
+ let(:user) { project_guest }
+
+ context 'when issue is confidential' do
+ before do
+ issue_subject.update!(confidential: true)
+ end
+
+ it { is_expected.to be_falsey }
+
+ context 'when user is assignee of the issue' do
+ before do
+ issue_subject.update!(assignees: [user])
+ end
+
+ it { is_expected.to be_truthy }
+ end
+ end
+ end
+ end
+
+ context 'when issue belongs directly to the group' do
+ let_it_be(:group) { create(:group) }
+ let_it_be_with_reload(:group_issue) { create(:issue, :group_level, namespace: group) }
+ let_it_be(:group_reporter) { create(:user).tap { |u| group.add_reporter(u) } }
+ let_it_be(:group_guest) { create(:user).tap { |u| group.add_guest(u) } }
+
+ let(:issue_subject) { group_issue }
+
+ context 'when user is in admin mode', :enable_admin_mode do
+ let(:user) { admin_user }
+
+ it { is_expected.to be_truthy }
+ end
+
+ context 'when user is a reporter' do
+ let(:user) { group_reporter }
+
+ it { is_expected.to be_truthy }
+
+ context 'when issue is hidden (banned author)' do
+ before do
+ issue_subject.author.ban!
+ end
+
+ it { is_expected.to be_falsey }
+ end
+ end
+
+ context 'when user is a guest' do
+ let(:user) { group_guest }
+
+ it { is_expected.to be_truthy }
+
+ context 'when issue is confidential' do
+ before do
+ issue_subject.update!(confidential: true)
+ end
+
+ it { is_expected.to be_falsey }
+
+ context 'when user is assignee of the issue' do
+ before do
+ issue_subject.update!(assignees: [user])
+ end
+
+ it { is_expected.to be_truthy }
+ end
+ end
+ end
+ end
+ end
end
diff --git a/spec/models/pages/lookup_path_spec.rb b/spec/models/pages/lookup_path_spec.rb
index fdab668c679..08ba823f8fa 100644
--- a/spec/models/pages/lookup_path_spec.rb
+++ b/spec/models/pages/lookup_path_spec.rb
@@ -99,25 +99,6 @@ RSpec.describe Pages::LookupPath, feature_category: :pages do
end
end
end
-
- context 'when deployment were created during migration' do
- before do
- allow(deployment).to receive(:migrated?).and_return(true)
- end
-
- it 'uses deployment from object storage' do
- freeze_time do
- expect(source).to eq(
- type: 'zip',
- path: deployment.file.url(expire_at: 1.day.from_now),
- global_id: "gid://gitlab/PagesDeployment/#{deployment.id}",
- sha256: deployment.file_sha256,
- file_size: deployment.size,
- file_count: deployment.file_count
- )
- end
- end
- end
end
end
diff --git a/spec/models/pages_deployment_spec.rb b/spec/models/pages_deployment_spec.rb
index 916197fe5e9..e74c7ee8612 100644
--- a/spec/models/pages_deployment_spec.rb
+++ b/spec/models/pages_deployment_spec.rb
@@ -28,16 +28,6 @@ RSpec.describe PagesDeployment, feature_category: :pages do
end
end
- describe '.migrated_from_legacy_storage' do
- it 'only returns migrated deployments' do
- migrated_deployment = create_migrated_deployment(project)
- # create one other deployment
- create(:pages_deployment, project: project)
-
- expect(described_class.migrated_from_legacy_storage).to eq([migrated_deployment])
- end
- end
-
context 'with deployments stored locally and remotely' do
before do
stub_pages_object_storage(::Pages::DeploymentUploader)
@@ -132,34 +122,6 @@ RSpec.describe PagesDeployment, feature_category: :pages do
end
end
- describe '#migrated?' do
- it 'returns false for normal deployment' do
- deployment = create(:pages_deployment)
-
- expect(deployment.migrated?).to eq(false)
- end
-
- it 'returns true for migrated deployment' do
- deployment = create_migrated_deployment(project)
-
- expect(deployment.migrated?).to eq(true)
- end
- end
-
- def create_migrated_deployment(project)
- public_path = File.join(project.pages_path, "public")
- FileUtils.mkdir_p(public_path)
- File.open(File.join(project.pages_path, "public/index.html"), "w") do |f|
- f.write("Hello!")
- end
-
- expect(::Pages::MigrateLegacyStorageToDeploymentService.new(project).execute[:status]).to eq(:success)
-
- project.reload.pages_metadatum.pages_deployment
- ensure
- FileUtils.rm_rf(public_path)
- end
-
describe 'default for file_store' do
let(:deployment) do
filepath = Rails.root.join("spec/fixtures/pages.zip")
diff --git a/spec/models/project_pages_metadatum_spec.rb b/spec/models/project_pages_metadatum_spec.rb
deleted file mode 100644
index 31a533e0363..00000000000
--- a/spec/models/project_pages_metadatum_spec.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe ProjectPagesMetadatum do
- describe '.only_on_legacy_storage' do
- it 'returns only deployed records without deployment' do
- create(:project) # without pages deployed
-
- legacy_storage_project = create(:project)
- legacy_storage_project.mark_pages_as_deployed
-
- project_with_deployment = create(:project)
- deployment = create(:pages_deployment, project: project_with_deployment)
- project_with_deployment.mark_pages_as_deployed
- project_with_deployment.update_pages_deployment!(deployment)
-
- expect(described_class.only_on_legacy_storage).to eq([legacy_storage_project.pages_metadatum])
- end
- end
-end
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index cc49661b118..23306e46237 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -5297,12 +5297,6 @@ RSpec.describe Project, factory_default: :keep, feature_category: :groups_and_pr
end
end
- describe '#pages_path' do
- it 'returns a path where pages are stored' do
- expect(project.pages_path).to eq(File.join(Settings.pages.path, project.namespace.full_path, project.path))
- end
- end
-
describe '#migrate_to_hashed_storage!' do
let(:project) { create(:project, :empty_repo, :legacy_storage) }
@@ -5392,12 +5386,6 @@ RSpec.describe Project, factory_default: :keep, feature_category: :groups_and_pr
end
end
- describe '#pages_path' do
- it 'returns a path where pages are stored' do
- expect(project.pages_path).to eq(File.join(Settings.pages.path, project.namespace.full_path, project.path))
- end
- end
-
describe '#migrate_to_hashed_storage!' do
let(:project) { create(:project, :repository, skip_disk_validation: true) }
diff --git a/spec/policies/group_policy_spec.rb b/spec/policies/group_policy_spec.rb
index 4aa18c72c45..cb7884b141e 100644
--- a/spec/policies/group_policy_spec.rb
+++ b/spec/policies/group_policy_spec.rb
@@ -1101,73 +1101,6 @@ RSpec.describe GroupPolicy, feature_category: :system_access do
end
end
- describe 'observability' do
- let(:allowed_admin) { be_allowed(:read_observability) && be_allowed(:admin_observability) }
- let(:allowed_read) { be_allowed(:read_observability) && be_disallowed(:admin_observability) }
- let(:disallowed) { be_disallowed(:read_observability) && be_disallowed(:admin_observability) }
-
- # rubocop:disable Layout/LineLength
- where(:feature_enabled, :admin_matcher, :owner_matcher, :maintainer_matcher, :developer_matcher, :reporter_matcher, :guest_matcher, :non_member_matcher, :anonymous_matcher) do
- false | ref(:disallowed) | ref(:disallowed) | ref(:disallowed) | ref(:disallowed) | ref(:disallowed) | ref(:disallowed) | ref(:disallowed) | ref(:disallowed)
- true | ref(:allowed_admin) | ref(:allowed_admin) | ref(:allowed_admin) | ref(:allowed_read) | ref(:disallowed) | ref(:disallowed) | ref(:disallowed) | ref(:disallowed)
- end
- # rubocop:enable Layout/LineLength
-
- with_them do
- before do
- stub_feature_flags(observability_group_tab: feature_enabled)
- end
-
- context 'admin', :enable_admin_mode do
- let(:current_user) { admin }
-
- it { is_expected.to admin_matcher }
- end
-
- context 'owner' do
- let(:current_user) { owner }
-
- it { is_expected.to owner_matcher }
- end
-
- context 'maintainer' do
- let(:current_user) { maintainer }
-
- it { is_expected.to maintainer_matcher }
- end
-
- context 'developer' do
- let(:current_user) { developer }
-
- it { is_expected.to developer_matcher }
- end
-
- context 'reporter' do
- let(:current_user) { reporter }
-
- it { is_expected.to reporter_matcher }
- end
-
- context 'with guest' do
- let(:current_user) { guest }
-
- it { is_expected.to guest_matcher }
- end
-
- context 'with non member' do
- let(:current_user) { create(:user) }
-
- it { is_expected.to non_member_matcher }
- end
-
- context 'with anonymous' do
- let(:current_user) { nil }
-
- it { is_expected.to anonymous_matcher }
- end
- end
- end
-
describe 'dependency proxy' do
RSpec.shared_examples 'disabling admin_package feature flag' do
before do
diff --git a/spec/requests/groups/observability_controller_spec.rb b/spec/requests/groups/observability_controller_spec.rb
deleted file mode 100644
index 247535bc990..00000000000
--- a/spec/requests/groups/observability_controller_spec.rb
+++ /dev/null
@@ -1,99 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Groups::ObservabilityController, feature_category: :tracing do
- let_it_be(:group) { create(:group) }
- let_it_be(:user) { create(:user) }
-
- let(:observability_url) { Gitlab::Observability.observability_url }
- let(:path) { nil }
- let(:expected_observability_path) { nil }
-
- shared_examples 'observability route request' do
- subject do
- get path
- response
- end
-
- it_behaves_like 'observability csp policy' do
- before_all do
- group.add_developer(user)
- end
-
- let(:tested_path) { path }
- end
-
- context 'when user is not authenticated' do
- it 'returns 404' do
- expect(subject).to have_gitlab_http_status(:not_found)
- end
- end
-
- context 'when user is a guest' do
- before do
- sign_in(user)
- end
-
- it 'returns 404' do
- expect(subject).to have_gitlab_http_status(:not_found)
- end
- end
-
- context 'when user has the correct permissions' do
- before do
- sign_in(user)
- set_permissions
- end
-
- context 'when observability url is missing' do
- before do
- allow(Gitlab::Observability).to receive(:observability_url).and_return("")
- end
-
- it 'returns 404' do
- expect(subject).to have_gitlab_http_status(:not_found)
- end
- end
-
- it 'returns 200' do
- expect(subject).to have_gitlab_http_status(:ok)
- end
-
- it 'renders the proper layout' do
- expect(subject).to render_template("layouts/group")
- expect(subject).to render_template("layouts/fullscreen")
- expect(subject).not_to render_template('layouts/nav/breadcrumbs')
- expect(subject).to render_template("nav/sidebar/_group")
- expect(subject).to render_template("groups/observability/observability")
- end
-
- it 'renders the js-observability-app element correctly' do
- element = Nokogiri::HTML.parse(subject.body).at_css('#js-observability-app')
- expect(element.attributes['data-observability-iframe-src'].value).to eq(expected_observability_path)
- end
- end
- end
-
- describe 'GET #explore' do
- let(:path) { group_observability_explore_path(group) }
- let(:expected_observability_path) { "#{observability_url}/-/#{group.id}/explore" }
-
- it_behaves_like 'observability route request' do
- let(:set_permissions) do
- group.add_developer(user)
- end
- end
- end
-
- describe 'GET #datasources' do
- let(:path) { group_observability_datasources_path(group) }
- let(:expected_observability_path) { "#{observability_url}/-/#{group.id}/datasources" }
-
- it_behaves_like 'observability route request' do
- let(:set_permissions) do
- group.add_maintainer(user)
- end
- end
- end
-end
diff --git a/spec/requests/projects/issues_controller_spec.rb b/spec/requests/projects/issues_controller_spec.rb
index 1ae65939c86..6c9b1966149 100644
--- a/spec/requests/projects/issues_controller_spec.rb
+++ b/spec/requests/projects/issues_controller_spec.rb
@@ -14,35 +14,12 @@ RSpec.describe Projects::IssuesController, feature_category: :team_planning do
let_it_be(:user) { create(:user) }
end
- describe 'GET #new' do
- include_context 'group project issue'
-
- before do
- group.add_developer(user)
- login_as(user)
- end
-
- it_behaves_like "observability csp policy", described_class do
- let(:tested_path) do
- new_project_issue_path(project)
- end
- end
- end
-
describe 'GET #show' do
before do
group.add_developer(user)
login_as(user)
end
- it_behaves_like "observability csp policy", described_class do
- include_context 'group project issue'
-
- let(:tested_path) do
- project_issue_path(project, issue)
- end
- end
-
describe 'incident tabs' do
let_it_be(:incident) { create(:incident, project: project) }
diff --git a/spec/requests/projects/merge_requests/creations_spec.rb b/spec/requests/projects/merge_requests/creations_spec.rb
index 8f55aa90bee..41246d419a1 100644
--- a/spec/requests/projects/merge_requests/creations_spec.rb
+++ b/spec/requests/projects/merge_requests/creations_spec.rb
@@ -76,17 +76,5 @@ RSpec.describe 'merge requests creations', feature_category: :code_review_workfl
end
end
end
-
- it_behaves_like "observability csp policy", Projects::MergeRequests::CreationsController do
- let(:tested_path) do
- project_new_merge_request_path(project, merge_request: {
- title: 'Some feature',
- source_branch: 'fix',
- target_branch: 'feature',
- target_project: project,
- source_project: project
- })
- end
- end
end
end
diff --git a/spec/requests/projects/merge_requests_controller_spec.rb b/spec/requests/projects/merge_requests_controller_spec.rb
index e6a281d8d59..e549913ccc3 100644
--- a/spec/requests/projects/merge_requests_controller_spec.rb
+++ b/spec/requests/projects/merge_requests_controller_spec.rb
@@ -14,19 +14,6 @@ RSpec.describe Projects::MergeRequestsController, feature_category: :source_code
let(:merge_request) { create :merge_request, source_project: project, author: user }
- context 'when logged in' do
- before do
- group.add_developer(user)
- login_as(user)
- end
-
- it_behaves_like "observability csp policy", described_class do
- let(:tested_path) do
- project_merge_request_path(project, merge_request)
- end
- end
- end
-
context 'when the author of the merge request is banned', feature_category: :insider_threat do
let_it_be(:user) { create(:user, :banned) }
diff --git a/spec/routing/group_routing_spec.rb b/spec/routing/group_routing_spec.rb
index 3ba7d5ad871..6fab711d05a 100644
--- a/spec/routing/group_routing_spec.rb
+++ b/spec/routing/group_routing_spec.rb
@@ -72,14 +72,6 @@ RSpec.shared_examples 'groups routing' do
expect(get("groups/#{group_path}/-/harbor/repositories/test/artifacts/test/tags")).to route_to('groups/harbor/tags#index', group_id: group_path, repository_id: 'test', artifact_id: 'test')
end
- it 'routes to the observability controller explore method' do
- expect(get("groups/#{group_path}/-/observability/explore")).to route_to('groups/observability#explore', group_id: group_path)
- end
-
- it 'routes to the observability controller datasources method' do
- expect(get("groups/#{group_path}/-/observability/datasources")).to route_to('groups/observability#datasources', group_id: group_path)
- end
-
it 'routes to the usage quotas controller' do
expect(get("groups/#{group_path}/-/usage_quotas")).to route_to("groups/usage_quotas#index", group_id: group_path)
end
diff --git a/spec/services/pages/migrate_from_legacy_storage_service_spec.rb b/spec/services/pages/migrate_from_legacy_storage_service_spec.rb
deleted file mode 100644
index 48690a035f5..00000000000
--- a/spec/services/pages/migrate_from_legacy_storage_service_spec.rb
+++ /dev/null
@@ -1,137 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Pages::MigrateFromLegacyStorageService, feature_category: :pages do
- let(:batch_size) { 10 }
- let(:mark_projects_as_not_deployed) { false }
- let(:service) { described_class.new(Rails.logger, ignore_invalid_entries: false, mark_projects_as_not_deployed: mark_projects_as_not_deployed) }
-
- shared_examples "migrates projects properly" do
- it 'does not try to migrate pages if pages are not deployed' do
- expect(::Pages::MigrateLegacyStorageToDeploymentService).not_to receive(:new)
-
- is_expected.to eq(migrated: 0, errored: 0)
- end
-
- context 'when pages are marked as deployed' do
- let(:project) { create(:project) }
-
- before do
- project.mark_pages_as_deployed
- end
-
- context 'when pages directory does not exist' do
- context 'when mark_projects_as_not_deployed is set' do
- let(:mark_projects_as_not_deployed) { true }
-
- it 'counts project as migrated' do
- expect_next_instance_of(::Pages::MigrateLegacyStorageToDeploymentService, project, ignore_invalid_entries: false, mark_projects_as_not_deployed: true) do |service|
- expect(service).to receive(:execute).and_call_original
- end
-
- is_expected.to eq(migrated: 1, errored: 0)
- end
- end
-
- it 'counts project as errored' do
- expect_next_instance_of(::Pages::MigrateLegacyStorageToDeploymentService, project, ignore_invalid_entries: false, mark_projects_as_not_deployed: false) do |service|
- expect(service).to receive(:execute).and_call_original
- end
-
- is_expected.to eq(migrated: 0, errored: 1)
- end
- end
-
- context 'when pages directory exists on disk' do
- before do
- FileUtils.mkdir_p File.join(project.pages_path, "public")
- File.open(File.join(project.pages_path, "public/index.html"), "w") do |f|
- f.write("Hello!")
- end
- end
-
- it 'migrates pages projects without deployments' do
- expect_next_instance_of(::Pages::MigrateLegacyStorageToDeploymentService, project, ignore_invalid_entries: false, mark_projects_as_not_deployed: false) do |service|
- expect(service).to receive(:execute).and_call_original
- end
-
- expect(project.pages_metadatum.reload.pages_deployment).to eq(nil)
- expect(subject).to eq(migrated: 1, errored: 0)
- expect(project.pages_metadatum.reload.pages_deployment).to be_present
- end
-
- context 'when deployed already exists for the project' do
- before do
- deployment = create(:pages_deployment, project: project)
- project.set_first_pages_deployment!(deployment)
- end
-
- it 'does not try to migrate project' do
- expect(::Pages::MigrateLegacyStorageToDeploymentService).not_to receive(:new)
-
- is_expected.to eq(migrated: 0, errored: 0)
- end
- end
- end
- end
- end
-
- describe '#execute_with_threads' do
- subject { service.execute_with_threads(threads: 3, batch_size: batch_size) }
-
- include_examples "migrates projects properly"
-
- context 'when there is work for multiple threads' do
- let(:batch_size) { 2 } # override to force usage of multiple threads
-
- it 'uses multiple threads' do
- projects = create_list(:project, 20)
- projects.each do |project|
- project.mark_pages_as_deployed
-
- FileUtils.mkdir_p File.join(project.pages_path, "public")
- File.open(File.join(project.pages_path, "public/index.html"), "w") do |f|
- f.write("Hello!")
- end
- end
-
- threads = Concurrent::Set.new
-
- expect(service).to receive(:migrate_project).exactly(20).times.and_wrap_original do |m, *args|
- threads.add(Thread.current)
-
- # sleep to be 100% certain that once thread can't consume all the queue
- # it works without it, but I want to avoid making this test flaky
- sleep(0.01)
-
- m.call(*args)
- end
-
- is_expected.to eq(migrated: 20, errored: 0)
- expect(threads.length).to eq(3)
- end
- end
- end
-
- describe "#execute_for_batch" do
- subject { service.execute_for_batch(Project.ids) }
-
- include_examples "migrates projects properly"
-
- it 'only tries to migrate projects with passed ids' do
- projects = create_list(:project, 5)
-
- projects.each(&:mark_pages_as_deployed)
- projects_to_migrate = projects.first(3)
-
- projects_to_migrate.each do |project|
- expect_next_instance_of(::Pages::MigrateLegacyStorageToDeploymentService, project, ignore_invalid_entries: false, mark_projects_as_not_deployed: false) do |service|
- expect(service).to receive(:execute).and_call_original
- end
- end
-
- expect(service.execute_for_batch(projects_to_migrate.pluck(:id))).to eq(migrated: 0, errored: 3)
- end
- end
-end
diff --git a/spec/services/pages/migrate_legacy_storage_to_deployment_service_spec.rb b/spec/services/pages/migrate_legacy_storage_to_deployment_service_spec.rb
deleted file mode 100644
index e1cce2c87eb..00000000000
--- a/spec/services/pages/migrate_legacy_storage_to_deployment_service_spec.rb
+++ /dev/null
@@ -1,118 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Pages::MigrateLegacyStorageToDeploymentService, feature_category: :pages do
- let(:project) { create(:project, :repository) }
- let(:service) { described_class.new(project) }
-
- it 'calls ::Pages::ZipDirectoryService' do
- expect_next_instance_of(::Pages::ZipDirectoryService, project.pages_path, ignore_invalid_entries: true) do |zip_service|
- expect(zip_service).to receive(:execute).and_call_original
- end
-
- expect(described_class.new(project, ignore_invalid_entries: true).execute[:status]).to eq(:error)
- end
-
- context 'when mark_projects_as_not_deployed is passed' do
- let(:service) { described_class.new(project, mark_projects_as_not_deployed: true) }
-
- it 'marks pages as not deployed if public directory is absent and invalid entries are ignored' do
- project.mark_pages_as_deployed
- expect(project.pages_metadatum.reload.deployed).to eq(true)
-
- expect(service.execute).to eq(
- status: :success,
- message: "Archive not created. Missing public directory in #{project.pages_path}? Marked project as not deployed"
- )
-
- expect(project.pages_metadatum.reload.deployed).to eq(false)
- end
-
- it 'does not mark pages as not deployed if public directory is absent but pages_deployment exists' do
- deployment = create(:pages_deployment, project: project)
- project.update_pages_deployment!(deployment)
- project.mark_pages_as_deployed
- expect(project.pages_metadatum.reload.deployed).to eq(true)
-
- expect(service.execute).to eq(
- status: :success,
- message: "Archive not created. Missing public directory in #{project.pages_path}? Marked project as not deployed"
- )
-
- expect(project.pages_metadatum.reload.deployed).to eq(true)
- end
- end
-
- it 'does not mark pages as not deployed if public directory is absent but invalid entries are not ignored' do
- project.mark_pages_as_deployed
-
- expect(project.pages_metadatum.reload.deployed).to eq(true)
-
- expect(service.execute).to eq(
- status: :error,
- message: "Archive not created. Missing public directory in #{project.pages_path}"
- )
-
- expect(project.pages_metadatum.reload.deployed).to eq(true)
- end
-
- it 'removes pages archive when can not save deployment' do
- archive = fixture_file_upload("spec/fixtures/pages.zip")
- expect_next_instance_of(::Pages::ZipDirectoryService) do |zip_service|
- expect(zip_service).to receive(:execute).and_return(
- status: :success, archive_path: archive.path, entries_count: 3
- )
- end
-
- expect_next_instance_of(PagesDeployment) do |deployment|
- expect(deployment).to receive(:save!).and_raise("Something")
- end
-
- expect do
- service.execute
- end.to raise_error("Something")
-
- expect(File.exist?(archive.path)).to eq(false)
- end
-
- context 'when pages site is deployed to legacy storage' do
- before do
- FileUtils.mkdir_p File.join(project.pages_path, "public")
- File.open(File.join(project.pages_path, "public/index.html"), "w") do |f|
- f.write("Hello!")
- end
- end
-
- it 'creates pages deployment' do
- expect do
- expect(described_class.new(project).execute).to eq(status: :success)
- end.to change { project.reload.pages_deployments.count }.by(1)
-
- deployment = project.pages_metadatum.pages_deployment
-
- Zip::File.open(deployment.file.path) do |zip_file|
- expect(zip_file.glob("public").first.ftype).to eq(:directory)
- expect(zip_file.glob("public/index.html").first.get_input_stream.read).to eq("Hello!")
- end
-
- expect(deployment.file_count).to eq(2)
- expect(deployment.file_sha256).to eq(Digest::SHA256.file(deployment.file.path).hexdigest)
- end
-
- it 'removes tmp pages archive' do
- described_class.new(project).execute
-
- expect(File.exist?(File.join(project.pages_path, '@migrated.zip'))).to eq(false)
- end
-
- it 'does not change pages deployment if it is set' do
- old_deployment = create(:pages_deployment, project: project)
- project.update_pages_deployment!(old_deployment)
-
- expect do
- described_class.new(project).execute
- end.not_to change { project.pages_metadatum.reload.pages_deployment_id }.from(old_deployment.id)
- end
- end
-end
diff --git a/spec/services/pages/zip_directory_service_spec.rb b/spec/services/pages/zip_directory_service_spec.rb
deleted file mode 100644
index 4917bc65a02..00000000000
--- a/spec/services/pages/zip_directory_service_spec.rb
+++ /dev/null
@@ -1,280 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Pages::ZipDirectoryService, feature_category: :pages do
- around do |example|
- Dir.mktmpdir do |dir|
- @work_dir = dir
- example.run
- end
- end
-
- let(:ignore_invalid_entries) { false }
-
- let(:service_directory) { @work_dir }
-
- let(:service) do
- described_class.new(service_directory, ignore_invalid_entries: ignore_invalid_entries)
- end
-
- let(:result) do
- service.execute
- end
-
- let(:status) { result[:status] }
- let(:message) { result[:message] }
- let(:archive) { result[:archive_path] }
- let(:entries_count) { result[:entries_count] }
-
- it 'returns true if ZIP64 is enabled' do
- expect(::Zip.write_zip64_support).to be true
- end
-
- shared_examples 'handles invalid public directory' do
- it 'returns success' do
- expect(status).to eq(:success)
- expect(archive).to be_nil
- expect(entries_count).to be_nil
- end
- end
-
- context "when work directory doesn't exist" do
- let(:service_directory) { "/tmp/not/existing/dir" }
-
- include_examples 'handles invalid public directory'
- end
-
- context 'when public directory is absent' do
- include_examples 'handles invalid public directory'
- end
-
- context 'when public directory is a symlink' do
- before do
- create_dir('target')
- create_file('./target/index.html', 'hello')
- create_link("public", "./target")
- end
-
- include_examples 'handles invalid public directory'
- end
-
- context 'when there is a public directory' do
- before do
- create_dir('public')
- end
-
- it 'creates the file next the public directory' do
- expect(archive).to eq(File.join(@work_dir, "@migrated.zip"))
- end
-
- it 'includes public directory' do
- with_zip_file do |zip_file|
- entry = zip_file.get_entry("public/")
- expect(entry.ftype).to eq(:directory)
- end
- end
-
- it 'returns number of entries' do
- create_file("public/index.html", "hello")
- create_link("public/link.html", "./index.html")
- expect(entries_count).to eq(3) # + 'public' directory
- end
-
- it 'removes the old file if it exists' do
- # simulate the old run
- described_class.new(@work_dir).execute
-
- with_zip_file do |zip_file|
- expect(zip_file.entries.count).to eq(1)
- end
- end
-
- it 'ignores other top level files and directories' do
- create_file("top_level.html", "hello")
- create_dir("public2")
-
- with_zip_file do |zip_file|
- expect { zip_file.get_entry("top_level.html") }.to raise_error(Errno::ENOENT)
- expect { zip_file.get_entry("public2/") }.to raise_error(Errno::ENOENT)
- end
- end
-
- it 'includes index.html file' do
- create_file("public/index.html", "Hello!")
-
- with_zip_file do |zip_file|
- entry = zip_file.get_entry("public/index.html")
- expect(zip_file.read(entry)).to eq("Hello!")
- end
- end
-
- it 'includes hidden file' do
- create_file("public/.hidden.html", "Hello!")
-
- with_zip_file do |zip_file|
- entry = zip_file.get_entry("public/.hidden.html")
- expect(zip_file.read(entry)).to eq("Hello!")
- end
- end
-
- it 'includes nested directories and files' do
- create_dir("public/nested")
- create_dir("public/nested/nested2")
- create_file("public/nested/nested2/nested.html", "Hello nested")
-
- with_zip_file do |zip_file|
- entry = zip_file.get_entry("public/nested")
- expect(entry.ftype).to eq(:directory)
-
- entry = zip_file.get_entry("public/nested/nested2")
- expect(entry.ftype).to eq(:directory)
-
- entry = zip_file.get_entry("public/nested/nested2/nested.html")
- expect(zip_file.read(entry)).to eq("Hello nested")
- end
- end
-
- it 'adds a valid symlink' do
- create_file("public/target.html", "hello")
- create_link("public/link.html", "./target.html")
-
- with_zip_file do |zip_file|
- entry = zip_file.get_entry("public/link.html")
- expect(entry.ftype).to eq(:symlink)
- expect(zip_file.read(entry)).to eq("./target.html")
- end
- end
-
- shared_examples "raises or ignores file" do |raised_exception, file|
- it 'raises error' do
- expect do
- result
- end.to raise_error(raised_exception)
- end
-
- context 'when errors are ignored' do
- let(:ignore_invalid_entries) { true }
-
- it 'does not create entry' do
- with_zip_file do |zip_file|
- expect { zip_file.get_entry(file) }.to raise_error(Errno::ENOENT)
- end
- end
- end
- end
-
- context 'when symlink points outside of public directory' do
- before do
- create_file("target.html", "hello")
- create_link("public/link.html", "../target.html")
- end
-
- include_examples "raises or ignores file", described_class::InvalidEntryError, "public/link.html"
- end
-
- context 'when target of the symlink is absent' do
- before do
- create_link("public/link.html", "./target.html")
- end
-
- include_examples "raises or ignores file", Errno::ENOENT, "public/link.html"
- end
-
- context 'when targets itself' do
- before do
- create_link("public/link.html", "./link.html")
- end
-
- include_examples "raises or ignores file", Errno::ELOOP, "public/link.html"
- end
-
- context 'when symlink is absolute and points to outside of directory' do
- before do
- target = File.join(@work_dir, "target")
- FileUtils.touch(target)
-
- create_link("public/link.html", target)
- end
-
- include_examples "raises or ignores file", described_class::InvalidEntryError, "public/link.html"
- end
-
- context 'when entry has unknown ftype' do
- before do
- file = create_file("public/index.html", "hello")
-
- allow(File).to receive(:lstat).and_call_original
- expect(File).to receive(:lstat).with(file) { double("lstat", ftype: "unknown") }
- end
-
- include_examples "raises or ignores file", described_class::InvalidEntryError, "public/index.html"
- end
-
- it "includes raw symlink if it's target is a valid directory" do
- create_dir("public/target")
- create_file("public/target/index.html", "hello")
- create_link("public/link", "./target")
-
- with_zip_file do |zip_file|
- expect(zip_file.entries.count).to eq(4) # /public and 3 created above
-
- entry = zip_file.get_entry("public/link")
- expect(entry.ftype).to eq(:symlink)
- expect(zip_file.read(entry)).to eq("./target")
- end
- end
- end
-
- context "validating fixtures pages archives" do
- using RSpec::Parameterized::TableSyntax
-
- where(:fixture_path) do
- ["spec/fixtures/pages.zip", "spec/fixtures/pages_non_writeable.zip"]
- end
-
- with_them do
- let(:full_fixture_path) { Rails.root.join(fixture_path) }
-
- it 'a created archives contains exactly the same entries' do
- SafeZip::Extract.new(full_fixture_path).extract(directories: ['public'], to: @work_dir)
-
- with_zip_file do |created_archive|
- Zip::File.open(full_fixture_path) do |original_archive|
- original_archive.entries do |original_entry|
- created_entry = created_archive.get_entry(original_entry.name)
-
- expect(created_entry.name).to eq(original_entry.name)
- expect(created_entry.ftype).to eq(original_entry.ftype)
- expect(created_archive.read(created_entry)).to eq(original_archive.read(original_entry))
- end
- end
- end
- end
- end
- end
-
- def create_file(name, content)
- file_path = File.join(@work_dir, name)
-
- File.open(file_path, "w") do |f|
- f.write(content)
- end
-
- file_path
- end
-
- def create_dir(dir)
- Dir.mkdir(File.join(@work_dir, dir))
- end
-
- def create_link(new_name, target)
- File.symlink(target, File.join(@work_dir, new_name))
- end
-
- def with_zip_file
- Zip::File.open(archive) do |zip_file|
- yield zip_file
- end
- end
-end
diff --git a/spec/services/todo_service_spec.rb b/spec/services/todo_service_spec.rb
index 0888c27aab2..0a6b11046f5 100644
--- a/spec/services/todo_service_spec.rb
+++ b/spec/services/todo_service_spec.rb
@@ -5,6 +5,7 @@ require 'spec_helper'
RSpec.describe TodoService, feature_category: :team_planning do
include AfterNextHelpers
+ let_it_be(:group) { create(:group) }
let_it_be(:project) { create(:project, :repository) }
let_it_be(:author) { create(:user) }
let_it_be(:assignee) { create(:user) }
@@ -657,11 +658,27 @@ RSpec.describe TodoService, feature_category: :team_planning do
end
describe '#mark_todo' do
- it 'creates a todo from a issue' do
+ it 'creates a todo from an issue' do
service.mark_todo(unassigned_issue, author)
should_create_todo(user: author, target: unassigned_issue, action: Todo::MARKED)
end
+
+ context 'when issue belongs to a group' do
+ it 'creates a todo from an issue' do
+ group_issue = create(:issue, :group_level, namespace: group)
+ service.mark_todo(group_issue, group_issue.author)
+
+ should_create_todo(
+ user: group_issue.author,
+ author: group_issue.author,
+ target: group_issue,
+ action: Todo::MARKED,
+ project: nil,
+ group: group
+ )
+ end
+ end
end
describe '#todo_exists?' do
@@ -726,6 +743,22 @@ RSpec.describe TodoService, feature_category: :team_planning do
should_create_todo(user: author, target: work_item, action: Todo::MARKED)
end
+
+ context 'when work item belongs to a group' do
+ it 'creates a todo from a work item' do
+ group_work_item = create(:work_item, :group_level, namespace: group)
+ service.mark_todo(group_work_item, group_work_item.author)
+
+ should_create_todo(
+ user: group_work_item.author,
+ author: group_work_item.author,
+ target: group_work_item,
+ action: Todo::MARKED,
+ project: nil,
+ group: group
+ )
+ end
+ end
end
describe '#todo_exists?' do
diff --git a/spec/support/ability_check_todo.yml b/spec/support/ability_check_todo.yml
index eafd595b137..a317f49ea94 100644
--- a/spec/support/ability_check_todo.yml
+++ b/spec/support/ability_check_todo.yml
@@ -66,8 +66,6 @@ ProjectPolicy:
- create_test_case
- read_group_saml_identity
UserPolicy:
-- admin_observability
- admin_terraform_state
-- read_observability
# Permanent excludes (please provide a reason):
diff --git a/spec/support/helpers/navbar_structure_helper.rb b/spec/support/helpers/navbar_structure_helper.rb
index 9a6af5fb8ae..fe39968b002 100644
--- a/spec/support/helpers/navbar_structure_helper.rb
+++ b/spec/support/helpers/navbar_structure_helper.rb
@@ -85,19 +85,6 @@ module NavbarStructureHelper
)
end
- def insert_observability_nav
- insert_after_nav_item(
- _('Kubernetes'),
- new_nav_item: {
- nav_item: _('Observability'),
- nav_sub_items: [
- _('Explore telemetry data'),
- _('Data sources')
- ]
- }
- )
- end
-
def insert_infrastructure_google_cloud_nav
insert_after_sub_nav_item(
s_('Terraform|Terraform states'),
diff --git a/spec/support/rspec_order_todo.yml b/spec/support/rspec_order_todo.yml
index 9512ff1a057..a93ed7c1fec 100644
--- a/spec/support/rspec_order_todo.yml
+++ b/spec/support/rspec_order_todo.yml
@@ -9354,8 +9354,6 @@
- './spec/services/pages_domains/create_acme_order_service_spec.rb'
- './spec/services/pages_domains/obtain_lets_encrypt_certificate_service_spec.rb'
- './spec/services/pages_domains/retry_acme_order_service_spec.rb'
-- './spec/services/pages/migrate_from_legacy_storage_service_spec.rb'
-- './spec/services/pages/migrate_legacy_storage_to_deployment_service_spec.rb'
- './spec/services/pages/zip_directory_service_spec.rb'
- './spec/services/personal_access_tokens/create_service_spec.rb'
- './spec/services/personal_access_tokens/last_used_service_spec.rb'
diff --git a/spec/support/shared_examples/observability/embed_observabilities_examples.rb b/spec/support/shared_examples/observability/embed_observabilities_examples.rb
deleted file mode 100644
index c8d4e9e0d7e..00000000000
--- a/spec/support/shared_examples/observability/embed_observabilities_examples.rb
+++ /dev/null
@@ -1,61 +0,0 @@
-# frozen_string_literal: true
-
-RSpec.shared_examples 'embeds observability' do
- it 'renders iframe in description' do
- page.within('.description') do
- expect_observability_iframe(page.html)
- end
- end
-
- it 'renders iframe in comment' do
- expect(page).not_to have_css('.note-text')
-
- page.within('.js-main-target-form') do
- fill_in('note[note]', with: observable_url)
- click_button('Comment')
- end
-
- wait_for_requests
-
- page.within('.note-text') do
- expect_observability_iframe(page.html)
- end
- end
-end
-
-RSpec.shared_examples 'does not embed observability' do
- it 'does not render iframe in description' do
- page.within('.description') do
- expect_observability_iframe(page.html, to_be_nil: true)
- end
- end
-
- it 'does not render iframe in comment' do
- expect(page).not_to have_css('.note-text')
-
- page.within('.js-main-target-form') do
- fill_in('note[note]', with: observable_url)
- click_button('Comment')
- end
-
- wait_for_requests
-
- page.within('.note-text') do
- expect_observability_iframe(page.html, to_be_nil: true)
- end
- end
-end
-
-def expect_observability_iframe(html, to_be_nil: false)
- iframe = Nokogiri::HTML.parse(html).at_css('#observability-ui-iframe')
-
- expect(html).to include(observable_url)
-
- if to_be_nil
- expect(iframe).to be_nil
- else
- expect(iframe).not_to be_nil
- iframe_src = "#{expected_observable_url}&theme=light&username=#{user.username}&kiosk=inline-embed"
- expect(iframe.attributes['src'].value).to eq(iframe_src)
- end
-end
diff --git a/spec/views/groups/observability/observability.html.haml_spec.rb b/spec/views/groups/observability/observability.html.haml_spec.rb
deleted file mode 100644
index 0561737cb39..00000000000
--- a/spec/views/groups/observability/observability.html.haml_spec.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe 'groups/observability/observability.html.haml' do
- let(:iframe_url) { "foo.test" }
-
- before do
- allow(view).to receive(:observability_iframe_src).and_return(iframe_url)
- end
-
- it 'renders as expected' do
- render
- page = Capybara.string(rendered)
- div = page.find('#js-observability-app')
- expect(div['data-observability-iframe-src']).to eq(iframe_url)
- end
-end