Change-Id: I5672073eaa8b5594a3e4d4d2be64054584771d2bchanges/85/3585/9
parent
d0f0a846c8
commit
7fffffb199
@ -0,0 +1,250 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
|
||||
use Data::Dumper;
|
||||
use NGCP::Schema;
|
||||
use NGCP::Panel::Utils::Subscriber;
|
||||
use NGCP::Panel::Utils::Preferences;
|
||||
use Test::More;
|
||||
use Data::HAL qw();
|
||||
use Data::HAL::Link qw();
|
||||
use Safe::Isa qw($_isa);
|
||||
use NGCP::Panel::Form::CFSimpleAPI;
|
||||
|
||||
my $schema = NGCP::Schema->connect();
|
||||
my $ql_exists = 0;
|
||||
my ($ql,$ana);
|
||||
|
||||
if($ql_exists){
|
||||
#use DBIx::Class::QueryLog;
|
||||
#use DBIx::Class::QueryLog::Analyzer;
|
||||
my $ql = DBIx::Class::QueryLog->new;
|
||||
$schema->storage->debugobj($ql);
|
||||
$schema->storage->debug(1);
|
||||
my $ana = DBIx::Class::QueryLog::Analyzer->new({ querylog => $ql });
|
||||
$ql->bucket('origin');
|
||||
}
|
||||
|
||||
my $time = time();
|
||||
print "start;\n";
|
||||
#print Dumper($schema);
|
||||
|
||||
my $item_rs = $schema->resultset('voip_subscribers')->search( {
|
||||
'me.status' => { '!=' => 'terminated' }
|
||||
},{
|
||||
prefetch => { 'provisioning_voip_subscriber'=>'voip_cf_mappings'},
|
||||
#prefetch => 'provisioning_voip_subscriber',
|
||||
rows => 200,
|
||||
},
|
||||
);
|
||||
my (@arr_orig,@arr_opt);
|
||||
for my $item ($item_rs->all) {
|
||||
# print Dumper({$item->get_inflated_columns});
|
||||
my %resource = ();
|
||||
my $prov_subs = $item->provisioning_voip_subscriber;
|
||||
for my $cf_type (qw/cfu cfb cft cfna/) {
|
||||
my $mapping = $schema->resultset('voip_cf_mappings')->search({
|
||||
subscriber_id => $prov_subs->id,
|
||||
type => $cf_type,
|
||||
})->first;
|
||||
if ($mapping) {
|
||||
$resource{$cf_type} = _contents_from_cfm($mapping, $item);
|
||||
} else {
|
||||
$resource{$cf_type} = {};
|
||||
}
|
||||
}
|
||||
if(keys %{$resource{cft}}){
|
||||
my $ringtimeout_preference = NGCP::Panel::Utils::Preferences::get_usr_preference_rs(
|
||||
c => undef, attribute => 'ringtimeout', prov_subscriber => $prov_subs, schema => $schema )->first;
|
||||
$ringtimeout_preference = $ringtimeout_preference ? $ringtimeout_preference->value : undef;
|
||||
$resource{cft}{ringtimeout} = $ringtimeout_preference;
|
||||
}
|
||||
additional_processing($item, \%resource);
|
||||
push @arr_orig, \%resource;
|
||||
}
|
||||
print "1.time=".(time()-$time).";\n";
|
||||
#exit;
|
||||
if($ql_exists){
|
||||
$ql->bucket('optimized');
|
||||
}
|
||||
$time = time();
|
||||
|
||||
for my $item ($item_rs->all) {
|
||||
my %resource = ();
|
||||
my $prov_subs = $item->provisioning_voip_subscriber;
|
||||
@resource{qw/cfu cfb cft cfna/} = ({}) x 4;
|
||||
for my $item_cf ($item->provisioning_voip_subscriber->voip_cf_mappings->all){
|
||||
$resource{$item_cf->type} = _contents_from_cfm($item_cf, $item);
|
||||
}
|
||||
if(keys %{$resource{cft}}){
|
||||
my $ringtimeout_preference = NGCP::Panel::Utils::Preferences::get_usr_preference_rs(
|
||||
c => undef, attribute => 'ringtimeout', prov_subscriber => $prov_subs, schema => $schema )->first;
|
||||
$ringtimeout_preference = $ringtimeout_preference ? $ringtimeout_preference->value : undef;
|
||||
$resource{cft}{ringtimeout} = $ringtimeout_preference;
|
||||
}
|
||||
additional_processing($item, \%resource);
|
||||
push @arr_opt, \%resource;
|
||||
}
|
||||
print "2.time=".(time()-$time).";\n";
|
||||
|
||||
is_deeply(\@arr_orig, \@arr_opt, "check that arrays are equiv");
|
||||
#print Dumper[\@arr_orig, \@arr_opt];
|
||||
if($ql_exists){
|
||||
print Dumper $ana->get_totaled_queries_by_bucket;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
sub additional_processing{
|
||||
my($item,$resource) = @_;
|
||||
my $type='';
|
||||
my %resource=%$resource;
|
||||
my $hal = Data::HAL->new(
|
||||
links => [
|
||||
Data::HAL::Link->new(
|
||||
relation => 'curies',
|
||||
href => 'http://purl.org/sipwise/ngcp-api/#rel-{rel}',
|
||||
name => 'ngcp',
|
||||
templated => 1,
|
||||
),
|
||||
Data::HAL::Link->new(relation => 'collection', href => sprintf("%s", '')),
|
||||
Data::HAL::Link->new(relation => 'profile', href => 'http://purl.org/sipwise/ngcp-api/'),
|
||||
Data::HAL::Link->new(relation => 'self', href => sprintf("%s%s", '', $item->id)),
|
||||
Data::HAL::Link->new(relation => "ngcp:$type", href => sprintf("/api/%s/%s", $type, $item->id)),
|
||||
Data::HAL::Link->new(relation => 'ngcp:subscribers', href => sprintf("/api/subscribers/%d", $item->id)),
|
||||
],
|
||||
relation => 'ngcp:callforwards',
|
||||
);
|
||||
my $form=NGCP::Panel::Form::CFSimpleAPI->new();
|
||||
|
||||
validate_form(
|
||||
form => $form,
|
||||
resource => \%resource,
|
||||
run => 0,
|
||||
);
|
||||
|
||||
$hal->resource(\%resource);
|
||||
|
||||
}
|
||||
sub _contents_from_cfm {
|
||||
my ($cfm_item, $sub) = @_;
|
||||
my (@times, @destinations);
|
||||
my $timeset_item = $cfm_item->time_set;
|
||||
my $dset_item = $cfm_item->destination_set;
|
||||
for my $time ($timeset_item ? $timeset_item->voip_cf_periods->all : () ) {
|
||||
push @times, {$time->get_inflated_columns};
|
||||
delete @{$times[-1]}{'time_set_id', 'id'};
|
||||
}
|
||||
for my $dest ($dset_item ? $dset_item->voip_cf_destinations->all : () ) {
|
||||
my ($d, $duri) = NGCP::Panel::Utils::Subscriber::destination_to_field($dest->destination);
|
||||
my $deflated;
|
||||
if($d eq "uri") {
|
||||
$deflated = NGCP::Panel::Utils::Subscriber::uri_deflate($duri,$sub) if $d eq "uri";
|
||||
$d = $dest->destination;
|
||||
}
|
||||
push @destinations, {$dest->get_inflated_columns,
|
||||
destination => $d,
|
||||
$deflated ? (simple_destination => $deflated) : (),
|
||||
};
|
||||
delete @{$destinations[-1]}{'destination_set_id', 'id'};
|
||||
}
|
||||
return {times => \@times, destinations => \@destinations};
|
||||
}
|
||||
sub validate_form {
|
||||
my (%params) = @_;
|
||||
|
||||
my $resource = $params{resource};
|
||||
my $form = $params{form};
|
||||
my $run = $params{run} // 1;
|
||||
my $exceptions = $params{exceptions} // [];
|
||||
my $form_params = $params{form_params} // {};
|
||||
push @{ $exceptions }, "external_id";
|
||||
|
||||
my @normalized = ();
|
||||
|
||||
# move {xxx_id} into {xxx}{id} for FormHandler
|
||||
foreach my $key(keys %{ $resource } ) {
|
||||
my $skip_normalize = grep {/^$key$/} @{ $exceptions };
|
||||
if($key =~ /^(.+)_id$/ && !$skip_normalize && !exists $resource->{$1}) {
|
||||
push @normalized, $1;
|
||||
$resource->{$1}{id} = delete $resource->{$key};
|
||||
}
|
||||
}
|
||||
|
||||
# remove unknown keys
|
||||
my %fields = map { $_->name => $_ } $form->fields;
|
||||
validate_fields($resource, \%fields, $run);
|
||||
|
||||
if($run) {
|
||||
# check keys/vals
|
||||
$form->process(params => $resource, posted => 1, %{$form_params} );
|
||||
unless($form->validated) {
|
||||
my $e = join '; ', map {
|
||||
sprintf 'field=\'%s\', input=\'%s\', errors=\'%s\'',
|
||||
($_->parent->$_isa('HTML::FormHandler::Field') ? $_->parent->name . '_' : '') . $_->name,
|
||||
$_->input // '',
|
||||
join('', @{ $_->errors })
|
||||
} $form->error_fields;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# move {xxx}{id} back into {xxx_id} for DB
|
||||
foreach my $key(@normalized) {
|
||||
next unless(exists $resource->{$key});
|
||||
$resource->{$key . '_id'} = defined($resource->{$key}{id}) ?
|
||||
int($resource->{$key}{id}) :
|
||||
$resource->{$key}{id};
|
||||
delete $resource->{$key};
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub validate_fields {
|
||||
my ($resource, $fields, $run) = @_;
|
||||
|
||||
for my $k (keys %{ $resource }) {
|
||||
#if($resource->{$k}->$_isa('JSON::XS::Boolean') || $resource->{$k}->$_isa('JSON::PP::Boolean')) {
|
||||
if($resource->{$k}->$_isa('JSON::PP::Boolean')) {
|
||||
$resource->{$k} = $resource->{$k} ? 1 : 0;
|
||||
}
|
||||
unless(exists $fields->{$k}) {
|
||||
delete $resource->{$k};
|
||||
}
|
||||
$resource->{$k} = DateTime::Format::RFC3339->format_datetime($resource->{$k})
|
||||
if $resource->{$k}->$_isa('DateTime');
|
||||
$resource->{$k} = $resource->{$k} + 0
|
||||
if(defined $resource->{$k} && (
|
||||
$fields->{$k}->$_isa('HTML::FormHandler::Field::Integer') ||
|
||||
$fields->{$k}->$_isa('HTML::FormHandler::Field::Money') ||
|
||||
$fields->{$k}->$_isa('HTML::FormHandler::Field::Float')) &&
|
||||
(is_int($resource->{$k}) || is_decimal($resource->{$k})));
|
||||
|
||||
if (defined $resource->{$k} &&
|
||||
$fields->{$k}->$_isa('HTML::FormHandler::Field::Repeatable') &&
|
||||
"ARRAY" eq ref $resource->{$k} ) {
|
||||
for my $elem (@{ $resource->{$k} }) {
|
||||
my ($subfield_instance) = $fields->{$k}->fields;
|
||||
my %subfields = map { $_->name => $_ } $subfield_instance->fields;
|
||||
validate_fields($elem, \%subfields, $run);
|
||||
}
|
||||
}
|
||||
|
||||
# only do this for converting back from obj to hal
|
||||
# otherwise it breaks db fields with the \0 and \1 notation
|
||||
unless($run) {
|
||||
$resource->{$k} = $resource->{$k} ? JSON::true : JSON::false
|
||||
if(defined $resource->{$k} &&
|
||||
$fields->{$k}->$_isa('HTML::FormHandler::Field::Boolean'));
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
1;
|
@ -0,0 +1,12 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
|
||||
use Data::Dumper;
|
||||
|
||||
use NGCP::Panel::Form::CFSimpleAPI;
|
||||
|
||||
for(my $i=0; $i<200;$i++){
|
||||
my $form=NGCP::Panel::Form::CFSimpleAPI->new();
|
||||
}
|
||||
1;
|
@ -1,281 +1,115 @@
|
||||
use Sipwise::Base;
|
||||
use Net::Domain qw(hostfqdn);
|
||||
use LWP::UserAgent;
|
||||
use JSON qw();
|
||||
use Test::More;
|
||||
|
||||
my $uri = $ENV{CATALYST_SERVER} || ('https://'.hostfqdn.':4443');
|
||||
my ($netloc) = ($uri =~ m!^https?://(.*)/?.*$!);
|
||||
|
||||
my ($ua, $req, $res);
|
||||
$ua = LWP::UserAgent->new;
|
||||
|
||||
$ua->ssl_opts(
|
||||
verify_hostname => 0,
|
||||
SSL_verify_mode => 0,
|
||||
);
|
||||
my $user = $ENV{API_USER} // 'administrator';
|
||||
my $pass = $ENV{API_PASS} // 'administrator';
|
||||
$ua->credentials($netloc, "api_admin_http", $user, $pass);
|
||||
|
||||
# OPTIONS tests
|
||||
{
|
||||
$req = HTTP::Request->new('OPTIONS', $uri.'/api/callforwards/');
|
||||
$res = $ua->request($req);
|
||||
is($res->code, 200, "check options request");
|
||||
is($res->header('Accept-Post'), "application/hal+json; profile=http://purl.org/sipwise/ngcp-api/#rel-callforwards", "check Accept-Post header in options response");
|
||||
my $opts = JSON::from_json($res->decoded_content);
|
||||
my @hopts = split /\s*,\s*/, $res->header('Allow');
|
||||
ok(exists $opts->{methods} && ref $opts->{methods} eq "ARRAY", "check for valid 'methods' in body");
|
||||
foreach my $opt(qw( GET HEAD OPTIONS )) {
|
||||
ok(grep(/^$opt$/, @hopts), "check for existence of '$opt' in Allow header");
|
||||
ok(grep(/^$opt$/, @{ $opts->{methods} }), "check for existence of '$opt' in body");
|
||||
}
|
||||
}
|
||||
|
||||
my $t = time;
|
||||
my $reseller_id = 1;
|
||||
my $billing_profile_id; #dummy
|
||||
|
||||
# collection test
|
||||
my $firstcf = undef;
|
||||
my $firstcustomer; #dummy
|
||||
my $custcontact = undef; #dummy
|
||||
my @allcustomers = (); #dummy
|
||||
my $system_contact_id; #dummy
|
||||
{
|
||||
# iterate over customers collection to check next/prev links and status
|
||||
my $nexturi = $uri.'/api/callforwards/?page=1&rows=5';
|
||||
do {
|
||||
$res = $ua->get($nexturi);
|
||||
is($res->code, 200, "fetch cfs page");
|
||||
my $collection = JSON::from_json($res->decoded_content);
|
||||
my $selfuri = $uri . $collection->{_links}->{self}->{href};
|
||||
is($selfuri, $nexturi, "check _links.self.href of collection");
|
||||
my $colluri = URI->new($selfuri);
|
||||
|
||||
cmp_ok($collection->{total_count}, '>', 0, "check 'total_count' of collection");
|
||||
|
||||
my %q = $colluri->query_form;
|
||||
ok(exists $q{page} && exists $q{rows}, "check existence of 'page' and 'row' in 'self'");
|
||||
my $page = int($q{page});
|
||||
my $rows = int($q{rows});
|
||||
if($page == 1) {
|
||||
ok(!exists $collection->{_links}->{prev}->{href}, "check absence of 'prev' on first page");
|
||||
} else {
|
||||
ok(exists $collection->{_links}->{prev}->{href}, "check existence of 'prev'");
|
||||
}
|
||||
if(($collection->{total_count} / $rows) <= $page) {
|
||||
ok(!exists $collection->{_links}->{next}->{href}, "check absence of 'next' on last page");
|
||||
} else {
|
||||
ok(exists $collection->{_links}->{next}->{href}, "check existence of 'next'");
|
||||
}
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
if($collection->{_links}->{next}->{href}) {
|
||||
$nexturi = $uri . $collection->{_links}->{next}->{href};
|
||||
} else {
|
||||
$nexturi = undef;
|
||||
}
|
||||
|
||||
# TODO: I'd expect that to be an array ref in any case!
|
||||
ok((ref $collection->{_links}->{'ngcp:callforwards'} eq "ARRAY" ||
|
||||
ref $collection->{_links}->{'ngcp:callforwards'} eq "HASH"), "check if 'ngcp:callforwards' is array/hash-ref");
|
||||
|
||||
# remove any contact we find in the collection for later check
|
||||
if(ref $collection->{_links}->{'ngcp:callforwards'} eq "HASH") {
|
||||
ok(exists $collection->{_embedded}->{'ngcp:callforwards'}->{_links}->{'ngcp:callforwards'}, "check presence of ngcp:callforwards relation");
|
||||
ok(exists $collection->{_embedded}->{'ngcp:callforwards'}->{_links}->{'ngcp:subscribers'}, "check presence of ngcp:subscribers relation");
|
||||
} else {
|
||||
foreach my $c(@{ $collection->{_embedded}->{'ngcp:callforwards'} }) {
|
||||
ok(exists $c->{_links}->{'ngcp:callforwards'}, "check presence of ngcp:callforwards relation");
|
||||
ok(exists $c->{_links}->{'ngcp:subscribers'}, "check presence of ngcp:subscribers relation");
|
||||
use Test::More;
|
||||
use Test::Collection;
|
||||
use Test::FakeData;
|
||||
use Data::Dumper;
|
||||
|
||||
|
||||
my $fake_data = Test::FakeData->new;
|
||||
$fake_data->set_data_from_script({
|
||||
'callforwards' => {
|
||||
'data' => {
|
||||
#not really necessary - there isn't POST method
|
||||
#subscriber_id => sub { return shift->get_id('subscribers',@_); },
|
||||
cfu => {
|
||||
destinations => [
|
||||
{ destination => "12345", timeout => 200},
|
||||
],
|
||||
times => undef,
|
||||
},
|
||||
cft => {
|
||||
destinations => [
|
||||
{ destination => "5678" },
|
||||
{ destination => "voicebox", timeout => 500 },
|
||||
],
|
||||
ringtimeout => 10,
|
||||
}
|
||||
}
|
||||
|
||||
} while($nexturi);
|
||||
}
|
||||
|
||||
|
||||
diag('Note that the next tests require at least one subscriber to be present');
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
my $test_machine = Test::Collection->new(
|
||||
name => 'callforwards',
|
||||
embedded_resources => [qw/subscribers callforwards/],
|
||||
);
|
||||
$test_machine->methods->{collection}->{allowed} = {map {$_ => 1} qw(GET HEAD OPTIONS)};
|
||||
$test_machine->methods->{item}->{allowed} = {map {$_ => 1} qw(GET HEAD OPTIONS PUT PATCH DELETE)};
|
||||
$test_machine->DATA_ITEM_STORE($fake_data->process('callforwards'));
|
||||
$test_machine->form_data_item( );
|
||||
|
||||
SKIP:{
|
||||
my ($res,$req,$content);
|
||||
my $cf1 = $test_machine->get_item_hal();
|
||||
|
||||
if(!$cf1->{content}->{total_count}){
|
||||
skip("Testing requires at least one present callforward. No creation is available.",1);
|
||||
}
|
||||
|
||||
# fetch a callforward (subscriber) id for later tests
|
||||
$req = HTTP::Request->new('GET', $uri.'/api/callforwards/?page=1&rows=1');
|
||||
$res = $ua->request($req);
|
||||
is($res->code, 200, "fetch first callforward");
|
||||
my $cf1 = JSON::from_json($res->decoded_content);
|
||||
my ($cf1_id) = $cf1->{_embedded}->{'ngcp:callforwards'}->{_links}{self}{href} =~ m!callforwards/([0-9]*)$!;
|
||||
$test_machine->check_bundle();
|
||||
|
||||
cmp_ok ($cf1_id, '>', 0, "should be positive integer");
|
||||
my($cf1_id) = $test_machine->get_id_from_hal($cf1->{content}); #($cf1,'callforwards');
|
||||
cmp_ok ($cf1_id, '>', 0, "should be positive integer");
|
||||
my $cf1single_uri = "/api/callforwards/$cf1_id";
|
||||
my $cf1single;
|
||||
(undef, $cf1single) = $test_machine->check_item_get($cf1single_uri,"fetch cf id $cf1_id");
|
||||
|
||||
# test cf item
|
||||
{
|
||||
$req = HTTP::Request->new('OPTIONS', "$uri/api/callforwards/$cf1_id");
|
||||
$res = $ua->request($req);
|
||||
is($res->code, 200, "check options on item");
|
||||
my @hopts = split /\s*,\s*/, $res->header('Allow');
|
||||
my $opts = JSON::from_json($res->decoded_content);
|
||||
ok(exists $opts->{methods} && ref $opts->{methods} eq "ARRAY", "check for valid 'methods' in body");
|
||||
foreach my $opt(qw( GET HEAD OPTIONS PUT PATCH DELETE )) {
|
||||
ok(grep(/^$opt$/, @hopts), "check for existence of '$opt' in Allow header");
|
||||
ok(grep(/^$opt$/, @{ $opts->{methods} }), "check for existence of '$opt' in body");
|
||||
}
|
||||
foreach my $opt(qw( POST )) {
|
||||
ok(!grep(/^$opt$/, @hopts), "check for absence of '$opt' in Allow header");
|
||||
ok(!grep(/^$opt$/, @{ $opts->{methods} }), "check for absence of '$opt' in body");
|
||||
}
|
||||
|
||||
# get our cf
|
||||
$req = HTTP::Request->new('GET', "$uri/api/callforwards/$cf1_id");
|
||||
|
||||
$res = $ua->request($req);
|
||||
is($res->code, 200, "fetch cf id $cf1_id");
|
||||
my $cf1single = JSON::from_json($res->decoded_content);
|
||||
#check cf structure
|
||||
is(ref $cf1single, "HASH", "cf should be hash");
|
||||
ok(exists $cf1single->{cfu}, "cf should have key cfu");
|
||||
ok(exists $cf1single->{cfb}, "cf should have key cfb");
|
||||
ok(exists $cf1single->{cft}, "cf should have key cft");
|
||||
ok(exists $cf1single->{cfna}, "cf should have key cfna");
|
||||
|
||||
# write this cf
|
||||
$req = HTTP::Request->new('PUT', "$uri/api/callforwards/$cf1_id");
|
||||
$req->header('Prefer' => "return=representation");
|
||||
$req->header('Content-Type' => 'application/json');
|
||||
$req->content(JSON::to_json({
|
||||
cfu => {
|
||||
destinations => [
|
||||
{ destination => "12345", timeout => 200},
|
||||
],
|
||||
times => undef,
|
||||
},
|
||||
cft => {
|
||||
destinations => [
|
||||
{ destination => "5678" },
|
||||
{ destination => "voicebox", timeout => 500 },
|
||||
],
|
||||
ringtimeout => 10,
|
||||
}
|
||||
}));
|
||||
$res = $ua->request($req);
|
||||
is($res->code, 200, "write a specific callforward") || diag ($res->message);
|
||||
my $cf1put = JSON::from_json($res->decoded_content);
|
||||
is (ref $cf1put, "HASH", "should be hashref");
|
||||
is ($cf1put->{cfu}{destinations}->[0]->{timeout}, 200, "Check timeout of cft");
|
||||
is ($cf1put->{cft}{destinations}->[0]->{simple_destination}, "5678", "Check first destination of cft");
|
||||
like ($cf1put->{cft}{destinations}->[0]->{destination}, qr/^sip:5678@/, "Check first destination of cft (regex, full uri)");
|
||||
is ($cf1put->{cft}{destinations}->[1]->{destination}, "voicebox", "Check second destination of cft");
|
||||
#write cf and check written values
|
||||
my($cf1_put,$cf1_get) = $test_machine->check_put2get({data_in => $test_machine->DATA_ITEM, uri => $cf1single_uri},undef, 1 );
|
||||
is (ref $cf1_put->{content}, "HASH", "should be hashref");
|
||||
is ($cf1_put->{content}->{cfu}{destinations}->[0]->{timeout}, 200, "Check timeout of cft");
|
||||
is ($cf1_put->{content}->{cft}{destinations}->[0]->{simple_destination}, "5678", "Check first destination of cft");
|
||||
like ($cf1_put->{content}->{cft}{destinations}->[0]->{destination}, qr/^sip:5678@/, "Check first destination of cft (regex, full uri)");
|
||||
is ($cf1_put->{content}->{cft}{destinations}->[1]->{destination}, "voicebox", "Check second destination of cft");
|
||||
|
||||
#write invalid 'timeout'
|
||||
$req = HTTP::Request->new('PUT', "$uri/api/callforwards/$cf1_id");
|
||||
$req->header('Prefer' => "return=representation");
|
||||
$req->header('Content-Type' => 'application/json');
|
||||
$req->content(JSON::to_json({
|
||||
($res,$content,$req) = $test_machine->request_put({
|
||||
cfu => {
|
||||
destinations => [
|
||||
{ destination => "12345", timeout => "foobar"},
|
||||
],
|
||||
times => undef,
|
||||
},
|
||||
}));
|
||||
$res = $ua->request($req);
|
||||
is($res->code, 422, "create customer with invalid type");
|
||||
my $err = JSON::from_json($res->decoded_content);
|
||||
is($err->{code}, "422", "check error code in body");
|
||||
like($err->{message}, qr/Validation failed/, "check error message in body");
|
||||
}, $cf1single_uri);
|
||||
$test_machine->http_code_msg(422, "create callforward with invalid timeout", $res, $content);
|
||||
is($content->{code}, "422", "check error code in body");
|
||||
like($content->{message}, qr/Validation failed/, "check error message in body");
|
||||
|
||||
# get invalid cf
|
||||
$req = HTTP::Request->new('GET', "$uri/api/callforwards/abc");
|
||||
$res = $ua->request($req);
|
||||
($res, $content) = $test_machine->request_get("/api/callforwards/abc");
|
||||
is($res->code, 400, "try invalid callforward id");
|
||||
$err = JSON::from_json($res->decoded_content);
|
||||
is($err->{code}, "400", "check error code in body");
|
||||
like($err->{message}, qr/Invalid id/, "check error message in body");
|
||||
|
||||
# PUT same result again
|
||||
my $old_cf1 = { %$cf1put };
|
||||
delete $cf1put->{_links};
|
||||
delete $cf1put->{_embedded};
|
||||
$req = HTTP::Request->new('PUT', "$uri/api/callforwards/$cf1_id");
|
||||
|
||||
# check if it fails without content type
|
||||
$req->remove_header('Content-Type');
|
||||
$req->header('Prefer' => "return=minimal");
|
||||
$res = $ua->request($req);
|
||||
is($res->code, 415, "check put missing content type");
|
||||
|
||||
# check if it fails with unsupported content type
|
||||
$req->header('Content-Type' => 'application/xxx');
|
||||
$res = $ua->request($req);
|
||||
is($res->code, 415, "check put invalid content type");
|
||||
|
||||
$req->remove_header('Content-Type');
|
||||
$req->header('Content-Type' => 'application/json');
|
||||
is($content->{code}, "400", "check error code in body");
|
||||
like($content->{message}, qr/Invalid id/, "check error message in body");
|
||||
|
||||
# check if it fails with invalid Prefer
|
||||
$req->header('Prefer' => "return=invalid");
|
||||
$res = $ua->request($req);
|
||||
is($res->code, 400, "check put invalid prefer");
|
||||
my($cf2_put,$cf2_get) = $test_machine->check_put2get({data_in => $cf1_put->{content}, uri => $cf1single_uri},undef, 1 );
|
||||
is_deeply($cf1_put->{content}, $cf2_put->{content}, "check put if unmodified put returns the same");
|
||||
$test_machine->check_embedded($cf2_put->{content});
|
||||
|
||||
$req->remove_header('Prefer');
|
||||
$req->header('Prefer' => "return=representation");
|
||||
|
||||
# check if it fails with missing body
|
||||
$res = $ua->request($req);
|
||||
is($res->code, 400, "check put no body");
|
||||
|
||||
# check if put is ok
|
||||
$req->content(JSON::to_json($cf1put));
|
||||
$res = $ua->request($req);
|
||||
is($res->code, 200, "check put successful");
|
||||
|
||||
my $new_cf1 = JSON::from_json($res->decoded_content);
|
||||
is_deeply($old_cf1, $new_cf1, "check put if unmodified put returns the same");
|
||||
|
||||
# check if we have the proper links
|
||||
ok(exists $new_cf1->{_links}->{'ngcp:callforwards'}, "check put presence of ngcp:customercontacts relation");
|
||||
ok(exists $new_cf1->{_links}->{'ngcp:subscribers'}, "check put presence of ngcp:billingprofiles relation");
|
||||
|
||||
|
||||
$req = HTTP::Request->new('PATCH', "$uri/api/callforwards/$cf1_id");
|
||||
$req->header('Prefer' => 'return=representation');
|
||||
$req->header('Content-Type' => 'application/json-patch+json');
|
||||
|
||||
$req->content(JSON::to_json(
|
||||
[ { op => 'replace', path => '/cfu/destinations/0/timeout', value => '123' } ]
|
||||
));
|
||||
$res = $ua->request($req);
|
||||
is($res->code, 200, "check patched cf item");
|
||||
my $mod_cf1 = JSON::from_json($res->decoded_content);
|
||||
my $mod_cf1;
|
||||
($res,$mod_cf1) = $test_machine->check_patch_correct( [ { op => 'replace', path => '/cfu/destinations/0/timeout', value => '123' } ] );
|
||||
is($mod_cf1->{cfu}{destinations}->[0]->{timeout}, "123", "check patched replace op");
|
||||
is($mod_cf1->{_links}->{self}->{href}, "/api/callforwards/$cf1_id", "check patched self link");
|
||||
is($mod_cf1->{_links}->{collection}->{href}, '/api/callforwards/', "check patched collection link");
|
||||
|
||||
|
||||
$req->content(JSON::to_json(
|
||||
[ { op => 'add', path => '/cfu/destinations/-', value => {destination => 99999} } ]
|
||||
));
|
||||
$res = $ua->request($req);
|
||||
($res,$mod_cf1) = $test_machine->request_patch( [ { op => 'add', path => '/cfu/destinations/-', value => {destination => 99999} } ] );
|
||||
is($res->code, 200, "check patch, add a cfu destination");
|
||||
|
||||
|
||||
$req->content(JSON::to_json(
|
||||
[ { op => 'replace', path => '/cfu/destinations/0/timeout', value => "" } ]
|
||||
));
|
||||
$res = $ua->request($req);
|
||||
($res,$mod_cf1) = $test_machine->request_patch( [ { op => 'replace', path => '/cfu/destinations/0/timeout', value => "" } ] );
|
||||
is($res->code, 422, "check patched undef timeout");
|
||||
|
||||
$req->content(JSON::to_json(
|
||||
[ { op => 'replace', path => '/cfu/destinations/0/timeout', value => 'invalid' } ]
|
||||
));
|
||||
$res = $ua->request($req);
|
||||
($res,$mod_cf1) = $test_machine->request_patch( [ { op => 'replace', path => '/cfu/destinations/0/timeout', value => 'invalid' } ] );
|
||||
is($res->code, 422, "check patched invalid status");
|
||||
|
||||
$req->content(JSON::to_json(
|
||||
[ { op => 'replace', path => '/some/path', value => 'invalid' } ]
|
||||
));
|
||||
$res = $ua->request($req);
|
||||
is($res->code, 422, "check patched invalid path");
|
||||
}
|
||||
|
||||
done_testing;
|
||||
|
||||
1;
|
||||
|
||||
# vim: set tabstop=4 expandtab:
|
||||
|
Loading…
Reference in new issue