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/error_tracking/components/error_details_info.vue57
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/pages/details.vue10
-rw-r--r--app/models/user.rb4
-rw-r--r--doc/architecture/blueprints/organization/index.md19
-rw-r--r--doc/ci/review_apps/img/review_apps_preview_in_mr.pngbin29800 -> 0 bytes
-rw-r--r--doc/ci/review_apps/img/review_apps_preview_in_mr_v16_0.pngbin0 -> 11322 bytes
-rw-r--r--doc/ci/review_apps/img/view_on_env_blob.pngbin11889 -> 0 bytes
-rw-r--r--doc/ci/review_apps/img/view_on_env_mr.pngbin102967 -> 0 bytes
-rw-r--r--doc/ci/review_apps/index.md10
-rw-r--r--doc/development/labels/index.md6
-rw-r--r--doc/user/enterprise_user/index.md11
-rw-r--r--doc/user/group/manage.md4
-rw-r--r--doc/user/project/merge_requests/approvals/img/approvals_premium_mr_widget_16_0.pngbin0 -> 36687 bytes
-rw-r--r--doc/user/project/merge_requests/approvals/img/approvals_premium_mr_widget_v13_3.pngbin42034 -> 0 bytes
-rw-r--r--doc/user/project/merge_requests/approvals/rules.md2
-rw-r--r--doc/user/project/repository/branches/img/delete_merged_branches.pngbin42886 -> 0 bytes
-rw-r--r--doc/user/project/repository/branches/index.md21
-rw-r--r--doc/user/project/repository/code_suggestions.md14
-rw-r--r--locale/gitlab.pot11
-rw-r--r--spec/frontend/error_tracking/components/error_details_info_spec.js80
-rw-r--r--spec/frontend/repository/components/table/index_spec.js50
-rw-r--r--spec/models/user_spec.rb22
22 files changed, 206 insertions, 115 deletions
diff --git a/app/assets/javascripts/error_tracking/components/error_details_info.vue b/app/assets/javascripts/error_tracking/components/error_details_info.vue
index f6f39f178fb..0b4eabe25d1 100644
--- a/app/assets/javascripts/error_tracking/components/error_details_info.vue
+++ b/app/assets/javascripts/error_tracking/components/error_details_info.vue
@@ -34,20 +34,14 @@ export default {
lastReleaseLink() {
return `${this.error.externalBaseUrl}/releases/${this.error.lastReleaseVersion}`;
},
- firstCommitLink() {
- return `${this.error.externalBaseUrl}/-/commit/${this.error.firstReleaseVersion}`;
- },
- lastCommitLink() {
- return `${this.error.externalBaseUrl}/-/commit/${this.error.lastReleaseVersion}`;
- },
shortFirstReleaseVersion() {
- return this.error.firstReleaseVersion.substr(0, 10);
+ return this.error.firstReleaseVersion?.substr(0, 10);
},
shortLastReleaseVersion() {
- return this.error.lastReleaseVersion.substr(0, 10);
+ return this.error.lastReleaseVersion?.substr(0, 10);
},
shortGitlabCommit() {
- return this.error.gitlabCommit.substr(0, 10);
+ return this.error.gitlabCommit?.substr(0, 10);
},
},
methods: {
@@ -72,11 +66,11 @@ export default {
data-testid="error-count-card"
>
<template #header>
- <span>{{ __('Events') }}</span>
+ {{ __('Events') }}
</template>
<template #default>
- <span>{{ error.count }}</span>
+ {{ error.count }}
</template>
</gl-card>
@@ -87,61 +81,66 @@ export default {
data-testid="user-count-card"
>
<template #header>
- <span>{{ __('Users') }}</span>
+ {{ __('Users') }}
</template>
<template #default>
- <span>{{ error.userCount }}</span>
+ {{ error.userCount }}
</template>
</gl-card>
<gl-card
- v-if="error.firstReleaseVersion"
+ v-if="error.firstSeen"
:class="$options.CARD_CLASS"
:body-class="$options.BODY_CLASS"
:header-class="$options.HEADER_CLASS"
data-testid="first-release-card"
>
<template #header>
- <gl-icon v-gl-tooltip :title="shortFirstReleaseVersion" name="commit" class="gl-mr-1" />
- <span>{{ __('First seen') }}</span>
+ {{ __('First seen') }}
</template>
- <template #default>
- <gl-link v-if="error.integrated" :href="firstCommitLink" class="gl-font-lg">
- <time-ago-tooltip :time="error.firstSeen" />
- </gl-link>
+ <template v-if="error.integrated" #default>
+ <time-ago-tooltip :time="error.firstSeen" />
+ <span v-if="shortFirstReleaseVersion" class="gl-font-sm gl-text-secondary">
+ <gl-icon name="commit" class="gl-mr-1" :size="12" />{{ shortFirstReleaseVersion }}
+ </span>
+ </template>
- <gl-link v-else :href="firstReleaseLink" target="_blank" class="gl-font-lg">
+ <template v-else #default>
+ <gl-link :href="firstReleaseLink" target="_blank" class="gl-font-lg">
<time-ago-tooltip :time="error.firstSeen" />
</gl-link>
</template>
</gl-card>
<gl-card
- v-if="error.lastReleaseVersion"
+ v-if="error.lastSeen"
:class="$options.CARD_CLASS"
:body-class="$options.BODY_CLASS"
:header-class="$options.HEADER_CLASS"
data-testid="last-release-card"
>
<template #header>
- <gl-icon v-gl-tooltip :title="shortLastReleaseVersion" name="commit" class="gl-mr-1" />
{{ __('Last seen') }}
</template>
- <template #default>
- <gl-link v-if="error.integrated" :href="lastCommitLink" class="gl-font-lg">
- <time-ago-tooltip :time="error.lastSeen" />
- </gl-link>
- <gl-link v-else :href="lastReleaseLink" target="_blank" class="gl-font-lg">
+ <template v-if="error.integrated" #default>
+ <time-ago-tooltip :time="error.lastSeen" />
+ <span v-if="shortLastReleaseVersion" class="gl-font-sm gl-text-secondary">
+ <gl-icon name="commit" class="gl-mr-1" :size="12" />{{ shortLastReleaseVersion }}
+ </span>
+ </template>
+
+ <template v-else #default>
+ <gl-link :href="lastReleaseLink" target="_blank" class="gl-font-lg">
<time-ago-tooltip :time="error.lastSeen" />
</gl-link>
</template>
</gl-card>
<gl-card
- v-if="error.gitlabCommit"
+ v-if="!error.integrated && error.gitlabCommit"
:class="$options.CARD_CLASS"
:body-class="$options.BODY_CLASS"
:header-class="$options.HEADER_CLASS"
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/pages/details.vue b/app/assets/javascripts/packages_and_registries/package_registry/pages/details.vue
index 6d4979ac785..40e175fab99 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/pages/details.vue
+++ b/app/assets/javascripts/packages_and_registries/package_registry/pages/details.vue
@@ -21,10 +21,8 @@ import { packageTypeToTrackCategory } from '~/packages_and_registries/package_re
import AdditionalMetadata from '~/packages_and_registries/package_registry/components/details/additional_metadata.vue';
import DependencyRow from '~/packages_and_registries/package_registry/components/details/dependency_row.vue';
import InstallationCommands from '~/packages_and_registries/package_registry/components/details/installation_commands.vue';
-import PackageFiles from '~/packages_and_registries/package_registry/components/details/package_files.vue';
import PackageHistory from '~/packages_and_registries/package_registry/components/details/package_history.vue';
import PackageTitle from '~/packages_and_registries/package_registry/components/details/package_title.vue';
-import PackageVersionsList from '~/packages_and_registries/package_registry/components/details/package_versions_list.vue';
import DeletePackages from '~/packages_and_registries/package_registry/components/functional/delete_packages.vue';
import {
PACKAGE_TYPE_NUGET,
@@ -76,9 +74,13 @@ export default {
PackageHistory,
AdditionalMetadata,
InstallationCommands,
- PackageFiles,
+ PackageFiles: () =>
+ import('~/packages_and_registries/package_registry/components/details/package_files.vue'),
DeletePackages,
- PackageVersionsList,
+ PackageVersionsList: () =>
+ import(
+ '~/packages_and_registries/package_registry/components/details/package_versions_list.vue'
+ ),
},
directives: {
GlTooltip: GlTooltipDirective,
diff --git a/app/models/user.rb b/app/models/user.rb
index 1bd0dbd5d5f..5d31f9e54b4 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -2260,6 +2260,10 @@ class User < ApplicationRecord
abuse_trust_scores.spamcheck.average(:score) || 0.0
end
+ def telesign_score
+ abuse_trust_scores.telesign.order(created_at: :desc).first&.score || 0.0
+ end
+
def trust_scores_for_source(source)
abuse_trust_scores.where(source: source)
end
diff --git a/doc/architecture/blueprints/organization/index.md b/doc/architecture/blueprints/organization/index.md
index bd8d085413c..8eb367ddfc8 100644
--- a/doc/architecture/blueprints/organization/index.md
+++ b/doc/architecture/blueprints/organization/index.md
@@ -1,7 +1,7 @@
---
status: ongoing
creation-date: "2023-04-05"
-authors: [ "@lohrc" ]
+authors: [ "@lohrc", "alexpooley" ]
coach: "@ayufan"
approvers: [ "@lohrc" ]
owning-stage: "~devops::data stores"
@@ -47,6 +47,7 @@ The Organization focuses on creating a better experience for Organizations to ma
- Aggregation: Data from all groups and projects in an Organization can be aggregated.
- An Organization includes settings, data, and features from all groups and projects under the same owner (including personal namespaces).
- Cascading behavior: Organization cascades behavior to all the projects and groups that are owned by the same Organization. It can be decided at the Organization level whether a setting can be overridden or not on the levels beneath.
+- Minimal burden on customers: The addition of Organizations should not change existing group and project paths to minimize the impact of URL changes.
### Non-Goals
@@ -89,7 +90,7 @@ The Organization MVC will contain the following functionality:
- Instance setting to allow the creation of multiple Organizations. This will be enabled by default on GitLab.com, and disabled for self-managed GitLab.
- Every instance will have a default organization. Initially, all users will be managed by this default Organization.
- Organization Owner. The creation of an Organization appoints that user as the Organization Owner. Once established, the Organization Owner can appoint other Organization Owners.
-- Organization users. A user is managed by one Organization, but can be part of multiple Organizations.
+- Organization users. A user is managed by one Organization, but can be part of multiple Organizations. Users are able to navigate between the different Organizations they are part of.
- Setup settings. Containing the Organization name, ID, description, README, and avatar. Settings are editable by the Organization Owner.
- Setup flow. Users are able to build an Organization on top of an existing top-level group. New users are able to create an Organization from scratch and to start building top-level groups from there.
- Visibility. Options will be `public` and `private`. A nonuser of a specific Organization will not see private Organizations in the explore section. Visibility is editable by the Organization Owner.
@@ -107,10 +108,10 @@ Organization Users can get access to groups and projects as:
- A project member: this grants access to the project, and limited access to parent groups, regardless of their visibility.
- A non-member: this grants access to public and internal groups and projects of that Organization. To access a private group or project in an Organization, a user must become a member.
-Organization Users can be managed by the Organization as:
+Organization Users can be managed in the following ways:
-- Enterprise Users, managed by the Organization. This includes control over their user account and the ability to block the user.
-- Non-Enterprise Users, managed by the User. Non-Enterprise Users can be removed from an Organization, but their user account remains in their control.
+- As [Enterprise Users](../../../user/enterprise_user/index.md), managed by the Organization. This includes control over their user account and the ability to block the user.
+- As Non-Enterprise Users, managed by the Default Organization. Non-Enterprise Users can be removed from an Organization, but the user keeps ownership of their user account.
Enterprise Users are only available to Organizations with a Premium or Ultimate subscription. Organizations on the free tier will only be able to host Non-Enterprise Users.
@@ -118,6 +119,10 @@ Enterprise Users are only available to Organizations with a Premium or Ultimate
Non-users are external to the Organization and can only access the public resources of an Organization, such as public projects.
+### Routing
+
+Today only users, projects, namespaces and container images are considered routable entities which require global uniqueness on `https://gitlab.com/<path>/-/`. Initially, Organization routes will be [unscoped](../../../development/routing.md). Organizations will follow the path `https://gitlab.com/-/organizations/org-name/` as one of the design goals is that the addition of Organizations should not change existing group and project paths.
+
## Iteration Plan
The following iteration plan outlines how we intend to arrive at the Organization MVC. We are following the guidelines for [Experiment, Beta, and Generally Available features](../../../policy/alpha-beta-support.md).
@@ -161,6 +166,7 @@ After the initial rollout of Organizations, the following functionality will be
1. Cascading Organization setting to enforce security scans.
1. Scan result policies at the Organization level.
1. Compliance frameworks.
+1. [Support the agent for Kubernetes sharing at the Organization level](https://gitlab.com/gitlab-org/gitlab/-/issues/382731).
## Alternative Solutions
@@ -169,7 +175,10 @@ An alternative approach to building Organizations is to convert top-level groups
## Decision Log
- 2023-05-10: [Billing is not part of the Organization MVC](https://gitlab.com/gitlab-org/gitlab/-/issues/406614#note_1384055365)
+- 2023-05-15: [Organization route setup](https://gitlab.com/gitlab-org/gitlab/-/issues/409913#note_1388679761)
## Links
- [Organization epic](https://gitlab.com/groups/gitlab-org/-/epics/9265)
+- [Enterprise Users](../../../user/enterprise_user/index.md)
+- [Cells blueprint](../cells/index.md)
diff --git a/doc/ci/review_apps/img/review_apps_preview_in_mr.png b/doc/ci/review_apps/img/review_apps_preview_in_mr.png
deleted file mode 100644
index 3e6506a6a3a..00000000000
--- a/doc/ci/review_apps/img/review_apps_preview_in_mr.png
+++ /dev/null
Binary files differ
diff --git a/doc/ci/review_apps/img/review_apps_preview_in_mr_v16_0.png b/doc/ci/review_apps/img/review_apps_preview_in_mr_v16_0.png
new file mode 100644
index 00000000000..40345b9987f
--- /dev/null
+++ b/doc/ci/review_apps/img/review_apps_preview_in_mr_v16_0.png
Binary files differ
diff --git a/doc/ci/review_apps/img/view_on_env_blob.png b/doc/ci/review_apps/img/view_on_env_blob.png
deleted file mode 100644
index acc457fbb38..00000000000
--- a/doc/ci/review_apps/img/view_on_env_blob.png
+++ /dev/null
Binary files differ
diff --git a/doc/ci/review_apps/img/view_on_env_mr.png b/doc/ci/review_apps/img/view_on_env_mr.png
deleted file mode 100644
index 0e61814a65d..00000000000
--- a/doc/ci/review_apps/img/view_on_env_mr.png
+++ /dev/null
Binary files differ
diff --git a/doc/ci/review_apps/index.md b/doc/ci/review_apps/index.md
index 004bd9dfc5f..f1646bee7d0 100644
--- a/doc/ci/review_apps/index.md
+++ b/doc/ci/review_apps/index.md
@@ -35,7 +35,7 @@ Access to the review app is made available as a link on the [merge request](../.
The following is an example of a merge request with an environment set dynamically.
-![review app in merge request](img/review_apps_preview_in_mr.png)
+![review app in merge request](img/review_apps_preview_in_mr_v16_0.png)
In this example, a branch was:
@@ -185,13 +185,9 @@ After you have the route mapping set up, it takes effect in the following locati
![View app file list in merge request widget](img/view_on_mr_widget.png)
-- In the diff for a comparison or commit.
+- In the diff for a comparison or commit, by selecting **View** (**{external-link}**) next to the file.
- ![View on environment button in merge request diff](img/view_on_env_mr.png)
-
-- In the blob file view.
-
- ![View on environment button in file view](img/view_on_env_blob.png)
+- In the blob file view, by selecting **View** (**{external-link}**) next to the file.
<!--- start_remove The following content will be removed on remove_date: '2024-05-22' -->
## Visual Reviews (deprecated) **(PREMIUM)**
diff --git a/doc/development/labels/index.md b/doc/development/labels/index.md
index 50b6ec74575..dfd2a9e4fd3 100644
--- a/doc/development/labels/index.md
+++ b/doc/development/labels/index.md
@@ -194,6 +194,8 @@ The current department labels are:
- `~"UX"`
- `~"Quality"`
+- `~"infrastructure"`
+- `~"security"`
## Team labels
@@ -206,8 +208,10 @@ people.
The current team labels are:
-- `~"Delivery"~`
+- `~"Delivery"`
- `~"Technical Writing"`
+- `~"Engineering Productivity"`
+- `~"Contributor Success"`
### Naming and color convention
diff --git a/doc/user/enterprise_user/index.md b/doc/user/enterprise_user/index.md
index ffeaaa8c591..8cebdf2749d 100644
--- a/doc/user/enterprise_user/index.md
+++ b/doc/user/enterprise_user/index.md
@@ -43,11 +43,18 @@ Prerequisites:
- A custom domain name `example.com` or subdomain `subdomain.example.com`.
- Access to your domain's server control panel to set up a DNS `TXT` record to verify your domain's ownership.
+- A project in the group.
+- You must have the Owner role in the top-level group.
Setting up a verified domain is similar to [setting up a custom domain on GitLab Pages](../project/pages/custom_domains_ssl_tls_certification/index.md). However, you must:
-- Link the domain to a project. For more information on group-level domain verification, see [issue 5299](https://gitlab.com/groups/gitlab-org/-/epics/5299).
-- Configure the DNS `TXT` record to verify the domain's ownership.
+- Link the domain to a single project.
+- Configure the `TXT` only in the DNS record to verify the domain's ownership.
+
+Domain verification is tied to the project you choose. A project is required because domain verification reuses the GitLab Pages verification feature, which requires a project. Domain verification applies at the top-level group and to all subgroups and projects nested under that top-level parent group.
+A member in the chosen project with [at least the Maintainer role](../permissions.md#project-members-permissions) can modify or remove the domain verification.
+If needed, you can create a new project to set up domain verification directly under your top-level group. This limits the ability to modify the domain verification to members with at least the Maintainer role.
+For more information on group-level domain verification, see [epic 5299](https://gitlab.com/groups/gitlab-org/-/epics/5299).
Steps:
diff --git a/doc/user/group/manage.md b/doc/user/group/manage.md
index c330e39533e..871174d3281 100644
--- a/doc/user/group/manage.md
+++ b/doc/user/group/manage.md
@@ -646,7 +646,7 @@ Support for group-level settings for merge request approval rules is tracked in
WARNING:
This feature is in [Beta](../../policy/alpha-beta-support.md#beta).
Code Suggestions use generative AI to suggest code while you're developing.
-Due to high demand, this feature will have unscheduled downtime and code suggestions in VS Code may be delayed.
+Due to high demand, this feature may have unscheduled downtime and code suggestions in VS Code may be delayed.
Code Suggestions may produce
[low-quality or incomplete suggestions](../project/repository/code_suggestions.md#model-accuracy-and-quality).
Beta users should read about the [known limitations](../project/repository/code_suggestions.md#known-limitations).
@@ -656,6 +656,8 @@ This setting enables users in the group to access [Code Suggestions](../project/
This setting [cascades to all projects](../project/merge_requests/approvals/settings.md#settings-cascading)
that belong to the group.
+However, each user can enable or disable Code Suggestions for themselves.
+
To enable Code Suggestions for a group:
1. On the top bar, select **Main menu > Groups** and find your group.
diff --git a/doc/user/project/merge_requests/approvals/img/approvals_premium_mr_widget_16_0.png b/doc/user/project/merge_requests/approvals/img/approvals_premium_mr_widget_16_0.png
new file mode 100644
index 00000000000..727dac0916b
--- /dev/null
+++ b/doc/user/project/merge_requests/approvals/img/approvals_premium_mr_widget_16_0.png
Binary files differ
diff --git a/doc/user/project/merge_requests/approvals/img/approvals_premium_mr_widget_v13_3.png b/doc/user/project/merge_requests/approvals/img/approvals_premium_mr_widget_v13_3.png
deleted file mode 100644
index 306bf57354d..00000000000
--- a/doc/user/project/merge_requests/approvals/img/approvals_premium_mr_widget_v13_3.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/merge_requests/approvals/rules.md b/doc/user/project/merge_requests/approvals/rules.md
index d55ca5dff04..3a6ce48d071 100644
--- a/doc/user/project/merge_requests/approvals/rules.md
+++ b/doc/user/project/merge_requests/approvals/rules.md
@@ -104,7 +104,7 @@ supports multiple default rules:
When an [eligible approver](#eligible-approvers) approves a merge request, it
reduces the number of approvals left (the **Approvals** column) for all rules that the approver belongs to:
-![Approvals premium merge request widget](img/approvals_premium_mr_widget_v13_3.png)
+![Approvals premium merge request widget](img/approvals_premium_mr_widget_16_0.png)
<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
For an overview, see [Multiple Approvers](https://www.youtube.com/watch?v=8JQJ5821FrA).
diff --git a/doc/user/project/repository/branches/img/delete_merged_branches.png b/doc/user/project/repository/branches/img/delete_merged_branches.png
deleted file mode 100644
index 649a758b95f..00000000000
--- a/doc/user/project/repository/branches/img/delete_merged_branches.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/repository/branches/index.md b/doc/user/project/repository/branches/index.md
index 7c09ce5c580..05494789b83 100644
--- a/doc/user/project/repository/branches/index.md
+++ b/doc/user/project/repository/branches/index.md
@@ -244,15 +244,22 @@ To compare branches in a repository:
## Delete merged branches
-![Delete merged branches](img/delete_merged_branches.png)
+Merged branches can be deleted in bulk if they meet all of these criteria:
-This feature allows merged branches to be deleted in bulk. Only branches that
-have been merged into the project's default branch and
-[are not protected](../../protected_branches.md) are deleted as part of
-this operation.
+- They are not [protected branches](../../protected_branches.md).
+- They have been merged into the project's default branch.
-It's particularly useful to clean up old branches that were not deleted
-automatically when a merge request was merged.
+Prerequisites:
+
+- You must have at least the Developer role in the project.
+
+To do this:
+
+1. On the top bar, select **Main menu > Projects** and find your project.
+1. On the left sidebar, select **Repository > Branches**.
+1. On the upper right corner of the page, select **More** **{ellipsis_v}**.
+1. Select **Delete merged branches**.
+1. In the modal window, enter the word `delete` to confirm, then select **Delete merged branches**.
## Related topics
diff --git a/doc/user/project/repository/code_suggestions.md b/doc/user/project/repository/code_suggestions.md
index 5e79f33542a..c3d29261f07 100644
--- a/doc/user/project/repository/code_suggestions.md
+++ b/doc/user/project/repository/code_suggestions.md
@@ -56,11 +56,25 @@ We are making improvements to the Code Suggestions underlying AI model weekly to
Usage of Code Suggestions is governed by the [GitLab Testing Agreement](https://about.gitlab.com/handbook/legal/testing-agreement/). Learn about [data usage when using Code Suggestions](#code-suggestions-data-usage).
+## Enable Code Suggestions for an individual user
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/121079) in GitLab 16.1 as [Beta](/ee/policy/alpha-beta-support.md#beta).
+
+Each user can enable Code Suggestions for themselves:
+
+1. On the top bar, in the upper-right corner, select your avatar.
+1. On the left sidebar, select **Preferences**.
+1. In the **Code Suggestions** section, enable the setting.
+
+NOTE:
+If Code Suggestions is [enabled for the group](../../group/manage.md#group-code-suggestions), the group setting overrides the user setting.
+
## Enable Code Suggestions in VS Code
Prerequisites:
- Your group owner must enable the [group level code suggestions setting](../../group/manage.md#group-code-suggestions).
+- Code Suggestions must be [enabled for your user account](#enable-code-suggestions-for-an-individual-user).
- If using a [personal access token](../../profile/personal_access_tokens.md#create-a-personal-access-token), the token must have the `read_api` and `read_user` scopes.
To enable Code Suggestions in VS Code:
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 8f709205234..d06749ed65f 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -1913,6 +1913,9 @@ msgstr ""
msgid "AI|Something went wrong. Please try again later"
msgstr ""
+msgid "AI|Text generated by AI"
+msgstr ""
+
msgid "AI|The container element wasn't found, stopping AI Genie."
msgstr ""
@@ -44497,8 +44500,10 @@ msgstr ""
msgid "TanukiBot|Give feedback"
msgstr ""
-msgid "TanukiBot|Sources"
-msgstr ""
+msgid "TanukiBot|Source"
+msgid_plural "TanukiBot|Sources"
+msgstr[0] ""
+msgstr[1] ""
msgid "TanukiBot|There was an error communicating with GitLab Chat. Please try again later."
msgstr ""
@@ -46107,7 +46112,7 @@ msgstr ""
msgid "This feature requires local storage to be enabled"
msgstr ""
-msgid "This field is auto-calculated based on the Progress score of its direct children. You can overwrite this value but it will be replaced by the auto-calcualtion anytime the Progress score of its direct children is updated."
+msgid "This field is auto-calculated based on the Progress score of its direct children. You can overwrite this value but it will be replaced by the auto-calculation anytime the Progress score of its direct children is updated."
msgstr ""
msgid "This field is required"
diff --git a/spec/frontend/error_tracking/components/error_details_info_spec.js b/spec/frontend/error_tracking/components/error_details_info_spec.js
index 4a741a4c31e..a3f4b0e0dd8 100644
--- a/spec/frontend/error_tracking/components/error_details_info_spec.js
+++ b/spec/frontend/error_tracking/components/error_details_info_spec.js
@@ -40,43 +40,45 @@ describe('ErrorDetails', () => {
});
it('should render a card with error counts', () => {
- expect(wrapper.findByTestId('error-count-card').text()).toContain('Events 12');
+ expect(wrapper.findByTestId('error-count-card').text()).toMatchInterpolatedText('Events 12');
});
it('should render a card with user counts', () => {
- expect(wrapper.findByTestId('user-count-card').text()).toContain('Users 2');
+ expect(wrapper.findByTestId('user-count-card').text()).toMatchInterpolatedText('Users 2');
});
- describe('release links', () => {
- it('if firstReleaseVersion is missing, does not render a card', () => {
+ describe('first seen card', () => {
+ it('if firstSeen is missing, does not render a card', () => {
+ mountComponent({
+ firstSeen: undefined,
+ });
expect(wrapper.findByTestId('first-release-card').exists()).toBe(false);
});
- describe('if firstReleaseVersion link exists', () => {
- it('renders the first release card', () => {
- mountComponent({
- firstReleaseVersion: 'first-release-version',
- });
- const card = wrapper.findByTestId('first-release-card');
- expect(card.exists()).toBe(true);
- expect(card.text()).toContain('First seen');
- expect(card.findComponent(GlLink).exists()).toBe(true);
- expect(card.findComponent(TimeAgoTooltip).exists()).toBe(true);
+ it('if firstSeen exists renders a card', () => {
+ mountComponent({
+ firstSeen: '2017-05-26T13:32:48Z',
});
+ const card = wrapper.findByTestId('first-release-card');
+ expect(card.exists()).toBe(true);
+ expect(card.text()).toContain('First seen');
+ expect(card.findComponent(TimeAgoTooltip).exists()).toBe(true);
+ expect(card.findComponent(TimeAgoTooltip).props('time')).toBe('2017-05-26T13:32:48Z');
+ });
- it('renders a link to the commit if error is integrated', () => {
+ describe('if firstReleaseVersion link exists', () => {
+ it('shows the shortened release tag as text, if error is integrated', () => {
mountComponent({
- externalBaseUrl: 'external-base-url',
firstReleaseVersion: 'first-release-version',
firstSeen: '2023-04-20T17:02:06+00:00',
integrated: true,
});
- expect(
- wrapper.findByTestId('first-release-card').findComponent(GlLink).attributes('href'),
- ).toBe('external-base-url/-/commit/first-release-version');
+ const card = wrapper.findByTestId('first-release-card');
+ expect(card.text()).toMatchInterpolatedText('First seen first-rele');
+ expect(card.findComponent(GlLink).exists()).toBe(false);
});
- it('renders a link to the release if error is not integrated', () => {
+ it('renders a link to the release, if error is not integrated', () => {
mountComponent({
externalBaseUrl: 'external-base-url',
firstReleaseVersion: 'first-release-version',
@@ -88,36 +90,40 @@ describe('ErrorDetails', () => {
).toBe('external-base-url/releases/first-release-version');
});
});
+ });
- it('if lastReleaseVersion is missing, does not render a card', () => {
+ describe('last seen card', () => {
+ it('if lastSeen is missing, does not render a card', () => {
+ mountComponent({
+ lastSeen: undefined,
+ });
expect(wrapper.findByTestId('last-release-card').exists()).toBe(false);
});
- describe('if lastReleaseVersion link exists', () => {
- it('renders the last release card', () => {
- mountComponent({
- lastReleaseVersion: 'last-release-version',
- });
- const card = wrapper.findByTestId('last-release-card');
- expect(card.exists()).toBe(true);
- expect(card.text()).toContain('Last seen');
- expect(card.findComponent(GlLink).exists()).toBe(true);
- expect(card.findComponent(TimeAgoTooltip).exists()).toBe(true);
+ it('if lastSeen exists renders a card', () => {
+ mountComponent({
+ lastSeen: '2017-05-26T13:32:48Z',
});
+ const card = wrapper.findByTestId('last-release-card');
+ expect(card.exists()).toBe(true);
+ expect(card.text()).toContain('Last seen');
+ expect(card.findComponent(TimeAgoTooltip).exists()).toBe(true);
+ expect(card.findComponent(TimeAgoTooltip).props('time')).toBe('2017-05-26T13:32:48Z');
+ });
- it('renders a link to the commit if error is integrated', () => {
+ describe('if lastReleaseVersion link exists', () => {
+ it('shows the shortened release tag as text, if error is integrated', () => {
mountComponent({
- externalBaseUrl: 'external-base-url',
lastReleaseVersion: 'last-release-version',
lastSeen: '2023-04-20T17:02:06+00:00',
integrated: true,
});
- expect(
- wrapper.findByTestId('last-release-card').findComponent(GlLink).attributes('href'),
- ).toBe('external-base-url/-/commit/last-release-version');
+ const card = wrapper.findByTestId('last-release-card');
+ expect(card.text()).toMatchInterpolatedText('Last seen last-relea');
+ expect(card.findComponent(GlLink).exists()).toBe(false);
});
- it('renders a link to the release if error is integrated', () => {
+ it('renders a link to the release, if error is not integrated', () => {
mountComponent({
externalBaseUrl: 'external-base-url',
lastReleaseVersion: 'last-release-version',
diff --git a/spec/frontend/repository/components/table/index_spec.js b/spec/frontend/repository/components/table/index_spec.js
index f7be367887c..a89a107b68f 100644
--- a/spec/frontend/repository/components/table/index_spec.js
+++ b/spec/frontend/repository/components/table/index_spec.js
@@ -1,11 +1,24 @@
+import Vue, { nextTick } from 'vue';
+import VueApollo from 'vue-apollo';
import { GlSkeletonLoader, GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
-import { nextTick } from 'vue';
import Table from '~/repository/components/table/index.vue';
import TableRow from '~/repository/components/table/row.vue';
+import refQuery from '~/repository/queries/ref.query.graphql';
+import createMockApollo from 'helpers/mock_apollo_helper';
-let vm;
-let $apollo;
+let wrapper;
+
+const createMockApolloProvider = (ref) => {
+ Vue.use(VueApollo);
+ const apolloProver = createMockApollo([]);
+ apolloProver.clients.defaultClient.cache.writeQuery({
+ query: refQuery,
+ data: { ref, escapedRef: ref },
+ });
+
+ return apolloProver;
+};
const MOCK_BLOBS = [
{
@@ -70,8 +83,15 @@ const MOCK_COMMITS = [
},
];
-function factory({ path, isLoading = false, hasMore = true, entries = {}, commits = [] }) {
- vm = shallowMount(Table, {
+function factory({
+ path,
+ isLoading = false,
+ hasMore = true,
+ entries = {},
+ commits = [],
+ ref = 'main',
+}) {
+ wrapper = shallowMount(Table, {
propsData: {
path,
isLoading,
@@ -79,13 +99,11 @@ function factory({ path, isLoading = false, hasMore = true, entries = {}, commit
hasMore,
commits,
},
- mocks: {
- $apollo,
- },
+ apolloProvider: createMockApolloProvider(ref),
});
}
-const findTableRows = () => vm.findAllComponents(TableRow);
+const findTableRows = () => wrapper.findAllComponents(TableRow);
describe('Repository table component', () => {
it.each`
@@ -94,14 +112,10 @@ describe('Repository table component', () => {
${'app/assets'} | ${'main'}
${'/'} | ${'test'}
`('renders table caption for $ref in $path', async ({ path, ref }) => {
- factory({ path });
-
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- vm.setData({ ref });
+ factory({ path, ref });
await nextTick();
- expect(vm.find('.table').attributes('aria-label')).toEqual(
+ expect(wrapper.find('.table').attributes('aria-label')).toEqual(
`Files, directories, and submodules in the path ${path} for commit reference ${ref}`,
);
});
@@ -109,7 +123,7 @@ describe('Repository table component', () => {
it('shows loading icon', () => {
factory({ path: '/', isLoading: true });
- expect(vm.findComponent(GlSkeletonLoader).exists()).toBe(true);
+ expect(wrapper.findComponent(GlSkeletonLoader).exists()).toBe(true);
});
it('renders table rows', () => {
@@ -152,7 +166,7 @@ describe('Repository table component', () => {
});
describe('Show more button', () => {
- const showMoreButton = () => vm.findComponent(GlButton);
+ const showMoreButton = () => wrapper.findComponent(GlButton);
it.each`
hasMore | expectButtonToExist
@@ -170,7 +184,7 @@ describe('Repository table component', () => {
await nextTick();
- expect(vm.emitted('showMore')).toHaveLength(1);
+ expect(wrapper.emitted('showMore')).toHaveLength(1);
});
});
});
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index d5c7ed59d6a..f5b274301ca 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -7760,4 +7760,26 @@ RSpec.describe User, feature_category: :user_profile do
end
end
end
+
+ describe '#telesign_score' do
+ let_it_be(:user1) { create(:user) }
+ let_it_be(:user2) { create(:user) }
+
+ context 'when the user has a telesign risk score' do
+ before do
+ create(:abuse_trust_score, user: user1, score: 12.0, source: :telesign)
+ create(:abuse_trust_score, user: user1, score: 24.0, source: :telesign)
+ end
+
+ it 'returns the latest score' do
+ expect(user1.telesign_score).to be(24.0)
+ end
+ end
+
+ context 'when the user does not have a telesign risk score' do
+ it 'defaults to zero' do
+ expect(user2.telesign_score).to be(0.0)
+ end
+ end
+ end
end