TT#55364 Fix /api/numbers PATCH for aliases

Change-Id: Iad3fd2bcb5bafbed7dffaaeae57a2efc2ff6fc5e
changes/84/28284/8
Irina Peshinskaya 7 years ago
parent 3a539b09c0
commit 1477062188

@ -49,7 +49,13 @@ sub query_params {
{
param => 'subscriber_id',
description => 'Filter for numbers assigned to a specific subscriber.',
query_type => 'string_eq',
#query_type => 'string_eq',#need to use full query spec due to the "me." absence
query => {
first => sub {
my $q = shift;
return { 'me.subscriber_id' => $q };
},
},
},
{
param => 'ac',

@ -203,13 +203,6 @@ sub update_item_model {
return $item;
}
sub post_process_hal_resource {
my($self, $c, $item, $resource, $form) = @_;
$resource->{is_devid} = bool $item->voip_dbalias->is_devid;
$resource->{devid_alias} = $item->voip_dbalias->devid_alias;
return $resource;
}
1;

@ -4,26 +4,26 @@ use HTML::FormHandler::Moose;
extends 'HTML::FormHandler';
has_field 'cc' => (
type => '+NGCP::Panel::Field::PosInteger',
element_attr => {
rel => ['tooltip'],
title => ['Country Code, e.g. 1 for US or 43 for Austria (read-only)']
type => 'Text',
element_attr => {
rel => ['tooltip'],
title => ['Country Code, e.g. 1 for US or 43 for Austria (read-only)']
},
);
has_field 'ac' => (
type => '+NGCP::Panel::Field::PosInteger',
element_attr => {
rel => ['tooltip'],
title => ['Area Code, e.g. 212 for NYC or 1 for Vienna (read-only)']
type => 'Text',
element_attr => {
rel => ['tooltip'],
title => ['Area Code, e.g. 212 for NYC or 1 for Vienna (read-only)']
},
);
has_field 'sn' => (
type => '+NGCP::Panel::Field::PosInteger',
element_attr => {
rel => ['tooltip'],
title => ['Subscriber Number, e.g. 12345678 (read-only)']
type => 'Text',
element_attr => {
rel => ['tooltip'],
title => ['Subscriber Number, e.g. 12345678 (read-only)']
},
);

@ -8,6 +8,7 @@ use parent 'NGCP::Panel::Role::API';
use Data::HAL qw();
use Data::HAL::Link qw();
use NGCP::Panel::Form;
use JSON::Types;
sub resource_name{
return 'numbers';
@ -43,9 +44,9 @@ sub _item_rs {
'me.subscriber_id' => { '!=' => undef },
'subscriber.status' => { '!=' => 'terminated' },
},{
'+select' => [\'if(me.id=subscriber.primary_number_id,1,0)'],
'+as' => ['is_primary'],
join => 'subscriber',
'+select' => [\'if(me.id=subscriber.primary_number_id,1,0)','voip_dbalias.is_devid','voip_dbalias.devid_alias'],
'+as' => ['is_primary','is_devid','devid_alias'],
join => ['subscriber', 'voip_dbalias'],
});
if($c->user->roles eq "admin") {
} elsif($c->user->roles eq "reseller") {
@ -86,6 +87,13 @@ sub post_process_hal_resource {
if($c->user->roles eq "admin") {
$resource->{reseller_id} = int($item->reseller_id);
}
if ($item->voip_dbalias) {
$resource->{is_devid} = bool $item->voip_dbalias->is_devid;
$resource->{devid_alias} = $item->voip_dbalias->devid_alias;
} else {
$resource->{is_devid} = JSON::false;
$resource->{devid_alias} = undef;
}
return $resource;
}

@ -4,6 +4,7 @@ use warnings;
use threads;
use Test::Collection;
use Test::FakeData;
use JSON;
use Test::More;
use Data::Dumper;
use Clone qw/clone/;
@ -13,14 +14,18 @@ use Clone qw/clone/;
my $test_machine = Test::Collection->new(
name => 'numbers',
);
$test_machine->methods->{collection}->{allowed} = {map {$_ => 1} qw(GET HEAD OPTIONS)};
$test_machine->methods->{item}->{allowed} = {map {$_ => 1} qw(GET HEAD OPTIONS PUT PATCH)};
my $fake_data = Test::FakeData->new;
$fake_data->set_data_from_script({
'numbers' => {
'data' => {
subscriber_id => sub { return shift->get_id('subscribers',@_); },
cc => 1,
ac => 1,
cc => 1,
ac => 1,
sn => 1,
},
},
@ -30,6 +35,50 @@ my $fake_data_processed = $fake_data->process('numbers');
$test_machine->DATA_ITEM_STORE($fake_data_processed);
$test_machine->form_data_item();
my ($res,$content,$req);
my $subscriber = $test_machine->get_item_hal('subscribers', '/api/subscribers/'.$test_machine->DATA_ITEM->{subscriber_id}, 1);
# cc WILL loose leading zero, as far as column billing.voip_numbers.cc is a integer and truncates leading zero
my $number_aliases_data = [
{'cc' => '11', 'ac' => '0022', 'sn' => '00444'.time().seq(),},
{'cc' => '11', 'ac' => '0022', 'sn' => '00444'.time().seq(),},
{'cc' => '11', 'ac' => '0022', 'sn' => '00444'.time().seq(),},
];
($res,$content,$req) = $test_machine->request_patch( [ {
op => 'replace',
path => '/alias_numbers',
value => $number_aliases_data
} ], $subscriber->{location} );
$test_machine->http_code_msg(200, "Check patch alias_numbers", $res, $content);
my $number_aliases = $test_machine->get_collection_hal('numbers', '/api/numbers/?type=alias&subscriber_id='.$test_machine->DATA_ITEM->{subscriber_id}, 1)->{collection};
my $number_primary = $test_machine->get_item_hal('numbers', '/api/numbers/?type=primary&subscriber_id='.$test_machine->DATA_ITEM->{subscriber_id}, 1);
#check that we didn't loose leading zeros
my $number_aliases_got = [ map {{'ac' => $_->{content}->{ac}, 'cc' => $_->{content}->{cc}, 'sn' => $_->{content}->{sn}}} @$number_aliases];
is_deeply($number_aliases_got, $number_aliases_data,"check that we didn't loose leading zeros in ac, cc, sn");
$test_machine->check_bundle();
$test_machine->check_get2put( {location => $number_aliases->[0]->{location}});
$test_machine->check_patch2get({location => $number_aliases->[0]->{location}});
$test_machine->check_patch2get({
location => $number_aliases->[0]->{location},
content => [
{'op' => 'replace', 'path' => '/is_devid', 'value' => JSON::true },
{'op' => 'replace', 'path' => '/devid_alias', 'value' => '000123456'},
],
});
#Two tests below will fail with error: Unprocessable Entity: Cannot reassign primary number, already at subscriber 357
#$test_machine->check_get2put( {location => $number_primary->{location}});
#$test_machine->check_patch2get({location => $number_primary->{location}}, undef, {
##we can exclude subscriber_id from patch, but anyway old_resource will provide it
# patch_exclude_fields => ['subscriber_id'],
#});
{
my $ticket = '32913';
my $time = time();
@ -62,7 +111,7 @@ $test_machine->form_data_item();
test_numbers_reassign($aliases1->[0],$aliases2->[0],$subscriber1,$subscriber2);
my $pbxsubscriberadmin = $fake_data->create('subscribers')->[0];
($res) = $subscriber_test_machine->request_patch([
($res) = $subscriber_test_machine->request_patch([
{ op => 'replace', path => '/administrative', value => 1 },
{ op => 'replace', path => '/webpassword', value => 'pbxadminpwd' },
{ op => 'replace', path => '/password', value => 'pbxadminpwd' }
@ -83,7 +132,7 @@ $test_machine->form_data_item();
}
$test_machine->runas('admin');
$subscriber_test_machine->clear_test_data_all();#fake data aren't registered in this test
$subscriber_test_machine->clear_test_data_all();#fake data aren't registered in this test
}
$fake_data->clear_test_data_all();
@ -96,6 +145,9 @@ done_testing;
sub test_numbers_reassign{
my($alias1,$alias2,$subscriber1,$subscriber2) = @_;
my $res;
my $test_machine_l = Test::Collection->new(
name => 'numbers',
);
#print Dumper [
# [ { op => 'replace', path => '/subscriber_id', value => $subscriber2->{content}->{id} } ] , $alias1,
@ -104,19 +156,19 @@ sub test_numbers_reassign{
# [ { op => 'replace', path => '/subscriber_id', value => $subscriber2->{content}->{id} } ] , $alias2
#
#];
my $tid = threads->tid();
$alias1->{content}->{subscriber_id} = $subscriber2->{content}->{id};
($res) = $test_machine->request_patch([ { op => 'replace', path => '/subscriber_id', value => $subscriber2->{content}->{id} } ] , $alias1->{location});
$test_machine->http_code_msg(200, "PATCH for /numbers/", $res);
($res) = $test_machine_l->request_patch([ { op => 'replace', path => '/subscriber_id', value => $subscriber2->{content}->{id} } ] , $alias1->{location});
$test_machine_l->http_code_msg(200, "PATCH 1 for /numbers/ in tid $tid;", $res);
($res) = $test_machine->request_patch([ { op => 'replace', path => '/subscriber_id', value => $subscriber1->{content}->{id} } ] , $alias1->{location});
$test_machine->http_code_msg(200, "PATCH for /numbers/", $res);
($res) = $test_machine_l->request_patch([ { op => 'replace', path => '/subscriber_id', value => $subscriber1->{content}->{id} } ] , $alias1->{location});
$test_machine_l->http_code_msg(200, "PATCH 2 for /numbers/ in tid $tid;", $res);
($res) = $test_machine->request_patch([ { op => 'replace', path => '/subscriber_id', value => $subscriber1->{content}->{id} } ] , $alias2->{location});
$test_machine->http_code_msg(200, "PATCH for /numbers/", $res);
($res) = $test_machine_l->request_patch([ { op => 'replace', path => '/subscriber_id', value => $subscriber1->{content}->{id} } ] , $alias2->{location});
$test_machine_l->http_code_msg(200, "PATCH 3 for /numbers/ in tid $tid;", $res);
($res) = $test_machine->request_patch([ { op => 'replace', path => '/subscriber_id', value => $subscriber2->{content}->{id} } ] , $alias2->{location});
$test_machine->http_code_msg(200, "PATCH for /numbers/", $res);
($res) = $test_machine_l->request_patch([ { op => 'replace', path => '/subscriber_id', value => $subscriber2->{content}->{id} } ] , $alias2->{location});
$test_machine_l->http_code_msg(200, "PATCH 4 for /numbers/ in tid $tid;", $res);
}
# vim: set tabstop=4 expandtab:

@ -252,10 +252,10 @@ has 'HEADERS' =>(
is => 'rw',
isa => 'HashRef',
default => sub{{
'GET' => {},
'POST' => {},
'PUT' => {},
'PATCH' => {},
'GET' => {},
'POST' => {},
'PUT' => {},
'PATCH' => {},
'DELETE' => {},
}},
);
@ -962,7 +962,7 @@ sub request_get{
my($self,$uri,$req,$headers) = @_;
if (!$req) {
$uri = $self->normalize_uri($uri);
$req //= $self->get_request_get($uri,$headers);
$req //= $self->get_request_get($uri,$headers);
}
my $res = $self->request($req);
my $content = $self->get_response_content($res);
@ -1060,9 +1060,9 @@ sub check_list_collection{
is($selfuri, $nexturi, $test_info_prefix."check _links.self.href of collection");
my $colluri = URI->new($selfuri);
if(
(!$self->NO_COUNT)
(!$self->NO_COUNT)
&& (
( $list_collection->{total_count} && is_int($list_collection->{total_count}) && $list_collection->{total_count} > 0 )
( $list_collection->{total_count} && is_int($list_collection->{total_count}) && $list_collection->{total_count} > 0 )
|| !$self->ALLOW_EMPTY_COLLECTION)){
ok($list_collection->{total_count} > 0, $test_info_prefix."check 'total_count' of collection");
}
@ -1107,9 +1107,9 @@ sub check_list_collection{
}
my $hal_name = $self->get_hal_name;
if((!$self->NO_COUNT)
if((!$self->NO_COUNT)
&& (
($list_collection->{total_count} && is_int($list_collection->{total_count}) && $list_collection->{total_count} > 0 )
($list_collection->{total_count} && is_int($list_collection->{total_count}) && $list_collection->{total_count} > 0 )
|| !$self->ALLOW_EMPTY_COLLECTION) ){
if (! ok(((ref $list_collection->{_links}->{$hal_name} eq "ARRAY" ) ||
(ref $list_collection->{_links}->{$hal_name} eq "HASH" ) ), $test_info_prefix."check if 'ngcp:".$self->name."' is array/hash-ref")) {
@ -1180,7 +1180,7 @@ sub check_created_listed{
}
ok($self->EXPECTED_AMOUNT_CREATED == scalar(keys %{$created_items}), "$self->{name}: check amount of created items");
if( $self->CHECK_LIST_LIMIT ) {
#we didn't load all collections into $listed, as we requested just limited pages,
#we didn't load all collections into $listed, as we requested just limited pages,
#so we can't check if all created are really listed
#let's try to get them just as latest items from the collection
my $query_params_old = $self->add_query_params('order_by=id&order_by_direction=desc');
@ -1650,7 +1650,7 @@ sub check_patch2get{
}
}
$patch_out->{content_in} = ref $patch_in eq 'HASH' && $patch_in->{content}
$patch_out->{content_in} = ref $patch_in eq 'HASH' && $patch_in->{content}
? $patch_in->{content}
: ref $patch_in eq 'ARRAY'
? $patch_in
@ -1660,7 +1660,7 @@ sub check_patch2get{
$patch_out->{content_patched} = Test::ApplyPatch::apply_patch(clone($patch_out->{content_before}),$patch_out->{content_in});
@{$patch_out}{qw/response content request/} = $self->request_patch( $patch_out->{content_in}, $patch_uri );
$self->http_code_msg(200, "check_patch2get: check patch successful",$patch_out->{response}, $patch_out->{content});
#print Dumper $patch_out;
@{$get_out}{qw/response content request/} = $self->check_item_get($get_out->{uri});
@ -1678,7 +1678,9 @@ sub check_patch2get{
$params->{compare_cb}->($patch_out,$get_out);
}
if(!$params->{skip_compare}){
is_deeply($get_out->{content}, $patch_out->{content_patched}, "$self->{name}: check_patch2get: check PATCHed item against GETed item");
if(!is_deeply($get_out->{content}, $patch_out->{content_patched}, "$self->{name}: check_patch2get: check PATCHed item against GETed item")) {
print Dumper ['get_out content',$get_out->{content},'patch_out content_patched',$patch_out->{content_patched}];
}
}
$get_out->{content}->{id} = $item_id;
$patch_out->{content_patched}->{id} = $item_id_in;
@ -1733,7 +1735,7 @@ sub put_and_get{
my($put_out,$put_get_out,$get_out);
$params //= ();
$put_in->{uri} //= $put_in->{location};
$get_in->{ignore_fields} //= [];
@ -1860,7 +1862,7 @@ sub name_prefix{
my($self,$name) = @_;
$name //= $self->name;
return $name ? $name.': ' : '';
}
}
sub get_cached_data{
my($self) = @_;

Loading…
Cancel
Save