Skip to content

Commit

Permalink
Merge pull request #21 from ninech/39593-find_by_method
Browse files Browse the repository at this point in the history
Add find_by method for Entities class
  • Loading branch information
born4new committed Jan 17, 2018
2 parents 9a1cc4c + 5dd05fc commit 9b385d7
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 2 deletions.
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,23 @@ sites = NetboxClientRuby.dcim.sites
puts "There are #{sites.total} sites in your Netbox instance."

# get the first site of the result set
first_site = sites[0]
first_site = sites.first
puts "The first site is called #{first_site.name}."

# filter devices by site
# Note that Netbox filters by *slug*
devices_of_site = NetboxClientRuby.dcim.devices.filter(site: first_site.slug)
puts "#{devices_of_site.total} devices belong to the site. #{devices_of_site}.length devices have been fetched."

# Finds a specific device
NetboxClientRuby.dcim.devices.find_by(name: 'my-device', other_field: 'other-value')

# Finds a specific device with a certain custom field
NetboxClientRuby.dcim.devices.find_by(cf_custom_url: 'https://google.com')

# Or a mix of regular and custom fields
NetboxClientRuby.dcim.devices.find_by(name: 'my-device', cf_custom_field: 'custom-value')

# get a site by id
s = NetboxClientRuby.dcim.site(1)

Expand Down
22 changes: 21 additions & 1 deletion lib/netbox_client_ruby/entities.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,28 @@ def path(path = nil)
end
end

def find_by(attributes)
fail ArgumentError, '"attributes" expects a hash' unless attributes.is_a? Hash

filter(attributes).find do |netbox_object|
attributes.all? do |filter_key, filter_value|
if filter_key.to_s.start_with?('cf_')
custom_field = filter_key.to_s.sub('cf_', '')

netbox_object.custom_fields[custom_field] == filter_value
else
if netbox_object.respond_to?(filter_key)
netbox_object.public_send(filter_key) == filter_value
else
false
end
end
end
end
end

def filter(filter)
raise ArgumentError, '"filter" expects a hash' unless filter.is_a? Hash
fail ArgumentError, '"filter" expects a hash' unless filter.is_a? Hash

@filter = filter
reset
Expand Down
117 changes: 117 additions & 0 deletions spec/netbox_client_ruby/entities_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ def entity_creator(raw_entity)
OpenStruct.new raw_entity
end
end

class TestEntities2
include NetboxClientRuby::Entities

path '/test'
data_key 'non_existent'
count_key 'non_existent'
end

class TestEntities3
include NetboxClientRuby::Entities
end
Expand Down Expand Up @@ -190,6 +192,121 @@ class TestEntities3
end
end

describe '#find_by' do
let(:found_object) { subject.find_by(filter_attributes) }

context 'not filtering with a hash' do
let(:filter_attributes) { ['This is not a hash'] }

it { expect { found_object }.to raise_error('"attributes" expects a hash') }
end

context 'one search criterion' do
let(:raw_data) do
super().tap do |raw_data|
raw_data['data_node'] = [
{ 'name' => 'obj1' },
{ 'name' => 'obj2' },
{ 'name' => 'obj3' },
]
end
end

context 'the filter key does not exist' do
let(:filter_attributes) { { 'does-not-exist' => 'obj2' } }

it { expect(found_object).to be_nil }
end

context 'the filter value does not exist' do
let(:filter_attributes) { { 'name' => 'obj5' } }

it { expect(found_object).to be_nil }
end

context 'the filter value is not exact' do
let(:filter_attributes) { { 'name' => 'obj' } }

it { expect(found_object).to be_nil }
end

context 'with correct filters' do
let(:filter_attributes) { { 'name' => 'obj2' } }

it { expect(found_object.name).to eq('obj2') }
end

describe 'search for custom fields' do
let(:raw_data) do
super().tap do |raw_data|
raw_data['data_node'] = [
{ 'name' => 'my-object', 'custom_fields' => { 'nine_urn' => 'urn:nine:server:1234' } },
{ 'name' => 'obj1', 'custom_fields' => { 'nine_urn' => 'urn:nine:server:123456' } },
{ 'name' => 'obj1', 'custom_fields' => { 'nine_urn' => 'urn:nine:server:12345678' } },
]
end
end

context 'the filter key is not prefixed with cf_' do
let(:filter_attributes) { { 'nine_urn' => 'urn:nine:server:1234' } }

it { expect(found_object).to be_nil }
end

context 'the filter value is not exact' do
let(:filter_attributes) { { 'cf_nine_urn' => 'urn:nine:server:12' } }

it { expect(found_object).to be_nil }
end

context 'with correct filters' do
let(:filter_attributes) { { 'cf_nine_urn' => 'urn:nine:server:1234' } }

it { expect(found_object.name).to eq('my-object') }
end
end
end

context 'many search criteria' do
let(:raw_data) do
super().tap do |raw_data|
raw_data['data_node'] = [
{ 'name' => 'obj1', 'model' => 'tail' },
{ 'name' => 'obj2', 'model' => 'tailgator' },
{ 'name' => 'obj3', 'model' => 'tailorswift' },
]
end
end

context 'one filter key does not exist' do
let(:filter_attributes) { { 'name' => 'obj1', 'does-not-exist' => 'tail' } }

it { expect(found_object).to be_nil }
end

context 'the filter value does not exist' do
let(:filter_attributes) { { 'name' => 'obj1', 'model' => 'tailgator' } }

it { expect(found_object).to be_nil }
end

context 'the filter value is not exact' do
let(:filter_attributes) { { 'name' => 'obj1', 'model' => 'tai' } }

it { expect(found_object).to be_nil }
end

context 'with correct filters' do
let(:filter_attributes) { { 'name' => 'obj3', model: 'tailorswift' } }

it 'returns the correct object' do
expect(found_object.name).to eq('obj3')
expect(found_object.model).to eq('tailorswift')
end
end
end
end

describe '#filter' do
let(:filter) { { something: true } }

Expand Down

0 comments on commit 9b385d7

Please sign in to comment.