Zonemaster-Backend/t/db.t
use strict;
use warnings;
use utf8;
use Encode;
use Test::More; # see done_testing()
use_ok( 'Zonemaster::Backend::DB' );
sub encode_and_fingerprint {
my $params = shift;
my $self = "Zonemaster::Backend::DB";
my $encoded_params = $self->encode_params( $params );
my $fingerprint = $self->generate_fingerprint( $params );
return ( $encoded_params, $fingerprint );
}
subtest 'encoding and fingerprint' => sub {
subtest 'missing properties' => sub {
my %params = ( domain => "example.com" );
my $expected_encoded_params = '{"domain":"example.com","ds_info":[],"ipv4":null,"ipv6":null,"nameservers":[],"profile":"default"}';
my ( $encoded_params, $fingerprint ) = encode_and_fingerprint( \%params );
is $encoded_params, $expected_encoded_params, 'domain only: the encoded strings should match';
#diag ($fingerprint);
my $expected_encoded_params_v4_true = '{"domain":"example.com","ds_info":[],"ipv4":true,"ipv6":null,"nameservers":[],"profile":"default"}';
$params{ipv4} = JSON::PP->true;
my ( $encoded_params_ipv4, $fingerprint_ipv4 ) = encode_and_fingerprint( \%params );
is $encoded_params_ipv4, $expected_encoded_params_v4_true, 'add ipv4: the encoded strings should match';
isnt $fingerprint_ipv4, $fingerprint, 'fingerprints should not match';
};
subtest 'array properties' => sub {
subtest 'ds_info' => sub {
my %params1 = (
domain => "example.com",
ds_info => [{
algorithm => 8,
keytag => 11627,
digtype => 2,
digest => "a6cca9e6027ecc80ba0f6d747923127f1d69005fe4f0ec0461bd633482595448"
}]
);
my %params2 = (
ds_info => [{
digtype => 2,
algorithm => 8,
keytag => 11627,
digest => "a6cca9e6027ecc80ba0f6d747923127f1d69005fe4f0ec0461bd633482595448"
}],
domain => "example.com"
);
my ( $encoded_params1, $fingerprint1 ) = encode_and_fingerprint( \%params1 );
my ( $encoded_params2, $fingerprint2 ) = encode_and_fingerprint( \%params2 );
is $fingerprint1, $fingerprint2, 'ds_info same fingerprint';
is $encoded_params1, $encoded_params2, 'ds_info same encoded string';
};
subtest 'nameservers order' => sub {
my %params1 = (
domain => "example.com",
nameservers => [
{ ns => "ns2.nic.fr", ip => "192.134.4.1" },
{ ns => "ns1.nic.fr" },
{ ip => "192.0.2.1", ns => "ns3.nic.fr"}
]
);
my %params2 = (
nameservers => [
{ ns => "ns3.nic.fr", ip => "192.0.2.1" },
{ ns => "ns1.nic.fr" },
{ ip => "192.134.4.1", ns => "ns2.nic.fr"}
],
domain => "example.com"
);
my %params3 = (
domain => "example.com",
nameservers => [
{ ip => "", ns => "ns1.nic.fr" },
{ ns => "ns3.nic.FR", ip => "192.0.2.1" },
{ ns => "ns2.nic.fr", ip => "192.134.4.1" }
]
);
my %params4 = (
domain => "example.com",
nameservers => [
{ ip => "192.134.4.1", ns => "nS2.Nic.FR"},
{ ns => "Ns1.nIC.fR", ip => "" },
{ ns => "ns3.nic.fr", ip => "192.0.2.1" }
]
);
my ( $encoded_params1, $fingerprint1 ) = encode_and_fingerprint( \%params1 );
my ( $encoded_params2, $fingerprint2 ) = encode_and_fingerprint( \%params2 );
my ( $encoded_params3, $fingerprint3 ) = encode_and_fingerprint( \%params3 );
my ( $encoded_params4, $fingerprint4 ) = encode_and_fingerprint( \%params4 );
is $fingerprint1, $fingerprint2, 'nameservers: same fingerprint';
is $encoded_params1, $encoded_params2, 'nameservers: same encoded string';
is $fingerprint1, $fingerprint3, 'nameservers: same fingerprint (empty ip)';
is $encoded_params1, $encoded_params3, 'nameservers: same encoded string (empty ip)';
is $fingerprint1, $fingerprint4, 'nameservers: same fingerprint (ignore nameservers\' ns case)';
is $encoded_params1, $encoded_params4, 'nameservers: same encoded string (ignore nameservers\' ns case)';
};
};
subtest 'should be case insensitive' => sub {
my %params1 = ( domain => "example.com" );
my %params2 = ( domain => "eXamPLe.COm" );
my ( $encoded_params1, $fingerprint1 ) = encode_and_fingerprint( \%params1 );
my ( $encoded_params2, $fingerprint2 ) = encode_and_fingerprint( \%params2 );
is $fingerprint1, $fingerprint2, 'same fingerprint';
is $encoded_params1, $encoded_params2, 'same encoded string';
};
subtest 'garbage properties set' => sub {
my $expected_encoded_params = '{"client":"GUI v3.3.0","domain":"example.com","ds_info":[],"ipv4":null,"ipv6":null,"nameservers":[],"profile":"default"}';
my %params1 = (
domain => "example.com",
);
my %params2 = (
domain => "example.com",
client => "GUI v3.3.0"
);
my ( $encoded_params1, $fingerprint1 ) = encode_and_fingerprint( \%params1 );
my ( $encoded_params2, $fingerprint2 ) = encode_and_fingerprint( \%params2 );
is $fingerprint1, $fingerprint2, 'leave out garbage property in fingerprint computation...';
is $encoded_params2, $expected_encoded_params, '...but keep it in the encoded string';
};
subtest 'should have different fingerprints' => sub {
subtest 'different profiles' => sub {
my %params1 = (
domain => "example.com",
profile => "profile_1"
);
my %params2 = (
domain => "example.com",
profile => "profile_2"
);
my ( undef, $fingerprint1 ) = encode_and_fingerprint( \%params1 );
my ( undef, $fingerprint2 ) = encode_and_fingerprint( \%params2 );
isnt $fingerprint1, $fingerprint2, 'different profiles, different fingerprints';
};
subtest 'different IP protocols' => sub {
my %params1 = (
domain => "example.com",
ipv4 => "true",
ipv6 => "false"
);
my %params2 = (
domain => "example.com",
ipv4 => "false",
ipv6 => "true"
);
my ( undef, $fingerprint1 ) = encode_and_fingerprint( \%params1 );
my ( undef, $fingerprint2 ) = encode_and_fingerprint( \%params2 );
isnt $fingerprint1, $fingerprint2, 'different IP protocols, different fingerprints';
};
};
subtest 'IDN domain' => sub {
my $expected_encoded_params = encode_utf8( '{"domain":"xn--caf-dma.example","ds_info":[],"ipv4":true,"ipv6":true,"nameservers":[],"profile":"default"}' );
my $expected_fingerprint = '8cb027ff2c175f48aed2623abad0cdd2';
my %params = ( domain => "café.example" );
$params{ipv4} = JSON::PP->true;
$params{ipv6} = JSON::PP->true;
my ( $encoded_params, $fingerprint ) = encode_and_fingerprint( \%params );
is $encoded_params, $expected_encoded_params, 'IDN domain: the encoded strings should match';
is $fingerprint, $expected_fingerprint, 'IDN domain: correct fingerprint';
};
subtest 'final dots' => sub {
subtest 'in domain' => sub {
my %params1 = ( domain => "example.com" );
my %params2 = ( domain => "example.com." );
my $expected_encoded_params = encode_utf8( '{"domain":"example.com","ds_info":[],"ipv4":null,"ipv6":null,"nameservers":[],"profile":"default"}' );
my ( $encoded_params1, $fingerprint1 ) = encode_and_fingerprint( \%params1 );
my ( $encoded_params2, $fingerprint2 ) = encode_and_fingerprint( \%params2 );
is $fingerprint1, $fingerprint2, 'same fingerprint';
is $encoded_params1, $expected_encoded_params, 'the encoded strings should match';
};
subtest 'in nameserver' => sub {
my %params1 = ( domain => "example.com", nameservers => [ { ns => "ns1.example.com." } ] );
my %params2 = ( domain => "example.com", nameservers => [ { ns => "ns1.example.com" } ] );
my $expected_encoded_params = encode_utf8( '{"domain":"example.com","ds_info":[],"ipv4":null,"ipv6":null,"nameservers":[{"ns":"ns1.example.com"}],"profile":"default"}' );
my ( $encoded_params1, $fingerprint1 ) = encode_and_fingerprint( \%params1 );
my ( $encoded_params2, $fingerprint2 ) = encode_and_fingerprint( \%params2 );
is $fingerprint1, $fingerprint2, 'same fingerprint';
is $encoded_params1, $expected_encoded_params, 'the encoded strings should match';
};
subtest 'root is not modified' => sub {
my %params = ( domain => "." );
my $expected_encoded_params = encode_utf8( '{"domain":".","ds_info":[],"ipv4":null,"ipv6":null,"nameservers":[],"profile":"default"}' );
my ( $encoded_params, $fingerprint ) = encode_and_fingerprint( \%params );
is $encoded_params, $expected_encoded_params, 'the encoded strings should match';
};
};
};
done_testing();