diff --git a/app/assets/javascripts/projects/settings/branch_rules/components/view/protection.vue b/app/assets/javascripts/projects/settings/branch_rules/components/view/protection.vue index 32d537e61ccbe0507a5e2c76172494a1a877a1c6..be931d3610faffcedeac74fa37da7741f7e0be6f 100644 --- a/app/assets/javascripts/projects/settings/branch_rules/components/view/protection.vue +++ b/app/assets/javascripts/projects/settings/branch_rules/components/view/protection.vue @@ -131,7 +131,9 @@ export default { @click="$emit('edit')" >{{ __('Edit') }} </gl-button> - <gl-link v-else :href="headerLinkHref">{{ headerLinkTitle }}</gl-link> + <gl-link v-else-if="headerLinkHref && headerLinkTitle" :href="headerLinkHref">{{ + headerLinkTitle + }}</gl-link> </template> <span v-if="showEmptyState && !$scopedSlots.content" diff --git a/ee/spec/frontend/audit_events/components/stream/__snapshots__/stream_item_spec.js.snap b/ee/spec/frontend/audit_events/components/stream/__snapshots__/stream_item_spec.js.snap index 98c05d4b79c5680bb243d806601744e7dd096e20..0589dd33d2a1ff3fb3f995d263dcff26f473d974 100644 --- a/ee/spec/frontend/audit_events/components/stream/__snapshots__/stream_item_spec.js.snap +++ b/ee/spec/frontend/audit_events/components/stream/__snapshots__/stream_item_spec.js.snap @@ -9,7 +9,7 @@ exports[`StreamItem Group http StreamItem when an item has event filters renders <a class="gl-link" href="/help/user/compliance/audit_event_streaming#update-event-filters" - rel="noopener" + rel="noopener noreferrer" target="_blank" > What are filters? @@ -26,7 +26,7 @@ exports[`StreamItem Group http StreamItem when an item has namespace filters ren <a class="gl-link" href="/help/user/compliance/audit_event_streaming#update-event-filters" - rel="noopener" + rel="noopener noreferrer" target="_blank" > What are filters? diff --git a/ee/spec/frontend/compliance_dashboard/components/frameworks_report/edit_framework/components/projects_section_spec.js b/ee/spec/frontend/compliance_dashboard/components/frameworks_report/edit_framework/components/projects_section_spec.js index 072639a320417378f7b70e6b99a9df7d68fc428f..03971cd633064139419099012f3083252521c2f4 100644 --- a/ee/spec/frontend/compliance_dashboard/components/frameworks_report/edit_framework/components/projects_section_spec.js +++ b/ee/spec/frontend/compliance_dashboard/components/frameworks_report/edit_framework/components/projects_section_spec.js @@ -80,7 +80,7 @@ describe('Projects section', () => { }); it('renders correct atrributes for the info link', () => { - expect(findLink().attributes('to')).toBe('/projects'); + expect(findLink().props('to')).toBe('/projects'); expect(findLink().attributes('href')).toBe('/projects'); }); }); diff --git a/ee/spec/frontend/pages/admin/ai/duo_self_hosted/self_hosted_models/self_hosted_models_table_spec.js b/ee/spec/frontend/pages/admin/ai/duo_self_hosted/self_hosted_models/self_hosted_models_table_spec.js index e4d69980ade3fee9ab8c30c3741caa1d1cdb30a8..8ef63a0f7ae48dd5d68308d35ced08ad253ef9f1 100644 --- a/ee/spec/frontend/pages/admin/ai/duo_self_hosted/self_hosted_models/self_hosted_models_table_spec.js +++ b/ee/spec/frontend/pages/admin/ai/duo_self_hosted/self_hosted_models/self_hosted_models_table_spec.js @@ -184,7 +184,7 @@ describe('SelfHostedModelsTable', () => { }); it('renders a link to create a new self-hosted model', () => { - expect(findEmptyStateLink().attributes('to')).toBe('new'); + expect(findEmptyStateLink().props('to')).toBe('new'); }); }); diff --git a/package.json b/package.json index 2f74fe391e4761cb6d40e6a6d3128fe79ea68846..4cdfff6649de68f64b7a6135e18a0479f08469e9 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "@gitlab/fonts": "^1.3.0", "@gitlab/query-language-rust": "0.4.2", "@gitlab/svgs": "3.123.0", - "@gitlab/ui": "110.1.0", + "@gitlab/ui": "111.0.0", "@gitlab/vue-router-vue3": "npm:vue-router@4.5.0", "@gitlab/vuex-vue3": "npm:vuex@4.1.0", "@gitlab/web-ide": "^0.0.1-dev-20250309164831", diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb index 542bc386f2a58ec4a51cc82984f410b7f678f2bd..09f94da688d68f81f6f9b6137132e816b6fcbf17 100644 --- a/spec/features/projects/jobs_spec.rb +++ b/spec/features/projects/jobs_spec.rb @@ -659,8 +659,8 @@ context 'when deployment does not have a deployable' do let!(:second_deployment) { create(:deployment, :success, environment: environment, deployable: nil) } - it 'has an empty href' do - expect(find_by_testid('job-deployment-link')['href']).to be_empty + it 'has a href of #' do + expect(page).to have_selector('[data-testid="job-deployment-link"][href="#"]') end end end diff --git a/spec/frontend/ci/jobs_mock_data.js b/spec/frontend/ci/jobs_mock_data.js index 39cf99595ac9c85b4eb3d3db589352c9289f706a..e7cb72f6057249c69a54ca96f5981266b58b70c4 100644 --- a/spec/frontend/ci/jobs_mock_data.js +++ b/spec/frontend/ci/jobs_mock_data.js @@ -1267,6 +1267,7 @@ export const mockPipelineWithoutMR = { path: 'pipeline/28029444', ref: { name: 'test-branch', + path: 'test-branch', }, }; diff --git a/spec/frontend/clusters/components/__snapshots__/new_cluster_spec.js.snap b/spec/frontend/clusters/components/__snapshots__/new_cluster_spec.js.snap index f90acb5cb22a05f769654879e1fa8331be33a8c6..f10f1eee440433c0c6feac9a4cd044049c208ada 100644 --- a/spec/frontend/clusters/components/__snapshots__/new_cluster_spec.js.snap +++ b/spec/frontend/clusters/components/__snapshots__/new_cluster_spec.js.snap @@ -9,12 +9,12 @@ exports[`NewCluster renders the cluster component correctly 1`] = ` </h4> <p> Enter details about your cluster. - <b-link-stub + <a class="gl-link" href="/help/user/project/clusters/add_existing_cluster" > How do I use a certificate to connect to my cluster? - </b-link-stub> + </a> </p> </div> `; diff --git a/spec/frontend/jira_connect/subscriptions/components/browser_support_alert_spec.js b/spec/frontend/jira_connect/subscriptions/components/browser_support_alert_spec.js index a8aa383d91760d4a8bd60331c3b3c5ad66b8aca2..8ba4c4a4cad6a0cb06b68aba98ad4ff75f6575aa 100644 --- a/spec/frontend/jira_connect/subscriptions/components/browser_support_alert_spec.js +++ b/spec/frontend/jira_connect/subscriptions/components/browser_support_alert_spec.js @@ -27,7 +27,7 @@ describe('BrowserSupportAlert', () => { createComponent({ mountFn: mount }); expect(findLink().attributes()).toMatchObject({ target: '_blank', - rel: 'noopener', + rel: 'noopener noreferrer', }); }); }); diff --git a/spec/frontend/organizations/groups/new/components/app_spec.js b/spec/frontend/organizations/groups/new/components/app_spec.js index 05de5d80f421d1c9941bf2e027325a5dccb320ee..5fd2129dc312a0ba8ab19f54190b543f956b945f 100644 --- a/spec/frontend/organizations/groups/new/components/app_spec.js +++ b/spec/frontend/organizations/groups/new/components/app_spec.js @@ -79,13 +79,11 @@ describe('OrganizationGroupsNewApp', () => { expect(findAllParagraphs().at(0).text()).toMatchInterpolatedText( 'Groups allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects.', ); - expect(findAllLinks().at(0).attributes('href')).toBe(helpPagePath('user/group/index')); + expect(findAllLinks().at(0).props('href')).toBe(helpPagePath('user/group/index')); expect(findAllParagraphs().at(1).text()).toContain( 'Groups can also be nested by creating subgroups.', ); - expect(findAllLinks().at(1).attributes('href')).toBe( - helpPagePath('user/group/subgroups/index'), - ); + expect(findAllLinks().at(1).props('href')).toBe(helpPagePath('user/group/subgroups/index')); }); it('renders form and passes correct props', () => { diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/__snapshots__/packages_list_app_spec.js.snap b/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/__snapshots__/packages_list_app_spec.js.snap index faba582bac8f5d2913cdcd870e6064a0d29be273..f483e033f24363a4c328496a34e5a2a3cb430883 100644 --- a/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/__snapshots__/packages_list_app_spec.js.snap +++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/__snapshots__/packages_list_app_spec.js.snap @@ -34,13 +34,14 @@ exports[`packages_list_app renders 1`] = ` class="gl-mb-0 gl-mt-4 gl-text-subtle" > Learn how to - <b-link-stub + <a class="gl-link" href="/help/user/packages/terraform_module_registry/_index" + rel="noopener noreferrer" target="_blank" > publish and share your packages - </b-link-stub> + </a> with GitLab. </p> <div diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/pypi_installation_spec.js.snap b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/pypi_installation_spec.js.snap index f0c35184a4f546554d8aa100b76b3d00eab7b46b..52f3e45b01f174f08c36a8f35d85b5e653948319 100644 --- a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/pypi_installation_spec.js.snap +++ b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/pypi_installation_spec.js.snap @@ -226,7 +226,7 @@ exports[`PypiInstallation renders all the messages 1`] = ` class="gl-link" data-testid="pypi-docs-link" href="/help/user/packages/pypi_repository/_index" - rel="noopener" + rel="noopener noreferrer" target="_blank" > see the documentation diff --git a/spec/frontend/projects/settings/branch_rules/components/view/protection_spec.js b/spec/frontend/projects/settings/branch_rules/components/view/protection_spec.js index eb5f707a4a23504f893dc7cfd745d17115bf2ac0..f71b855510df82742fac75ffde3ebbd8b3251191 100644 --- a/spec/frontend/projects/settings/branch_rules/components/view/protection_spec.js +++ b/spec/frontend/projects/settings/branch_rules/components/view/protection_spec.js @@ -108,15 +108,34 @@ describe('Branch rule protection', () => { }); describe('When `edit_branch_rules` FF is disabled', () => { - beforeEach(() => createComponent({ editBranchRules: false })); - it('does not render `Edit` button', () => { + createComponent({ editBranchRules: false }); + expect(findEditButton().exists()).toBe(false); }); - it('renders link to manage branch protections', () => { - expect(findLink().text()).toBe(protectionPropsMock.headerLinkTitle); - expect(findLink().attributes('href')).toBe(protectionPropsMock.headerLinkHref); + describe('when headerLinkHref and headerLinkTitle are set', () => { + beforeEach(() => { + createComponent({ editBranchRules: false }); + }); + + it('renders link to manage branch protections', () => { + expect(findLink().text()).toBe(protectionPropsMock.headerLinkTitle); + expect(findLink().attributes('href')).toBe(protectionPropsMock.headerLinkHref); + }); + }); + + describe('when headerLinkHref and headerLinkTitle are not set', () => { + beforeEach(() => { + createComponent( + { editBranchRules: false }, + { headerLinkHref: null, headerLinkTitle: null }, + ); + }); + + it('does not render link to manage branch protections', () => { + expect(findLink().exists()).toBe(false); + }); }); it('renders a protection row for status checks', () => { diff --git a/yarn.lock b/yarn.lock index 55e64491ca090841491c1d4f27151d3cb9015057..49bc28e6ec4d7ea60df6d932cdda9bc542ccb7ef 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1417,7 +1417,8 @@ resolved "https://registry.yarnpkg.com/@gitlab/fonts/-/fonts-1.3.0.tgz#df89c1bb6714e4a8a5d3272568aa4de7fb337267" integrity sha512-DoMUIN3DqjEn7wvcxBg/b7Ite5fTdF5EmuOZoBRo2j0UBGweDXmNBi+9HrTZs4cBU660dOxcf1hATFcG3npbPg== -"@gitlab/noop@^1.0.1": +"@gitlab/noop@^1.0.1", jackspeak@^3.1.2, "jackspeak@npm:@gitlab/noop@1.0.1": + name jackspeak version "1.0.1" resolved "https://registry.yarnpkg.com/@gitlab/noop/-/noop-1.0.1.tgz#71a831146ee02732b4a61d2d3c11204564753454" integrity sha512-s++4wjMYeDvBp9IO59DBrWjy8SE/gFkjTDO5ck2W0S6Vv7OlqgErwL7pHngAnrSmTJAzyUG8wHGqo0ViS4jn5Q== @@ -1441,10 +1442,10 @@ resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-3.123.0.tgz#1fa3b1a709755ff7c8ef67e18c0442101655ebf0" integrity sha512-yjVn+utOTIKk8d9JlvGo6EgJ4TQ+CKpe3RddflAqtsQqQuL/2MlVdtaUePybxYzWIaumFuh5LouQ6BrWyw1niQ== -"@gitlab/ui@110.1.0": - version "110.1.0" - resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-110.1.0.tgz#5a38aafb92d67b589318c39f72b5ba622fa89b83" - integrity sha512-tCezdqWgSNKuksfvVfm8TWBSIbkuK0jhCoffFFKl3HzBf9FWnCqS5+XEHLU3nPttZBTi5T761BTNqqHx8SZUAg== +"@gitlab/ui@111.0.0": + version "111.0.0" + resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-111.0.0.tgz#b827f61df673074d1cb0d3d074314635bcb74aff" + integrity sha512-AynSxduL6i5xIMSysKZWhXaSXYkJGZlmCpPz2gWCBy0+IX0r8giXwHfhGqNJ/VYaZCpkTVYeY1gTiFguPlCsbg== dependencies: "@floating-ui/dom" "1.4.3" echarts "^5.3.2" @@ -9487,11 +9488,6 @@ iterall@^1.2.1: resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.3.0.tgz#afcb08492e2915cbd8a0884eb93a8c94d0d72fea" integrity sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg== -jackspeak@^3.1.2, "jackspeak@npm:@gitlab/noop@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@gitlab/noop/-/noop-1.0.1.tgz#71a831146ee02732b4a61d2d3c11204564753454" - integrity sha512-s++4wjMYeDvBp9IO59DBrWjy8SE/gFkjTDO5ck2W0S6Vv7OlqgErwL7pHngAnrSmTJAzyUG8wHGqo0ViS4jn5Q== - jed@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/jed/-/jed-1.1.1.tgz#7a549bbd9ffe1585b0cd0a191e203055bee574b4"