Bugzilla – Attachment 162138 Details for
Bug 17390
Add REST API endpoint for Authorised Values
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 17390: Add /authorised_values endpoint
Bug-17390-Add-authorisedvalues-endpoint.patch (text/plain), 23.13 KB, created by
Martin Renvoize (ashimema)
on 2024-02-14 10:14:10 UTC
(
hide
)
Description:
Bug 17390: Add /authorised_values endpoint
Filename:
MIME Type:
Creator:
Martin Renvoize (ashimema)
Created:
2024-02-14 10:14:10 UTC
Size:
23.13 KB
patch
obsolete
>From 7ff782188759fbb52de4e563063e7f1bb55852c2 Mon Sep 17 00:00:00 2001 >From: Jonathan Druart <jonathan.druart@bugs.koha-community.org> >Date: Fri, 12 Jun 2020 15:20:05 +0200 >Subject: [PATCH] Bug 17390: Add /authorised_values endpoint > >This patch add the different routes for authorised values: >* GET /authorised_values >* GET /authorised_values/{authorised_value_id} >* POST /authorised_values >* PUT /authorised_values/{authorised_value_id} >* DELETE /authorised_values/{authorised_value_id} > >Test plan: >- Make sure the tests in t/db_dependent/api/v1/authorised_values.t pass >- Test the different routes. >For instance: >GET /authorised_values # list all the avs >GET /authorised_values?category=YES_NO # list all the YES_NO avs > >POST /authorised_values > { > "category": "YES_NO", > "description": "not sure", > "opac_description": "something else", > "value": "maybe" > } > >DELETE /authorised_values/X # with X the AV id of "maybe" > >Sponsored-by: Orex Digital >--- > Koha/REST/V1/AuthorisedValues.pm | 109 ++++++ > api/v1/swagger/paths/authorised_values.yaml | 216 +++++++++++- > api/v1/swagger/swagger.yaml | 4 + > t/db_dependent/api/v1/authorised_values.t | 352 +++++++++++++++++++- > 4 files changed, 679 insertions(+), 2 deletions(-) > >diff --git a/Koha/REST/V1/AuthorisedValues.pm b/Koha/REST/V1/AuthorisedValues.pm >index 3a4706f6681..8fe3522f6c3 100644 >--- a/Koha/REST/V1/AuthorisedValues.pm >+++ b/Koha/REST/V1/AuthorisedValues.pm >@@ -20,6 +20,7 @@ use Modern::Perl; > use Mojo::Base 'Mojolicious::Controller'; > > use Koha::AuthorisedValueCategories; >+use Koha::AuthorisedValues; > > use Try::Tiny; > >@@ -52,7 +53,115 @@ sub list_av_from_category { > } catch { > $c->unhandled_exception($_); > }; >+} >+ >+=head3 list >+ >+=cut >+ >+sub list { >+ my $c = shift->openapi->valid_input or return; >+ >+ return try { >+ my $av_set = Koha::AuthorisedValues->new; >+ my $avs = $c->objects->search( $av_set ); >+ return $c->render( status => 200, openapi => $avs ); >+ } >+ catch { >+ $c->unhandled_exception($_); >+ }; >+ >+} >+ >+=head3 get >+ >+=cut >+ >+sub get { >+ my $c = shift->openapi->valid_input or return; >+ >+ return try { >+ my $av = Koha::AuthorisedValues->find( $c->validation->param('authorised_value_id') ); >+ unless ($av) { >+ return $c->render( status => 404, >+ openapi => { error => "Authorised value not found" } ); >+ } >+ >+ return $c->render( status => 200, openapi => $av->to_api ); >+ } >+ catch { >+ $c->unhandled_exception($_); >+ } >+} >+ >+=head3 add >+ >+=cut >+ >+sub add { >+ my $c = shift->openapi->valid_input or return; >+ >+ return try { >+ my $av = Koha::AuthorisedValue->new_from_api( $c->validation->param('body') ); >+ $av->store; >+ $c->res->headers->location( $c->req->url->to_string . '/' . $av->id ); >+ return $c->render( >+ status => 201, >+ openapi => $av->to_api >+ ); >+ } >+ catch { >+ $c->unhandled_exception($_); >+ }; >+} >+ >+=head3 update >+ >+=cut > >+sub update { >+ my $c = shift->openapi->valid_input or return; >+ >+ my $av = Koha::AuthorisedValues->find( $c->validation->param('authorised_value_id') ); >+ >+ if ( not defined $av ) { >+ return $c->render( status => 404, >+ openapi => { error => "Object not found" } ); >+ } >+ >+ return try { >+ $av->set_from_api( $c->validation->param('body') ); >+ $av->store(); >+ return $c->render( status => 200, openapi => $av->to_api ); >+ } >+ catch { >+ $c->unhandled_exception($_); >+ }; >+} >+ >+=head3 delete >+ >+=cut >+ >+sub delete { >+ my $c = shift->openapi->valid_input or return; >+ >+ my $av = Koha::AuthorisedValues->find( $c->validation->param('authorised_value_id') ); >+ if ( not defined $av ) { >+ return $c->render( status => 404, >+ openapi => { error => "Object not found" } ); >+ } >+ >+ return try { >+ $av->delete; >+ return $c->render( >+ status => 204, >+ openapi => q{} >+ ); >+ } >+ catch { >+ $c->unhandled_exception($_); >+ }; > } > > 1; >diff --git a/api/v1/swagger/paths/authorised_values.yaml b/api/v1/swagger/paths/authorised_values.yaml >index 07e298dc217..c3f0821975a 100644 >--- a/api/v1/swagger/paths/authorised_values.yaml >+++ b/api/v1/swagger/paths/authorised_values.yaml >@@ -1,4 +1,218 @@ > --- >+/authorised_values: >+ get: >+ operationId: listAuthorisedValues >+ parameters: >+ - description: Search authorised values by category >+ in: query >+ name: category >+ required: false >+ type: string >+ - description: Search authorised values by value >+ in: query >+ name: value >+ required: false >+ type: string >+ - description: Search authorised values by description >+ in: query >+ name: description >+ required: false >+ type: string >+ - description: Search authorised values by opac description >+ in: query >+ name: opac_description >+ required: false >+ type: string >+ - description: Search authorised values by image url >+ in: query >+ name: image_url >+ required: false >+ type: string >+ - $ref: ../parameters.json#/match >+ - $ref: ../parameters.json#/order_by >+ - $ref: ../parameters.json#/page >+ - $ref: ../parameters.json#/per_page >+ - $ref: ../parameters.json#/q_param >+ - $ref: ../parameters.json#/q_body >+ - $ref: ../parameters.json#/q_header >+ produces: >+ - application/json >+ responses: >+ 200: >+ description: A list of authorised values >+ schema: >+ items: >+ $ref: ../definitions.json#/authorised_value >+ type: array >+ 403: >+ description: Access forbidden >+ schema: >+ $ref: ../definitions.json#/error >+ 500: >+ description: Internal error >+ schema: >+ $ref: ../definitions.json#/error >+ 503: >+ description: Under maintenance >+ schema: >+ $ref: ../definitions.json#/error >+ tags: >+ - authorised >+ - values >+ x-koha-authorization: >+ permissions: >+ catalogue: 1 >+ x-mojo-to: AuthorisedValues#list >+ post: >+ operationId: addAuthorisedValue >+ parameters: >+ - description: A JSON object containing informations about the new authorised value >+ in: body >+ name: body >+ required: true >+ schema: >+ $ref: ../definitions.json#/authorised_value >+ produces: >+ - application/json >+ responses: >+ 201: >+ description: Authorised value added >+ schema: >+ $ref: ../definitions.json#/authorised_value >+ 401: >+ description: Authentication required >+ schema: >+ $ref: ../definitions.json#/error >+ 403: >+ description: Access forbidden >+ schema: >+ $ref: ../definitions.json#/error >+ 500: >+ description: Internal error >+ schema: >+ $ref: ../definitions.json#/error >+ 503: >+ description: Under maintenance >+ schema: >+ $ref: ../definitions.json#/error >+ tags: >+ - authorised >+ - values >+ x-koha-authorization: >+ permissions: >+ parameters: manage_auth_values >+ x-mojo-to: AuthorisedValues#add >+"/authorised_values/{authorised_value_id}": >+ delete: >+ operationId: deleteAuthorisedValue >+ parameters: >+ - $ref: ../parameters.json#/authorised_value_id_pp >+ produces: >+ - application/json >+ responses: >+ 204: >+ description: Authorised value deleted >+ 401: >+ description: Authentication required >+ schema: >+ $ref: ../definitions.json#/error >+ 403: >+ description: Access forbidden >+ schema: >+ $ref: ../definitions.json#/error >+ 404: >+ description: Authorised value not found >+ schema: >+ $ref: ../definitions.json#/error >+ 500: >+ description: Internal error >+ schema: >+ $ref: ../definitions.json#/error >+ 503: >+ description: Under maintenance >+ schema: >+ $ref: ../definitions.json#/error >+ tags: >+ - authorised >+ - values >+ x-koha-authorization: >+ permissions: >+ parameters: manage_auth_values >+ x-mojo-to: AuthorisedValues#delete >+ get: >+ operationId: getAuthorisedValue >+ parameters: >+ - $ref: ../parameters.json#/authorised_value_id_pp >+ produces: >+ - application/json >+ responses: >+ 200: >+ description: An authorised value >+ schema: >+ $ref: ../definitions.json#/authorised_value >+ 404: >+ description: Authorised value not found >+ schema: >+ $ref: ../definitions.json#/error >+ 500: >+ description: Internal error >+ schema: >+ $ref: ../definitions.json#/error >+ 503: >+ description: Under maintenance >+ schema: >+ $ref: ../definitions.json#/error >+ tags: >+ - authorised >+ - values >+ x-koha-authorization: >+ permissions: >+ catalogue: 1 >+ x-mojo-to: AuthorisedValues#get >+ put: >+ operationId: updateAuthorisedValue >+ parameters: >+ - $ref: ../parameters.json#/authorised_value_id_pp >+ - description: An authorised value object >+ in: body >+ name: body >+ required: true >+ schema: >+ $ref: ../definitions.json#/authorised_value >+ produces: >+ - application/json >+ responses: >+ 200: >+ description: An authorised value >+ schema: >+ $ref: ../definitions.json#/authorised_value >+ 401: >+ description: Authentication required >+ schema: >+ $ref: ../definitions.json#/error >+ 403: >+ description: Access forbidden >+ schema: >+ $ref: ../definitions.json#/error >+ 404: >+ description: Authorised value not found >+ schema: >+ $ref: ../definitions.json#/error >+ 500: >+ description: Internal error >+ schema: >+ $ref: ../definitions.json#/error >+ 503: >+ description: Under maintenance >+ schema: >+ $ref: ../definitions.json#/error >+ tags: >+ - authorised >+ - value >+ x-koha-authorization: >+ permissions: >+ parameters: manage_auth_values >+ x-mojo-to: AuthorisedValues#update > "/authorised_value_categories/{authorised_value_category_name}/authorised_values": > get: > x-mojo-to: AuthorisedValues#list_av_from_category >@@ -66,7 +280,7 @@ > schema: > $ref: "../swagger.yaml#/definitions/error" > 404: >- description: Ressource not found >+ description: Resource not found > schema: > $ref: "../swagger.yaml#/definitions/error" > 500: >diff --git a/api/v1/swagger/swagger.yaml b/api/v1/swagger/swagger.yaml >index 227921d7957..2b372b868d7 100644 >--- a/api/v1/swagger/swagger.yaml >+++ b/api/v1/swagger/swagger.yaml >@@ -217,6 +217,10 @@ paths: > $ref: ./paths/auth.yaml#/~1auth~1identity_providers~1{identity_provider_id}~1domains > "/auth/identity_providers/{identity_provider_id}/domains/{identity_provider_domain_id}": > $ref: ./paths/auth.yaml#/~1auth~1identity_providers~1{identity_provider_id}~1domains~1{identity_provider_domain_id} >+ "/authorised_values": >+ $ref: ./paths/authorised_values.yaml#/~1authorised_values >+ "/authorised_values/{authorised_value_id}": >+ $ref: ./paths/authorised_values.yaml#/~1authorised_values~1{authorised_value_id} > /authorised_value_categories: > $ref: ./paths/authorised_value_categories.yaml#/~1authorised_value_categories > "/authorised_value_categories/{authorised_value_category_name}/authorised_values": >diff --git a/t/db_dependent/api/v1/authorised_values.t b/t/db_dependent/api/v1/authorised_values.t >index 187087d4408..87c9a75383f 100755 >--- a/t/db_dependent/api/v1/authorised_values.t >+++ b/t/db_dependent/api/v1/authorised_values.t >@@ -17,7 +17,7 @@ > > use Modern::Perl; > >-use Test::More tests => 1; >+use Test::More tests => 6; > use Test::Mojo; > > use t::lib::TestBuilder; >@@ -85,3 +85,353 @@ subtest 'list_av_from_category() tests' => sub { > > $schema->storage->txn_rollback; > }; >+ >+subtest 'list() tests' => sub { >+ >+ plan tests => 20; >+ >+ $schema->storage->txn_begin; >+ >+ Koha::AuthorisedValues->search->delete; >+ >+ my $librarian = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 2 ** 2 } # catalogue flag = 2 >+ } >+ ); >+ my $password = 'thePassword123'; >+ $librarian->set_password( { password => $password, skip_validation => 1 } ); >+ my $userid = $librarian->userid; >+ >+ my $patron = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 0 } >+ } >+ ); >+ >+ $patron->set_password( { password => $password, skip_validation => 1 } ); >+ my $unauth_userid = $patron->userid; >+ >+ ## Authorized user tests >+ # No AVs, so empty array should be returned >+ $t->get_ok("//$userid:$password@/api/v1/authorised_values") >+ ->status_is(200) >+ ->json_is( [] ); >+ >+ my $av = $builder->build_object({ class => 'Koha::AuthorisedValues' }); >+ >+ # One av created, should get returned >+ $t->get_ok("//$userid:$password@/api/v1/authorised_values") >+ ->status_is(200) >+ ->json_is( [$av->to_api] ); >+ >+ my $another_av = $builder->build_object( >+ { class => 'Koha::AuthorisedValues', value => { lib => $av->lib } } ); >+ my $av_with_another_lib = $builder->build_object({ class => 'Koha::AuthorisedValues' }); >+ >+ # Two avs created, they should both be returned >+ $t->get_ok("//$userid:$password@/api/v1/authorised_values") >+ ->status_is(200) >+ ->json_is([$av->to_api, >+ $another_av->to_api, >+ $av_with_another_lib->to_api >+ ] ); >+ >+ # Filtering works, two avs sharing lib >+ $t->get_ok("//$userid:$password@/api/v1/authorised_values?description=" . $av->lib ) >+ ->status_is(200) >+ ->json_is([ $av->to_api, >+ $another_av->to_api >+ ]); >+ >+ $t->get_ok("//$userid:$password@/api/v1/authorised_values?value=" . $av->authorised_value ) >+ ->status_is(200) >+ ->json_is( [$av->to_api] ); >+ >+ # Warn on unsupported query parameter >+ $t->get_ok("//$userid:$password@/api/v1/authorised_values?av_blah=blah" ) >+ ->status_is(400) >+ ->json_is( [{ path => '/query/av_blah', message => 'Malformed query string'}] ); >+ >+ # Unauthorized access >+ $t->get_ok("//$unauth_userid:$password@/api/v1/authorised_values") >+ ->status_is(403); >+ >+ $schema->storage->txn_rollback; >+}; >+ >+subtest 'get() tests' => sub { >+ >+ plan tests => 8; >+ >+ $schema->storage->txn_begin; >+ >+ my $av = $builder->build_object({ class => 'Koha::AuthorisedValues' }); >+ my $librarian = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 2**2 } # catalogue flag = 2 >+ } >+ ); >+ my $password = 'thePassword123'; >+ $librarian->set_password( { password => $password, skip_validation => 1 } ); >+ my $userid = $librarian->userid; >+ >+ my $patron = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 0 } >+ } >+ ); >+ >+ $patron->set_password( { password => $password, skip_validation => 1 } ); >+ my $unauth_userid = $patron->userid; >+ >+ $t->get_ok( "//$userid:$password@/api/v1/authorised_values/" . $av->id ) >+ ->status_is(200) >+ ->json_is($av->to_api); >+ >+ $t->get_ok( "//$unauth_userid:$password@/api/v1/authorised_values/" . $av->id ) >+ ->status_is(403); >+ >+ my $av_to_delete = $builder->build_object({ class => 'Koha::AuthorisedValues' }); >+ my $non_existent_id = $av_to_delete->id; >+ $av_to_delete->delete; >+ >+ $t->get_ok( "//$userid:$password@/api/v1/authorised_values/$non_existent_id" ) >+ ->status_is(404) >+ ->json_is( '/error' => 'Authorised value not found' ); >+ >+ $schema->storage->txn_rollback; >+}; >+ >+subtest 'add() tests' => sub { >+ >+ plan tests => 18; >+ >+ $schema->storage->txn_begin; >+ >+ my $librarian = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 2**3 } # parameters flag = 2 >+ } >+ ); >+ my $password = 'thePassword123'; >+ $librarian->set_password( { password => $password, skip_validation => 1 } ); >+ my $userid = $librarian->userid; >+ >+ my $patron = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 0 } >+ } >+ ); >+ >+ $patron->set_password( { password => $password, skip_validation => 1 } ); >+ my $unauth_userid = $patron->userid; >+ >+ my $av_cat = $builder->build_object({ class => 'Koha::AuthorisedValueCategories' }); >+ my $av = { >+ category => $av_cat->category_name, >+ value => "a value", >+ description => "a lib", >+ opac_description => "opac lib" >+ }; >+ >+ # Unauthorized attempt to write >+ $t->post_ok("//$unauth_userid:$password@/api/v1/authorised_values" => json => $av) >+ ->status_is(403); >+ >+ # Authorized attempt to write invalid data >+ my $av_with_invalid_field = { >+ blah => "Av Blah", >+ category => $av_cat->category_name, >+ value => "a value", >+ description => "a lib", >+ opac_description => "opac lib" >+ }; >+ >+ $t->post_ok( "//$userid:$password@/api/v1/authorised_values" => json => $av_with_invalid_field ) >+ ->status_is(400) >+ ->json_is( >+ "/errors" => [ >+ { >+ message => "Properties not allowed: blah.", >+ path => "/body" >+ } >+ ] >+ ); >+ >+ # Authorized attempt to write >+ my $av_id = >+ $t->post_ok( "//$userid:$password@/api/v1/authorised_values" => json => $av ) >+ ->status_is( 201, 'SWAGGER3.2.1' ) >+ ->header_like( >+ Location => qr|^\/api\/v1\/authorised_values/\d*|, >+ 'SWAGGER3.4.1' >+ ) >+ ->json_is( '/category' => $av->{category} ) >+ ->json_is( '/value' => $av->{value} ) >+ ->json_is( '/description' => $av->{description} ) >+ ->json_is( '/opac_description' => $av->{opac_description} ) >+ ->tx->res->json->{authorised_value_id}; >+ >+ # Authorized attempt to create with null id >+ $av->{authorised_value_id} = undef; >+ $t->post_ok( "//$userid:$password@/api/v1/authorised_values" => json => $av ) >+ ->status_is(400) >+ ->json_has('/errors'); >+ >+ # Authorized attempt to create with existing id >+ $av->{authorised_value_id} = $av_id; >+ $t->post_ok( "//$userid:$password@/api/v1/authorised_values" => json => $av ) >+ ->status_is(400) >+ ->json_is( >+ "/errors" => [ >+ { >+ message => "Read-only.", >+ path => "/body/authorised_value_id" >+ } >+ ] >+ ); >+ >+ $schema->storage->txn_rollback; >+}; >+ >+subtest 'update() tests' => sub { >+ >+ plan tests => 15; >+ >+ $schema->storage->txn_begin; >+ >+ my $librarian = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 2**3 } # parameters flag = 2 >+ } >+ ); >+ my $password = 'thePassword123'; >+ $librarian->set_password( { password => $password, skip_validation => 1 } ); >+ my $userid = $librarian->userid; >+ >+ my $patron = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 0 } >+ } >+ ); >+ >+ $patron->set_password( { password => $password, skip_validation => 1 } ); >+ my $unauth_userid = $patron->userid; >+ >+ my $av_id = $builder->build_object({ class => 'Koha::AuthorisedValues' } )->id; >+ >+ # Unauthorized attempt to update >+ $t->put_ok( "//$unauth_userid:$password@/api/v1/authorised_values/$av_id" => json => { name => 'New unauthorized name change' } ) >+ ->status_is(403); >+ >+ my $av_cat = $builder->build_object({ class => 'Koha::AuthorisedValueCategories' }); >+ >+ # Attempt partial update on a PUT >+ my $av_with_missing_field = { >+ category => $av_cat->category_name, >+ value => "a value", >+ }; >+ >+ $t->put_ok( "//$userid:$password@/api/v1/authorised_values/$av_id" => json => $av_with_missing_field ) >+ ->status_is(400) >+ ->json_is( "/errors" => >+ [ { message => "Missing property.", path => "/body/description" } ] >+ ); >+ >+ # Full object update on PUT >+ my $av_with_updated_field = { >+ category => $av_cat->category_name, >+ value => "a value", >+ description => "a lib", >+ }; >+ >+ $t->put_ok( "//$userid:$password@/api/v1/authorised_values/$av_id" => json => $av_with_updated_field ) >+ ->status_is(200) >+ ->json_is( '/description' => 'a lib' ); >+ >+ # Authorized attempt to write invalid data >+ my $av_with_invalid_field = { >+ blah => "Av Blah", >+ category => $av_cat->category_name, >+ value => "a value", >+ description => "a lib", >+ opac_description => "opac lib" >+ }; >+ >+ $t->put_ok( "//$userid:$password@/api/v1/authorised_values/$av_id" => json => $av_with_invalid_field ) >+ ->status_is(400) >+ ->json_is( >+ "/errors" => [ >+ { >+ message => "Properties not allowed: blah.", >+ path => "/body" >+ } >+ ] >+ ); >+ >+ my $av_to_delete = $builder->build_object({ class => 'Koha::AuthorisedValues' }); >+ my $non_existent_id = $av_to_delete->id; >+ $av_to_delete->delete; >+ >+ $t->put_ok( "//$userid:$password@/api/v1/authorised_values/$non_existent_id" => json => $av_with_updated_field ) >+ ->status_is(404); >+ >+ # Wrong method (POST) >+ $av_with_updated_field->{authorised_value_id} = 2; >+ >+ $t->post_ok( "//$userid:$password@/api/v1/authorised_values/$av_id" => json => $av_with_updated_field ) >+ ->status_is(404); >+ >+ $schema->storage->txn_rollback; >+}; >+ >+subtest 'delete() tests' => sub { >+ >+ plan tests => 7; >+ >+ $schema->storage->txn_begin; >+ >+ my $librarian = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 2**3 } # parameters flag = 2 >+ } >+ ); >+ my $password = 'thePassword123'; >+ $librarian->set_password( { password => $password, skip_validation => 1 } ); >+ my $userid = $librarian->userid; >+ >+ my $patron = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 0 } >+ } >+ ); >+ >+ $patron->set_password( { password => $password, skip_validation => 1 } ); >+ my $unauth_userid = $patron->userid; >+ >+ my $av_id = $builder->build_object({ class => 'Koha::AuthorisedValues' })->id; >+ >+ # Unauthorized attempt to delete >+ $t->delete_ok( "//$unauth_userid:$password@/api/v1/authorised_values/$av_id" ) >+ ->status_is(403); >+ >+ $t->delete_ok("//$userid:$password@/api/v1/authorised_values/$av_id") >+ ->status_is(204, 'SWAGGER3.2.4') >+ ->content_is('', 'SWAGGER3.3.4'); >+ >+ $t->delete_ok("//$userid:$password@/api/v1/authorised_values/$av_id") >+ ->status_is(404); >+ >+ $schema->storage->txn_rollback; >+}; >-- >2.43.0
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 17390
:
55979
|
55980
|
92036
|
92037
|
105820
|
105849
| 162138