Commit 8c6d3c42 authored by Mark Florian's avatar Mark Florian

Merge branch 'bool-auto-fix' into 'master'

Add field hasSolutions for Vulnerability

See merge request gitlab-org/gitlab!48820
parents 5a7cfc87 7efa826c
......@@ -24911,6 +24911,11 @@ type Vulnerability implements Noteable {
last: Int
): VulnerabilityExternalIssueLinkConnection!
"""
Indicates whether there is a solution available for this vulnerability.
"""
hasSolutions: Boolean
"""
GraphQL ID of the vulnerability
"""
......
......@@ -72489,6 +72489,20 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "hasSolutions",
"description": "Indicates whether there is a solution available for this vulnerability.",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "id",
"description": "GraphQL ID of the vulnerability",
......@@ -3748,6 +3748,7 @@ Represents a vulnerability.
| `discussions` | DiscussionConnection! | All discussions on this noteable |
| `dismissedAt` | Time | Timestamp of when the vulnerability state was changed to dismissed |
| `externalIssueLinks` | VulnerabilityExternalIssueLinkConnection! | List of external issue links related to the vulnerability |
| `hasSolutions` | Boolean | Indicates whether there is a solution available for this vulnerability. |
| `id` | ID! | GraphQL ID of the vulnerability |
| `identifiers` | VulnerabilityIdentifier! => Array | Identifiers of the vulnerability. |
| `issueLinks` | VulnerabilityIssueLinkConnection! | List of issue links related to the vulnerability |
......
......@@ -436,7 +436,7 @@ export default {
<template #cell(activity)="{ item }">
<div class="gl-display-flex gl-justify-content-end">
<gl-badge
v-if="item.solutions"
v-if="item.hasSolutions"
v-gl-tooltip
data-testid="vulnerability-solutions-bulb"
variant="neutral"
......
......@@ -23,7 +23,7 @@ query project(
) {
nodes {
...Vulnerability
solutions
hasSolutions
}
pageInfo {
...PageInfo
......
......@@ -74,6 +74,10 @@ module Types
field :dismissed_at, Types::TimeType, null: true,
description: 'Timestamp of when the vulnerability state was changed to dismissed'
field :has_solutions, GraphQL::BOOLEAN_TYPE, null: true,
description: 'Indicates whether there is a solution available for this vulnerability.',
resolver_method: :has_solutions?
def user_notes_count
::Gitlab::Graphql::Aggregations::Vulnerabilities::LazyUserNotesCountAggregate.new(context, object)
end
......@@ -101,5 +105,9 @@ module Types
def project
Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, object.project_id).find
end
def has_solutions?
object.finding&.remediations&.any?
end
end
end
---
title: Add field hasSolutions for Vulnerability GraphQL type
merge_request: 48820
author:
type: added
......@@ -2,7 +2,7 @@ export const generateVulnerabilities = () => [
{
id: 'id_0',
detectedAt: '2020-07-29T15:36:54Z',
solutions: true,
hasSolutions: true,
identifiers: [
{
externalType: 'cve',
......@@ -35,7 +35,7 @@ export const generateVulnerabilities = () => [
{
id: 'id_1',
detectedAt: '2020-07-22T19:31:24Z',
solutions: false,
hasSolutions: false,
identifiers: [
{
externalType: 'gemnasium',
......
......@@ -29,6 +29,7 @@ RSpec.describe GitlabSchema.types['Vulnerability'] do
dismissed_at
notes
external_issue_links
has_solutions
discussions]
end
......@@ -67,4 +68,37 @@ RSpec.describe GitlabSchema.types['Vulnerability'] do
)
end
end
describe 'has_solutions' do
let(:query) do
%(
query {
project(fullPath: "#{project.full_path}") {
name
vulnerabilities {
nodes {
hasSolutions
}
}
}
}
)
end
context 'N+1 queries' do
it 'avoids N+1 database queries' do
pending('See: https://gitlab.com/gitlab-org/gitlab/-/issues/292993')
control_count = ActiveRecord::QueryRecorder.new { GitlabSchema.execute(query, context: { current_user: user }) }.count
create(:vulnerability, :with_remediation, project: project)
create(:vulnerability, :with_remediation, project: project)
expect { GitlabSchema.execute(query, context: { current_user: user }) }.not_to exceed_query_limit(control_count)
result = GitlabSchema.execute(query, context: { current_user: user }).to_h
vulnerability = result.dig('data', 'project', 'vulnerabilities', 'nodes').first
expect(vulnerability['hasSolution']).to be_truthy
end
end
end
end
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