Commit 9aae0070 authored by Heinrich Lee Yu's avatar Heinrich Lee Yu

Merge branch '267966-remove-deprecated-graphql-fields' into 'master'

Remove graphql deprecated fields

See merge request gitlab-org/gitlab!63293
parents 59c3615c 89009fc7
...@@ -7,12 +7,6 @@ module Mutations ...@@ -7,12 +7,6 @@ module Mutations
authorize :update_user authorize :update_user
field :updated_ids,
[::Types::GlobalIDType[::Todo]],
null: false,
deprecated: { reason: 'Use to-do items', milestone: '13.2' },
description: 'IDs of the updated to-do items.'
field :todos, [::Types::TodoType], field :todos, [::Types::TodoType],
null: false, null: false,
description: 'Updated to-do items.' description: 'Updated to-do items.'
...@@ -23,7 +17,6 @@ module Mutations ...@@ -23,7 +17,6 @@ module Mutations
updated_ids = mark_all_todos_done updated_ids = mark_all_todos_done
{ {
updated_ids: updated_ids,
todos: Todo.id_in(updated_ids), todos: Todo.id_in(updated_ids),
errors: [] errors: []
} }
......
...@@ -12,11 +12,6 @@ module Mutations ...@@ -12,11 +12,6 @@ module Mutations
required: true, required: true,
description: 'The global IDs of the to-do items to restore (a maximum of 50 is supported at once).' description: 'The global IDs of the to-do items to restore (a maximum of 50 is supported at once).'
field :updated_ids, [::Types::GlobalIDType[Todo]],
null: false,
description: 'The IDs of the updated to-do items.',
deprecated: { reason: 'Use to-do items', milestone: '13.2' }
field :todos, [::Types::TodoType], field :todos, [::Types::TodoType],
null: false, null: false,
description: 'Updated to-do items.' description: 'Updated to-do items.'
......
...@@ -5,15 +5,7 @@ module Types ...@@ -5,15 +5,7 @@ module Types
extend ActiveSupport::Concern extend ActiveSupport::Concern
prepended do prepended do
mount_aliased_mutation 'AddAwardEmoji', # placeholder for any FOSS mutations to be deprecated
Mutations::AwardEmojis::Add,
deprecated: { reason: 'Use awardEmojiAdd', milestone: '13.2' }
mount_aliased_mutation 'RemoveAwardEmoji',
Mutations::AwardEmojis::Remove,
deprecated: { reason: 'Use awardEmojiRemove', milestone: '13.2' }
mount_aliased_mutation 'ToggleAwardEmoji',
Mutations::AwardEmojis::Toggle,
deprecated: { reason: 'Use awardEmojiToggle', milestone: '13.2' }
end end
end end
end end
...@@ -61,12 +61,6 @@ module Types ...@@ -61,12 +61,6 @@ module Types
description: 'Raw URL of the snippet.', description: 'Raw URL of the snippet.',
null: false null: false
field :blob, type: Types::Snippets::BlobType,
description: 'Snippet blob.',
calls_gitaly: true,
null: false,
deprecated: { reason: 'Use `blobs`', milestone: '13.3' }
field :blobs, type: Types::Snippets::BlobType.connection_type, field :blobs, type: Types::Snippets::BlobType.connection_type,
description: 'Snippet blobs.', description: 'Snippet blobs.',
calls_gitaly: true, calls_gitaly: true,
......
...@@ -455,30 +455,6 @@ four standard [pagination arguments](#connection-pagination-arguments): ...@@ -455,30 +455,6 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="queryvulnerabilitiescountbydayenddate"></a>`endDate` | [`ISO8601Date!`](#iso8601date) | Last day for which to fetch vulnerability history. | | <a id="queryvulnerabilitiescountbydayenddate"></a>`endDate` | [`ISO8601Date!`](#iso8601date) | Last day for which to fetch vulnerability history. |
| <a id="queryvulnerabilitiescountbydaystartdate"></a>`startDate` | [`ISO8601Date!`](#iso8601date) | First day for which to fetch vulnerability history. | | <a id="queryvulnerabilitiescountbydaystartdate"></a>`startDate` | [`ISO8601Date!`](#iso8601date) | First day for which to fetch vulnerability history. |
### `Query.vulnerabilitiesCountByDayAndSeverity`
Number of vulnerabilities per severity level, per day, for the projects on the
current user's instance security dashboard.
.
WARNING:
**Deprecated** in 13.3.
Use of this is not recommended.
Use: [`Query.vulnerabilitiesCountByDay`](#queryvulnerabilitiescountbyday).
Returns [`VulnerabilitiesCountByDayAndSeverityConnection`](#vulnerabilitiescountbydayandseverityconnection).
This field returns a [connection](#connections). It accepts the
four standard [pagination arguments](#connection-pagination-arguments):
`before: String`, `after: String`, `first: Int`, `last: Int`.
#### Arguments
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="queryvulnerabilitiescountbydayandseverityenddate"></a>`endDate` | [`ISO8601Date!`](#iso8601date) | Last day for which to fetch vulnerability history. |
| <a id="queryvulnerabilitiescountbydayandseveritystartdate"></a>`startDate` | [`ISO8601Date!`](#iso8601date) | First day for which to fetch vulnerability history. |
### `Query.vulnerability` ### `Query.vulnerability`
Find a vulnerability. Find a vulnerability.
...@@ -510,30 +486,6 @@ mutation($id: NoteableID!, $body: String!) { ...@@ -510,30 +486,6 @@ mutation($id: NoteableID!, $body: String!) {
} }
``` ```
### `Mutation.addAwardEmoji`
WARNING:
**Deprecated** in 13.2.
Use awardEmojiAdd.
Input type: `AddAwardEmojiInput`
#### Arguments
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationaddawardemojiawardableid"></a>`awardableId` | [`AwardableID!`](#awardableid) | The global ID of the awardable resource. |
| <a id="mutationaddawardemojiclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationaddawardemojiname"></a>`name` | [`String!`](#string) | The emoji name. |
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationaddawardemojiawardemoji"></a>`awardEmoji` | [`AwardEmoji`](#awardemoji) | The award emoji after mutation. |
| <a id="mutationaddawardemojiclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationaddawardemojierrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
### `Mutation.addProjectToSecurityDashboard` ### `Mutation.addProjectToSecurityDashboard`
Input type: `AddProjectToSecurityDashboardInput` Input type: `AddProjectToSecurityDashboardInput`
...@@ -1485,7 +1437,6 @@ Input type: `DastScannerProfileCreateInput` ...@@ -1485,7 +1437,6 @@ Input type: `DastScannerProfileCreateInput`
| ---- | ---- | ----------- | | ---- | ---- | ----------- |
| <a id="mutationdastscannerprofilecreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. | | <a id="mutationdastscannerprofilecreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationdastscannerprofilecreateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. | | <a id="mutationdastscannerprofilecreateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| <a id="mutationdastscannerprofilecreateglobalid"></a>`globalId` **{warning-solid}** | [`DastScannerProfileID`](#dastscannerprofileid) | **Deprecated:** Use `id`. Deprecated in 13.6. |
| <a id="mutationdastscannerprofilecreateid"></a>`id` | [`DastScannerProfileID`](#dastscannerprofileid) | ID of the scanner profile. | | <a id="mutationdastscannerprofilecreateid"></a>`id` | [`DastScannerProfileID`](#dastscannerprofileid) | ID of the scanner profile. |
### `Mutation.dastScannerProfileDelete` ### `Mutation.dastScannerProfileDelete`
...@@ -1943,31 +1894,6 @@ Input type: `DiscussionToggleResolveInput` ...@@ -1943,31 +1894,6 @@ Input type: `DiscussionToggleResolveInput`
| <a id="mutationdiscussiontoggleresolvediscussion"></a>`discussion` | [`Discussion`](#discussion) | The discussion after mutation. | | <a id="mutationdiscussiontoggleresolvediscussion"></a>`discussion` | [`Discussion`](#discussion) | The discussion after mutation. |
| <a id="mutationdiscussiontoggleresolveerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. | | <a id="mutationdiscussiontoggleresolveerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
### `Mutation.dismissVulnerability`
WARNING:
**Deprecated** in 13.5.
Use vulnerabilityDismiss.
Input type: `DismissVulnerabilityInput`
#### Arguments
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationdismissvulnerabilityclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationdismissvulnerabilitycomment"></a>`comment` | [`String`](#string) | Comment why vulnerability should be dismissed. |
| <a id="mutationdismissvulnerabilitydismissalreason"></a>`dismissalReason` | [`VulnerabilityDismissalReason`](#vulnerabilitydismissalreason) | Reason why vulnerability should be dismissed. |
| <a id="mutationdismissvulnerabilityid"></a>`id` | [`VulnerabilityID!`](#vulnerabilityid) | ID of the vulnerability to be dismissed. |
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationdismissvulnerabilityclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationdismissvulnerabilityerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| <a id="mutationdismissvulnerabilityvulnerability"></a>`vulnerability` | [`Vulnerability`](#vulnerability) | The vulnerability after dismissal. |
### `Mutation.enableDevopsAdoptionNamespace` ### `Mutation.enableDevopsAdoptionNamespace`
**BETA** This endpoint is subject to change without notice. **BETA** This endpoint is subject to change without notice.
...@@ -3513,30 +3439,6 @@ Input type: `ReleaseUpdateInput` ...@@ -3513,30 +3439,6 @@ Input type: `ReleaseUpdateInput`
| <a id="mutationreleaseupdateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. | | <a id="mutationreleaseupdateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| <a id="mutationreleaseupdaterelease"></a>`release` | [`Release`](#release) | The release after mutation. | | <a id="mutationreleaseupdaterelease"></a>`release` | [`Release`](#release) | The release after mutation. |
### `Mutation.removeAwardEmoji`
WARNING:
**Deprecated** in 13.2.
Use awardEmojiRemove.
Input type: `RemoveAwardEmojiInput`
#### Arguments
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationremoveawardemojiawardableid"></a>`awardableId` | [`AwardableID!`](#awardableid) | The global ID of the awardable resource. |
| <a id="mutationremoveawardemojiclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationremoveawardemojiname"></a>`name` | [`String!`](#string) | The emoji name. |
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationremoveawardemojiawardemoji"></a>`awardEmoji` | [`AwardEmoji`](#awardemoji) | The award emoji after mutation. |
| <a id="mutationremoveawardemojiclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationremoveawardemojierrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
### `Mutation.removeProjectFromSecurityDashboard` ### `Mutation.removeProjectFromSecurityDashboard`
Input type: `RemoveProjectFromSecurityDashboardInput` Input type: `RemoveProjectFromSecurityDashboardInput`
...@@ -3577,55 +3479,6 @@ Input type: `RepositionImageDiffNoteInput` ...@@ -3577,55 +3479,6 @@ Input type: `RepositionImageDiffNoteInput`
| <a id="mutationrepositionimagediffnoteerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. | | <a id="mutationrepositionimagediffnoteerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| <a id="mutationrepositionimagediffnotenote"></a>`note` | [`Note`](#note) | The note after mutation. | | <a id="mutationrepositionimagediffnotenote"></a>`note` | [`Note`](#note) | The note after mutation. |
### `Mutation.revertVulnerabilityToDetected`
WARNING:
**Deprecated** in 13.5.
Use vulnerabilityRevertToDetected.
Input type: `RevertVulnerabilityToDetectedInput`
#### Arguments
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationrevertvulnerabilitytodetectedclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationrevertvulnerabilitytodetectedid"></a>`id` | [`VulnerabilityID!`](#vulnerabilityid) | ID of the vulnerability to be reverted. |
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationrevertvulnerabilitytodetectedclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationrevertvulnerabilitytodetectederrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| <a id="mutationrevertvulnerabilitytodetectedvulnerability"></a>`vulnerability` | [`Vulnerability`](#vulnerability) | The vulnerability after revert. |
### `Mutation.runDastScan`
WARNING:
**Deprecated** in 13.4.
Use DastOnDemandScanCreate.
Input type: `RunDASTScanInput`
#### Arguments
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationrundastscanbranch"></a>`branch` | [`String!`](#string) | The branch to be associated with the scan. |
| <a id="mutationrundastscanclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationrundastscanprojectpath"></a>`projectPath` | [`ID!`](#id) | The project the DAST scan belongs to. |
| <a id="mutationrundastscanscantype"></a>`scanType` | [`DastScanTypeEnum!`](#dastscantypeenum) | The type of scan to be run. |
| <a id="mutationrundastscantargeturl"></a>`targetUrl` | [`String!`](#string) | The URL of the target to be scanned. |
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationrundastscanclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationrundastscanerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| <a id="mutationrundastscanpipelineurl"></a>`pipelineUrl` | [`String`](#string) | URL of the pipeline that was created. |
### `Mutation.runnerDelete` ### `Mutation.runnerDelete`
Available only when feature flag `runner_graphql_query` is enabled. Available only when feature flag `runner_graphql_query` is enabled.
...@@ -3803,7 +3656,6 @@ Input type: `TodoRestoreManyInput` ...@@ -3803,7 +3656,6 @@ Input type: `TodoRestoreManyInput`
| <a id="mutationtodorestoremanyclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. | | <a id="mutationtodorestoremanyclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationtodorestoremanyerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. | | <a id="mutationtodorestoremanyerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| <a id="mutationtodorestoremanytodos"></a>`todos` | [`[Todo!]!`](#todo) | Updated to-do items. | | <a id="mutationtodorestoremanytodos"></a>`todos` | [`[Todo!]!`](#todo) | Updated to-do items. |
| <a id="mutationtodorestoremanyupdatedids"></a>`updatedIds` **{warning-solid}** | [`[TodoID!]!`](#todoid) | **Deprecated:** Use to-do items. Deprecated in 13.2. |
### `Mutation.todosMarkAllDone` ### `Mutation.todosMarkAllDone`
...@@ -3822,32 +3674,6 @@ Input type: `TodosMarkAllDoneInput` ...@@ -3822,32 +3674,6 @@ Input type: `TodosMarkAllDoneInput`
| <a id="mutationtodosmarkalldoneclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. | | <a id="mutationtodosmarkalldoneclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationtodosmarkalldoneerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. | | <a id="mutationtodosmarkalldoneerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| <a id="mutationtodosmarkalldonetodos"></a>`todos` | [`[Todo!]!`](#todo) | Updated to-do items. | | <a id="mutationtodosmarkalldonetodos"></a>`todos` | [`[Todo!]!`](#todo) | Updated to-do items. |
| <a id="mutationtodosmarkalldoneupdatedids"></a>`updatedIds` **{warning-solid}** | [`[TodoID!]!`](#todoid) | **Deprecated:** Use to-do items. Deprecated in 13.2. |
### `Mutation.toggleAwardEmoji`
WARNING:
**Deprecated** in 13.2.
Use awardEmojiToggle.
Input type: `ToggleAwardEmojiInput`
#### Arguments
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationtoggleawardemojiawardableid"></a>`awardableId` | [`AwardableID!`](#awardableid) | The global ID of the awardable resource. |
| <a id="mutationtoggleawardemojiclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationtoggleawardemojiname"></a>`name` | [`String!`](#string) | The emoji name. |
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationtoggleawardemojiawardemoji"></a>`awardEmoji` | [`AwardEmoji`](#awardemoji) | The award emoji after mutation. |
| <a id="mutationtoggleawardemojiclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationtoggleawardemojierrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| <a id="mutationtoggleawardemojitoggledon"></a>`toggledOn` | [`Boolean!`](#boolean) | Indicates the status of the emoji. True if the toggle awarded the emoji, and false if the toggle removed the emoji. |
### `Mutation.updateAlertStatus` ### `Mutation.updateAlertStatus`
...@@ -6875,29 +6701,6 @@ The edge type for [`UserCore`](#usercore). ...@@ -6875,29 +6701,6 @@ The edge type for [`UserCore`](#usercore).
| <a id="usercoreedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. | | <a id="usercoreedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
| <a id="usercoreedgenode"></a>`node` | [`UserCore`](#usercore) | The item at the end of the edge. | | <a id="usercoreedgenode"></a>`node` | [`UserCore`](#usercore) | The item at the end of the edge. |
#### `VulnerabilitiesCountByDayAndSeverityConnection`
The connection type for [`VulnerabilitiesCountByDayAndSeverity`](#vulnerabilitiescountbydayandseverity).
##### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="vulnerabilitiescountbydayandseverityconnectionedges"></a>`edges` | [`[VulnerabilitiesCountByDayAndSeverityEdge]`](#vulnerabilitiescountbydayandseverityedge) | A list of edges. |
| <a id="vulnerabilitiescountbydayandseverityconnectionnodes"></a>`nodes` | [`[VulnerabilitiesCountByDayAndSeverity]`](#vulnerabilitiescountbydayandseverity) | A list of nodes. |
| <a id="vulnerabilitiescountbydayandseverityconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
#### `VulnerabilitiesCountByDayAndSeverityEdge`
The edge type for [`VulnerabilitiesCountByDayAndSeverity`](#vulnerabilitiescountbydayandseverity).
##### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="vulnerabilitiescountbydayandseverityedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
| <a id="vulnerabilitiescountbydayandseverityedgenode"></a>`node` | [`VulnerabilitiesCountByDayAndSeverity`](#vulnerabilitiescountbydayandseverity) | The item at the end of the edge. |
#### `VulnerabilitiesCountByDayConnection` #### `VulnerabilitiesCountByDayConnection`
The connection type for [`VulnerabilitiesCountByDay`](#vulnerabilitiescountbyday). The connection type for [`VulnerabilitiesCountByDay`](#vulnerabilitiescountbyday).
...@@ -8043,7 +7846,6 @@ Represents a DAST scanner profile. ...@@ -8043,7 +7846,6 @@ Represents a DAST scanner profile.
| Name | Type | Description | | Name | Type | Description |
| ---- | ---- | ----------- | | ---- | ---- | ----------- |
| <a id="dastscannerprofileeditpath"></a>`editPath` | [`String`](#string) | Relative web path to the edit page of a scanner profile. | | <a id="dastscannerprofileeditpath"></a>`editPath` | [`String`](#string) | Relative web path to the edit page of a scanner profile. |
| <a id="dastscannerprofileglobalid"></a>`globalId` **{warning-solid}** | [`DastScannerProfileID!`](#dastscannerprofileid) | **Deprecated** in 13.6. Use `id`. |
| <a id="dastscannerprofileid"></a>`id` | [`DastScannerProfileID!`](#dastscannerprofileid) | ID of the DAST scanner profile. | | <a id="dastscannerprofileid"></a>`id` | [`DastScannerProfileID!`](#dastscannerprofileid) | ID of the DAST scanner profile. |
| <a id="dastscannerprofileprofilename"></a>`profileName` | [`String`](#string) | Name of the DAST scanner profile. | | <a id="dastscannerprofileprofilename"></a>`profileName` | [`String`](#string) | Name of the DAST scanner profile. |
| <a id="dastscannerprofilereferencedinsecuritypolicies"></a>`referencedInSecurityPolicies` | [`[String!]`](#string) | List of security policy names that are referencing given project. | | <a id="dastscannerprofilereferencedinsecuritypolicies"></a>`referencedInSecurityPolicies` | [`[String!]`](#string) | List of security policy names that are referencing given project. |
...@@ -9558,27 +9360,6 @@ four standard [pagination arguments](#connection-pagination-arguments): ...@@ -9558,27 +9360,6 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="groupvulnerabilitiescountbydayenddate"></a>`endDate` | [`ISO8601Date!`](#iso8601date) | Last day for which to fetch vulnerability history. | | <a id="groupvulnerabilitiescountbydayenddate"></a>`endDate` | [`ISO8601Date!`](#iso8601date) | Last day for which to fetch vulnerability history. |
| <a id="groupvulnerabilitiescountbydaystartdate"></a>`startDate` | [`ISO8601Date!`](#iso8601date) | First day for which to fetch vulnerability history. | | <a id="groupvulnerabilitiescountbydaystartdate"></a>`startDate` | [`ISO8601Date!`](#iso8601date) | First day for which to fetch vulnerability history. |
##### `Group.vulnerabilitiesCountByDayAndSeverity`
Number of vulnerabilities per severity level, per day, for the projects in the group and its subgroups.
WARNING:
**Deprecated** in 13.3.
Use `vulnerabilitiesCountByDay`.
Returns [`VulnerabilitiesCountByDayAndSeverityConnection`](#vulnerabilitiescountbydayandseverityconnection).
This field returns a [connection](#connections). It accepts the
four standard [pagination arguments](#connection-pagination-arguments):
`before: String`, `after: String`, `first: Int`, `last: Int`.
###### Arguments
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="groupvulnerabilitiescountbydayandseverityenddate"></a>`endDate` | [`ISO8601Date!`](#iso8601date) | Last day for which to fetch vulnerability history. |
| <a id="groupvulnerabilitiescountbydayandseveritystartdate"></a>`startDate` | [`ISO8601Date!`](#iso8601date) | First day for which to fetch vulnerability history. |
##### `Group.vulnerabilityGrades` ##### `Group.vulnerabilityGrades`
Represents vulnerable project counts for each grade. Represents vulnerable project counts for each grade.
...@@ -12417,18 +12198,6 @@ Counts of requirements by their state. ...@@ -12417,18 +12198,6 @@ Counts of requirements by their state.
| <a id="rootstoragestatisticsuploadssize"></a>`uploadsSize` | [`Float!`](#float) | The uploads size in bytes. | | <a id="rootstoragestatisticsuploadssize"></a>`uploadsSize` | [`Float!`](#float) | The uploads size in bytes. |
| <a id="rootstoragestatisticswikisize"></a>`wikiSize` | [`Float!`](#float) | The wiki size in bytes. | | <a id="rootstoragestatisticswikisize"></a>`wikiSize` | [`Float!`](#float) | The wiki size in bytes. |
### `RunDASTScanPayload`
Autogenerated return type of RunDASTScan.
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="rundastscanpayloadclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="rundastscanpayloaderrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| <a id="rundastscanpayloadpipelineurl"></a>`pipelineUrl` | [`String`](#string) | URL of the pipeline that was created. |
### `RunnerArchitecture` ### `RunnerArchitecture`
#### Fields #### Fields
...@@ -12771,7 +12540,6 @@ Represents a snippet entry. ...@@ -12771,7 +12540,6 @@ Represents a snippet entry.
| Name | Type | Description | | Name | Type | Description |
| ---- | ---- | ----------- | | ---- | ---- | ----------- |
| <a id="snippetauthor"></a>`author` | [`UserCore`](#usercore) | The owner of the snippet. | | <a id="snippetauthor"></a>`author` | [`UserCore`](#usercore) | The owner of the snippet. |
| <a id="snippetblob"></a>`blob` **{warning-solid}** | [`SnippetBlob!`](#snippetblob) | **Deprecated** in 13.3. Use `blobs`. |
| <a id="snippetcreatedat"></a>`createdAt` | [`Time!`](#time) | Timestamp this snippet was created. | | <a id="snippetcreatedat"></a>`createdAt` | [`Time!`](#time) | Timestamp this snippet was created. |
| <a id="snippetdescription"></a>`description` | [`String`](#string) | Description of the snippet. | | <a id="snippetdescription"></a>`description` | [`String`](#string) | Description of the snippet. |
| <a id="snippetdescriptionhtml"></a>`descriptionHtml` | [`String`](#string) | The GitLab Flavored Markdown rendering of `description`. | | <a id="snippetdescriptionhtml"></a>`descriptionHtml` | [`String`](#string) | The GitLab Flavored Markdown rendering of `description`. |
...@@ -13389,18 +13157,6 @@ Represents the count of vulnerabilities by severity on a particular day. This da ...@@ -13389,18 +13157,6 @@ Represents the count of vulnerabilities by severity on a particular day. This da
| <a id="vulnerabilitiescountbydaytotal"></a>`total` | [`Int!`](#int) | Total number of vulnerabilities on a particular day. | | <a id="vulnerabilitiescountbydaytotal"></a>`total` | [`Int!`](#int) | Total number of vulnerabilities on a particular day. |
| <a id="vulnerabilitiescountbydayunknown"></a>`unknown` | [`Int!`](#int) | Total number of vulnerabilities on a particular day with unknown severity. | | <a id="vulnerabilitiescountbydayunknown"></a>`unknown` | [`Int!`](#int) | Total number of vulnerabilities on a particular day with unknown severity. |
### `VulnerabilitiesCountByDayAndSeverity`
Represents the number of vulnerabilities for a particular severity on a particular day. This data is retained for 365 days.
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="vulnerabilitiescountbydayandseveritycount"></a>`count` | [`Int`](#int) | Number of vulnerabilities. |
| <a id="vulnerabilitiescountbydayandseverityday"></a>`day` | [`ISO8601Date`](#iso8601date) | Date for the count. |
| <a id="vulnerabilitiescountbydayandseverityseverity"></a>`severity` | [`VulnerabilitySeverity`](#vulnerabilityseverity) | Severity of the counted vulnerabilities. |
### `Vulnerability` ### `Vulnerability`
Represents a vulnerability. Represents a vulnerability.
......
...@@ -10,6 +10,32 @@ GraphQL is a versionless API, unlike the REST API. ...@@ -10,6 +10,32 @@ GraphQL is a versionless API, unlike the REST API.
Occasionally, items have to be updated or removed from the GraphQL API. Occasionally, items have to be updated or removed from the GraphQL API.
According to our [process for removing items](index.md#deprecation-and-removal-process), here are the items that have been removed. According to our [process for removing items](index.md#deprecation-and-removal-process), here are the items that have been removed.
## GitLab 14.0
Fields removed in [GitLab 14.0](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/63293):
### GraphQL Mutations
| Argument name | Mutation | Deprecated in | Use instead |
| -------------------- | -------------------- | ------------- | -------------------------- |
| `updated_ids` | `todosMarkAllDone` | 13.2 | `todos` |
| `updated_ids` | `todoRestoreMany` | 13.2 | `todos` |
| `global_id` | `dastScannerProfileCreate`| 13.6 | `todos` |
| - | `addAwardEmoji` | 13.2 | `awardEmojiAdd` |
| - | `removeAwardEmoji` | 13.2 | `awardEmojiRemove` |
| - | `toggleAwardEmoji` | 13.2 | `ToggleAwardEmoji` |
| - | `runDastScan` | 13.5 | `dastOnDemandScanCreate` |
| - | `dismissVulnerability` | 13.5 | `vulnerabilityDismiss` |
| - | `revertVulnerabilityToDetected` | 13.5 | `vulnerabilityRevertToDetected` |
### GraphQL Types
| Field name | GraphQL type | Deprecated in | Use instead |
| -------------------- | -------------------- | ------------- | -------------------------- |
| `blob` | `SnippetType` | 13.3 | `blobs` |
| `global_id` | `DastScannerProfileType` | 13.6 | `blobs` |
| `vulnerabilities_count_by_day_and_severity` | `GroupType`, `QueryType` | 13.3 | None. Plaintext tokens no longer supported for security reasons. |
## GitLab 13.6 ## GitLab 13.6
Fields removed in [GitLab 13.6](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/44866): Fields removed in [GitLab 13.6](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/44866):
......
mutation runDastScan(
$projectPath: ID!
$targetUrl: String!
$branch: String!
$scanType: DastScanTypeEnum!
) {
runDastScan(
input: {
projectPath: $projectPath
targetUrl: $targetUrl
branch: $branch
scanType: $scanType
}
) {
pipelineUrl
errors
}
}
...@@ -6,15 +6,6 @@ module EE ...@@ -6,15 +6,6 @@ module EE
extend ActiveSupport::Concern extend ActiveSupport::Concern
prepended do prepended do
mount_mutation ::Mutations::Pipelines::RunDastScan,
deprecated: { reason: 'Use DastOnDemandScanCreate', milestone: '13.4' }
mount_aliased_mutation 'DismissVulnerability', ::Mutations::Vulnerabilities::Dismiss,
deprecated: { reason: 'Use vulnerabilityDismiss', milestone: '13.5' }
mount_aliased_mutation 'RevertVulnerabilityToDetected', ::Mutations::Vulnerabilities::RevertToDetected,
deprecated: { reason: 'Use vulnerabilityRevertToDetected', milestone: '13.5' }
mount_aliased_mutation 'CreateIteration', ::Mutations::Iterations::Create, mount_aliased_mutation 'CreateIteration', ::Mutations::Iterations::Create,
deprecated: { reason: 'Use iterationCreate', milestone: '14.0' } deprecated: { reason: 'Use iterationCreate', milestone: '14.0' }
end end
......
...@@ -65,13 +65,6 @@ module EE ...@@ -65,13 +65,6 @@ module EE
description: 'Number of vulnerabilities per day for the projects in the group and its subgroups.', description: 'Number of vulnerabilities per day for the projects in the group and its subgroups.',
resolver: ::Resolvers::VulnerabilitiesCountPerDayResolver resolver: ::Resolvers::VulnerabilitiesCountPerDayResolver
field :vulnerabilities_count_by_day_and_severity,
::Types::VulnerabilitiesCountByDayAndSeverityType.connection_type,
null: true,
description: 'Number of vulnerabilities per severity level, per day, for the projects in the group and its subgroups.',
resolver: ::Resolvers::VulnerabilitiesHistoryResolver,
deprecated: { reason: 'Use `vulnerabilitiesCountByDay`', milestone: '13.3' }
field :vulnerability_grades, field :vulnerability_grades,
[::Types::VulnerableProjectsByGradeType], [::Types::VulnerableProjectsByGradeType],
null: false, null: false,
......
...@@ -37,16 +37,6 @@ module EE ...@@ -37,16 +37,6 @@ module EE
Number of vulnerabilities per day for the projects on the current user's instance security dashboard. Number of vulnerabilities per day for the projects on the current user's instance security dashboard.
DESC DESC
field :vulnerabilities_count_by_day_and_severity,
::Types::VulnerabilitiesCountByDayAndSeverityType.connection_type,
null: true,
resolver: ::Resolvers::VulnerabilitiesHistoryResolver,
deprecated: { reason: :discouraged, replacement: 'Query.vulnerabilitiesCountByDay', milestone: '13.3' },
description: <<~DESC
Number of vulnerabilities per severity level, per day, for the projects on the
current user's instance security dashboard.
DESC
field :geo_node, ::Types::Geo::GeoNodeType, field :geo_node, ::Types::Geo::GeoNodeType,
null: true, null: true,
resolver: ::Resolvers::Geo::GeoNodeResolver, resolver: ::Resolvers::Geo::GeoNodeResolver,
......
...@@ -11,11 +11,6 @@ module Mutations ...@@ -11,11 +11,6 @@ module Mutations
null: true, null: true,
description: 'ID of the scanner profile.' description: 'ID of the scanner profile.'
field :global_id, ::Types::GlobalIDType[::DastScannerProfile],
null: true,
description: 'ID of the scanner profile.',
deprecated: { reason: 'Use `id`', milestone: '13.6' }
argument :full_path, GraphQL::ID_TYPE, argument :full_path, GraphQL::ID_TYPE,
required: true, required: true,
description: 'The project the scanner profile belongs to.' description: 'The project the scanner profile belongs to.'
......
# frozen_string_literal: true
module Mutations
module Pipelines
class RunDastScan < BaseMutation
include FindsProject
graphql_name 'RunDASTScan'
field :pipeline_url, GraphQL::STRING_TYPE,
null: true,
description: 'URL of the pipeline that was created.'
argument :project_path, GraphQL::ID_TYPE,
required: true,
description: 'The project the DAST scan belongs to.'
argument :target_url, GraphQL::STRING_TYPE,
required: true,
description: 'The URL of the target to be scanned.'
argument :branch, GraphQL::STRING_TYPE,
required: true,
description: 'The branch to be associated with the scan.'
argument :scan_type, Types::DastScanTypeEnum,
required: true,
description: 'The type of scan to be run.'
authorize :create_on_demand_dast_scan
def resolve(project_path:, target_url:, branch:, scan_type:)
project = authorized_find!(project_path)
result = ::DastOnDemandScans::CreateService.new(
container: project,
current_user: current_user,
params: {
branch: branch,
dast_site_profile: DastSiteProfile.new(dast_site: DastSite.new(url: target_url))
}
).execute
if result.success?
success_response(project: project, pipeline: result.payload[:pipeline])
else
error_response(result.message)
end
end
private
def success_response(project:, pipeline:)
pipeline_url = Rails.application.routes.url_helpers.project_pipeline_url(
project,
pipeline
)
{
errors: [],
pipeline_url: pipeline_url
}
end
def error_response(message)
{ errors: [message] }
end
end
end
end
# frozen_string_literal: true
module Resolvers
class VulnerabilitiesHistoryResolver < VulnerabilitiesBaseResolver
include Gitlab::Utils::StrongMemoize
MAX_DAYS = ::Vulnerability::MAX_DAYS_OF_HISTORY
type Types::VulnerabilitiesCountByDayAndSeverityType, null: true
argument :start_date, GraphQL::Types::ISO8601Date, required: true,
description: 'First day for which to fetch vulnerability history.'
argument :end_date, GraphQL::Types::ISO8601Date, required: true,
description: 'Last day for which to fetch vulnerability history.'
def resolve(**args)
return [] unless vulnerable
start_date = args[:start_date]
end_date = args[:end_date]
days = end_date - start_date + 1
if days > MAX_DAYS
raise ::Vulnerability::TooManyDaysError, "Cannot fetch counts for more than #{MAX_DAYS} days"
else
vulnerable.vulnerabilities.counts_by_day_and_severity(start_date, end_date).to_a
end
end
end
end
...@@ -10,11 +10,6 @@ module Types ...@@ -10,11 +10,6 @@ module Types
field :id, ::Types::GlobalIDType[::DastScannerProfile], null: false, field :id, ::Types::GlobalIDType[::DastScannerProfile], null: false,
description: 'ID of the DAST scanner profile.' description: 'ID of the DAST scanner profile.'
field :global_id, ::Types::GlobalIDType[::DastScannerProfile], null: false,
description: 'ID of the DAST scanner profile.',
deprecated: { reason: 'Use `id`', milestone: '13.6' },
method: :id
field :profile_name, GraphQL::STRING_TYPE, null: true, field :profile_name, GraphQL::STRING_TYPE, null: true,
description: 'Name of the DAST scanner profile.', description: 'Name of the DAST scanner profile.',
method: :name method: :name
......
# frozen_string_literal: true
module Types
# rubocop: disable Graphql/AuthorizeTypes
class VulnerabilitiesCountByDayAndSeverityType < BaseObject
graphql_name 'VulnerabilitiesCountByDayAndSeverity'
description 'Represents the number of vulnerabilities for a particular severity on a particular day. This data is retained for 365 days'
field :count, GraphQL::INT_TYPE, null: true,
description: 'Number of vulnerabilities.'
field :day, GraphQL::Types::ISO8601Date, null: true,
description: 'Date for the count.'
field :severity, VulnerabilitySeverityEnum, null: true,
description: 'Severity of the counted vulnerabilities.'
end
end
...@@ -16,7 +16,7 @@ RSpec.describe GitlabSchema.types['Group'] do ...@@ -16,7 +16,7 @@ RSpec.describe GitlabSchema.types['Group'] do
it { expect(described_class).to have_graphql_field(:timelogs, complexity: 5) } it { expect(described_class).to have_graphql_field(:timelogs, complexity: 5) }
it { expect(described_class).to have_graphql_field(:vulnerabilities) } it { expect(described_class).to have_graphql_field(:vulnerabilities) }
it { expect(described_class).to have_graphql_field(:vulnerability_scanners) } it { expect(described_class).to have_graphql_field(:vulnerability_scanners) }
it { expect(described_class).to have_graphql_field(:vulnerabilities_count_by_day_and_severity) } it { expect(described_class).to have_graphql_field(:vulnerabilities_count_by_day) }
it { expect(described_class).to have_graphql_field(:vulnerability_grades) } it { expect(described_class).to have_graphql_field(:vulnerability_grades) }
it { expect(described_class).to have_graphql_field(:code_coverage_activities) } it { expect(described_class).to have_graphql_field(:code_coverage_activities) }
it { expect(described_class).to have_graphql_field(:stats) } it { expect(described_class).to have_graphql_field(:stats) }
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Mutations::Pipelines::RunDastScan do
let(:group) { create(:group) }
let(:project) { create(:project, :repository, group: group) }
let(:user) { create(:user) }
let(:project_path) { project.full_path }
let(:target_url) { generate(:url) }
let(:branch) { project.default_branch }
let(:scan_type) { Types::DastScanTypeEnum.enum[:passive] }
subject(:mutation) { described_class.new(object: nil, context: { current_user: user }, field: nil) }
before do
stub_licensed_features(security_on_demand_scans: true)
end
describe '#resolve' do
subject do
mutation.resolve(
branch: branch,
project_path: project_path,
target_url: target_url,
scan_type: scan_type
)
end
context 'when on demand scan feature is not enabled' do
it 'raises an exception' do
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
end
end
context 'when on demand scan feature is enabled' do
context 'when the project does not exist' do
let(:project_path) { SecureRandom.hex }
it 'raises an exception' do
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
end
end
context 'when the user is not associated with the project' do
it 'raises an exception' do
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
end
end
context 'when the user is an owner' do
it 'has no errors' do
group.add_owner(user)
expect(subject[:errors]).to be_empty
end
end
context 'when the user is a maintainer' do
it 'has no errors' do
project.add_maintainer(user)
expect(subject[:errors]).to be_empty
end
end
context 'when the user is a developer' do
it 'has no errors' do
project.add_developer(user)
expect(subject[:errors]).to be_empty
end
end
context 'when the user can run a dast scan' do
it 'returns a pipeline_url containing the correct path' do
project.add_developer(user)
actual_url = subject[:pipeline_url]
pipeline = Ci::Pipeline.last
expected_url = Rails.application.routes.url_helpers.project_pipeline_url(
project,
pipeline
)
expect(actual_url).to eq(expected_url)
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Resolvers::VulnerabilitiesHistoryResolver do
include GraphqlHelpers
subject { resolve(described_class, obj: group, args: args, ctx: { current_user: user }) }
let_it_be(:group) { create(:group) }
let_it_be(:project) { create(:project, namespace: group) }
let_it_be(:user) { create(:user) }
describe '#resolve' do
let(:args) { { start_date: Date.parse('2019-10-15'), end_date: Date.parse('2019-10-21') } }
it "fetches historical vulnerability data from the start date to the end date" do
travel_to(Date.parse('2019-10-31')) do
create(:vulnerability, :critical, created_at: 15.days.ago, dismissed_at: 10.days.ago, project: project)
create(:vulnerability, :high, created_at: 15.days.ago, dismissed_at: 11.days.ago, project: project)
create(:vulnerability, :critical, created_at: 14.days.ago, resolved_at: 12.days.ago, project: project)
ordered_history = subject.sort_by { |count| [count['day'], count['severity']] }
expect(ordered_history.to_json).to eq([
{ 'day' => '2019-10-16', 'severity' => 'critical', 'count' => 1, 'id' => nil },
{ 'day' => '2019-10-16', 'severity' => 'high', 'count' => 1, 'id' => nil },
{ 'day' => '2019-10-17', 'severity' => 'critical', 'count' => 2, 'id' => nil },
{ 'day' => '2019-10-17', 'severity' => 'high', 'count' => 1, 'id' => nil },
{ 'day' => '2019-10-18', 'severity' => 'critical', 'count' => 2, 'id' => nil },
{ 'day' => '2019-10-18', 'severity' => 'high', 'count' => 1, 'id' => nil },
{ 'day' => '2019-10-19', 'severity' => 'critical', 'count' => 1, 'id' => nil },
{ 'day' => '2019-10-19', 'severity' => 'high', 'count' => 1, 'id' => nil },
{ 'day' => '2019-10-20', 'severity' => 'critical', 'count' => 1, 'id' => nil }
].to_json)
end
end
context 'when given more than 10 days' do
let(:args) { { start_date: Date.parse('2019-10-11'), end_date: Date.parse('2019-10-21') } }
it 'raises an error stating that no more than 10 days can be requested' do
expect { subject }.to raise_error(::Vulnerability::TooManyDaysError, 'Cannot fetch counts for more than 10 days')
end
end
end
end
...@@ -8,7 +8,7 @@ RSpec.describe GitlabSchema.types['DastScannerProfile'] do ...@@ -8,7 +8,7 @@ RSpec.describe GitlabSchema.types['DastScannerProfile'] do
let_it_be(:dast_scanner_profile) { create(:dast_scanner_profile) } let_it_be(:dast_scanner_profile) { create(:dast_scanner_profile) }
let_it_be(:project) { dast_scanner_profile.project } let_it_be(:project) { dast_scanner_profile.project }
let_it_be(:user) { create(:user) } let_it_be(:user) { create(:user) }
let_it_be(:fields) { %i[id globalId profileName spiderTimeout targetTimeout editPath scanType useAjaxSpider showDebugMessages referencedInSecurityPolicies] } let_it_be(:fields) { %i[id profileName spiderTimeout targetTimeout editPath scanType useAjaxSpider showDebugMessages referencedInSecurityPolicies] }
let(:response) do let(:response) do
GitlabSchema.execute( GitlabSchema.execute(
...@@ -45,7 +45,6 @@ RSpec.describe GitlabSchema.types['DastScannerProfile'] do ...@@ -45,7 +45,6 @@ RSpec.describe GitlabSchema.types['DastScannerProfile'] do
dastScannerProfiles { dastScannerProfiles {
nodes { nodes {
id id
globalId
profileName profileName
targetTimeout targetTimeout
spiderTimeout spiderTimeout
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe GitlabSchema.types['Mutation'] do
describe 'deprecated mutations' do
using RSpec::Parameterized::TableSyntax
where(:field_name, :reason, :milestone) do
'RunDastScan' | 'Use DastOnDemandScanCreate' | '13.4'
end
with_them do
let(:field) { get_field(field_name) }
let(:deprecation_reason) { "#{reason}. Deprecated in #{milestone}." }
it { expect(field).to be_present }
it { expect(field.deprecation_reason).to eq(deprecation_reason) }
end
end
describe 'aliased deprecated mutations' do
using RSpec::Parameterized::TableSyntax
where(:alias_name, :canonical_name) do
'DismissVulnerability' | 'VulnerabilityDismiss'
'RevertVulnerabilityToDetected' | 'VulnerabilityRevertToDetected'
end
with_them do
let(:alias_field) { get_field(alias_name) }
let(:canonical_field) { get_field(canonical_name) }
it { expect(alias_field).to be_present }
it { expect(canonical_field).to be_present }
it { expect(alias_field.deprecation_reason).to be_present }
it { expect(canonical_field.deprecation_reason).not_to be_present }
it { expect(alias_field.resolver.fields).to eq(canonical_field.resolver.fields) }
it { expect(alias_field.resolver.arguments).to eq(canonical_field.resolver.arguments) }
end
end
def get_field(name)
described_class.fields[GraphqlHelpers.fieldnamerize(name.camelize)]
end
end
...@@ -10,7 +10,7 @@ RSpec.describe GitlabSchema.types['Query'] do ...@@ -10,7 +10,7 @@ RSpec.describe GitlabSchema.types['Query'] do
:vulnerabilities, :vulnerabilities,
:vulnerability, :vulnerability,
:instance_security_dashboard, :instance_security_dashboard,
:vulnerabilities_count_by_day_and_severity, :vulnerabilities_count_by_day,
:current_license, :current_license,
:license_history_entries :license_history_entries
).at_least ).at_least
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe GitlabSchema.types['VulnerabilitiesCountByDayAndSeverity'] do
it { expect(described_class).to have_graphql_fields(:count, :day, :severity) }
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'group(fullPath).vulnerabilitiesCountByDayAndSeverity' do
include GraphqlHelpers
let_it_be(:group) { create(:group) }
let_it_be(:project) { create(:project, namespace: group) }
let_it_be(:current_user) { create(:user) }
let(:query) { graphql_query_for(:group, { fullPath: group.full_path }, history_field) }
let(:query_result) { graphql_data.dig('group', 'vulnerabilitiesCountByDayAndSeverity', 'nodes') }
let(:history_field) do
query_graphql_field(
:vulnerabilitiesCountByDayAndSeverity,
{
start_date: Date.parse('2019-10-15').iso8601,
end_date: Date.parse('2019-10-21').iso8601
},
history_fields
)
end
let(:history_fields) do
query_graphql_field(:nodes, nil, <<~FIELDS)
count
day
severity
FIELDS
end
it "fetches historical vulnerability data from the start date to the end date for projects in the group and its subgroups" do
travel_to(Time.zone.parse('2019-10-31')) do
project.add_developer(current_user)
create(:vulnerability, :critical, created_at: 15.days.ago, dismissed_at: 10.days.ago, project: project)
create(:vulnerability, :high, created_at: 15.days.ago, dismissed_at: 11.days.ago, project: project)
create(:vulnerability, :critical, created_at: 14.days.ago, resolved_at: 12.days.ago, project: project)
post_graphql(query, current_user: current_user)
ordered_history = query_result.sort_by { |count| [count['day'], count['severity']] }
expect(ordered_history).to eq([
{ 'severity' => 'CRITICAL', 'day' => '2019-10-16', 'count' => 1 },
{ 'severity' => 'HIGH', 'day' => '2019-10-16', 'count' => 1 },
{ 'severity' => 'CRITICAL', 'day' => '2019-10-17', 'count' => 2 },
{ 'severity' => 'HIGH', 'day' => '2019-10-17', 'count' => 1 },
{ 'severity' => 'CRITICAL', 'day' => '2019-10-18', 'count' => 2 },
{ 'severity' => 'HIGH', 'day' => '2019-10-18', 'count' => 1 },
{ 'severity' => 'CRITICAL', 'day' => '2019-10-19', 'count' => 1 },
{ 'severity' => 'HIGH', 'day' => '2019-10-19', 'count' => 1 },
{ 'severity' => 'CRITICAL', 'day' => '2019-10-20', 'count' => 1 }
])
end
end
end
...@@ -25,12 +25,6 @@ RSpec.describe 'Creating a DAST Scanner Profile' do ...@@ -25,12 +25,6 @@ RSpec.describe 'Creating a DAST Scanner Profile' do
expect(mutation_response['id']).to eq(dast_scanner_profile.to_global_id.to_s) expect(mutation_response['id']).to eq(dast_scanner_profile.to_global_id.to_s)
end end
it 'returns the dast_scanner_profile global_id' do
post_graphql_mutation(mutation, current_user: current_user)
expect(mutation_response['globalId']).to eq(dast_scanner_profile.to_global_id.to_s)
end
it 'sets default values of omitted properties' do it 'sets default values of omitted properties' do
post_graphql_mutation(mutation, current_user: current_user) post_graphql_mutation(mutation, current_user: current_user)
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'Running a DAST Scan' do
include GraphqlHelpers
let(:project) { create(:project, :repository, creator: current_user) }
let(:current_user) { create(:user) }
let(:project_path) { project.full_path }
let(:target_url) { generate(:url) }
let(:branch) { project.default_branch }
let(:scan_type) { Types::DastScanTypeEnum.enum[:passive].upcase }
let(:mutation) do
graphql_mutation(
:run_dast_scan,
branch: branch,
project_path: project_path,
target_url: target_url,
scan_type: scan_type
)
end
def mutation_response
graphql_mutation_response(:run_dast_scan)
end
before do
stub_licensed_features(security_on_demand_scans: true)
end
context 'when on demand scan feature is not enabled' do
it_behaves_like 'a mutation that returns top-level errors',
errors: ['The resource that you are attempting to access does not ' \
'exist or you don\'t have permission to perform this action']
end
context 'when on demand scan feature is enabled' do
context 'when the user does not have permission to run a dast scan' do
it_behaves_like 'a mutation that returns top-level errors',
errors: ['The resource that you are attempting to access does not ' \
'exist or you don\'t have permission to perform this action']
end
context 'when the user can run a dast scan' do
before do
project.add_developer(current_user)
end
it 'returns a pipeline_url containing the correct path' do
post_graphql_mutation(mutation, current_user: current_user)
pipeline = Ci::Pipeline.last
expected_url = Rails.application.routes.url_helpers.project_pipeline_url(
project,
pipeline
)
expect(mutation_response['pipelineUrl']).to eq(expected_url)
end
context 'when pipeline creation fails' do
before do
allow_any_instance_of(Ci::Pipeline).to receive(:created_successfully?).and_return(false)
allow_any_instance_of(Ci::Pipeline).to receive(:full_error_messages).and_return('error message')
end
it_behaves_like 'a mutation that returns errors in the response', errors: ['error message']
end
end
end
end
...@@ -87,11 +87,5 @@ RSpec.describe 'Query.project(fullPath).dastScannerProfiles' do ...@@ -87,11 +87,5 @@ RSpec.describe 'Query.project(fullPath).dastScannerProfiles' do
it { is_expected.to eq(dast_scanner_profile.to_global_id.to_s) } it { is_expected.to eq(dast_scanner_profile.to_global_id.to_s) }
end end
describe 'first dast scanner profile globalId' do
subject { response_data.dig('project', 'dastScannerProfiles', 'nodes').first['globalId'] }
it { is_expected.to eq(dast_scanner_profile.to_global_id.to_s) }
end
end end
end end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'Query' do
include GraphqlHelpers
describe '.vulnerabilitiesCountByDayAndSeverity' do
let(:query_result) { graphql_data.dig('vulnerabilitiesCountByDayAndSeverity', 'nodes') }
let(:query) do
graphql_query_for(
:vulnerabilitiesCountByDayAndSeverity,
{
start_date: Date.parse('2019-10-15').iso8601,
end_date: Date.parse('2019-10-21').iso8601
},
history_fields
)
end
let(:history_fields) do
query_graphql_field(:nodes, nil, <<~FIELDS)
count
day
severity
FIELDS
end
it "fetches historical vulnerability data from the start date to the end date for projects on the current user's instance security dashboard" do
travel_to(Time.zone.parse('2019-10-31')) do
project = create(:project)
current_user = create(:user)
current_user.security_dashboard_projects << project
project.add_developer(current_user)
create(:vulnerability, :critical, created_at: 15.days.ago, dismissed_at: 10.days.ago, project: project)
create(:vulnerability, :high, created_at: 15.days.ago, dismissed_at: 11.days.ago, project: project)
create(:vulnerability, :critical, created_at: 14.days.ago, resolved_at: 12.days.ago, project: project)
post_graphql(query, current_user: current_user)
ordered_history = query_result.sort_by { |count| [count['day'], count['severity']] }
expect(ordered_history).to eq([
{ 'severity' => 'CRITICAL', 'day' => '2019-10-16', 'count' => 1 },
{ 'severity' => 'HIGH', 'day' => '2019-10-16', 'count' => 1 },
{ 'severity' => 'CRITICAL', 'day' => '2019-10-17', 'count' => 2 },
{ 'severity' => 'HIGH', 'day' => '2019-10-17', 'count' => 1 },
{ 'severity' => 'CRITICAL', 'day' => '2019-10-18', 'count' => 2 },
{ 'severity' => 'HIGH', 'day' => '2019-10-18', 'count' => 1 },
{ 'severity' => 'CRITICAL', 'day' => '2019-10-19', 'count' => 1 },
{ 'severity' => 'HIGH', 'day' => '2019-10-19', 'count' => 1 },
{ 'severity' => 'CRITICAL', 'day' => '2019-10-20', 'count' => 1 }
])
end
end
end
end
...@@ -21,26 +21,25 @@ RSpec.describe Mutations::Todos::MarkAllDone do ...@@ -21,26 +21,25 @@ RSpec.describe Mutations::Todos::MarkAllDone do
describe '#resolve' do describe '#resolve' do
it 'marks all pending todos as done' do it 'marks all pending todos as done' do
updated_todo_ids, todos = mutation_for(current_user).resolve.values_at(:updated_ids, :todos) todos = mutation_for(current_user).resolve[:todos]
expect(todo1.reload.state).to eq('done') expect(todo1.reload.state).to eq('done')
expect(todo2.reload.state).to eq('done') expect(todo2.reload.state).to eq('done')
expect(todo3.reload.state).to eq('done') expect(todo3.reload.state).to eq('done')
expect(other_user_todo.reload.state).to eq('pending') expect(other_user_todo.reload.state).to eq('pending')
expect(updated_todo_ids).to contain_exactly(todo1.id, todo3.id)
expect(todos).to contain_exactly(todo1, todo3) expect(todos).to contain_exactly(todo1, todo3)
end end
it 'behaves as expected if there are no todos for the requesting user' do it 'behaves as expected if there are no todos for the requesting user' do
updated_todo_ids = mutation_for(user3).resolve.dig(:updated_ids) todos = mutation_for(user3).resolve[:todos]
expect(todo1.reload.state).to eq('pending') expect(todo1.reload.state).to eq('pending')
expect(todo2.reload.state).to eq('done') expect(todo2.reload.state).to eq('done')
expect(todo3.reload.state).to eq('pending') expect(todo3.reload.state).to eq('pending')
expect(other_user_todo.reload.state).to eq('pending') expect(other_user_todo.reload.state).to eq('pending')
expect(updated_todo_ids).to be_empty expect(todos).to be_empty
end end
context 'when user is not logged in' do context 'when user is not logged in' do
......
...@@ -15,28 +15,6 @@ RSpec.describe Types::MutationType do ...@@ -15,28 +15,6 @@ RSpec.describe Types::MutationType do
expect(described_class).to have_graphql_mutation(Mutations::MergeRequests::SetDraft) expect(described_class).to have_graphql_mutation(Mutations::MergeRequests::SetDraft)
end end
describe 'deprecated and aliased mutations' do
using RSpec::Parameterized::TableSyntax
where(:alias_name, :canonical_name) do
'AddAwardEmoji' | 'AwardEmojiAdd'
'RemoveAwardEmoji' | 'AwardEmojiRemove'
'ToggleAwardEmoji' | 'AwardEmojiToggle'
end
with_them do
let(:alias_field) { get_field(alias_name) }
let(:canonical_field) { get_field(canonical_name) }
it { expect(alias_field).to be_present }
it { expect(canonical_field).to be_present }
it { expect(alias_field.deprecation_reason).to be_present }
it { expect(canonical_field.deprecation_reason).not_to be_present }
it { expect(alias_field.resolver.fields).to eq(canonical_field.resolver.fields) }
it { expect(alias_field.resolver.arguments).to eq(canonical_field.resolver.arguments) }
end
end
def get_field(name) def get_field(name)
described_class.fields[GraphqlHelpers.fieldnamerize(name)] described_class.fields[GraphqlHelpers.fieldnamerize(name)]
end end
......
...@@ -13,7 +13,7 @@ RSpec.describe GitlabSchema.types['Snippet'] do ...@@ -13,7 +13,7 @@ RSpec.describe GitlabSchema.types['Snippet'] do
:visibility_level, :created_at, :updated_at, :visibility_level, :created_at, :updated_at,
:web_url, :raw_url, :ssh_url_to_repo, :http_url_to_repo, :web_url, :raw_url, :ssh_url_to_repo, :http_url_to_repo,
:notes, :discussions, :user_permissions, :notes, :discussions, :user_permissions,
:description_html, :blob, :blobs] :description_html, :blobs]
expect(described_class).to have_graphql_fields(*expected_fields) expect(described_class).to have_graphql_fields(*expected_fields)
end end
...@@ -133,32 +133,6 @@ RSpec.describe GitlabSchema.types['Snippet'] do ...@@ -133,32 +133,6 @@ RSpec.describe GitlabSchema.types['Snippet'] do
end end
end end
describe '#blob' do
let(:query_blob) { subject.dig('data', 'snippets', 'nodes')[0]['blob'] }
subject { GitlabSchema.execute(snippet_query_for(field: 'blob'), context: { current_user: user }).as_json }
context 'when snippet has repository' do
let!(:snippet) { create(:personal_snippet, :repository, :public, author: user) }
let(:blob) { snippet.blobs.first }
it 'returns the first blob from the repository' do
expect(query_blob['name']).to eq blob.name
expect(query_blob['path']).to eq blob.path
end
end
context 'when snippet does not have a repository' do
let!(:snippet) { create(:personal_snippet, :public, author: user) }
let(:blob) { snippet.blob }
it 'returns SnippetBlob type' do
expect(query_blob['name']).to eq blob.name
expect(query_blob['path']).to eq blob.path
end
end
end
describe '#blobs' do describe '#blobs' do
let_it_be(:snippet) { create(:personal_snippet, :public, author: user) } let_it_be(:snippet) { create(:personal_snippet, :public, author: user) }
......
...@@ -31,7 +31,7 @@ RSpec.describe GitlabSchema.types['SnippetBlobViewer'] do ...@@ -31,7 +31,7 @@ RSpec.describe GitlabSchema.types['SnippetBlobViewer'] do
end end
it 'returns false' do it 'returns false' do
snippet_blob = subject.dig('data', 'snippets', 'edges')[0].dig('node', 'blob') snippet_blob = subject.dig('data', 'snippets', 'edges').first.dig('node', 'blobs', 'nodes').find { |b| b['path'] == blob.path }
expect(snippet_blob['path']).to eq blob.path expect(snippet_blob['path']).to eq blob.path
expect(blob_attribute).to be_nil expect(blob_attribute).to be_nil
...@@ -47,7 +47,8 @@ RSpec.describe GitlabSchema.types['SnippetBlobViewer'] do ...@@ -47,7 +47,8 @@ RSpec.describe GitlabSchema.types['SnippetBlobViewer'] do
snippets(ids: "#{snippet.to_global_id}") { snippets(ids: "#{snippet.to_global_id}") {
edges { edges {
node { node {
blob { blobs {
nodes {
path path
simpleViewer { simpleViewer {
collapsed collapsed
...@@ -57,6 +58,7 @@ RSpec.describe GitlabSchema.types['SnippetBlobViewer'] do ...@@ -57,6 +58,7 @@ RSpec.describe GitlabSchema.types['SnippetBlobViewer'] do
} }
} }
} }
}
) )
end end
...@@ -73,7 +75,8 @@ RSpec.describe GitlabSchema.types['SnippetBlobViewer'] do ...@@ -73,7 +75,8 @@ RSpec.describe GitlabSchema.types['SnippetBlobViewer'] do
snippets(ids: "#{snippet.to_global_id}") { snippets(ids: "#{snippet.to_global_id}") {
edges { edges {
node { node {
blob { blobs {
nodes {
path path
simpleViewer { simpleViewer {
tooLarge tooLarge
...@@ -83,6 +86,7 @@ RSpec.describe GitlabSchema.types['SnippetBlobViewer'] do ...@@ -83,6 +86,7 @@ RSpec.describe GitlabSchema.types['SnippetBlobViewer'] do
} }
} }
} }
}
) )
end end
......
...@@ -22,8 +22,8 @@ RSpec.describe 'Marking all todos done' do ...@@ -22,8 +22,8 @@ RSpec.describe 'Marking all todos done' do
graphql_mutation(:todos_mark_all_done, input, graphql_mutation(:todos_mark_all_done, input,
<<-QL.strip_heredoc <<-QL.strip_heredoc
clientMutationId clientMutationId
todos { id }
errors errors
updatedIds
QL QL
) )
end end
...@@ -40,7 +40,7 @@ RSpec.describe 'Marking all todos done' do ...@@ -40,7 +40,7 @@ RSpec.describe 'Marking all todos done' do
expect(todo3.reload.state).to eq('done') expect(todo3.reload.state).to eq('done')
expect(other_user_todo.reload.state).to eq('pending') expect(other_user_todo.reload.state).to eq('pending')
updated_todo_ids = mutation_response['updatedIds'] updated_todo_ids = mutation_response['todos'].map { |todo| todo['id'] }
expect(updated_todo_ids).to contain_exactly(global_id_of(todo1), global_id_of(todo3)) expect(updated_todo_ids).to contain_exactly(global_id_of(todo1), global_id_of(todo3))
end end
...@@ -52,7 +52,7 @@ RSpec.describe 'Marking all todos done' do ...@@ -52,7 +52,7 @@ RSpec.describe 'Marking all todos done' do
expect(todo3.reload.state).to eq('pending') expect(todo3.reload.state).to eq('pending')
expect(other_user_todo.reload.state).to eq('pending') expect(other_user_todo.reload.state).to eq('pending')
updated_todo_ids = mutation_response['updatedIds'] updated_todo_ids = mutation_response['todos']
expect(updated_todo_ids).to be_empty expect(updated_todo_ids).to be_empty
end end
......
...@@ -22,7 +22,6 @@ RSpec.describe 'Restoring many Todos' do ...@@ -22,7 +22,6 @@ RSpec.describe 'Restoring many Todos' do
<<-QL.strip_heredoc <<-QL.strip_heredoc
clientMutationId clientMutationId
errors errors
updatedIds
todos { todos {
id id
state state
...@@ -44,7 +43,6 @@ RSpec.describe 'Restoring many Todos' do ...@@ -44,7 +43,6 @@ RSpec.describe 'Restoring many Todos' do
expect(mutation_response).to include( expect(mutation_response).to include(
'errors' => be_empty, 'errors' => be_empty,
'updatedIds' => match_array(input_ids),
'todos' => contain_exactly( 'todos' => contain_exactly(
{ 'id' => global_id_of(todo1), 'state' => 'pending' }, { 'id' => global_id_of(todo1), 'state' => 'pending' },
{ 'id' => global_id_of(todo2), 'state' => 'pending' } { 'id' => global_id_of(todo2), 'state' => 'pending' }
......
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