Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2023-09-19 12:08:54 +00:00
parent 236caf4b92
commit 6b95202d1c
16 changed files with 158 additions and 124 deletions

View File

@ -1 +1 @@
e450c7ca1115ddc16b3db84a5400b781ed81e2e6
fe0a04858c9a5172379077343b16e1fd2e017903

View File

@ -152,6 +152,7 @@ audit events to external destinations.
| [`incident_closed_by_project_bot`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/121485) | Triggered when an incident is closed using a project access token | **{check-circle}** Yes | **{check-circle}** Yes | `incident_management` | GitLab [16.1](https://gitlab.com/gitlab-org/gitlab/-/issues/323299) |
| [`incident_created_by_project_bot`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/121485) | Triggered when an incident is created using a project access token | **{check-circle}** Yes | **{check-circle}** Yes | `incident_management` | GitLab [16.1](https://gitlab.com/gitlab-org/gitlab/-/issues/323299) |
| [`incident_reopened_by_project_bot`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/121485) | Triggered when an incident is reopened using a project access token | **{check-circle}** Yes | **{check-circle}** Yes | `incident_management` | GitLab [16.1](https://gitlab.com/gitlab-org/gitlab/-/issues/323299) |
| [`instance_google_cloud_logging_configuration_created`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/130663) | Triggered when Instance level Google Cloud Logging configuration is created | **{check-circle}** Yes | **{check-circle}** Yes | `audit_events` | GitLab [16.4](https://gitlab.com/gitlab-org/gitlab/-/issues/423038) |
| [`instance_google_cloud_logging_configuration_deleted`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/131752) | Triggered when instance level Google Cloud Logging configuration is deleted. | **{check-circle}** Yes | **{check-circle}** Yes | `audit_events` | GitLab [16.5](https://gitlab.com/gitlab-org/gitlab/-/issues/423040) |
| [`ip_restrictions_changed`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/86037) | Event triggered on any changes in the IP AllowList | **{check-circle}** Yes | **{check-circle}** Yes | `system_access` | GitLab [15.0](https://gitlab.com/gitlab-org/gitlab/-/issues/358986) |
| [`issue_closed_by_project_bot`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/121485) | Triggered when an issue is closed using a project access token | **{check-circle}** Yes | **{check-circle}** Yes | `team_planning` | GitLab [16.1](https://gitlab.com/gitlab-org/gitlab/-/issues/323299) |

View File

@ -990,7 +990,7 @@ For example, if a commit (`<COMMIT_ID>`) deletes line 463 in the README, you can
on the deletion by referencing line 463 in the *old* file:
```shell
curl --request POST --header "PRIVATE-TOKEN: [ACCESS_TOKEN]" \
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
--form "note=Very clever to remove this unnecessary line!" \
--form "path=README" --form "line=463" --form "line_type=old" \
"https://gitlab.com/api/v4/projects/47/repository/commits/<COMMIT_ID>/comments"
@ -1000,7 +1000,7 @@ If a commit (`<COMMIT_ID>`) adds line 157 to `hello.rb`, you can comment on the
addition by referencing line 157 in the *new* file:
```shell
curl --request POST --header "PRIVATE-TOKEN: [ACCESS_TOKEN]" \
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
--form "note=This is brilliant!" --form "path=hello.rb" \
--form "line=157" --form "line_type=new" \
"https://gitlab.com/api/v4/projects/47/repository/commits/<COMMIT_ID>/comments"

View File

@ -4096,6 +4096,29 @@ Input type: `InstanceExternalAuditEventDestinationUpdateInput`
| <a id="mutationinstanceexternalauditeventdestinationupdateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| <a id="mutationinstanceexternalauditeventdestinationupdateinstanceexternalauditeventdestination"></a>`instanceExternalAuditEventDestination` | [`InstanceExternalAuditEventDestination`](#instanceexternalauditeventdestination) | Updated destination. |
### `Mutation.instanceGoogleCloudLoggingConfigurationCreate`
Input type: `InstanceGoogleCloudLoggingConfigurationCreateInput`
#### Arguments
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationinstancegooglecloudloggingconfigurationcreateclientemail"></a>`clientEmail` | [`String!`](#string) | Email address associated with the service account that will be used to authenticate and interact with the Google Cloud Logging service. This is part of the IAM credentials. |
| <a id="mutationinstancegooglecloudloggingconfigurationcreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationinstancegooglecloudloggingconfigurationcreategoogleprojectidname"></a>`googleProjectIdName` | [`String!`](#string) | Unique identifier of the Google Cloud project to which the logging configuration belongs. |
| <a id="mutationinstancegooglecloudloggingconfigurationcreatelogidname"></a>`logIdName` | [`String`](#string) | Unique identifier used to distinguish and manage different logs within the same Google Cloud project.(defaults to `audit_events`). |
| <a id="mutationinstancegooglecloudloggingconfigurationcreatename"></a>`name` | [`String`](#string) | Destination name. |
| <a id="mutationinstancegooglecloudloggingconfigurationcreateprivatekey"></a>`privateKey` | [`String!`](#string) | Private Key associated with the service account. This key is used to authenticate the service account and authorize it to interact with the Google Cloud Logging service. |
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationinstancegooglecloudloggingconfigurationcreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationinstancegooglecloudloggingconfigurationcreateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| <a id="mutationinstancegooglecloudloggingconfigurationcreateinstancegooglecloudloggingconfiguration"></a>`instanceGoogleCloudLoggingConfiguration` | [`InstanceGoogleCloudLoggingConfigurationType`](#instancegooglecloudloggingconfigurationtype) | configuration created. |
### `Mutation.instanceGoogleCloudLoggingConfigurationDestroy`
Input type: `InstanceGoogleCloudLoggingConfigurationDestroyInput`
@ -23757,8 +23780,8 @@ The amount of time for a job to be picked up by a runner, in percentiles.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="queueinghistorytimeseriesp25"></a>`p25` **{warning-solid}** | [`Duration`](#duration) | **Introduced** in 16.4. This feature is an Experiment. It can be changed or removed at any time. 25th percentile. 25% of the durations are lower than this value. |
| <a id="queueinghistorytimeseriesp50"></a>`p50` **{warning-solid}** | [`Duration`](#duration) | **Introduced** in 16.4. This feature is an Experiment. It can be changed or removed at any time. 50th percentile. 50% of the durations are lower than this value. |
| <a id="queueinghistorytimeseriesp75"></a>`p75` **{warning-solid}** | [`Duration`](#duration) | **Introduced** in 16.4. This feature is an Experiment. It can be changed or removed at any time. 75th percentile. 75% of the durations are lower than this value. |
| <a id="queueinghistorytimeseriesp90"></a>`p90` **{warning-solid}** | [`Duration`](#duration) | **Introduced** in 16.4. This feature is an Experiment. It can be changed or removed at any time. 90th percentile. 90% of the durations are lower than this value. |
| <a id="queueinghistorytimeseriesp95"></a>`p95` **{warning-solid}** | [`Duration`](#duration) | **Introduced** in 16.4. This feature is an Experiment. It can be changed or removed at any time. 95th percentile. 95% of the durations are lower than this value. |
| <a id="queueinghistorytimeseriesp99"></a>`p99` **{warning-solid}** | [`Duration`](#duration) | **Introduced** in 16.4. This feature is an Experiment. It can be changed or removed at any time. 99th percentile. 99% of the durations are lower than this value. |

View File

@ -48,7 +48,7 @@ If successful, returns [`200`](rest/index.md#status-codes) and the following res
Example request:
```shell
curl --header "Authorization: Bearer <your_access_token>" "https://gitlab.example.com/api/v4/groups/:id/member_roles"
curl --header "Authorization: Bearer <your_access_token>" "https://gitlab.example.com/api/v4/groups/84/member_roles"
```
Example response:
@ -124,7 +124,7 @@ If successful, returns [`201`](rest/index.md#status-codes) and the following att
Example request:
```shell
curl --request POST --header "Content-Type: application/json" --header "Authorization: Bearer $YOUR_ACCESS_TOKEN" --data '{"name" : "Custom guest", "base_access_level" : 10, "read_code" : true}' "https://example.gitlab.com/api/v4/groups/:id/member_roles"
curl --request POST --header "Content-Type: application/json" --header "Authorization: Bearer <your_access_token>" --data '{"name" : "Custom guest", "base_access_level" : 10, "read_code" : true}' "https://gitlab.example.com/api/v4/groups/84/member_roles"
```
Example response:
@ -168,5 +168,5 @@ If successful, returns [`204`](rest/index.md#status-codes) and an empty response
Example request:
```shell
curl --request DELETE --header "Content-Type: application/json" --header "Authorization: Bearer $YOUR_ACCESS_TOKEN" "https://example.gitlab.com/api/v4/groups/:group_id/member_roles/:member_role_id"
curl --request DELETE --header "Content-Type: application/json" --header "Authorization: Bearer <your_access_token>" "https://gitlab.example.com/api/v4/groups/84/member_roles/1"
```

View File

@ -40,7 +40,7 @@ To use GitLab CI/CD with a Bitbucket Cloud repository:
using the Personal Access Token we just generated for authentication.
```plaintext
https://gitlab.com/api/v4/projects/<PROJECT_ID>/mirror/pull?private_token=<PERSONAL_ACCESS_TOKEN>
https://gitlab.example.com/api/v4/projects/:project_id/mirror/pull?private_token=<your_personal_access_token>
```
The web hook Trigger should be set to 'Repository Push'.

View File

@ -371,7 +371,7 @@ For example:
```yaml
variables:
SITE_URL: "https://example.gitlab.com"
SITE_URL: "https://gitlab.example.com"
job:
script:

View File

@ -108,8 +108,8 @@ For example, to configure these values in the
```ruby
::Gitlab::CurrentSettings.update!(secret_detection_token_revocation_token: 'MYSECRETTOKEN')
::Gitlab::CurrentSettings.update!(secret_detection_token_revocation_url: 'https://example.gitlab.com/revocation_service/v1/revoke_tokens')
::Gitlab::CurrentSettings.update!(secret_detection_revocation_token_types_url: 'https://example.gitlab.com/revocation_service/v1/revocable_token_types')
::Gitlab::CurrentSettings.update!(secret_detection_token_revocation_url: 'https://gitlab.example.com/revocation_service/v1/revoke_tokens')
::Gitlab::CurrentSettings.update!(secret_detection_revocation_token_types_url: 'https://gitlab.example.com/revocation_service/v1/revocable_token_types')
::Gitlab::CurrentSettings.update!(secret_detection_token_revocation_enabled: true)
```

View File

@ -42,16 +42,13 @@ To view the dependencies of a project or all projects in a group:
Details of each dependency are listed, sorted by decreasing severity of vulnerabilities (if any). You can sort the list instead by component name or packager.
NOTE:
The project search feature is supported only on groups that have up to 600 occurrences in their group hierarchy.
| Field | Description |
|:----------|:-----------|
| Component | The dependency's name and version. |
| Packager | The packager used to install the dependency. |
| Location | For system dependencies, this lists the image that was scanned. For application dependencies, this shows a link to the packager-specific lock file in your project that declared the dependency. It also shows the [dependency path](#dependency-paths) to a top-level dependency, if any, and if supported. |
| License<sup>1</sup> | Links to dependency's software licenses. A warning badge that includes the number of vulnerabilities detected in the dependency. |
| Projects<sup>2</sup> | Links to the project related to the dependency. If there are multiple projects, the total number of projects is displayed. |
| Projects<sup>2</sup> | Links to the project with the dependency. If multiple projects have the same dependency, the total number of these projects is shown. To go to a project with this dependency, select the **Projects** number, then search for and select its name. The project search feature is supported only on groups that have up to 600 occurrences in their group hierarchy. |
<html>
<small>Footnotes:

View File

@ -491,12 +491,15 @@ The following custom roles are available:
You can discuss individual custom role and permission requests in [issue 391760](https://gitlab.com/gitlab-org/gitlab/-/issues/391760).
When you enable the view vulnerability custom role for a user with the Guest role, that user has access to elevated permissions, and therefore:
When you enable a custom role for a user with the Guest role, that user has
access to elevated permissions, and therefore:
- Is considered a [billable user](../subscriptions/self_managed/index.md#billable-users) on self-managed GitLab.
- [Uses a seat](../subscriptions/gitlab_com/index.md#how-seat-usage-is-determined) on GitLab.com.
This does not apply to the Guest+1 custom role because the `view_code` ability is excluded from this behavior.
This does not apply to Guest+1, a Guest custom role that only enables the `read_code`
permission. Users with that specific custom role are not considered billable users
and do not use a seat.
### Create a custom role
@ -567,24 +570,24 @@ the Owner role:
1. Invites a user as a direct member to the root group or any subgroup or project in the root
group's hierarchy as a Guest. At this point, this Guest user cannot see any
code on the projects in the group or subgroup.
1. Optional. If the Owner does not know the `ID` of the Guest user receiving a custom
role, finds that `ID` by making an [API request](../api/member_roles.md#list-all-member-roles-of-a-group).
1. Optional. If the Owner does not know the `id` of the Guest user receiving a custom
role, finds that `id` by making an [API request](../api/member_roles.md#list-all-member-roles-of-a-group).
1. Associates the member with the Guest+1 role using the [Group and Project Members API endpoint](../api/members.md#edit-a-member-of-a-group-or-project)
```shell
# to update a project membership
curl --request PUT --header "Content-Type: application/json" --header "Authorization: Bearer $YOUR_ACCESS_TOKEN" --data '{"member_role_id": '$MEMBER_ROLE_ID', "access_level": 10}' "https://example.gitlab.com/api/v4/projects/$ID/members/$GUEST_USER_ID"
curl --request PUT --header "Content-Type: application/json" --header "Authorization: Bearer <your_access_token>" --data '{"member_role_id": '<member_role_id>', "access_level": 10}' "https://gitlab.example.com/api/v4/projects/<project_id>/members/<user_id>"
# to update a group membership
curl --request PUT --header "Content-Type: application/json" --header "Authorization: Bearer $YOUR_ACCESS_TOKEN" --data '{"member_role_id": '$MEMBER_ROLE_ID', "access_level": 10}' "https://example.gitlab.com/api/v4/groups/$ID/members/$GUEST_USER_ID"
curl --request PUT --header "Content-Type: application/json" --header "Authorization: Bearer <your_access_token>" --data '{"member_role_id": '<member_role_id>', "access_level": 10}' "https://gitlab.example.com/api/v4/groups/<group_id>/members/<user_id>"
```
Where:
- `$ID`: The `ID` or [URL-encoded path of the project or group](../api/rest/index.md#namespaced-path-encoding) associated with the membership receiving the custom role.
- `$MEMBER_ROLE_ID`: The `ID` of the member role created in the previous section.
- `$GUEST_USER_ID`: The `ID` of the Guest user receiving a custom role.
- `<project_id` and `<group_id>`: The `id` or [URL-encoded path of the project or group](../api/rest/index.md#namespaced-path-encoding) associated with the membership receiving the custom role.
- `<member_role_id>`: The `id` of the member role created in the previous section.
- `<user_id>`: The `id` of the user receiving a custom role.
Now the Guest+1 user can view code on all projects associated with this membership.
@ -604,7 +607,11 @@ To remove a custom role from a group member, use the [Group and Project Members
and pass an empty `member_role_id` value.
```shell
curl --request PUT --header "Content-Type: application/json" --header "Authorization: Bearer $YOUR_ACCESS_TOKEN" --data '{"member_role_id": "", "access_level": 10}' "https://example.gitlab.com/api/v4/groups/$GROUP_PATH/members/$GUEST_USER_ID"
# to update a project membership
curl --request PUT --header "Content-Type: application/json" --header "Authorization: Bearer <your_access_token>" --data '{"member_role_id": "", "access_level": 10}' "https://gitlab.example.com/api/v4/projects/<project_id>/members/<user_id>"
# to update a group membership
curl --request PUT --header "Content-Type: application/json" --header "Authorization: Bearer <your_access_token>" --data '{"member_role_id": "", "access_level": 10}' "https://gitlab.example.com/api/v4/groups/<group_id>/members/<user_id>"
```
#### Remove a group member with a custom role from the group
@ -628,11 +635,12 @@ custom role.
1. In the **Actions** column, select **Delete role** (**{remove}**) and confirm.
To delete a custom role, you can also [use the API](../api/member_roles.md#remove-member-role-of-a-group).
To use the API, you must know the `ID` of the custom role. If you do not know this
`ID`, find it by making an [API request](../api/member_roles.md#list-all-member-roles-of-a-group).
To use the API, you must know the `id` of the custom role. If you do not know this
`id`, find it by making an [API request](../api/member_roles.md#list-all-member-roles-of-a-group).
### Known issues
- Additional permissions can only be applied to users with the Guest role.
- If a user with a custom role is shared with a group or project, their custom role is not transferred over with them. The user has the regular Guest role in the new group or project.
- If a user with a custom role is shared with a group or project, their custom
role is not transferred over with them. The user has the regular Guest role in
the new group or project.
- You cannot use an [Auditor user](../administration/auditor_users.md) as a template for a custom role.

View File

@ -988,7 +988,7 @@ Payload example:
"draft": {
"previous": true,
"current": false
}
},
"updated_at": {
"previous": "2017-09-15 16:50:55 UTC",
"current":"2017-09-15 16:52:00 UTC"
@ -1026,7 +1026,7 @@ Payload example:
"last_edited_by_id": {
"previous": null,
"current": 3278533
},
}
},
"assignees": [
{

View File

@ -117,6 +117,14 @@ Your customer success manager then provisions access by commenting on [issue 415
After GitLab has provisioned access to Code Suggestions for your instance,
the users in your instance can now enable Code Suggestions.
### Configure network and proxy settings
Configure any firewalls to allow outbound connections to `https://codesuggestions.gitlab.com/`.
If your GitLab instance uses an HTTP proxy server to access the internet, ensure
the server is configured to allow outbound connections, including the
[`gitlab_workhorse` environment variable](https://docs.gitlab.com/omnibus/settings/environment-variables.html).
### Update GitLab
In GitLab 16.3 and later, GitLab is enforcing the cloud licensing requirement for Code Suggestions:
@ -164,12 +172,6 @@ This feature is currently in [Beta](../../../../policy/experiment-beta-support.m
Code Suggestions depends on both Google Vertex AI Codey APIs and the GitLab Code Suggestions service. We have built this feature to gracefully degrade and have controls in place to allow us to
mitigate abuse or misuse. GitLab may disable this feature for any or all customers at any time at our discretion.
### Code Suggestions network and proxy settings
Make sure any firewalls are configured to allow outbound connections to `https://codesuggestions.gitlab.com/`.
If your GitLab instance uses an HTTP proxy server to access the internet, make sure that it is configured, including for [`gitlab_workhorse`](https://docs.gitlab.com/omnibus/settings/environment-variables.html).
### Data privacy
A self-managed GitLab instance does not generate the code suggestion. After successful

View File

@ -3,7 +3,8 @@
module Constraints
class ActivityPubConstrainer
def matches?(request)
mime_types.any? { |m| request.headers.fetch('Accept', '').include?(m) }
accept = header(request)
mime_types.any? { |m| accept.include?(m) }
end
private
@ -11,5 +12,9 @@ module Constraints
def mime_types
['application/activity+json', 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"']
end
def header(request)
request.headers['Accept'] || request.headers['Content-Type'] || ''
end
end
end

View File

@ -352,7 +352,7 @@ export default {
merge_request_widget_path: '/root/acets-app/-/merge_requests/22/widget.json',
merge_request_cached_widget_path: '/cached.json',
merge_check_path: '/root/acets-app/-/merge_requests/22/merge_check',
ci_environments_status_url: '/root/acets-app/-/merge_requests/22/ci_environments_status',
ci_environments_status_path: '/root/acets-app/-/merge_requests/22/ci_environments_status',
project_archived: false,
default_merge_commit_message_with_description:
"Merge branch 'daaaa' into 'main'\n\nUpdate README.md\n\nSee merge request !22",

View File

@ -184,23 +184,6 @@ describe('MrWidgetOptions', () => {
});
describe('default', () => {
beforeEach(() => {
jest.spyOn(document, 'dispatchEvent');
});
// quarantine: https://gitlab.com/gitlab-org/gitlab/-/issues/385238
// eslint-disable-next-line jest/no-disabled-tests
describe.skip('data', () => {
beforeEach(() => {
createComponent();
});
it('should instantiate Store and Service', () => {
expect(wrapper.vm.mr).toBeDefined();
expect(wrapper.vm.service).toBeDefined();
});
});
describe('computed', () => {
describe('componentName', () => {
beforeEach(async () => {
@ -353,30 +336,42 @@ describe('MrWidgetOptions', () => {
describe('methods', () => {
describe('checkStatus', () => {
let cb;
let isCbExecuted;
beforeEach(async () => {
await createComponent();
jest.spyOn(wrapper.vm.service, 'checkStatus').mockResolvedValue({ data: mockData });
jest.spyOn(wrapper.vm.mr, 'setData').mockImplementation(() => {});
jest.spyOn(wrapper.vm, 'handleNotification').mockImplementation(() => {});
isCbExecuted = false;
cb = () => {
isCbExecuted = true;
};
it('checks the status of the pipelines', async () => {
const callback = jest.fn();
await createComponent({ updatedMrData: { foo: 1 } });
await waitForPromises();
eventHub.$emit('MRWidgetUpdateRequested', callback);
await waitForPromises();
expect(callback).toHaveBeenCalledWith(expect.objectContaining({ foo: 1 }));
});
it('should tell service to check status if document is visible', () => {
wrapper.vm.checkStatus(cb);
return nextTick().then(() => {
expect(wrapper.vm.service.checkStatus).toHaveBeenCalled();
expect(wrapper.vm.mr.setData).toHaveBeenCalled();
expect(wrapper.vm.handleNotification).toHaveBeenCalledWith(mockData);
expect(isCbExecuted).toBe(true);
it('notifies the user of the pipeline status', async () => {
jest.spyOn(notify, 'notifyMe').mockImplementation(() => {});
const logoFilename = 'logo.png';
await createComponent({
updatedMrData: { gitlabLogo: logoFilename },
});
eventHub.$emit('MRWidgetUpdateRequested');
await waitForPromises();
expect(notify.notifyMe).toHaveBeenCalledWith(
`Pipeline passed`,
`Pipeline passed for "${mockData.title}"`,
logoFilename,
);
});
it('updates the stores data', async () => {
const mockSetData = jest.fn();
await createComponent({
data: {
mr: {
setData: mockSetData,
setGraphqlData: jest.fn(),
},
},
});
eventHub.$emit('MRWidgetUpdateRequested');
expect(mockSetData).toHaveBeenCalled();
});
});
@ -398,66 +393,63 @@ describe('MrWidgetOptions', () => {
describe('fetchDeployments', () => {
beforeEach(async () => {
mock
.onGet(mockData.ci_environments_status_path)
.reply(() => [HTTP_STATUS_OK, [{ id: 1, status: SUCCESS }]]);
await createComponent();
});
it('should fetch deployments', () => {
jest
.spyOn(wrapper.vm.service, 'fetchDeployments')
.mockResolvedValue({ data: [{ id: 1, status: SUCCESS }] });
wrapper.vm.fetchPreMergeDeployments();
return nextTick().then(() => {
expect(wrapper.vm.service.fetchDeployments).toHaveBeenCalled();
expect(wrapper.vm.mr.deployments.length).toEqual(1);
expect(wrapper.vm.mr.deployments[0].id).toBe(1);
});
it('should fetch deployments', async () => {
eventHub.$emit('FetchDeployments', {});
await waitForPromises();
expect(wrapper.vm.mr.deployments.length).toEqual(1);
expect(wrapper.vm.mr.deployments[0].id).toBe(1);
});
});
describe('fetchActionsContent', () => {
const innerHTML = 'hello world';
beforeEach(async () => {
jest.spyOn(document, 'dispatchEvent');
mock.onGet(mockData.commit_change_content_path).reply(() => [HTTP_STATUS_OK, innerHTML]);
await createComponent();
});
it('should fetch content of Cherry Pick and Revert modals', () => {
jest
.spyOn(wrapper.vm.service, 'fetchMergeActionsContent')
.mockResolvedValue({ data: 'hello world' });
wrapper.vm.fetchActionsContent();
return nextTick().then(() => {
expect(wrapper.vm.service.fetchMergeActionsContent).toHaveBeenCalled();
expect(document.body.textContent).toContain('hello world');
expect(document.dispatchEvent).toHaveBeenCalledWith(
new CustomEvent('merged:UpdateActions'),
);
});
it('should fetch content of Cherry Pick and Revert modals', async () => {
eventHub.$emit('FetchActionsContent');
await waitForPromises();
expect(document.body.textContent).toContain(innerHTML);
expect(document.dispatchEvent).toHaveBeenCalledWith(
new CustomEvent('merged:UpdateActions'),
);
});
});
describe('bindEventHubListeners', () => {
const mockSetData = jest.fn();
beforeEach(async () => {
await createComponent();
await createComponent({
data: {
mr: {
setData: mockSetData,
setGraphqlData: jest.fn(),
},
},
});
});
it.each`
event | method | methodArgs
${'MRWidgetUpdateRequested'} | ${'checkStatus'} | ${(x) => [x]}
${'MRWidgetRebaseSuccess'} | ${'checkStatus'} | ${(x) => [x, true]}
${'FetchActionsContent'} | ${'fetchActionsContent'} | ${() => []}
${'EnablePolling'} | ${'resumePolling'} | ${() => []}
${'DisablePolling'} | ${'stopPolling'} | ${() => []}
${'FetchDeployments'} | ${'fetchPreMergeDeployments'} | ${() => []}
`('should bind to $event', ({ event, method, methodArgs }) => {
jest.spyOn(wrapper.vm, method).mockImplementation();
it('refetches when "MRWidgetUpdateRequested" event is emitted', async () => {
expect(stateQueryHandler).toHaveBeenCalledTimes(1);
eventHub.$emit('MRWidgetUpdateRequested', () => {});
await waitForPromises();
expect(stateQueryHandler).toHaveBeenCalledTimes(2);
});
const eventArg = {};
eventHub.$emit(event, eventArg);
expect(wrapper.vm[method]).toHaveBeenCalledWith(...methodArgs(eventArg));
it('refetches when "MRWidgetRebaseSuccess" event is emitted', async () => {
expect(stateQueryHandler).toHaveBeenCalledTimes(1);
eventHub.$emit('MRWidgetRebaseSuccess', () => {});
await waitForPromises();
expect(stateQueryHandler).toHaveBeenCalledTimes(2);
});
it('should bind to SetBranchRemoveFlag', () => {
@ -473,7 +465,7 @@ describe('MrWidgetOptions', () => {
it('should bind to FailedToMerge', async () => {
expect(findAlertMessage().exists()).toBe(false);
expect(findPipelineContainer().props('mr')).toMatchObject({
mergeError: null,
mergeError: undefined,
state: 'merged',
});
const mergeError = 'Something bad happened!';
@ -488,12 +480,10 @@ describe('MrWidgetOptions', () => {
});
it('should bind to UpdateWidgetData', () => {
jest.spyOn(wrapper.vm.mr, 'setData').mockImplementation();
const data = { ...mockData };
eventHub.$emit('UpdateWidgetData', data);
expect(wrapper.vm.mr.setData).toHaveBeenCalledWith(data);
expect(mockSetData).toHaveBeenCalledWith(data);
});
});

View File

@ -11,16 +11,24 @@ RSpec.describe Constraints::ActivityPubConstrainer, feature_category: :groups_an
let(:request) { ActionDispatch::Request.new(headers) }
['application/ld+json; profile="https://www.w3.org/ns/activitystreams"', 'application/activity+json'].each do |mime|
context "when mime is #{mime}" do
context "when Accept header is #{mime}" do
let(:headers) { { 'HTTP_ACCEPT' => mime } }
it 'matches the header' do
is_expected.to be_truthy
end
end
context "when Content-Type header is #{mime}" do
let(:headers) { { 'CONTENT_TYPE' => mime } }
it 'matches the header' do
is_expected.to be_truthy
end
end
end
context 'when Accept header is missing' do
context 'when Accept and Content-Type headers are missing' do
let(:headers) { {} }
it 'does not match' do