Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
9fcbd94aaa
commit
90755d1898
|
@ -1 +1 @@
|
|||
7bcfd0b9498c0226f4f21476920fd8cc98137876
|
||||
7807bc4670c11dad1d2981e6d1090fe0ddd9e088
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
<script>
|
||||
import { GlDropdown, GlDropdownItem, GlDropdownText, GlSearchBoxByType } from '@gitlab/ui';
|
||||
import {
|
||||
GlAvatarLabeled,
|
||||
GlDropdown,
|
||||
GlDropdownItem,
|
||||
GlDropdownText,
|
||||
GlSearchBoxByType,
|
||||
} from '@gitlab/ui';
|
||||
import { debounce } from 'lodash';
|
||||
import Api from '~/api';
|
||||
import { s__ } from '~/locale';
|
||||
|
@ -8,6 +14,7 @@ import { SEARCH_DELAY } from '../constants';
|
|||
export default {
|
||||
name: 'GroupSelect',
|
||||
components: {
|
||||
GlAvatarLabeled,
|
||||
GlDropdown,
|
||||
GlDropdownItem,
|
||||
GlDropdownText,
|
||||
|
@ -49,6 +56,7 @@ export default {
|
|||
id: group.id,
|
||||
name: group.full_name,
|
||||
path: group.path,
|
||||
avatarUrl: group.avatar_url,
|
||||
}));
|
||||
this.isFetching = false;
|
||||
})
|
||||
|
@ -82,7 +90,7 @@ export default {
|
|||
menu-class="gl-w-full!"
|
||||
>
|
||||
<gl-search-box-by-type
|
||||
v-model.trim="searchTerm"
|
||||
v-model="searchTerm"
|
||||
:is-loading="isFetching"
|
||||
:placeholder="$options.i18n.searchPlaceholder"
|
||||
data-qa-selector="group_select_dropdown_search_field"
|
||||
|
@ -93,7 +101,13 @@ export default {
|
|||
:name="group.name"
|
||||
@click="selectGroup(group)"
|
||||
>
|
||||
{{ group.name }}
|
||||
<gl-avatar-labeled
|
||||
:label="group.name"
|
||||
:src="group.avatarUrl"
|
||||
:entity-id="group.id"
|
||||
:entity-name="group.name"
|
||||
:size="32"
|
||||
/>
|
||||
</gl-dropdown-item>
|
||||
<gl-dropdown-text v-if="isFetchResultEmpty && !isFetching" data-testid="empty-result-message">
|
||||
<span class="gl-text-gray-500">{{ $options.i18n.emptySearchResult }}</span>
|
||||
|
|
|
@ -36,7 +36,7 @@ export default {
|
|||
<gl-nav-item-dropdown
|
||||
:text="navData.activeTitle"
|
||||
icon="dot-grid"
|
||||
menu-class="gl-mt-3! gl-max-w-none! gl-max-h-none! gl-sm-w-auto!"
|
||||
menu-class="gl-mt-3! gl-max-w-none! gl-max-h-none! gl-sm-w-auto! js-top-nav-dropdown-menu"
|
||||
toggle-class="top-nav-toggle js-top-nav-dropdown-toggle gl-px-3!"
|
||||
no-flip
|
||||
>
|
||||
|
|
|
@ -30,6 +30,7 @@ export default {
|
|||
return dateInWords(date);
|
||||
},
|
||||
},
|
||||
safeHtmlConfig: { ADD_ATTR: ['target'] },
|
||||
};
|
||||
</script>
|
||||
|
||||
|
@ -71,7 +72,10 @@ export default {
|
|||
<gl-icon name="license" />{{ packageName }}
|
||||
</gl-badge>
|
||||
</div>
|
||||
<div v-safe-html="feature.body" class="gl-pt-3 gl-line-height-20"></div>
|
||||
<div
|
||||
v-safe-html:[$options.safeHtmlConfig]="feature.body"
|
||||
class="gl-pt-3 gl-line-height-20"
|
||||
></div>
|
||||
<gl-button
|
||||
:href="feature.url"
|
||||
target="_blank"
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Mutations
|
||||
module Ci
|
||||
module Runner
|
||||
class Update < BaseMutation
|
||||
graphql_name 'RunnerUpdate'
|
||||
|
||||
authorize :update_runner
|
||||
|
||||
RunnerID = ::Types::GlobalIDType[::Ci::Runner]
|
||||
|
||||
argument :id, RunnerID,
|
||||
required: true,
|
||||
description: 'ID of the runner to update.'
|
||||
|
||||
argument :description, GraphQL::STRING_TYPE,
|
||||
required: false,
|
||||
description: 'Description of the runner.'
|
||||
|
||||
argument :maximum_timeout, GraphQL::INT_TYPE,
|
||||
required: false,
|
||||
description: 'Maximum timeout (in seconds) for jobs processed by the runner.'
|
||||
|
||||
argument :access_level, ::Types::Ci::RunnerAccessLevelEnum,
|
||||
required: false,
|
||||
description: 'Access level of the runner.'
|
||||
|
||||
argument :active, GraphQL::BOOLEAN_TYPE,
|
||||
required: false,
|
||||
description: 'Indicates the runner is allowed to receive jobs.'
|
||||
|
||||
argument :locked, GraphQL::BOOLEAN_TYPE, required: false,
|
||||
description: 'Indicates the runner is locked.'
|
||||
|
||||
argument :run_untagged, GraphQL::BOOLEAN_TYPE,
|
||||
required: false,
|
||||
description: 'Indicates the runner is able to run untagged jobs.'
|
||||
|
||||
argument :tag_list, [GraphQL::STRING_TYPE], required: false,
|
||||
description: 'Tags associated with the runner.'
|
||||
|
||||
field :runner,
|
||||
Types::Ci::RunnerType,
|
||||
null: true,
|
||||
description: 'The runner after mutation.'
|
||||
|
||||
def resolve(id:, **runner_attrs)
|
||||
runner = authorized_find!(id)
|
||||
|
||||
unless ::Ci::UpdateRunnerService.new(runner).update(runner_attrs)
|
||||
return { runner: nil, errors: runner.errors.full_messages }
|
||||
end
|
||||
|
||||
{ runner: runner, errors: [] }
|
||||
end
|
||||
|
||||
def find_object(id)
|
||||
# TODO: remove this line when the compatibility layer is removed
|
||||
# See: https://gitlab.com/gitlab-org/gitlab/-/issues/257883
|
||||
id = RunnerID.coerce_isolated_input(id)
|
||||
|
||||
GitlabSchema.find_by_gid(id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -99,6 +99,7 @@ module Types
|
|||
mount_mutation Mutations::Ci::CiCdSettingsUpdate
|
||||
mount_mutation Mutations::Ci::Job::Play
|
||||
mount_mutation Mutations::Ci::Job::Retry
|
||||
mount_mutation Mutations::Ci::Runner::Update, feature_flag: :runner_graphql_query
|
||||
mount_mutation Mutations::Namespace::PackageSettings::Update
|
||||
mount_mutation Mutations::UserCallouts::Create
|
||||
end
|
||||
|
|
|
@ -33,7 +33,7 @@ class ReleaseHighlight
|
|||
next unless include_item?(item)
|
||||
|
||||
begin
|
||||
item.tap {|i| i['body'] = Kramdown::Document.new(i['body']).to_html }
|
||||
item.tap {|i| i['body'] = Banzai.render(i['body'], { project: nil }) }
|
||||
rescue StandardError => e
|
||||
Gitlab::ErrorTracking.track_exception(e, file_path: file_path)
|
||||
|
||||
|
|
|
@ -4,5 +4,5 @@
|
|||
":human-time-estimate" => "issue.humanTimeEstimate",
|
||||
":human-time-spent" => "issue.humanTimeSpent",
|
||||
":limit-to-hours" => "timeTrackingLimitToHours",
|
||||
":issuable-id" => "issue.id",
|
||||
":issuable-id" => "issue.id ? issue.id.toString() : ''",
|
||||
"root-path" => "#{root_url}" }
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: usage_data_i_testing_group_code_coverage_project_click_total
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/51411
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/299893
|
||||
milestone: '13.8'
|
||||
type: development
|
||||
group: group::testing
|
||||
default_enabled: true
|
|
@ -3568,6 +3568,34 @@ Input type: `RunDASTScanInput`
|
|||
| <a id="mutationrundastscanerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
|
||||
| <a id="mutationrundastscanpipelineurl"></a>`pipelineUrl` | [`String`](#string) | URL of the pipeline that was created. |
|
||||
|
||||
### `Mutation.runnerUpdate`
|
||||
|
||||
Available only when feature flag `runner_graphql_query` is enabled.
|
||||
|
||||
Input type: `RunnerUpdateInput`
|
||||
|
||||
#### Arguments
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mutationrunnerupdateaccesslevel"></a>`accessLevel` | [`CiRunnerAccessLevel`](#cirunneraccesslevel) | Access level of the runner. |
|
||||
| <a id="mutationrunnerupdateactive"></a>`active` | [`Boolean`](#boolean) | Indicates the runner is allowed to receive jobs. |
|
||||
| <a id="mutationrunnerupdateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
|
||||
| <a id="mutationrunnerupdatedescription"></a>`description` | [`String`](#string) | Description of the runner. |
|
||||
| <a id="mutationrunnerupdateid"></a>`id` | [`CiRunnerID!`](#cirunnerid) | ID of the runner to update. |
|
||||
| <a id="mutationrunnerupdatelocked"></a>`locked` | [`Boolean`](#boolean) | Indicates the runner is locked. |
|
||||
| <a id="mutationrunnerupdatemaximumtimeout"></a>`maximumTimeout` | [`Int`](#int) | Maximum timeout (in seconds) for jobs processed by the runner. |
|
||||
| <a id="mutationrunnerupdaterununtagged"></a>`runUntagged` | [`Boolean`](#boolean) | Indicates the runner is able to run untagged jobs. |
|
||||
| <a id="mutationrunnerupdatetaglist"></a>`tagList` | [`[String!]`](#string) | Tags associated with the runner. |
|
||||
|
||||
#### Fields
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mutationrunnerupdateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
|
||||
| <a id="mutationrunnerupdateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
|
||||
| <a id="mutationrunnerupdaterunner"></a>`runner` | [`CiRunner`](#cirunner) | The runner after mutation. |
|
||||
|
||||
### `Mutation.terraformStateDelete`
|
||||
|
||||
Input type: `TerraformStateDeleteInput`
|
||||
|
|
|
@ -180,7 +180,6 @@
|
|||
category: testing
|
||||
redis_slot: testing
|
||||
aggregation: weekly
|
||||
feature_flag: usage_data_i_testing_group_code_coverage_project_click_total
|
||||
- name: i_testing_load_performance_widget_total
|
||||
category: testing
|
||||
redis_slot: testing
|
||||
|
|
|
@ -5,28 +5,32 @@ require 'spec_helper'
|
|||
RSpec.describe 'Admin Mode Logout', :js do
|
||||
include TermsHelper
|
||||
include UserLoginHelper
|
||||
include Spec::Support::Helpers::Features::TopNavSpecHelpers
|
||||
|
||||
let(:user) { create(:admin) }
|
||||
|
||||
shared_examples 'combined_menu: feature flag examples' do
|
||||
before do
|
||||
gitlab_sign_in(user)
|
||||
# TODO: This used to use gitlab_sign_in, instead of sign_in, but that is buggy. See
|
||||
# this issue to look into why: https://gitlab.com/gitlab-org/gitlab/-/issues/331851
|
||||
sign_in(user)
|
||||
gitlab_enable_admin_mode_sign_in(user)
|
||||
visit admin_root_path
|
||||
end
|
||||
|
||||
it 'disable removes admin mode and redirects to root page' do
|
||||
pending_on_combined_menu_flag
|
||||
|
||||
gitlab_disable_admin_mode
|
||||
|
||||
expect(current_path).to eq root_path
|
||||
expect(page).to have_link(href: new_admin_session_path)
|
||||
|
||||
open_top_nav
|
||||
|
||||
within_top_nav do
|
||||
expect(page).to have_link(href: new_admin_session_path)
|
||||
end
|
||||
end
|
||||
|
||||
it 'disable shows flash notice' do
|
||||
pending_on_combined_menu_flag
|
||||
|
||||
gitlab_disable_admin_mode
|
||||
|
||||
expect(page).to have_selector('.flash-notice')
|
||||
|
@ -38,17 +42,20 @@ RSpec.describe 'Admin Mode Logout', :js do
|
|||
end
|
||||
|
||||
it 'disable removes admin mode and redirects to root page' do
|
||||
pending_on_combined_menu_flag
|
||||
|
||||
gitlab_disable_admin_mode
|
||||
|
||||
expect(current_path).to eq root_path
|
||||
expect(page).to have_link(href: new_admin_session_path)
|
||||
|
||||
open_top_nav
|
||||
|
||||
within_top_nav do
|
||||
expect(page).to have_link(href: new_admin_session_path)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with combined_menu: feature flag on' do
|
||||
context 'with combined_menu feature flag on' do
|
||||
let(:needs_rewrite_for_combined_menu_flag_on) { true }
|
||||
|
||||
before do
|
||||
|
@ -67,8 +74,4 @@ RSpec.describe 'Admin Mode Logout', :js do
|
|||
|
||||
it_behaves_like 'combined_menu: feature flag examples'
|
||||
end
|
||||
|
||||
def pending_on_combined_menu_flag
|
||||
pending 'https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56587' if needs_rewrite_for_combined_menu_flag_on
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,6 +4,7 @@ require 'spec_helper'
|
|||
|
||||
RSpec.describe 'Admin mode' do
|
||||
include MobileHelpers
|
||||
include Spec::Support::Helpers::Features::TopNavSpecHelpers
|
||||
include StubENV
|
||||
|
||||
let(:admin) { create(:admin) }
|
||||
|
@ -21,6 +22,7 @@ RSpec.describe 'Admin mode' do
|
|||
context 'when not in admin mode' do
|
||||
it 'has no leave admin mode button' do
|
||||
visit new_admin_session_path
|
||||
open_top_nav
|
||||
|
||||
page.within('.navbar-sub-nav') do
|
||||
expect(page).not_to have_link(href: destroy_admin_session_path)
|
||||
|
@ -28,12 +30,11 @@ RSpec.describe 'Admin mode' do
|
|||
end
|
||||
|
||||
it 'can open pages not in admin scope' do
|
||||
pending_on_combined_menu_flag
|
||||
|
||||
visit new_admin_session_path
|
||||
open_top_nav_projects
|
||||
|
||||
page.within('.navbar-sub-nav') do
|
||||
find_all('a', text: 'Projects').first.click
|
||||
within_top_nav do
|
||||
click_link('Your projects')
|
||||
end
|
||||
|
||||
expect(page).to have_current_path(dashboard_projects_path)
|
||||
|
@ -78,71 +79,64 @@ RSpec.describe 'Admin mode' do
|
|||
end
|
||||
|
||||
it 'contains link to leave admin mode' do
|
||||
pending_on_combined_menu_flag
|
||||
open_top_nav
|
||||
|
||||
page.within('.navbar-sub-nav') do
|
||||
within_top_nav do
|
||||
expect(page).to have_link(href: destroy_admin_session_path)
|
||||
end
|
||||
end
|
||||
|
||||
it 'can leave admin mode using main dashboard link', :js do
|
||||
pending_on_combined_menu_flag
|
||||
gitlab_disable_admin_mode
|
||||
|
||||
page.within('.navbar-sub-nav') do
|
||||
click_on 'Leave Admin Mode'
|
||||
open_top_nav
|
||||
|
||||
within_top_nav do
|
||||
expect(page).to have_link(href: new_admin_session_path)
|
||||
end
|
||||
end
|
||||
|
||||
it 'can leave admin mode using dropdown menu on smaller screens', :js do
|
||||
pending_on_combined_menu_flag
|
||||
|
||||
resize_screen_xs
|
||||
visit root_dashboard_path
|
||||
|
||||
find('.header-more').click
|
||||
find('.header-more').click unless Feature.enabled?(:combined_menu)
|
||||
|
||||
page.within '.navbar-sub-nav' do
|
||||
click_on 'Leave Admin Mode'
|
||||
gitlab_disable_admin_mode
|
||||
|
||||
find('.header-more').click
|
||||
open_top_nav
|
||||
find('.header-more').click unless Feature.enabled?(:combined_menu)
|
||||
|
||||
expect(page).to have_link(href: new_admin_session_path)
|
||||
end
|
||||
expect(page).to have_link(href: new_admin_session_path)
|
||||
end
|
||||
|
||||
it 'can open pages not in admin scope' do
|
||||
pending_on_combined_menu_flag
|
||||
open_top_nav_projects
|
||||
|
||||
page.within('.navbar-sub-nav') do
|
||||
find_all('a', text: 'Projects').first.click
|
||||
|
||||
expect(page).to have_current_path(dashboard_projects_path)
|
||||
within_top_nav do
|
||||
click_link('Your projects')
|
||||
end
|
||||
|
||||
expect(page).to have_current_path(dashboard_projects_path)
|
||||
end
|
||||
|
||||
context 'nav bar' do
|
||||
it 'shows admin dashboard links on bigger screen' do
|
||||
pending_on_combined_menu_flag
|
||||
|
||||
visit root_dashboard_path
|
||||
open_top_nav
|
||||
|
||||
page.within '.navbar' do
|
||||
expect(page).to have_link(text: 'Admin Area', href: admin_root_path, visible: true)
|
||||
expect(page).to have_link(text: 'Leave Admin Mode', href: destroy_admin_session_path, visible: true)
|
||||
end
|
||||
link_text = Feature.enabled?(:combined_menu) ? 'Admin' : 'Admin Area'
|
||||
expect(page).to have_link(text: link_text, href: admin_root_path, visible: true)
|
||||
expect(page).to have_link(text: 'Leave Admin Mode', href: destroy_admin_session_path, visible: true)
|
||||
end
|
||||
|
||||
it 'relocates admin dashboard links to dropdown list on smaller screen', :js do
|
||||
pending_on_combined_menu_flag
|
||||
skip('not applicable with :combined_menu feature flag enabled') if Feature.enabled?(:combined_menu)
|
||||
|
||||
resize_screen_xs
|
||||
visit root_dashboard_path
|
||||
|
||||
page.within '.navbar' do
|
||||
expect(page).not_to have_link(text: 'Leave Admin Mode', href: destroy_admin_session_path, visible: true)
|
||||
end
|
||||
expect(page).not_to have_link(text: 'Leave Admin Mode', href: destroy_admin_session_path, visible: true)
|
||||
|
||||
find('.header-more').click
|
||||
|
||||
|
@ -159,11 +153,11 @@ RSpec.describe 'Admin mode' do
|
|||
end
|
||||
|
||||
it 'can leave admin mode', :js do
|
||||
pending_on_combined_menu_flag
|
||||
gitlab_disable_admin_mode
|
||||
|
||||
page.within('.navbar-sub-nav') do
|
||||
click_on 'Leave Admin Mode'
|
||||
open_top_nav
|
||||
|
||||
within_top_nav do
|
||||
expect(page).to have_link(href: new_admin_session_path)
|
||||
end
|
||||
end
|
||||
|
@ -179,16 +173,15 @@ RSpec.describe 'Admin mode' do
|
|||
|
||||
it 'shows no admin mode buttons in navbar' do
|
||||
visit admin_root_path
|
||||
open_top_nav
|
||||
|
||||
page.within('.navbar-sub-nav') do
|
||||
expect(page).not_to have_link(href: new_admin_session_path)
|
||||
expect(page).not_to have_link(href: destroy_admin_session_path)
|
||||
end
|
||||
expect(page).not_to have_link(href: new_admin_session_path)
|
||||
expect(page).not_to have_link(href: destroy_admin_session_path)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with combined_menu: feature flag on' do
|
||||
context 'with combined_menu feature flag on', :js do
|
||||
let(:needs_rewrite_for_combined_menu_flag_on) { true }
|
||||
|
||||
before do
|
||||
|
@ -207,8 +200,4 @@ RSpec.describe 'Admin mode' do
|
|||
|
||||
it_behaves_like 'combined_menu: feature flag examples'
|
||||
end
|
||||
|
||||
def pending_on_combined_menu_flag
|
||||
pending 'https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56587' if needs_rewrite_for_combined_menu_flag_on
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
# TODO: This entire spec file can be deleted once the combined_menu feature is fully rolled
|
||||
# out and the flag is removed, because it will then be irrelevant (there will be no more tabs).
|
||||
# Feature flag removal issue: https://gitlab.com/gitlab-org/gitlab/-/issues/324086
|
||||
RSpec.describe 'Dashboard Active Tab', :js do
|
||||
shared_examples 'combined_menu: feature flag examples' do
|
||||
before do
|
||||
|
@ -10,8 +13,6 @@ RSpec.describe 'Dashboard Active Tab', :js do
|
|||
|
||||
shared_examples 'page has active tab' do |title|
|
||||
it "#{title} tab" do
|
||||
pending_on_combined_menu_flag
|
||||
|
||||
subject
|
||||
|
||||
expect(page).to have_selector('.navbar-sub-nav li.active', count: 1)
|
||||
|
@ -32,27 +33,11 @@ RSpec.describe 'Dashboard Active Tab', :js do
|
|||
end
|
||||
end
|
||||
|
||||
context 'with combined_menu: feature flag on' do
|
||||
let(:needs_rewrite_for_combined_menu_flag_on) { true }
|
||||
|
||||
before do
|
||||
stub_feature_flags(combined_menu: true)
|
||||
end
|
||||
|
||||
it_behaves_like 'combined_menu: feature flag examples'
|
||||
end
|
||||
|
||||
context 'with combined_menu feature flag off' do
|
||||
let(:needs_rewrite_for_combined_menu_flag_on) { false }
|
||||
|
||||
before do
|
||||
stub_feature_flags(combined_menu: false)
|
||||
end
|
||||
|
||||
it_behaves_like 'combined_menu: feature flag examples'
|
||||
end
|
||||
|
||||
def pending_on_combined_menu_flag
|
||||
pending 'https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56587' if needs_rewrite_for_combined_menu_flag_on
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,6 +4,7 @@ require 'spec_helper'
|
|||
|
||||
RSpec.describe 'The group dashboard' do
|
||||
include ExternalAuthorizationServiceHelpers
|
||||
include Spec::Support::Helpers::Features::TopNavSpecHelpers
|
||||
|
||||
let(:user) { create(:user) }
|
||||
|
||||
|
@ -14,11 +15,11 @@ RSpec.describe 'The group dashboard' do
|
|||
|
||||
describe 'The top navigation' do
|
||||
it 'has all the expected links' do
|
||||
pending_on_combined_menu_flag
|
||||
|
||||
visit dashboard_groups_path
|
||||
|
||||
within('.navbar') do
|
||||
open_top_nav
|
||||
|
||||
within_top_nav do
|
||||
expect(page).to have_button('Projects')
|
||||
expect(page).to have_button('Groups')
|
||||
expect(page).to have_link('Activity')
|
||||
|
@ -28,12 +29,12 @@ RSpec.describe 'The group dashboard' do
|
|||
end
|
||||
|
||||
it 'hides some links when an external authorization service is enabled' do
|
||||
pending_on_combined_menu_flag
|
||||
|
||||
enable_external_authorization_service_check
|
||||
visit dashboard_groups_path
|
||||
|
||||
within('.navbar') do
|
||||
open_top_nav
|
||||
|
||||
within_top_nav do
|
||||
expect(page).to have_button('Projects')
|
||||
expect(page).to have_button('Groups')
|
||||
expect(page).not_to have_link('Activity')
|
||||
|
@ -44,7 +45,7 @@ RSpec.describe 'The group dashboard' do
|
|||
end
|
||||
end
|
||||
|
||||
context 'with combined_menu: feature flag on' do
|
||||
context 'with combined_menu feature flag on', :js do
|
||||
let(:needs_rewrite_for_combined_menu_flag_on) { true }
|
||||
|
||||
before do
|
||||
|
@ -63,8 +64,4 @@ RSpec.describe 'The group dashboard' do
|
|||
|
||||
it_behaves_like 'combined_menu: feature flag examples'
|
||||
end
|
||||
|
||||
def pending_on_combined_menu_flag
|
||||
pending 'https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56587' if needs_rewrite_for_combined_menu_flag_on
|
||||
end
|
||||
end
|
||||
|
|
|
@ -38,6 +38,10 @@ RSpec.describe 'Dashboard shortcuts', :js do
|
|||
find('body').send_keys([:shift, 'A'])
|
||||
|
||||
check_page_title('Activity')
|
||||
|
||||
find('body').send_keys([:shift, 'L'])
|
||||
|
||||
check_page_title('Milestones')
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -69,7 +73,7 @@ RSpec.describe 'Dashboard shortcuts', :js do
|
|||
end
|
||||
end
|
||||
|
||||
context 'with combined_menu: feature flag on' do
|
||||
context 'with combined_menu feature flag on' do
|
||||
before do
|
||||
stub_feature_flags(combined_menu: true)
|
||||
end
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe 'Frequently visited items', :js do
|
||||
include Spec::Support::Helpers::Features::TopNavSpecHelpers
|
||||
|
||||
let_it_be(:user) { create(:user) }
|
||||
|
||||
shared_examples 'combined_menu: feature flag examples' do
|
||||
|
@ -14,9 +16,8 @@ RSpec.describe 'Frequently visited items', :js do
|
|||
let_it_be(:project) { create(:project, :public) }
|
||||
|
||||
it 'increments localStorage counter when visiting the project' do
|
||||
pending_on_combined_menu_flag
|
||||
|
||||
visit project_path(project)
|
||||
open_top_nav_projects
|
||||
|
||||
frequent_projects = nil
|
||||
|
||||
|
@ -34,9 +35,8 @@ RSpec.describe 'Frequently visited items', :js do
|
|||
let_it_be(:group) { create(:group, :public) }
|
||||
|
||||
it 'increments localStorage counter when visiting the group' do
|
||||
pending_on_combined_menu_flag
|
||||
|
||||
visit group_path(group)
|
||||
open_top_nav_groups
|
||||
|
||||
frequent_groups = nil
|
||||
|
||||
|
@ -51,7 +51,7 @@ RSpec.describe 'Frequently visited items', :js do
|
|||
end
|
||||
end
|
||||
|
||||
context 'with combined_menu: feature flag on' do
|
||||
context 'with combined_menu feature flag on' do
|
||||
let(:needs_rewrite_for_combined_menu_flag_on) { true }
|
||||
|
||||
before do
|
||||
|
@ -70,8 +70,4 @@ RSpec.describe 'Frequently visited items', :js do
|
|||
|
||||
it_behaves_like 'combined_menu: feature flag examples'
|
||||
end
|
||||
|
||||
def pending_on_combined_menu_flag
|
||||
pending 'https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56587' if needs_rewrite_for_combined_menu_flag_on
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,6 +4,7 @@ require 'spec_helper'
|
|||
|
||||
RSpec.describe 'New project', :js do
|
||||
include Select2Helper
|
||||
include Spec::Support::Helpers::Features::TopNavSpecHelpers
|
||||
|
||||
shared_examples 'combined_menu: feature flag examples' do
|
||||
context 'as a user' do
|
||||
|
@ -45,34 +46,39 @@ RSpec.describe 'New project', :js do
|
|||
end
|
||||
|
||||
it 'when in control it renders "project" in the new projects dropdown' do
|
||||
pending_on_combined_menu_flag
|
||||
|
||||
stub_experiments(new_repo: :control)
|
||||
|
||||
visit new_project_path
|
||||
|
||||
find('#nav-projects-dropdown').click
|
||||
open_top_nav_projects
|
||||
|
||||
page.within('#nav-projects-dropdown') do
|
||||
expect(page).to have_selector('a', text: 'Create blank project')
|
||||
expect(page).to have_selector('a', text: 'Import project')
|
||||
expect(page).to have_no_selector('a', text: 'Create blank project/repository')
|
||||
expect(page).to have_no_selector('a', text: 'Import project/repository')
|
||||
within_top_nav do
|
||||
if Feature.enabled?(:combined_menu)
|
||||
expect(page).to have_selector('a', text: 'Create new project')
|
||||
expect(page).to have_no_selector('a', text: 'Create blank project/repository')
|
||||
else
|
||||
expect(page).to have_selector('a', text: 'Create blank project')
|
||||
expect(page).to have_selector('a', text: 'Import project')
|
||||
expect(page).to have_no_selector('a', text: 'Create blank project/repository')
|
||||
expect(page).to have_no_selector('a', text: 'Import project/repository')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'when in candidate it renders "project/repository" in the new projects dropdown' do
|
||||
pending_on_combined_menu_flag
|
||||
|
||||
stub_experiments(new_repo: :candidate)
|
||||
|
||||
visit new_project_path
|
||||
|
||||
find('#nav-projects-dropdown').click
|
||||
open_top_nav_projects
|
||||
|
||||
page.within('#nav-projects-dropdown') do
|
||||
expect(page).to have_selector('a', text: 'Create blank project/repository')
|
||||
expect(page).to have_selector('a', text: 'Import project/repository')
|
||||
within_top_nav do
|
||||
if Feature.enabled?(:combined_menu)
|
||||
expect(page).to have_selector('a', text: 'Create new project')
|
||||
else
|
||||
expect(page).to have_selector('a', text: 'Create blank project/repository')
|
||||
expect(page).to have_selector('a', text: 'Import project/repository')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -412,7 +418,7 @@ RSpec.describe 'New project', :js do
|
|||
end
|
||||
end
|
||||
|
||||
context 'with combined_menu: feature flag on' do
|
||||
context 'with combined_menu feature flag on' do
|
||||
let(:needs_rewrite_for_combined_menu_flag_on) { true }
|
||||
|
||||
before do
|
||||
|
@ -431,8 +437,4 @@ RSpec.describe 'New project', :js do
|
|||
|
||||
it_behaves_like 'combined_menu: feature flag examples'
|
||||
end
|
||||
|
||||
def pending_on_combined_menu_flag
|
||||
pending 'https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56587' if needs_rewrite_for_combined_menu_flag_on
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
- title: bright and sunshinin' day
|
||||
body: |
|
||||
## bright and sunshinin' day
|
||||
bright and sunshinin' [day](https://en.wikipedia.org/wiki/Day)
|
||||
self-managed: true
|
||||
gitlab-com: false
|
||||
packages: ["Premium", "Ultimate"]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { GlDropdown, GlDropdownItem, GlSearchBoxByType } from '@gitlab/ui';
|
||||
import { GlAvatarLabeled, GlDropdown, GlSearchBoxByType } from '@gitlab/ui';
|
||||
import { mount } from '@vue/test-utils';
|
||||
import waitForPromises from 'helpers/wait_for_promises';
|
||||
import Api from '~/api';
|
||||
|
@ -8,8 +8,8 @@ const createComponent = () => {
|
|||
return mount(GroupSelect, {});
|
||||
};
|
||||
|
||||
const group1 = { id: 1, full_name: 'Group One' };
|
||||
const group2 = { id: 2, full_name: 'Group Two' };
|
||||
const group1 = { id: 1, full_name: 'Group One', avatar_url: 'test' };
|
||||
const group2 = { id: 2, full_name: 'Group Two', avatar_url: 'test' };
|
||||
const allGroups = [group1, group2];
|
||||
|
||||
describe('GroupSelect', () => {
|
||||
|
@ -29,10 +29,10 @@ describe('GroupSelect', () => {
|
|||
const findSearchBoxByType = () => wrapper.findComponent(GlSearchBoxByType);
|
||||
const findDropdown = () => wrapper.findComponent(GlDropdown);
|
||||
const findDropdownToggle = () => findDropdown().find('button[aria-haspopup="true"]');
|
||||
const findDropdownItemByText = (text) =>
|
||||
const findAvatarByLabel = (text) =>
|
||||
wrapper
|
||||
.findAllComponents(GlDropdownItem)
|
||||
.wrappers.find((dropdownItemWrapper) => dropdownItemWrapper.text() === text);
|
||||
.findAllComponents(GlAvatarLabeled)
|
||||
.wrappers.find((dropdownItemWrapper) => dropdownItemWrapper.props('label') === text);
|
||||
|
||||
it('renders GlSearchBoxByType with default attributes', () => {
|
||||
expect(findSearchBoxByType().exists()).toBe(true);
|
||||
|
@ -74,9 +74,20 @@ describe('GroupSelect', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('avatar label', () => {
|
||||
it('includes the correct attributes with name and avatar_url', () => {
|
||||
expect(findAvatarByLabel(group1.full_name).attributes()).toMatchObject({
|
||||
src: group1.avatar_url,
|
||||
'entity-id': `${group1.id}`,
|
||||
'entity-name': group1.full_name,
|
||||
size: '32',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when group is selected from the dropdown', () => {
|
||||
beforeEach(() => {
|
||||
findDropdownItemByText(group1.full_name).vm.$emit('click');
|
||||
findAvatarByLabel(group1.full_name).trigger('click');
|
||||
});
|
||||
|
||||
it('emits `input` event used by `v-model`', () => {
|
||||
|
|
|
@ -8,7 +8,7 @@ describe("What's new single feature", () => {
|
|||
const exampleFeature = {
|
||||
title: 'Compliance pipeline configurations',
|
||||
body:
|
||||
'<p>We are thrilled to announce that it is now possible to define enforceable pipelines that will run for any project assigned a corresponding compliance framework.</p>',
|
||||
'<p data-testid="body-content">We are thrilled to announce that it is now possible to define enforceable pipelines that will run for any project assigned a corresponding <a href="https://en.wikipedia.org/wiki/Compliance_(psychology)" target="_blank" rel="noopener noreferrer" onload="alert(xss)">compliance</a> framework.</p>',
|
||||
stage: 'Manage',
|
||||
'self-managed': true,
|
||||
'gitlab-com': true,
|
||||
|
@ -20,6 +20,7 @@ describe("What's new single feature", () => {
|
|||
};
|
||||
|
||||
const findReleaseDate = () => wrapper.find('[data-testid="release-date"]');
|
||||
const findBodyAnchor = () => wrapper.find('[data-testid="body-content"] a');
|
||||
|
||||
const createWrapper = ({ feature } = {}) => {
|
||||
wrapper = shallowMount(Feature, {
|
||||
|
@ -43,4 +44,13 @@ describe("What's new single feature", () => {
|
|||
expect(findReleaseDate().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
it('safe-html config allows target attribute on elements', () => {
|
||||
createWrapper({ feature: exampleFeature });
|
||||
expect(findBodyAnchor().attributes()).toEqual({
|
||||
href: expect.any(String),
|
||||
rel: 'noopener noreferrer',
|
||||
target: '_blank',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Mutations::Ci::Runner::Update do
|
||||
include GraphqlHelpers
|
||||
|
||||
let_it_be(:user) { create(:user) }
|
||||
let_it_be(:runner) { create(:ci_runner, active: true, locked: false, run_untagged: true) }
|
||||
|
||||
let(:current_ctx) { { current_user: user } }
|
||||
let(:mutated_runner) { subject[:runner] }
|
||||
|
||||
let(:mutation_params) do
|
||||
{
|
||||
id: runner.to_global_id,
|
||||
description: 'updated description'
|
||||
}
|
||||
end
|
||||
|
||||
specify { expect(described_class).to require_graphql_authorizations(:update_runner) }
|
||||
|
||||
describe '#resolve' do
|
||||
subject do
|
||||
sync(resolve(described_class, args: mutation_params, ctx: current_ctx))
|
||||
end
|
||||
|
||||
context 'when the user cannot admin the runner' do
|
||||
it 'raises an error' do
|
||||
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with invalid params' do
|
||||
it 'raises an error' do
|
||||
mutation_params[:id] = "invalid-id"
|
||||
|
||||
expect { subject }.to raise_error(::GraphQL::CoercionError)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when required arguments are missing' do
|
||||
let(:mutation_params) { {} }
|
||||
|
||||
it 'raises an error' do
|
||||
expect { subject }.to raise_error(ArgumentError, "missing keyword: :id")
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user can update runner', :enable_admin_mode do
|
||||
let(:admin_user) { create(:user, :admin) }
|
||||
let(:current_ctx) { { current_user: admin_user } }
|
||||
|
||||
let(:mutation_params) do
|
||||
{
|
||||
id: runner.to_global_id,
|
||||
description: 'updated description',
|
||||
maximum_timeout: 900,
|
||||
access_level: 'ref_protected',
|
||||
active: false,
|
||||
locked: true,
|
||||
run_untagged: false,
|
||||
tag_list: %w(tag1 tag2)
|
||||
}
|
||||
end
|
||||
|
||||
context 'with valid arguments' do
|
||||
it 'updates runner with correct values' do
|
||||
expected_attributes = mutation_params.except(:id)
|
||||
|
||||
subject
|
||||
|
||||
expect(subject[:errors]).to be_empty
|
||||
expect(subject[:runner]).to be_an_instance_of(Ci::Runner)
|
||||
expect(subject[:runner]).to have_attributes(expected_attributes)
|
||||
expect(runner.reload).to have_attributes(expected_attributes)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with out-of-range maximum_timeout and missing tag_list' do
|
||||
it 'returns a descriptive error' do
|
||||
mutation_params[:maximum_timeout] = 100
|
||||
mutation_params.delete(:tag_list)
|
||||
|
||||
expect(subject[:errors]).to contain_exactly(
|
||||
'Maximum timeout needs to be at least 10 minutes',
|
||||
'Tags list can not be empty when runner is not allowed to pick untagged jobs'
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -67,12 +67,12 @@ RSpec.describe ReleaseHighlight, :clean_gitlab_redis_cache do
|
|||
expect(subject[:next_page]).to eq(2)
|
||||
end
|
||||
|
||||
it 'parses the body as markdown and returns html' do
|
||||
expect(subject[:items].first['body']).to match("<h2 id=\"bright-and-sunshinin-day\">bright and sunshinin’ day</h2>")
|
||||
it 'parses the body as markdown and returns html, and links are target="_blank"' do
|
||||
expect(subject[:items].first['body']).to match('<p data-sourcepos="1:1-1:62" dir="auto">bright and sunshinin\' <a href="https://en.wikipedia.org/wiki/Day" rel="nofollow noreferrer noopener" target="_blank">day</a></p>')
|
||||
end
|
||||
|
||||
it 'logs an error if theres an error parsing markdown for an item, and skips it' do
|
||||
allow(Kramdown::Document).to receive(:new).and_raise
|
||||
allow(Banzai).to receive(:render).and_raise
|
||||
|
||||
expect(Gitlab::ErrorTracking).to receive(:track_exception)
|
||||
expect(subject[:items]).to be_empty
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# These helpers help you interact within the Editor Lite (single-file editor, snippets, etc.).
|
||||
#
|
||||
module Spec
|
||||
module Support
|
||||
module Helpers
|
||||
module Features
|
||||
module TopNavSpecHelpers
|
||||
def open_top_nav
|
||||
return unless Feature.enabled?(:combined_menu)
|
||||
|
||||
find('.js-top-nav-dropdown-toggle').click
|
||||
end
|
||||
|
||||
def within_top_nav
|
||||
if Feature.enabled?(:combined_menu)
|
||||
within('.js-top-nav-dropdown-menu') do
|
||||
yield
|
||||
end
|
||||
else
|
||||
within('.navbar-sub-nav') do
|
||||
yield
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def open_top_nav_projects
|
||||
if Feature.enabled?(:combined_menu)
|
||||
open_top_nav
|
||||
|
||||
within_top_nav do
|
||||
click_button('Projects')
|
||||
end
|
||||
else
|
||||
find('#nav-projects-dropdown').click
|
||||
end
|
||||
end
|
||||
|
||||
def open_top_nav_groups
|
||||
return unless Feature.enabled?(:combined_menu)
|
||||
|
||||
open_top_nav
|
||||
|
||||
within_top_nav do
|
||||
click_button('Groups')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -77,7 +77,11 @@ module LoginHelpers
|
|||
|
||||
# Requires Javascript driver.
|
||||
def gitlab_disable_admin_mode
|
||||
click_on 'Leave Admin Mode'
|
||||
open_top_nav
|
||||
|
||||
within_top_nav do
|
||||
click_on 'Leave Admin Mode'
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
|
Loading…
Reference in New Issue