Merge branch '30195-document-search-param-on-api' into 'master'

Add "search" optional param and docs for V4

Closes #30195

See merge request !10358
This commit is contained in:
Sean McGivern 2017-04-05 21:49:06 +00:00
commit 50a0fd03ad
4 changed files with 231 additions and 292 deletions

View File

@ -0,0 +1,4 @@
---
title: Add search optional param and docs for V4
merge_request:
author:

View File

@ -26,16 +26,20 @@ GET /issues?labels=foo,bar&state=opened
GET /issues?milestone=1.0.0 GET /issues?milestone=1.0.0
GET /issues?milestone=1.0.0&state=opened GET /issues?milestone=1.0.0&state=opened
GET /issues?iids[]=42&iids[]=43 GET /issues?iids[]=42&iids[]=43
GET /issues?search=issue+title+or+description
``` ```
| Attribute | Type | Required | Description | |-------------+----------------+----------+-----------------------------------------------------------------------------------------------------------------------------|
| --------- | ---- | -------- | ----------- | | Attribute | Type | Required | Description |
| `state` | string | no | Return all issues or just those that are `opened` or `closed`| |-------------+----------------+----------+-----------------------------------------------------------------------------------------------------------------------------|
| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `No+Label` lists all issues with no labels | | `state` | string | no | Return all issues or just those that are `opened` or `closed` |
| `milestone` | string| no | The milestone title | | `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `No+Label` lists all issues with no labels |
| `iids` | Array[integer] | no | Return only the issues having the given `iid` | | `milestone` | string | no | The milestone title |
| `order_by`| string | no | Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at` | | `iids` | Array[integer] | no | Return only the issues having the given `iid` |
| `sort` | string | no | Return requests sorted in `asc` or `desc` order. Default is `desc` | | `order_by` | string | no | Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at` |
| `sort` | string | no | Return requests sorted in `asc` or `desc` order. Default is `desc` |
| `search` | string | no | Search issues against their `title` and `description` |
|-------------+----------------+----------+-----------------------------------------------------------------------------------------------------------------------------|
```bash ```bash
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/issues curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/issues
@ -104,17 +108,21 @@ GET /groups/:id/issues?labels=foo,bar&state=opened
GET /groups/:id/issues?milestone=1.0.0 GET /groups/:id/issues?milestone=1.0.0
GET /groups/:id/issues?milestone=1.0.0&state=opened GET /groups/:id/issues?milestone=1.0.0&state=opened
GET /groups/:id/issues?iids[]=42&iids[]=43 GET /groups/:id/issues?iids[]=42&iids[]=43
GET /groups/:id/issues?search=issue+title+or+description
``` ```
| Attribute | Type | Required | Description | |-------------+----------------+----------+-----------------------------------------------------------------------------------------------------------------------------|
| --------- | ---- | -------- | ----------- | | Attribute | Type | Required | Description |
| `id` | integer | yes | The ID of a group | |-------------+----------------+----------+-----------------------------------------------------------------------------------------------------------------------------|
| `state` | string | no | Return all issues or just those that are `opened` or `closed`| | `id` | integer | yes | The ID of a group |
| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `No+Label` lists all issues with no labels | | `state` | string | no | Return all issues or just those that are `opened` or `closed` |
| `iids` | Array[integer] | no | Return only the issues having the given `iid` | | `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `No+Label` lists all issues with no labels |
| `milestone` | string| no | The milestone title | | `iids` | Array[integer] | no | Return only the issues having the given `iid` |
| `order_by`| string | no | Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at` | | `milestone` | string | no | The milestone title |
| `sort` | string | no | Return requests sorted in `asc` or `desc` order. Default is `desc` | | `order_by` | string | no | Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at` |
| `sort` | string | no | Return requests sorted in `asc` or `desc` order. Default is `desc` |
| `search` | string | no | Search group issues against their `title` and `description` |
|-------------+----------------+----------+-----------------------------------------------------------------------------------------------------------------------------|
```bash ```bash
@ -184,17 +192,21 @@ GET /projects/:id/issues?labels=foo,bar&state=opened
GET /projects/:id/issues?milestone=1.0.0 GET /projects/:id/issues?milestone=1.0.0
GET /projects/:id/issues?milestone=1.0.0&state=opened GET /projects/:id/issues?milestone=1.0.0&state=opened
GET /projects/:id/issues?iids[]=42&iids[]=43 GET /projects/:id/issues?iids[]=42&iids[]=43
GET /projects/:id/issues?search=issue+title+or+description
``` ```
| Attribute | Type | Required | Description | |-------------+----------------+----------+-----------------------------------------------------------------------------------------------------------------------------|
| --------- | ---- | -------- | ----------- | | Attribute | Type | Required | Description |
| `id` | integer | yes | The ID of a project | |-------------+----------------+----------+-----------------------------------------------------------------------------------------------------------------------------|
| `iids` | Array[integer] | no | Return only the milestone having the given `iid` | | `id` | integer | yes | The ID of a project |
| `state` | string | no | Return all issues or just those that are `opened` or `closed`| | `iids` | Array[integer] | no | Return only the milestone having the given `iid` |
| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `No+Label` lists all issues with no labels | | `state` | string | no | Return all issues or just those that are `opened` or `closed` |
| `milestone` | string| no | The milestone title | | `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `No+Label` lists all issues with no labels |
| `order_by`| string | no | Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at` | | `milestone` | string | no | The milestone title |
| `sort` | string | no | Return requests sorted in `asc` or `desc` order. Default is `desc` | | `order_by` | string | no | Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at` |
| `sort` | string | no | Return requests sorted in `asc` or `desc` order. Default is `desc` |
| `search` | string | no | Search project issues against their `title` and `description` |
|-------------+----------------+----------+-----------------------------------------------------------------------------------------------------------------------------|
```bash ```bash
@ -258,10 +270,12 @@ Get a single project issue.
GET /projects/:id/issues/:issue_iid GET /projects/:id/issues/:issue_iid
``` ```
|-------------+---------+----------+--------------------------------------|
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | |-------------+---------+----------+--------------------------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer | yes | The ID of a project |
| `issue_iid` | integer | yes | The internal ID of a project's issue | | `issue_iid` | integer | yes | The internal ID of a project's issue |
|-------------+---------+----------+--------------------------------------|
```bash ```bash
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/4/issues/41 curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/4/issues/41
@ -323,19 +337,23 @@ Creates a new project issue.
POST /projects/:id/issues POST /projects/:id/issues
``` ```
| Attribute | Type | Required | Description | |-------------------------------------------+---------+----------+------------------------------------------------------------------------------------------------------------------------------------------------------|
| --------- | ---- | -------- | ----------- | | Attribute | Type | Required | Description |
| `id` | integer | yes | The ID of a project | |-------------------------------------------+---------+----------+------------------------------------------------------------------------------------------------------------------------------------------------------|
| `title` | string | yes | The title of an issue | | `id` | integer | yes | The ID of a project |
| `description` | string | no | The description of an issue | | `title` | string | yes | The title of an issue |
| `confidential` | boolean | no | Set an issue to be confidential. Default is `false`. | | `description` | string | no | The description of an issue |
| `assignee_id` | integer | no | The ID of a user to assign issue | | `confidential` | boolean | no | Set an issue to be confidential. Default is `false`. |
| `milestone_id` | integer | no | The ID of a milestone to assign issue | | `assignee_id` | integer | no | The ID of a user to assign issue |
| `labels` | string | no | Comma-separated label names for an issue | | `milestone_id` | integer | no | The ID of a milestone to assign issue |
| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. `2016-03-11T03:45:40Z` (requires admin or project owner rights) | | `labels` | string | no | Comma-separated label names for an issue |
| `due_date` | string | no | Date time string in the format YEAR-MONTH-DAY, e.g. `2016-03-11` | | `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. `2016-03-11T03:45:40Z` (requires admin or project owner rights) |
| `merge_request_to_resolve_discussions_of` | integer | no | The IID of a merge request in which to resolve all issues. This will fill the issue with a default description and mark all discussions as resolved. When passing a description or title, these values will take precedence over the default values. | | `due_date` | string | no | Date time string in the format YEAR-MONTH-DAY, e.g. `2016-03-11` |
| `discussion_to_resolve` | string | no | The ID of a discussion to resolve. This will fill in the issue with a default description and mark the discussion as resolved. Use in combination with `merge_request_to_resolve_discussions_of`. | | `merge_request_to_resolve_discussions_of` | integer | no | The IID of a merge request in which to resolve all issues. This will fill the issue with a default description and mark all discussions as resolved. |
| - | - | - | When passing a description or title, these values will take precedence over the default values. |
| `discussion_to_resolve` | string | no | The ID of a discussion to resolve. This will fill in the issue with a default description and mark the discussion |
| - | - | - | as resolved. Use in combination with `merge_request_to_resolve_discussions_of`. |
|-------------------------------------------+---------+----------+------------------------------------------------------------------------------------------------------------------------------------------------------|
```bash ```bash
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/4/issues?title=Issues%20with%20auth&labels=bug curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/4/issues?title=Issues%20with%20auth&labels=bug
@ -383,8 +401,9 @@ closed.
PUT /projects/:id/issues/:issue_iid PUT /projects/:id/issues/:issue_iid
``` ```
|----------------+---------+----------+------------------------------------------------------------------------------------------------------------|
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | |----------------+---------+----------+------------------------------------------------------------------------------------------------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer | yes | The ID of a project |
| `issue_iid` | integer | yes | The internal ID of a project's issue | | `issue_iid` | integer | yes | The internal ID of a project's issue |
| `title` | string | no | The title of an issue | | `title` | string | no | The title of an issue |
@ -396,6 +415,7 @@ PUT /projects/:id/issues/:issue_iid
| `state_event` | string | no | The state event of an issue. Set `close` to close the issue and `reopen` to reopen it | | `state_event` | string | no | The state event of an issue. Set `close` to close the issue and `reopen` to reopen it |
| `updated_at` | string | no | Date time string, ISO 8601 formatted, e.g. `2016-03-11T03:45:40Z` (requires admin or project owner rights) | | `updated_at` | string | no | Date time string, ISO 8601 formatted, e.g. `2016-03-11T03:45:40Z` (requires admin or project owner rights) |
| `due_date` | string | no | Date time string in the format YEAR-MONTH-DAY, e.g. `2016-03-11` | | `due_date` | string | no | Date time string in the format YEAR-MONTH-DAY, e.g. `2016-03-11` |
|----------------+---------+----------+------------------------------------------------------------------------------------------------------------|
```bash ```bash
curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/4/issues/85?state_event=close curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/4/issues/85?state_event=close
@ -442,10 +462,12 @@ Only for admins and project owners. Soft deletes the issue in question.
DELETE /projects/:id/issues/:issue_iid DELETE /projects/:id/issues/:issue_iid
``` ```
|-------------+---------+----------+--------------------------------------|
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | |-------------+---------+----------+--------------------------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer | yes | The ID of a project |
| `issue_iid` | integer | yes | The internal ID of a project's issue | | `issue_iid` | integer | yes | The internal ID of a project's issue |
|-------------+---------+----------+--------------------------------------|
```bash ```bash
curl --request DELETE --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/4/issues/85 curl --request DELETE --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/4/issues/85
@ -464,11 +486,13 @@ project, it will then be assigned to the issue that is being moved.
POST /projects/:id/issues/:issue_iid/move POST /projects/:id/issues/:issue_iid/move
``` ```
|-----------------+---------+----------+--------------------------------------|
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | |-----------------+---------+----------+--------------------------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer | yes | The ID of a project |
| `issue_iid` | integer | yes | The internal ID of a project's issue | | `issue_iid` | integer | yes | The internal ID of a project's issue |
| `to_project_id` | integer | yes | The ID of the new project | | `to_project_id` | integer | yes | The ID of the new project |
|-----------------+---------+----------+--------------------------------------|
```bash ```bash
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/4/issues/85/move curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/4/issues/85/move
@ -520,10 +544,12 @@ is returned.
POST /projects/:id/issues/:issue_iid/subscribe POST /projects/:id/issues/:issue_iid/subscribe
``` ```
|-------------+---------+----------+--------------------------------------|
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | |-------------+---------+----------+--------------------------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer | yes | The ID of a project |
| `issue_iid` | integer | yes | The internal ID of a project's issue | | `issue_iid` | integer | yes | The internal ID of a project's issue |
|-------------+---------+----------+--------------------------------------|
```bash ```bash
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/issues/93/subscribe curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/issues/93/subscribe
@ -575,10 +601,12 @@ status code `304` is returned.
POST /projects/:id/issues/:issue_iid/unsubscribe POST /projects/:id/issues/:issue_iid/unsubscribe
``` ```
|-------------+---------+----------+--------------------------------------|
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | |-------------+---------+----------+--------------------------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer | yes | The ID of a project |
| `issue_iid` | integer | yes | The internal ID of a project's issue | | `issue_iid` | integer | yes | The internal ID of a project's issue |
|-------------+---------+----------+--------------------------------------|
```bash ```bash
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/issues/93/unsubscribe curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/issues/93/unsubscribe
@ -594,10 +622,12 @@ returned.
POST /projects/:id/issues/:issue_iid/todo POST /projects/:id/issues/:issue_iid/todo
``` ```
|-------------+---------+----------+--------------------------------------|
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | |-------------+---------+----------+--------------------------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer | yes | The ID of a project |
| `issue_iid` | integer | yes | The internal ID of a project's issue | | `issue_iid` | integer | yes | The internal ID of a project's issue |
|-------------+---------+----------+--------------------------------------|
```bash ```bash
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/issues/93/todo curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/issues/93/todo
@ -685,11 +715,13 @@ Sets an estimated time of work for this issue.
POST /projects/:id/issues/:issue_iid/time_estimate POST /projects/:id/issues/:issue_iid/time_estimate
``` ```
|-------------+---------+----------+------------------------------------------|
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | |-------------+---------+----------+------------------------------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer | yes | The ID of a project |
| `issue_iid` | integer | yes | The internal ID of a project's issue | | `issue_iid` | integer | yes | The internal ID of a project's issue |
| `duration` | string | yes | The duration in human format. e.g: 3h30m | | `duration` | string | yes | The duration in human format. e.g: 3h30m |
|-------------+---------+----------+------------------------------------------|
```bash ```bash
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/issues/93/time_estimate?duration=3h30m curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/issues/93/time_estimate?duration=3h30m
@ -714,10 +746,12 @@ Resets the estimated time for this issue to 0 seconds.
POST /projects/:id/issues/:issue_iid/reset_time_estimate POST /projects/:id/issues/:issue_iid/reset_time_estimate
``` ```
|-------------+---------+----------+--------------------------------------|
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | |-------------+---------+----------+--------------------------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer | yes | The ID of a project |
| `issue_iid` | integer | yes | The internal ID of a project's issue | | `issue_iid` | integer | yes | The internal ID of a project's issue |
|-------------+---------+----------+--------------------------------------|
```bash ```bash
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/issues/93/reset_time_estimate curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/issues/93/reset_time_estimate
@ -742,11 +776,13 @@ Adds spent time for this issue
POST /projects/:id/issues/:issue_iid/add_spent_time POST /projects/:id/issues/:issue_iid/add_spent_time
``` ```
|-------------+---------+----------+------------------------------------------|
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | |-------------+---------+----------+------------------------------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer | yes | The ID of a project |
| `issue_iid` | integer | yes | The internal ID of a project's issue | | `issue_iid` | integer | yes | The internal ID of a project's issue |
| `duration` | string | yes | The duration in human format. e.g: 3h30m | | `duration` | string | yes | The duration in human format. e.g: 3h30m |
|-------------+---------+----------+------------------------------------------|
```bash ```bash
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/issues/93/add_spent_time?duration=1h curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/issues/93/add_spent_time?duration=1h
@ -771,10 +807,12 @@ Resets the total spent time for this issue to 0 seconds.
POST /projects/:id/issues/:issue_iid/reset_spent_time POST /projects/:id/issues/:issue_iid/reset_spent_time
``` ```
|-------------+---------+----------+--------------------------------------|
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | |-------------+---------+----------+--------------------------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer | yes | The ID of a project |
| `issue_iid` | integer | yes | The internal ID of a project's issue | | `issue_iid` | integer | yes | The internal ID of a project's issue |
|-------------+---------+----------+--------------------------------------|
```bash ```bash
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/issues/93/reset_spent_time curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/issues/93/reset_spent_time
@ -797,10 +835,12 @@ Example response:
GET /projects/:id/issues/:issue_iid/time_stats GET /projects/:id/issues/:issue_iid/time_stats
``` ```
|-------------+---------+----------+--------------------------------------|
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | |-------------+---------+----------+--------------------------------------|
| `id` | integer | yes | The ID of a project | | `id` | integer | yes | The ID of a project |
| `issue_iid` | integer | yes | The internal ID of a project's issue | | `issue_iid` | integer | yes | The internal ID of a project's issue |
|-------------+---------+----------+--------------------------------------|
```bash ```bash
curl --request GET --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/issues/93/time_stats curl --request GET --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/issues/93/time_stats

View File

@ -26,6 +26,7 @@ module API
desc: 'Return issues sorted in `asc` or `desc` order.' desc: 'Return issues sorted in `asc` or `desc` order.'
optional :milestone, type: String, desc: 'Return issues for a specific milestone' optional :milestone, type: String, desc: 'Return issues for a specific milestone'
optional :iids, type: Array[Integer], desc: 'The IID array of issues' optional :iids, type: Array[Integer], desc: 'The IID array of issues'
optional :search, type: String, desc: 'Search issues for text present in the title or description'
use :pagination use :pagination
end end

View File

@ -12,6 +12,8 @@ describe API::Issues, api: true do
let(:assignee) { create(:assignee) } let(:assignee) { create(:assignee) }
let(:admin) { create(:user, :admin) } let(:admin) { create(:user, :admin) }
let!(:project) { create(:empty_project, :public, creator_id: user.id, namespace: user.namespace ) } let!(:project) { create(:empty_project, :public, creator_id: user.id, namespace: user.namespace ) }
let(:issue_title) { 'foo' }
let(:issue_description) { 'closed' }
let!(:closed_issue) do let!(:closed_issue) do
create :closed_issue, create :closed_issue,
author: user, author: user,
@ -38,7 +40,9 @@ describe API::Issues, api: true do
project: project, project: project,
milestone: milestone, milestone: milestone,
created_at: generate(:past_time), created_at: generate(:past_time),
updated_at: 1.hour.ago updated_at: 1.hour.ago,
title: issue_title,
description: issue_description
end end
let!(:label) do let!(:label) do
create(:label, title: 'label', color: '#FFAABB', project: project) create(:label, title: 'label', color: '#FFAABB', project: project)
@ -61,6 +65,7 @@ describe API::Issues, api: true do
context "when unauthenticated" do context "when unauthenticated" do
it "returns authentication error" do it "returns authentication error" do
get api("/issues") get api("/issues")
expect(response).to have_http_status(401) expect(response).to have_http_status(401)
end end
end end
@ -69,9 +74,7 @@ describe API::Issues, api: true do
it "returns an array of issues" do it "returns an array of issues" do
get api("/issues", user) get api("/issues", user)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 2)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first['title']).to eq(issue.title) expect(json_response.first['title']).to eq(issue.title)
expect(json_response.last).to have_key('web_url') expect(json_response.last).to have_key('web_url')
end end
@ -79,41 +82,43 @@ describe API::Issues, api: true do
it 'returns an array of closed issues' do it 'returns an array of closed issues' do
get api('/issues?state=closed', user) get api('/issues?state=closed', user)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 1)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(closed_issue.id) expect(json_response.first['id']).to eq(closed_issue.id)
end end
it 'returns an array of opened issues' do it 'returns an array of opened issues' do
get api('/issues?state=opened', user) get api('/issues?state=opened', user)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 1)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(issue.id) expect(json_response.first['id']).to eq(issue.id)
end end
it 'returns an array of all issues' do it 'returns an array of all issues' do
get api('/issues?state=all', user) get api('/issues?state=all', user)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 2)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
expect(json_response.first['id']).to eq(issue.id) expect(json_response.first['id']).to eq(issue.id)
expect(json_response.second['id']).to eq(closed_issue.id) expect(json_response.second['id']).to eq(closed_issue.id)
end end
it 'returns issues matching given search string for title' do
get api("/issues?search=#{issue.title}", user)
expect_paginated_array_response(size: 1)
expect(json_response.first['id']).to eq(issue.id)
end
it 'returns issues matching given search string for description' do
get api("/issues?search=#{issue.description}", user)
expect_paginated_array_response(size: 1)
expect(json_response.first['id']).to eq(issue.id)
end
it 'returns an array of labeled issues' do it 'returns an array of labeled issues' do
get api("/issues?labels=#{label.title}", user) get api("/issues?labels=#{label.title}", user)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 1)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['labels']).to eq([label.title]) expect(json_response.first['labels']).to eq([label.title])
end end
@ -126,29 +131,20 @@ describe API::Issues, api: true do
get api("/issues", user), labels: "#{label.title},#{label_b.title},#{label_c.title}" get api("/issues", user), labels: "#{label.title},#{label_b.title},#{label_c.title}"
expect(response).to have_http_status(200) expect_paginated_array_response(size: 1)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['labels']).to eq([label_c.title, label_b.title, label.title]) expect(json_response.first['labels']).to eq([label_c.title, label_b.title, label.title])
end end
it 'returns an empty array if no issue matches labels' do it 'returns an empty array if no issue matches labels' do
get api('/issues?labels=foo,bar', user) get api('/issues?labels=foo,bar', user)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 0)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(0)
end end
it 'returns an array of labeled issues matching given state' do it 'returns an array of labeled issues matching given state' do
get api("/issues?labels=#{label.title}&state=opened", user) get api("/issues?labels=#{label.title}&state=opened", user)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 1)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['labels']).to eq([label.title]) expect(json_response.first['labels']).to eq([label.title])
expect(json_response.first['state']).to eq('opened') expect(json_response.first['state']).to eq('opened')
end end
@ -156,47 +152,32 @@ describe API::Issues, api: true do
it 'returns unlabeled issues for "No Label" label' do it 'returns unlabeled issues for "No Label" label' do
get api("/issues", user), labels: 'No Label' get api("/issues", user), labels: 'No Label'
expect(response).to have_http_status(200) expect_paginated_array_response(size: 1)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['labels']).to be_empty expect(json_response.first['labels']).to be_empty
end end
it 'returns an empty array if no issue matches labels and state filters' do it 'returns an empty array if no issue matches labels and state filters' do
get api("/issues?labels=#{label.title}&state=closed", user) get api("/issues?labels=#{label.title}&state=closed", user)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 0)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(0)
end end
it 'returns an empty array if no issue matches milestone' do it 'returns an empty array if no issue matches milestone' do
get api("/issues?milestone=#{empty_milestone.title}", user) get api("/issues?milestone=#{empty_milestone.title}", user)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 0)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(0)
end end
it 'returns an empty array if milestone does not exist' do it 'returns an empty array if milestone does not exist' do
get api("/issues?milestone=foo", user) get api("/issues?milestone=foo", user)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 0)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(0)
end end
it 'returns an array of issues in given milestone' do it 'returns an array of issues in given milestone' do
get api("/issues?milestone=#{milestone.title}", user) get api("/issues?milestone=#{milestone.title}", user)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 2)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
expect(json_response.first['id']).to eq(issue.id) expect(json_response.first['id']).to eq(issue.id)
expect(json_response.second['id']).to eq(closed_issue.id) expect(json_response.second['id']).to eq(closed_issue.id)
end end
@ -205,49 +186,36 @@ describe API::Issues, api: true do
get api("/issues?milestone=#{milestone.title}"\ get api("/issues?milestone=#{milestone.title}"\
'&state=closed', user) '&state=closed', user)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 1)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(closed_issue.id) expect(json_response.first['id']).to eq(closed_issue.id)
end end
it 'returns an array of issues with no milestone' do it 'returns an array of issues with no milestone' do
get api("/issues?milestone=#{no_milestone_title}", author) get api("/issues?milestone=#{no_milestone_title}", author)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 1)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(confidential_issue.id) expect(json_response.first['id']).to eq(confidential_issue.id)
end end
it 'returns an array of issues found by iids' do it 'returns an array of issues found by iids' do
get api('/issues', user), iids: [closed_issue.iid] get api('/issues', user), iids: [closed_issue.iid]
expect(response).to have_http_status(200) expect_paginated_array_response(size: 1)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(closed_issue.id) expect(json_response.first['id']).to eq(closed_issue.id)
end end
it 'returns an empty array if iid does not exist' do it 'returns an empty array if iid does not exist' do
get api("/issues", user), iids: [99999] get api("/issues", user), iids: [99999]
expect(response).to have_http_status(200) expect_paginated_array_response(size: 0)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(0)
end end
it 'sorts by created_at descending by default' do it 'sorts by created_at descending by default' do
get api('/issues', user) get api('/issues', user)
response_dates = json_response.map { |issue| issue['created_at'] } response_dates = json_response.map { |issue| issue['created_at'] }
expect(response).to have_http_status(200)
expect(response).to include_pagination_headers expect_paginated_array_response(size: 2)
expect(json_response).to be_an Array
expect(response_dates).to eq(response_dates.sort.reverse) expect(response_dates).to eq(response_dates.sort.reverse)
end end
@ -255,9 +223,8 @@ describe API::Issues, api: true do
get api('/issues?sort=asc', user) get api('/issues?sort=asc', user)
response_dates = json_response.map { |issue| issue['created_at'] } response_dates = json_response.map { |issue| issue['created_at'] }
expect(response).to have_http_status(200)
expect(response).to include_pagination_headers expect_paginated_array_response(size: 2)
expect(json_response).to be_an Array
expect(response_dates).to eq(response_dates.sort) expect(response_dates).to eq(response_dates.sort)
end end
@ -265,9 +232,8 @@ describe API::Issues, api: true do
get api('/issues?order_by=updated_at', user) get api('/issues?order_by=updated_at', user)
response_dates = json_response.map { |issue| issue['updated_at'] } response_dates = json_response.map { |issue| issue['updated_at'] }
expect(response).to have_http_status(200)
expect(response).to include_pagination_headers expect_paginated_array_response(size: 2)
expect(json_response).to be_an Array
expect(response_dates).to eq(response_dates.sort.reverse) expect(response_dates).to eq(response_dates.sort.reverse)
end end
@ -275,9 +241,8 @@ describe API::Issues, api: true do
get api('/issues?order_by=updated_at&sort=asc', user) get api('/issues?order_by=updated_at&sort=asc', user)
response_dates = json_response.map { |issue| issue['updated_at'] } response_dates = json_response.map { |issue| issue['updated_at'] }
expect(response).to have_http_status(200)
expect(response).to include_pagination_headers expect_paginated_array_response(size: 2)
expect(json_response).to be_an Array
expect(response_dates).to eq(response_dates.sort) expect(response_dates).to eq(response_dates.sort)
end end
@ -316,7 +281,9 @@ describe API::Issues, api: true do
assignee: user, assignee: user,
project: group_project, project: group_project,
milestone: group_milestone, milestone: group_milestone,
updated_at: 1.hour.ago updated_at: 1.hour.ago,
title: issue_title,
description: issue_description
end end
let!(:group_label) do let!(:group_label) do
create(:label, title: 'group_lbl', color: '#FFAABB', project: group_project) create(:label, title: 'group_lbl', color: '#FFAABB', project: group_project)
@ -336,74 +303,65 @@ describe API::Issues, api: true do
it 'returns all group issues (including opened and closed)' do it 'returns all group issues (including opened and closed)' do
get api(base_url, admin) get api(base_url, admin)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 3)
expect(json_response).to be_an Array
expect(json_response.length).to eq(3)
end end
it 'returns group issues without confidential issues for non project members' do it 'returns group issues without confidential issues for non project members' do
get api("#{base_url}?state=opened", non_member) get api("#{base_url}?state=opened", non_member)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 1)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['title']).to eq(group_issue.title) expect(json_response.first['title']).to eq(group_issue.title)
end end
it 'returns group confidential issues for author' do it 'returns group confidential issues for author' do
get api("#{base_url}?state=opened", author) get api("#{base_url}?state=opened", author)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 2)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
end end
it 'returns group confidential issues for assignee' do it 'returns group confidential issues for assignee' do
get api("#{base_url}?state=opened", assignee) get api("#{base_url}?state=opened", assignee)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 2)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
end end
it 'returns group issues with confidential issues for project members' do it 'returns group issues with confidential issues for project members' do
get api("#{base_url}?state=opened", user) get api("#{base_url}?state=opened", user)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 2)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
end end
it 'returns group confidential issues for admin' do it 'returns group confidential issues for admin' do
get api("#{base_url}?state=opened", admin) get api("#{base_url}?state=opened", admin)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 2)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
end end
it 'returns an array of labeled group issues' do it 'returns an array of labeled group issues' do
get api("#{base_url}?labels=#{group_label.title}", user) get api("#{base_url}?labels=#{group_label.title}", user)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 1)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['labels']).to eq([group_label.title]) expect(json_response.first['labels']).to eq([group_label.title])
end end
it 'returns an array of labeled group issues where all labels match' do it 'returns an array of labeled group issues where all labels match' do
get api("#{base_url}?labels=#{group_label.title},foo,bar", user) get api("#{base_url}?labels=#{group_label.title},foo,bar", user)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 0)
expect(response).to include_pagination_headers end
expect(json_response).to be_an Array
expect(json_response.length).to eq(0) it 'returns issues matching given search string for title' do
get api("#{base_url}?search=#{group_issue.title}", user)
expect_paginated_array_response(size: 1)
expect(json_response.first['id']).to eq(group_issue.id)
end
it 'returns issues matching given search string for description' do
get api("#{base_url}?search=#{group_issue.description}", user)
expect_paginated_array_response(size: 1)
expect(json_response.first['id']).to eq(group_issue.id)
end end
it 'returns an array of labeled issues when all labels matches' do it 'returns an array of labeled issues when all labels matches' do
@ -415,65 +373,45 @@ describe API::Issues, api: true do
get api("#{base_url}", user), labels: "#{group_label.title},#{label_b.title},#{label_c.title}" get api("#{base_url}", user), labels: "#{group_label.title},#{label_b.title},#{label_c.title}"
expect(response).to have_http_status(200) expect_paginated_array_response(size: 1)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['labels']).to eq([label_c.title, label_b.title, group_label.title]) expect(json_response.first['labels']).to eq([label_c.title, label_b.title, group_label.title])
end end
it 'returns an array of issues found by iids' do it 'returns an array of issues found by iids' do
get api(base_url, user), iids: [group_issue.iid] get api(base_url, user), iids: [group_issue.iid]
expect(response).to have_http_status(200) expect_paginated_array_response(size: 1)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(group_issue.id) expect(json_response.first['id']).to eq(group_issue.id)
end end
it 'returns an empty array if iid does not exist' do it 'returns an empty array if iid does not exist' do
get api(base_url, user), iids: [99999] get api(base_url, user), iids: [99999]
expect(response).to have_http_status(200) expect_paginated_array_response(size: 0)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(0)
end end
it 'returns an empty array if no group issue matches labels' do it 'returns an empty array if no group issue matches labels' do
get api("#{base_url}?labels=foo,bar", user) get api("#{base_url}?labels=foo,bar", user)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 0)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(0)
end end
it 'returns an empty array if no issue matches milestone' do it 'returns an empty array if no issue matches milestone' do
get api("#{base_url}?milestone=#{group_empty_milestone.title}", user) get api("#{base_url}?milestone=#{group_empty_milestone.title}", user)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 0)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(0)
end end
it 'returns an empty array if milestone does not exist' do it 'returns an empty array if milestone does not exist' do
get api("#{base_url}?milestone=foo", user) get api("#{base_url}?milestone=foo", user)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 0)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(0)
end end
it 'returns an array of issues in given milestone' do it 'returns an array of issues in given milestone' do
get api("#{base_url}?state=opened&milestone=#{group_milestone.title}", user) get api("#{base_url}?state=opened&milestone=#{group_milestone.title}", user)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 1)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(group_issue.id) expect(json_response.first['id']).to eq(group_issue.id)
end end
@ -481,10 +419,7 @@ describe API::Issues, api: true do
get api("#{base_url}?milestone=#{group_milestone.title}"\ get api("#{base_url}?milestone=#{group_milestone.title}"\
'&state=closed', user) '&state=closed', user)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 1)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(group_closed_issue.id) expect(json_response.first['id']).to eq(group_closed_issue.id)
end end
@ -492,9 +427,8 @@ describe API::Issues, api: true do
get api("#{base_url}?milestone=#{no_milestone_title}", user) get api("#{base_url}?milestone=#{no_milestone_title}", user)
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array expect_paginated_array_response(size: 1)
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(group_confidential_issue.id) expect(json_response.first['id']).to eq(group_confidential_issue.id)
end end
@ -502,9 +436,8 @@ describe API::Issues, api: true do
get api(base_url, user) get api(base_url, user)
response_dates = json_response.map { |issue| issue['created_at'] } response_dates = json_response.map { |issue| issue['created_at'] }
expect(response).to have_http_status(200)
expect(response).to include_pagination_headers expect_paginated_array_response(size: 3)
expect(json_response).to be_an Array
expect(response_dates).to eq(response_dates.sort.reverse) expect(response_dates).to eq(response_dates.sort.reverse)
end end
@ -512,9 +445,8 @@ describe API::Issues, api: true do
get api("#{base_url}?sort=asc", user) get api("#{base_url}?sort=asc", user)
response_dates = json_response.map { |issue| issue['created_at'] } response_dates = json_response.map { |issue| issue['created_at'] }
expect(response).to have_http_status(200)
expect(response).to include_pagination_headers expect_paginated_array_response(size: 3)
expect(json_response).to be_an Array
expect(response_dates).to eq(response_dates.sort) expect(response_dates).to eq(response_dates.sort)
end end
@ -522,9 +454,8 @@ describe API::Issues, api: true do
get api("#{base_url}?order_by=updated_at", user) get api("#{base_url}?order_by=updated_at", user)
response_dates = json_response.map { |issue| issue['updated_at'] } response_dates = json_response.map { |issue| issue['updated_at'] }
expect(response).to have_http_status(200)
expect(response).to include_pagination_headers expect_paginated_array_response(size: 3)
expect(json_response).to be_an Array
expect(response_dates).to eq(response_dates.sort.reverse) expect(response_dates).to eq(response_dates.sort.reverse)
end end
@ -532,9 +463,8 @@ describe API::Issues, api: true do
get api("#{base_url}?order_by=updated_at&sort=asc", user) get api("#{base_url}?order_by=updated_at&sort=asc", user)
response_dates = json_response.map { |issue| issue['updated_at'] } response_dates = json_response.map { |issue| issue['updated_at'] }
expect(response).to have_http_status(200)
expect(response).to include_pagination_headers expect_paginated_array_response(size: 3)
expect(json_response).to be_an Array
expect(response_dates).to eq(response_dates.sort) expect(response_dates).to eq(response_dates.sort)
end end
end end
@ -563,79 +493,55 @@ describe API::Issues, api: true do
get api("/projects/#{restricted_project.id}/issues", non_member) get api("/projects/#{restricted_project.id}/issues", non_member)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 0)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response).to eq([])
end end
it 'returns project issues without confidential issues for non project members' do it 'returns project issues without confidential issues for non project members' do
get api("#{base_url}/issues", non_member) get api("#{base_url}/issues", non_member)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 2)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
expect(json_response.first['title']).to eq(issue.title) expect(json_response.first['title']).to eq(issue.title)
end end
it 'returns project issues without confidential issues for project members with guest role' do it 'returns project issues without confidential issues for project members with guest role' do
get api("#{base_url}/issues", guest) get api("#{base_url}/issues", guest)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 2)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
expect(json_response.first['title']).to eq(issue.title) expect(json_response.first['title']).to eq(issue.title)
end end
it 'returns project confidential issues for author' do it 'returns project confidential issues for author' do
get api("#{base_url}/issues", author) get api("#{base_url}/issues", author)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 3)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(3)
expect(json_response.first['title']).to eq(issue.title) expect(json_response.first['title']).to eq(issue.title)
end end
it 'returns project confidential issues for assignee' do it 'returns project confidential issues for assignee' do
get api("#{base_url}/issues", assignee) get api("#{base_url}/issues", assignee)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 3)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(3)
expect(json_response.first['title']).to eq(issue.title) expect(json_response.first['title']).to eq(issue.title)
end end
it 'returns project issues with confidential issues for project members' do it 'returns project issues with confidential issues for project members' do
get api("#{base_url}/issues", user) get api("#{base_url}/issues", user)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 3)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(3)
expect(json_response.first['title']).to eq(issue.title) expect(json_response.first['title']).to eq(issue.title)
end end
it 'returns project confidential issues for admin' do it 'returns project confidential issues for admin' do
get api("#{base_url}/issues", admin) get api("#{base_url}/issues", admin)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 3)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(3)
expect(json_response.first['title']).to eq(issue.title) expect(json_response.first['title']).to eq(issue.title)
end end
it 'returns an array of labeled project issues' do it 'returns an array of labeled project issues' do
get api("#{base_url}/issues?labels=#{label.title}", user) get api("#{base_url}/issues?labels=#{label.title}", user)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 1)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['labels']).to eq([label.title]) expect(json_response.first['labels']).to eq([label.title])
end end
@ -648,74 +554,65 @@ describe API::Issues, api: true do
get api("#{base_url}/issues", user), labels: "#{label.title},#{label_b.title},#{label_c.title}" get api("#{base_url}/issues", user), labels: "#{label.title},#{label_b.title},#{label_c.title}"
expect(response).to have_http_status(200) expect_paginated_array_response(size: 1)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['labels']).to eq([label_c.title, label_b.title, label.title]) expect(json_response.first['labels']).to eq([label_c.title, label_b.title, label.title])
end end
it 'returns issues matching given search string for title' do
get api("#{base_url}/issues?search=#{issue.title}", user)
expect_paginated_array_response(size: 1)
expect(json_response.first['id']).to eq(issue.id)
end
it 'returns issues matching given search string for description' do
get api("#{base_url}/issues?search=#{issue.description}", user)
expect_paginated_array_response(size: 1)
expect(json_response.first['id']).to eq(issue.id)
end
it 'returns an array of issues found by iids' do it 'returns an array of issues found by iids' do
get api("#{base_url}/issues", user), iids: [issue.iid] get api("#{base_url}/issues", user), iids: [issue.iid]
expect(response).to have_http_status(200) expect_paginated_array_response(size: 1)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(issue.id) expect(json_response.first['id']).to eq(issue.id)
end end
it 'returns an empty array if iid does not exist' do it 'returns an empty array if iid does not exist' do
get api("#{base_url}/issues", user), iids: [99999] get api("#{base_url}/issues", user), iids: [99999]
expect(response).to have_http_status(200) expect_paginated_array_response(size: 0)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(0)
end end
it 'returns an empty array if not all labels matches' do it 'returns an empty array if not all labels matches' do
get api("#{base_url}/issues?labels=#{label.title},foo", user) get api("#{base_url}/issues?labels=#{label.title},foo", user)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 0)
expect(json_response).to be_an Array
expect(json_response.length).to eq(0)
end end
it 'returns an empty array if no project issue matches labels' do it 'returns an empty array if no project issue matches labels' do
get api("#{base_url}/issues?labels=foo,bar", user) get api("#{base_url}/issues?labels=foo,bar", user)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 0)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(0)
end end
it 'returns an empty array if no issue matches milestone' do it 'returns an empty array if no issue matches milestone' do
get api("#{base_url}/issues?milestone=#{empty_milestone.title}", user) get api("#{base_url}/issues?milestone=#{empty_milestone.title}", user)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 0)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(0)
end end
it 'returns an empty array if milestone does not exist' do it 'returns an empty array if milestone does not exist' do
get api("#{base_url}/issues?milestone=foo", user) get api("#{base_url}/issues?milestone=foo", user)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 0)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(0)
end end
it 'returns an array of issues in given milestone' do it 'returns an array of issues in given milestone' do
get api("#{base_url}/issues?milestone=#{milestone.title}", user) get api("#{base_url}/issues?milestone=#{milestone.title}", user)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 2)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
expect(json_response.first['id']).to eq(issue.id) expect(json_response.first['id']).to eq(issue.id)
expect(json_response.second['id']).to eq(closed_issue.id) expect(json_response.second['id']).to eq(closed_issue.id)
end end
@ -723,20 +620,14 @@ describe API::Issues, api: true do
it 'returns an array of issues matching state in milestone' do it 'returns an array of issues matching state in milestone' do
get api("#{base_url}/issues?milestone=#{milestone.title}&state=closed", user) get api("#{base_url}/issues?milestone=#{milestone.title}&state=closed", user)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 1)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(closed_issue.id) expect(json_response.first['id']).to eq(closed_issue.id)
end end
it 'returns an array of issues with no milestone' do it 'returns an array of issues with no milestone' do
get api("#{base_url}/issues?milestone=#{no_milestone_title}", user) get api("#{base_url}/issues?milestone=#{no_milestone_title}", user)
expect(response).to have_http_status(200) expect_paginated_array_response(size: 1)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(confidential_issue.id) expect(json_response.first['id']).to eq(confidential_issue.id)
end end
@ -744,9 +635,8 @@ describe API::Issues, api: true do
get api("#{base_url}/issues", user) get api("#{base_url}/issues", user)
response_dates = json_response.map { |issue| issue['created_at'] } response_dates = json_response.map { |issue| issue['created_at'] }
expect(response).to have_http_status(200)
expect(response).to include_pagination_headers expect_paginated_array_response(size: 3)
expect(json_response).to be_an Array
expect(response_dates).to eq(response_dates.sort.reverse) expect(response_dates).to eq(response_dates.sort.reverse)
end end
@ -754,9 +644,8 @@ describe API::Issues, api: true do
get api("#{base_url}/issues?sort=asc", user) get api("#{base_url}/issues?sort=asc", user)
response_dates = json_response.map { |issue| issue['created_at'] } response_dates = json_response.map { |issue| issue['created_at'] }
expect(response).to have_http_status(200)
expect(response).to include_pagination_headers expect_paginated_array_response(size: 3)
expect(json_response).to be_an Array
expect(response_dates).to eq(response_dates.sort) expect(response_dates).to eq(response_dates.sort)
end end
@ -764,9 +653,8 @@ describe API::Issues, api: true do
get api("#{base_url}/issues?order_by=updated_at", user) get api("#{base_url}/issues?order_by=updated_at", user)
response_dates = json_response.map { |issue| issue['updated_at'] } response_dates = json_response.map { |issue| issue['updated_at'] }
expect(response).to have_http_status(200)
expect(response).to include_pagination_headers expect_paginated_array_response(size: 3)
expect(json_response).to be_an Array
expect(response_dates).to eq(response_dates.sort.reverse) expect(response_dates).to eq(response_dates.sort.reverse)
end end
@ -774,9 +662,8 @@ describe API::Issues, api: true do
get api("#{base_url}/issues?order_by=updated_at&sort=asc", user) get api("#{base_url}/issues?order_by=updated_at&sort=asc", user)
response_dates = json_response.map { |issue| issue['updated_at'] } response_dates = json_response.map { |issue| issue['updated_at'] }
expect(response).to have_http_status(200)
expect(response).to include_pagination_headers expect_paginated_array_response(size: 3)
expect(json_response).to be_an Array
expect(response_dates).to eq(response_dates.sort) expect(response_dates).to eq(response_dates.sort)
end end
end end
@ -1457,4 +1344,11 @@ describe API::Issues, api: true do
include_examples 'time tracking endpoints', 'issue' include_examples 'time tracking endpoints', 'issue'
end end
def expect_paginated_array_response(size: nil)
expect(response).to have_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(size) if size
end
end end