Skip to content

Commit ee56c5f

Browse files
committed
Fixes #37729 - Add version option for deb filter rules
1 parent df7ea59 commit ee56c5f

File tree

9 files changed

+470
-44
lines changed

9 files changed

+470
-44
lines changed

app/controllers/katello/api/v2/debs_controller.rb

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,23 @@ class Api::V2::DebsController < Api::V2::ApiController
1313
def auto_complete(search)
1414
page_size = Katello::Concerns::FilteredAutoCompleteSearch::PAGE_SIZE
1515
debs = Deb.in_repositories(@repositories)
16-
col = ''
17-
case search
18-
when 'name'
19-
col = "#{Deb.table_name}.name"
20-
when 'arch'
21-
col = "#{Deb.table_name}.architecture"
22-
end
23-
debs = debs.where("#{col} ILIKE ?", "#{params[:term]}%").select(col).group(col).order(col).limit(page_size)
24-
render :json => debs.pluck(col)
16+
col = case search
17+
when 'name' then "#{Deb.table_name}.name"
18+
when 'arch' then "#{Deb.table_name}.architecture"
19+
end
20+
return render json: [] if col.blank?
21+
22+
scope = debs.select(col).group(col).order(col).limit(page_size)
23+
scope = scope.where("#{col} ILIKE ?", "%#{params[:term]}%") if params[:term].present?
24+
render json: scope.pluck(Arel.sql(col))
2525
end
2626

2727
def auto_complete_name
2828
auto_complete('name')
2929
end
3030

3131
def auto_complete_arch
32-
auto_complete('architecture')
32+
auto_complete('arch')
3333
end
3434

3535
api :GET, "/debs", N_("List deb packages")
@@ -115,7 +115,11 @@ def find_hosts
115115
end
116116

117117
def find_repositories
118-
@repositories = Repository.readable.where(:id => params[:repoids])
118+
if params[:repoids].present?
119+
@repositories = Repository.readable.where(:id => params[:repoids])
120+
else
121+
@repositories = Repository.readable
122+
end
119123
end
120124

121125
def resource_class

app/models/katello/content_view_deb_filter.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ def query_debs_from_collection(collection, rule)
4545
query_arch = rule.architecture.tr("*", "%")
4646
query = query.where("#{Deb.table_name}.architecture ilike ?", query_arch)
4747
end
48+
if rule.version.present?
49+
query = query.search_version_equal(rule.version)
50+
elsif rule.min_version.present? || rule.max_version.present?
51+
query = query.search_version_range(rule.min_version, rule.max_version)
52+
end
4853
query.default_sort
4954
end
5055
end

app/models/katello/deb.rb

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,16 @@ def self.content_facet_association_class
2929
ContentFacetApplicableDeb
3030
end
3131

32-
def self.search_version_range(min = nil, max = nil)
33-
query = self.all
34-
query = Katello::Util::PackageFilter.new(query, min, Katello::Util::PackageFilter::GREATER_THAN).results if min
35-
query = Katello::Util::PackageFilter.new(query, max, Katello::Util::PackageFilter::LESS_THAN).results if max
32+
scope :search_version_equal, ->(ver) {
33+
where("deb_version_cmp(#{::Katello::Deb.table_name}.version, ?) = 0", ver)
34+
}
35+
36+
scope :search_version_range, ->(min_ver, max_ver) {
37+
query = all
38+
query = query.where("deb_version_cmp(#{::Katello::Deb.table_name}.version, ?) >= 0", min_ver) if min_ver.present?
39+
query = query.where("deb_version_cmp(#{::Katello::Deb.table_name}.version, ?) <= 0", max_ver) if max_ver.present?
3640
query
37-
end
38-
39-
def self.search_version_equal(version)
40-
Katello::Util::PackageFilter.new(self, version, Katello::Util::PackageFilter::EQUAL).results
41-
end
41+
}
4242

4343
def self.total_for_repositories(repos)
4444
self.in_repositories(repos).count
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
require 'katello_test_helper'
2+
3+
module Katello
4+
class Api::V2::ContentViewDebFilterRulesControllerTest < ActionController::TestCase
5+
fixtures :katello_content_view_filters,
6+
:katello_content_view_deb_filter_rules,
7+
:katello_debs
8+
9+
tests Katello::Api::V2::ContentViewFilterRulesController
10+
11+
def models
12+
@filter = katello_content_view_filters(:simple_deb_filter)
13+
@rule = katello_content_view_deb_filter_rules(:deb_test_package)
14+
@rule_other_filter = katello_content_view_deb_filter_rules(:deb_other_filter_rule)
15+
@arch_rule = katello_content_view_deb_filter_rules(:deb_arch_rule)
16+
@deb_one = katello_debs(:one)
17+
end
18+
19+
def permissions
20+
@view_permission = :view_content_views
21+
@create_permission = :create_content_views
22+
@update_permission = :edit_content_views
23+
@destroy_permission = :destroy_content_views
24+
end
25+
26+
def setup
27+
setup_controller_defaults_api
28+
models
29+
permissions
30+
end
31+
32+
def test_index
33+
get :index, params: { content_view_filter_id: @filter.id }
34+
assert_response :success
35+
assert_template 'api/v2/content_view_filter_rules/index'
36+
end
37+
38+
def test_index_protected
39+
allowed_perms = [@view_permission]
40+
denied_perms = [@create_permission, @update_permission, @destroy_permission]
41+
42+
assert_protected_action(:index, allowed_perms, denied_perms) do
43+
get :index, params: { content_view_filter_id: @filter.id }
44+
end
45+
end
46+
47+
def test_create_single_name
48+
post :create, params: { content_view_filter_id: @filter.id,
49+
name: 'debtest', architecture: 'amd64',
50+
version: '2.0' }
51+
assert_response :success
52+
assert_template layout: 'katello/api/v2/layouts/resource'
53+
assert_includes @filter.reload.deb_rules.pluck(:name), 'debtest'
54+
end
55+
56+
def test_create_name_array
57+
post :create, params: { content_view_filter_id: @filter.id,
58+
name: %w(debtest debtest2),
59+
architecture: '',
60+
min_version: '1.0' }
61+
assert_response :success
62+
assert_template layout: 'katello/api/v2/layouts/collection'
63+
names = @filter.reload.deb_rules.map(&:name).uniq
64+
assert_equal %w(archpkg debpkg debtest debtest2).sort, names.sort
65+
end
66+
67+
def test_create_protected
68+
allowed_perms = [@update_permission]
69+
denied_perms = [@view_permission, @create_permission, @destroy_permission]
70+
71+
assert_protected_action(:create, allowed_perms, denied_perms) do
72+
post :create, params: { content_view_filter_id: @filter.id,
73+
name: 'debtest', version: '1.0' }
74+
end
75+
end
76+
77+
def test_show
78+
get :show, params: { content_view_filter_id: @filter.id, id: @arch_rule.id }
79+
assert_response :success
80+
assert_template 'api/v2/content_view_filter_rules/show'
81+
end
82+
83+
def test_mismatched_filter_and_rule
84+
get :show, params: { content_view_filter_id: @filter.id, id: @rule_other_filter.id }
85+
assert_response 404
86+
end
87+
88+
def test_update
89+
put :update, params: { content_view_filter_id: @filter.id,
90+
id: @arch_rule.id,
91+
name: 'updatepkg',
92+
architecture: 'arm64',
93+
max_version: '3.0' }
94+
assert_response :success
95+
assert_equal 'updatepkg', @arch_rule.reload.name
96+
assert_equal 'arm64', @arch_rule.reload.architecture
97+
assert_equal '3.0', @arch_rule.max_version
98+
end
99+
100+
def test_update_protected
101+
allowed_perms = [@update_permission]
102+
denied_perms = [@view_permission, @create_permission, @destroy_permission]
103+
104+
assert_protected_action(:update, allowed_perms, denied_perms) do
105+
put :update, params: { content_view_filter_id: @filter.id,
106+
id: @arch_rule.id, name: 'oops' }
107+
end
108+
end
109+
110+
def test_destroy
111+
delete :destroy, params: { content_view_filter_id: @filter.id, id: @arch_rule.id }
112+
assert_response :success
113+
assert_nil ContentViewDebFilterRule.find_by_id(@arch_rule.id)
114+
end
115+
116+
def test_destroy_protected
117+
allowed_perms = [@update_permission]
118+
denied_perms = [@view_permission, @create_permission, @destroy_permission]
119+
120+
assert_protected_action(:destroy, allowed_perms, denied_perms) do
121+
delete :destroy, params: { content_view_filter_id: @filter.id, id: @arch_rule.id }
122+
end
123+
end
124+
end
125+
end

test/controllers/api/v2/debs_controller_test.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,27 @@ def test_autocomplete_name
9696
assert_includes JSON.parse(response.body), @deb.name
9797
end
9898

99+
def test_autocomplete_name_blank_term
100+
response = get :auto_complete_name, params: { :repoids => [@repo.id], :term => '' }
101+
102+
assert_response :success
103+
assert_includes JSON.parse(response.body), @deb.name
104+
end
105+
106+
def test_autocomplete_arch
107+
response = get :auto_complete_arch, params: { :repoids => [@repo.id], :term => @deb.architecture.first }
108+
109+
assert_response :success
110+
assert_includes JSON.parse(response.body), @deb.architecture
111+
end
112+
113+
def test_autocomplete_arch_blank_term
114+
response = get :auto_complete_arch, params: { :repoids => [@repo.id], :term => '' }
115+
116+
assert_response :success
117+
assert_includes JSON.parse(response.body), @deb.architecture
118+
end
119+
99120
def test_show
100121
get :show, params: { :id => @deb.id }
101122

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
_fixture:
2+
model_class: Katello::ContentViewDebFilterRule
3+
4+
deb_test_package:
5+
name: debpkg
6+
version: 1.0
7+
content_view_filter_id: <%= ActiveRecord::FixtureSet.identify(:simple_deb_filter) %>
8+
created_at: <%= Time.now %>
9+
updated_at: <%= Time.now %>
10+
11+
deb_arch_rule:
12+
name: archpkg
13+
architecture: amd64
14+
min_version: 1.0
15+
content_view_filter_id: <%= ActiveRecord::FixtureSet.identify(:simple_deb_filter) %>
16+
created_at: <%= Time.now %>
17+
updated_at: <%= Time.now %>
18+
19+
deb_other_filter_rule:
20+
name: otherpkg
21+
version: 2.0
22+
content_view_filter_id: <%= ActiveRecord::FixtureSet.identify(:another_deb_filter) %>
23+
created_at: <%= Time.now %>
24+
updated_at: <%= Time.now %>

test/fixtures/models/katello_content_view_filters.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,17 @@ extra_filter:
3333
content_view_id: <%= ActiveRecord::FixtureSet.identify(:acme_default) %>
3434
type: <%= Katello::ContentViewErratumFilter.name %>
3535

36+
simple_deb_filter:
37+
name: Simple Deb Filter
38+
content_view_id: <%= ActiveRecord::FixtureSet.identify(:library_view) %>
39+
type: <%= Katello::ContentViewDebFilter.name %>
40+
41+
populated_deb_filter:
42+
name: Populated Deb Filter
43+
content_view_id: <%= ActiveRecord::FixtureSet.identify(:library_view) %>
44+
type: <%= Katello::ContentViewDebFilter.name %>
45+
46+
another_deb_filter:
47+
name: Another Deb Filter
48+
content_view_id: <%= ActiveRecord::FixtureSet.identify(:library_view) %>
49+
type: <%= Katello::ContentViewDebFilter.name %>

test/models/deb_test.rb

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
require 'katello_test_helper'
2+
3+
module Katello
4+
class DebTestBase < ActiveSupport::TestCase
5+
def setup
6+
@repo = katello_repositories(:debian_10_amd64)
7+
@deb_one = katello_debs(:one)
8+
@deb_two = katello_debs(:two)
9+
@deb_three = katello_debs(:three)
10+
@deb_one_v2 = katello_debs(:one_new)
11+
12+
Deb.any_instance.stubs(:backend_data).returns({})
13+
end
14+
end
15+
16+
class DebTest < DebTestBase
17+
def test_repositories
18+
assert_includes @deb_one.repository_ids, @repo.id
19+
end
20+
21+
def test_create
22+
pulp_id = 'dummy-uuid-999'
23+
assert Deb.create!(pulp_id: pulp_id, name: 'dummy')
24+
assert Deb.find_by_pulp_id(pulp_id)
25+
end
26+
27+
def test_with_identifiers
28+
set = Deb.with_identifiers([@deb_one.id, @deb_two.pulp_id])
29+
assert_equal 2, set.size
30+
assert_includes set, @deb_one
31+
assert_includes set, @deb_two
32+
end
33+
end
34+
35+
class DebVersionSearchTest < DebTestBase
36+
def create_deb(name:, version:, arch: 'amd64')
37+
Deb.create!(
38+
name: name,
39+
version: version,
40+
architecture: arch,
41+
pulp_id: SecureRandom.uuid,
42+
filename: "#{name}_#{version}_#{arch}.deb",
43+
repository_ids: [@repo.id]
44+
)
45+
end
46+
47+
def test_search_version_greater_or_equal
48+
result = Deb.in_repositories(@repo).search_for('version >= 1.1')
49+
assert_includes result, @deb_one_v2
50+
refute_includes result, @deb_one
51+
end
52+
53+
def search_version_less_than
54+
result = Deb.in_repositories(@repo).search_for('version < 1.1')
55+
assert_includes result, @deb_one
56+
refute_includes result, @deb_one_v2
57+
end
58+
59+
def search_version_equal
60+
result = Deb.in_repositories(@repo).search_for('version = 1.0')
61+
assert_includes result, @deb_one
62+
refute_includes result, @deb_one_v2
63+
end
64+
65+
def test_search_with_epoch_handling
66+
deb_epoch_2 = create_deb(name: "epochpkg", version: "2:1.0")
67+
deb_epoch_1 = create_deb(name: "epochpkg", version: "1:1.0")
68+
69+
greater = Deb.in_repositories(@repo).search_for('version > 1:1.0')
70+
assert_includes greater, deb_epoch_2
71+
refute_includes greater, deb_epoch_1
72+
73+
equal = Deb.in_repositories(@repo).search_for('version = 1:1.0')
74+
assert_equal [deb_epoch_1], equal
75+
end
76+
77+
def test_search_range
78+
deb_0_9 = create_deb(name: 'rangepkg', version: '0.9')
79+
deb_1_2 = create_deb(name: 'rangepkg', version: '1.2')
80+
81+
inside = Deb.in_repositories(@repo).search_for('version >= 1.0 AND version <= 1.1')
82+
outside = Deb.in_repositories(@repo).search_for('version < 1.0 OR version > 1.1')
83+
84+
assert_includes inside, @deb_one
85+
assert_includes inside, @deb_one_v2
86+
refute_includes inside, deb_0_9
87+
refute_includes inside, deb_1_2
88+
89+
assert_includes outside, deb_0_9
90+
assert_includes outside, deb_1_2
91+
end
92+
end
93+
end

0 commit comments

Comments
 (0)