Commit d4d854b3 authored by Eugenia Grieff's avatar Eugenia Grieff

Move common argument to new concern

- Add request specs
- Update schema
parent 73866ca7
...@@ -18516,7 +18516,7 @@ type Project { ...@@ -18516,7 +18516,7 @@ type Project {
""" """
requirement( requirement(
""" """
Filter requirements by author username Filter requirements by author username.
""" """
authorUsername: [String!] authorUsername: [String!]
...@@ -18531,17 +18531,17 @@ type Project { ...@@ -18531,17 +18531,17 @@ type Project {
iids: [ID!] iids: [ID!]
""" """
Search query for requirement title Search query for requirement title.
""" """
search: String search: String
""" """
List requirements by sort order List requirements by sort order.
""" """
sort: Sort sort: Sort
""" """
Filter requirements by state Filter requirements by state.
""" """
state: RequirementState state: RequirementState
): Requirement ): Requirement
...@@ -18561,7 +18561,7 @@ type Project { ...@@ -18561,7 +18561,7 @@ type Project {
after: String after: String
""" """
Filter requirements by author username Filter requirements by author username.
""" """
authorUsername: [String!] authorUsername: [String!]
...@@ -18591,17 +18591,17 @@ type Project { ...@@ -18591,17 +18591,17 @@ type Project {
last: Int last: Int
""" """
Search query for requirement title Search query for requirement title.
""" """
search: String search: String
""" """
List requirements by sort order List requirements by sort order.
""" """
sort: Sort sort: Sort
""" """
Filter requirements by state Filter requirements by state.
""" """
state: RequirementState state: RequirementState
): RequirementConnection ): RequirementConnection
......
...@@ -26214,20 +26214,6 @@ ...@@ -26214,20 +26214,6 @@
"description": "Autogenerated input type of ExportRequirements", "description": "Autogenerated input type of ExportRequirements",
"fields": null, "fields": null,
"inputFields": [ "inputFields": [
{
"name": "projectPath",
"description": "Full project path the requirements are associated with.",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
},
"defaultValue": null
},
{ {
"name": "sort", "name": "sort",
"description": "List requirements by sort order.", "description": "List requirements by sort order.",
...@@ -26276,6 +26262,20 @@ ...@@ -26276,6 +26262,20 @@
}, },
"defaultValue": null "defaultValue": null
}, },
{
"name": "projectPath",
"description": "Full project path the requirements are associated with.",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
},
"defaultValue": null
},
{ {
"name": "clientMutationId", "name": "clientMutationId",
"description": "A unique identifier for the client performing the mutation.", "description": "A unique identifier for the client performing the mutation.",
...@@ -53998,66 +53998,66 @@ ...@@ -53998,66 +53998,66 @@
"description": "Find a single requirement", "description": "Find a single requirement",
"args": [ "args": [
{ {
"name": "iid", "name": "sort",
"description": "IID of the requirement, e.g., \"1\"", "description": "List requirements by sort order.",
"type": { "type": {
"kind": "SCALAR", "kind": "ENUM",
"name": "ID", "name": "Sort",
"ofType": null "ofType": null
}, },
"defaultValue": null "defaultValue": null
}, },
{ {
"name": "iids", "name": "state",
"description": "List of IIDs of requirements, e.g., [1, 2]", "description": "Filter requirements by state.",
"type": { "type": {
"kind": "LIST", "kind": "ENUM",
"name": null, "name": "RequirementState",
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null "ofType": null
}
}
}, },
"defaultValue": null "defaultValue": null
}, },
{ {
"name": "sort", "name": "search",
"description": "List requirements by sort order", "description": "Search query for requirement title.",
"type": { "type": {
"kind": "ENUM", "kind": "SCALAR",
"name": "Sort", "name": "String",
"ofType": null "ofType": null
}, },
"defaultValue": null "defaultValue": null
}, },
{ {
"name": "state", "name": "authorUsername",
"description": "Filter requirements by state", "description": "Filter requirements by author username.",
"type": { "type": {
"kind": "ENUM", "kind": "LIST",
"name": "RequirementState", "name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null "ofType": null
}
}
}, },
"defaultValue": null "defaultValue": null
}, },
{ {
"name": "search", "name": "iid",
"description": "Search query for requirement title", "description": "IID of the requirement, e.g., \"1\"",
"type": { "type": {
"kind": "SCALAR", "kind": "SCALAR",
"name": "String", "name": "ID",
"ofType": null "ofType": null
}, },
"defaultValue": null "defaultValue": null
}, },
{ {
"name": "authorUsername", "name": "iids",
"description": "Filter requirements by author username", "description": "List of IIDs of requirements, e.g., [1, 2]",
"type": { "type": {
"kind": "LIST", "kind": "LIST",
"name": null, "name": null,
...@@ -54066,7 +54066,7 @@ ...@@ -54066,7 +54066,7 @@
"name": null, "name": null,
"ofType": { "ofType": {
"kind": "SCALAR", "kind": "SCALAR",
"name": "String", "name": "ID",
"ofType": null "ofType": null
} }
} }
...@@ -54101,66 +54101,66 @@ ...@@ -54101,66 +54101,66 @@
"description": "Find requirements", "description": "Find requirements",
"args": [ "args": [
{ {
"name": "iid", "name": "sort",
"description": "IID of the requirement, e.g., \"1\"", "description": "List requirements by sort order.",
"type": { "type": {
"kind": "SCALAR", "kind": "ENUM",
"name": "ID", "name": "Sort",
"ofType": null "ofType": null
}, },
"defaultValue": null "defaultValue": null
}, },
{ {
"name": "iids", "name": "state",
"description": "List of IIDs of requirements, e.g., [1, 2]", "description": "Filter requirements by state.",
"type": { "type": {
"kind": "LIST", "kind": "ENUM",
"name": null, "name": "RequirementState",
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null "ofType": null
}
}
}, },
"defaultValue": null "defaultValue": null
}, },
{ {
"name": "sort", "name": "search",
"description": "List requirements by sort order", "description": "Search query for requirement title.",
"type": { "type": {
"kind": "ENUM", "kind": "SCALAR",
"name": "Sort", "name": "String",
"ofType": null "ofType": null
}, },
"defaultValue": null "defaultValue": null
}, },
{ {
"name": "state", "name": "authorUsername",
"description": "Filter requirements by state", "description": "Filter requirements by author username.",
"type": { "type": {
"kind": "ENUM", "kind": "LIST",
"name": "RequirementState", "name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null "ofType": null
}
}
}, },
"defaultValue": null "defaultValue": null
}, },
{ {
"name": "search", "name": "iid",
"description": "Search query for requirement title", "description": "IID of the requirement, e.g., \"1\"",
"type": { "type": {
"kind": "SCALAR", "kind": "SCALAR",
"name": "String", "name": "ID",
"ofType": null "ofType": null
}, },
"defaultValue": null "defaultValue": null
}, },
{ {
"name": "authorUsername", "name": "iids",
"description": "Filter requirements by author username", "description": "List of IIDs of requirements, e.g., [1, 2]",
"type": { "type": {
"kind": "LIST", "kind": "LIST",
"name": null, "name": null,
...@@ -54169,7 +54169,7 @@ ...@@ -54169,7 +54169,7 @@
"name": null, "name": null,
"ofType": { "ofType": {
"kind": "SCALAR", "kind": "SCALAR",
"name": "String", "name": "ID",
"ofType": null "ofType": null
} }
} }
...@@ -4,6 +4,7 @@ module Mutations ...@@ -4,6 +4,7 @@ module Mutations
module RequirementsManagement module RequirementsManagement
class ExportRequirements < BaseMutation class ExportRequirements < BaseMutation
include ResolvesProject include ResolvesProject
include CommonRequirementArguments
graphql_name 'ExportRequirements' graphql_name 'ExportRequirements'
...@@ -13,22 +14,6 @@ module Mutations ...@@ -13,22 +14,6 @@ module Mutations
required: true, required: true,
description: 'Full project path the requirements are associated with.' description: 'Full project path the requirements are associated with.'
argument :sort, Types::SortEnum,
required: false,
description: 'List requirements by sort order.'
argument :state, Types::RequirementsManagement::RequirementStateEnum,
required: false,
description: 'Filter requirements by state.'
argument :search, GraphQL::STRING_TYPE,
required: false,
description: 'Search query for requirement title.'
argument :author_username, [GraphQL::STRING_TYPE],
required: false,
description: 'Filter requirements by author username.'
def resolve(args) def resolve(args)
project_path = args.delete(:project_path) project_path = args.delete(:project_path)
project = authorized_find!(full_path: project_path) project = authorized_find!(full_path: project_path)
......
# frozen_string_literal: true
module CommonRequirementArguments
extend ActiveSupport::Concern
included do
argument :sort, Types::SortEnum,
required: false,
description: 'List requirements by sort order.'
argument :state, Types::RequirementsManagement::RequirementStateEnum,
required: false,
description: 'Filter requirements by state.'
argument :search, GraphQL::STRING_TYPE,
required: false,
description: 'Search query for requirement title.'
argument :author_username, [GraphQL::STRING_TYPE],
required: false,
description: 'Filter requirements by author username.'
end
end
...@@ -4,6 +4,7 @@ module Resolvers ...@@ -4,6 +4,7 @@ module Resolvers
module RequirementsManagement module RequirementsManagement
class RequirementsResolver < BaseResolver class RequirementsResolver < BaseResolver
include LooksAhead include LooksAhead
include CommonRequirementArguments
type ::Types::RequirementsManagement::RequirementType.connection_type, null: true type ::Types::RequirementsManagement::RequirementType.connection_type, null: true
...@@ -15,22 +16,6 @@ module Resolvers ...@@ -15,22 +16,6 @@ module Resolvers
required: false, required: false,
description: 'List of IIDs of requirements, e.g., [1, 2]' description: 'List of IIDs of requirements, e.g., [1, 2]'
argument :sort, Types::SortEnum,
required: false,
description: 'List requirements by sort order'
argument :state, Types::RequirementsManagement::RequirementStateEnum,
required: false,
description: 'Filter requirements by state'
argument :search, GraphQL::STRING_TYPE,
required: false,
description: 'Search query for requirement title'
argument :author_username, [GraphQL::STRING_TYPE],
required: false,
description: 'Filter requirements by author username'
def resolve_with_lookahead(**args) def resolve_with_lookahead(**args)
# The project could have been loaded in batch by `BatchLoader`. # The project could have been loaded in batch by `BatchLoader`.
# At this point we need the `id` of the project to query for issues, so # At this point we need the `id` of the project to query for issues, so
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'Exporting Requirements' do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
let_it_be(:project) { create(:project) }
let_it_be(:requirement) { create(:requirement, project: project) }
let(:attributes) { { state: 'OPENED', author_username: [current_user.username], sort: :CREATED_ASC, search: requirement.title } }
let(:mutation) do
params = { project_path: project.full_path }.merge(attributes)
graphql_mutation(:export_requirements, params)
end
def mutation_response
graphql_mutation_response(:export_requirements)
end
shared_examples 'requirements export fails' do
it_behaves_like 'a mutation that returns a top-level access error'
it 'does not schedule export job' do
expect(IssuableExportCsvWorker).not_to receive(:perform_async)
end
end
context 'when the user does not have permission' do
before do
stub_licensed_features(requirements: true)
end
it_behaves_like 'requirements export fails'
end
context 'when the user has permission' do
before do
project.add_reporter(current_user)
end
context 'when requirements are disabled' do
before do
stub_licensed_features(requirements: false)
end
it_behaves_like 'requirements export fails'
end
context 'when requirements are enabled' do
before do
stub_licensed_features(requirements: true)
end
it 'schedules job to export requirements', :aggregate_failures do
args = {
author_username: [current_user.username],
search: requirement.title,
sort: :created_asc,
state: 'opened'
}
expect(IssuableExportCsvWorker)
.to receive(:perform_async).with(:requirement, current_user.id, project.id, args)
post_graphql_mutation(mutation, current_user: current_user)
expect(mutation_response['errors']).to be_empty
end
end
end
end
...@@ -6,7 +6,7 @@ RSpec.shared_examples 'resource with requirement permissions' do ...@@ -6,7 +6,7 @@ RSpec.shared_examples 'resource with requirement permissions' do
let(:all_permissions) do let(:all_permissions) do
[:read_requirement, :create_requirement, :admin_requirement, [:read_requirement, :create_requirement, :admin_requirement,
:update_requirement, :destroy_requirement, :update_requirement, :destroy_requirement,
:create_requirement_test_report] :create_requirement_test_report, :export_requirements]
end end
let(:manage_permissions) { all_permissions - [:destroy_requirement] } let(:manage_permissions) { all_permissions - [:destroy_requirement] }
......
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