diff --git a/lib/NGCP/Panel/Controller/API/Contacts.pm b/lib/NGCP/Panel/Controller/API/SystemContacts.pm similarity index 59% rename from lib/NGCP/Panel/Controller/API/Contacts.pm rename to lib/NGCP/Panel/Controller/API/SystemContacts.pm index 860594c7bd..6fabf2b30b 100644 --- a/lib/NGCP/Panel/Controller/API/Contacts.pm +++ b/lib/NGCP/Panel/Controller/API/SystemContacts.pm @@ -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) = @_; diff --git a/lib/NGCP/Panel/Controller/API/ContactsItem.pm b/lib/NGCP/Panel/Controller/API/SystemContactsItem.pm similarity index 70% rename from lib/NGCP/Panel/Controller/API/ContactsItem.pm rename to lib/NGCP/Panel/Controller/API/SystemContactsItem.pm index 151f7cbd11..ef6acfea80 100644 --- a/lib/NGCP/Panel/Controller/API/ContactsItem.pm +++ b/lib/NGCP/Panel/Controller/API/SystemContactsItem.pm @@ -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, diff --git a/lib/NGCP/Panel/Role/API.pm b/lib/NGCP/Panel/Role/API.pm index c455c9cb35..5ef956586f 100644 --- a/lib/NGCP/Panel/Role/API.pm +++ b/lib/NGCP/Panel/Role/API.pm @@ -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) = @_; diff --git a/t/api-contracts.t b/t/api-contracts.t index a44687ab6b..ad58921f1b 100644 --- a/t/api-contracts.t +++ b/t/api-contracts.t @@ -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"); diff --git a/t/api-contacts.t b/t/api-systemcontacts.t similarity index 74% rename from t/api-contacts.t rename to t/api-systemcontacts.t index 7bd8d4b63f..dc04e65012 100644 --- a/t/api-contacts.t +++ b/t/api-systemcontacts.t @@ -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;