Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 35 additions & 1 deletion app/controllers/api/v2/hosts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,38 @@ def boot
render_exception(e, :status => :unprocessable_entity)
end

api :PUT, "/hosts/:id/wol", N_("Send Wake on LAN request to host")
param :id, :identifier_dottable, :required => true

def wol
primary_interface = @host.primary_interface

unless primary_interface
return render_error :custom_error, :status => :unprocessable_entity, :locals => { :message => _('Host has no primary interface') }
end

unless primary_interface.mac.present?
return render_error :custom_error, :status => :unprocessable_entity, :locals => { :message => _('Primary interface has no MAC address') }
end

unless primary_interface.subnet&.dhcp?
return render_error :custom_error, :status => :unprocessable_entity, :locals => { :message => _('Primary interface subnet has no DHCP proxy configured') }
end

dhcp_proxy = primary_interface.subnet.dhcp
unless dhcp_proxy.has_feature?('WOL')
return render_error :custom_error, :status => :unprocessable_entity, :locals => { :message => _('DHCP proxy does not have WOL feature enabled') }
end

begin
wol_api = ProxyAPI::Wol.new(:url => dhcp_proxy.url)
result = wol_api.wake(primary_interface.mac)
render :json => { :wol => result }, :status => :ok
rescue => e
render_error :custom_error, :status => :unprocessable_entity, :locals => { :message => e.message }
end
end

api :POST, "/hosts/facts", N_("Upload facts for a host, creating the host if required")
param :name, String, :required => true, :desc => N_("hostname of the host")
param :facts, Hash, :required => true, :desc => N_("hash containing the facts for the host")
Expand Down Expand Up @@ -382,6 +414,8 @@ def action_permission
:power
when 'boot'
:ipmi_boot
when 'wol'
:power
when 'console'
:console
when 'disassociate', 'forget_status'
Expand All @@ -397,7 +431,7 @@ def action_permission

def parent_permission(child_permission)
case child_permission.to_s
when 'power', 'boot', 'console', 'vm_compute_attributes', 'get_status', 'template', 'enc', 'rebuild_config', 'inherited_parameters'
when 'power', 'boot', 'wol', 'console', 'vm_compute_attributes', 'get_status', 'template', 'enc', 'rebuild_config', 'inherited_parameters'
'view'
when 'disassociate'
'edit'
Expand Down
20 changes: 20 additions & 0 deletions app/services/proxy_api/wol.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module ProxyAPI
class Wol < ProxyAPI::Resource
def initialize(args)
@url = args[:url] + "/wol"
super args
end

# Send Wake on LAN request
# [+mac+] : MAC address in coloned sextuplet format
# Returns : Boolean status
def wake(mac)
raise "Must define a MAC address" if mac.blank?

params = { :mac_address => mac }
parse post(params)
rescue => e
raise ProxyException.new(url, e, N_("Unable to send Wake on LAN request for MAC %s"), mac)
end
end
end
2 changes: 1 addition & 1 deletion config/initializers/f_foreman_permissions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@
:"api/v2/hosts" => [:rebuild_config],
}
map.permission :power_hosts, {:hosts => [:power],
:"api/v2/hosts" => [:power, :power_status] }
:"api/v2/hosts" => [:power, :power_status, :wol] }
map.permission :console_hosts, {:hosts => [:console] }
map.permission :ipmi_boot_hosts, { :hosts => [:ipmi_boot],
:"api/v2/hosts" => [:boot] }
Expand Down
1 change: 1 addition & 0 deletions config/routes/api/v2.rb
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@
put :boot, :on => :member
get :power, :on => :member, :action => :power_status
put :power, :on => :member
put :wol, :on => :member
put :rebuild_config, :on => :member
get :inherited_parameters, :on => :member
post :facts, :on => :collection
Expand Down
2 changes: 1 addition & 1 deletion db/seeds.d/110-smart_proxy_features.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Proxy features
proxy_features = ["Templates", "TFTP", "DNS", "DHCP", "Puppet CA", "BMC", "Realm", "Facts", "Logs", "HTTPBoot", "External IPAM",
"Registration"]
"Registration", "WOL"]

proxy_features.each do |input|
f = Feature.where(:name => input).first_or_create
Expand Down
123 changes: 123 additions & 0 deletions test/controllers/api/v2/hosts_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
:compute_resource_id => compute_attrs.compute_resource_id,
:compute_profile_id => compute_attrs.compute_profile_id
)
end

Check failure on line 53 in test/controllers/api/v2/hosts_controller_test.rb

View workflow job for this annotation

GitHub Actions / test:functionals - Ruby 3.0 and Node 18 on PostgreSQL 13

Failure: test_0002_should deny user without power permission ActiveRecord::RecordInvalid: Validation failed: Primary interface is already set on the host, Provision interface is already set on the host, Name has already been taken test/factories/disable_auditing.rb:13:in `block (3 levels) in <top (required)>' test/factories/disable_auditing.rb:13:in `block (2 levels) in <top (required)>' test/controllers/api/v2/hosts_controller_test.rb:1437:in `block (2 levels) in <class:HostsControllerTest>' test/test_helper.rb:88:in `before_setup'

Check failure on line 53 in test/controllers/api/v2/hosts_controller_test.rb

View workflow job for this annotation

GitHub Actions / test:functionals - Ruby 3.0 and Node 18 on PostgreSQL 13

Failure: test_0001_should allow user with power permission to send WOL request ActiveRecord::RecordInvalid: Validation failed: Primary interface is already set on the host, Provision interface is already set on the host, Name has already been taken test/factories/disable_auditing.rb:13:in `block (3 levels) in <top (required)>' test/factories/disable_auditing.rb:13:in `block (2 levels) in <top (required)>' test/controllers/api/v2/hosts_controller_test.rb:1437:in `block (2 levels) in <class:HostsControllerTest>' test/test_helper.rb:88:in `before_setup'

Check failure on line 53 in test/controllers/api/v2/hosts_controller_test.rb

View workflow job for this annotation

GitHub Actions / test:functionals - Ruby 3.0 and Node 18 on PostgreSQL 13

Failure: test_0008_should return 404 for non-existent host ActiveRecord::RecordInvalid: Validation failed: Primary interface is already set on the host, Provision interface is already set on the host, Name has already been taken test/factories/disable_auditing.rb:13:in `block (3 levels) in <top (required)>' test/factories/disable_auditing.rb:13:in `block (2 levels) in <top (required)>' test/controllers/api/v2/hosts_controller_test.rb:1437:in `block (2 levels) in <class:HostsControllerTest>' test/test_helper.rb:88:in `before_setup'

Check failure on line 53 in test/controllers/api/v2/hosts_controller_test.rb

View workflow job for this annotation

GitHub Actions / test:functionals - Ruby 3.0 and Node 18 on PostgreSQL 13

Failure: test_0001_should send WOL request successfully ActiveRecord::RecordInvalid: Validation failed: Primary interface is already set on the host, Provision interface is already set on the host, Name has already been taken test/factories/disable_auditing.rb:13:in `block (3 levels) in <top (required)>' test/factories/disable_auditing.rb:13:in `block (2 levels) in <top (required)>' test/controllers/api/v2/hosts_controller_test.rb:1437:in `block (2 levels) in <class:HostsControllerTest>' test/test_helper.rb:88:in `before_setup'

Check failure on line 53 in test/controllers/api/v2/hosts_controller_test.rb

View workflow job for this annotation

GitHub Actions / test:functionals - Ruby 3.0 and Node 18 on PostgreSQL 13

Failure: test_0006_should return error when DHCP proxy does not have WOL feature ActiveRecord::RecordInvalid: Validation failed: Primary interface is already set on the host, Provision interface is already set on the host, Name has already been taken test/factories/disable_auditing.rb:13:in `block (3 levels) in <top (required)>' test/factories/disable_auditing.rb:13:in `block (2 levels) in <top (required)>' test/controllers/api/v2/hosts_controller_test.rb:1437:in `block (2 levels) in <class:HostsControllerTest>' test/test_helper.rb:88:in `before_setup'

Check failure on line 53 in test/controllers/api/v2/hosts_controller_test.rb

View workflow job for this annotation

GitHub Actions / test:functionals - Ruby 3.0 and Node 18 on PostgreSQL 13

Failure: test_0004_should return error when primary interface has empty MAC address ActiveRecord::RecordInvalid: Validation failed: Primary interface is already set on the host, Provision interface is already set on the host, Name has already been taken test/factories/disable_auditing.rb:13:in `block (3 levels) in <top (required)>' test/factories/disable_auditing.rb:13:in `block (2 levels) in <top (required)>' test/controllers/api/v2/hosts_controller_test.rb:1437:in `block (2 levels) in <class:HostsControllerTest>' test/test_helper.rb:88:in `before_setup'

Check failure on line 53 in test/controllers/api/v2/hosts_controller_test.rb

View workflow job for this annotation

GitHub Actions / test:functionals - Ruby 3.0 and Node 18 on PostgreSQL 13

Failure: test_0002_should return error when host has no primary interface ActiveRecord::RecordInvalid: Validation failed: Primary interface is already set on the host, Provision interface is already set on the host, Name has already been taken test/factories/disable_auditing.rb:13:in `block (3 levels) in <top (required)>' test/factories/disable_auditing.rb:13:in `block (2 levels) in <top (required)>' test/controllers/api/v2/hosts_controller_test.rb:1437:in `block (2 levels) in <class:HostsControllerTest>' test/test_helper.rb:88:in `before_setup'

Check failure on line 53 in test/controllers/api/v2/hosts_controller_test.rb

View workflow job for this annotation

GitHub Actions / test:functionals - Ruby 3.0 and Node 18 on PostgreSQL 13

Failure: test_0007_should handle ProxyException with proper error message ActiveRecord::RecordInvalid: Validation failed: Primary interface is already set on the host, Provision interface is already set on the host, Name has already been taken test/factories/disable_auditing.rb:13:in `block (3 levels) in <top (required)>' test/factories/disable_auditing.rb:13:in `block (2 levels) in <top (required)>' test/controllers/api/v2/hosts_controller_test.rb:1437:in `block (2 levels) in <class:HostsControllerTest>' test/test_helper.rb:88:in `before_setup'

Check failure on line 53 in test/controllers/api/v2/hosts_controller_test.rb

View workflow job for this annotation

GitHub Actions / test:functionals - Ruby 3.0 and Node 18 on PostgreSQL 13

Failure: test_0005_should return error when primary interface subnet has no DHCP proxy ActiveRecord::RecordInvalid: Validation failed: Primary interface is already set on the host, Provision interface is already set on the host, Name has already been taken test/factories/disable_auditing.rb:13:in `block (3 levels) in <top (required)>' test/factories/disable_auditing.rb:13:in `block (2 levels) in <top (required)>' test/controllers/api/v2/hosts_controller_test.rb:1437:in `block (2 levels) in <class:HostsControllerTest>' test/test_helper.rb:88:in `before_setup'

Check failure on line 53 in test/controllers/api/v2/hosts_controller_test.rb

View workflow job for this annotation

GitHub Actions / test:functionals - Ruby 3.0 and Node 18 on PostgreSQL 13

Failure: test_0003_should return error when primary interface has no MAC address ActiveRecord::RecordInvalid: Validation failed: Primary interface is already set on the host, Provision interface is already set on the host, Name has already been taken test/factories/disable_auditing.rb:13:in `block (3 levels) in <top (required)>' test/factories/disable_auditing.rb:13:in `block (2 levels) in <top (required)>' test/controllers/api/v2/hosts_controller_test.rb:1437:in `block (2 levels) in <class:HostsControllerTest>' test/test_helper.rb:88:in `before_setup'

Check failure on line 53 in test/controllers/api/v2/hosts_controller_test.rb

View workflow job for this annotation

GitHub Actions / test:functionals - Ruby 2.7 and Node 18 on PostgreSQL 13

Failure: test_0001_should send WOL request successfully ActiveRecord::RecordInvalid: Validation failed: Primary interface is already set on the host, Provision interface is already set on the host, Name has already been taken test/factories/disable_auditing.rb:13:in `block (3 levels) in <top (required)>' test/factories/disable_auditing.rb:13:in `block (2 levels) in <top (required)>' test/controllers/api/v2/hosts_controller_test.rb:1437:in `block (2 levels) in <class:HostsControllerTest>' test/test_helper.rb:88:in `before_setup'

Check failure on line 53 in test/controllers/api/v2/hosts_controller_test.rb

View workflow job for this annotation

GitHub Actions / test:functionals - Ruby 2.7 and Node 18 on PostgreSQL 13

Failure: test_0003_should return error when primary interface has no MAC address ActiveRecord::RecordInvalid: Validation failed: Primary interface is already set on the host, Provision interface is already set on the host, Name has already been taken test/factories/disable_auditing.rb:13:in `block (3 levels) in <top (required)>' test/factories/disable_auditing.rb:13:in `block (2 levels) in <top (required)>' test/controllers/api/v2/hosts_controller_test.rb:1437:in `block (2 levels) in <class:HostsControllerTest>' test/test_helper.rb:88:in `before_setup'

Check failure on line 53 in test/controllers/api/v2/hosts_controller_test.rb

View workflow job for this annotation

GitHub Actions / test:functionals - Ruby 2.7 and Node 18 on PostgreSQL 13

Failure: test_0008_should return 404 for non-existent host ActiveRecord::RecordInvalid: Validation failed: Primary interface is already set on the host, Provision interface is already set on the host, Name has already been taken test/factories/disable_auditing.rb:13:in `block (3 levels) in <top (required)>' test/factories/disable_auditing.rb:13:in `block (2 levels) in <top (required)>' test/controllers/api/v2/hosts_controller_test.rb:1437:in `block (2 levels) in <class:HostsControllerTest>' test/test_helper.rb:88:in `before_setup'

Check failure on line 53 in test/controllers/api/v2/hosts_controller_test.rb

View workflow job for this annotation

GitHub Actions / test:functionals - Ruby 2.7 and Node 18 on PostgreSQL 13

Failure: test_0007_should handle ProxyException with proper error message ActiveRecord::RecordInvalid: Validation failed: Primary interface is already set on the host, Provision interface is already set on the host, Name has already been taken test/factories/disable_auditing.rb:13:in `block (3 levels) in <top (required)>' test/factories/disable_auditing.rb:13:in `block (2 levels) in <top (required)>' test/controllers/api/v2/hosts_controller_test.rb:1437:in `block (2 levels) in <class:HostsControllerTest>' test/test_helper.rb:88:in `before_setup'

Check failure on line 53 in test/controllers/api/v2/hosts_controller_test.rb

View workflow job for this annotation

GitHub Actions / test:functionals - Ruby 2.7 and Node 18 on PostgreSQL 13

Failure: test_0002_should return error when host has no primary interface ActiveRecord::RecordInvalid: Validation failed: Primary interface is already set on the host, Provision interface is already set on the host, Name has already been taken test/factories/disable_auditing.rb:13:in `block (3 levels) in <top (required)>' test/factories/disable_auditing.rb:13:in `block (2 levels) in <top (required)>' test/controllers/api/v2/hosts_controller_test.rb:1437:in `block (2 levels) in <class:HostsControllerTest>' test/test_helper.rb:88:in `before_setup'

Check failure on line 53 in test/controllers/api/v2/hosts_controller_test.rb

View workflow job for this annotation

GitHub Actions / test:functionals - Ruby 2.7 and Node 18 on PostgreSQL 13

Failure: test_0005_should return error when primary interface subnet has no DHCP proxy ActiveRecord::RecordInvalid: Validation failed: Primary interface is already set on the host, Provision interface is already set on the host, Name has already been taken test/factories/disable_auditing.rb:13:in `block (3 levels) in <top (required)>' test/factories/disable_auditing.rb:13:in `block (2 levels) in <top (required)>' test/controllers/api/v2/hosts_controller_test.rb:1437:in `block (2 levels) in <class:HostsControllerTest>' test/test_helper.rb:88:in `before_setup'

Check failure on line 53 in test/controllers/api/v2/hosts_controller_test.rb

View workflow job for this annotation

GitHub Actions / test:functionals - Ruby 2.7 and Node 18 on PostgreSQL 13

Failure: test_0006_should return error when DHCP proxy does not have WOL feature ActiveRecord::RecordInvalid: Validation failed: Primary interface is already set on the host, Provision interface is already set on the host, Name has already been taken test/factories/disable_auditing.rb:13:in `block (3 levels) in <top (required)>' test/factories/disable_auditing.rb:13:in `block (2 levels) in <top (required)>' test/controllers/api/v2/hosts_controller_test.rb:1437:in `block (2 levels) in <class:HostsControllerTest>' test/test_helper.rb:88:in `before_setup'

Check failure on line 53 in test/controllers/api/v2/hosts_controller_test.rb

View workflow job for this annotation

GitHub Actions / test:functionals - Ruby 2.7 and Node 18 on PostgreSQL 13

Failure: test_0004_should return error when primary interface has empty MAC address ActiveRecord::RecordInvalid: Validation failed: Primary interface is already set on the host, Provision interface is already set on the host, Name has already been taken test/factories/disable_auditing.rb:13:in `block (3 levels) in <top (required)>' test/factories/disable_auditing.rb:13:in `block (2 levels) in <top (required)>' test/controllers/api/v2/hosts_controller_test.rb:1437:in `block (2 levels) in <class:HostsControllerTest>' test/test_helper.rb:88:in `before_setup'

Check failure on line 53 in test/controllers/api/v2/hosts_controller_test.rb

View workflow job for this annotation

GitHub Actions / test:functionals - Ruby 2.7 and Node 18 on PostgreSQL 13

Failure: test_0001_should allow user with power permission to send WOL request ActiveRecord::RecordInvalid: Validation failed: Primary interface is already set on the host, Provision interface is already set on the host, Name has already been taken test/factories/disable_auditing.rb:13:in `block (3 levels) in <top (required)>' test/factories/disable_auditing.rb:13:in `block (2 levels) in <top (required)>' test/controllers/api/v2/hosts_controller_test.rb:1437:in `block (2 levels) in <class:HostsControllerTest>' test/test_helper.rb:88:in `before_setup'

Check failure on line 53 in test/controllers/api/v2/hosts_controller_test.rb

View workflow job for this annotation

GitHub Actions / test:functionals - Ruby 2.7 and Node 18 on PostgreSQL 13

Failure: test_0002_should deny user without power permission ActiveRecord::RecordInvalid: Validation failed: Primary interface is already set on the host, Provision interface is already set on the host, Name has already been taken test/factories/disable_auditing.rb:13:in `block (3 levels) in <top (required)>' test/factories/disable_auditing.rb:13:in `block (2 levels) in <top (required)>' test/controllers/api/v2/hosts_controller_test.rb:1437:in `block (2 levels) in <class:HostsControllerTest>' test/test_helper.rb:88:in `before_setup'

def basic_attrs_with_hg
hostgroup_attr = {
Expand Down Expand Up @@ -1427,4 +1427,127 @@
assert_equal json_response['facet_param'], 'bar'
end
end

context 'Wake-on-LAN (WOL) tests' do
setup do
@dhcp_proxy = FactoryBot.create(:dhcp_smart_proxy)
@dhcp_proxy.features << FactoryBot.create(:feature, :name => 'WOL')
@subnet = FactoryBot.create(:subnet_ipv4, :dhcp => @dhcp_proxy)
@host = FactoryBot.create(:host, :managed)
@primary_interface = FactoryBot.create(:nic_primary_and_provision,
:host => @host,
:subnet => @subnet,
:mac => '00:61:23:18:48:a5')
@host.interfaces = [@primary_interface]
@host.save!
User.current = users(:apiadmin)
end

test 'should send WOL request successfully' do
ProxyAPI::Wol.any_instance.expects(:wake).with('00:61:23:18:48:a5').returns(true)

put :wol, params: { :id => @host.to_param }

assert_response :success
response_body = JSON.parse(@response.body)
assert_equal true, response_body['wol']
end

test 'should return error when host has no primary interface' do
@host.interfaces = []
@host.save!

put :wol, params: { :id => @host.to_param }

assert_response :unprocessable_entity
response_body = JSON.parse(@response.body)
assert_match(/Host has no primary interface/, response_body['error']['message'])
end

test 'should return error when primary interface has no MAC address' do
@primary_interface.update_attribute(:mac, nil)

put :wol, params: { :id => @host.to_param }

assert_response :unprocessable_entity
response_body = JSON.parse(@response.body)
assert_match(/Primary interface has no MAC address/, response_body['error']['message'])
end

test 'should return error when primary interface has empty MAC address' do
@primary_interface.update_attribute(:mac, '')

put :wol, params: { :id => @host.to_param }

assert_response :unprocessable_entity
response_body = JSON.parse(@response.body)
assert_match(/Primary interface has no MAC address/, response_body['error']['message'])
end

test 'should return error when primary interface subnet has no DHCP proxy' do
@primary_interface.subnet.update_attribute(:dhcp, nil)

put :wol, params: { :id => @host.to_param }

assert_response :unprocessable_entity
response_body = JSON.parse(@response.body)
assert_match(/Primary interface subnet has no DHCP proxy configured/, response_body['error']['message'])
end

test 'should return error when DHCP proxy does not have WOL feature' do
@dhcp_proxy.features.delete_all

put :wol, params: { :id => @host.to_param }

assert_response :unprocessable_entity
response_body = JSON.parse(@response.body)
assert_match(/DHCP proxy does not have WOL feature enabled/, response_body['error']['message'])
end

test 'should handle ProxyException with proper error message' do
proxy_exception = ProxyException.new('http://proxy.example.com/wol',
StandardError.new('Network error'),
N_("Unable to send Wake on LAN request for MAC %s"),
'00:61:23:18:48:a5')
ProxyAPI::Wol.any_instance.expects(:wake).with('00:61:23:18:48:a5').raises(proxy_exception)

put :wol, params: { :id => @host.to_param }

assert_response :unprocessable_entity
response_body = JSON.parse(@response.body)
assert_match(/Unable to send Wake on LAN request/, response_body['error']['message'])
end

test 'should return 404 for non-existent host' do
put :wol, params: { :id => 'non-existent-host' }

assert_response :not_found
end

context 'permissions' do
setup do
setup_user 'view', 'hosts'
setup_user 'power', 'hosts'
end

test 'should allow user with power permission to send WOL request' do
ProxyAPI::Wol.any_instance.expects(:wake).with('00:61:23:18:48:a5').returns(true)

put :wol, params: { :id => @host.to_param }, session: set_session_user.merge(:user => @one.id)

assert_response :success
response_body = JSON.parse(@response.body)
assert_equal true, response_body['wol']
end

test 'should deny user without power permission' do
setup_user 'view', 'hosts'
# Don't add power permission

put :wol, params: { :id => @host.to_param }, session: set_session_user.merge(:user => @one.id)

assert_response :forbidden
end
end
end
end
69 changes: 69 additions & 0 deletions test/unit/proxy_api/wol_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
require 'test_helper'

class ProxyApiWolTest < ActiveSupport::TestCase
def setup
@url = "http://dummyproxy.theforeman.org:8443"
@wol_proxy = ProxyAPI::Wol.new({:url => @url})
end

test "base url should equal /wol" do
expected = @url + "/wol"
assert_equal(expected, @wol_proxy.url)
end

test "wake should raise exception when MAC address is nil" do
exception = assert_raise ProxyAPI::ProxyException do
@wol_proxy.wake(nil)
end
assert_includes(exception.message, "Must define a MAC address")
end

test "wake should handle proxy communication errors" do
mac = "00:11:22:33:44:55"
error = StandardError.new("Connection timeout")

@wol_proxy.stubs(:post).raises(error)

exception = assert_raise ProxyAPI::ProxyException do
@wol_proxy.wake(mac)
end

assert_match(/Unable to send Wake on LAN request for MAC/, exception.message)
assert_match(/#{mac}/, exception.message)
end

test "wake should handle JSON parsing errors" do
mac = "00:11:22:33:44:55"
expected_params = { :mac_address => mac }

@wol_proxy.stubs(:post).with(expected_params).returns(fake_rest_client_response("invalid json"))
@wol_proxy.stubs(:parse).raises(JSON::ParserError.new("Invalid JSON"))

exception = assert_raise ProxyAPI::ProxyException do
@wol_proxy.wake(mac)
end

assert_match(/Unable to send Wake on LAN request for MAC/, exception.message)
assert_match(/#{mac}/, exception.message)
end

test "wake should return parsed response on success" do
mac = "00:11:22:33:44:55"
expected_params = { :mac_address => mac }
response_data = { "status" => "success", "result" => true }

@wol_proxy.stubs(:post).with(expected_params).returns(fake_rest_client_response(response_data))
@wol_proxy.stubs(:parse).returns(response_data)

result = @wol_proxy.wake(mac)
assert_equal(response_data, result)
end

private

def fake_rest_client_response(data)
response = mock('RestClient::Response')
response.stubs(:body).returns(data.to_json)
response
end
end
2 changes: 1 addition & 1 deletion test/unit/shared/access_permissions_test_base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def check_routes(app_routes, skipped_actions, skip_patterns: [/^(api\/v2\/)?(dum
# Pass if the controller deliberately skips login requirement
next if controller < ApplicationController && filters.select { |f| f.filter == :require_login }.empty?

assert_not_empty Foreman::AccessControl.permissions.select { |p| p.actions.include? path }, "permission for #{path} not found, check access_permissions.rb"
assert_not_empty Foreman::AccessControl.permissions.select { |p| p.actions.include? path }, "permission for #{path} not found, check config/initializers/f_foreman_permissions.rb.rb"
end
end
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
export const mockHost = {
hostId: 1,
hostFriendlyId: 'test-host.example.com',
hostName: 'test-host.example.com',
computeId: 123,
isBuild: false,
};

export const basePermissions = {
destroy_hosts: true,
create_hosts: true,
edit_hosts: true,
build_hosts: true,
power_hosts: true,
};

export const noPermissions = {
destroy_hosts: false,
create_hosts: false,
edit_hosts: false,
build_hosts: false,
power_hosts: false,
};

export const noPowerPermissions = {
...basePermissions,
power_hosts: false,
};

export const baseProps = {
...mockHost,
permissions: basePermissions,
};

export const noPowerProps = {
...mockHost,
permissions: noPowerPermissions,
};

export const noPermissionProps = {
...mockHost,
permissions: noPermissions,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { shallowRenderComponentWithFixtures } from '../../../../common/testHelpers';
import ActionsBar from '../index';
import {
baseProps,
noPowerProps,
noPermissionProps
} from './ActionsBar.fixtures';

// Mock the required external dependencies
jest.mock('../../../../../foreman_navigation', () => ({
visit: jest.fn(),
}));

jest.mock('../../../../Root/Context/ForemanContext', () => ({
useForemanSettings: () => ({ destroyVmOnHostDelete: false }),
useForemanHostsPageUrl: () => '/hosts',
}));

jest.mock('react-redux', () => ({
useSelector: jest.fn(() => []),
useDispatch: () => jest.fn(),
connect: jest.fn(() => (component) => component),
}));

const fixtures = {
'renders ActionsBar with all permissions (including power)': baseProps,
'renders ActionsBar without power permissions': noPowerProps,
'renders ActionsBar without any permissions': noPermissionProps,
};

describe('ActionsBar', () => {
describe('rendering', () => {
const components = shallowRenderComponentWithFixtures(ActionsBar, fixtures);
components.forEach(({ description, component }) => {
it(description, () => {
expect(component).toMatchSnapshot();
});
});
});
});
Loading
Loading