Skip to content

Commit

Permalink
Merge pull request RedHatInsights#927 from skateman/gql-tags-filter
Browse files Browse the repository at this point in the history
feat(GraphQL): RHICOMPL-2037 allow filtering results by tags
  • Loading branch information
skateman authored Aug 3, 2021
2 parents 42d71e8 + 7c2fa28 commit 9fe338e
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 11 deletions.
10 changes: 3 additions & 7 deletions app/controllers/concerns/collection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ def resolve_collection
end

def filter_by_tags(data)
return data unless tags_supported? && params[:tags]&.any?
unless TagFiltering.tags_supported?(resource) && params[:tags]&.any?
return data
end

tags = parse_tags(params[:tags])
data.where('tags @> ?', tags.to_json)
Expand All @@ -31,11 +33,5 @@ def sort(data)

data.order(build_order_by(data.klass, params[:sort_by]))
end

private

def tags_supported?
resource.column_names.include?('tags')
end
end
end
8 changes: 5 additions & 3 deletions app/controllers/concerns/metadata.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ def set_headers
end

# This is part of a JSON schema, no need for strict metrics
# rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/MethodLength
def metadata(opts = {})
opts[:total] ||= resolve_collection.count
Expand All @@ -22,14 +21,13 @@ def metadata(opts = {})
meta: {
total: opts[:total],
search: params[:search],
tags: tags_supported? ? params.fetch(:tags, []) : nil,
tags: tags,
limit: pagination_limit,
offset: pagination_offset
}.compact,
links: links(last_offset(opts[:total]))
}
end
# rubocop:enable Metrics/AbcSize
# rubocop:enable Metrics/MethodLength

def links(last_offset)
Expand Down Expand Up @@ -89,5 +87,9 @@ def meta_link(other_params = {})
link_params = base_link_params.merge(other_params).compact
"#{base_link_url}?#{link_params.to_query}"
end

def tags
TagFiltering.tags_supported?(resource) ? params.fetch(:tags, []) : nil
end
end
end
4 changes: 4 additions & 0 deletions app/controllers/concerns/tag_filtering.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,8 @@ def decode_value(str)
.scrub
end
end

def self.tags_supported?(resource)
resource.column_names.include?('tags')
end
end
22 changes: 21 additions & 1 deletion app/graphql/resolvers/concerns/collection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,18 @@ module Collection
extend ActiveSupport::Concern

include Sorting
include TagFiltering

included do
type ["Types::#{self::MODEL_CLASS}".safe_constantize], null: false
argument :search, String, 'Search query', required: false
argument :limit, Integer, 'Pagination limit', required: false
argument :offset, Integer, 'Pagination offset', required: false
argument :sort_by, [String], 'Sort results', required: false

if TagFiltering.tags_supported?(self::MODEL_CLASS)
argument :tags, [String], 'Filter by tags', required: false
end
end

def resolve(**kwargs)
Expand All @@ -24,12 +29,16 @@ def resolve(**kwargs)

private

def filter_list(search: nil, sort_by: nil, offset: nil, limit: nil)
def filter_list(
search: nil, sort_by: nil, tags: nil, offset: nil, limit: nil
)
filters = []
filters << search_filter(search: search) if search.present?

filters << sort_filter(sort_by: sort_by) if sort_by.present?

filters << tags_filter(tags: tags) if permit_tags?(tags)

if offset.present? || limit.present?
filters << pagination_filter(offset: offset, limit: limit)
end
Expand Down Expand Up @@ -63,13 +72,24 @@ def sort_filter(sort_by:)
end
end

def tags_filter(tags:)
lambda do |scope|
tags = parse_tags(tags)
scope.where('tags @> ?', tags.to_json)
end
end

def model_class
self.class::MODEL_CLASS
end

def authorized_scope
Pundit.policy_scope(context[:current_user], model_class)
end

def permit_tags?(tags)
TagFiltering.tags_supported?(model_class) && tags.present?
end
end
end
end
5 changes: 5 additions & 0 deletions app/graphql/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,11 @@ type Query implements Node {
Sort results
"""
sortBy: [String!]

"""
Filter by tags
"""
tags: [String!]
): SystemConnection!
testResult(
"""
Expand Down
33 changes: 33 additions & 0 deletions test/graphql/queries/system_query_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,39 @@ class SystemQueryTest < ActiveSupport::TestCase
assert_equal node['tags'], [TAG]
end

should 'allow filtering by tags' do
TAG = { 'namespace' => 'foo', 'key' => 'bar', 'value' => 'baz' }.freeze
query = <<-GRAPHQL
query getSystems($tags: [String!]){
systems(tags: $tags) {
edges {
node {
id
name
}
}
}
}
GRAPHQL

WHost.find(@host1.id).update(
tags: [{ namespace: 'foo', key: 'bar', value: 'baz' }]
)
setup_two_hosts

result = Schema.execute(
query,
variables: {
tags: ['foo/bar=baz']
},
context: { current_user: @user }
)

nodes = result['data']['systems']['edges']
assert_equal(nodes.count, 1)
assert_equal nodes.first['node']['id'], @host1.id
end

test 'query children profile only returns profiles owned by host' do
query = <<-GRAPHQL
query getSystems {
Expand Down

0 comments on commit 9fe338e

Please sign in to comment.