Commit 098fa21c authored by Dmytro Zaporozhets (DZ)'s avatar Dmytro Zaporozhets (DZ)

Merge branch 'issue_224614-allow_filter_requirements_by_status' into 'master'

Allow to filter requirements by status on GraphQL

See merge request gitlab-org/gitlab!53767
parents e23cf8b6 bb8560df
......@@ -20289,6 +20289,11 @@ type Project {
"""
iids: [ID!]
"""
The state of latest requirement test report.
"""
lastTestReportState: TestReportState
"""
Search query for requirement title.
"""
......@@ -20349,6 +20354,11 @@ type Project {
"""
last: Int
"""
The state of latest requirement test report.
"""
lastTestReportState: TestReportState
"""
Search query for requirement title.
"""
......
......@@ -58823,6 +58823,16 @@
}
},
"defaultValue": null
},
{
"name": "lastTestReportState",
"description": "The state of latest requirement test report.",
"type": {
"kind": "ENUM",
"name": "TestReportState",
"ofType": null
},
"defaultValue": null
}
],
"type": {
......@@ -58927,6 +58937,16 @@
},
"defaultValue": null
},
{
"name": "lastTestReportState",
"description": "The state of latest requirement test report.",
"type": {
"kind": "ENUM",
"name": "TestReportState",
"ofType": null
},
"defaultValue": null
},
{
"name": "after",
"description": "Returns the elements in the list that come after the specified cursor.",
......@@ -22,6 +22,7 @@ module RequirementsManagement
items = by_iid(items)
items = by_author(items)
items = by_search(items)
items = by_last_test_report_state(items)
sort(items)
end
......@@ -58,6 +59,12 @@ module RequirementsManagement
items.with_author(authors)
end
def by_last_test_report_state(items)
return items unless params[:last_test_report_state]
items.with_last_test_report_state(params[:last_test_report_state])
end
def get_authors(username_param)
# Save a DB hit if the current_user is the only author, or there are none.
return current_user if [username_param].flatten == [current_user&.username]
......
......@@ -16,6 +16,10 @@ module Resolvers
required: false,
description: 'List of IIDs of requirements, e.g., [1, 2].'
argument :last_test_report_state, ::Types::RequirementsManagement::TestReportStateEnum,
required: false,
description: 'The state of latest requirement test report.'
def resolve_with_lookahead(**args)
# 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
......
......@@ -37,6 +37,22 @@ module RequirementsManagement
scope :with_author, -> (user) { where(author: user) }
scope :counts_by_state, -> { group(:state).count }
# Used to filter requirements by latest test report state
scope :include_last_test_report_with_state, -> do
joins(
"INNER JOIN LATERAL (
SELECT DISTINCT ON (requirement_id) requirement_id, state
FROM requirements_management_test_reports
WHERE requirement_id = requirements.id
ORDER BY requirement_id, created_at DESC LIMIT 1
) AS test_reports ON true"
)
end
scope :with_last_test_report_state, -> (state) do
include_last_test_report_with_state.where( test_reports: { state: state } )
end
class << self
# Searches for records with a matching title.
#
......
---
title: Allow to filter requirements by latest requirement test report status on GraphQL
merge_request: 53767
author:
type: added
......@@ -51,6 +51,19 @@ RSpec.describe RequirementsManagement::RequirementsFinder do
end
end
context 'when last_test_report_state is set' do
let(:params) { { project_id: project.id, last_test_report_state: 'passed' } }
it 'returns matched requirements' do
create(:test_report, state: :passed)
create(:test_report, requirement: requirement1, state: :failed)
create(:test_report, requirement: requirement1, state: :passed)
create(:test_report, requirement: requirement3, state: :passed)
is_expected.to match_array([requirement1, requirement3])
end
end
context 'when user can not read requirements in the project' do
let(:user) { create(:user) }
let(:params) { { project_id: project.id } }
......
......@@ -42,6 +42,15 @@ RSpec.describe Resolvers::RequirementsManagement::RequirementsResolver do
expect(resolve_requirements(iids: [requirement1.iid, requirement3.iid])).to contain_exactly(requirement1, requirement3)
end
it 'filters by last test report state' do
create(:test_report, state: :failed)
create(:test_report, requirement: requirement1, state: :passed)
create(:test_report, requirement: requirement1, state: :failed)
create(:test_report, requirement: requirement3, state: :failed)
expect(resolve_requirements(last_test_report_state: 'failed')).to contain_exactly(requirement1, requirement3)
end
describe 'sorting' do
context 'when sorting by created_at' do
it 'sorts requirements ascending' do
......
......@@ -76,6 +76,34 @@ RSpec.describe RequirementsManagement::Requirement do
it { is_expected.to contain_exactly(requirement_one) }
end
end
describe '.with_last_test_report_state' do
let_it_be(:requirement1) { create(:requirement) }
let_it_be(:requirement2) { create(:requirement) }
let_it_be(:requirement3) { create(:requirement) }
before do
create(:test_report, requirement: requirement1, state: :passed)
create(:test_report, requirement: requirement1, state: :failed)
create(:test_report, requirement: requirement2, state: :failed)
create(:test_report, requirement: requirement2, state: :passed)
create(:test_report, requirement: requirement3, state: :passed)
end
subject { described_class.with_last_test_report_state(state) }
context 'for passed state' do
let(:state) { 'passed' }
it { is_expected.to contain_exactly(requirement2, requirement3) }
end
context 'for failed state' do
let(:state) { 'failed' }
it { is_expected.to contain_exactly(requirement1) }
end
end
end
describe '#last_test_report_state' do
......
......@@ -95,6 +95,10 @@ RSpec.describe 'getting a requirement list for a project' do
let_it_be(:requirement2) { create(:requirement, project: filter_project, author: other_user, title: 'something about kubernetes') }
before do
create(:test_report, requirement: requirement1, state: :failed)
create(:test_report, requirement: requirement1, state: :passed)
create(:test_report, requirement: requirement2, state: :failed)
post_graphql(query, current_user: current_user)
end
......@@ -156,6 +160,16 @@ RSpec.describe 'getting a requirement list for a project' do
match_single_result(requirement2)
end
end
context 'when given lastTestReportState' do
let(:params) { '(lastTestReportState: PASSED)' }
it 'returns filtered requirements' do
expect(graphql_errors).to be_nil
match_single_result(requirement1)
end
end
end
describe 'sorting and pagination' do
......
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