Commit a11a84ec authored by Natalia Tepluhina's avatar Natalia Tepluhina

Merge branch '235676-it-s-hard-to-add-a-project-to-the-instance-security-dashboard' into 'master'

Search by namespace in Security Dashboard

See merge request gitlab-org/gitlab!41191
parents 0286ff19 9c61110c
......@@ -16,6 +16,10 @@ module Resolvers
required: false,
description: 'Filter projects by IDs'
argument :search_namespaces, GraphQL::BOOLEAN_TYPE,
required: false,
description: 'Include namespace in project search'
def resolve(**args)
ProjectsFinder
.new(current_user: current_user, params: project_finder_params(args), project_ids_relation: parse_gids(args[:ids]))
......@@ -28,7 +32,8 @@ module Resolvers
{
without_deleted: true,
non_public: params[:membership],
search: params[:search]
search: params[:search],
search_namespaces: params[:search_namespaces]
}.compact
end
......
......@@ -14048,6 +14048,11 @@ type Query {
Search query for project name, path, or description
"""
search: String
"""
Include namespace in project search
"""
searchNamespaces: Boolean
): ProjectConnection
"""
......
......@@ -41150,6 +41150,16 @@
},
"defaultValue": null
},
{
"name": "searchNamespaces",
"description": "Include namespace in project search",
"type": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
},
"defaultValue": null
},
{
"name": "after",
"description": "Returns the elements in the list that come after the specified cursor.",
......@@ -222,6 +222,7 @@ export default {
search: searchQuery,
first: this.$options.PROJECTS_PER_PAGE,
after: pageInfo.endCursor,
searchNamespaces: true,
},
});
},
......
#import "~/graphql_shared/fragments/pageInfo.fragment.graphql"
#import "ee/security_dashboard/graphql/project.fragment.graphql"
query getProjects($search: String!, $after: String = "", $first: Int!) {
projects(search: $search, after: $after, first: $first, membership: true) {
query getProjects(
$search: String!
$after: String = ""
$first: Int!
$searchNamespaces: Boolean = false
) {
projects(
search: $search
after: $after
first: $first
membership: true
searchNamespaces: $searchNamespaces
) {
nodes {
...Project
}
......
---
title: Search projects by namespace from Global Security Dashboard
merge_request: 41191
author:
type: changed
......@@ -86,6 +86,7 @@ describe('Project Manager component', () => {
search: 'test',
first: wrapper.vm.$options.PROJECTS_PER_PAGE,
after: '',
searchNamespaces: true,
},
});
});
......
......@@ -8,10 +8,15 @@ RSpec.describe Resolvers::ProjectsResolver do
describe '#resolve' do
subject { resolve(described_class, obj: nil, args: filters, ctx: { current_user: current_user }) }
let_it_be(:group) { create(:group, name: 'public-group') }
let_it_be(:private_group) { create(:group, name: 'private-group') }
let_it_be(:project) { create(:project, :public) }
let_it_be(:other_project) { create(:project, :public) }
let_it_be(:group_project) { create(:project, :public, group: group) }
let_it_be(:private_project) { create(:project, :private) }
let_it_be(:other_private_project) { create(:project, :private) }
let_it_be(:other_private_project) { create(:project, :private) }
let_it_be(:private_group_project) { create(:project, :private, group: private_group) }
let_it_be(:user) { create(:user) }
......@@ -20,6 +25,7 @@ RSpec.describe Resolvers::ProjectsResolver do
before_all do
project.add_developer(user)
private_project.add_developer(user)
private_group.add_developer(user)
end
context 'when user is not logged in' do
......@@ -27,7 +33,7 @@ RSpec.describe Resolvers::ProjectsResolver do
context 'when no filters are applied' do
it 'returns all public projects' do
is_expected.to contain_exactly(project, other_project)
is_expected.to contain_exactly(project, other_project, group_project)
end
context 'when search filter is provided' do
......@@ -45,6 +51,22 @@ RSpec.describe Resolvers::ProjectsResolver do
is_expected.to be_empty
end
end
context 'when searchNamespaces filter is provided' do
let(:filters) { { search: 'group', search_namespaces: true } }
it 'returns projects in a matching namespace' do
is_expected.to contain_exactly(group_project)
end
end
context 'when searchNamespaces filter false' do
let(:filters) { { search: 'group', search_namespaces: false } }
it 'returns ignores namespace matches' do
is_expected.to be_empty
end
end
end
end
......@@ -53,7 +75,7 @@ RSpec.describe Resolvers::ProjectsResolver do
context 'when no filters are applied' do
it 'returns all visible projects for the user' do
is_expected.to contain_exactly(project, other_project, private_project)
is_expected.to contain_exactly(project, other_project, group_project, private_project, private_group_project)
end
context 'when search filter is provided' do
......@@ -68,7 +90,23 @@ RSpec.describe Resolvers::ProjectsResolver do
let(:filters) { { membership: true } }
it 'returns projects that user is member of' do
is_expected.to contain_exactly(project, private_project)
is_expected.to contain_exactly(project, private_project, private_group_project)
end
end
context 'when searchNamespaces filter is provided' do
let(:filters) { { search: 'group', search_namespaces: true } }
it 'returns projects from matching group' do
is_expected.to contain_exactly(group_project, private_group_project)
end
end
context 'when searchNamespaces filter false' do
let(:filters) { { search: 'group', search_namespaces: false } }
it 'returns ignores namespace matches' do
is_expected.to be_empty
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