MT#5255 API: move contacts to systemcontacts.

Clearly distinguish between systemcontacts (those without reseller) from
customercontacts (those with resellers). Separating them frees us from
having to handle reseller_id magic.
agranig/rest
Andreas Granig 13 years ago
parent beb93987eb
commit f4a9e39a8a

@ -1,14 +1,12 @@
package NGCP::Panel::Controller::API::Contacts;
package NGCP::Panel::Controller::API::SystemContacts;
use Sipwise::Base;
use namespace::sweep;
use boolean qw(true);
use Data::HAL qw();
use Data::HAL::Link qw();
use Data::Record qw();
use HTTP::Headers qw();
use HTTP::Status qw(:constants);
use MooseX::ClassAttribute qw(class_has);
use NGCP::Panel::Form::Contact::Admin qw();
use NGCP::Panel::Form::Contact::Reseller qw();
use Path::Tiny qw(path);
use Safe::Isa qw($_isa);
@ -20,8 +18,9 @@ require Catalyst::ActionRole::RequireSSL;
with 'NGCP::Panel::Role::API';
class_has('dispatch_path', is => 'ro', default => '/api/contacts/');
class_has('relation', is => 'ro', default => 'http://purl.org/sipwise/ngcp-api/#rel-contacts');
class_has('resource_name', is => 'ro', default => 'systemcontacts');
class_has('dispatch_path', is => 'ro', default => '/api/systemcontacts/');
class_has('relation', is => 'ro', default => 'http://purl.org/sipwise/ngcp-api/#rel-systemcontacts');
__PACKAGE__->config(
action => {
@ -49,20 +48,19 @@ sub GET :Allow {
my $page = $c->request->params->{page} // 1;
my $rows = $c->request->params->{rows} // 10;
{
last if $self->cached($c);
my $contacts = $c->model('DB')->resultset('contacts');
$self->last_modified($contacts->get_column('modify_timestamp')->max_rs->single->modify_timestamp);
my $total_count = int($contacts->count);
$contacts = $contacts->search(undef, {
page => $page,
rows => $rows,
});
my (@embedded, @links);
my $form = NGCP::Panel::Form::Contact::Reseller->new;
for my $contact ($contacts->search({}, {order_by => {-asc => 'me.id'}, prefetch => ['reseller']})->all) {
push @embedded, $self->hal_from_contact($contact);
push @embedded, $self->hal_from_contact($c, $contact, $form);
push @links, Data::HAL::Link->new(
relation => 'ngcp:contacts',
href => sprintf('/api/contacts/%d', $contact->id),
relation => 'ngcp:'.$self->resource_name,
href => sprintf('/%s%d', $c->request->path, $contact->id),
);
}
push @links,
@ -73,12 +71,12 @@ sub GET :Allow {
templated => true,
),
Data::HAL::Link->new(relation => 'profile', href => 'http://purl.org/sipwise/ngcp-api/'),
Data::HAL::Link->new(relation => 'self', href => "/api/contacts/?page=$page&rows=$rows");
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 => "/api/contacts/?page=".($page+1)."&rows=$rows"),
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 => "/api/contacts/?page=".($page-1)."&rows=$rows");
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(
@ -88,18 +86,14 @@ sub GET :Allow {
$hal->resource({
total_count => $total_count,
});
my $rname = $self->resource_name;
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-contacts)"|rel="item $1"|;
s|rel="(http://purl.org/sipwise/ngcp-api/#rel-$rname)"|rel="item $1"|;
s/rel=self/rel="collection self"/;
$_
} $hal->http_headers),
Cache_Control => 'no-cache, private',
ETag => $self->etag($hal->as_json),
Expires => DateTime::Format::HTTP->format_datetime($self->expires),
Last_Modified => DateTime::Format::HTTP->format_datetime($self->last_modified),
), $hal->as_json);
$c->cache->set($c->request->uri->canonical->as_string, $response, { expires_at => $self->expires->epoch });
$c->response->headers($response->headers);
$c->response->body($response->content);
return;
@ -119,8 +113,7 @@ sub OPTIONS :Allow {
my $allowed_methods = $self->allowed_methods;
$c->response->headers(HTTP::Headers->new(
Allow => $allowed_methods->join(', '),
Accept_Post => 'application/hal+json; profile=http://purl.org/sipwise/ngcp-api/#rel-contacts',
Content_Language => 'en',
Accept_Post => 'application/hal+json; profile=http://purl.org/sipwise/ngcp-api/#rel-'.$self->resource_name,
));
$c->response->content_type('application/json');
$c->response->body(JSON::to_json({ methods => $allowed_methods })."\n");
@ -137,34 +130,13 @@ sub POST :Allow {
);
last unless $resource;
my $contact_form;
if($c->user->roles eq "api_admin") {
if($resource->{reseller_id}) {
$contact_form = NGCP::Panel::Form::Contact::Admin->new;
} else {
$contact_form = NGCP::Panel::Form::Contact::Reseller->new;
delete $resource->{reseller_id};
}
} else {
$contact_form = NGCP::Panel::Form::Contact::Reseller->new;
$resource->{reseller_id} = $c->user->reseller_id;
}
my $form = NGCP::Panel::Form::Contact::Reseller->new;
last unless $self->validate_form(
c => $c,
resource => $resource,
form => $contact_form,
form => $form,
);
if($c->user->roles eq "api_admin" && !exists $resource->{reseller_id}) {
# admins can pass a contact without reseller_id
} else {
my $reseller = $c->model('DB')->resultset('resellers')->find($resource->{reseller_id});
unless($reseller) {
$self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid reseller_id."); # TODO: log error, ...
last;
}
}
my $now = DateTime->now;
$resource->{create_timestamp} = $now;
$resource->{modify_timestamp} = $now;
@ -173,24 +145,21 @@ sub POST :Allow {
$contact = $c->model('DB')->resultset('contacts')->create($resource);
} catch($e) {
$c->log->error("failed to create contact: $e"); # TODO: user, message, trace, ...
$self->error($c, HTTP_INTERNAL_SERVER_ERROR, "failed to create contact");
$self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create contact.");
last;
}
$c->cache->remove($c->request->uri->canonical->as_string);
$c->response->status(HTTP_CREATED);
$c->response->header(Location => sprintf('/api/contacts/%d', $contact->id));
$c->response->header(Location => sprintf('/%s%d', $c->request->path, $contact->id));
$c->response->body(q());
}
return;
}
sub hal_from_contact : Private {
my ($self, $contact) = @_;
# XXX invalid 00-00-00 dates
my %resource = $contact->get_inflated_columns;
my $id = delete $resource{id};
my ($self, $c, $contact, $form) = @_;
my %resource = $contact->get_inflated_columns;
my $hal = Data::HAL->new(
links => [
@ -200,38 +169,29 @@ sub hal_from_contact : Private {
name => 'ngcp',
templated => true,
),
Data::HAL::Link->new(relation => 'collection', href => '/api/contacts/'),
Data::HAL::Link->new(relation => 'collection', href => sprintf('/%s', $c->request->path)),
Data::HAL::Link->new(relation => 'profile', href => 'http://purl.org/sipwise/ngcp-api/'),
Data::HAL::Link->new(relation => 'self', href => "/api/contacts/$id"),
Data::HAL::Link->new(relation => 'self', href => sprintf("/%s%d", $c->request->path, $contact->id)),
$contact->reseller
? Data::HAL::Link->new(
relation => 'ngcp:resellers',
href => sprintf('/api/resellers/%d', $contact->reseller_id),
) : (),
],
relation => 'ngcp:contacts',
relation => 'ngcp:'.$self->resource_name,
);
return unless $self->validate_form(
c => $c,
form => $form,
resource => \%resource,
run => 0,
);
my %fields = map { $_->name => undef } grep { 'Text' eq $_->type || 'Email' eq $_->type }
NGCP::Panel::Form::Contact::Reseller->new->fields;
for my $k (keys %resource) {
delete $resource{$k} unless exists $fields{$k};
$resource{$k} = DateTime::Format::RFC3339->format_datetime($resource{$k}) if $resource{$k}->$_isa('DateTime');
}
$hal->resource({%resource});
return $hal;
}
sub valid_id : Private {
my ($self, $c, $id) = @_;
return 1 if $id->is_integer;
$c->response->status(HTTP_BAD_REQUEST);
$c->response->header('Content-Language' => 'en');
$c->response->content_type('application/xhtml+xml');
$c->stash(template => 'api/invalid_query_parameter.tt', key => 'id');
return;
}
sub end : Private {
my ($self, $c) = @_;

@ -1,19 +1,13 @@
package NGCP::Panel::Controller::API::ContactsItem;
package NGCP::Panel::Controller::API::SystemContactsItem;
use Sipwise::Base;
use namespace::sweep;
use boolean qw(true);
use Data::HAL qw();
use Data::HAL::Link qw();
use Data::Record qw();
use DateTime::Format::HTTP qw();
use DateTime::Format::RFC3339 qw();
use Digest::SHA3 qw(sha3_256_base64);
use HTTP::Headers qw();
use HTTP::Status qw(:constants);
use JSON qw();
use MooseX::ClassAttribute qw(class_has);
use NGCP::Panel::Form::Contact::Reseller qw();
use NGCP::Panel::Form::Contact::Admin qw();
use NGCP::Panel::Utils::ValidateJSON qw();
use Path::Tiny qw(path);
use Safe::Isa qw($_isa);
@ -24,8 +18,9 @@ require Catalyst::ActionRole::RequireSSL;
with 'NGCP::Panel::Role::API';
class_has('dispatch_path', is => 'ro', default => '/api/contacts/');
class_has('relation', is => 'ro', default => 'http://purl.org/sipwise/ngcp-api/#rel-contacts');
class_has('resource_name', is => 'ro', default => 'systemcontacts');
class_has('dispatch_path', is => 'ro', default => '/api/systemcontacts/');
class_has('relation', is => 'ro', default => 'http://purl.org/sipwise/ngcp-api/#rel-systemcontacts');
__PACKAGE__->config(
action => {
@ -52,23 +47,20 @@ sub GET :Allow {
my ($self, $c, $id) = @_;
{
last unless $self->valid_id($c, $id);
last if $self->cached($c);
my $contact = $self->contact_by_id($c, $id);
last unless $self->resource_exists($c, contact => $contact);
my $hal = $self->hal_from_contact($c, $contact);
my $form = NGCP::Panel::Form::Contact::Reseller->new;
my $hal = $self->hal_from_contact($c, $contact, $form);
# TODO: we don't need reseller stuff here!
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"|;
s/rel=self/rel="item self"/;
$_
} $hal->http_headers),
Cache_Control => 'no-cache, private',
ETag => $self->etag($hal->as_json),
Expires => DateTime::Format::HTTP->format_datetime($self->expires),
Last_Modified => DateTime::Format::HTTP->format_datetime($self->last_modified),
), $hal->as_json);
$c->cache->set($c->request->uri->canonical->as_string, $response, { expires_at => $self->expires->epoch });
$c->response->headers($response->headers);
$c->response->body($response->content);
return;
@ -89,7 +81,6 @@ sub OPTIONS :Allow {
$c->response->headers(HTTP::Headers->new(
Allow => $allowed_methods->join(', '),
Accept_Patch => 'application/json-patch+json',
Content_Language => 'en',
));
$c->response->content_type('application/json');
$c->response->body(JSON::to_json({ methods => $allowed_methods })."\n");
@ -234,84 +225,29 @@ sub PUT :Allow {
my $preference = $self->require_preference($c);
last unless $preference;
my $contact;
my $cached = $c->cache->get($c->request->uri->canonical->as_string);
if ($cached) {
try {
die 'not a response object' unless $cached->$_isa('HTTP::Response');
} catch($e) {
die "cache poisoned: $e";
};
last unless $self->valid_precondition($c, $cached->header('ETag'), 'contact');
try {
=pod
# TODO: what does this actually do? we need to go to DB for fetching the
# contact anyways, no?
NGCP::Panel::Utils::ValidateJSON->new($cached->content);
$resource = JSON::decode_json($cached->content);
delete $resource->{_links};
delete $resource->{_embedded};
$c->log->debug("+++++++++++++++ got contact for PUT from cache");
=cut
} catch($e) {
die "cache poisoned: $e";
};
} else {
if ('*' eq $c->request->header('If-Match')) {
$contact = $self->contact_by_id($c, $id);
last unless $self->resource_exists($c, contact => $contact);
} else {
$self->error($c, HTTP_PRECONDITION_FAILED, "This 'contact' entity cannot be found, it is either expired or does not exist. Fetch a fresh one.");
last;
}
}
my $contact_form;
my $undef_reseller;
if($c->user->roles eq "api_admin") {
if(defined $resource->{reseller_id}) {
$contact_form = NGCP::Panel::Form::Contact::Admin->new;
} else {
$contact_form = NGCP::Panel::Form::Contact::Reseller->new;
delete $resource->{reseller_id};
$undef_reseller = 1;
}
} else {
$contact_form = NGCP::Panel::Form::Contact::Reseller->new;
# keep the reseller_id as is if a reseller is updating a contact
delete $resource->{reseller_id};
}
my $form = NGCP::Panel::Form::Contact::Reseller->new;
last unless $self->validate_form(
c => $c,
resource => $resource,
form => $contact_form,
form => $form,
);
$resource->{reseller_id} = undef
if($undef_reseller);
$resource->{modify_timestamp} = DateTime->now;
$contact = $self->contact_by_id($c, $id) unless $contact;
my $contact = $self->contact_by_id($c, $id);
$contact->update($resource);
$guard->commit;
if ('minimal' eq $preference) {
$c->cache->remove($c->request->uri->canonical->as_string);
$c->response->status(HTTP_NO_CONTENT);
$c->response->header(Preference_Applied => 'return=minimal');
$c->response->body(q());
} else {
my $hal = $self->hal_from_contact($c, $contact);
my $hal = $self->hal_from_contact($c, $contact, $form);
my $response = HTTP::Response->new(HTTP_OK, undef, HTTP::Headers->new(
$hal->http_headers,
Cache_Control => 'no-cache, private',
ETag => $self->etag($hal->as_json),
Expires => DateTime::Format::HTTP->format_datetime($self->expires),
Last_Modified => DateTime::Format::HTTP->format_datetime($self->last_modified),
), $hal->as_json);
$c->cache->set($c->request->uri->canonical->as_string, $response, { expires_at => $self->expires->epoch });
$c->response->headers($response->headers);
$c->response->header(Preference_Applied => 'return=representation'); # don't cache this
$c->response->header(Preference_Applied => 'return=representation');
$c->response->body($response->content);
}
}
@ -335,8 +271,6 @@ sub DELETE :Allow {
}
$guard->commit;
$c->cache->remove($c->request->uri->canonical->as_string);
$c->response->status(HTTP_NO_CONTENT);
$c->response->body(q());
}
@ -345,26 +279,17 @@ sub DELETE :Allow {
sub contact_by_id : Private {
my ($self, $c, $id) = @_;
my $contact_rs = $c->model('DB')->resultset('contacts');
if($c->user->roles eq "api_admin") {
# admin can handle all contacts
} elsif($c->user->roles eq "api_reseller") {
$contact_rs = $contact_rs->search({
reseller_id => $c->user->reseller_id,
});
} else {
# TODO: for subscribers etc?
return;
}
# we only return system contacts, that is, a contact without reseller
my $contact_rs = $c->model('DB')->resultset('contacts')
->search({ reseller_id => undef });
return $contact_rs->find({'me.id' => $id});
}
sub hal_from_contact : Private {
my ($self, $c, $contact) = @_;
# XXX invalid 00-00-00 dates
my %resource = $contact->get_inflated_columns;
my $id = $resource{id};
$self->last_modified(delete $resource{modify_timestamp});
my $hal = Data::HAL->new(
links => [
@ -374,24 +299,14 @@ sub hal_from_contact : Private {
name => 'ngcp',
templated => true,
),
Data::HAL::Link->new(relation => 'collection', href => '/api/contacts/'),
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 => "/api/contacts/$id"),
$contact->reseller
? Data::HAL::Link->new(
relation => 'ngcp:resellers',
href => sprintf('/api/resellers/%d', $contact->reseller_id),
) : (),
Data::HAL::Link->new(relation => 'self', href => sprintf("/%s", $c->request->path)),
],
relation => 'ngcp:contacts',
relation => 'ngcp:'.$self->resource_name,
);
my $form;
if($c->user->roles eq "api_admin") {
$form = NGCP::Panel::Form::Contact::Admin->new;
} else {
$form = NGCP::Panel::Form::Contact::Reseller->new;
}
my $form = NGCP::Panel::Form::Contact::Reseller->new;
$self->validate_form(
c => $c,
resource => \%resource,

@ -99,6 +99,7 @@ sub validate_form {
# 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};
@ -177,6 +178,8 @@ sub require_wellformed_json {
return 1;
}
=pod
# don't use caching for now, keep it as simple as possible
sub cached {
my ($self, $c) = @_;
my $response = $c->cache->get($c->request->uri->canonical->as_string);
@ -213,6 +216,7 @@ sub expires {
my ($self) = @_;
return DateTime->now->clone->add(years => 1); # XXX insert product end-of-life
}
=cut
sub allowed_methods {
my ($self) = @_;

@ -1 +1,6 @@
# TODO: try to set reseller_id of contact of a system contract, which should fail
# TODO: try to delete used contact
# $req = HTTP::Request->new('DELETE', $uri.'/api/systemcontacts/1');
# $res = $ua->request($req);
# ok($res->code == 423, "check delete of used contact");

@ -23,10 +23,10 @@ $ua->ssl_opts(
# OPTIONS tests
{
$req = HTTP::Request->new('OPTIONS', $uri.'/api/contacts/');
$req = HTTP::Request->new('OPTIONS', $uri.'/api/systemcontacts/');
$res = $ua->request($req);
ok($res->code == 200, "check options request");
ok($res->header('Accept-Post') eq "application/hal+json; profile=http://purl.org/sipwise/ngcp-api/#rel-contacts", "check Accept-Post header in options response");
ok($res->header('Accept-Post') eq "application/hal+json; profile=http://purl.org/sipwise/ngcp-api/#rel-systemcontacts", "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");
@ -43,13 +43,12 @@ my @allcontacts = ();
# create 6 new system contacts (no reseller)
my %contacts = ();
for(my $i = 1; $i <= 6; ++$i) {
$req = HTTP::Request->new('POST', $uri.'/api/contacts/');
$req = HTTP::Request->new('POST', $uri.'/api/systemcontacts/');
$req->header('Content-Type' => 'application/json');
$req->content(JSON::to_json({
firstname => "Test_First_$i",
lastname => "Test_Last_$i",
email => "test.$i\@test.invalid",
reseller_id => 1,
}));
$res = $ua->request($req);
ok($res->code == 201, "create test contact $i");
@ -59,7 +58,7 @@ my @allcontacts = ();
}
# try to create invalid contact without email
$req = HTTP::Request->new('POST', $uri.'/api/contacts/');
$req = HTTP::Request->new('POST', $uri.'/api/systemcontacts/');
$req->header('Content-Type' => 'application/json');
$req->content(JSON::to_json({
firstname => "Test_First_invalid",
@ -71,23 +70,8 @@ my @allcontacts = ();
ok($email_err->{code} eq "422", "check error code in body");
ok($email_err->{message} =~ /field=\'email\'/, "check error message in body");
# try to create invalid contact with invalid reseller_id
$req = HTTP::Request->new('POST', $uri.'/api/contacts/');
$req->header('Content-Type' => 'application/json');
$req->content(JSON::to_json({
firstname => "Test_First_invalid",
lastname => "Test_Last_invalid",
email => "test.invalid\@test.invalid",
reseller_id => 99999,
}));
$res = $ua->request($req);
ok($res->code == 422, "create test contact with invalid reseller_id");
my $reseller_err = JSON::from_json($res->decoded_content);
ok($reseller_err->{code} eq "422", "check error code in body");
ok($reseller_err->{message} =~ /Invalid reseller_id/, "check error message in body");
# iterate over contacts collection to check next/prev links
my $nexturi = $uri.'/api/contacts/?page=1&rows=5';
my $nexturi = $uri.'/api/systemcontacts/?page=1&rows=5';
do {
$res = $ua->get($nexturi);
ok($res->code == 200, "fetch contacts page");
@ -120,15 +104,15 @@ my @allcontacts = ();
}
# TODO: I'd expect that to be an array ref in any case!
ok((ref $collection->{_links}->{'ngcp:contacts'} eq "ARRAY" ||
ref $collection->{_links}->{'ngcp:contacts'} eq "HASH"), "check if 'ngcp:contacts' is array/hash-ref");
ok((ref $collection->{_links}->{'ngcp:systemcontacts'} eq "ARRAY" ||
ref $collection->{_links}->{'ngcp:systemcontacts'} eq "HASH"), "check if 'ngcp:contacts' is array/hash-ref");
# remove any contact we find in the collection for later check
if(ref $collection->{_links}->{'ngcp:contacts'} eq "HASH") {
if(ref $collection->{_links}->{'ngcp:systemcontacts'} eq "HASH") {
# TODO: handle hashref
delete $contacts{$collection->{_links}->{'ngcp:contacts'}->{href}};
delete $contacts{$collection->{_links}->{'ngcp:systemcontacts'}->{href}};
} else {
foreach my $c(@{ $collection->{_links}->{'ngcp:contacts'} }) {
foreach my $c(@{ $collection->{_links}->{'ngcp:systemcontacts'} }) {
delete $contacts{$c->{href}};
}
}
@ -161,10 +145,7 @@ my @allcontacts = ();
ok(exists $contact->{firstname}, "check existence of firstname");
ok(exists $contact->{lastname}, "check existence of lastname");
ok(exists $contact->{email}, "check existence of email");
ok(exists $contact->{reseller_id}, "check existence of reseller_id");
if(defined $contact->{reseller_id}) {
ok($res->decoded_content =~ /\"reseller_id\"\s*:\s*\d+/, "check if reseller_id is number");
}
ok(!exists $contact->{reseller_id}, "check absence of reseller_id");
# PUT same result again
my $old_contact = { %$contact };
@ -217,24 +198,14 @@ my @allcontacts = ();
my $new_contact = JSON::from_json($res->decoded_content);
is_deeply($old_contact, $new_contact, "check put if unmodified put returns the same");
# check if a contact without reseller doesn't have a resellers link
$contact->{reseller_id} = undef;
$req->content(JSON::to_json($contact));
$res = $ua->request($req);
ok($res->code == 200, "check put successful");
$new_contact = JSON::from_json($res->decoded_content);
ok(!defined $new_contact->{reseller_id}, "check put if reseller_id is undef");
ok(!exists $new_contact->{_links}->{'ngcp:resellers'}, "check put absence of ngcp:resellers relation");
# check if a contact with reseller has resellers link
# check if a system contact with reseller has no resellers link
$contact->{reseller_id} = 1;
$req->content(JSON::to_json($contact));
$res = $ua->request($req);
ok($res->code == 200, "check put successful");
$new_contact = JSON::from_json($res->decoded_content);
ok(defined $new_contact->{reseller_id} && $new_contact->{reseller_id} == 1, "check put if reseller_id is set");
ok(exists $new_contact->{_links}->{'ngcp:resellers'} && ref $new_contact->{_links}->{'ngcp:resellers'} eq "HASH", "check put presence of ngcp:resellers relation");
ok($new_contact->{_links}->{'ngcp:resellers'}->{href} eq "/api/resellers/1", "check put correct ngcp:resellers relation href");
ok(!exists $new_contact->{reseller_id}, "check put if reseller_id is absent");
ok(!exists $new_contact->{_links}->{'ngcp:resellers'}, "check put absence of ngcp:resellers relation");
}
# DELETE
@ -244,9 +215,6 @@ my @allcontacts = ();
$res = $ua->request($req);
ok($res->code == 204, "check delete of contact");
}
$req = HTTP::Request->new('DELETE', $uri.'/api/contacts/1');
$res = $ua->request($req);
ok($res->code == 423, "check delete of used contact");
}
done_testing;
Loading…
Cancel
Save