Commit 42c23d9d authored by Justin Zeng's avatar Justin Zeng Committed by Heinrich Lee Yu

Handle and test for different link types in IssueLinksResolver

parent 87864b30
...@@ -11,6 +11,14 @@ module Resolvers ...@@ -11,6 +11,14 @@ module Resolvers
delegate :issue_links, :created_issue_links, to: :object, private: true delegate :issue_links, :created_issue_links, to: :object, private: true
def ready?(**args)
unless valid_link_type?(args)
raise Gitlab::Graphql::Errors::ArgumentError, 'Provide a valid vulnerability issue link type'
end
super
end
def resolve(link_type: nil, **) def resolve(link_type: nil, **)
issue_links_by_link_type(link_type) issue_links_by_link_type(link_type)
end end
...@@ -25,6 +33,17 @@ module Resolvers ...@@ -25,6 +33,17 @@ module Resolvers
issue_links.by_link_type(link_type) issue_links.by_link_type(link_type)
end end
end end
def valid_link_type?(args)
if args[:link_type].class == String
link_type = args[:link_type].downcase
link_types = ::Vulnerabilities::IssueLink.link_types.keys
link_types.include?(link_type)
else
args[:link_type].nil?
end
end
end end
end end
end end
---
title: Test for different link types in IssueLinksResolver and create E2E specs
merge_request: 46297
author: Justin Zeng
type: other
...@@ -5,18 +5,42 @@ require 'spec_helper' ...@@ -5,18 +5,42 @@ require 'spec_helper'
RSpec.describe Resolvers::Vulnerabilities::IssueLinksResolver do RSpec.describe Resolvers::Vulnerabilities::IssueLinksResolver do
include GraphqlHelpers include GraphqlHelpers
let_it_be(:user) { create(:user) }
let_it_be(:vulnerability) { create(:vulnerability) }
subject { resolve(described_class, obj: vulnerability, args: filters, ctx: { current_user: user }) }
describe '#ready?' do
context 'when the link_type filter is given but is not `CREATED` or `RELATED` ' do
context 'when the filter is a string' do
let(:filters) { { link_type: 'some string' } }
it { expect { subject }.to raise_error(Gitlab::Graphql::Errors::ArgumentError, 'Provide a valid vulnerability issue link type') }
end
context 'when the filter is a number' do
let(:filters) { { link_type: 99 } }
it { expect { subject }.to raise_error(Gitlab::Graphql::Errors::ArgumentError), 'Provide a valid vulnerability issue link type' }
end
context 'when the filter is a symbol' do
let(:filters) { { link_type: :CREATED } }
it { expect { subject }.to raise_error(Gitlab::Graphql::Errors::ArgumentError), 'Provide a valid vulnerability issue link type' }
end
end
end
describe '#resolve' do describe '#resolve' do
let_it_be(:user) { create(:user) }
let_it_be(:vulnerability) { create(:vulnerability) }
let_it_be(:related_issue) { create(:vulnerabilities_issue_link, :related, vulnerability: vulnerability) } let_it_be(:related_issue) { create(:vulnerabilities_issue_link, :related, vulnerability: vulnerability) }
let_it_be(:created_issue) { create(:vulnerabilities_issue_link, :created, vulnerability: vulnerability) } let_it_be(:created_issue) { create(:vulnerabilities_issue_link, :created, vulnerability: vulnerability) }
subject { resolve(described_class, obj: vulnerability, args: filters, ctx: { current_user: user }) }
context 'when there is no filter given' do context 'when there is no filter given' do
let(:filters) { {} } let(:filters) { {} }
it { is_expected.to match_array([related_issue, created_issue]) } it { is_expected.to match_array([related_issue, created_issue]) }
it { expect { subject }.not_to raise_error }
end end
context 'when the link_type filter is given' do context 'when the link_type filter is given' do
...@@ -24,12 +48,14 @@ RSpec.describe Resolvers::Vulnerabilities::IssueLinksResolver do ...@@ -24,12 +48,14 @@ RSpec.describe Resolvers::Vulnerabilities::IssueLinksResolver do
let(:filters) { { link_type: 'CREATED' } } let(:filters) { { link_type: 'CREATED' } }
it { is_expected.to match_array([created_issue]) } it { is_expected.to match_array([created_issue]) }
it { expect { subject }.not_to raise_error }
end end
context 'when the filter is `RELATED`' do context 'when the filter is `RELATED`' do
let(:filters) { { link_type: 'RELATED' } } let(:filters) { { link_type: 'RELATED' } }
it { is_expected.to match_array([related_issue]) } it { is_expected.to match_array([related_issue]) }
it { expect { subject }.not_to raise_error }
end end
end end
end end
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'Query.vulnerabilities.issueLinks' do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user, security_dashboard_projects: [project]) }
let_it_be(:vulnerability) { create(:vulnerability, project: project) }
let_it_be(:related_issue) { create(:vulnerabilities_issue_link, :related, vulnerability: vulnerability) }
let_it_be(:created_issue) { create(:vulnerabilities_issue_link, :created, vulnerability: vulnerability) }
before do
project.add_developer(user)
stub_licensed_features(security_dashboard: true)
end
context 'when invalid linkType argument is provided' do
it 'errors with a string' do
query_issue_links('"created"')
expect(graphql_errors).to include(a_hash_including('message' => "Argument 'linkType' on Field 'issueLinks' has an invalid value (\"created\"). Expected type 'VulnerabilityIssueLinkType'."))
end
it 'errors with a number' do
query_issue_links(1)
expect(graphql_errors).to include(a_hash_including('message' => "Argument 'linkType' on Field 'issueLinks' has an invalid value (1). Expected type 'VulnerabilityIssueLinkType'."))
end
it 'errors with lowercased `created`' do
query_issue_links('created')
expect(graphql_errors).to include(a_hash_including('message' => "Argument 'linkType' on Field 'issueLinks' has an invalid value (created). Expected type 'VulnerabilityIssueLinkType'."))
end
it 'errors with lowercased `related`' do
query_issue_links('related')
expect(graphql_errors).to include(a_hash_including('message' => "Argument 'linkType' on Field 'issueLinks' has an invalid value (related). Expected type 'VulnerabilityIssueLinkType'."))
end
end
context 'when valid linkType argument is provided' do
it 'returns a list of VulnerabilityIssueLink with `CREATED` linkType' do
query_issue_links('CREATED')
expect_issue_links_response(created_issue)
end
it 'returns a list of VulnerabilityIssueLink with `RELATED` linkType' do
query_issue_links('RELATED')
expect_issue_links_response(related_issue)
end
end
context 'when no arguments are provided' do
it 'returns a list of all VulnerabilityIssueLink' do
query_issue_links
expect_issue_links_response(related_issue, created_issue)
end
end
def query_issue_links(link_type = nil)
query = graphql_query_for('vulnerabilities', {}, query_graphql_field('nodes', {}, create_fields(link_type)))
post_graphql(query, current_user: user)
end
def create_fields(link_type)
if link_type.nil?
<<~QUERY
issueLinks {
nodes {
id
}
}
QUERY
else
<<~QUERY
issueLinks (linkType: #{link_type}) {
nodes {
id
}
}
QUERY
end
end
def expect_issue_links_response(*issue_links)
actual_issue_links = graphql_data['vulnerabilities']['nodes'].map do |vulnerability|
vulnerability["issueLinks"]["nodes"].map { |issue_link| issue_link['id'] }
end
expected_issue_links = issue_links.map { |issue_link| issue_link.to_global_id.to_s }
expect(actual_issue_links.flatten).to contain_exactly(*expected_issue_links)
expect(graphql_errors).to be_nil
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