Skip to content

Commit

Permalink
Merge pull request #126 from mocktools/develop
Browse files Browse the repository at this point in the history
Ruby DnsMock v1.6.0
  • Loading branch information
bestwebua authored Jan 5, 2024
2 parents 4fe0483 + 2305d7e commit e04f255
Show file tree
Hide file tree
Showing 12 changed files with 223 additions and 2 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.6.0] - 2024-01-05

### Added

- Added ability to mock SRV records. Thanks [@Siphonay](https://github.com/Siphonay) for feature suggestion

### Updated

- Updated gem version
- Updated gem documentation

## [1.5.18] - 2024-01-03

### Updated
Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,16 @@ records = {
},
'1.2.3.4' => { # You can define RDNS host address without lookup prefix. It will be converted to 4.3.2.1.in-addr.arpa automatically
ptr: %w[domain_1.com domain_2.com]
},
'_sip._tcp.example.com' => { # Please use {_service._proto.domain} pattern to follow the valid RFC-2782 SRV host pattern representation
srv: [
{
priority: 0,
weight: 10,
port: 5_060,
target: 'domain.com'
}
]
}
}

Expand Down
4 changes: 3 additions & 1 deletion lib/dns_mock/core.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
require 'socket'

module DnsMock
AVAILABLE_DNS_RECORD_TYPES = %i[a aaaa cname mx ns ptr soa txt].freeze
AVAILABLE_DNS_RECORD_TYPES = %i[a aaaa cname mx ns ptr soa srv txt].freeze

module Error
require_relative '../dns_mock/error/argument_type'
Expand Down Expand Up @@ -33,6 +33,7 @@ module Factory
require_relative '../dns_mock/record/factory/ns'
require_relative '../dns_mock/record/factory/ptr'
require_relative '../dns_mock/record/factory/soa'
require_relative '../dns_mock/record/factory/srv'
require_relative '../dns_mock/record/factory/txt'
end
end
Expand All @@ -47,6 +48,7 @@ module Builder
require_relative '../dns_mock/record/builder/ns'
require_relative '../dns_mock/record/builder/ptr'
require_relative '../dns_mock/record/builder/soa'
require_relative '../dns_mock/record/builder/srv'
require_relative '../dns_mock/record/builder/txt'
end
end
Expand Down
19 changes: 19 additions & 0 deletions lib/dns_mock/record/builder/srv.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

module DnsMock
module Record
module Builder
class Srv < DnsMock::Record::Builder::Base
FACTORY_ARGS_ORDER = %i[priority weight port target].freeze

def build
records_data.map do |record_data|
target_factory.new(
record_data: record_data.values_at(*DnsMock::Record::Builder::Srv::FACTORY_ARGS_ORDER)
).create
end
end
end
end
end
end
15 changes: 15 additions & 0 deletions lib/dns_mock/record/factory/srv.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

module DnsMock
module Record
module Factory
Srv = ::Class.new(DnsMock::Record::Factory::Base) do
record_type :srv

def instance_params
record_data[0..-2] << create_dns_name(record_data.last)
end
end
end
end
end
1 change: 1 addition & 0 deletions lib/dns_mock/server/records_dictionary_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class RecordsDictionaryBuilder
[DnsMock::Record::Builder::Ns, DnsMock::Record::Factory::Ns, ::Array],
[DnsMock::Record::Builder::Ptr, DnsMock::Record::Factory::Ptr, ::Array],
[DnsMock::Record::Builder::Soa, DnsMock::Record::Factory::Soa, ::Array],
[DnsMock::Record::Builder::Srv, DnsMock::Record::Factory::Srv, ::Array],
[DnsMock::Record::Builder::Txt, DnsMock::Record::Factory::Txt, ::Array]
]
).to_h.freeze
Expand Down
2 changes: 1 addition & 1 deletion lib/dns_mock/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module DnsMock
VERSION = '1.5.18'
VERSION = '1.6.0'
end
33 changes: 33 additions & 0 deletions spec/dns_mock/record/builder/srv_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# frozen_string_literal: true

RSpec.describe DnsMock::Record::Builder::Srv do
describe 'class dependencies' do
subject(:builder_class) { described_class }

it { is_expected.to be < DnsMock::Record::Builder::Base }
it { is_expected.to be_const_defined(:FACTORY_ARGS_ORDER) }
end

describe '.call' do
subject(:builder) { described_class.call(target_factory, records_data) }

let(:target_factory) { class_double('TargetFactory') }
let(:target_class_instance) { instance_double('TargetClass') }
let(:target_factory_instance) { instance_double('TargetFactory', create: target_class_instance) }
let(:records_data) do
(1..8).each_slice(4).map do |chunk|
DnsMock::Record::Builder::Srv::FACTORY_ARGS_ORDER.zip(chunk).to_h
end
end

it 'returns array of target class instances' do
records_data.each do |record_data|
expect(target_factory)
.to receive(:new)
.with(record_data: record_data.values)
.and_return(target_factory_instance)
end
expect(builder).to eq(::Array.new(records_data.size) { target_class_instance })
end
end
end
72 changes: 72 additions & 0 deletions spec/dns_mock/record/factory/srv_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# frozen_string_literal: true

RSpec.describe DnsMock::Record::Factory::Srv do
it { expect(described_class).to be < DnsMock::Record::Factory::Base }

describe '#instance_params' do
subject(:instance_params) { described_class.new(record_data: record_data).instance_params }

let(:int_params) { (0..3).to_a }
let(:dns_name) { random_hostname }
let(:record_data) { int_params + [dns_name] }
let(:expected_data) do
[
*int_params,
create_dns_name(dns_name)
]
end

it 'returns prepared target class instance params' do
expect(instance_params).to eq(expected_data)
end
end

describe '#create' do
subject(:create_factory) { described_class.new(record_data: record_data.values).create }

let(:record_data) do
{
priority: 0,
weight: 10,
port: 5_060,
target: target
}
end

context 'when valid record context' do
shared_examples 'returns instance of target class' do
it 'returns instance of target class' do
expect(DnsMock::Representer::Punycode).to receive(:call).with(target).and_call_original
expect(create_factory).to be_an_instance_of(described_class.target_class)
dns_names = record_data.slice(:target).transform_values do |value|
create_dns_name(ascii_hostname ? value : to_punycode_hostname(value))
end
record_data.merge(dns_names).each { |key, value| expect(create_factory.public_send(key)).to eq(value) }
end
end

context 'when ASCII hostname' do
let(:ascii_hostname) { true }
let(:target) { random_hostname }

include_examples 'returns instance of target class'
end

context 'when non ASCII hostname' do
let(:ascii_hostname) { false }
let(:target) { random_non_ascii_hostname }

include_examples 'returns instance of target class'
end
end

context 'when invalid record context' do
context 'when invalid mname' do
let(:target) { 42 }
let(:error_context) { "cannot interpret as DNS name: #{target}. Invalid SRV record context" }

it_behaves_like 'target class exception wrapper'
end
end
end
end
42 changes: 42 additions & 0 deletions spec/dns_mock_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,27 @@
.and_minimum(soa_record[:minimum])
.config(**rspec_dns_config)
end

it 'returns predefined SRV record' do
srv_record = records_by_domain[:srv].first

expect(domain).to have_dns
.with_type('SRV')
.and_priority(srv_record[:priority])
.config(**rspec_dns_config)
expect(domain).to have_dns
.with_type('SRV')
.and_weight(srv_record[:weight])
.config(**rspec_dns_config)
expect(domain).to have_dns
.with_type('SRV')
.and_port(srv_record[:port])
.config(**rspec_dns_config)
expect(domain).to have_dns
.with_type('SRV')
.and_target(srv_record[:target])
.config(**rspec_dns_config)
end
end

context 'when internationalized records' do
Expand Down Expand Up @@ -269,6 +290,27 @@
.and_minimum(soa_record[:minimum])
.config(**rspec_dns_config)
end

it 'returns predefined SRV record' do
srv_record = records_by_domain[:srv].first

expect(domain).to have_dns
.with_type('SRV')
.and_priority(srv_record[:priority])
.config(**rspec_dns_config)
expect(domain).to have_dns
.with_type('SRV')
.and_weight(srv_record[:weight])
.config(**rspec_dns_config)
expect(domain).to have_dns
.with_type('SRV')
.and_port(srv_record[:port])
.config(**rspec_dns_config)
expect(domain).to have_dns
.with_type('SRV')
.and_target(to_punycode_hostname(srv_record[:target]))
.config(**rspec_dns_config)
end
end

context 'when records not found' do
Expand Down
8 changes: 8 additions & 0 deletions spec/support/helpers/context_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ def create_records(hostname = DnsMock::RspecHelper::ContextGenerator.random_host
expire: 604_800,
minimum: 3_600
}
],
srv: [
{
priority: 0,
weight: 10,
port: 5_060,
target: random_hostname_by_ascii(hostname)
}
]
}.slice(*(records.empty? ? DnsMock::AVAILABLE_DNS_RECORD_TYPES : records))
}
Expand Down
8 changes: 8 additions & 0 deletions spec/support/helpers/records_dictionary.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ def create_records_dictionary(hostname = DnsMock::RspecHelper::ContextGenerator.
expire: 604_800,
minimum: 3_600
}
],
srv: [
{
priority: 0,
weight: 10,
port: 5_060,
target: random_hostname
}
]
}.slice(*(options.empty? ? DnsMock::AVAILABLE_DNS_RECORD_TYPES : options))
}
Expand Down

0 comments on commit e04f255

Please sign in to comment.