Commit 0be08932 authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents e30c2a00 3e98649b
...@@ -6,13 +6,9 @@ info: To determine the technical writer assigned to the Stage/Group associated w ...@@ -6,13 +6,9 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Merge requests API **(FREE)** # Merge requests API **(FREE)**
> - `with_labels_details` was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413) in GitLab 12.7.
> - `author_username` and `author_username` were [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13060) in GitLab 12.10.
> - `reference` was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20354) in GitLab 12.10 in favour of `references`. > - `reference` was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20354) in GitLab 12.10 in favour of `references`.
> - `with_merge_status_recheck` was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31890) in GitLab 13.0.
> - `reviewer_username` and `reviewer_id` were [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49341) in GitLab 13.8. > - `reviewer_username` and `reviewer_id` were [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49341) in GitLab 13.8.
> - `reviewer_ids` was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/51186) in GitLab 13.8. > - `draft` was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/63473) as a replacement for `work_in_progress` in GitLab 14.0.
> - `draft` was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/63473) as an eventual replacement for `work_in_progress` in GitLab 14.0
Every API call to merge requests must be authenticated. Every API call to merge requests must be authenticated.
...@@ -53,9 +49,10 @@ default it returns only merge requests created by the current user. To ...@@ -53,9 +49,10 @@ default it returns only merge requests created by the current user. To
get all merge requests, use parameter `scope=all`. get all merge requests, use parameter `scope=all`.
The `state` parameter can be used to get only merge requests with a The `state` parameter can be used to get only merge requests with a
given state (`opened`, `closed`, `locked`, or `merged`) or all of them (`all`). It should be noted that when searching by `locked` it mostly returns no results as it is a short-lived, transitional state. given state (`opened`, `closed`, `locked`, or `merged`) or all of them (`all`).
The pagination parameters `page` and `per_page` can be used to It should be noted that when searching by `locked` it mostly returns no results
restrict the list of merge requests. as it is a short-lived, transitional state. The pagination parameters `page` and
`per_page` can be used to restrict the list of merge requests.
```plaintext ```plaintext
GET /merge_requests GET /merge_requests
...@@ -79,21 +76,21 @@ Parameters: ...@@ -79,21 +76,21 @@ Parameters:
| `sort` | string | no | Return requests sorted in `asc` or `desc` order. Default is `desc`. | | `sort` | string | no | Return requests sorted in `asc` or `desc` order. Default is `desc`. |
| `milestone` | string | no | Return merge requests for a specific milestone. `None` returns merge requests with no milestone. `Any` returns merge requests that have an assigned milestone. | | `milestone` | string | no | Return merge requests for a specific milestone. `None` returns merge requests with no milestone. `Any` returns merge requests that have an assigned milestone. |
| `view` | string | no | If `simple`, returns the `iid`, URL, title, description, and basic state of merge request. | | `view` | string | no | If `simple`, returns the `iid`, URL, title, description, and basic state of merge request. |
| `labels` | string | no | Return merge requests matching a comma-separated list of labels. `None` lists all merge requests with no labels. `Any` lists all merge requests with at least one label. `No+Label` (Deprecated) lists all merge requests with no labels. Predefined names are case-insensitive. | | `labels` | string | no | Return merge requests matching a comma-separated list of labels. `None` lists all merge requests with no labels. `Any` lists all merge requests with at least one label. Predefined names are case-insensitive. |
| `with_labels_details` | boolean | no | If `true`, response returns more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. | | `with_labels_details` | boolean | no | If `true`, response returns more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413) in GitLab 12.7. |
| `with_merge_status_recheck` | boolean | no | If `true`, this projection requests (but does not guarantee) that the `merge_status` field be recalculated asynchronously. Default is `false`. | | `with_merge_status_recheck` | boolean | no | If `true`, this projection requests (but does not guarantee) that the `merge_status` field be recalculated asynchronously. Default is `false`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31890) in GitLab 13.0. |
| `created_after` | datetime | no | Return merge requests created on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) | | `created_after` | datetime | no | Return merge requests created on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `created_before` | datetime | no | Return merge requests created on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) | | `created_before` | datetime | no | Return merge requests created on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `updated_after` | datetime | no | Return merge requests updated on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) | | `updated_after` | datetime | no | Return merge requests updated on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `updated_before` | datetime | no | Return merge requests updated on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) | | `updated_before` | datetime | no | Return merge requests updated on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `scope` | string | no | Return merge requests for the given scope: `created_by_me`, `assigned_to_me` or `all`. Defaults to `created_by_me`<br> For versions before 11.0, use the now deprecated `created-by-me` or `assigned-to-me` scopes instead. | | `scope` | string | no | Return merge requests for the given scope: `created_by_me`, `assigned_to_me` or `all`. Defaults to `created_by_me`. |
| `author_id` | integer | no | Returns merge requests created by the given user `id`. Mutually exclusive with `author_username`. Combine with `scope=all` or `scope=assigned_to_me`. | | `author_id` | integer | no | Returns merge requests created by the given user `id`. Mutually exclusive with `author_username`. Combine with `scope=all` or `scope=assigned_to_me`. |
| `author_username` | string | no | Returns merge requests created by the given `username`. Mutually exclusive with `author_id`. | | `author_username` | string | no | Returns merge requests created by the given `username`. Mutually exclusive with `author_id`. [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13060) in GitLab 12.10. |
| `assignee_id` | integer | no | Returns merge requests assigned to the given user `id`. `None` returns unassigned merge requests. `Any` returns merge requests with an assignee. | | `assignee_id` | integer | no | Returns merge requests assigned to the given user `id`. `None` returns unassigned merge requests. `Any` returns merge requests with an assignee. |
| `approver_ids` **(PREMIUM)** | integer array | no | Returns merge requests which have specified all the users with the given `id`s as individual approvers. `None` returns merge requests without approvers. `Any` returns merge requests with an approver. | | `approver_ids` **(PREMIUM)** | integer array | no | Returns merge requests which have specified all the users with the given `id`s as individual approvers. `None` returns merge requests without approvers. `Any` returns merge requests with an approver. |
| `approved_by_ids` **(PREMIUM)** | integer array | no | Returns merge requests which have been approved by all the users with the given `id`s (Max: 5). `None` returns merge requests with no approvals. `Any` returns merge requests with an approval. | | `approved_by_ids` **(PREMIUM)** | integer array | no | Returns merge requests which have been approved by all the users with the given `id`s (Max: 5). `None` returns merge requests with no approvals. `Any` returns merge requests with an approval. |
| `reviewer_id` | integer | no | Returns merge requests which have the user as a [reviewer](../user/project/merge_requests/getting_started.md#reviewer) with the given user `id`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_username`. | | `reviewer_id` | integer | no | Returns merge requests which have the user as a [reviewer](../user/project/merge_requests/getting_started.md#reviewer) with the given user `id`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_username`. |
| `reviewer_username` | string | no | Returns merge requests which have the user as a [reviewer](../user/project/merge_requests/getting_started.md#reviewer) with the given `username`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_id`. | | `reviewer_username` | string | no | Returns merge requests which have the user as a [reviewer](../user/project/merge_requests/getting_started.md#reviewer) with the given `username`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_id`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49341) in GitLab 13.8. |
| `my_reaction_emoji` | string | no | Return merge requests reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. | | `my_reaction_emoji` | string | no | Return merge requests reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. |
| `source_branch` | string | no | Return merge requests with the given source branch. | | `source_branch` | string | no | Return merge requests with the given source branch. |
| `target_branch` | string | no | Return merge requests with the given target branch. | | `target_branch` | string | no | Return merge requests with the given target branch. |
...@@ -266,21 +263,21 @@ Parameters: ...@@ -266,21 +263,21 @@ Parameters:
| `sort` | string | no | Return requests sorted in `asc` or `desc` order. Default is `desc`. | | `sort` | string | no | Return requests sorted in `asc` or `desc` order. Default is `desc`. |
| `milestone` | string | no | Return merge requests for a specific milestone. `None` returns merge requests with no milestone. `Any` returns merge requests that have an assigned milestone. | | `milestone` | string | no | Return merge requests for a specific milestone. `None` returns merge requests with no milestone. `Any` returns merge requests that have an assigned milestone. |
| `view` | string | no | If `simple`, returns the `iid`, URL, title, description, and basic state of merge request. | | `view` | string | no | If `simple`, returns the `iid`, URL, title, description, and basic state of merge request. |
| `labels` | string | no | Return merge requests matching a comma-separated list of labels. `None` lists all merge requests with no labels. `Any` lists all merge requests with at least one label. `No+Label` (Deprecated) lists all merge requests with no labels. Predefined names are case-insensitive. | | `labels` | string | no | Return merge requests matching a comma-separated list of labels. `None` lists all merge requests with no labels. `Any` lists all merge requests with at least one label. Predefined names are case-insensitive. |
| `with_labels_details` | boolean | no | If `true`, response returns more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. | | `with_labels_details` | boolean | no | If `true`, response returns more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413) in GitLab 12.7. |
| `with_merge_status_recheck` | boolean | no | If `true`, this projection requests (but does not guarantee) that the `merge_status` field be recalculated asynchronously. Default is `false`. | | `with_merge_status_recheck` | boolean | no | If `true`, this projection requests (but does not guarantee) that the `merge_status` field be recalculated asynchronously. Default is `false`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31890) in GitLab 13.0. |
| `created_after` | datetime | no | Return merge requests created on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) | | `created_after` | datetime | no | Return merge requests created on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `created_before` | datetime | no | Return merge requests created on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) | | `created_before` | datetime | no | Return merge requests created on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `updated_after` | datetime | no | Return merge requests updated on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) | | `updated_after` | datetime | no | Return merge requests updated on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `updated_before` | datetime | no | Return merge requests updated on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) | | `updated_before` | datetime | no | Return merge requests updated on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `scope` | string | no | Return merge requests for the given scope: `created_by_me`, `assigned_to_me`, or `all`. | | `scope` | string | no | Return merge requests for the given scope: `created_by_me`, `assigned_to_me`, or `all`. |
| `author_id` | integer | no | Returns merge requests created by the given user `id`. Mutually exclusive with `author_username`. | | `author_id` | integer | no | Returns merge requests created by the given user `id`. Mutually exclusive with `author_username`. |
| `author_username` | string | no | Returns merge requests created by the given `username`. Mutually exclusive with `author_id`.| | `author_username` | string | no | Returns merge requests created by the given `username`. Mutually exclusive with `author_id`. [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13060) in GitLab 12.10. |
| `assignee_id` | integer | no | Returns merge requests assigned to the given user `id`. `None` returns unassigned merge requests. `Any` returns merge requests with an assignee. | | `assignee_id` | integer | no | Returns merge requests assigned to the given user `id`. `None` returns unassigned merge requests. `Any` returns merge requests with an assignee. |
| `approver_ids` **(PREMIUM)** | integer array | no | Returns merge requests which have specified all the users with the given `id`s as individual approvers. `None` returns merge requests without approvers. `Any` returns merge requests with an approver. | | `approver_ids` **(PREMIUM)** | integer array | no | Returns merge requests which have specified all the users with the given `id`s as individual approvers. `None` returns merge requests without approvers. `Any` returns merge requests with an approver. |
| `approved_by_ids` **(PREMIUM)** | integer array | no | Returns merge requests which have been approved by all the users with the given `id`s (Max: 5). `None` returns merge requests with no approvals. `Any` returns merge requests with an approval. | | `approved_by_ids` **(PREMIUM)** | integer array | no | Returns merge requests which have been approved by all the users with the given `id`s (Max: 5). `None` returns merge requests with no approvals. `Any` returns merge requests with an approval. |
| `reviewer_id` | integer | no | Returns merge requests which have the user as a [reviewer](../user/project/merge_requests/getting_started.md#reviewer) with the given user `id`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_username`. | | `reviewer_id` | integer | no | Returns merge requests which have the user as a [reviewer](../user/project/merge_requests/getting_started.md#reviewer) with the given user `id`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_username`. |
| `reviewer_username` | string | no | Returns merge requests which have the user as a [reviewer](../user/project/merge_requests/getting_started.md#reviewer) with the given `username`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_id`. | | `reviewer_username` | string | no | Returns merge requests which have the user as a [reviewer](../user/project/merge_requests/getting_started.md#reviewer) with the given `username`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_id`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49341) in GitLab 13.8. |
| `my_reaction_emoji` | string | no | Return merge requests reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. | | `my_reaction_emoji` | string | no | Return merge requests reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. |
| `source_branch` | string | no | Return merge requests with the given source branch. | | `source_branch` | string | no | Return merge requests with the given source branch. |
...@@ -453,8 +450,8 @@ Parameters: ...@@ -453,8 +450,8 @@ Parameters:
| `sort` | string | no | Return merge requests sorted in `asc` or `desc` order. Default is `desc`. | | `sort` | string | no | Return merge requests sorted in `asc` or `desc` order. Default is `desc`. |
| `milestone` | string | no | Return merge requests for a specific milestone. `None` returns merge requests with no milestone. `Any` returns merge requests that have an assigned milestone. | | `milestone` | string | no | Return merge requests for a specific milestone. `None` returns merge requests with no milestone. `Any` returns merge requests that have an assigned milestone. |
| `view` | string | no | If `simple`, returns the `iid`, URL, title, description, and basic state of merge request. | | `view` | string | no | If `simple`, returns the `iid`, URL, title, description, and basic state of merge request. |
| `labels` | string | no | Return merge requests matching a comma-separated list of labels. `None` lists all merge requests with no labels. `Any` lists all merge requests with at least one label. `No+Label` (Deprecated) lists all merge requests with no labels. Predefined names are case-insensitive. | | `labels` | string | no | Return merge requests matching a comma-separated list of labels. `None` lists all merge requests with no labels. `Any` lists all merge requests with at least one label. Predefined names are case-insensitive. |
| `with_labels_details` | boolean | no | If `true`, response returns more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413) in GitLab 12.7.| | `with_labels_details` | boolean | no | If `true`, response returns more details for each label in labels field: `:name`, `:color`, `:description`, `:description_html`, `:text_color`. Default is `false`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413) in GitLab 12.7. |
| `with_merge_status_recheck` | boolean | no | If `true`, this projection requests (but does not guarantee) that the `merge_status` field be recalculated asynchronously. Default is `false`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31890) in GitLab 13.0. | | `with_merge_status_recheck` | boolean | no | If `true`, this projection requests (but does not guarantee) that the `merge_status` field be recalculated asynchronously. Default is `false`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31890) in GitLab 13.0. |
| `created_after` | datetime | no | Return merge requests created on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | | `created_after` | datetime | no | Return merge requests created on or after the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). |
| `created_before` | datetime | no | Return merge requests created on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | | `created_before` | datetime | no | Return merge requests created on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). |
...@@ -462,12 +459,12 @@ Parameters: ...@@ -462,12 +459,12 @@ Parameters:
| `updated_before` | datetime | no | Return merge requests updated on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | | `updated_before` | datetime | no | Return merge requests updated on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). |
| `scope` | string | no | Return merge requests for the given scope: `created_by_me`, `assigned_to_me` or `all`. | | `scope` | string | no | Return merge requests for the given scope: `created_by_me`, `assigned_to_me` or `all`. |
| `author_id` | integer | no | Returns merge requests created by the given user `id`. Mutually exclusive with `author_username`. | | `author_id` | integer | no | Returns merge requests created by the given user `id`. Mutually exclusive with `author_username`. |
| `author_username` | string | no | Returns merge requests created by the given `username`. Mutually exclusive with `author_id`. _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13060) in GitLab 12.10)_. | | `author_username` | string | no | Returns merge requests created by the given `username`. Mutually exclusive with `author_id`. [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13060) in GitLab 12.10. |
| `assignee_id` | integer | no | Returns merge requests assigned to the given user `id`. `None` returns unassigned merge requests. `Any` returns merge requests with an assignee. | | `assignee_id` | integer | no | Returns merge requests assigned to the given user `id`. `None` returns unassigned merge requests. `Any` returns merge requests with an assignee. |
| `approver_ids` **(PREMIUM)** | integer array | no | Returns merge requests which have specified all the users with the given `id`s as individual approvers. `None` returns merge requests without approvers. `Any` returns merge requests with an approver. | | `approver_ids` **(PREMIUM)** | integer array | no | Returns merge requests which have specified all the users with the given `id`s as individual approvers. `None` returns merge requests without approvers. `Any` returns merge requests with an approver. |
| `approved_by_ids` **(PREMIUM)** | integer array | no | Returns merge requests which have been approved by all the users with the given `id`s (Max: 5). `None` returns merge requests with no approvals. `Any` returns merge requests with an approval. | | `approved_by_ids` **(PREMIUM)** | integer array | no | Returns merge requests which have been approved by all the users with the given `id`s (Max: 5). `None` returns merge requests with no approvals. `Any` returns merge requests with an approval. |
| `reviewer_id` | integer | no | Returns merge requests which have the user as a [reviewer](../user/project/merge_requests/getting_started.md#reviewer) with the given user `id`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_username`. | | `reviewer_id` | integer | no | Returns merge requests which have the user as a [reviewer](../user/project/merge_requests/getting_started.md#reviewer) with the given user `id`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_username`. |
| `reviewer_username` | string | no | Returns merge requests which have the user as a [reviewer](../user/project/merge_requests/getting_started.md#reviewer) with the given `username`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_id`. | | `reviewer_username` | string | no | Returns merge requests which have the user as a [reviewer](../user/project/merge_requests/getting_started.md#reviewer) with the given `username`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_id`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49341) in GitLab 13.8. |
| `my_reaction_emoji` | string | no | Return merge requests reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. | | `my_reaction_emoji` | string | no | Return merge requests reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. |
| `source_branch` | string | no | Return merge requests with the given source branch. | | `source_branch` | string | no | Return merge requests with the given source branch. |
| `target_branch` | string | no | Return merge requests with the given target branch. | | `target_branch` | string | no | Return merge requests with the given target branch. |
...@@ -1074,14 +1071,14 @@ POST /projects/:id/merge_requests ...@@ -1074,14 +1071,14 @@ POST /projects/:id/merge_requests
| `title` | string | yes | Title of MR. | | `title` | string | yes | Title of MR. |
| `assignee_id` | integer | no | Assignee user ID. | | `assignee_id` | integer | no | Assignee user ID. |
| `assignee_ids` | integer array | no | The ID of the user(s) to assign the MR to. Set to `0` or provide an empty value to unassign all assignees. | | `assignee_ids` | integer array | no | The ID of the user(s) to assign the MR to. Set to `0` or provide an empty value to unassign all assignees. |
| `reviewer_ids` | integer array | no | The ID of the user(s) added as a reviewer to the MR. If set to `0` or left empty, no reviewers are added. | | `reviewer_ids` | integer array | no | The ID of the user(s) added as a reviewer to the MR. If set to `0` or left empty, no reviewers are added. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49341) in GitLab 13.8. |
| `description` | string | no | Description of MR. Limited to 1,048,576 characters. | | `description` | string | no | Description of MR. Limited to 1,048,576 characters. |
| `target_project_id` | integer | no | The target project (numeric ID). | | `target_project_id` | integer | no | The target project (numeric ID). |
| `labels` | string | no | Labels for MR as a comma-separated list. | | `labels` | string | no | Labels for MR as a comma-separated list. |
| `milestone_id` | integer | no | The global ID of a milestone. | | `milestone_id` | integer | no | The global ID of a milestone. |
| `remove_source_branch` | boolean | no | Flag indicating if a merge request should remove the source branch when merging. | | `remove_source_branch` | boolean | no | Flag indicating if a merge request should remove the source branch when merging. |
| `allow_collaboration` | boolean | no | Allow commits from members who can merge to the target branch. | | `allow_collaboration` | boolean | no | Allow commits from members who can merge to the target branch. |
| `allow_maintainer_to_push` | boolean | no | Deprecated, see `allow_collaboration`. | | `allow_maintainer_to_push` | boolean | no | [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/22665), see `allow_collaboration`. |
| `squash` | boolean | no | Squash commits into a single commit when merging. | | `squash` | boolean | no | Squash commits into a single commit when merging. |
```json ```json
...@@ -1224,7 +1221,7 @@ PUT /projects/:id/merge_requests/:merge_request_iid ...@@ -1224,7 +1221,7 @@ PUT /projects/:id/merge_requests/:merge_request_iid
| `title` | string | no | Title of MR. | | `title` | string | no | Title of MR. |
| `assignee_id` | integer | no | The ID of the user to assign the merge request to. Set to `0` or provide an empty value to unassign all assignees. | | `assignee_id` | integer | no | The ID of the user to assign the merge request to. Set to `0` or provide an empty value to unassign all assignees. |
| `assignee_ids` | integer array | no | The ID of the user(s) to assign the MR to. Set to `0` or provide an empty value to unassign all assignees. | | `assignee_ids` | integer array | no | The ID of the user(s) to assign the MR to. Set to `0` or provide an empty value to unassign all assignees. |
| `reviewer_ids` | integer array | no | The ID of the user(s) set as a reviewer to the MR. Set the value to `0` or provide an empty value to unset all reviewers. | | `reviewer_ids` | integer array | no | The ID of the user(s) set as a reviewer to the MR. Set the value to `0` or provide an empty value to unset all reviewers. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49341) in GitLab 13.8. |
| `milestone_id` | integer | no | The global ID of a milestone to assign the merge request to. Set to `0` or provide an empty value to unassign a milestone.| | `milestone_id` | integer | no | The global ID of a milestone to assign the merge request to. Set to `0` or provide an empty value to unassign a milestone.|
| `labels` | string | no | Comma-separated label names for a merge request. Set to an empty string to unassign all labels. | | `labels` | string | no | Comma-separated label names for a merge request. Set to an empty string to unassign all labels. |
| `add_labels` | string | no | Comma-separated label names to add to a merge request. | | `add_labels` | string | no | Comma-separated label names to add to a merge request. |
...@@ -1235,7 +1232,7 @@ PUT /projects/:id/merge_requests/:merge_request_iid ...@@ -1235,7 +1232,7 @@ PUT /projects/:id/merge_requests/:merge_request_iid
| `squash` | boolean | no | Squash commits into a single commit when merging. | | `squash` | boolean | no | Squash commits into a single commit when merging. |
| `discussion_locked` | boolean | no | Flag indicating if the merge request's discussion is locked. If the discussion is locked only project members can add, edit or resolve comments. | | `discussion_locked` | boolean | no | Flag indicating if the merge request's discussion is locked. If the discussion is locked only project members can add, edit or resolve comments. |
| `allow_collaboration` | boolean | no | Allow commits from members who can merge to the target branch. | | `allow_collaboration` | boolean | no | Allow commits from members who can merge to the target branch. |
| `allow_maintainer_to_push` | boolean | no | Deprecated, see `allow_collaboration`. | | `allow_maintainer_to_push` | boolean | no | [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/22665), see `allow_collaboration`. |
Must include at least one non-required attribute from above. Must include at least one non-required attribute from above.
......
<script> <script>
import { GlLoadingIcon, GlLink } from '@gitlab/ui'; import { GlLoadingIcon, GlLink, GlKeysetPagination } from '@gitlab/ui';
import CorpusTable from 'ee/security_configuration/corpus_management/components/corpus_table.vue'; import CorpusTable from 'ee/security_configuration/corpus_management/components/corpus_table.vue';
import CorpusUpload from 'ee/security_configuration/corpus_management/components/corpus_upload.vue'; import CorpusUpload from 'ee/security_configuration/corpus_management/components/corpus_upload.vue';
import { s__, __ } from '~/locale'; import { s__, __ } from '~/locale';
...@@ -9,6 +9,7 @@ export default { ...@@ -9,6 +9,7 @@ export default {
components: { components: {
GlLoadingIcon, GlLoadingIcon,
GlLink, GlLink,
GlKeysetPagination,
CorpusTable, CorpusTable,
CorpusUpload, CorpusUpload,
}, },
...@@ -16,12 +17,14 @@ export default { ...@@ -16,12 +17,14 @@ export default {
states: { states: {
query: getCorpusesQuery, query: getCorpusesQuery,
variables() { variables() {
return { return this.queryVariables;
projectPath: this.projectFullPath,
};
}, },
update: (data) => { update: (data) => {
return data; const { pageInfo } = data.project.corpuses;
return {
...data,
pageInfo,
};
}, },
error() { error() {
this.states = null; this.states = null;
...@@ -29,20 +32,67 @@ export default { ...@@ -29,20 +32,67 @@ export default {
}, },
}, },
inject: ['projectFullPath', 'corpusHelpPath'], inject: ['projectFullPath', 'corpusHelpPath'],
data() {
return {
pagination: {
firstPageSize: this.$options.pageSize,
lastPageSize: null,
},
};
},
pageSize: 10,
i18n: { i18n: {
header: s__('CorpusManagement|Fuzz testing corpus management'), header: s__('CorpusManagement|Fuzz testing corpus management'),
subHeader: s__( subHeader: s__(
'CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing.', 'CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing.',
), ),
learnMore: __('Learn More'), learnMore: __('Learn More'),
previousPage: __('Prev'),
nextPage: __('Next'),
}, },
computed: { computed: {
corpuses() { corpuses() {
return this.states?.project.corpuses.nodes || []; return this.states?.project.corpuses.nodes || [];
}, },
pageInfo() {
return this.states?.pageInfo || {};
},
isLoading() { isLoading() {
return this.$apollo.loading; return this.$apollo.loading;
}, },
queryVariables() {
return {
projectPath: this.projectFullPath,
...this.pagination,
};
},
hasPagination() {
return Boolean(this.states) && (this.pageInfo.hasPreviousPage || this.pageInfo.hasNextPage);
},
},
methods: {
fetchCorpuses() {
this.pagination = {
afterCursor: null,
beforeCursor: null,
firstPageSize: this.$options.pageSize,
};
this.$apollo.queries.states.refetch();
},
nextPage() {
this.pagination = {
firstPageSize: this.$options.pageSize,
lastPageSize: null,
afterCursor: this.states.pageInfo.endCursor,
};
},
prevPage() {
this.pagination = {
firstPageSize: null,
lastPageSize: this.$options.pageSize,
beforeCursor: this.states.pageInfo.startCursor,
};
},
}, },
}; };
</script> </script>
...@@ -59,10 +109,21 @@ export default { ...@@ -59,10 +109,21 @@ export default {
</p> </p>
</header> </header>
<gl-loading-icon v-if="isLoading" size="lg" /> <corpus-upload @corpus-added="fetchCorpuses" />
<gl-loading-icon v-if="isLoading" size="lg" class="gl-py-13" />
<template v-else> <template v-else>
<corpus-upload />
<corpus-table :corpuses="corpuses" /> <corpus-table :corpuses="corpuses" />
</template> </template>
<div v-if="hasPagination" class="gl-display-flex gl-justify-content-center gl-mt-5">
<gl-keyset-pagination
v-bind="pageInfo"
:prev-text="$options.i18n.previousPage"
:next-text="$options.i18n.nextPage"
@prev="prevPage"
@next="nextPage"
/>
</div>
</div> </div>
</template> </template>
...@@ -52,6 +52,9 @@ export default { ...@@ -52,6 +52,9 @@ export default {
thClass, thClass,
}, },
], ],
i18n: {
emptyTable: s__('CorpusManagement|Currently, there are no uploaded or generated corpuses.'),
},
methods: { methods: {
onDelete({ name }) { onDelete({ name }) {
this.$apollo.mutate({ this.$apollo.mutate({
...@@ -73,7 +76,11 @@ export default { ...@@ -73,7 +76,11 @@ export default {
}; };
</script> </script>
<template> <template>
<gl-table :items="corpuses" :fields="$options.fields"> <gl-table :items="corpuses" :fields="$options.fields" show-empty>
<template #empty>
{{ $options.i18n.emptyTable }}
</template>
<template #cell(name)="{ item }"> <template #cell(name)="{ item }">
<name :corpus="item" /> <name :corpus="item" />
</template> </template>
......
...@@ -5,7 +5,7 @@ import { s__, __ } from '~/locale'; ...@@ -5,7 +5,7 @@ import { s__, __ } from '~/locale';
import addCorpusMutation from '../graphql/mutations/add_corpus.mutation.graphql'; import addCorpusMutation from '../graphql/mutations/add_corpus.mutation.graphql';
import resetCorpus from '../graphql/mutations/reset_corpus.mutation.graphql'; import resetCorpus from '../graphql/mutations/reset_corpus.mutation.graphql';
import uploadCorpus from '../graphql/mutations/upload_corpus.mutation.graphql'; import uploadCorpus from '../graphql/mutations/upload_corpus.mutation.graphql';
import getCorpusesQuery from '../graphql/queries/get_corpuses.query.graphql'; import getUploadState from '../graphql/queries/get_upload_state.query.graphql';
import CorpusUploadForm from './corpus_upload_form.vue'; import CorpusUploadForm from './corpus_upload_form.vue';
export default { export default {
...@@ -26,10 +26,7 @@ export default { ...@@ -26,10 +26,7 @@ export default {
inject: ['projectFullPath'], inject: ['projectFullPath'],
apollo: { apollo: {
states: { states: {
query: getCorpusesQuery, query: getUploadState,
variables() {
return this.queryVariables;
},
update(data) { update(data) {
return data; return data;
}, },
...@@ -76,19 +73,17 @@ export default { ...@@ -76,19 +73,17 @@ export default {
}, },
methods: { methods: {
addCorpus() { addCorpus() {
this.$apollo.mutate({ return this.$apollo
.mutate({
mutation: addCorpusMutation, mutation: addCorpusMutation,
refetchQueries: [
{
query: getCorpusesQuery,
variables: this.queryVariables,
},
],
variables: { variables: {
name: this.$options.i18n.newCorpus, name: this.$options.i18n.newCorpus,
projectPath: this.projectFullPath, projectPath: this.projectFullPath,
packageId: this.states.uploadState.uploadedPackageId, packageId: this.states.uploadState.uploadedPackageId,
}, },
})
.then(() => {
this.$emit('corpus-added');
}); });
}, },
resetCorpus() { resetCorpus() {
......
fragment UploadState on UploadState {
isUploading
progress
cancelSource
uploadedPackageId
}
query getCorpuses($projectPath: ID!) { #import "~/graphql_shared/fragments/pageInfo.fragment.graphql"
#import "../fragments/uploadState.fragment.graphql"
query getCorpuses(
$projectPath: ID!
$beforeCursor: String = ""
$afterCursor: String = ""
$firstPageSize: Int
$lastPageSize: Int
) {
project(fullPath: $projectPath) { project(fullPath: $projectPath) {
id id
corpuses { corpuses(
before: $beforeCursor
after: $afterCursor
first: $firstPageSize
last: $lastPageSize
) {
nodes { nodes {
id id
package { package {
...@@ -24,12 +38,12 @@ query getCorpuses($projectPath: ID!) { ...@@ -24,12 +38,12 @@ query getCorpuses($projectPath: ID!) {
} }
} }
} }
pageInfo {
...PageInfo
} }
} }
uploadState(projectPath: $projectPath) @client { }
isUploading uploadState @client {
progress ...UploadState
cancelSource
uploadedPackageId
} }
} }
#import "../fragments/uploadState.fragment.graphql"
query getUploadState {
uploadState @client {
...UploadState
}
}
...@@ -3,15 +3,14 @@ import { publishPackage } from '~/api/packages_api'; ...@@ -3,15 +3,14 @@ import { publishPackage } from '~/api/packages_api';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import { convertToGraphQLId } from '~/graphql_shared/utils'; import { convertToGraphQLId } from '~/graphql_shared/utils';
import { TYPE_PACKAGES_PACKAGE } from '~/graphql_shared/constants'; import { TYPE_PACKAGES_PACKAGE } from '~/graphql_shared/constants';
import getCorpusesQuery from '../queries/get_corpuses.query.graphql'; import getUploadState from '../queries/get_upload_state.query.graphql';
import updateProgress from '../mutations/update_progress.mutation.graphql'; import updateProgress from '../mutations/update_progress.mutation.graphql';
import uploadComplete from '../mutations/upload_complete.mutation.graphql'; import uploadComplete from '../mutations/upload_complete.mutation.graphql';
import corpusCreate from '../mutations/corpus_create.mutation.graphql'; import corpusCreate from '../mutations/corpus_create.mutation.graphql';
export default { export default {
Query: { Query: {
/* eslint-disable no-unused-vars */ uploadState() {
uploadState(_, { projectPath }) {
return { return {
isUploading: false, isUploading: false,
progress: 0, progress: 0,
...@@ -24,7 +23,7 @@ export default { ...@@ -24,7 +23,7 @@ export default {
Mutation: { Mutation: {
addCorpus: (_, { projectPath, packageId }, { cache, client }) => { addCorpus: (_, { projectPath, packageId }, { cache, client }) => {
const sourceData = cache.readQuery({ const sourceData = cache.readQuery({
query: getCorpusesQuery, query: getUploadState,
variables: { projectPath }, variables: { projectPath },
}); });
...@@ -33,7 +32,7 @@ export default { ...@@ -33,7 +32,7 @@ export default {
draftState.uploadState.progress = 0; draftState.uploadState.progress = 0;
}); });
cache.writeQuery({ query: getCorpusesQuery, data, variables: { projectPath } }); cache.writeQuery({ query: getUploadState, data, variables: { projectPath } });
client.mutate({ client.mutate({
mutation: corpusCreate, mutation: corpusCreate,
...@@ -60,7 +59,7 @@ export default { ...@@ -60,7 +59,7 @@ export default {
const source = CancelToken.source(); const source = CancelToken.source();
const sourceData = cache.readQuery({ const sourceData = cache.readQuery({
query: getCorpusesQuery, query: getUploadState,
variables: { projectPath }, variables: { projectPath },
}); });
...@@ -70,7 +69,7 @@ export default { ...@@ -70,7 +69,7 @@ export default {
uploadState.cancelSource = source; uploadState.cancelSource = source;
}); });
cache.writeQuery({ query: getCorpusesQuery, data: targetData, variables: { projectPath } }); cache.writeQuery({ query: getUploadState, data: targetData, variables: { projectPath } });
publishPackage( publishPackage(
{ projectPath, name, version: 0, fileName: `${name}.zip`, files }, { projectPath, name, version: 0, fileName: `${name}.zip`, files },
...@@ -83,13 +82,13 @@ export default { ...@@ -83,13 +82,13 @@ export default {
variables: { projectPath, packageId: data.package_id }, variables: { projectPath, packageId: data.package_id },
}); });
}) })
.catch((e) => { .catch(() => {
/* TODO: Error handling */ /* TODO: Error handling */
}); });
}, },
uploadComplete: (_, { projectPath, packageId }, { cache }) => { uploadComplete: (_, { projectPath, packageId }, { cache }) => {
const sourceData = cache.readQuery({ const sourceData = cache.readQuery({
query: getCorpusesQuery, query: getUploadState,
variables: { projectPath }, variables: { projectPath },
}); });
...@@ -100,11 +99,11 @@ export default { ...@@ -100,11 +99,11 @@ export default {
uploadState.uploadedPackageId = packageId; uploadState.uploadedPackageId = packageId;
}); });
cache.writeQuery({ query: getCorpusesQuery, data, variables: { projectPath } }); cache.writeQuery({ query: getUploadState, data, variables: { projectPath } });
}, },
updateProgress: (_, { projectPath, progress }, { cache }) => { updateProgress: (_, { projectPath, progress }, { cache }) => {
const sourceData = cache.readQuery({ const sourceData = cache.readQuery({
query: getCorpusesQuery, query: getUploadState,
variables: { projectPath }, variables: { projectPath },
}); });
...@@ -114,11 +113,11 @@ export default { ...@@ -114,11 +113,11 @@ export default {
uploadState.progress = progress; uploadState.progress = progress;
}); });
cache.writeQuery({ query: getCorpusesQuery, data, variables: { projectPath } }); cache.writeQuery({ query: getUploadState, data, variables: { projectPath } });
}, },
resetCorpus: (_, { projectPath }, { cache }) => { resetCorpus: (_, { projectPath }, { cache }) => {
const sourceData = cache.readQuery({ const sourceData = cache.readQuery({
query: getCorpusesQuery, query: getUploadState,
variables: { projectPath }, variables: { projectPath },
}); });
...@@ -131,7 +130,7 @@ export default { ...@@ -131,7 +130,7 @@ export default {
uploadState.cancelToken = null; uploadState.cancelToken = null;
}); });
cache.writeQuery({ query: getCorpusesQuery, data, variables: { projectPath } }); cache.writeQuery({ query: getUploadState, data, variables: { projectPath } });
}, },
}, },
}; };
import { GlLoadingIcon } from '@gitlab/ui'; import { merge } from 'lodash';
import { GlLoadingIcon, GlKeysetPagination } from '@gitlab/ui';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import CorpusManagement from 'ee/security_configuration/corpus_management/components/corpus_management.vue'; import CorpusManagement from 'ee/security_configuration/corpus_management/components/corpus_management.vue';
import CorpusTable from 'ee/security_configuration/corpus_management/components/corpus_table.vue'; import CorpusTable from 'ee/security_configuration/corpus_management/components/corpus_table.vue';
import CorpusUpload from 'ee/security_configuration/corpus_management/components/corpus_upload.vue'; import CorpusUpload from 'ee/security_configuration/corpus_management/components/corpus_upload.vue';
import { corpuses } from './mock_data'; import getCorpusesQuery from 'ee/security_configuration/corpus_management/graphql/queries/get_corpuses.query.graphql';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { getCorpusesQueryResponse } from './mock_data';
const TEST_PROJECT_FULL_PATH = '/namespace/project'; const TEST_PROJECT_FULL_PATH = '/namespace/project';
const TEST_CORPUS_HELP_PATH = '/docs/corpus-management'; const TEST_CORPUS_HELP_PATH = '/docs/corpus-management';
...@@ -11,19 +20,49 @@ const TEST_CORPUS_HELP_PATH = '/docs/corpus-management'; ...@@ -11,19 +20,49 @@ const TEST_CORPUS_HELP_PATH = '/docs/corpus-management';
describe('EE - CorpusManagement', () => { describe('EE - CorpusManagement', () => {
let wrapper; let wrapper;
const createComponentFactory = (mountFn = shallowMount) => (options = {}) => { const createMockApolloProvider = ({
const defaultMocks = { getCorpusesQueryRequestHandler = jest.fn().mockResolvedValue(getCorpusesQueryResponse),
$apollo: { } = {}) => {
loading: false, Vue.use(VueApollo);
const requestHandlers = [[getCorpusesQuery, getCorpusesQueryRequestHandler]];
const mockResolvers = {
Query: {
uploadState() {
return {
isUploading: false,
progress: 0,
cancelSource: null,
uploadedPackageId: null,
__typename: 'UploadState',
};
}, },
},
};
return createMockApollo(requestHandlers, mockResolvers);
};
const findPagination = () => wrapper.findComponent(GlKeysetPagination);
const nextPage = (cursor) => {
findPagination().vm.$emit('next', cursor);
return findPagination().vm.$nextTick();
}; };
const prevPage = (cursor) => {
findPagination().vm.$emit('prev', cursor);
return findPagination().vm.$nextTick();
};
const createComponentFactory = (mountFn = shallowMount) => (options = {}) => {
wrapper = mountFn(CorpusManagement, { wrapper = mountFn(CorpusManagement, {
mocks: defaultMocks,
provide: { provide: {
projectFullPath: TEST_PROJECT_FULL_PATH, projectFullPath: TEST_PROJECT_FULL_PATH,
corpusHelpPath: TEST_CORPUS_HELP_PATH, corpusHelpPath: TEST_CORPUS_HELP_PATH,
}, },
apolloProvider: createMockApolloProvider(),
...options, ...options,
}); });
}; };
...@@ -36,39 +75,119 @@ describe('EE - CorpusManagement', () => { ...@@ -36,39 +75,119 @@ describe('EE - CorpusManagement', () => {
describe('corpus management', () => { describe('corpus management', () => {
describe('when loaded', () => { describe('when loaded', () => {
beforeEach(() => { it('bootstraps and renders the component', async () => {
const data = () => { createComponent();
return { states: { project: { corpuses } } }; await waitForPromises();
};
createComponent({ data });
});
it('bootstraps and renders the component', () => {
expect(wrapper.findComponent(CorpusManagement).exists()).toBe(true); expect(wrapper.findComponent(CorpusManagement).exists()).toBe(true);
expect(wrapper.findComponent(CorpusTable).exists()).toBe(true); expect(wrapper.findComponent(CorpusTable).exists()).toBe(true);
expect(wrapper.findComponent(CorpusUpload).exists()).toBe(true); expect(wrapper.findComponent(CorpusUpload).exists()).toBe(true);
expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(false); expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(false);
}); });
it('renders the correct header', () => { it('renders the correct header', async () => {
createComponent();
await waitForPromises();
const header = wrapper.findComponent(CorpusManagement).find('header'); const header = wrapper.findComponent(CorpusManagement).find('header');
expect(header.element).toMatchSnapshot(); expect(header.element).toMatchSnapshot();
}); });
describe('pagination', () => {
it('hides pagination when no previous or next pages are available', async () => {
createComponent({
apolloProvider: createMockApolloProvider({
getCorpusesQueryRequestHandler: jest.fn().mockResolvedValue(
merge({}, getCorpusesQueryResponse, {
data: {
project: {
corpuses: {
pageInfo: {
hasNextPage: false,
hasPreviousPage: false,
},
},
},
},
}),
),
}),
});
await waitForPromises();
expect(findPagination().exists()).toBe(false);
});
it('passes correct props to GlKeysetPagination', async () => {
createComponent();
await waitForPromises();
expect(findPagination().exists()).toBe(true);
expect(findPagination().props()).toMatchObject({
disabled: false,
endCursor: 'end-cursor',
hasNextPage: true,
hasPreviousPage: true,
nextButtonLink: null,
nextText: 'Next',
prevButtonLink: null,
prevText: 'Prev',
startCursor: 'start-cursor',
});
});
it('updates query variables when going to previous page', async () => {
const getCorpusesQueryRequestHandler = jest
.fn()
.mockResolvedValue(getCorpusesQueryResponse);
createComponent({
apolloProvider: createMockApolloProvider({ getCorpusesQueryRequestHandler }),
});
await waitForPromises();
await prevPage(getCorpusesQueryResponse.data.project.corpuses.pageInfo.startCursor);
expect(getCorpusesQueryRequestHandler).toHaveBeenCalledWith({
beforeCursor: getCorpusesQueryResponse.data.project.corpuses.pageInfo.startCursor,
afterCursor: '',
projectPath: TEST_PROJECT_FULL_PATH,
lastPageSize: 10,
firstPageSize: null,
});
});
it('updates query variables when going to next page', async () => {
const getCorpusesQueryRequestHandler = jest
.fn()
.mockResolvedValue(getCorpusesQueryResponse);
createComponent({
apolloProvider: createMockApolloProvider({ getCorpusesQueryRequestHandler }),
});
await waitForPromises();
await nextPage(getCorpusesQueryResponse.data.project.corpuses.pageInfo.endCursor);
expect(getCorpusesQueryRequestHandler).toHaveBeenLastCalledWith({
afterCursor: getCorpusesQueryResponse.data.project.corpuses.pageInfo.endCursor,
beforeCursor: '',
projectPath: TEST_PROJECT_FULL_PATH,
firstPageSize: 10,
lastPageSize: null,
});
});
});
}); });
describe('when loading', () => { describe('when loading', () => {
it('shows loading state when loading', () => { it('shows loading state when loading', () => {
const mocks = { createComponent();
$apollo: {
loading: jest.fn().mockResolvedValue(true),
},
};
createComponent({ mocks });
expect(wrapper.findComponent(CorpusManagement).exists()).toBe(true); expect(wrapper.findComponent(CorpusManagement).exists()).toBe(true);
expect(wrapper.findComponent(CorpusUpload).exists()).toBe(true);
expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(true); expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(true);
expect(wrapper.findComponent(CorpusTable).exists()).toBe(false); expect(wrapper.findComponent(CorpusTable).exists()).toBe(false);
expect(wrapper.findComponent(CorpusUpload).exists()).toBe(false);
}); });
}); });
}); });
......
...@@ -60,5 +60,13 @@ describe('Corpus table', () => { ...@@ -60,5 +60,13 @@ describe('Corpus table', () => {
actionComponent.vm.$emit('delete', 'corpus-name'); actionComponent.vm.$emit('delete', 'corpus-name');
expect(mutate).toHaveBeenCalledTimes(1); expect(mutate).toHaveBeenCalledTimes(1);
}); });
describe('with no corpuses', () => {
it('renders the empty state', async () => {
wrapper.setProps({ corpuses: [] });
await wrapper.vm.$nextTick();
expect(wrapper.text()).toContain('Currently, there are no uploaded or generated corpuses');
});
});
}); });
}); });
const pipelines = { const pipelines = {
nodes: [ nodes: [
{ {
id: 'gid://gitlab/Packages::PackagePipelines/1',
ref: 'farias-gl/go-fuzzing-example', ref: 'farias-gl/go-fuzzing-example',
path: 'gitlab-examples/security/security-reports/-/jobs/1107103952', path: 'gitlab-examples/security/security-reports/-/jobs/1107103952',
updatedAt: new Date(2020, 4, 3).toString(), createdAt: new Date(2020, 4, 3).toString(),
}, },
], ],
}; };
...@@ -11,6 +12,7 @@ const pipelines = { ...@@ -11,6 +12,7 @@ const pipelines = {
const packageFiles = { const packageFiles = {
nodes: [ nodes: [
{ {
id: 'gid://gitlab/Packages::PackageFile/1',
downloadPath: '/download-path', downloadPath: '/download-path',
size: 4e8, size: 4e8,
}, },
...@@ -19,7 +21,9 @@ const packageFiles = { ...@@ -19,7 +21,9 @@ const packageFiles = {
export const corpuses = [ export const corpuses = [
{ {
id: 'gid://gitlab/AppSec::Fuzzing::Coverage::Corpus/1',
package: { package: {
id: 'gid://gitlab/Packages::Package/1',
name: 'Corpus-sample-1-13830-23932', name: 'Corpus-sample-1-13830-23932',
updatedAt: new Date(2021, 2, 12).toString(), updatedAt: new Date(2021, 2, 12).toString(),
pipelines, pipelines,
...@@ -27,7 +31,9 @@ export const corpuses = [ ...@@ -27,7 +31,9 @@ export const corpuses = [
}, },
}, },
{ {
id: 'gid://gitlab/AppSec::Fuzzing::Coverage::Corpus/2',
package: { package: {
id: 'gid://gitlab/Packages::Package/2',
name: 'Corpus-sample-2-5830-2393', name: 'Corpus-sample-2-5830-2393',
updatedAt: new Date(2021, 3, 12).toString(), updatedAt: new Date(2021, 3, 12).toString(),
pipelines, pipelines,
...@@ -35,7 +41,9 @@ export const corpuses = [ ...@@ -35,7 +41,9 @@ export const corpuses = [
}, },
}, },
{ {
id: 'gid://gitlab/AppSec::Fuzzing::Coverage::Corpus/3',
package: { package: {
id: 'gid://gitlab/Packages::Package/3',
name: 'Corpus-sample-3-1431-4425', name: 'Corpus-sample-3-1431-4425',
updatedAt: new Date(2021, 4, 12).toString(), updatedAt: new Date(2021, 4, 12).toString(),
pipelines: { pipelines: {
...@@ -49,6 +57,7 @@ export const corpuses = [ ...@@ -49,6 +57,7 @@ export const corpuses = [
packageFiles: { packageFiles: {
nodes: [ nodes: [
{ {
id: 'gid://gitlab/Packages::PackageFile/1',
downloadPath: '/download-path', downloadPath: '/download-path',
size: 3.21e8, size: 3.21e8,
}, },
...@@ -57,7 +66,9 @@ export const corpuses = [ ...@@ -57,7 +66,9 @@ export const corpuses = [
}, },
}, },
{ {
id: 'gid://gitlab/AppSec::Fuzzing::Coverage::Corpus/4',
package: { package: {
id: 'gid://gitlab/Packages::Package/3',
name: 'Corpus-sample-4-5830-1393', name: 'Corpus-sample-4-5830-1393',
updatedAt: new Date(2021, 5, 12).toString(), updatedAt: new Date(2021, 5, 12).toString(),
pipelines, pipelines,
...@@ -65,7 +76,9 @@ export const corpuses = [ ...@@ -65,7 +76,9 @@ export const corpuses = [
}, },
}, },
{ {
id: 'gid://gitlab/AppSec::Fuzzing::Coverage::Corpus/5',
package: { package: {
id: 'gid://gitlab/Packages::Package/4',
name: 'Corpus-sample-5-13830-23932', name: 'Corpus-sample-5-13830-23932',
updatedAt: new Date(2021, 6, 12).toString(), updatedAt: new Date(2021, 6, 12).toString(),
pipelines, pipelines,
...@@ -73,7 +86,9 @@ export const corpuses = [ ...@@ -73,7 +86,9 @@ export const corpuses = [
}, },
}, },
{ {
id: 'gid://gitlab/AppSec::Fuzzing::Coverage::Corpus/6',
package: { package: {
id: 'gid://gitlab/Packages::Package/5',
name: 'Corpus-sample-6-2450-2393', name: 'Corpus-sample-6-2450-2393',
updatedAt: new Date(2021, 7, 12).toString(), updatedAt: new Date(2021, 7, 12).toString(),
pipelines, pipelines,
...@@ -81,3 +96,20 @@ export const corpuses = [ ...@@ -81,3 +96,20 @@ export const corpuses = [
}, },
}, },
]; ];
export const getCorpusesQueryResponse = {
data: {
project: {
id: 'gid://gitlab/Project/8',
corpuses: {
nodes: corpuses,
pageInfo: {
hasNextPage: true,
hasPreviousPage: true,
startCursor: 'start-cursor',
endCursor: 'end-cursor',
},
},
},
},
};
...@@ -9763,6 +9763,9 @@ msgstr "" ...@@ -9763,6 +9763,9 @@ msgstr ""
msgid "CorpusManagement|Corpus name" msgid "CorpusManagement|Corpus name"
msgstr "" msgstr ""
msgid "CorpusManagement|Currently, there are no uploaded or generated corpuses."
msgstr ""
msgid "CorpusManagement|Fuzz testing corpus management" msgid "CorpusManagement|Fuzz testing corpus management"
msgstr "" msgstr ""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment