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
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/invite_members/components/invite_members_modal.vue7
-rw-r--r--app/assets/javascripts/invite_members/components/invite_modal_base.vue2
-rw-r--r--app/assets/javascripts/invite_members/components/user_limit_notification.vue97
-rw-r--r--app/assets/javascripts/invite_members/init_invite_members_modal.js5
-rw-r--r--app/assets/javascripts/lib/graphql.js3
-rw-r--r--app/assets/javascripts/runner/components/cells/runner_summary_cell.vue12
-rw-r--r--app/assets/javascripts/runner/components/runner_list.vue7
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_how_to_merge_modal.vue2
-rw-r--r--app/helpers/invite_members_helper.rb1
-rw-r--r--db/fixtures/development/02_users.rb2
-rw-r--r--db/fixtures/development/03_project_3_features.rb2
-rw-r--r--db/fixtures/development/03_project_4_routes.rb2
-rw-r--r--doc/administration/index.md2
-rw-r--r--doc/development/fe_guide/accessibility.md2
-rw-r--r--doc/development/fe_guide/performance.md2
-rw-r--r--doc/development/fe_guide/source_editor.md10
-rw-r--r--doc/development/fe_guide/vue.md4
-rw-r--r--doc/development/fe_guide/vue3_migration.md2
-rw-r--r--doc/development/secure_coding_guidelines.md2
-rw-r--r--doc/development/testing_guide/best_practices.md2
-rw-r--r--doc/development/testing_guide/end_to_end/execution_context_selection.md4
-rw-r--r--doc/development/testing_guide/end_to_end/feature_flags.md2
-rw-r--r--doc/development/testing_guide/end_to_end/index.md2
-rw-r--r--doc/development/testing_guide/end_to_end/rspec_metadata_tests.md2
-rw-r--r--doc/development/testing_guide/end_to_end/running_tests_that_require_special_setup.md4
-rw-r--r--doc/integration/gitpod.md2
-rw-r--r--doc/integration/index.md2
-rw-r--r--doc/integration/jira/index.md2
-rw-r--r--doc/integration/mattermost/index.md4
-rw-r--r--doc/integration/salesforce.md2
-rw-r--r--doc/integration/saml.md2
-rw-r--r--doc/subscriptions/index.md4
-rw-r--r--doc/update/index.md10
-rw-r--r--doc/user/packages/container_registry/reduce_container_registry_storage.md2
-rw-r--r--locale/gitlab.pot20
-rwxr-xr-xscripts/review_apps/review-apps.sh4
-rw-r--r--spec/frontend/invite_members/components/user_limit_notification_spec.js71
-rw-r--r--spec/frontend/runner/components/cells/runner_summary_cell_spec.js6
-rw-r--r--spec/frontend/runner/components/runner_list_spec.js4
39 files changed, 264 insertions, 53 deletions
diff --git a/app/assets/javascripts/invite_members/components/invite_members_modal.vue b/app/assets/javascripts/invite_members/components/invite_members_modal.vue
index da0c7860932..23225869636 100644
--- a/app/assets/javascripts/invite_members/components/invite_members_modal.vue
+++ b/app/assets/javascripts/invite_members/components/invite_members_modal.vue
@@ -24,6 +24,7 @@ import { responseMessageFromSuccess } from '../utils/response_message_parser';
import { getInvalidFeedbackMessage } from '../utils/get_invalid_feedback_message';
import ModalConfetti from './confetti.vue';
import MembersTokenSelect from './members_token_select.vue';
+import UserLimitNotification from './user_limit_notification.vue';
export default {
name: 'InviteMembersModal',
@@ -37,6 +38,7 @@ export default {
InviteModalBase,
MembersTokenSelect,
ModalConfetti,
+ UserLimitNotification,
},
inject: ['newProjectPath'],
props: {
@@ -308,6 +310,11 @@ export default {
<span v-if="isCelebration">{{ $options.labels.modal.celebrate.intro }} </span>
<modal-confetti v-if="isCelebration" />
</template>
+
+ <template #user-limit-notification>
+ <user-limit-notification />
+ </template>
+
<template #select="{ validationState, labelId }">
<members-token-select
v-model="newUsersToInvite"
diff --git a/app/assets/javascripts/invite_members/components/invite_modal_base.vue b/app/assets/javascripts/invite_members/components/invite_modal_base.vue
index bafbe94b8bd..43cd889c9b3 100644
--- a/app/assets/javascripts/invite_members/components/invite_modal_base.vue
+++ b/app/assets/javascripts/invite_members/components/invite_modal_base.vue
@@ -215,6 +215,8 @@ export default {
<slot name="intro-text-after"></slot>
</div>
+ <slot name="user-limit-notification"></slot>
+
<gl-form-group
:invalid-feedback="invalidFeedbackMessage"
:state="validationState"
diff --git a/app/assets/javascripts/invite_members/components/user_limit_notification.vue b/app/assets/javascripts/invite_members/components/user_limit_notification.vue
new file mode 100644
index 00000000000..beef1aef8a1
--- /dev/null
+++ b/app/assets/javascripts/invite_members/components/user_limit_notification.vue
@@ -0,0 +1,97 @@
+<script>
+import { GlAlert, GlSprintf, GlLink } from '@gitlab/ui';
+import { s__, n__, sprintf } from '~/locale';
+
+const CLOSE_TO_LIMIT_COUNT = 2;
+
+const WARNING_ALERT_TITLE = s__(
+ 'InviteMembersModal|You only have space for %{count} more %{members} in %{name}',
+);
+
+const DANGER_ALERT_TITLE = s__(
+ "InviteMembersModal|You've reached your %{count} %{members} limit for %{name}",
+);
+
+const CLOSE_TO_LIMIT_MESSAGE = s__(
+ 'InviteMembersModal|To get more members an owner of this namespace can %{trialLinkStart}start a trial%{trialLinkEnd} or %{upgradeLinkStart}upgrade%{upgradeLinkEnd} to a paid tier.',
+);
+
+const REACHED_LIMIT_MESSAGE = s__(
+ 'InviteMembersModal|New members will be unable to participate. You can manage your members by removing ones you no longer need.',
+).concat(' ', CLOSE_TO_LIMIT_MESSAGE);
+
+export default {
+ name: 'UserLimitNotification',
+ components: { GlAlert, GlSprintf, GlLink },
+ inject: ['name', 'newTrialRegistrationPath', 'purchasePath', 'freeUsersLimit', 'membersCount'],
+ computed: {
+ reachedLimit() {
+ return this.isLimit();
+ },
+ closeToLimit() {
+ return this.isLimit(CLOSE_TO_LIMIT_COUNT);
+ },
+ warningAlertTitle() {
+ return sprintf(WARNING_ALERT_TITLE, {
+ count: this.freeUsersLimit - this.membersCount,
+ members: this.pluralMembers(this.freeUsersLimit - this.membersCount),
+ name: this.name,
+ });
+ },
+ dangerAlertTitle() {
+ return sprintf(DANGER_ALERT_TITLE, {
+ count: this.freeUsersLimit,
+ members: this.pluralMembers(this.freeUsersLimit),
+ name: this.name,
+ });
+ },
+ variant() {
+ return this.reachedLimit ? 'danger' : 'warning';
+ },
+ title() {
+ return this.reachedLimit ? this.dangerAlertTitle : this.warningAlertTitle;
+ },
+ message() {
+ if (this.reachedLimit) {
+ return this.$options.i18n.reachedLimitMessage;
+ }
+
+ return this.$options.i18n.closeToLimitMessage;
+ },
+ },
+ methods: {
+ isLimit(deviation = 0) {
+ if (this.freeUsersLimit && this.membersCount) {
+ return this.membersCount >= this.freeUsersLimit - deviation;
+ }
+
+ return false;
+ },
+ pluralMembers(count) {
+ return n__('member', 'members', count);
+ },
+ },
+ i18n: {
+ reachedLimitMessage: REACHED_LIMIT_MESSAGE,
+ closeToLimitMessage: CLOSE_TO_LIMIT_MESSAGE,
+ },
+};
+</script>
+
+<template>
+ <gl-alert
+ v-if="reachedLimit || closeToLimit"
+ :variant="variant"
+ :dismissible="false"
+ :title="title"
+ >
+ <gl-sprintf :message="message">
+ <template #trialLink="{ content }">
+ <gl-link :href="newTrialRegistrationPath" class="gl-label-link">{{ content }}</gl-link>
+ </template>
+ <template #upgradeLink="{ content }">
+ <gl-link :href="purchasePath" class="gl-label-link">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </gl-alert>
+</template>
diff --git a/app/assets/javascripts/invite_members/init_invite_members_modal.js b/app/assets/javascripts/invite_members/init_invite_members_modal.js
index cb05798bb9d..958121ad735 100644
--- a/app/assets/javascripts/invite_members/init_invite_members_modal.js
+++ b/app/assets/javascripts/invite_members/init_invite_members_modal.js
@@ -24,7 +24,12 @@ export default (function initInviteMembersModal() {
el,
name: 'InviteMembersModalRoot',
provide: {
+ name: el.dataset.name,
newProjectPath: el.dataset.newProjectPath,
+ newTrialRegistrationPath: el.dataset.newTrialRegistrationPath,
+ purchasePath: el.dataset.purchasePath,
+ freeUsersLimit: el.dataset.freeUsersLimit && parseInt(el.dataset.freeUsersLimit, 10),
+ membersCount: el.dataset.membersCount && parseInt(el.dataset.membersCount, 10),
},
render: (createElement) =>
createElement(InviteMembersModal, {
diff --git a/app/assets/javascripts/lib/graphql.js b/app/assets/javascripts/lib/graphql.js
index b0eafc2668e..451950346b0 100644
--- a/app/assets/javascripts/lib/graphql.js
+++ b/app/assets/javascripts/lib/graphql.js
@@ -47,6 +47,9 @@ export const typePolicies = {
DesignCollection: {
merge: true,
},
+ TreeEntry: {
+ keyFields: ['webPath'],
+ },
};
export const stripWhitespaceFromQuery = (url, path) => {
diff --git a/app/assets/javascripts/runner/components/cells/runner_summary_cell.vue b/app/assets/javascripts/runner/components/cells/runner_summary_cell.vue
index 937ec631633..754908c9385 100644
--- a/app/assets/javascripts/runner/components/cells/runner_summary_cell.vue
+++ b/app/assets/javascripts/runner/components/cells/runner_summary_cell.vue
@@ -33,6 +33,9 @@ export default {
description() {
return this.runner.description;
},
+ ipAddress() {
+ return this.runner.ipAddress;
+ },
},
i18n: {
I18N_LOCKED_RUNNER_DESCRIPTION,
@@ -53,10 +56,11 @@ export default {
:title="$options.i18n.I18N_LOCKED_RUNNER_DESCRIPTION"
name="lock"
/>
- <tooltip-on-truncate class="gl-display-block" :title="description" truncate-target="child">
- <div class="gl-text-truncate">
- {{ description }}
- </div>
+ <tooltip-on-truncate class="gl-display-block gl-text-truncate" :title="description">
+ {{ description }}
+ </tooltip-on-truncate>
+ <tooltip-on-truncate class="gl-display-block gl-text-truncate" :title="ipAddress">
+ {{ __('IP Address') }} <strong>{{ ipAddress }}</strong>
</tooltip-on-truncate>
</div>
</template>
diff --git a/app/assets/javascripts/runner/components/runner_list.vue b/app/assets/javascripts/runner/components/runner_list.vue
index 51749b0255f..819b6951e13 100644
--- a/app/assets/javascripts/runner/components/runner_list.vue
+++ b/app/assets/javascripts/runner/components/runner_list.vue
@@ -60,7 +60,6 @@ export default {
tableField({ key: 'status', label: s__('Runners|Status') }),
tableField({ key: 'summary', label: s__('Runners|Runner'), thClasses: ['gl-lg-w-25p'] }),
tableField({ key: 'version', label: __('Version') }),
- tableField({ key: 'ipAddress', label: __('IP') }),
tableField({ key: 'jobCount', label: __('Jobs') }),
tableField({ key: 'tagList', label: __('Tags'), thClasses: ['gl-lg-w-25p'] }),
tableField({ key: 'contactedAt', label: __('Last contact') }),
@@ -99,12 +98,6 @@ export default {
</tooltip-on-truncate>
</template>
- <template #cell(ipAddress)="{ item: { ipAddress } }">
- <tooltip-on-truncate class="gl-display-block gl-text-truncate" :title="ipAddress">
- {{ ipAddress }}
- </tooltip-on-truncate>
- </template>
-
<template #cell(jobCount)="{ item: { jobCount } }">
{{ formatJobCount(jobCount) }}
</template>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_how_to_merge_modal.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_how_to_merge_modal.vue
index b062833cdf8..e906b8c3b59 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_how_to_merge_modal.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_how_to_merge_modal.vue
@@ -79,7 +79,7 @@ export default {
},
data() {
return {
- resolveConflictsFromCli: helpPagePath('ee/user/project/merge_requests/conflicts.html', {
+ resolveConflictsFromCli: helpPagePath('user/project/merge_requests/conflicts', {
anchor: 'resolve-conflicts-from-the-command-line',
}),
};
diff --git a/app/helpers/invite_members_helper.rb b/app/helpers/invite_members_helper.rb
index 885f6bac510..a682d2712be 100644
--- a/app/helpers/invite_members_helper.rb
+++ b/app/helpers/invite_members_helper.rb
@@ -46,6 +46,7 @@ module InviteMembersHelper
}
end
+ # Overridden in EE
def common_invite_modal_dataset(source)
dataset = {
id: source.id,
diff --git a/db/fixtures/development/02_users.rb b/db/fixtures/development/02_users.rb
index 03e4605e729..ceed0d6d12a 100644
--- a/db/fixtures/development/02_users.rb
+++ b/db/fixtures/development/02_users.rb
@@ -4,7 +4,7 @@ class Gitlab::Seeder::Users
include ActionView::Helpers::NumberHelper
RANDOM_USERS_COUNT = 20
- MASS_NAMESPACES_COUNT = 100
+ MASS_NAMESPACES_COUNT = ENV['CI'] ? 1 : 100
MASS_USERS_COUNT = ENV['CI'] ? 10 : 1_000_000
attr_reader :opts
diff --git a/db/fixtures/development/03_project_3_features.rb b/db/fixtures/development/03_project_3_features.rb
index 8b910af2c6c..374d46d030e 100644
--- a/db/fixtures/development/03_project_3_features.rb
+++ b/db/fixtures/development/03_project_3_features.rb
@@ -13,7 +13,7 @@ class Gitlab::Seeder::ProjectFeatures
Gitlab::Seeder.with_mass_insert(Project.count, "Project features") do
Project.each_batch(of: BATCH_SIZE) do |batch, index|
range = batch.pluck(Arel.sql('MIN(id)'), Arel.sql('MAX(id)')).first
- count = index * BATCH_SIZE
+ count = index * batch.size
Gitlab::Seeder.log_message("Creating project features: #{count}.")
ActiveRecord::Base.connection.execute <<~SQL
diff --git a/db/fixtures/development/03_project_4_routes.rb b/db/fixtures/development/03_project_4_routes.rb
index 66da34ce83c..3340849a733 100644
--- a/db/fixtures/development/03_project_4_routes.rb
+++ b/db/fixtures/development/03_project_4_routes.rb
@@ -13,7 +13,7 @@ class Gitlab::Seeder::ProjectRoutes
Gitlab::Seeder.with_mass_insert(Project.count, "Project routes") do
Project.each_batch(of: BATCH_SIZE / 2) do |batch, index|
range = batch.pluck(Arel.sql('MIN(id)'), Arel.sql('MAX(id)')).first
- count = index * BATCH_SIZE / 2
+ count = index * batch.size
Gitlab::Seeder.log_message("Creating project routes: #{count}.")
ActiveRecord::Base.connection.execute <<~SQL
diff --git a/doc/administration/index.md b/doc/administration/index.md
index 89d1f2ce2eb..fa473332717 100644
--- a/doc/administration/index.md
+++ b/doc/administration/index.md
@@ -32,7 +32,7 @@ Learn how to install, configure, update, and maintain your GitLab instance.
- [Install](../install/index.md): Requirements, directory structures, and installation methods.
- [Reference architectures](reference_architectures/index.md): Add additional resources to support more users.
- - [Installing GitLab on Amazon Web Services (AWS)](../install/aws/index.md): Set up GitLab on Amazon AWS.
+- [Installing GitLab on Amazon Web Services (AWS)](../install/aws/index.md): Set up GitLab on Amazon AWS.
- [Geo](geo/index.md): Replicate your GitLab instance to other geographic locations as a read-only fully operational version.
- [Disaster Recovery](geo/disaster_recovery/index.md): Quickly fail-over to a different site with minimal effort in a disaster situation.
- [Add License](../user/admin_area/license.md): Add a license at install time to unlock features that are in paid tiers of GitLab.
diff --git a/doc/development/fe_guide/accessibility.md b/doc/development/fe_guide/accessibility.md
index e71e414002a..2a1083d031f 100644
--- a/doc/development/fe_guide/accessibility.md
+++ b/doc/development/fe_guide/accessibility.md
@@ -32,7 +32,7 @@ By default, macOS limits the <kbd>tab</kbd> key to **Text boxes and lists only**
1. Open the **Shortcuts** tab.
1. Enable the setting **Use keyboard navigation to move focus between controls**.
-You can read more about enabling browser-specific keyboard navigation on [a11yproject](https://www.a11yproject.com/posts/2017-12-29-macos-browser-keyboard-navigation/).
+You can read more about enabling browser-specific keyboard navigation on [a11yproject](https://www.a11yproject.com/posts/macos-browser-keyboard-navigation/).
## Quick checklist
diff --git a/doc/development/fe_guide/performance.md b/doc/development/fe_guide/performance.md
index 94beecf6168..bcdc49a1070 100644
--- a/doc/development/fe_guide/performance.md
+++ b/doc/development/fe_guide/performance.md
@@ -457,6 +457,6 @@ General tips:
## Additional Resources
- [WebPage Test](https://www.webpagetest.org) for testing site loading time and size.
-- [Google PageSpeed Insights](https://developers.google.com/speed/pagespeed/insights/) grades web pages and provides feedback to improve the page.
+- [Google PageSpeed Insights](https://pagespeed.web.dev/) grades web pages and provides feedback to improve the page.
- [Profiling with Chrome DevTools](https://developer.chrome.com/docs/devtools/)
- [Browser Diet](https://browserdiet.com/) is a community-built guide that catalogues practical tips for improving web page performance.
diff --git a/doc/development/fe_guide/source_editor.md b/doc/development/fe_guide/source_editor.md
index 2ff0bacfc3a..b06e341630f 100644
--- a/doc/development/fe_guide/source_editor.md
+++ b/doc/development/fe_guide/source_editor.md
@@ -35,7 +35,7 @@ Vue component, but the integration of Source Editor is generally straightforward
const editor = new SourceEditor({
// Editor Options.
// The list of all accepted options can be found at
- // https://microsoft.github.io/monaco-editor/api/enums/monaco.editor.editoroption.html
+ // https://microsoft.github.io/monaco-editor/api/enums/monaco.editor.EditorOption.html
});
```
@@ -56,19 +56,19 @@ An instance of Source Editor accepts the following configuration options:
| `blobContent` | `false` | `String`: The initial content to render in the editor. |
| `extensions` | `false` | `Array`: Extensions to use in this instance. |
| `blobGlobalId` | `false` | `String`: An auto-generated property.<br>**Note:** This property may go away in the future. Do not pass `blobGlobalId` unless you know what you're doing.|
-| Editor Options | `false` | `Object(s)`: Any property outside of the list above is treated as an Editor Option for this particular instance. Use this field to override global Editor Options on the instance level. A full [index of Editor Options](https://microsoft.github.io/monaco-editor/api/enums/monaco.editor.editoroption.html) is available. |
+| Editor Options | `false` | `Object(s)`: Any property outside of the list above is treated as an Editor Option for this particular instance. Use this field to override global Editor Options on the instance level. A full [index of Editor Options](https://microsoft.github.io/monaco-editor/api/enums/monaco.editor.EditorOption.html) is available. |
## API
The editor uses the same public API as
-[provided by Monaco editor](https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.istandalonecodeeditor.html)
+[provided by Monaco editor](https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.IStandaloneCodeEditor.html)
with additional functions on the instance level:
| Function | Arguments | Description
| --------------------- | ----- | ----- |
| `updateModelLanguage` | `path`: String | Updates the instance's syntax highlighting to follow the extension of the passed `path`. Available only on the instance level.|
| `use` | Array of objects | Array of extensions to apply to the instance. Accepts only the array of _objects_. You must fetch the extensions' ES6 modules must be fetched and resolved in your views or components before they are passed to `use`. This property is available on _instance_ (applies extension to this particular instance) and _global editor_ (applies the same extension to all instances) levels. |
-| Monaco Editor options | See [documentation](https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.istandalonecodeeditor.html) | Default Monaco editor options |
+| Monaco Editor options | See [documentation](https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.IStandaloneCodeEditor.html) | Default Monaco editor options |
## Tips
@@ -202,7 +202,7 @@ export default {
In the code example, `this` refers to the instance. By referring to the instance,
we can access the complete underlying
-[Monaco editor API](https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.istandalonecodeeditor.html),
+[Monaco editor API](https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.IStandaloneCodeEditor.html),
which includes functions like `getValue()`.
Now let's use our extension:
diff --git a/doc/development/fe_guide/vue.md b/doc/development/fe_guide/vue.md
index b947d90cc11..2119a49aea8 100644
--- a/doc/development/fe_guide/vue.md
+++ b/doc/development/fe_guide/vue.md
@@ -499,7 +499,7 @@ component under test, with the `computed` property, for example). Remember to us
We should test for events emitted in response to an action in our component. This is used to
verify the correct events are being fired with the correct arguments.
-For any DOM events we should use [`trigger`](https://vue-test-utils.vuejs.org/api/wrapper/#trigger)
+For any DOM events we should use [`trigger`](https://v1.test-utils.vuejs.org/api/wrapper/#trigger)
to fire out event.
```javascript
@@ -530,7 +530,7 @@ it('should fire the itemClicked event', () => {
```
We should verify an event has been fired by asserting against the result of the
-[`emitted()`](https://vue-test-utils.vuejs.org/api/wrapper/#emitted) method.
+[`emitted()`](https://v1.test-utils.vuejs.org/api/wrapper/#emitted) method.
## Vue.js Expert Role
diff --git a/doc/development/fe_guide/vue3_migration.md b/doc/development/fe_guide/vue3_migration.md
index f174408c946..8c8bb36d962 100644
--- a/doc/development/fe_guide/vue3_migration.md
+++ b/doc/development/fe_guide/vue3_migration.md
@@ -156,6 +156,6 @@ export default {
</template>
```
-[In Vue 3](https://v3.vuejs.org/guide/migration/props-default-this.html#props-default-function-this-access),
+[In Vue 3](https://v3-migration.vuejs.org/breaking-changes/props-default-this.html),
the props default value factory is passed the raw props as an argument, and can
also access injections.
diff --git a/doc/development/secure_coding_guidelines.md b/doc/development/secure_coding_guidelines.md
index ad5bb7cd08b..8a86a46d1d3 100644
--- a/doc/development/secure_coding_guidelines.md
+++ b/doc/development/secure_coding_guidelines.md
@@ -203,7 +203,7 @@ Go's [`regexp`](https://pkg.go.dev/regexp) package uses `re2` and isn't vulnerab
### Description
-A [Server-side Request Forgery (SSRF)](https://www.hackerone.com/blog-How-To-Server-Side-Request-Forgery-SSRF) is an attack in which an attacker
+A [Server-side Request Forgery (SSRF)](https://www.hackerone.com/application-security/how-server-side-request-forgery-ssrf) is an attack in which an attacker
is able coerce a application into making an outbound request to an unintended
resource. This resource is usually internal. In GitLab, the connection most
commonly uses HTTP, but an SSRF can be performed with any protocol, such as
diff --git a/doc/development/testing_guide/best_practices.md b/doc/development/testing_guide/best_practices.md
index 09306dfc2a7..7ae49d33e91 100644
--- a/doc/development/testing_guide/best_practices.md
+++ b/doc/development/testing_guide/best_practices.md
@@ -21,7 +21,7 @@ a level that is difficult to manage.
Test heuristics can help solve this problem. They concisely address many of the common ways bugs
manifest themselves in our code. When designing our tests, take time to review known test heuristics to inform
our test design. We can find some helpful heuristics documented in the Handbook in the
-[Test Engineering](https://about.gitlab.com/handbook/engineering/quality/test-engineering/#test-heuristics) section.
+[Test Engineering](https://about.gitlab.com/handbook/engineering/quality/quality-engineering/test-engineering/#test-heuristics) section.
## RSpec
diff --git a/doc/development/testing_guide/end_to_end/execution_context_selection.md b/doc/development/testing_guide/end_to_end/execution_context_selection.md
index 0fdcf0c8c3b..0a4c5fcf451 100644
--- a/doc/development/testing_guide/end_to_end/execution_context_selection.md
+++ b/doc/development/testing_guide/end_to_end/execution_context_selection.md
@@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Execution context selection
-Some tests are designed to be run against specific environments, or in specific [pipelines](https://about.gitlab.com/handbook/engineering/quality/guidelines/debugging-qa-test-failures/#scheduled-qa-test-pipelines) or jobs. We can specify the test execution context using the `only` and `except` metadata.
+Some tests are designed to be run against specific environments, or in specific [pipelines](https://about.gitlab.com/handbook/engineering/quality/quality-engineering/debugging-qa-test-failures/#scheduled-qa-test-pipelines) or jobs. We can specify the test execution context using the `only` and `except` metadata.
## Available switches
@@ -118,7 +118,7 @@ To run a test tagged with `except` locally, you can either:
Similarly to specifying that a test should only run against a specific environment, it's also possible to quarantine a
test only when it runs against a specific environment. The syntax is exactly the same, except that the `only: { ... }`
-hash is nested in the [`quarantine: { ... }`](https://about.gitlab.com/handbook/engineering/quality/guidelines/debugging-qa-test-failures/#quarantining-tests) hash.
+hash is nested in the [`quarantine: { ... }`](https://about.gitlab.com/handbook/engineering/quality/quality-engineering/debugging-qa-test-failures/#quarantining-tests) hash.
For example, `quarantine: { only: { subdomain: :staging } }` only quarantines the test when run against `staging`.
The quarantine feature can be explicitly disabled with the `DISABLE_QUARANTINE` environment variable. This can be useful when running tests locally.
diff --git a/doc/development/testing_guide/end_to_end/feature_flags.md b/doc/development/testing_guide/end_to_end/feature_flags.md
index c3e3f117c2b..2547c41eb82 100644
--- a/doc/development/testing_guide/end_to_end/feature_flags.md
+++ b/doc/development/testing_guide/end_to_end/feature_flags.md
@@ -162,7 +162,7 @@ for details.
## Confirming that end-to-end tests pass with a feature flag enabled
-End-to-end tests should pass with a feature flag enabled before it is enabled on Staging or on GitLab.com. Tests that need to be updated should be identified as part of [quad-planning](https://about.gitlab.com/handbook/engineering/quality/quad-planning/). The relevant [counterpart Software Engineer in Test](https://about.gitlab.com/handbook/engineering/quality/#individual-contributors) is responsible for updating the tests or assisting another engineer to do so. However, if a change does not go through quad-planning and a required test update is not made, test failures could block deployment.
+End-to-end tests should pass with a feature flag enabled before it is enabled on Staging or on GitLab.com. Tests that need to be updated should be identified as part of [quad-planning](https://about.gitlab.com/handbook/engineering/quality/quality-engineering/quad-planning/). The relevant [counterpart Software Engineer in Test](https://about.gitlab.com/handbook/engineering/quality/#individual-contributors) is responsible for updating the tests or assisting another engineer to do so. However, if a change does not go through quad-planning and a required test update is not made, test failures could block deployment.
### Automatic test execution when a feature flag definition changes
diff --git a/doc/development/testing_guide/end_to_end/index.md b/doc/development/testing_guide/end_to_end/index.md
index dc989acbdcc..481a3e2ba99 100644
--- a/doc/development/testing_guide/end_to_end/index.md
+++ b/doc/development/testing_guide/end_to_end/index.md
@@ -135,7 +135,7 @@ The [existing scenarios](https://gitlab.com/gitlab-org/gitlab-qa/blob/master/doc
that run in the downstream `gitlab-qa-mirror` pipeline include many tests, but there are times when you might want to run a
test or a group of tests that are different than the groups in any of the existing scenarios.
-For example, when we [dequarantine](https://about.gitlab.com/handbook/engineering/quality/guidelines/debugging-qa-test-failures/#dequarantining-tests)
+For example, when we [dequarantine](https://about.gitlab.com/handbook/engineering/quality/quality-engineering/debugging-qa-test-failures/#dequarantining-tests)
a flaky test we first want to make sure that it's no longer flaky.
We can do that using the `ce:custom-parallel` and `ee:custom-parallel` jobs.
Both are manual jobs that you can configure using custom variables.
diff --git a/doc/development/testing_guide/end_to_end/rspec_metadata_tests.md b/doc/development/testing_guide/end_to_end/rspec_metadata_tests.md
index f9b505a8271..3a8c5118c2f 100644
--- a/doc/development/testing_guide/end_to_end/rspec_metadata_tests.md
+++ b/doc/development/testing_guide/end_to_end/rspec_metadata_tests.md
@@ -33,7 +33,7 @@ This is a partial list of the [RSpec metadata](https://relishapp.com/rspec/rspec
| `:only` | The test is only to be run in specific execution contexts. See [test execution context selection](execution_context_selection.md) for more information. |
| `:orchestrated` | The GitLab instance under test may be [configured by `gitlab-qa`](https://gitlab.com/gitlab-org/gitlab-qa/-/blob/master/docs/what_tests_can_be_run.md#orchestrated-tests) to be different to the default GitLab configuration, or `gitlab-qa` may launch additional services in separate Docker containers, or both. Tests tagged with `:orchestrated` are excluded when testing environments where we can't dynamically modify the GitLab configuration (for example, Staging). |
| `:packages` | The test requires a GitLab instance that has the [Package Registry](../../../administration/packages/#gitlab-package-registry-administration) enabled. |
-| `:quarantine` | The test has been [quarantined](https://about.gitlab.com/handbook/engineering/quality/guidelines/debugging-qa-test-failures/#quarantining-tests), runs in a separate job that only includes quarantined tests, and is allowed to fail. The test is skipped in its regular job so that if it fails it doesn't hold up the pipeline. Note that you can also [quarantine a test only when it runs in a specific context](execution_context_selection.md#quarantine-a-test-for-a-specific-environment). |
+| `:quarantine` | The test has been [quarantined](https://about.gitlab.com/handbook/engineering/quality/quality-engineering/debugging-qa-test-failures/#quarantining-tests), runs in a separate job that only includes quarantined tests, and is allowed to fail. The test is skipped in its regular job so that if it fails it doesn't hold up the pipeline. Note that you can also [quarantine a test only when it runs in a specific context](execution_context_selection.md#quarantine-a-test-for-a-specific-environment). |
| `:relative_url` | The test requires a GitLab instance to be installed under a [relative URL](../../../install/relative_url.md). |
| `:reliable` | The test has been [promoted to a reliable test](https://about.gitlab.com/handbook/engineering/quality/quality-engineering/reliable-tests/#promoting-an-existing-test-to-reliable) meaning it passes consistently in all pipelines, including merge requests. |
| `:repository_storage` | The test requires a GitLab instance to be configured to use multiple [repository storage paths](../../../administration/repository_storage_paths.md). Paired with the `:orchestrated` tag. |
diff --git a/doc/development/testing_guide/end_to_end/running_tests_that_require_special_setup.md b/doc/development/testing_guide/end_to_end/running_tests_that_require_special_setup.md
index 49a9124253d..599e1104b72 100644
--- a/doc/development/testing_guide/end_to_end/running_tests_that_require_special_setup.md
+++ b/doc/development/testing_guide/end_to_end/running_tests_that_require_special_setup.md
@@ -299,7 +299,7 @@ Geo requires an EE license. To visit the Geo sites in your browser, you need a r
#### Notes
-- You can find the full image address from a pipeline by [following these instructions](https://about.gitlab.com/handbook/engineering/quality/guidelines/tips-and-tricks/#running-gitlab-qa-pipeline-against-a-specific-gitlab-release). You might be prompted to set the `GITLAB_QA_ACCESS_TOKEN` variable if you specify the full image address.
+- You can find the full image address from a pipeline by [following these instructions](https://about.gitlab.com/handbook/engineering/quality/quality-engineering/tips-and-tricks/#running-gitlab-qa-pipeline-against-a-specific-gitlab-release). You might be prompted to set the `GITLAB_QA_ACCESS_TOKEN` variable if you specify the full image address.
- You can increase the wait time for replication by setting `GEO_MAX_FILE_REPLICATION_TIME` and `GEO_MAX_DB_REPLICATION_TIME`. The default is 120 seconds.
- To save time during tests, create a Personal Access Token with API access on the Geo primary node, and pass that value in as `GITLAB_QA_ACCESS_TOKEN` and `GITLAB_QA_ADMIN_ACCESS_TOKEN`.
@@ -395,7 +395,7 @@ Tests that are tagged with `:mobile` can be run against specified mobile devices
Running directly against an environment like staging is not recommended because Sauce Labs test logs expose credentials. Therefore, it is best practice and the default to use a tunnel.
-For tunnel installation instructions, read [Sauce Connect Proxy Installation](https://docs.saucelabs.com/secure-connections/sauce-connect/installation). To start the tunnel, after following the installation above, copy the run command in Sauce Labs > Tunnels (must be logged in to Sauce Labs with the credentials found in 1Password) and run in terminal.
+For tunnel installation instructions, read [Sauce Connect Proxy Installation](https://docs.saucelabs.com/secure-connections/sauce-connect/installation/index.html). To start the tunnel, after following the installation above, copy the run command in Sauce Labs > Tunnels (must be logged in to Sauce Labs with the credentials found in 1Password) and run in terminal.
NOTE:
It is highly recommended to use `GITLAB_QA_ACCESS_TOKEN` to speed up tests and reduce flakiness.
diff --git a/doc/integration/gitpod.md b/doc/integration/gitpod.md
index 977e794396e..f54542ff43f 100644
--- a/doc/integration/gitpod.md
+++ b/doc/integration/gitpod.md
@@ -28,7 +28,7 @@ To use the GitLab Gitpod integration, it must be enabled for your GitLab instanc
1. It's [enabled and configured by a GitLab administrator](#configure-a-self-managed-instance).
1. It's [enabled in their user settings](#enable-gitpod-in-your-user-settings).
-To learn more about Gitpod, see their [features](https://www.gitpod.io/features) and
+To learn more about Gitpod, see their [features](https://www.gitpod.io/) and
[documentation](https://www.gitpod.io/docs/).
## Enable Gitpod in your user settings
diff --git a/doc/integration/index.md b/doc/integration/index.md
index e7f6e01eea1..b26c841f943 100644
--- a/doc/integration/index.md
+++ b/doc/integration/index.md
@@ -89,7 +89,7 @@ at Super User also has relevant information.
**Omnibus Trusted Chain**
-[Install the self signed certificate or custom certificate authorities](https://docs.gitlab.com/omnibus/common_installation_problems/index.html#using-self-signed-certificate-or-custom-certificate-authorities)
+[Install the self signed certificate or custom certificate authorities](https://docs.gitlab.com/omnibus/troubleshooting.html#using-self-signed-certificate-or-custom-certificate-authorities)
in to Omnibus GitLab.
It is enough to concatenate the certificate to the main trusted certificate
diff --git a/doc/integration/jira/index.md b/doc/integration/jira/index.md
index 3052d85b2cb..371f3a4ab8e 100644
--- a/doc/integration/jira/index.md
+++ b/doc/integration/jira/index.md
@@ -56,7 +56,7 @@ or the Jira DVCS (distributed version control system) connector,
## Authentication in Jira
The authentication method in Jira depends on whether you host Jira on your own server or on
-[Atlassian cloud](https://www.atlassian.com/cloud):
+[Atlassian cloud](https://www.atlassian.com/migration/assess/why-cloud):
- **Jira Server** supports basic authentication. When connecting, a **username and password** are
required. Connecting to Jira Server using the Central Authentication Service (CAS) is not possible. For more information, read
diff --git a/doc/integration/mattermost/index.md b/doc/integration/mattermost/index.md
index 6ac4faa5a35..c8e2df1f88f 100644
--- a/doc/integration/mattermost/index.md
+++ b/doc/integration/mattermost/index.md
@@ -477,7 +477,7 @@ Mattermost System Console or manually.
If a configuration setting is specified via both the `gitlab.rb` (as an environment variable)
and `config.json` files, the environment variable gets precedence.
-If you encounter any issues [visit the GitLab Mattermost troubleshooting forum](https://forum.mattermost.org/t/upgrading-to-gitlab-mattermost-in-gitlab-8-9/1735) and share any relevant portions of `mattermost.log` along with the step at which you encountered issues.
+If you encounter any issues [visit the GitLab Mattermost troubleshooting forum](https://forum.mattermost.com/t/upgrading-to-gitlab-mattermost-in-gitlab-8-9/1735) and share any relevant portions of `mattermost.log` along with the step at which you encountered issues.
### Upgrading GitLab Mattermost outside of GitLab
@@ -523,7 +523,7 @@ You can fix this by setting up a `mattermost-cli` [shell alias](#mattermost-comm
For help and support around your GitLab Mattermost deployment please see:
-- [Troubleshooting Forum](https://forum.mattermost.org/t/how-to-use-the-troubleshooting-forum/150) for configuration questions and issues.
+- [Troubleshooting Forum](https://forum.mattermost.com/t/how-to-use-the-troubleshooting-forum/150) for configuration questions and issues.
- [Troubleshooting FAQ](https://docs.mattermost.com/install/troubleshooting.html).
- [Mattermost GitLab Issues Support Handbook](https://docs.mattermost.com/process/support.html?highlight=omnibus#gitlab-issues).
- [GitLab Mattermost issue tracker](https://gitlab.com/gitlab-org/gitlab-mattermost/-/issues) for verified bugs with repro steps.
diff --git a/doc/integration/salesforce.md b/doc/integration/salesforce.md
index ebd936424d3..8d4d8ff9f52 100644
--- a/doc/integration/salesforce.md
+++ b/doc/integration/salesforce.md
@@ -11,7 +11,7 @@ You can integrate your GitLab instance with [Salesforce](https://www.salesforce.
## Create a Salesforce Connected App
To enable Salesforce OmniAuth provider, you must use Salesforce's credentials for your GitLab instance.
-To get the credentials (a pair of Client ID and Client Secret), you must [create a Connected App](https://help.salesforce.com/s/articleView?id=connected_app_create.htm&type=5) on Salesforce.
+To get the credentials (a pair of Client ID and Client Secret), you must [create a Connected App](https://help.salesforce.com/s/articleView?id=sf.connected_app_create.htm&type=5) on Salesforce.
1. Sign in to [Salesforce](https://login.salesforce.com/).
diff --git a/doc/integration/saml.md b/doc/integration/saml.md
index d6099826eb1..c5383f9e34b 100644
--- a/doc/integration/saml.md
+++ b/doc/integration/saml.md
@@ -790,7 +790,7 @@ documentation on how to use SAML to sign in to GitLab.
Examples:
- [ADFS (Active Directory Federation Services)](https://docs.microsoft.com/en-us/windows-server/identity/ad-fs/operations/create-a-relying-party-trust)
-- [Auth0](https://auth0.com/docs/configure/saml-configuration/configure-auth0-saml-identity-provider)
+- [Auth0](https://auth0.com/docs/authenticate/protocols/saml/saml-sso-integrations/configure-auth0-saml-identity-provider)
- [PingOne by Ping Identity](http://docs.pingidentity.com/bundle/pingoneforenterprise/page/xsh1564020480660-1.html)
GitLab provides the following setup notes for guidance only.
diff --git a/doc/subscriptions/index.md b/doc/subscriptions/index.md
index 6c5543edb58..fbeeceb9dbb 100644
--- a/doc/subscriptions/index.md
+++ b/doc/subscriptions/index.md
@@ -34,8 +34,8 @@ GitLab SaaS or GitLab self-managed:
your own GitLab instance.
On a GitLab self-managed instance, a GitLab subscription provides the same set of
-features for _all_ users. On GitLab SaaS, you can apply a subscription to either
-a group or a personal namespace.
+features for _all_ users. On GitLab SaaS, you can apply a subscription to a group
+namespace. You cannot apply a subscription to a personal namespace.
NOTE:
Subscriptions cannot be transferred between GitLab SaaS and GitLab self-managed.
diff --git a/doc/update/index.md b/doc/update/index.md
index 5a00a728535..b9951f3997e 100644
--- a/doc/update/index.md
+++ b/doc/update/index.md
@@ -576,6 +576,8 @@ for how to proceed.
- The support of PostgreSQL 11 [has been dropped](../install/requirements.md#database). Make sure to [update your database](https://docs.gitlab.com/omnibus/settings/database.html#upgrade-packaged-postgresql-server) to version 12 before updating to GitLab 14.0.
- See [Maintenance mode issue in GitLab 13.9 to 14.4](#maintenance-mode-issue-in-gitlab-139-to-144).
+- See [Custom Rack Attack initializers](#custom-rack-attack-initializers) if you persist your own custom Rack Attack
+ initializers during upgrades.
#### Upgrading to later 14.Y releases
@@ -754,6 +756,14 @@ all servers must first be upgraded to 13.1.Z before upgrading to 13.2.0 or later
1. Only then, continue to upgrade to later versions of GitLab.
+#### Custom Rack Attack initializers
+
+From GitLab 13.0.1, custom Rack Attack initializers (`config/initializers/rack_attack.rb`) are replaced with initializers
+supplied with GitLab during upgrades. We recommend you use these GitLab-supplied initializers.
+
+If you persist your own Rack Attack initializers between upgrades, you might
+[get `500` errors](https://gitlab.com/gitlab-org/gitlab/-/issues/334681) when [upgrading to GitLab 14.0 and later](#1400).
+
### 12.2.0
In 12.2.0, we enabled Rails' authenticated cookie encryption. Old sessions are
diff --git a/doc/user/packages/container_registry/reduce_container_registry_storage.md b/doc/user/packages/container_registry/reduce_container_registry_storage.md
index 7e8b2865b6e..ed4a7518746 100644
--- a/doc/user/packages/container_registry/reduce_container_registry_storage.md
+++ b/doc/user/packages/container_registry/reduce_container_registry_storage.md
@@ -79,7 +79,7 @@ the Container Registry after the policy runs. The next time the policy runs, the
so it may take multiple runs for all tags to be deleted.
WARNING:
-GitLab self-managed installs support for third-party container registries that comply with the
+GitLab self-managed installations support third-party container registries that comply with the
[Docker Registry HTTP API V2](https://docs.docker.com/registry/spec/api/)
specification. However, this specification does not include a tag delete operation. Therefore, when
interacting with third-party container registries, GitLab uses a workaround to delete tags. See the
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index d85a2767f06..e1de407de9c 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -18659,9 +18659,6 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
-msgid "IP"
-msgstr ""
-
msgid "IP Address"
msgstr ""
@@ -20542,6 +20539,9 @@ msgstr ""
msgid "InviteMembersModal|Members were successfully added"
msgstr ""
+msgid "InviteMembersModal|New members will be unable to participate. You can manage your members by removing ones you no longer need."
+msgstr ""
+
msgid "InviteMembersModal|Search for a group to invite"
msgstr ""
@@ -20560,6 +20560,12 @@ msgstr ""
msgid "InviteMembersModal|To assign issues to a new team member, you need a project for the issues. %{linkStart}Create a project to get started.%{linkEnd}"
msgstr ""
+msgid "InviteMembersModal|To get more members an owner of this namespace can %{trialLinkStart}start a trial%{trialLinkEnd} or %{upgradeLinkStart}upgrade%{upgradeLinkEnd} to a paid tier."
+msgstr ""
+
+msgid "InviteMembersModal|You only have space for %{count} more %{members} in %{name}"
+msgstr ""
+
msgid "InviteMembersModal|You're inviting a group to the %{strongStart}%{name}%{strongEnd} group."
msgstr ""
@@ -20572,6 +20578,9 @@ msgstr ""
msgid "InviteMembersModal|You're inviting members to the %{strongStart}%{name}%{strongEnd} project."
msgstr ""
+msgid "InviteMembersModal|You've reached your %{count} %{members} limit for %{name}"
+msgstr ""
+
msgid "InviteMembers|Invite a group"
msgstr ""
@@ -44459,6 +44468,11 @@ msgstr ""
msgid "math|There was an error rendering this math block"
msgstr ""
+msgid "member"
+msgid_plural "members"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "merge request"
msgid_plural "merge requests"
msgstr[0] ""
diff --git a/scripts/review_apps/review-apps.sh b/scripts/review_apps/review-apps.sh
index 695de95b8fc..f529c8eaafe 100755
--- a/scripts/review_apps/review-apps.sh
+++ b/scripts/review_apps/review-apps.sh
@@ -213,7 +213,7 @@ function create_application_secret() {
local initial_root_password_shared_secret
local gitlab_license_shared_secret
- initial_root_password_shared_secret=$(kubectl get secret --namespace ${namespace} --no-headers -o=custom-columns=NAME:.metadata.name shared-gitlab-initial-root-password | tail -n 1)
+ initial_root_password_shared_secret=$(kubectl get secret --namespace ${namespace} --no-headers -o=custom-columns=NAME:.metadata.name shared-gitlab-initial-root-password 2> /dev/null | tail -n 1)
if [[ "${initial_root_password_shared_secret}" == "" ]]; then
echoinfo "Creating the 'shared-gitlab-initial-root-password' secret in the ${namespace} namespace..." true
kubectl create secret generic --namespace "${namespace}" \
@@ -226,7 +226,7 @@ function create_application_secret() {
if [ -z "${REVIEW_APPS_EE_LICENSE_FILE}" ]; then echo "License not found" && return; fi
- gitlab_license_shared_secret=$(kubectl get secret --namespace ${namespace} --no-headers -o=custom-columns=NAME:.metadata.name shared-gitlab-license | tail -n 1)
+ gitlab_license_shared_secret=$(kubectl get secret --namespace ${namespace} --no-headers -o=custom-columns=NAME:.metadata.name shared-gitlab-license 2> /dev/null | tail -n 1)
if [[ "${gitlab_license_shared_secret}" == "" ]]; then
echoinfo "Creating the 'shared-gitlab-license' secret in the ${namespace} namespace..." true
kubectl create secret generic --namespace "${namespace}" \
diff --git a/spec/frontend/invite_members/components/user_limit_notification_spec.js b/spec/frontend/invite_members/components/user_limit_notification_spec.js
new file mode 100644
index 00000000000..c779cf2ee3f
--- /dev/null
+++ b/spec/frontend/invite_members/components/user_limit_notification_spec.js
@@ -0,0 +1,71 @@
+import { GlAlert, GlSprintf } from '@gitlab/ui';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import UserLimitNotification from '~/invite_members/components/user_limit_notification.vue';
+
+describe('UserLimitNotification', () => {
+ let wrapper;
+
+ const findAlert = () => wrapper.findComponent(GlAlert);
+
+ const createComponent = (providers = {}) => {
+ wrapper = shallowMountExtended(UserLimitNotification, {
+ provide: {
+ name: 'my group',
+ newTrialRegistrationPath: 'newTrialRegistrationPath',
+ purchasePath: 'purchasePath',
+ freeUsersLimit: 5,
+ membersCount: 1,
+ ...providers,
+ },
+ stubs: { GlSprintf },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('when limit is not reached', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('renders empty block', () => {
+ expect(findAlert().exists()).toBe(false);
+ });
+ });
+
+ describe('when close to limit', () => {
+ beforeEach(() => {
+ createComponent({ membersCount: 3 });
+ });
+
+ it("renders user's limit notification", () => {
+ const alert = findAlert();
+
+ expect(alert.attributes('title')).toEqual(
+ 'You only have space for 2 more members in my group',
+ );
+
+ expect(alert.text()).toEqual(
+ 'To get more members an owner of this namespace can start a trial or upgrade to a paid tier.',
+ );
+ });
+ });
+
+ describe('when limit is reached', () => {
+ beforeEach(() => {
+ createComponent({ membersCount: 5 });
+ });
+
+ it("renders user's limit notification", () => {
+ const alert = findAlert();
+
+ expect(alert.attributes('title')).toEqual("You've reached your 5 members limit for my group");
+
+ expect(alert.text()).toEqual(
+ 'New members will be unable to participate. You can manage your members by removing ones you no longer need. To get more members an owner of this namespace can start a trial or upgrade to a paid tier.',
+ );
+ });
+ });
+});
diff --git a/spec/frontend/runner/components/cells/runner_summary_cell_spec.js b/spec/frontend/runner/components/cells/runner_summary_cell_spec.js
index b6d957d27ea..b2e8c5a3ad9 100644
--- a/spec/frontend/runner/components/cells/runner_summary_cell_spec.js
+++ b/spec/frontend/runner/components/cells/runner_summary_cell_spec.js
@@ -5,6 +5,7 @@ import { INSTANCE_TYPE, PROJECT_TYPE } from '~/runner/constants';
const mockId = '1';
const mockShortSha = '2P6oDVDm';
const mockDescription = 'runner-1';
+const mockIpAddress = '0.0.0.0';
describe('RunnerTypeCell', () => {
let wrapper;
@@ -18,6 +19,7 @@ describe('RunnerTypeCell', () => {
id: `gid://gitlab/Ci::Runner/${mockId}`,
shortSha: mockShortSha,
description: mockDescription,
+ ipAddress: mockIpAddress,
runnerType: INSTANCE_TYPE,
...runner,
},
@@ -59,6 +61,10 @@ describe('RunnerTypeCell', () => {
expect(wrapper.text()).toContain(mockDescription);
});
+ it('Displays the runner ip address', () => {
+ expect(wrapper.text()).toContain(mockIpAddress);
+ });
+
it('Displays a custom slot', () => {
const slotContent = 'My custom runner summary';
diff --git a/spec/frontend/runner/components/runner_list_spec.js b/spec/frontend/runner/components/runner_list_spec.js
index a0f42738d2c..951a7ac048c 100644
--- a/spec/frontend/runner/components/runner_list_spec.js
+++ b/spec/frontend/runner/components/runner_list_spec.js
@@ -47,7 +47,6 @@ describe('RunnerList', () => {
'Status',
'Runner',
'Version',
- 'IP',
'Jobs',
'Tags',
'Last contact',
@@ -68,7 +67,7 @@ describe('RunnerList', () => {
});
it('Displays details of a runner', () => {
- const { id, description, version, ipAddress, shortSha } = mockRunners[0];
+ const { id, description, version, shortSha } = mockRunners[0];
// Badges
expect(findCell({ fieldKey: 'status' }).text()).toMatchInterpolatedText(
@@ -83,7 +82,6 @@ describe('RunnerList', () => {
// Other fields
expect(findCell({ fieldKey: 'version' }).text()).toBe(version);
- expect(findCell({ fieldKey: 'ipAddress' }).text()).toBe(ipAddress);
expect(findCell({ fieldKey: 'jobCount' }).text()).toBe('0');
expect(findCell({ fieldKey: 'tagList' }).text()).toBe('');
expect(findCell({ fieldKey: 'contactedAt' }).text()).toEqual(expect.any(String));