TT#32913 Remove excrescent code from /api/numbers

and add test script

Change-Id: I70407cec591b8d719582dd476e7586496a795d69
changes/38/19338/16
Irina Peshinskaya 7 years ago
parent ab10122651
commit 469d481b9f

@ -3,15 +3,11 @@ use NGCP::Panel::Utils::Generic qw(:all);
use Sipwise::Base;
use boolean qw(true);
use Data::HAL qw();
use Data::HAL::Link qw();
use HTTP::Headers qw();
use HTTP::Status qw(:constants);
use parent qw/NGCP::Panel::Role::Entities NGCP::Panel::Role::API::Numbers/;
use NGCP::Panel::Utils::DateTime;
use Path::Tiny qw(path);
use Safe::Isa qw($_isa);
__PACKAGE__->set_config({
allowed_roles => [qw/admin reseller subscriberadmin/],
});
sub allowed_methods{
return [qw/GET OPTIONS HEAD/];
@ -70,74 +66,6 @@ sub query_params {
];
}
use parent qw/NGCP::Panel::Role::Entities NGCP::Panel::Role::API::Numbers/;
sub resource_name{
return 'numbers';
}
sub dispatch_path{
return '/api/numbers/';
}
sub relation{
return 'http://purl.org/sipwise/ngcp-api/#rel-numbers';
}
__PACKAGE__->set_config({
allowed_roles => [qw/admin reseller subscriberadmin/],
});
sub GET :Allow {
my ($self, $c) = @_;
my $page = $c->request->params->{page} // 1;
my $rows = $c->request->params->{rows} // 10;
{
my $numbers = $self->item_rs($c);
(my $total_count, $numbers) = $self->paginate_order_collection($c, $numbers);
my (@embedded, @links);
my $form = $self->get_form($c);
for my $domain ($numbers->all) {
push @embedded, $self->hal_from_item($c, $domain, $form);
push @links, Data::HAL::Link->new(
relation => 'ngcp:'.$self->resource_name,
href => sprintf('/%s%d', $c->request->path, $domain->id),
);
}
push @links,
Data::HAL::Link->new(
relation => 'curies',
href => 'http://purl.org/sipwise/ngcp-api/#rel-{rel}',
name => 'ngcp',
templated => true,
),
Data::HAL::Link->new(relation => 'profile', href => 'http://purl.org/sipwise/ngcp-api/'),
Data::HAL::Link->new(relation => 'self', href => sprintf('/%s?page=%s&rows=%s', $c->request->path, $page, $rows));
if(($total_count / $rows) > $page ) {
push @links, Data::HAL::Link->new(relation => 'next', href => sprintf('/%s?page=%d&rows=%d', $c->request->path, $page + 1, $rows));
}
if($page > 1) {
push @links, Data::HAL::Link->new(relation => 'prev', href => sprintf('/%s?page=%d&rows=%d', $c->request->path, $page - 1, $rows));
}
my $hal = Data::HAL->new(
embedded => [@embedded],
links => [@links],
);
$hal->resource({
total_count => $total_count,
});
my $rname = $self->resource_name;
my $response = HTTP::Response->new(HTTP_OK, undef,
HTTP::Headers->new($hal->http_headers(skip_links => 1)), $hal->as_json);
$c->response->headers($response->headers);
$c->response->body($response->content);
return;
}
return;
}
1;
# vim: set tabstop=4 expandtab:

@ -1,160 +1,165 @@
package NGCP::Panel::Controller::API::NumbersItem;
use NGCP::Panel::Utils::Generic qw(:all);
use Sipwise::Base;
use NGCP::Panel::Utils::Generic qw(:all);
use parent qw/NGCP::Panel::Role::EntitiesItem NGCP::Panel::Role::API::Numbers/;
use boolean qw(true);
use Data::HAL qw();
use Data::HAL::Link qw();
use HTTP::Headers qw();
use HTTP::Status qw(:constants);
use JSON::Types;
use NGCP::Panel::Utils::ValidateJSON qw();
use NGCP::Panel::Utils::DateTime;
use Path::Tiny qw(path);
use Safe::Isa qw($_isa);
require Catalyst::ActionRole::ACL;
require NGCP::Panel::Role::HTTPMethods;
require Catalyst::ActionRole::RequireSSL;
__PACKAGE__->set_config({
allowed_roles => {
Default => [qw/admin reseller subscriberadmin/],
Journal => [qw/admin reseller/],
}
});
sub allowed_methods{
return [qw/GET PUT PATCH OPTIONS HEAD/];
}
use parent qw/NGCP::Panel::Role::EntitiesItem NGCP::Panel::Role::API::Numbers/;
sub resource_name{
return 'numbers';
}
sub dispatch_path{
return '/api/numbers/';
}
sub relation{
return 'http://purl.org/sipwise/ngcp-api/#rel-numbers';
}
sub journal_query_params {
my($self,$query_params) = @_;
return $self->get_journal_query_params($query_params);
}
__PACKAGE__->set_config({
allowed_roles => {
Default => [qw/admin reseller subscriberadmin/],
Journal => [qw/admin reseller/],
sub get_journal_methods{
return [qw/handle_item_base_journal handle_journals_get handle_journalsitem_get handle_journals_options handle_journalsitem_options handle_journals_head handle_journalsitem_head handle_journalsitem_put handle_journalsitem_patch/];
}
sub update_item_model {
my ($self, $c, $item, $old_resource, $resource, $form) = @_;
my $schema = $c->model('DB');
# we maybe want to remove such checks to compare readonly fields:
foreach my $field(qw/cc ac sn is_primary/) {
unless(($old_resource->{$field} // '') eq ($resource->{$field} // '')
or ('JSON::false' eq ref $resource->{$field} and $old_resource->{$field} == 0)
or ('JSON::true' eq ref $resource->{$field} and $old_resource->{$field} == 1)) {
$self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Field '$field' is not allowed to be updated via this API endpoint, use /api/subscriber/\$id instead.");
return;
}
}
});
sub GET :Allow {
my ($self, $c, $id) = @_;
{
last unless $self->valid_id($c, $id);
my $item = $self->item_by_id($c, $id);
last unless $self->resource_exists($c, number => $item);
my $hal = $self->hal_from_item($c, $item);
my $response = HTTP::Response->new(HTTP_OK, undef, HTTP::Headers->new(
(map { # XXX Data::HAL must be able to generate links with multiple relations
s|rel="(http://purl.org/sipwise/ngcp-api/#rel-resellers)"|rel="item $1"|r =~
s/rel=self/rel="item self"/r;
} $hal->http_headers),
), $hal->as_json);
$c->response->headers($response->headers);
$c->response->body($response->content);
$form //= $self->get_form($c);
return unless $self->validate_form(
c => $c,
form => $form,
resource => $resource,
);
my $sub = $schema->resultset('voip_subscribers')
->find($resource->{subscriber_id});
unless($sub) {
$self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid 'subscriber_id', does not exist.");
return;
}
if($c->user->roles eq "subscriberadmin" && $sub->contract_id != $c->user->account_id) {
$self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid 'subscriber_id', does not exist.");
return;
}
my $old_sub = $schema->resultset('voip_subscribers')->find($old_resource->{subscriber_id});
if($old_sub->primary_number_id == $old_resource->{id}) {
$self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Cannot reassign primary number, already at subscriber ".$old_sub->id);
return;
}
return;
}
sub PUT :Allow {
my ($self, $c, $id) = @_;
my $guard = $c->model('DB')->txn_scope_guard;
{
my $preference = $self->require_preference($c);
last unless $preference;
try {
my $item = $self->item_by_id($c, $id);
last unless $self->resource_exists($c, number => $item);
my $resource = $self->get_valid_put_data(
# capture old subscriber's aliases
my $old_aliases_before = NGCP::Panel::Utils::Events::get_aliases_snapshot(
c => $c,
id => $id,
media_type => 'application/json',
schema => $schema,
subscriber => $old_sub,
);
last unless $resource;
my $old_resource = { $item->get_inflated_columns };
my $form = $self->get_form($c);
$item = $self->update_item($c, $item, $old_resource, $resource, $form);
last unless $item;
$guard->commit;
if ('minimal' eq $preference) {
$c->response->status(HTTP_NO_CONTENT);
$c->response->header(Preference_Applied => 'return=minimal');
$c->response->body(q());
} else {
my $hal = $self->hal_from_item($c, $item, $form);
my $response = HTTP::Response->new(HTTP_OK, undef, HTTP::Headers->new(
$hal->http_headers,
), $hal->as_json);
$c->response->headers($response->headers);
$c->response->header(Preference_Applied => 'return=representation');
$c->response->body($response->content);
}
}
return;
}
sub PATCH :Allow {
my ($self, $c, $id) = @_;
my $guard = $c->model('DB')->txn_scope_guard;
{
my $preference = $self->require_preference($c);
last unless $preference;
my $json = $self->get_valid_patch_data(
c => $c,
id => $id,
media_type => 'application/json-patch+json',
# capture new subscriber's aliases
my $aliases_before = NGCP::Panel::Utils::Events::get_aliases_snapshot(
c => $c,
schema => $schema,
subscriber => $sub,
);
last unless $json;
my $item = $self->item_by_id($c, $id);
last unless $self->resource_exists($c, number => $item);
my $old_resource = { $item->get_inflated_columns };
my $resource = $self->apply_patch($c, $old_resource, $json);
last unless $resource;
my $form = $self->get_form($c);
$item = $self->update_item($c, $item, $old_resource, $resource, $form);
last unless $item;
$guard->commit;
if ('minimal' eq $preference) {
$c->response->status(HTTP_NO_CONTENT);
$c->response->header(Preference_Applied => 'return=minimal');
$c->response->body(q());
} else {
my $hal = $self->hal_from_item($c, $item, $form);
my $response = HTTP::Response->new(HTTP_OK, undef, HTTP::Headers->new(
$hal->http_headers,
), $hal->as_json);
$c->response->headers($response->headers);
$c->response->header(Preference_Applied => 'return=representation');
$c->response->body($response->content);
}
my $oldalias = [$old_sub->voip_numbers->all];
$oldalias = [ map {
if($_->id == $old_sub->primary_number_id) {
# filter primary number
();
} else {
if($_->id == $item->id) {
# filter number we're about to remove
();
} else {
# otherwise keep number
{ e164 => { cc => $_->cc, ac => $_->ac, sn => $_->sn } };
}
}
} @{ $oldalias } ];
NGCP::Panel::Utils::Subscriber::update_subscriber_numbers(
c => $c,
schema => $schema,
alias_numbers => $oldalias,
reseller_id => $old_sub->contract->contact->reseller_id,
subscriber_id => $old_sub->id,
);
my $newalias = [ $sub->voip_numbers->all ];
$newalias = [ map {
if($_->id == $sub->primary_number_id) {
# filter primary number
();
} else {
if($_->id == $item->id) {
# filter number we're about to remove
();
} else {
# otherwise keep number
{ e164 => { cc => $_->cc, ac => $_->ac, sn => $_->sn } };
}
}
} @{ $newalias } ];
push @{ $newalias }, { e164 => { cc => $item->cc, ac => $item->ac, sn => $item->sn } };
NGCP::Panel::Utils::Subscriber::update_subscriber_numbers(
c => $c,
schema => $schema,
alias_numbers => $newalias,
reseller_id => $sub->contract->contact->reseller_id,
subscriber_id => $sub->id,
);
# edr events for old sub
my $old_sub_profile = $old_sub->provisioning_voip_subscriber->profile_id;
NGCP::Panel::Utils::Events::insert_profile_events(
c => $c, schema => $schema, subscriber_id => $old_sub->id,
old => $old_sub_profile, new => $old_sub_profile,
%$old_aliases_before,
);
# edr events for new sub
my $new_sub_profile = $sub->provisioning_voip_subscriber->profile_id;
NGCP::Panel::Utils::Events::insert_profile_events(
c => $c, schema => $schema, subscriber_id => $sub->id,
old => $new_sub_profile, new => $new_sub_profile,
%$aliases_before,
);
} catch($e) {
$c->log->error("failed to update number: $e");
$self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to update number.");
return;
}
return;
# reload item, in case the id changed (which shouldn't happen)
$item = $self->_item_rs($c)->find({
cc => $item->cc, ac => $item->ac, sn => $item->sn
});
return $item;
}
sub get_journal_methods{
return [qw/handle_item_base_journal handle_journals_get handle_journalsitem_get handle_journals_options handle_journalsitem_options handle_journals_head handle_journalsitem_head handle_journalsitem_put handle_journalsitem_patch/];
}
1;

@ -5,14 +5,21 @@ use Sipwise::Base;
use parent 'NGCP::Panel::Role::API';
use boolean qw(true);
use Data::HAL qw();
use Data::HAL::Link qw();
use HTTP::Status qw(:constants);
use JSON::Types;
use NGCP::Panel::Form;
use NGCP::Panel::Utils::XMLDispatcher;
use NGCP::Panel::Utils::Prosody;
sub resource_name{
return 'numbers';
}
sub dispatch_path{
return '/api/numbers/';
}
sub relation{
return 'http://purl.org/sipwise/ngcp-api/#rel-numbers';
}
sub get_form {
my ($self, $c) = @_;
@ -28,45 +35,6 @@ sub get_form {
return;
}
sub hal_from_item {
my ($self, $c, $item, $form) = @_;
my %resource = $item->get_inflated_columns;
my $hal = Data::HAL->new(
links => [
Data::HAL::Link->new(
relation => 'curies',
href => 'http://purl.org/sipwise/ngcp-api/#rel-{rel}',
name => 'ngcp',
templated => true,
),
Data::HAL::Link->new(relation => 'collection', href => sprintf("/api/%s/", $self->resource_name)),
Data::HAL::Link->new(relation => 'profile', href => 'http://purl.org/sipwise/ngcp-api/'),
Data::HAL::Link->new(relation => 'self', href => sprintf("%s%d", $self->dispatch_path, $item->id)),
Data::HAL::Link->new(relation => 'ngcp:subscribers', href => sprintf("/api/subscribers/%d", $item->subscriber_id)),
$self->get_journal_relation_link($item->id),
],
relation => 'ngcp:'.$self->resource_name,
);
$form //= $self->get_form($c);
$self->validate_form(
c => $c,
resource => \%resource,
form => $form,
run => 0,
);
$resource{id} = int($item->id);
if($c->user->roles eq "admin") {
$resource{reseller_id} = int($item->reseller_id);
}
$hal->resource({%resource});
return $hal;
}
sub _item_rs {
my ($self, $c) = @_;
@ -106,145 +74,19 @@ sub _item_rs {
return $item_rs;
}
sub item_by_id {
my ($self, $c, $id) = @_;
my $item_rs = $self->item_rs($c);
return $item_rs->find($id);
sub hal_links{
my($self, $c, $item, $resource, $form) = @_;
return [
Data::HAL::Link->new(relation => 'ngcp:subscribers', href => sprintf("/api/subscribers/%d", $item->subscriber_id)),
];
}
sub update_item {
my ($self, $c, $item, $old_resource, $resource, $form) = @_;
my $schema = $c->model('DB');
# we maybe want to remove such checks to compare readonly fields:
foreach my $field(qw/cc ac sn is_primary/) {
unless(($old_resource->{$field} // '') eq ($resource->{$field} // '')
or ('JSON::false' eq ref $resource->{$field} and $old_resource->{$field} == 0)
or ('JSON::true' eq ref $resource->{$field} and $old_resource->{$field} == 1)) {
$self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Field '$field' is not allowed to be updated via this API endpoint, use /api/subscriber/\$id instead.");
return;
}
}
$form //= $self->get_form($c);
return unless $self->validate_form(
c => $c,
form => $form,
resource => $resource,
);
my $sub = $schema->resultset('voip_subscribers')
->find($resource->{subscriber_id});
unless($sub) {
$self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid 'subscriber_id', does not exist.");
return;
}
if($c->user->roles eq "subscriberadmin" && $sub->contract_id != $c->user->account_id) {
$self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid 'subscriber_id', does not exist.");
return;
}
my $old_sub = $schema->resultset('voip_subscribers')->find($old_resource->{subscriber_id});
if($old_sub->primary_number_id == $old_resource->{id}) {
$self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Cannot reassign primary number, already at subscriber ".$old_sub->id);
return;
}
try {
# capture old subscriber's aliases
my $old_aliases_before = NGCP::Panel::Utils::Events::get_aliases_snapshot(
c => $c,
schema => $schema,
subscriber => $old_sub,
);
# capture new subscriber's aliases
my $aliases_before = NGCP::Panel::Utils::Events::get_aliases_snapshot(
c => $c,
schema => $schema,
subscriber => $sub,
);
my $oldalias = [$old_sub->voip_numbers->all];
$oldalias = [ map {
if($_->id == $old_sub->primary_number_id) {
# filter primary number
();
} else {
if($_->id == $item->id) {
# filter number we're about to remove
();
} else {
# otherwise keep number
{ e164 => { cc => $_->cc, ac => $_->ac, sn => $_->sn } };
}
}
} @{ $oldalias } ];
NGCP::Panel::Utils::Subscriber::update_subscriber_numbers(
c => $c,
schema => $schema,
alias_numbers => $oldalias,
reseller_id => $old_sub->contract->contact->reseller_id,
subscriber_id => $old_sub->id,
);
my $newalias = [ $sub->voip_numbers->all ];
$newalias = [ map {
if($_->id == $sub->primary_number_id) {
# filter primary number
();
} else {
if($_->id == $item->id) {
# filter number we're about to remove
();
} else {
# otherwise keep number
{ e164 => { cc => $_->cc, ac => $_->ac, sn => $_->sn } };
}
}
} @{ $newalias } ];
push @{ $newalias }, { e164 => { cc => $item->cc, ac => $item->ac, sn => $item->sn } };
NGCP::Panel::Utils::Subscriber::update_subscriber_numbers(
c => $c,
schema => $schema,
alias_numbers => $newalias,
reseller_id => $sub->contract->contact->reseller_id,
subscriber_id => $sub->id,
);
# edr events for old sub
my $old_sub_profile = $old_sub->provisioning_voip_subscriber->profile_id;
NGCP::Panel::Utils::Events::insert_profile_events(
c => $c, schema => $schema, subscriber_id => $old_sub->id,
old => $old_sub_profile, new => $old_sub_profile,
%$old_aliases_before,
);
# edr events for new sub
my $new_sub_profile = $sub->provisioning_voip_subscriber->profile_id;
NGCP::Panel::Utils::Events::insert_profile_events(
c => $c, schema => $schema, subscriber_id => $sub->id,
old => $new_sub_profile, new => $new_sub_profile,
%$aliases_before,
);
} catch($e) {
$c->log->error("failed to update number: $e");
$self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to update number.");
return;
sub post_process_hal_resource {
my($self, $c, $item, $resource, $form) = @_;
if($c->user->roles eq "admin") {
$resource->{reseller_id} = int($item->reseller_id);
}
# reload item, in case the id changed (which shouldn't happen)
$item = $self->_item_rs($c)->find({
cc => $item->cc, ac => $item->ac, sn => $item->sn
});
return $item;
return $resource;
}
1;

@ -0,0 +1,103 @@
use strict;
use warnings;
use Test::Collection;
use Test::FakeData;
use Test::More;
use Data::Dumper;
use Clone qw/clone/;
#use NGCP::Panel::Utils::Subscriber;
my $test_machine = Test::Collection->new(
name => 'numbers',
);
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,
sn => 1,
},
},
});
my $fake_data_processed = $fake_data->process('numbers');
$test_machine->DATA_ITEM_STORE($fake_data_processed);
$test_machine->form_data_item();
{
my $ticket = '32913';
my $time = time();
my $subscriber_test_machine = Test::Collection->new(
name => 'subscribers',
);
$subscriber_test_machine->DATA_ITEM_STORE($fake_data->process('subscribers'));
my $subscriber1 = $fake_data->create('subscribers')->[0];
my $subscriber2 = $fake_data->create('subscribers')->[0];
#print Dumper $subscriber1;
$subscriber1->{content}->{alias_numbers} = [
{ cc=> '111', ac => $ticket, sn => $time },
{ cc=> '112', ac => $ticket, sn => $time },
{ cc=> '113', ac => $ticket, sn => $time },
];
$subscriber2->{content}->{alias_numbers} = [
{ cc=> '211', ac => $ticket, sn => $time },
{ cc=> '212', ac => $ticket, sn => $time },
{ cc=> '213', ac => $ticket, sn => $time },
];
my ($res,$content,$request);
($res,$content,$request) = $subscriber_test_machine->request_put(@{$subscriber1}{qw/content location/});
($res,$content,$request) = $subscriber_test_machine->request_put(@{$subscriber2}{qw/content location/});
my ($alias1) = $test_machine->get_item_hal('numbers', '/api/numbers/?type=alias&subscriber_id='.$subscriber1->{content}->{id});
my ($alias2) = $test_machine->get_item_hal('numbers','/api/numbers/?type=alias&subscriber_id='.$subscriber2->{content}->{id});
test_numbers_reassign($alias1,$alias2,$subscriber1,$subscriber2);
my $pbxsubscriberadmin = $fake_data->create('subscribers')->[0];
($res) = $subscriber_test_machine->request_patch([
{ op => 'replace', path => '/administrative', value => 1 },
{ op => 'replace', path => '/webpassword', value => 'pbxadminpwd' },
{ op => 'replace', path => '/password', value => 'pbxadminpwd' }
] , $pbxsubscriberadmin->{location});
$subscriber_test_machine->http_code_msg(200, "PATCH for /pbxsubscriberadmin/", $res);
$pbxsubscriberadmin = $subscriber_test_machine->get_item_hal('subscribers', $pbxsubscriberadmin->{location});
$test_machine->set_subscriber_credentials($pbxsubscriberadmin->{content});
$test_machine->runas('subscriber');
test_numbers_reassign($alias1,$alias2,$subscriber1,$subscriber2);
$test_machine->runas('admin');
$subscriber_test_machine->clear_test_data_all();#fake data aren't registered in this test
}
$fake_data->clear_test_data_all();
$test_machine->clear_test_data_all();#fake data aren't registered in this test machine, so they will stay.
$fake_data->clear_test_data_all();
undef $test_machine;
undef $fake_data;
done_testing;
sub test_numbers_reassign{
my($alias1,$alias2,$subscriber1,$subscriber2) = @_;
my $res;
$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->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->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->request_patch([ { op => 'replace', path => '/subscriber_id', value => $subscriber2->{content}->{id} } ] , $alias2->{location});
$test_machine->http_code_msg(200, "PATCH for /numbers/", $res);
}
# vim: set tabstop=4 expandtab:

@ -6,7 +6,7 @@ use Test::FakeData;
use Test::More;
use Data::Dumper;
use Clone qw/clone/;
use feature 'state';
#use NGCP::Panel::Utils::Subscriber;
my $test_machine = Test::Collection->new(
@ -53,18 +53,22 @@ $fake_data->set_data_from_script({
},
'query' => [['username',{'query_type'=> 'string_like'}]],
'create_special'=> sub {
state $num;
$num //= 0;
$num++;
my ($self,$collection_name,$test_machine) = @_;
my $pilot = $test_machine->get_item_hal('subscribers','/api/subscribers/?customer_id='.$self->data->{$collection_name}->{data}->{customer_id}.'&'.'is_pbx_pilot=1');
if($pilot->{total_count} <= 0){
undef $pilot;
}
$test_machine->check_create_correct(1, sub{
return $test_machine->check_create_correct(1, sub{
my $time = time;
$_[0]->{is_pbx_pilot} = ($pilot || $_[1]->{i} > 1)? 0 : 1;
$_[0]->{pbx_extension} = time();
$_[0]->{webusername} .= time();
$_[0]->{username} .= time();
$_[0]->{pbx_extension} = $time.$num;
$_[0]->{webusername} .= $time.$num;
$_[0]->{username} .= $time.$num;
delete $_[0]->{alias_numbers};
$_[0]->{primary_number}->{sn} = time();
$_[0]->{primary_number}->{sn} = $time.$num;
}, $self->data->{$collection_name}->{data} );
},
'update_change_fields' => [qw/modify_timestamp create_timestamp primary_number_id/],

@ -677,6 +677,7 @@ sub get_request_patch{
$content and $req->content($content);
return $req;
}
sub request_put{
my($self,$content,$uri) = @_;
$uri ||= $self->get_uri_current;
@ -687,6 +688,7 @@ sub request_put{
return wantarray ? ($res,$rescontent,$req) : $res;
}
}
sub request_patch{
my($self,$content, $uri, $req) = @_;
$uri ||= $self->get_uri_current;
@ -718,6 +720,7 @@ sub request_post{
my $additional_info = { id => $self->get_id_from_location($location) // '' };
return wantarray ? ($res,$rescontent,$req,$content,$additional_info) : $res;
};
sub request_options{
my ($self,$uri) = @_;
# OPTIONS tests
@ -1336,6 +1339,8 @@ sub put_and_get{
my($put_out,$put_get_out,$get_out);
$params //= ();
$put_in->{uri} //= $put_in->{location};
$get_in->{ignore_fields} //= [];
$put_in->{ignore_fields} //= [];

Loading…
Cancel
Save