foreman_scc_manager 1.8.9 → 1.8.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ab78f155bda869b47a6124ada7ebcdf9d067c6173c400dfd9c052c70227695f9
4
- data.tar.gz: '009d1c1db82b1c52e4e0ab47ebdb1769dbb4ea0e71fb6a2a0b5b26fff5b0cb41'
3
+ metadata.gz: 4d5ff33d39add7e5f2977ff1a48e4cf80ff7dbdf2975362c8c53c67a3f7259a7
4
+ data.tar.gz: aeefb0d7ef8ea9d83bd617335781dadf90c5f17eea8ae5bc1322b6659460bdfe
5
5
  SHA512:
6
- metadata.gz: da25af4b803899a68ef9b3fae9646901437051d5b69dd4b5c588cca5e0018ea0b797d32255ed4dc5ba6ccb5044a119c2d712bb3b35905aeb231182145f910878
7
- data.tar.gz: 15b7aa5a3f7a05e3c517aa6aa41fcef1c9bee3fb00d5f49405166264d21a7857fc348940c06a0279d88330d29b7480e90d2f3e32025ee2bcba95c1acf84f1c7b
6
+ metadata.gz: 6016a5bec42de9c7a09fc3b03267ff53f48e5ad9f065d367faf599f2a36dc7fa5060ce20555ef5d92c986cb333c051989603fdbbf98843c2c7a51b5fd7cbcc64
7
+ data.tar.gz: 0ccb001c57fcdedb3a343878f033761a854349e1f1a66a38cd0183b2b286e7b70beb576ce067803452122ffe4480fb055705d5ad46bcda170700e69a894a37b9
data/README.md CHANGED
@@ -1,13 +1,20 @@
1
- [![Build Status master](https://travis-ci.org/ATIX-AG/foreman_scc_manager.svg?branch=master)](https://travis-ci.org/ATIX-AG/foreman_scc_manager)
1
+ ![Rubocop](https://github.com/ATIX-AG/foreman_scc_manager/actions/workflows/rubocop.yaml/badge.svg)
2
+ ![Unit Tests](https://github.com/ATIX-AG/foreman_scc_manager/actions/workflows/unit_tests.yaml/badge.svg)
3
+ [![Gem Version](https://badge.fury.io/rb/foreman_scc_manager.svg)](https://badge.fury.io/rb/foreman_scc_manager)
2
4
 
3
- # ForemanSccManager
5
+ # Foreman SCC Manager
4
6
 
5
- Foreman plugin to sync SUSE Customer Center products and repositories into Katello
7
+ Foreman plugin to sync SUSE Customer Center products and repositories into Katello.
6
8
 
7
9
  ## Installation
8
10
 
9
- See [How_to_Install_a_Plugin](http://projects.theforeman.org/projects/foreman/wiki/How_to_Install_a_Plugin)
10
- for how to install Foreman plugins
11
+ This plugin installation is not supported by foreman-installer and has to be installed manually:
12
+
13
+ ```sh
14
+ yum install tfm-rubygem-foreman_scc_manager
15
+
16
+ foreman-installer
17
+ ```
11
18
 
12
19
  ## Compatibility
13
20
 
@@ -27,10 +34,12 @@ for how to install Foreman plugins
27
34
  | 1.15 | 3.4 | ~> 1.1.0 |
28
35
 
29
36
  ## Documentation
30
- The plugin documentation can be found at https://docs.orcharhino.com/sources/management_ui/the_content_menu/suse_subscriptions.html.
31
37
 
32
- A Hammer CLI extension is available for this plugin:
33
- https://github.com/ATIX-AG/hammer-cli-foreman-scc-manager
38
+ [Plugin documentation](https://docs.orcharhino.com/or/docs/sources/usage_guides/managing_sles_systems_guide.html#mssg_installing_the_scc_manager_plugin)
39
+
40
+ ## Hammer CLI Extension
41
+
42
+ [Hammer CLI for Foreman SCC Manager](https://github.com/ATIX-AG/hammer-cli-foreman-scc-manager)
34
43
 
35
44
  ## Contributing
36
45
 
@@ -38,7 +47,7 @@ Fork and send a Pull Request. Thanks!
38
47
 
39
48
  ## Copyright
40
49
 
41
- Copyright (c) 2021 ATIX AG - http://www.atix.de
50
+ Copyright (c) 2021 ATIX AG - https://atix.de
42
51
 
43
52
  This program is free software: you can redistribute it and/or modify
44
53
  it under the terms of the GNU General Public License as published by
@@ -52,4 +61,3 @@ GNU General Public License for more details.
52
61
 
53
62
  You should have received a copy of the GNU General Public License
54
63
  along with this program. If not, see <http://www.gnu.org/licenses/>.
55
-
data/Rakefile CHANGED
@@ -35,13 +35,9 @@ end
35
35
 
36
36
  task default: :test
37
37
 
38
- begin
39
- require 'rubocop/rake_task'
40
- RuboCop::RakeTask.new
41
- rescue StandardError => _e
42
- puts 'Rubocop not loaded.'
43
- end
44
-
45
- task :default do
46
- Rake::Task['rubocop'].execute
38
+ class ForemanSccManager::Engine
39
+ def self.root
40
+ File.expand_path('__dir__')
41
+ end
47
42
  end
43
+ import 'lib/tasks/rubocop.rake'
@@ -12,11 +12,22 @@ module Api
12
12
 
13
13
  before_action :find_resource, :only => [:show, :subscribe]
14
14
 
15
- api :GET, '/scc_accounts/:scc_account_id/scc_products/', N_('List all products for scc_account')
15
+ def metadata_subtotal
16
+ if @scc_products.present?
17
+ @scc_products.count
18
+ else
19
+ super
20
+ end
21
+ end
22
+
23
+ api :GET, '/scc_accounts/:scc_account_id/scc_products/', N_('List products for an scc_account')
16
24
  param :scc_account_id, :identifier_dottable, :required => true
25
+ param :subscribed_only, :bool, :required => false, :desc => N_('Show subscribed products only')
17
26
  param_group :search_and_pagination, ::Api::V2::BaseController
27
+
18
28
  def index
19
29
  scope = resource_scope
30
+ scope = scope.where.not(:product_id => nil) if ::Foreman::Cast.to_bool(params[:subscribed_only])
20
31
  scope = scope.where(:organization => params[:organization_id]) if params[:organization_id].present?
21
32
  @scc_products = scope.search_for(params[:search], :order => params[:order]).paginate(:page => params[:page])
22
33
  end
@@ -47,8 +58,8 @@ module Api
47
58
  private
48
59
 
49
60
  def find_resource
50
- @scc_account = ::SccAccount.find_by!(id: params[:scc_account_id])
51
- @scc_product = @scc_account.scc_products.find_by!(id: params[:id])
61
+ @scc_account = ::SccAccount.find(params[:scc_account_id])
62
+ @scc_product = @scc_account.scc_products.find(params[:id])
52
63
  end
53
64
 
54
65
  def action_permission
@@ -2,7 +2,7 @@ class SccAccountsController < ApplicationController
2
2
  helper_method :scc_filtered_products
3
3
  before_action :find_organization
4
4
  before_action :find_resource, only: %i[show edit update destroy sync bulk_subscribe]
5
- before_action :find_available_gpg_keys, only: %i[new edit]
5
+ before_action :find_available_gpg_keys, only: %i[new edit update create]
6
6
  include Foreman::Controller::AutoCompleteSearch
7
7
 
8
8
  # GET /scc_accounts
@@ -37,7 +37,7 @@ class SccAccountsController < ApplicationController
37
37
  # POST /scc_accounts/test_connection
38
38
  def test_connection
39
39
  @scc_account = SccAccount.new(scc_account_params)
40
- @scc_account.password = SccAccount.find_by!(id: params[:scc_account_id]).password if params[:scc_account_id].present? && scc_account_params[:password].empty?
40
+ @scc_account.password = SccAccount.find(params[:scc_account_id]).password if params[:scc_account_id].present? && scc_account_params[:password].empty?
41
41
  respond_to do |format|
42
42
  if @scc_account.test_connection
43
43
  format.json { render json: nil, status: :ok }
@@ -101,12 +101,16 @@ class SccAccountsController < ApplicationController
101
101
 
102
102
  def find_available_gpg_keys
103
103
  @scc_account ? org = @scc_account.organization : org = @organization
104
- @selectable_gpg_keys = ::Katello::GpgKey.where(organization: org).collect { |p| [p.name, p.id] }.unshift ['None', nil]
104
+ if ::Katello.const_defined?(:ContentCredential)
105
+ @selectable_gpg_keys = ::Katello::ContentCredential.where(organization: org).collect { |p| [p.name, p.id] }.unshift ['None', nil]
106
+ else
107
+ @selectable_gpg_keys = ::Katello::GpgKey.where(organization: org).collect { |p| [p.name, p.id] }.unshift ['None', nil]
108
+ end
105
109
  end
106
110
 
107
111
  def find_organization
108
112
  @organization = Organization.current
109
- redirect_to '/select_organization?toState=' + request.path unless @organization
113
+ redirect_to "/select_organization?toState=#{request.path}" unless @organization
110
114
  end
111
115
 
112
116
  # Use callbacks to share common setup or constraints between actions.
@@ -54,7 +54,11 @@ module Actions
54
54
  def create_sub_plans
55
55
  product = ::Katello::Product.new
56
56
  product.name = input[:product_name]
57
- product.gpg_key = ::Katello::GpgKey.find_by(id: input[:gpg_key], organization: input[:organization_id])
57
+ if ::Katello.const_defined?(:ContentCredential)
58
+ product.gpg_key = ::Katello::ContentCredential.find_by(id: input[:gpg_key], organization: input[:organization_id])
59
+ else
60
+ product.gpg_key = ::Katello::GpgKey.find_by(id: input[:gpg_key], organization: input[:organization_id])
61
+ end
58
62
  product.description = input[:product_description]
59
63
  trigger(::Actions::Katello::Product::Create,
60
64
  product,
@@ -1,21 +1,17 @@
1
1
  module SccManager
2
2
  # adapted from https://github.com/SUSE/connect
3
3
  def self.get_scc_data(base_url, rest_url, login, password)
4
- if SETTINGS[:katello][:cdn_proxy] && SETTINGS[:katello][:cdn_proxy][:host]
5
- proxy_config = SETTINGS[:katello][:cdn_proxy]
6
- uri = URI('')
7
-
8
- uri.scheme = URI.parse(proxy_config[:host]).scheme
9
- uri.host = URI.parse(proxy_config[:host]).host
10
- uri.port = proxy_config[:port].try(:to_s)
11
- uri.user = proxy_config[:user]
4
+ if (proxy_config = ::HttpProxy.default_global_content_proxy)
5
+ uri = URI(proxy_config[:url])
6
+ uri.user = proxy_config[:username]
12
7
  uri.password = proxy_config[:password] if uri.user.present?
13
8
 
14
9
  RestClient.proxy = uri.to_s
15
10
  end
16
11
 
17
12
  url = base_url + rest_url
18
- auth_header = { Authorization: 'Basic ' + Base64.encode64("#{login}:#{password}").chomp,
13
+ credentials = Base64.encode64("#{login}:#{password}").chomp
14
+ auth_header = { Authorization: "Basic #{credentials}",
19
15
  Accept: 'application/vnd.scc.suse.com.v4+json' }
20
16
  results = []
21
17
  loop do
@@ -45,12 +45,7 @@ class SccAccount < ApplicationRecord
45
45
  end
46
46
 
47
47
  def sync_date_is_valid_datetime
48
- errors.add(:sync_date, 'must be a valid datetime') if interval != NEVER &&
49
- sync_date.present? &&
50
- !sync_date.respond_to?(:min) &&
51
- !sync_date.respond_to?(:hour) &&
52
- !sync_date.respond_to?(:wday) &&
53
- !sync_date.respond_to?(:day)
48
+ errors.add(:sync_date, 'must be a valid datetime') if interval != NEVER && sync_date.blank?
54
49
  end
55
50
 
56
51
  def to_s
@@ -104,7 +99,7 @@ class SccAccount < ApplicationRecord
104
99
  end
105
100
 
106
101
  def add_recurring_logic(sync_date, interval)
107
- sd = sync_date
102
+ sd = sync_date.presence || Time.now
108
103
 
109
104
  raise _('Interval cannot be nil') if interval.nil?
110
105
 
@@ -177,7 +172,7 @@ class SccAccount < ApplicationRecord
177
172
  def update_scc_repositories(upstream_repositories)
178
173
  upstream_repo_ids = []
179
174
  # initially invalidate all repositories and validate them during update
180
- invalidated_repos = invalidate_subscription_status(scc_repositories)
175
+ invalidated_repos = invalidate_subscription_status(scc_repositories, save_record: false)
181
176
  # import repositories
182
177
  upstream_repositories.each do |ur|
183
178
  cached_repository = scc_repositories.find_or_initialize_by(scc_id: ur['id'])
@@ -201,7 +196,7 @@ class SccAccount < ApplicationRecord
201
196
  # subscription_valid can be set to nil
202
197
  to_invalidate = invalidated_repos.select { |ir| ir.katello_root_repository_id.present? && !ir.subscription_valid }
203
198
  ::Foreman::Logging.logger('foreman_scc_manager').debug "Invalidating #{to_invalidate.count} expired repositories"
204
- invalidate_subscription_status(to_invalidate, true)
199
+ invalidate_subscription_status(to_invalidate, save_record: true)
205
200
 
206
201
  # delete repositories being removed upstream and that are not subscribed to
207
202
  to_delete = scc_repositories.where.not(scc_id: upstream_repo_ids)
@@ -212,7 +207,7 @@ class SccAccount < ApplicationRecord
212
207
  def update_scc_products(upstream_products)
213
208
  upstream_product_ids = []
214
209
  # initially invalidate all products and validate them during update
215
- invalidated_products = invalidate_subscription_status(scc_products)
210
+ invalidated_products = invalidate_subscription_status(scc_products, save_record: false)
216
211
  # import products
217
212
  upstream_products.each do |up|
218
213
  cached_product = scc_products.find_or_initialize_by(scc_id: up['id'])
@@ -238,7 +233,7 @@ class SccAccount < ApplicationRecord
238
233
  # subscription_valid can be set to nil
239
234
  to_invalidate = invalidated_products.select { |ip| ip.product_id.present? && !ip.subscription_valid }
240
235
  ::Foreman::Logging.logger('foreman_scc_manager').debug "Invalidating #{to_invalidate.count} expired products"
241
- invalidate_subscription_status(to_invalidate, true)
236
+ invalidate_subscription_status(to_invalidate, save_record: true)
242
237
 
243
238
  # delete products being removed upstream and that are not subscribed to
244
239
  to_delete = scc_products.where.not(scc_id: upstream_product_ids).where(product_id: nil)
@@ -271,9 +266,9 @@ class SccAccount < ApplicationRecord
271
266
 
272
267
  # set all products/repos invalid
273
268
  # params: items_to_invalidate: ActiveRecord_(*)
274
- # save_record: store in database or not (default)
269
+ # save_record: store in database or not
275
270
  # return: ActiveRecord elements with invalidated subscription status
276
- def invalidate_subscription_status(items_to_invalidate, save_record = false)
271
+ def invalidate_subscription_status(items_to_invalidate, save_record:)
277
272
  if items_to_invalidate.present?
278
273
  items_to_invalidate.each do |inv|
279
274
  inv.subscription_valid = false
@@ -9,11 +9,11 @@ class SccRepository < ApplicationRecord
9
9
  has_and_belongs_to_many :scc_products
10
10
 
11
11
  def full_url
12
- token.blank? ? url : url + '?' + token
12
+ token.blank? ? url : "#{url}?#{token}"
13
13
  end
14
14
 
15
15
  def uniq_name(scc_product)
16
- scc_product.scc_id.to_s + ' ' + description
16
+ "#{scc_product.scc_id} #{description}"
17
17
  end
18
18
 
19
19
  def pretty_name
data/config/routes.rb CHANGED
@@ -23,7 +23,7 @@ Rails.application.routes.draw do
23
23
  :defaults => { :apiv => 'v2' },
24
24
  :apiv => /v1|v2/,
25
25
  :constraints => ApiConstraints.new(:version => 2, :default => true) do
26
- resources :scc_accounts do
26
+ resources :scc_accounts, except: %i[new edit] do
27
27
  collection do
28
28
  post 'test_connection'
29
29
  get 'auto_complete_search'
@@ -1,6 +1,10 @@
1
1
  class AddGpgKeyToSccAccount < ActiveRecord::Migration[5.2]
2
2
  def change
3
- add_column :scc_accounts, :katello_gpg_key_id, :integer, null: true
4
- add_foreign_key :scc_accounts, :katello_gpg_keys, column: :katello_gpg_key_id, on_delete: :nullify
3
+ add_column :scc_accounts, :katello_gpg_key_id, :integer, null: true
4
+ if ::Katello.const_defined?(:ContentCredential)
5
+ add_foreign_key :scc_accounts, :katello_content_credentials, column: :katello_gpg_key_id, on_delete: :nullify
6
+ else
7
+ add_foreign_key :scc_accounts, :katello_gpg_keys, column: :katello_gpg_key_id, on_delete: :nullify
8
+ end
5
9
  end
6
10
  end
@@ -0,0 +1,19 @@
1
+ class AddPermissions < ActiveRecord::Migration[6.0]
2
+ PRODUCT_PERMISSION_NAMES = [
3
+ 'view_scc_products',
4
+ 'subscribe_scc_products'
5
+ ].freeze
6
+
7
+ def up
8
+ Permission.create!(:name => 'test_connection_scc_accounts', :resource_type => 'SccAccount')
9
+ PRODUCT_PERMISSION_NAMES.each do |p|
10
+ Permission.create!(:name => p, :resource_type => SccProduct)
11
+ end
12
+ end
13
+
14
+ def down
15
+ (PRODUCT_PERMISSION_NAMES + ['test_connection_scc_accounts']).each do |p|
16
+ Permission.where(:name => p).destroy_all
17
+ end
18
+ end
19
+ end
@@ -32,8 +32,8 @@ module ForemanSccManager
32
32
  # Add permissions
33
33
  security_block :foreman_scc_manager do
34
34
  permission :view_scc_accounts,
35
- { :scc_accounts => [:show, :index],
36
- :'api/v2/scc_accounts' => [:show, :index] },
35
+ { :scc_accounts => [:show, :index, :auto_complete_search],
36
+ :'api/v2/scc_accounts' => [:show, :index, :auto_complete_search] },
37
37
  :resource_type => 'SccAccount'
38
38
 
39
39
  permission :use_scc_accounts,
@@ -60,15 +60,33 @@ module ForemanSccManager
60
60
  { :scc_accounts => [:sync],
61
61
  :'api/v2/scc_accounts' => [:sync] },
62
62
  :resource_type => 'SccAccount'
63
+
64
+ permission :test_connection_scc_accounts,
65
+ { :scc_accounts => [:test_connection],
66
+ :'api/v2/scc_accounts' => [:test_connection] },
67
+ :resource_type => 'SccAccount'
68
+
69
+ permission :view_scc_products,
70
+ { :scc_products => [:index, :show],
71
+ :'api/v2/scc_products' => [:index, :show] },
72
+ :resource_type => 'SccProduct'
73
+
74
+ permission :subscribe_scc_products,
75
+ { :scc_products => [:subscribe, :unsubscribe],
76
+ :'api/v2/scc_products' => [:subscribe, :unsibscribe] },
77
+ :resource_type => 'SccProduct'
63
78
  end
64
79
 
65
80
  # Add a new role called 'SccManager' if it doesn't exist
66
81
  role 'SccManager',
67
- %i[view_scc_accounts use_scc_accounts new_scc_accounts edit_scc_accounts delete_scc_accounts sync_scc_accounts],
82
+ %i[view_scc_accounts use_scc_accounts new_scc_accounts edit_scc_accounts
83
+ delete_scc_accounts sync_scc_accounts test_connection_scc_accounts
84
+ view_scc_products subscribe_scc_products],
68
85
  'Role granting permissons to manage SUSE Subscriptions'
69
86
 
70
87
  role 'SccViewer',
71
- %i[view_scc_accounts use_scc_accounts sync_scc_accounts create_products view_products],
88
+ %i[view_scc_accounts use_scc_accounts sync_scc_accounts
89
+ create_products view_products subscribe_scc_products view_scc_products],
72
90
  'Role granting permissons to view and use SUSE Subscriptions'
73
91
 
74
92
  add_all_permissions_to_default_roles
@@ -1,3 +1,3 @@
1
1
  module ForemanSccManager
2
- VERSION = '1.8.9'.freeze
2
+ VERSION = '1.8.15'.freeze
3
3
  end
@@ -0,0 +1,24 @@
1
+ require 'test_plugin_helper'
2
+
3
+ class SccManagerActions < ActiveSupport::TestCase
4
+ include Dynflow::Testing
5
+
6
+ let(:action_class) { ::Actions::SccManager::Sync }
7
+
8
+ def setup
9
+ @scc_account = scc_accounts(:one)
10
+ # ensure we have an org label
11
+ get_organization
12
+ end
13
+
14
+ test 'plan sync action' do
15
+ action = create_action(action_class)
16
+ action.stubs(:action_subject).with(@scc_account)
17
+
18
+ assert_respond_to(action, :phase)
19
+ plan_action(action, @scc_account)
20
+
21
+ assert_action_planned_with(action, ::Actions::SccManager::SyncProducts, @scc_account)
22
+ assert_action_planned_with(action, ::Actions::SccManager::SyncRepositories, @scc_account)
23
+ end
24
+ end
@@ -208,13 +208,52 @@ class Api::V2::SccAccountsControllerTest < ActionController::TestCase
208
208
  assert_response :ok
209
209
  end
210
210
 
211
- test 'should refuse update scc_account' do
211
+ test 'should refuse update scc_account with invalid interval' do
212
212
  account = scc_accounts(:two)
213
213
  put :update, params: { id: account.id, :scc_account => { :interval => 'yearly' } }
214
214
  assert_equal 'yearly', assigns(:scc_account).interval
215
215
  assert_response :unprocessable_entity
216
216
  end
217
217
 
218
+ test 'should refuse update scc_account with empty date' do
219
+ account = scc_accounts(:two)
220
+ put :update, params: { id: account.id, :scc_account => { :interval => 'weekly', :sync_date => '' } }
221
+ assert_response :unprocessable_entity
222
+ assert_error_message 'Sync date must be a valid datetime'
223
+ end
224
+
225
+ test 'should fail to update scc_account with interval set and invalid date' do
226
+ account = scc_accounts(:two)
227
+ put :update, params: { id: account.id, :scc_account => { :sync_date => 'invalid_date', :interval => 'weekly' } }
228
+
229
+ assert_response :unprocessable_entity
230
+ assert_error_message 'Sync date must be a valid datetime'
231
+ end
232
+
233
+ test 'should fail to update scc_account with empty name' do
234
+ account = scc_accounts(:two)
235
+ put :update, params: { id: account.id, :scc_account => { :name => '', :sync_date => Time.now, :interval => 'weekly' } }
236
+
237
+ assert_response :unprocessable_entity
238
+ assert_error_message "Name can't be blank"
239
+ end
240
+
241
+ test 'should fail to update scc_account with empty login' do
242
+ account = scc_accounts(:two)
243
+ put :update, params: { id: account.id, :scc_account => { :login => '', :sync_date => Time.now, :interval => 'weekly' } }
244
+
245
+ assert_response :unprocessable_entity
246
+ assert_error_message "Login can't be blank"
247
+ end
248
+
249
+ test 'should fail to update scc_account with empty base_url' do
250
+ account = scc_accounts(:two)
251
+ put :update, params: { id: account.id, :scc_account => { :base_url => '', :sync_date => Time.now, :interval => 'weekly' } }
252
+
253
+ assert_response :unprocessable_entity
254
+ assert_error_message "Base url can't be blank"
255
+ end
256
+
218
257
  test 'new account SCC server connection-test' do
219
258
  scc_setup
220
259
  account = scc_accounts(:one)
@@ -305,4 +344,10 @@ class Api::V2::SccAccountsControllerTest < ActionController::TestCase
305
344
  end
306
345
  assert_response :ok
307
346
  end
347
+
348
+ private
349
+
350
+ def assert_error_message(message)
351
+ assert_includes JSON.parse(response.body)['error']['full_messages'], message
352
+ end
308
353
  end
@@ -5,7 +5,9 @@ class Api::V2::SccProductsControllerTest < ActionController::TestCase
5
5
  @scc_account = scc_accounts(:one)
6
6
  @scc_product1 = scc_products(:one)
7
7
  @scc_product2 = scc_products(:two)
8
- @scc_account.scc_products = [@scc_product1, @scc_product2]
8
+ @scc_product3 = scc_products(:three)
9
+ @scc_product4 = scc_products(:four)
10
+ @scc_account.scc_products = [@scc_product1, @scc_product2, @scc_product3, @scc_product4]
9
11
  end
10
12
 
11
13
  test 'should get index' do
@@ -37,4 +39,22 @@ class Api::V2::SccProductsControllerTest < ActionController::TestCase
37
39
  put :subscribe, params: { :id => 'doest-not-exit', :scc_account_id => @scc_account.id }
38
40
  assert_response :not_found
39
41
  end
42
+
43
+ test 'show subscribed products only' do
44
+ get :index, params: { :scc_account_id => @scc_account.id, :subscribed_only => true }
45
+ assert_response :success
46
+ body = ActiveSupport::JSON.decode(@response.body)
47
+ assert_not_empty body
48
+ assert_equal 2, body['results'].count
49
+ assert_equal 2, body['subtotal']
50
+ end
51
+
52
+ test 'show all products if subscribed_only flag is set to false' do
53
+ get :index, params: { :scc_account_id => @scc_account.id, :subscribed_only => false }
54
+ assert_response :success
55
+ body = ActiveSupport::JSON.decode(@response.body)
56
+ assert_not_empty body
57
+ assert_equal 4, body['results'].count
58
+ assert_equal 4, body['subtotal']
59
+ end
40
60
  end
@@ -69,8 +69,58 @@ class SccAccountsControllerTest < ActionController::TestCase
69
69
  test 'should update scc_account' do
70
70
  account = scc_accounts(:two)
71
71
  put :update, params: { id: account.id, :scc_account => { :sync_date => Time.now, :interval => 'weekly' } }, session: set_session_user
72
+ assert_redirected_to '/scc_accounts'
73
+ assert_equal 'weekly', SccAccount.find(account.id).interval
74
+ end
75
+
76
+ test 'should update scc_account with empty date if interval not set' do
77
+ account = scc_accounts(:two)
78
+ put :update, params: { id: account.id, :scc_account => { :name => 'new_name', :sync_date => '', :interval => 'never' } }, session: set_session_user
79
+
80
+ assert_equal 'new_name', SccAccount.find(account.id).name
81
+ end
82
+
83
+ test 'updates scc_account even if the date is invalid' do
84
+ # @todo reminder to fix this in the future
85
+ account = scc_accounts(:two)
86
+ put :update, params: { id: account.id, :scc_account => { :name => 'new_name', :sync_date => 'invalid_date', :interval => 'never' } }, session: set_session_user
87
+
88
+ assert_not_equal account.name, SccAccount.find(account.id).name
89
+ end
90
+
91
+ test 'should fail to update scc_account with interval set and empty date' do
92
+ account = scc_accounts(:two)
93
+ put :update, params: { id: account.id, :scc_account => { :sync_date => '', :interval => 'weekly' } }, session: set_session_user
94
+
95
+ assert_equal SccAccount.find(account.id).sync_date, account.sync_date
96
+ end
97
+
98
+ test 'should fail to update scc_account with interval set and invalid date' do
99
+ account = scc_accounts(:two)
100
+ put :update, params: { id: account.id, :scc_account => { :sync_date => 'invalid_date', :interval => 'weekly' } }, session: set_session_user
101
+
102
+ assert_equal SccAccount.find(account.id).sync_date, account.sync_date
103
+ end
104
+
105
+ test 'should fail to update scc_account with empty name' do
106
+ account = scc_accounts(:two)
107
+ put :update, params: { id: account.id, :scc_account => { :name => '', :sync_date => Time.now, :interval => 'weekly' } }, session: set_session_user
108
+
109
+ assert_equal account.name, SccAccount.find(account.id).name
110
+ end
111
+
112
+ test 'should fail to update scc_account with empty login' do
113
+ account = scc_accounts(:two)
114
+ put :update, params: { id: account.id, :scc_account => { :login => '', :sync_date => Time.now, :interval => 'weekly' } }, session: set_session_user
115
+
116
+ assert_equal account.login, SccAccount.find(account.id).login
117
+ end
118
+
119
+ test 'should fail to update scc_account with empty base url' do
120
+ account = scc_accounts(:two)
121
+ put :update, params: { id: account.id, :scc_account => { :base_url => '', :sync_date => Time.now, :interval => 'weekly' } }, session: set_session_user
72
122
 
73
- assert_equal 'weekly', assigns(:scc_account).interval
123
+ assert_equal account.base_url, SccAccount.find(account.id).base_url
74
124
  end
75
125
 
76
126
  test 'SCC server sync products' do
@@ -6,6 +6,7 @@ one:
6
6
  name: onename
7
7
  interval: never
8
8
  organization_id: <%= ActiveRecord::FixtureSet.identify(:empty_organization) %>
9
+ sync_date: Time.now
9
10
 
10
11
  two:
11
12
  login: twouser
@@ -14,6 +15,7 @@ two:
14
15
  name: twoname
15
16
  interval: never
16
17
  organization_id: <%= ActiveRecord::FixtureSet.identify(:empty_organization) %>
18
+ sync_date: 2021-07-05T21:33:49
17
19
 
18
20
  account_missing_url:
19
21
  login: fakeuser1
@@ -10,6 +10,7 @@ one:
10
10
  description: "<p> lorem ipsum dolor sit amet </p>"
11
11
  product_type: base
12
12
  subscription_valid: nil
13
+ product_id: nil
13
14
 
14
15
  two:
15
16
  scc_account_id: test_account1
@@ -21,6 +22,7 @@ two:
21
22
  description: "<p> lorem ipsum dolor sit amet </p><p> lorem lorem lorem </p>"
22
23
  product_type: extras
23
24
  subscription_valid: true
25
+ product_id: nil
24
26
 
25
27
  three:
26
28
  scc_account_id: test_account1
@@ -32,18 +34,31 @@ three:
32
34
  description: lorem ipsum dolor sit amet
33
35
  product_type: base
34
36
  subscription_valid: nil
37
+ product_id: 1
38
+
39
+ four:
40
+ scc_account_id: test_account1
41
+ scc_id: 444
42
+ name: four
43
+ version: 4
44
+ arch: x86_128
45
+ friendly_name: number four
46
+ description: lorem ipsum dolor sit amet
47
+ product_type: base
48
+ subscription_valid: nil
49
+ product_id: 2
35
50
 
36
51
  # create a couple of products as scc_extensions
37
52
  <% 1.upto(10) do |i| %>
38
53
  p_extension_<%= i %>:
39
54
  scc_account_id: test_account1
40
55
  scc_id: <%= i %>
41
- name: p_ext_<%= i%>
56
+ name: p_ext_<%= i%>
42
57
  version: 3
43
58
  arch: x86_128
44
- friendly_name: number <%= i%>
59
+ friendly_name: number <%= i%>
45
60
  description: lorem ipsum dolor sit amet
46
61
  product_type: extension
47
62
  subscription_valid: nil
63
+ product_id: nil
48
64
  <% end %>
49
-
@@ -30,7 +30,7 @@ end
30
30
 
31
31
  class SccProductSearchTest < ActiveSupport::TestCase
32
32
  test 'default ordered by name' do
33
- product_names = ['one', 'two', 'three',
33
+ product_names = ['one', 'two', 'three', 'four',
34
34
  'p_ext_1', 'p_ext_10', 'p_ext_2', 'p_ext_3',
35
35
  'p_ext_4', 'p_ext_5', 'p_ext_6', 'p_ext_7',
36
36
  'p_ext_8', 'p_ext_9']
@@ -1,6 +1,8 @@
1
1
  # This calls the main test_helper in Foreman-core
2
2
  require 'test_helper'
3
3
 
4
+ require 'dynflow/testing'
5
+ Dynflow::Testing.logger_adapter.level = 1
4
6
  require 'foreman_tasks/test_helpers'
5
7
  require "#{ForemanSccManager::Engine.root}/test/support/fixtures_support"
6
8