Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
9248363e3e
commit
b28aa8bd7d
32 changed files with 225 additions and 125 deletions
|
@ -11,7 +11,17 @@ function broadcastCount(newCount) {
|
|||
}
|
||||
|
||||
function updateUserMergeRequestCounts(newCount) {
|
||||
const mergeRequestsCountEl = document.querySelector('.merge-requests-count');
|
||||
const mergeRequestsCountEl = document.querySelector('.js-assigned-mr-count');
|
||||
mergeRequestsCountEl.textContent = newCount.toLocaleString();
|
||||
}
|
||||
|
||||
function updateReviewerMergeRequestCounts(newCount) {
|
||||
const mergeRequestsCountEl = document.querySelector('.js-reviewer-mr-count');
|
||||
mergeRequestsCountEl.textContent = newCount.toLocaleString();
|
||||
}
|
||||
|
||||
function updateMergeRequestCounts(newCount) {
|
||||
const mergeRequestsCountEl = document.querySelector('.js-merge-requests-count');
|
||||
mergeRequestsCountEl.textContent = newCount.toLocaleString();
|
||||
mergeRequestsCountEl.classList.toggle('hidden', Number(newCount) === 0);
|
||||
}
|
||||
|
@ -22,10 +32,14 @@ function updateUserMergeRequestCounts(newCount) {
|
|||
export function refreshUserMergeRequestCounts() {
|
||||
return Api.userCounts()
|
||||
.then(({ data }) => {
|
||||
const count = data.merge_requests;
|
||||
const assignedMergeRequests = data.assigned_merge_requests;
|
||||
const reviewerMergeRequests = data.review_requested_merge_requests;
|
||||
const fullCount = assignedMergeRequests + reviewerMergeRequests;
|
||||
|
||||
updateUserMergeRequestCounts(count);
|
||||
broadcastCount(count);
|
||||
updateUserMergeRequestCounts(assignedMergeRequests);
|
||||
updateReviewerMergeRequestCounts(reviewerMergeRequests);
|
||||
updateMergeRequestCounts(fullCount);
|
||||
broadcastCount(fullCount);
|
||||
})
|
||||
.catch((ex) => {
|
||||
console.error(ex); // eslint-disable-line no-console
|
||||
|
@ -60,7 +74,7 @@ export function openUserCountsBroadcast() {
|
|||
if (currentUserId) {
|
||||
channel = new BroadcastChannel(`mr_count_channel_${currentUserId}`);
|
||||
channel.onmessage = (ev) => {
|
||||
updateUserMergeRequestCounts(ev.data);
|
||||
updateMergeRequestCounts(ev.data);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// NOTE! For the first iteration, we are simply copying the implementation of Assignees
|
||||
// It will soon be overhauled in Issue https://gitlab.com/gitlab-org/gitlab/-/issues/233736
|
||||
import { deprecatedCreateFlash as Flash } from '~/flash';
|
||||
import { refreshUserMergeRequestCounts } from '~/commons/nav/user_merge_requests';
|
||||
import eventHub from '~/sidebar/event_hub';
|
||||
import Store from '~/sidebar/stores/sidebar_store';
|
||||
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||
|
@ -80,8 +81,7 @@ export default {
|
|||
.saveReviewers(this.field)
|
||||
.then(() => {
|
||||
this.loading = false;
|
||||
// Uncomment once this issue has been addressed > https://gitlab.com/gitlab-org/gitlab/-/issues/237922
|
||||
// refreshUserMergeRequestCounts();
|
||||
refreshUserMergeRequestCounts();
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
|
|
|
@ -796,6 +796,14 @@
|
|||
.navbar-gitlab {
|
||||
li.dropdown {
|
||||
position: static;
|
||||
|
||||
&.user-counter {
|
||||
margin-left: 8px !important;
|
||||
|
||||
> a {
|
||||
padding: 0 4px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -172,7 +172,7 @@
|
|||
}
|
||||
|
||||
li {
|
||||
.badge.badge-pill {
|
||||
.badge.badge-pill:not(.merge-request-badge) {
|
||||
box-shadow: none;
|
||||
font-weight: $gl-font-weight-bold;
|
||||
}
|
||||
|
@ -438,7 +438,7 @@
|
|||
|
||||
.title-container,
|
||||
.navbar-nav {
|
||||
.badge.badge-pill {
|
||||
.badge.badge-pill:not(.merge-request-badge) {
|
||||
position: inherit;
|
||||
font-weight: $gl-font-weight-normal;
|
||||
margin-left: -6px;
|
||||
|
|
|
@ -11,6 +11,10 @@ module DashboardHelper
|
|||
merge_requests_dashboard_path(assignee_username: current_user.username)
|
||||
end
|
||||
|
||||
def reviewer_mrs_dashboard_path
|
||||
merge_requests_dashboard_path(reviewer_username: current_user.username)
|
||||
end
|
||||
|
||||
def dashboard_nav_links
|
||||
@dashboard_nav_links ||= get_dashboard_nav_links
|
||||
end
|
||||
|
|
|
@ -159,6 +159,32 @@ module MergeRequestsHelper
|
|||
|
||||
issuable_path(issuable, { merge_request: { wip_event: wip_event } })
|
||||
end
|
||||
|
||||
def user_merge_requests_counts
|
||||
@user_merge_requests_counts ||= begin
|
||||
assigned_count = assigned_issuables_count(:merge_requests)
|
||||
review_requested_count = review_requested_merge_requests_count
|
||||
total_count = assigned_count + review_requested_count
|
||||
|
||||
{
|
||||
assigned: assigned_count,
|
||||
review_requested: review_requested_count,
|
||||
total: total_count
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def merge_request_reviewers_enabled?
|
||||
Feature.enabled?(:merge_request_reviewers, default_enabled: :yaml)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def review_requested_merge_requests_count
|
||||
return 0 unless merge_request_reviewers_enabled?
|
||||
|
||||
current_user.review_requested_open_merge_requests_count
|
||||
end
|
||||
end
|
||||
|
||||
MergeRequestsHelper.prepend_if_ee('EE::MergeRequestsHelper')
|
||||
|
|
|
@ -1564,6 +1564,12 @@ class User < ApplicationRecord
|
|||
end
|
||||
end
|
||||
|
||||
def review_requested_open_merge_requests_count(force: false)
|
||||
Rails.cache.fetch(['users', id, 'review_requested_open_merge_requests_count'], force: force, expires_in: 20.minutes) do
|
||||
MergeRequestsFinder.new(self, reviewer_id: id, state: 'opened', non_archived: true).execute.count
|
||||
end
|
||||
end
|
||||
|
||||
def assigned_open_issues_count(force: false)
|
||||
Rails.cache.fetch(['users', id, 'assigned_open_issues_count'], force: force, expires_in: 20.minutes) do
|
||||
IssuesFinder.new(self, assignee_id: self.id, state: 'opened', non_archived: true).execute.count
|
||||
|
@ -1607,6 +1613,7 @@ class User < ApplicationRecord
|
|||
|
||||
def invalidate_merge_request_cache_counts
|
||||
Rails.cache.delete(['users', id, 'assigned_open_merge_requests_count'])
|
||||
Rails.cache.delete(['users', id, 'review_requested_open_merge_requests_count'])
|
||||
end
|
||||
|
||||
def invalidate_todos_done_count
|
||||
|
|
|
@ -135,10 +135,6 @@ class ProjectPolicy < BasePolicy
|
|||
::Feature.enabled?(:build_service_proxy, @subject)
|
||||
end
|
||||
|
||||
condition(:project_bot_is_member) do
|
||||
user.project_bot? & team_member?
|
||||
end
|
||||
|
||||
with_scope :subject
|
||||
condition(:packages_disabled) { !@subject.packages_enabled }
|
||||
|
||||
|
@ -619,8 +615,6 @@ class ProjectPolicy < BasePolicy
|
|||
enable :admin_resource_access_tokens
|
||||
end
|
||||
|
||||
rule { project_bot_is_member & ~blocked }.enable :bot_log_in
|
||||
|
||||
private
|
||||
|
||||
def user_is_user?
|
||||
|
|
|
@ -112,9 +112,11 @@ module MergeRequests
|
|||
end
|
||||
|
||||
def handle_reviewers_change(merge_request, old_reviewers)
|
||||
affected_reviewers = (old_reviewers + merge_request.reviewers) - (old_reviewers & merge_request.reviewers)
|
||||
create_reviewer_note(merge_request, old_reviewers)
|
||||
notification_service.async.changed_reviewer_of_merge_request(merge_request, current_user, old_reviewers)
|
||||
todo_service.reassigned_reviewable(merge_request, current_user, old_reviewers)
|
||||
invalidate_cache_counts(merge_request, users: affected_reviewers.compact)
|
||||
end
|
||||
|
||||
def create_branch_change_note(issuable, branch_type, old_branch, new_branch)
|
||||
|
|
|
@ -47,17 +47,36 @@
|
|||
%span.badge.badge-pill.issues-count.green-badge{ class: ('hidden' if issues_count == 0) }
|
||||
= number_with_delimiter(issues_count)
|
||||
- if header_link?(:merge_requests)
|
||||
= nav_link(path: 'dashboard#merge_requests', html_options: { class: "user-counter" }) do
|
||||
= link_to assigned_mrs_dashboard_path, title: _('Merge requests'), class: 'dashboard-shortcuts-merge_requests', aria: { label: _('Merge requests') },
|
||||
data: { qa_selector: 'merge_requests_shortcut_button', toggle: 'tooltip', placement: 'bottom',
|
||||
- reviewers_enabled = merge_request_reviewers_enabled?
|
||||
= nav_link(path: 'dashboard#merge_requests', html_options: { class: "user-counter #{reviewers_enabled ? 'dropdown' : ''}" }) do
|
||||
= link_to assigned_mrs_dashboard_path, class: 'dashboard-shortcuts-merge_requests', title: _('Merge requests'), aria: { label: _('Merge requests') },
|
||||
data: { qa_selector: 'merge_requests_shortcut_button',
|
||||
toggle: reviewers_enabled ? "dropdown" : "tooltip",
|
||||
placement: 'bottom',
|
||||
track_label: 'main_navigation',
|
||||
track_event: 'click_merge_link',
|
||||
track_property: 'navigation',
|
||||
container: 'body' } do
|
||||
= sprite_icon('git-merge')
|
||||
- merge_requests_count = assigned_issuables_count(:merge_requests)
|
||||
%span.badge.badge-pill.merge-requests-count{ class: ('hidden' if merge_requests_count == 0) }
|
||||
= number_with_delimiter(merge_requests_count)
|
||||
%span.badge.badge-pill.merge-requests-count.js-merge-requests-count{ class: ('hidden' if user_merge_requests_counts[:total] == 0) }
|
||||
= number_with_delimiter(user_merge_requests_counts[:total])
|
||||
- if reviewers_enabled
|
||||
= sprite_icon('chevron-down', css_class: 'caret-down gl-mx-0!')
|
||||
- if reviewers_enabled
|
||||
.dropdown-menu.dropdown-menu-right
|
||||
%ul
|
||||
%li.dropdown-header
|
||||
= _('Merge requests')
|
||||
%li
|
||||
= link_to assigned_mrs_dashboard_path, class: 'gl-display-flex! gl-align-items-center' do
|
||||
= _('Assigned to you')
|
||||
%span.badge.gl-badge.badge-pill.badge-muted.merge-request-badge.gl-ml-auto.js-assigned-mr-count{ class: "" }
|
||||
= user_merge_requests_counts[:assigned]
|
||||
%li
|
||||
= link_to reviewer_mrs_dashboard_path, class: 'gl-display-flex! gl-align-items-center' do
|
||||
= _('Review requests for you')
|
||||
%span.badge.gl-badge.badge-pill.badge-muted.merge-request-badge.gl-ml-auto.js-reviewer-mr-count{ class: "" }
|
||||
= user_merge_requests_counts[:review_requested]
|
||||
- if header_link?(:todos)
|
||||
= nav_link(controller: 'dashboard/todos', html_options: { class: "user-counter" }) do
|
||||
= link_to dashboard_todos_path, title: _('To-Do List'), aria: { label: _('To-Do List') }, class: 'shortcuts-todos',
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Fix project access token regression
|
||||
merge_request: 50800
|
||||
author:
|
||||
type: fixed
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
title: Fix empty pipeline analytics charts when time_zone is non-UTC
|
||||
merge_request: 50760
|
||||
author:
|
||||
type: fixed
|
|
@ -459,11 +459,11 @@ Cluster.
|
|||
| `alert` | Hash | yes | Alerts detail. Currently same format as [3rd party alert](../operations/incident_management/alert_integrations.md#customize-the-alert-payload-outside-of-gitlab). |
|
||||
|
||||
```plaintext
|
||||
POST internal/kubernetes/modules/cilium/network_alert
|
||||
POST internal/kubernetes/modules/cilium_alert
|
||||
```
|
||||
|
||||
Example Request:
|
||||
|
||||
```shell
|
||||
curl --request POST --header "Gitlab-Kas-Api-Request: <JWT token>" --header "Authorization: Bearer <agent token>" --header "Content-Type: application/json" --data '"{\"alert\":{\"title\":\"minimal\",\"message\":\"network problem\",\"evalMatches\":[{\"value\":1,\"metric\":\"Count\",\"tags\":{}}]}}"' "http://localhost:3000/api/v4/internal/kubernetes/modules/cilium/network_alert"
|
||||
curl --request POST --header "Gitlab-Kas-Api-Request: <JWT token>" --header "Authorization: Bearer <agent token>" --header "Content-Type: application/json" --data '"{\"alert\":{\"title\":\"minimal\",\"message\":\"network problem\",\"evalMatches\":[{\"value\":1,\"metric\":\"Count\",\"tags\":{}}]}}"' "http://localhost:3000/api/v4/internal/kubernetes/modules/cilium_alert"
|
||||
```
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 27 KiB |
Binary file not shown.
Before Width: | Height: | Size: 9.8 KiB |
BIN
doc/user/admin_area/img/license_upload_v13_8.png
Normal file
BIN
doc/user/admin_area/img/license_upload_v13_8.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
|
@ -42,18 +42,21 @@ Otherwise, you can:
|
|||
|
||||
1. Navigate to the **License** tab, and click **Upload New License**.
|
||||
|
||||
![License Admin Area](img/license_admin_area.png)
|
||||
- *If you've received a `.gitlab-license` file:*
|
||||
1. Download the license file to your local machine.
|
||||
1. Select **Upload `.gitlab-license` file**.
|
||||
1. Select **Choose File** and select the license file.
|
||||
In this example the license file is named `GitLab.gitlab-license`.
|
||||
1. Check the **Subscription Agreement** checkbox.
|
||||
1. Select **Upload License**.
|
||||
|
||||
- *If you've received a `.gitlab-license` file,* you should have already downloaded
|
||||
it in your local machine. You can then upload it directly by choosing the
|
||||
license file and clicking the **Upload license** button. In the image below,
|
||||
the selected license file is named `GitLab.gitlab-license`.
|
||||
![Upload license](img/license_upload_v13_8.png)
|
||||
|
||||
![Upload license](img/license_upload.png)
|
||||
|
||||
- *If you've received your license as plain text,* select the
|
||||
**Enter license key** option, copy the license, paste it into the **License key**
|
||||
field, and click **Upload license**.
|
||||
- *If you've received your license as plain text:*
|
||||
1. Select **Enter license key**.
|
||||
1. Copy the license and paste it into the **License key** field.
|
||||
1. Check the **Subscription Agreement** checkbox.
|
||||
1. Select **Upload License**.
|
||||
|
||||
## Add your license at install time
|
||||
|
||||
|
|
|
@ -47,6 +47,9 @@ To enforce confirmation of the email address used for new sign ups:
|
|||
1. Go to **Admin Area > Settings > General** and expand **Sign-up restrictions**.
|
||||
1. Select the **Enable email restrictions for sign ups** checkbox, then select **Save changes**.
|
||||
|
||||
In [GitLab 13.7 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/273258), if an administrator disables this setting, the users in pending approval state are
|
||||
automatically approved in a background job.
|
||||
|
||||
## User cap **(CORE ONLY)**
|
||||
|
||||
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/4315) in GitLab 13.6.
|
||||
|
|
|
@ -102,7 +102,7 @@ To authenticate to the Package Registry, you must use one of the following:
|
|||
- It's not recommended, but you can use [OAuth tokens](../../../api/oauth2.md#resource-owner-password-credentials-flow).
|
||||
Standard OAuth tokens cannot authenticate to the GitLab NPM Registry. You must use a personal access token with OAuth headers.
|
||||
- A [CI job token](#authenticate-with-a-ci-job-token).
|
||||
- Your NPM package name must be in the format of [@scope:package-name](#package-naming-convention). It must match exactly, including the case.
|
||||
- Your NPM package name must be in the format of [@scope/package-name](#package-naming-convention). It must match exactly, including the case.
|
||||
|
||||
### Authenticate with a personal access token or deploy token
|
||||
|
||||
|
@ -201,7 +201,7 @@ Then, you can run `npm publish` either locally or by using GitLab CI/CD.
|
|||
|
||||
## Package naming convention
|
||||
|
||||
Your NPM package name must be in the format of `@scope:package-name`.
|
||||
Your NPM package name must be in the format of `@scope/package-name`.
|
||||
|
||||
- The `@scope` is the root namespace of the GitLab project. It must match exactly, including the case.
|
||||
- The `package-name` can be whatever you want.
|
||||
|
@ -241,7 +241,7 @@ Prerequisites:
|
|||
|
||||
- [Authenticate](#authenticate-to-the-package-registry) to the Package Registry.
|
||||
- Set a [project-level NPM endpoint](#use-the-gitlab-endpoint-for-npm-packages).
|
||||
- Your NPM package name must be in the format of [@scope:package-name](#package-naming-convention). It must match exactly, including the case.
|
||||
- Your NPM package name must be in the format of [@scope/package-name](#package-naming-convention). It must match exactly, including the case.
|
||||
|
||||
To upload an NPM package to your project, run this command:
|
||||
|
||||
|
@ -461,7 +461,7 @@ If you get this error, ensure that:
|
|||
### `npm publish` returns `npm ERR! 400 Bad Request`
|
||||
|
||||
If you get this error, your package name may not meet the
|
||||
[@scope:package-name package naming convention](#package-naming-convention).
|
||||
[@scope/package-name package naming convention](#package-naming-convention).
|
||||
|
||||
Ensure the name meets the convention exactly, including the case.
|
||||
Then try to publish again.
|
||||
|
|
|
@ -235,9 +235,12 @@ password = ${env.CI_JOB_TOKEN}
|
|||
|
||||
When publishing packages, note that:
|
||||
|
||||
- The maximum allowed size is 50 MB.
|
||||
- You must [authenticate with the Package Registry](#authenticate-with-the-package-registry).
|
||||
- Your [version string must be valid](#ensure-your-version-string-is-valid).
|
||||
- The maximum allowed package size is 5 GB.
|
||||
- You can't upload the same version of a package multiple times. If you try,
|
||||
you receive the error `Validation failed: File name has already been taken`.
|
||||
- You cannot publish PyPI packages to a group, only to a project.
|
||||
|
||||
### Ensure your version string is valid
|
||||
|
||||
|
|
|
@ -12,7 +12,9 @@ module API
|
|||
unauthorized! unless current_user
|
||||
|
||||
{
|
||||
merge_requests: current_user.assigned_open_merge_requests_count
|
||||
merge_requests: current_user.assigned_open_merge_requests_count, # @deprecated
|
||||
assigned_merge_requests: current_user.assigned_open_merge_requests_count,
|
||||
review_requested_merge_requests: current_user.review_requested_open_merge_requests_count
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -198,7 +198,9 @@ module Gitlab
|
|||
|
||||
return unless valid_scoped_token?(token, all_available_scopes)
|
||||
|
||||
if token.user.can?(:log_in) || token.user.can?(:bot_log_in, project)
|
||||
return if project && token.user.project_bot? && !project.bots.include?(token.user)
|
||||
|
||||
if token.user.can?(:log_in) || token.user.project_bot?
|
||||
Gitlab::Auth::Result.new(token.user, nil, :personal_access_token, abilities_for_scopes(token.scopes))
|
||||
end
|
||||
end
|
||||
|
@ -283,7 +285,7 @@ module Gitlab
|
|||
return unless build.project.builds_enabled?
|
||||
|
||||
if build.user
|
||||
return unless build.user.can?(:log_in) || build.user.can?(:bot_log_in, build.project)
|
||||
return unless build.user.can?(:log_in) || (build.user.project_bot? && build.project.bots&.include?(build.user))
|
||||
|
||||
# If user is assigned to build, use restricted credentials of user
|
||||
Gitlab::Auth::Result.new(build.user, build.project, :build, build_authentication_abilities)
|
||||
|
|
|
@ -31,10 +31,9 @@ module Gitlab
|
|||
|
||||
current = @from
|
||||
while current <= @to
|
||||
label = current.strftime(@format)
|
||||
@labels << label
|
||||
@total << (totals_count[label] || 0)
|
||||
@success << (success_count[label] || 0)
|
||||
@labels << current.strftime(@format)
|
||||
@total << (totals_count[current] || 0)
|
||||
@success << (success_count[current] || 0)
|
||||
|
||||
current += interval_step
|
||||
end
|
||||
|
@ -46,7 +45,6 @@ module Gitlab
|
|||
query
|
||||
.group("date_trunc('#{interval}', #{::Ci::Pipeline.table_name}.created_at)")
|
||||
.count(:created_at)
|
||||
.transform_keys { |date| date.strftime(@format) }
|
||||
end
|
||||
# rubocop: enable CodeReuse/ActiveRecord
|
||||
|
||||
|
|
|
@ -3943,6 +3943,9 @@ msgstr ""
|
|||
msgid "Assigned to me"
|
||||
msgstr ""
|
||||
|
||||
msgid "Assigned to you"
|
||||
msgstr ""
|
||||
|
||||
msgid "Assignee"
|
||||
msgid_plural "%d Assignees"
|
||||
msgstr[0] ""
|
||||
|
@ -24032,6 +24035,9 @@ msgstr ""
|
|||
msgid "Review requested from %{name}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Review requests for you"
|
||||
msgstr ""
|
||||
|
||||
msgid "Review the changes locally"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -110,6 +110,12 @@ RSpec.describe 'Dashboard Merge Requests' do
|
|||
visit merge_requests_dashboard_path(assignee_username: current_user.username)
|
||||
end
|
||||
|
||||
it 'includes assigned and reviewers in badge' do
|
||||
expect(find('.merge-requests-count')).to have_content('3')
|
||||
expect(find('.js-assigned-mr-count')).to have_content('2')
|
||||
expect(find('.js-reviewer-mr-count')).to have_content('1')
|
||||
end
|
||||
|
||||
it 'shows assigned merge requests' do
|
||||
expect(page).to have_content(assigned_merge_request.title)
|
||||
expect(page).to have_content(assigned_merge_request_from_fork.title)
|
||||
|
|
|
@ -8,7 +8,7 @@ import Api from '~/api';
|
|||
jest.mock('~/api');
|
||||
|
||||
const TEST_COUNT = 1000;
|
||||
const MR_COUNT_CLASS = 'merge-requests-count';
|
||||
const MR_COUNT_CLASS = 'js-merge-requests-count';
|
||||
|
||||
describe('User Merge Requests', () => {
|
||||
let channelMock;
|
||||
|
@ -24,7 +24,9 @@ describe('User Merge Requests', () => {
|
|||
newBroadcastChannelMock = jest.fn().mockImplementation(() => channelMock);
|
||||
|
||||
global.BroadcastChannel = newBroadcastChannelMock;
|
||||
setFixtures(`<div class="${MR_COUNT_CLASS}">0</div>`);
|
||||
setFixtures(
|
||||
`<div><div class="${MR_COUNT_CLASS}">0</div><div class="js-assigned-mr-count"></div><div class="js-reviewer-mr-count"></div></div>`,
|
||||
);
|
||||
});
|
||||
|
||||
const findMRCountText = () => document.body.querySelector(`.${MR_COUNT_CLASS}`).textContent;
|
||||
|
@ -33,7 +35,10 @@ describe('User Merge Requests', () => {
|
|||
beforeEach(() => {
|
||||
Api.userCounts.mockReturnValue(
|
||||
Promise.resolve({
|
||||
data: { merge_requests: TEST_COUNT },
|
||||
data: {
|
||||
assigned_merge_requests: TEST_COUNT,
|
||||
review_requested_merge_requests: TEST_COUNT,
|
||||
},
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
@ -46,7 +51,7 @@ describe('User Merge Requests', () => {
|
|||
});
|
||||
|
||||
it('updates the top count of merge requests', () => {
|
||||
expect(findMRCountText()).toEqual(TEST_COUNT.toLocaleString());
|
||||
expect(findMRCountText()).toEqual(Number(TEST_COUNT + TEST_COUNT).toLocaleString());
|
||||
});
|
||||
|
||||
it('calls the API', () => {
|
||||
|
@ -54,7 +59,7 @@ describe('User Merge Requests', () => {
|
|||
});
|
||||
|
||||
it('posts count to BroadcastChannel', () => {
|
||||
expect(channelMock.postMessage).toHaveBeenCalledWith(TEST_COUNT);
|
||||
expect(channelMock.postMessage).toHaveBeenCalledWith(TEST_COUNT + TEST_COUNT);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -89,4 +89,10 @@ RSpec.describe DashboardHelper do
|
|||
|
||||
it { is_expected.to eq(false) }
|
||||
end
|
||||
|
||||
describe '#reviewer_mrs_dashboard_path' do
|
||||
subject { helper.reviewer_mrs_dashboard_path }
|
||||
|
||||
it { is_expected.to eq(merge_requests_dashboard_path(reviewer_username: user.username)) }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -67,4 +67,37 @@ RSpec.describe MergeRequestsHelper do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#user_merge_requests_counts' do
|
||||
let(:user) do
|
||||
double(
|
||||
assigned_open_merge_requests_count: 1,
|
||||
review_requested_open_merge_requests_count: 2
|
||||
)
|
||||
end
|
||||
|
||||
subject { helper.user_merge_requests_counts }
|
||||
|
||||
before do
|
||||
allow(helper).to receive(:current_user).and_return(user)
|
||||
end
|
||||
|
||||
it "returns assigned, review requested and total merge request counts" do
|
||||
expect(subject).to eq(
|
||||
assigned: user.assigned_open_merge_requests_count,
|
||||
review_requested: user.review_requested_open_merge_requests_count,
|
||||
total: user.assigned_open_merge_requests_count + user.review_requested_open_merge_requests_count
|
||||
)
|
||||
end
|
||||
|
||||
context 'when merge_request_reviewers is disabled' do
|
||||
before do
|
||||
stub_feature_flags(merge_request_reviewers: false)
|
||||
end
|
||||
|
||||
it 'returns review_requested as 0' do
|
||||
expect(subject[:review_requested]).to eq(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -47,10 +47,6 @@ RSpec.describe Gitlab::Ci::Charts do
|
|||
|
||||
subject { chart.to }
|
||||
|
||||
before do
|
||||
create(:ci_empty_pipeline, project: project, duration: 120)
|
||||
end
|
||||
|
||||
it 'includes the whole current day' do
|
||||
is_expected.to eq(Date.today.end_of_day)
|
||||
end
|
||||
|
@ -62,37 +58,6 @@ RSpec.describe Gitlab::Ci::Charts do
|
|||
it 'uses %d %B as labels format' do
|
||||
expect(chart.labels).to include(chart.from.strftime('%d %B'))
|
||||
end
|
||||
|
||||
it 'returns count of pipelines run each day in the current week' do
|
||||
expect(chart.total).to contain_exactly(0, 0, 0, 0, 0, 0, 0, 1)
|
||||
end
|
||||
end
|
||||
|
||||
context 'weekchart_non_utc' do
|
||||
today = Date.today
|
||||
end_of_today = Time.use_zone(Time.find_zone('Asia/Dubai')) { today.end_of_day }
|
||||
|
||||
let(:project) { create(:project) }
|
||||
let(:chart) do
|
||||
allow(Date).to receive(:today).and_return(today)
|
||||
allow(today).to receive(:end_of_day).and_return(end_of_today)
|
||||
Gitlab::Ci::Charts::WeekChart.new(project)
|
||||
end
|
||||
|
||||
subject { chart.total }
|
||||
|
||||
before do
|
||||
create(:ci_empty_pipeline, project: project, duration: 120)
|
||||
end
|
||||
|
||||
it 'uses a non-utc time zone for range times' do
|
||||
expect(chart.to.zone).to eq(end_of_today.zone)
|
||||
expect(chart.from.zone).to eq(end_of_today.zone)
|
||||
end
|
||||
|
||||
it 'returns count of pipelines run each day in the current week' do
|
||||
is_expected.to contain_exactly(0, 0, 0, 0, 0, 0, 0, 1)
|
||||
end
|
||||
end
|
||||
|
||||
context 'pipeline_times' do
|
||||
|
|
|
@ -4084,6 +4084,7 @@ RSpec.describe User do
|
|||
cache_mock = double
|
||||
|
||||
expect(cache_mock).to receive(:delete).with(['users', user.id, 'assigned_open_merge_requests_count'])
|
||||
expect(cache_mock).to receive(:delete).with(['users', user.id, 'review_requested_open_merge_requests_count'])
|
||||
|
||||
allow(Rails).to receive(:cache).and_return(cache_mock)
|
||||
|
||||
|
@ -4163,6 +4164,20 @@ RSpec.describe User do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#review_requested_open_merge_requests_count' do
|
||||
it 'returns number of open merge requests from non-archived projects' do
|
||||
user = create(:user)
|
||||
project = create(:project, :public)
|
||||
archived_project = create(:project, :public, :archived)
|
||||
|
||||
create(:merge_request, source_project: project, author: user, reviewers: [user])
|
||||
create(:merge_request, :closed, source_project: project, author: user, reviewers: [user])
|
||||
create(:merge_request, source_project: archived_project, author: user, reviewers: [user])
|
||||
|
||||
expect(user.review_requested_open_merge_requests_count(force: true)).to eq 1
|
||||
end
|
||||
end
|
||||
|
||||
describe '#assigned_open_issues_count' do
|
||||
it 'returns number of open issues from non-archived projects' do
|
||||
user = create(:user)
|
||||
|
|
|
@ -401,40 +401,6 @@ RSpec.describe ProjectPolicy do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'bot_log_in' do
|
||||
let(:bot_user) { create(:user, :project_bot) }
|
||||
let(:project) { private_project }
|
||||
|
||||
context 'when bot is in project and is not blocked' do
|
||||
before do
|
||||
project.add_maintainer(bot_user)
|
||||
end
|
||||
|
||||
it 'is a valid project bot' do
|
||||
expect(bot_user.can?(:bot_log_in, project)).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
context 'when project bot is invalid' do
|
||||
context 'when bot is not in project' do
|
||||
it 'is not a valid project bot' do
|
||||
expect(bot_user.can?(:bot_log_in, project)).to be_falsy
|
||||
end
|
||||
end
|
||||
|
||||
context 'when bot user is blocked' do
|
||||
before do
|
||||
project.add_maintainer(bot_user)
|
||||
bot_user.block!
|
||||
end
|
||||
|
||||
it 'is not a valid project bot' do
|
||||
expect(bot_user.can?(:bot_log_in, project)).to be_falsy
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'support bot' do
|
||||
let(:current_user) { User.support_bot }
|
||||
|
||||
|
|
|
@ -521,6 +521,19 @@ RSpec.describe MergeRequests::UpdateService, :mailer do
|
|||
should_email(user2)
|
||||
should_email(user3)
|
||||
end
|
||||
|
||||
it 'updates open merge request counter for reviewers', :use_clean_rails_memory_store_caching do
|
||||
merge_request.reviewers = [user3]
|
||||
|
||||
# Cache them to ensure the cache gets invalidated on update
|
||||
expect(user2.review_requested_open_merge_requests_count).to eq(0)
|
||||
expect(user3.review_requested_open_merge_requests_count).to eq(1)
|
||||
|
||||
update_merge_request(reviewer_ids: [user2.id])
|
||||
|
||||
expect(user2.review_requested_open_merge_requests_count).to eq(1)
|
||||
expect(user3.review_requested_open_merge_requests_count).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the milestone is removed' do
|
||||
|
|
Loading…
Reference in a new issue