Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
1f7ce4357d
commit
beb5d989d2
22 changed files with 114 additions and 182 deletions
|
@ -128,6 +128,7 @@ export default {
|
|||
variant="confirm"
|
||||
category="primary"
|
||||
class="gl-mt-5"
|
||||
:data-qa-selector="`${feature.type}_mr_button`"
|
||||
/>
|
||||
|
||||
<gl-button
|
||||
|
|
|
@ -10,20 +10,23 @@ export default {
|
|||
render(h) {
|
||||
if (extensions.length === 0) return null;
|
||||
|
||||
return h(
|
||||
'div',
|
||||
{},
|
||||
extensions.map((extension) =>
|
||||
h(extension, {
|
||||
props: extension.props.reduce(
|
||||
(acc, key) => ({
|
||||
...acc,
|
||||
[key]: this.mr[key],
|
||||
}),
|
||||
{},
|
||||
),
|
||||
}),
|
||||
return h('div', {}, [
|
||||
...extensions.map((extension) =>
|
||||
h(
|
||||
{ ...extension },
|
||||
{
|
||||
props: {
|
||||
...extension.props.reduce(
|
||||
(acc, key) => ({
|
||||
...acc,
|
||||
[key]: this.mr[key],
|
||||
}),
|
||||
{},
|
||||
),
|
||||
},
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
]);
|
||||
},
|
||||
};
|
||||
|
|
|
@ -100,6 +100,7 @@ export default {
|
|||
:loading="isLoading"
|
||||
:variant="variant"
|
||||
:category="category"
|
||||
:data-qa-selector="`${feature.type}_mr_button`"
|
||||
@click="mutate"
|
||||
>{{ $options.i18n.buttonLabel }}</gl-button
|
||||
>
|
||||
|
|
|
@ -477,8 +477,6 @@ module ApplicationSettingsHelper
|
|||
end
|
||||
|
||||
def pending_user_count
|
||||
return 0 if Gitlab::CurrentSettings.new_user_signups_cap.blank?
|
||||
|
||||
User.blocked_pending_approval.count
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
= render 'devise/shared/tab_single', tab_title: _('Sign in preview')
|
||||
.login-box
|
||||
%form.gl-show-field-errors
|
||||
- title = _('This form is disabled in preview')
|
||||
.form-group
|
||||
= label_tag :login
|
||||
= text_field_tag :login, nil, class: "form-control gl-form-input top", title: _('Please provide your username or email address.')
|
||||
= text_field_tag :login, nil, disabled: true, class: "form-control gl-form-input top", title: title
|
||||
.form-group
|
||||
= label_tag :password
|
||||
= password_field_tag :password, nil, class: "form-control gl-form-input bottom", title: _('This field is required.')
|
||||
= password_field_tag :password, nil, disabled: true, class: "form-control gl-form-input bottom", title: title
|
||||
.form-group
|
||||
= button_tag _("Sign in"), class: "btn gl-button btn-confirm", type: "button"
|
||||
= button_tag _("Sign in"), disabled: true, class: "btn gl-button btn-confirm", type: "button", title: title
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
%aside.nav-sidebar.qa-admin-sidebar{ class: ("sidebar-collapsed-desktop" if collapsed_sidebar?), 'aria-label': _('Admin navigation') }
|
||||
.nav-sidebar-inner-scroll
|
||||
.context-header
|
||||
= link_to admin_root_path, title: _('Admin Overview') do
|
||||
= link_to admin_root_path, title: _('Admin Overview'), class: 'has-tooltip', data: { container: 'body', placement: 'right' } do
|
||||
%span{ class: ['avatar-container', 'settings-avatar', 'rect-avatar', 's32'] }
|
||||
= sprite_icon('admin', size: 18)
|
||||
%span.sidebar-context-title
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
%aside.nav-sidebar{ class: ("sidebar-collapsed-desktop" if collapsed_sidebar?), **sidebar_tracking_attributes_by_object(current_user), 'aria-label': _('User settings') }
|
||||
.nav-sidebar-inner-scroll
|
||||
.context-header
|
||||
= link_to profile_path, title: _('Profile Settings') do
|
||||
= link_to profile_path, title: _('Profile Settings'), class: 'has-tooltip', data: { container: 'body', placement: 'right' } do
|
||||
%span{ class: ['avatar-container', 'settings-avatar', 's32'] }
|
||||
= image_tag avatar_icon_for_user(current_user, 32), class: ['avatar', 'avatar-tile', 'js-sidebar-user-avatar', 's32'], alt: current_user.name, data: { testid: 'sidebar-user-avatar' }
|
||||
%span.sidebar-context-title= _('User Settings')
|
||||
|
|
|
@ -69,7 +69,7 @@ staging:
|
|||
- gem install dpl
|
||||
- dpl --provider=heroku --app=my-app-staging --api_key=$HEROKU_STAGING_API_KEY
|
||||
only:
|
||||
- master
|
||||
- main
|
||||
```
|
||||
|
||||
The first line `apt-get update -yq` updates the list of available packages,
|
||||
|
@ -81,7 +81,7 @@ The above example is valid for all Debian-compatible systems.
|
|||
It's pretty common in the development workflow to have staging (development) and
|
||||
production environments
|
||||
|
||||
Let's consider the following example: we would like to deploy the `master`
|
||||
Let's consider the following example: we would like to deploy the `main`
|
||||
branch to `staging` and all tags to the `production` environment.
|
||||
The final `.gitlab-ci.yml` for that setup would look like this:
|
||||
|
||||
|
@ -92,7 +92,7 @@ staging:
|
|||
- gem install dpl
|
||||
- dpl --provider=heroku --app=my-app-staging --api_key=$HEROKU_STAGING_API_KEY
|
||||
only:
|
||||
- master
|
||||
- main
|
||||
|
||||
production:
|
||||
stage: deploy
|
||||
|
@ -105,7 +105,7 @@ production:
|
|||
|
||||
We created two deploy jobs that are executed on different events:
|
||||
|
||||
- `staging`: Executed for all commits pushed to the `master` branch
|
||||
- `staging`: Executed for all commits pushed to the `main` branch
|
||||
- `production`: Executed for all pushed tags
|
||||
|
||||
We also use two secure variables:
|
||||
|
|
|
@ -258,6 +258,10 @@ sudo systemctl daemon-reload
|
|||
|
||||
### 10. Install libraries, migrations, etc
|
||||
|
||||
Make sure you have the required
|
||||
[PostgreSQL extensions](../install/requirements.md#postgresql-requirements),
|
||||
then proceed to install the needed libraries:
|
||||
|
||||
```shell
|
||||
cd /home/git/gitlab
|
||||
|
||||
|
@ -304,15 +308,18 @@ cd /home/git/gitlab
|
|||
sudo -u git -H bundle exec rake "gitlab:workhorse:install[/home/git/gitlab-workhorse]" RAILS_ENV=production
|
||||
```
|
||||
|
||||
NOTE:
|
||||
If you get any errors concerning Rack attack, see the [13.0](#1301) specific
|
||||
upgrade instructions.
|
||||
|
||||
### 13. Update Gitaly
|
||||
|
||||
#### Compile Gitaly
|
||||
|
||||
```shell
|
||||
cd /home/git/gitaly
|
||||
sudo -u git -H git fetch --all --tags --prune
|
||||
sudo -u git -H git checkout v$(</home/git/gitlab/GITALY_SERVER_VERSION)
|
||||
sudo -u git -H make
|
||||
# Fetch Gitaly source with Git and compile with Go
|
||||
cd /home/git/gitlab
|
||||
sudo -u git -H bundle exec rake "gitlab:gitaly:install[/home/git/gitaly,/home/git/repositories]" RAILS_ENV=production
|
||||
```
|
||||
|
||||
### 14. Update GitLab Pages
|
||||
|
@ -375,14 +382,13 @@ Additional instructions here.
|
|||
|
||||
### 13.0.1
|
||||
|
||||
As part of [deprecating Rack Attack throttles on Omnibus GitLab](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/4750), Rack Attack initializer on GitLab
|
||||
As part of [deprecating Rack Attack throttles on Omnibus GitLab](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/4750), the Rack Attack initializer on GitLab
|
||||
was renamed from [`config/initializers/rack_attack_new.rb` to `config/initializers/rack_attack.rb`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33072).
|
||||
If this file exists on your installation, consider creating a backup before updating:
|
||||
|
||||
```shell
|
||||
cd /home/git/gitlab
|
||||
|
||||
cp config/initializers/rack_attack.rb config/initializers/rack_attack_backup.rb
|
||||
cp config/initializers/rack_attack.rb ~/config/initializers/rack_attack_backup.rb
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
|
|
@ -68,8 +68,12 @@ Install GitLab HAR Recorder:
|
|||
1. Make sure proxy is used!
|
||||
1. Stop the recorder.
|
||||
|
||||
To verify the HAR contains all requests, use the [HAR Viewer (online)](http://www.softwareishard.com/har/viewer/).
|
||||
[Google Admin Toolbox HAR Analyzer](https://toolbox.googleapps.com/apps/har_analyzer/)
|
||||
To verify the HAR contains all requests, use an online HAR viewer, for example:
|
||||
|
||||
- [HAR Viewer](http://www.softwareishard.com/har/viewer/)
|
||||
<!-- vale gitlab.Admin = NO -->
|
||||
- [Google Admin Toolbox HAR Analyzer](https://toolbox.googleapps.com/apps/har_analyzer/)
|
||||
<!-- vale gitlab.Admin = YES -->
|
||||
|
||||
### Insomnia API Client
|
||||
|
||||
|
@ -190,7 +194,9 @@ a text editor.
|
|||
Tools recommended for viewing HAR files include:
|
||||
|
||||
- [HAR Viewer](http://www.softwareishard.com/har/viewer/) - (online)
|
||||
<!-- vale gitlab.Admin = NO -->
|
||||
- [Google Admin Toolbox HAR Analyzer](https://toolbox.googleapps.com/apps/har_analyzer/) - (online)
|
||||
<!-- vale gitlab.Admin = YES -->
|
||||
- [Fiddler](https://www.telerik.com/fiddler) - local
|
||||
- [Insomnia API Client](https://insomnia.rest/) - local
|
||||
|
||||
|
|
|
@ -118,7 +118,7 @@ pages:
|
|||
paths:
|
||||
- public
|
||||
only:
|
||||
- master
|
||||
- main
|
||||
```
|
||||
|
||||
### `.gitlab-ci.yml` for a static site generator
|
||||
|
@ -133,7 +133,7 @@ the `pages` job with the [`only` parameter](../../../ci/yaml/index.md#only--exce
|
|||
whenever a new commit is pushed to a branch used specifically for your
|
||||
pages.
|
||||
|
||||
That way, you can have your project's code in the `master` branch and use an
|
||||
That way, you can have your project's code in the `main` branch and use an
|
||||
orphan branch (let's name it `pages`) to host your static generator site.
|
||||
|
||||
You can create a new empty branch like this:
|
||||
|
@ -163,7 +163,7 @@ pages:
|
|||
- pages
|
||||
```
|
||||
|
||||
See an example that has different files in the [`master` branch](https://gitlab.com/pages/jekyll-branched/tree/master)
|
||||
See an example that has different files in the [`main` branch](https://gitlab.com/pages/jekyll-branched/tree/main)
|
||||
and the source files for Jekyll are in a [`pages` branch](https://gitlab.com/pages/jekyll-branched/tree/pages) which
|
||||
also includes `.gitlab-ci.yml`.
|
||||
|
||||
|
|
|
@ -21,7 +21,11 @@ module Sidebars
|
|||
|
||||
override :extra_nav_link_html_options
|
||||
def extra_nav_link_html_options
|
||||
{ class: 'context-header' }
|
||||
{
|
||||
class: 'context-header has-tooltip',
|
||||
title: context.group.name,
|
||||
data: { container: 'body', placement: 'right' }
|
||||
}
|
||||
end
|
||||
|
||||
override :render?
|
||||
|
|
|
@ -28,7 +28,11 @@ module Sidebars
|
|||
|
||||
override :extra_nav_link_html_options
|
||||
def extra_nav_link_html_options
|
||||
{ class: 'context-header' }
|
||||
{
|
||||
class: 'context-header has-tooltip',
|
||||
title: context.project.name,
|
||||
data: { container: 'body', placement: 'right' }
|
||||
}
|
||||
end
|
||||
|
||||
override :render?
|
||||
|
|
|
@ -25370,9 +25370,6 @@ msgstr ""
|
|||
msgid "Please provide attributes to update"
|
||||
msgstr ""
|
||||
|
||||
msgid "Please provide your username or email address."
|
||||
msgstr ""
|
||||
|
||||
msgid "Please reach out if you have any questions and we'll be happy to assist."
|
||||
msgstr ""
|
||||
|
||||
|
@ -34536,6 +34533,9 @@ msgstr ""
|
|||
msgid "This field is required."
|
||||
msgstr ""
|
||||
|
||||
msgid "This form is disabled in preview"
|
||||
msgstr ""
|
||||
|
||||
msgid "This group"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -20,6 +20,13 @@ module QA
|
|||
element :file_name_content
|
||||
end
|
||||
|
||||
def has_secure_description?(scanner_name)
|
||||
scanner_url_name = scanner_name.downcase.tr('_', '-')
|
||||
"Configure #{scanner_name} in `.gitlab-ci.yml` using the GitLab managed template. You can " \
|
||||
"[add variable overrides](https://docs.gitlab.com/ee/user/application_security/#{scanner_url_name}/#customizing-the-#{scanner_url_name}-settings) " \
|
||||
"to customize #{scanner_name} settings."
|
||||
end
|
||||
|
||||
def create_merge_request
|
||||
click_element(:issuable_create_button, Page::MergeRequest::Show)
|
||||
end
|
||||
|
|
|
@ -288,13 +288,11 @@ module QA
|
|||
end
|
||||
|
||||
def merge_immediately!
|
||||
merge_moment_dropdown_found = has_element?(:merge_moment_dropdown, wait: 0)
|
||||
|
||||
if merge_moment_dropdown_found
|
||||
click_element(:merge_moment_dropdown)
|
||||
click_element(:merge_immediately_menu_item)
|
||||
if has_element?(:merge_moment_dropdown)
|
||||
click_element(:merge_moment_dropdown, skip_finished_loading_check: true)
|
||||
click_element(:merge_immediately_menu_item, skip_finished_loading_check: true)
|
||||
else
|
||||
click_element(:merge_button)
|
||||
click_element(:merge_button, skip_finished_loading_check: true)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -9,19 +9,31 @@ module QA
|
|||
include QA::Page::Settings::Common
|
||||
|
||||
view 'app/assets/javascripts/security_configuration/components/feature_card.vue' do
|
||||
element :dependency_scanning_status, "`${feature.type}_status`" # rubocop:disable QA/ElementWithPattern
|
||||
element :sast_status, "`${feature.type}_status`" # rubocop:disable QA/ElementWithPattern
|
||||
element :sast_enable_button, "`${feature.type}_enable_button`" # rubocop:disable QA/ElementWithPattern
|
||||
element :dependency_scanning_mr_button, "`${feature.type}_mr_button`" # rubocop:disable QA/ElementWithPattern
|
||||
end
|
||||
|
||||
def click_sast_enable_button
|
||||
click_element(:sast_enable_button)
|
||||
end
|
||||
|
||||
def click_dependency_scanning_mr_button
|
||||
click_element(:dependency_scanning_mr_button)
|
||||
end
|
||||
|
||||
def has_sast_status?(status_text)
|
||||
within_element(:sast_status) do
|
||||
has_text?(status_text)
|
||||
end
|
||||
end
|
||||
|
||||
def has_dependency_scanning_status?(status_text)
|
||||
within_element(:dependency_scanning_status) do
|
||||
has_text?(status_text)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -34,6 +34,10 @@ RSpec.describe 'Admin Appearance' do
|
|||
visit admin_application_settings_appearances_path
|
||||
click_link "Sign-in page"
|
||||
|
||||
expect(find('#login')).to be_disabled
|
||||
expect(find('#password')).to be_disabled
|
||||
expect(find('button')).to be_disabled
|
||||
|
||||
expect_custom_sign_in_appearance(appearance)
|
||||
end
|
||||
|
||||
|
|
|
@ -35,9 +35,6 @@ describe('Signup Form', () => {
|
|||
|
||||
const findDenyListRawInputGroup = () => wrapper.findByTestId('domain-denylist-raw-input-group');
|
||||
const findDenyListFileInputGroup = () => wrapper.findByTestId('domain-denylist-file-input-group');
|
||||
|
||||
const findRequireAdminApprovalCheckbox = () =>
|
||||
wrapper.findByTestId('require-admin-approval-checkbox');
|
||||
const findUserCapInput = () => wrapper.findByTestId('user-cap-input');
|
||||
const findModal = () => wrapper.find(GlModal);
|
||||
|
||||
|
@ -191,125 +188,6 @@ describe('Signup Form', () => {
|
|||
});
|
||||
|
||||
describe('form submit button confirmation modal for side-effect of adding possibly unwanted new users', () => {
|
||||
it.each`
|
||||
requireAdminApprovalAction | userCapAction | pendingUserCount | buttonEffect
|
||||
${'unchanged from true'} | ${'unchanged'} | ${0} | ${'submits form'}
|
||||
${'unchanged from false'} | ${'unchanged'} | ${0} | ${'submits form'}
|
||||
${'toggled off'} | ${'unchanged'} | ${1} | ${'shows confirmation modal'}
|
||||
${'toggled off'} | ${'unchanged'} | ${0} | ${'submits form'}
|
||||
${'toggled on'} | ${'unchanged'} | ${0} | ${'submits form'}
|
||||
${'unchanged from false'} | ${'increased'} | ${1} | ${'shows confirmation modal'}
|
||||
${'unchanged from true'} | ${'increased'} | ${0} | ${'submits form'}
|
||||
${'toggled off'} | ${'increased'} | ${1} | ${'shows confirmation modal'}
|
||||
${'toggled off'} | ${'increased'} | ${0} | ${'submits form'}
|
||||
${'toggled on'} | ${'increased'} | ${1} | ${'shows confirmation modal'}
|
||||
${'toggled on'} | ${'increased'} | ${0} | ${'submits form'}
|
||||
${'toggled on'} | ${'decreased'} | ${0} | ${'submits form'}
|
||||
${'toggled on'} | ${'decreased'} | ${1} | ${'submits form'}
|
||||
${'unchanged from false'} | ${'changed from limited to unlimited'} | ${1} | ${'shows confirmation modal'}
|
||||
${'unchanged from false'} | ${'changed from limited to unlimited'} | ${0} | ${'submits form'}
|
||||
${'unchanged from false'} | ${'changed from unlimited to limited'} | ${0} | ${'submits form'}
|
||||
${'unchanged from false'} | ${'unchanged from unlimited'} | ${0} | ${'submits form'}
|
||||
`(
|
||||
'$buttonEffect if require admin approval for new sign-ups is $requireAdminApprovalAction and the user cap is $userCapAction and pending user count is $pendingUserCount',
|
||||
async ({ requireAdminApprovalAction, userCapAction, pendingUserCount, buttonEffect }) => {
|
||||
let isModalDisplayed;
|
||||
|
||||
switch (buttonEffect) {
|
||||
case 'shows confirmation modal':
|
||||
isModalDisplayed = true;
|
||||
break;
|
||||
case 'submits form':
|
||||
isModalDisplayed = false;
|
||||
break;
|
||||
default:
|
||||
isModalDisplayed = false;
|
||||
break;
|
||||
}
|
||||
|
||||
const isFormSubmittedWhenClickingFormSubmitButton = !isModalDisplayed;
|
||||
|
||||
const injectedProps = {
|
||||
pendingUserCount,
|
||||
};
|
||||
|
||||
const USER_CAP_DEFAULT = 5;
|
||||
|
||||
switch (userCapAction) {
|
||||
case 'changed from unlimited to limited':
|
||||
injectedProps.newUserSignupsCap = '';
|
||||
break;
|
||||
case 'unchanged from unlimited':
|
||||
injectedProps.newUserSignupsCap = '';
|
||||
break;
|
||||
default:
|
||||
injectedProps.newUserSignupsCap = USER_CAP_DEFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (requireAdminApprovalAction) {
|
||||
case 'unchanged from true':
|
||||
injectedProps.requireAdminApprovalAfterUserSignup = true;
|
||||
break;
|
||||
case 'unchanged from false':
|
||||
injectedProps.requireAdminApprovalAfterUserSignup = false;
|
||||
break;
|
||||
case 'toggled off':
|
||||
injectedProps.requireAdminApprovalAfterUserSignup = true;
|
||||
break;
|
||||
case 'toggled on':
|
||||
injectedProps.requireAdminApprovalAfterUserSignup = false;
|
||||
break;
|
||||
default:
|
||||
injectedProps.requireAdminApprovalAfterUserSignup = false;
|
||||
break;
|
||||
}
|
||||
|
||||
formSubmitSpy = jest.spyOn(HTMLFormElement.prototype, 'submit').mockImplementation();
|
||||
|
||||
await mountComponent({
|
||||
injectedProps,
|
||||
stubs: { GlButton, GlModal: stubComponent(GlModal) },
|
||||
});
|
||||
|
||||
findModal().vm.show = jest.fn();
|
||||
|
||||
if (
|
||||
requireAdminApprovalAction === 'toggled off' ||
|
||||
requireAdminApprovalAction === 'toggled on'
|
||||
) {
|
||||
await findRequireAdminApprovalCheckbox().vm.$emit('input', false);
|
||||
}
|
||||
|
||||
switch (userCapAction) {
|
||||
case 'increased':
|
||||
await findUserCapInput().vm.$emit('input', USER_CAP_DEFAULT + 1);
|
||||
break;
|
||||
case 'decreased':
|
||||
await findUserCapInput().vm.$emit('input', USER_CAP_DEFAULT - 1);
|
||||
break;
|
||||
case 'changed from limited to unlimited':
|
||||
await findUserCapInput().vm.$emit('input', '');
|
||||
break;
|
||||
case 'changed from unlimited to limited':
|
||||
await findUserCapInput().vm.$emit('input', USER_CAP_DEFAULT);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
await findFormSubmitButton().trigger('click');
|
||||
|
||||
if (isFormSubmittedWhenClickingFormSubmitButton) {
|
||||
expect(formSubmitSpy).toHaveBeenCalled();
|
||||
expect(findModal().vm.show).not.toHaveBeenCalled();
|
||||
} else {
|
||||
expect(formSubmitSpy).not.toHaveBeenCalled();
|
||||
expect(findModal().vm.show).toHaveBeenCalled();
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
describe('modal actions', () => {
|
||||
beforeEach(async () => {
|
||||
const INITIAL_USER_CAP = 5;
|
||||
|
|
|
@ -271,18 +271,6 @@ RSpec.describe ApplicationSettingsHelper do
|
|||
expect(pending_user_count).to eq 1
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the new_user_signups_cap is not present' do
|
||||
let(:user_cap) { nil }
|
||||
|
||||
it { is_expected.to eq 0 }
|
||||
|
||||
it 'does not query users unnecessarily' do
|
||||
expect(User).not_to receive(:blocked_pending_approval)
|
||||
|
||||
pending_user_count
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#sidekiq_job_limiter_modes_for_select' do
|
||||
|
|
15
spec/lib/sidebars/groups/menus/scope_menu_spec.rb
Normal file
15
spec/lib/sidebars/groups/menus/scope_menu_spec.rb
Normal file
|
@ -0,0 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Sidebars::Groups::Menus::ScopeMenu do
|
||||
let(:group) { build(:group) }
|
||||
let(:user) { group.owner }
|
||||
let(:context) { Sidebars::Groups::Context.new(current_user: user, container: group) }
|
||||
|
||||
describe '#extra_nav_link_html_options' do
|
||||
subject { described_class.new(context).extra_nav_link_html_options }
|
||||
|
||||
specify { is_expected.to match(hash_including(class: 'context-header has-tooltip', title: context.group.name)) }
|
||||
end
|
||||
end
|
|
@ -12,4 +12,10 @@ RSpec.describe Sidebars::Projects::Menus::ScopeMenu do
|
|||
|
||||
specify { is_expected.to match(hash_including(class: 'shortcuts-project rspec-project-link')) }
|
||||
end
|
||||
|
||||
describe '#extra_nav_link_html_options' do
|
||||
subject { described_class.new(context).extra_nav_link_html_options }
|
||||
|
||||
specify { is_expected.to match(hash_including(class: 'context-header has-tooltip', title: context.project.name)) }
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue