Bugzilla – Attachment 42645 Details for
Bug 14843
Notifications and messages via REST API
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 14843: Notifications and messages via REST API
Bug-14843-Notifications-and-messages-via-REST-API.patch (text/plain), 36.75 KB, created by
Lari Taskula
on 2015-09-17 10:40:05 UTC
(
hide
)
Description:
Bug 14843: Notifications and messages via REST API
Filename:
MIME Type:
Creator:
Lari Taskula
Created:
2015-09-17 10:40:05 UTC
Size:
36.75 KB
patch
obsolete
>From 23ceac22d498cd563040e824a9b7372f744270c9 Mon Sep 17 00:00:00 2001 >From: Lari Taskula <larit@student.uef.fi> >Date: Mon, 7 Sep 2015 15:18:06 +0300 >Subject: [PATCH] Bug 14843: Notifications and messages via REST API > >This patch adds notifications/messages to REST API. The purpose is to >let user with permissions get/create/update/delete/resend messages in message_queue. > >For the operations we have to introduce new functionalities to C4::Letters. >Currently it is not possible to delete/update notifications or get message >by id. With this patch we are able to do these operations. > >Two new subroutines are: >C4::Letters::DequeueLetter and >C4::Letters::UpdateQueuedMessage > >There are specific permissions for each operation. Under pemission module >'messages', the following permissions can be found: > - get_message > - create_message > - update_message (also allows resend via status change) > - delete_message > - resend_message > >Endpoints that this patch adds are: >GET /api/v1/messages (GETs all messages) >POST /api/v1/messages (creates new message) >GET /api/v1/messages/{messagenumber} (GETs specific message) >PUT /api/v1/messages/{messagenumber} (modifies specific message) >DELETE /api/v1/messages/{messagenumber} (deletes specific message) >POST /api/v1/messages/{messagenumber}/resend (makes new resend for a message) > >See Swagger definitions for more precise descriptions. > >Includes REST tests and unit tests for new subroutines in C4::Letters. >--- > C4/Letters.pm | 118 ++++++++- > Koha/REST/V1/Messages.pm | 262 ++++++++++++++++++++ > api/v1/swagger.json | 262 ++++++++++++++++++++ > ...ermissions_for_message_queue_REST_operations.pl | 38 +++ > t/db_dependent/Api/V1/Messages.pm | 272 +++++++++++++++++++++ > t/db_dependent/Letters.t | 15 +- > 6 files changed, 965 insertions(+), 2 deletions(-) > create mode 100644 Koha/REST/V1/Messages.pm > create mode 100644 installer/data/mysql/atomicupdate/Bug14767-Add_Permissions_for_message_queue_REST_operations.pl > create mode 100644 t/db_dependent/Api/V1/Messages.pm > >diff --git a/C4/Letters.pm b/C4/Letters.pm >index 518830c..01a4282 100644 >--- a/C4/Letters.pm >+++ b/C4/Letters.pm >@@ -935,6 +935,34 @@ ENDSQL > return $dbh->last_insert_id(undef,undef,'message_queue', undef); > } > >+=head2 DequeueLetter >+ >+ my $success = DequeueLetter( { message_id => $message_id } ) >+ >+Removes a message from message_queue >+ >+return 1 on success, otherwise 0 >+ >+=cut >+ >+sub DequeueLetter { >+ my $params = shift or return; >+ >+ return unless exists $params->{'message_id'} or not $params->{'message_id'}; >+ >+ my $dbh = C4::Context->dbh(); >+ my $statement = << 'ENDSQL'; >+DELETE FROM message_queue >+WHERE message_id = ? >+ENDSQL >+ >+ my $sth = $dbh->prepare($statement); >+ my $result = $sth->execute( >+ $params->{'message_id'}, # message_id >+ ); >+ return ($result > 0); >+} >+ > =head2 SendQueuedMessages ([$hashref]) > > my $sent = SendQueuedMessages( { verbose => 1 } ); >@@ -1026,7 +1054,7 @@ sub GetQueuedMessages { > > my $dbh = C4::Context->dbh(); > my $statement = << 'ENDSQL'; >-SELECT message_id, borrowernumber, subject, content, message_transport_type, status, time_queued, delivery_note >+SELECT message_id, borrowernumber, subject, content, metadata, letter_code, message_transport_type, status, time_queued, to_address, from_address, content_type, delivery_note > FROM message_queue > ENDSQL > >@@ -1051,6 +1079,94 @@ ENDSQL > return $sth->fetchall_arrayref({}); > } > >+ >+=head2 UpdateQueuedMessage ([$hashref]) >+ >+ my $message = UpdateQueuedMessage( { >+ borrowernumber => '123', message_id => '100', >+ letter => { subject => "New subject", content => "New content" }, >+ } ); >+ >+Updates the message in message_queue. Message is identified by >+required parameter message_id. >+ >+returns: >+1 on success, otherwise 0 >+ >+=cut >+ >+sub UpdateQueuedMessage { >+ my $params = shift; >+ >+ if (not $params->{'message_id'}) { >+ warn __PACKAGE__."::UpdateQueuedMessage: param message_id is required"; >+ return; >+ } >+ >+ my $dbh = C4::Context->dbh(); >+ my $statement = << 'ENDSQL'; >+UPDATE message_queue >+SET >+ENDSQL >+ >+ my @query_params; >+ >+ if ($params->{'borrowernumber'}) { >+ $statement .= " borrowernumber = ?, "; >+ push @query_params, $params->{'borrowernumber'}; >+ } >+ if ($params->{'subject'}) { >+ $statement .= " subject = ?, "; >+ push @query_params, $params->{'subject'}; >+ } >+ if ($params->{'content'}) { >+ $statement .= " content = ?, "; >+ push @query_params, $params->{'content'}; >+ } >+ if ($params->{'metadata'}) { >+ $statement .= " metadata = ?, "; >+ push @query_params, $params->{'metadata'}; >+ } >+ if ($params->{'letter_code'}) { >+ $statement .= " letter_code = ?, "; >+ push @query_params, $params->{'letter_code'}; >+ } >+ if ($params->{'content_type'}) { >+ $statement .= " content_type = ?, "; >+ push @query_params, $params->{'content_type'}; >+ } >+ if ($params->{'message_transport_type'}) { >+ $statement .= " message_transport_type = ?, "; >+ push @query_params, $params->{'message_transport_type'}; >+ } >+ if ($params->{'status'}) { >+ $statement .= " status = ?, "; >+ push @query_params, $params->{'status'}; >+ } >+ if ($params->{'to_address'}) { >+ $statement .= " to_address = ?, "; >+ push @query_params, $params->{'to_address'}; >+ } >+ if ($params->{'from_address'}) { >+ $statement .= " from_address = ?, "; >+ push @query_params, $params->{'from_address'}; >+ } >+ if ($params->{'delivery_note'}) { >+ $statement .= " delivery_note = ?, "; >+ push @query_params, $params->{'delivery_note'}; >+ } >+ return 0 if $statement =~ /SET(\s*)$/; >+ $statement =~ s/,(\s*)$//g; # remove last , >+ >+ $statement .= " WHERE message_id = ?"; >+ push @query_params, $params->{'message_id'}; >+ >+ my $sth = $dbh->prepare( $statement ); >+ my $result = $sth->execute( @query_params ); >+ return ($result > 0); >+} >+ >+ > =head2 GetMessageTransportTypes > > my @mtt = GetMessageTransportTypes(); >diff --git a/Koha/REST/V1/Messages.pm b/Koha/REST/V1/Messages.pm >new file mode 100644 >index 0000000..79aad2d >--- /dev/null >+++ b/Koha/REST/V1/Messages.pm >@@ -0,0 +1,262 @@ >+package Koha::REST::V1::Messages; >+ >+use Modern::Perl; >+ >+use Mojo::Base 'Mojolicious::Controller'; >+ >+use C4::Letters; >+use Data::Dumper; >+ >+ >+ >+=head2 list_messages($c, $args, $cb) >+ >+Lists all messages from message_queue. >+ >+=cut >+sub list_messages { >+ my ($c, $args, $cb) = @_; >+ >+ my $messages = C4::Letters::GetQueuedMessages(); >+ >+ if (@$messages > 0) { >+ my $return_messages; >+ foreach my $message (@$messages){ >+ push @$return_messages, _set_default_values({ message => $message }); >+ } >+ return $c->$cb($return_messages , 200); >+ } >+ $c->$cb({ error => "No messages found." }, 404); >+} >+ >+ >+ >+=head2 create_message($c, $args, $cb) >+ >+Creates a new message into message queue. >+ >+=cut >+sub create_message { >+ my ($c, $args, $cb) = @_; >+ >+ # Content is required. Check for missing content. >+ if (exists $args->{body}->{content}) { >+ my $content = $args->{body}->{content}; >+ $content =~ s/\s+//g if(defined $content); >+ if ( not $content ) { >+ return $c->$cb({ error => "Property cannot be empty in: /body/content" }, 400); >+ } >+ } else { >+ return $c->$cb({ error => "Missing property: /body/content" }, 400); >+ } >+ >+ if (exists $args->{body}->{borrowernumber}) { >+ my $content = $args->{body}->{borrowernumber}; >+ $content =~ s/\s+//g if(defined $content); >+ if ( not $content ) { >+ return $c->$cb({ error => "Property cannot be empty in: /body/borrowernumber" }, 400); >+ } >+ } else { >+ return $c->$cb({ error => "Missing property: /body/borrowernumber" }, 400); >+ } >+ >+ >+ # message_transport_type is required. Check for missing parameter. >+ my $transport_type = $args->{body}->{message_transport_type}; >+ $transport_type =~ s/\s+//g if(defined $transport_type); >+ if ( not $transport_type ) { >+ return $c->$cb({ error => "Missing property: /body/message_transport_type" }, 400); >+ } >+ >+ # message_transport_type also must be one of the predefined values >+ my $transport_types = C4::Letters::GetMessageTransportTypes(); >+ if ( !grep( /^$transport_type$/, @$transport_types ) ) { >+ return $c->$cb({ error => "Invalid value '".$transport_type."' in: /body/message_transport_type. Valid values are ". join(', ', @$transport_types) }, 400); >+ } >+ >+ # Make some changes in names of parameters due to inconsistent naming in C4::Letters >+ >+ # Enqueue the letter >+ my $message = C4::Letters::EnqueueLetter(_convert_to_enqueue({ message => $args->{'body'} })); >+ >+ # Check if the message was enqueued >+ if ($message){ >+ # Get the newly created message and return it >+ $message = C4::Letters::GetMessage( $message ); >+ >+ $message = _set_default_values({ message => $message }); >+ >+ return $c->$cb($message, 201); >+ } >+ $c->$cb({ error => "Message could not be created." }, 404) >+} >+ >+ >+ >+=head2 update_message($c, $args, $cb) >+ >+Updates the message in message_queue. >+ >+=cut >+sub update_message { >+ my ($c, $args, $cb) = @_; >+ >+ # Content is required. Check for missing content. >+ if (exists $args->{body}->{content}) { >+ my $content = $args->{body}->{content}; >+ $content =~ s/\s+//g if(defined $content); >+ if ( $content eq '' ) { >+ return $c->$cb({ error => "Property cannot be empty in: /body/content" }, 400); >+ } >+ } >+ >+ if (exists $args->{body}->{message_transport_type}) { >+ my $transport_type = $args->{body}->{message_transport_type}; >+ # message_transport_type also must be one of the predefined values >+ my $transport_types = C4::Letters::GetMessageTransportTypes(); >+ if ( !grep( /^$transport_type$/, @$transport_types ) ) { >+ return $c->$cb({ error => "Invalid value '".$transport_type >+ ."' in: /body/message_transport_type. Valid values are " >+ . join(', ', @$transport_types) }, 400); >+ } >+ } >+ >+ # create update hash >+ my $update = $args->{'body'}; >+ $update->{'message_id'} = $args->{'messagenumber'}; >+ >+ my $message = C4::Letters::UpdateQueuedMessage( $update ); >+ return $c->$cb({ error => "Message could not be found." }, 404) if not $message; >+ >+ $message = C4::Letters::GetMessage($args->{'messagenumber'}); >+ >+ if ($message){ >+ $message = _set_default_values({ message => $message }); >+ return $c->$cb($message, 200); >+ } >+ $c->$cb({ error => "Message could not be updated." }, 404); >+} >+ >+ >+ >+=head2 delete_message($c, $args, $cb) >+ >+Delete the message from message_queue. >+ >+=cut >+sub delete_message { >+ my ($c, $args, $cb) = @_; >+ >+ my $message = C4::Letters::DequeueLetter({ message_id => $args->{'messagenumber'} }); >+ >+ if ($message){ >+ return $c->$cb('', 204); >+ } >+ >+ $c->$cb({ error => "Message could not be found." }, 404) >+} >+ >+ >+ >+=head2 get_message($c, $args, $cb) >+ >+Returns a message from message_queue. >+ >+=cut >+sub get_message { >+ my ($c, $args, $cb) = @_; >+ >+ my $message = C4::Letters::GetMessage($args->{'messagenumber'}); >+ >+ if ($message) { >+ my $message = _set_default_values({ message => $message }); >+ >+ return $c->$cb($message, 200); >+ } >+ >+ return $c->$cb({ error => "Could not find the message" }, 404); >+} >+ >+ >+ >+=head2 create_resend($c, $args, $cb) >+ >+Attempts to resend a message. >+ >+=cut >+sub create_resend { >+ my ($c, $args, $cb) = @_; >+ >+ >+ my $message = C4::Letters::GetMessage($args->{'messagenumber'}); >+ >+ if ($message) { >+ if (C4::Letters::ResendMessage($args->{'messagenumber'})) { >+ >+ return $c->$cb('', 204); >+ } >+ } >+ >+ return $c->$cb({ error => "Could not find the message" }, 404); >+} >+ >+ >+ >+=head2 _set_default_values({ message => $message }) >+ >+=cut >+sub _set_default_values { >+ my $params = shift; >+ >+ return unless exists $params->{'message'} or not defined $params->{'message'}; >+ >+ # Convert the returned message into C4::Letters::EnqueueLetter format >+ return { >+ message_id => int($params->{'message'}->{'message_id'}), >+ borrowernumber => int($params->{'message'}->{'borrowernumber'}), >+ subject => $params->{'message'}->{'subject'} || '', >+ content => $params->{'message'}->{'content'} || '', >+ letter_code => $params->{'message'}->{'letter_code'} || '', >+ content_type => $params->{'message'}->{'content_type'} || '', >+ metadata => $params->{'message'}->{'metadata'} || '', >+ message_transport_type => $params->{'message'}->{'message_transport_type'} || '', >+ to_address => $params->{'message'}->{'to_address'} || '', >+ from_address => $params->{'message'}->{'from_address'} || '', >+ delivery_note => $params->{'message'}->{'delivery_note'} || '', >+ status => $params->{'message'}->{'status'} || '', >+ time_queued => $params->{'message'}->{'time_queued'} || '' >+ }; >+} >+ >+ >+ >+=head2 _convert_to_message({ message => $message }) >+ >+Due to inconsistent naming in C4::Letters::EnqueueLetter, we use the >+database format and convert it in this function into the format that >+EnqueueLetter supports. >+ >+=cut >+sub _convert_to_enqueue { >+ my $params = shift; >+ >+ return unless exists $params->{'message'} or not defined $params->{'message'}; >+ >+ # Convert the returned message into C4::Letters::EnqueueLetter format >+ return { >+ borrowernumber => int($params->{'message'}->{'borrowernumber'}), >+ letter => { >+ title => $params->{'message'}->{'subject'} || '', >+ content => $params->{'message'}->{'content'} || '', >+ code => $params->{'message'}->{'letter_code'} || '', >+ 'content-type' => $params->{'message'}->{'content_type'} || '', >+ metadata => $params->{'message'}->{'metadata'} || '', >+ }, >+ message_transport_type => $params->{'message'}->{'message_transport_type'} || '', >+ to_address => $params->{'message'}->{'to_address'} || '', >+ from_address => $params->{'message'}->{'from_address'} || '', >+ delivery_note => $params->{'message'}->{'delivery_note'} || '' >+ }; >+} >+ >+1; >diff --git a/api/v1/swagger.json b/api/v1/swagger.json >index 2477452..5d37123 100644 >--- a/api/v1/swagger.json >+++ b/api/v1/swagger.json >@@ -309,6 +309,204 @@ > } > } > } >+ }, >+ "/messages": { >+ "get": { >+ "x-mojo-controller": "Koha::REST::V1::Messages", >+ "operationId": "listMessages", >+ "x-koha-permission": { >+ "messages": "get_message" >+ }, >+ "tags": ["messages"], >+ "produces": [ >+ "application/json" >+ ], >+ "responses": { >+ "200": { >+ "description": "A list of messages", >+ "schema": { >+ "type": "array", >+ "items": { >+ "$ref" : "#/definitions/message" >+ } >+ } >+ }, >+ "404": { >+ "description": "Messages not found", >+ "schema": { >+ "$ref": "#/definitions/error" >+ } >+ } >+ } >+ }, >+ "post": { >+ "x-mojo-controller": "Koha::REST::V1::Messages", >+ "operationId": "createMessage", >+ "x-koha-permission": { >+ "messages": "create_message" >+ }, >+ "tags": ["messages"], >+ "parameters": [ >+ { >+ "name": "body", >+ "in": "body", >+ "description": "A JSON object containing informations about the new message", >+ "required": true, >+ "schema": { "$ref": "#/definitions/message" } >+ } >+ ], >+ "produces": [ >+ "application/json" >+ ], >+ "responses": { >+ "201": { >+ "description": "A message", >+ "schema": { >+ "$ref": "#/definitions/message" >+ } >+ }, >+ "400": { >+ "description": "Missing or wrong parameters", >+ "schema": { "$ref": "#/definitions/error" } >+ } >+ } >+ } >+ }, >+ "/messages/{messagenumber}": { >+ "put": { >+ "x-mojo-controller": "Koha::REST::V1::Messages", >+ "operationId": "updateMessage", >+ "x-koha-permission": { >+ "messages": "update_message" >+ }, >+ "tags": ["messages"], >+ "parameters": [ >+ { >+ "name": "body", >+ "in": "body", >+ "description": "A JSON object containing informations about the new message", >+ "required": false, >+ "schema": { "$ref": "#/definitions/message" } >+ }, >+ { >+ "$ref": "#/parameters/messagenumberPathParam" >+ } >+ ], >+ "produces": [ >+ "application/json" >+ ], >+ "responses": { >+ "200": { >+ "description": "A message", >+ "schema": { >+ "$ref" : "#/definitions/message" >+ } >+ }, >+ "400": { >+ "description": "Missing or wrong parameters", >+ "schema": { "$ref": "#/definitions/error" } >+ }, >+ "404": { >+ "description": "Message not found", >+ "schema": { >+ "$ref": "#/definitions/error" >+ } >+ } >+ } >+ }, >+ "delete": { >+ "x-mojo-controller": "Koha::REST::V1::Messages", >+ "operationId": "deleteMessage", >+ "x-koha-permission": { >+ "messages": "delete_message" >+ }, >+ "tags": ["messages"], >+ "parameters": [ >+ { >+ "$ref": "#/parameters/messagenumberPathParam" >+ } >+ ], >+ "produces": [ >+ "application/json" >+ ], >+ "responses": { >+ "204": { >+ "description": "Deleting the message succeeded.", >+ "schema": { >+ "type": "string" >+ } >+ }, >+ "404": { >+ "description": "Message not found.", >+ "schema": { >+ "$ref": "#/definitions/error" >+ } >+ } >+ } >+ }, >+ "get": { >+ "x-mojo-controller": "Koha::REST::V1::Messages", >+ "operationId": "getMessage", >+ "x-koha-permission": { >+ "messages": "get_message" >+ }, >+ "tags": ["messages"], >+ "parameters": [ >+ { >+ "$ref": "#/parameters/messagenumberPathParam" >+ } >+ ], >+ "produces": [ >+ "application/json" >+ ], >+ "responses": { >+ "200": { >+ "description": "A message", >+ "schema": { >+ "$ref" : "#/definitions/message" >+ } >+ }, >+ "404": { >+ "description": "Message not found", >+ "schema": { >+ "$ref": "#/definitions/error" >+ } >+ } >+ } >+ } >+ }, >+ "/messages/{messagenumber}/resend": { >+ "post": { >+ "x-mojo-controller": "Koha::REST::V1::Messages", >+ "operationId": "createResend", >+ "description": "Resends a message.", >+ "x-koha-permission": { >+ "messages": "resend_message" >+ }, >+ "tags": ["messages"], >+ "parameters": [ >+ { >+ "$ref": "#/parameters/messagenumberPathParam" >+ } >+ ], >+ "produces": [ >+ "application/json" >+ ], >+ "responses": { >+ "204": { >+ "description": "Resending the message succeeded.", >+ "schema": { >+ "type": "string" >+ } >+ }, >+ "404": { >+ "description": "Message not found", >+ "schema": { >+ "$ref": "#/definitions/error" >+ } >+ } >+ } >+ } > } > }, > "definitions": { >@@ -485,12 +683,69 @@ > "borrowernumber": { > "description": "Borrower internal identifier" > }, >+ > "branchcode": { > "description": "Branch code" > }, > "itemnumber": { > "description": "Item internal identifier" > }, >+ "message": { >+ "type": "object", >+ "properties": { >+ "message_id": { >+ "description": "Message internal identifier", >+ "type": "integer" >+ }, >+ "time_queued": { >+ "description": "Date and time of when message was placed in queue", >+ "type": "string" >+ }, >+ "borrowernumber": { >+ "$ref": "#/definitions/borrowernumber" >+ }, >+ "subject": { >+ "description": "Subject of the message", >+ "type": "string" >+ }, >+ "content": { >+ "description": "Content of the message", >+ "type": "string" >+ }, >+ "metadata": { >+ "description": "", >+ "type": "string" >+ }, >+ "letter_code": { >+ "description": "", >+ "type": "string" >+ }, >+ "content_type": { >+ "description": "Content type", >+ "type": "string" >+ }, >+ "message_transport_type": { >+ "description": "Transport method. Values accepted by default are 'email', 'sms', 'phone' and 'print'", >+ "type": "string" >+ }, >+ "status": { >+ "description": "Delivery status", >+ "type": "string" >+ }, >+ "to_address": { >+ "description": "Destination email address", >+ "type": "string" >+ }, >+ "from_address": { >+ "description": "Source address of email", >+ "type": "string" >+ }, >+ "delivery_note": { >+ "description": "Additional delivery notes", >+ "type": "string" >+ } >+ } >+ }, > "error": { > "type": "object", > "properties": { >@@ -529,6 +784,13 @@ > "description": "Internal item identifier", > "required": "true", > "type": "integer" >+ }, >+ "messagenumberPathParam": { >+ "name": "messagenumber", >+ "in": "path", >+ "description": "Internal message identifier", >+ "required": "true", >+ "type": "integer" > } > }, > "securityDefinitions": { >diff --git a/installer/data/mysql/atomicupdate/Bug14767-Add_Permissions_for_message_queue_REST_operations.pl b/installer/data/mysql/atomicupdate/Bug14767-Add_Permissions_for_message_queue_REST_operations.pl >new file mode 100644 >index 0000000..a91db80 >--- /dev/null >+++ b/installer/data/mysql/atomicupdate/Bug14767-Add_Permissions_for_message_queue_REST_operations.pl >@@ -0,0 +1,38 @@ >+#!/usr/bin/perl >+ >+# Copyright Open Source Freedom Fighters >+# >+# This file is part of Koha. >+# >+# Koha is free software; you can redistribute it and/or modify it under the >+# terms of the GNU General Public License as published by the Free Software >+# Foundation; either version 3 of the License, or (at your option) any later >+# version. >+# >+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >+# A PARTICULAR PURPOSE. See the GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License along >+# with Koha; if not, write to the Free Software Foundation, Inc., >+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >+ >+use C4::Context; >+use Koha::AtomicUpdater; >+ >+my $dbh = C4::Context->dbh(); >+my $atomicUpdater = Koha::AtomicUpdater->new(); >+ >+unless($atomicUpdater->find('Bug14767-Add_Permissions_for_message_queue_REST_operations.pl')) { >+ >+ use Koha::Auth::PermissionManager; >+ my $pm = Koha::Auth::PermissionManager->new(); >+ $pm->addPermissionModule({module => 'messages', description => 'Permission regarding notifications and messages in message queue.'}); >+ $pm->addPermission({module => 'messages', code => 'get_message', description => "Allows to get the messages in message queue."}); >+ $pm->addPermission({module => 'messages', code => 'create_message', description => "Allows to create a new message and queue it."}); >+ $pm->addPermission({module => 'messages', code => 'update_message', description => "Allows to update messages in message queue."}); >+ $pm->addPermission({module => 'messages', code => 'delete_message', description => "Allows to delete a message and queue it."}); >+ $pm->addPermission({module => 'messages', code => 'resend_message', description => "Allows to resend messages in message queue."}); >+ >+ print "Upgrade done (Bug 14767: Add Pemissions for message queue REST operations)\n"; >+} >diff --git a/t/db_dependent/Api/V1/Messages.pm b/t/db_dependent/Api/V1/Messages.pm >new file mode 100644 >index 0000000..359335c >--- /dev/null >+++ b/t/db_dependent/Api/V1/Messages.pm >@@ -0,0 +1,272 @@ >+package t::db_dependent::Api::V1::Messages; >+ >+use Modern::Perl; >+use Test::More; >+ >+use t::lib::TestObjects::ObjectFactory; >+use t::lib::TestObjects::MessageQueueFactory; >+ >+use C4::Letters; >+ >+sub get200 { >+ my ($class, $restTest, $driver) = @_; >+ my $testContext = $restTest->get_testContext(); >+ my $activeUser = $restTest->get_activeBorrower(); >+ my $path = $restTest->get_routePath(); >+ >+ #Create the test context. >+ my $messages = t::lib::TestObjects::MessageQueueFactory->createTestGroup( >+ { >+ subject => "The quick brown fox", >+ content => "Jumps over the lazy dog.", >+ cardnumber => $activeUser->{'_result'}->{'_column_data'}->{cardnumber}, >+ message_transport_type => 'sms', >+ from_address => '11A001@example.com', >+ }, undef, $testContext, undef, undef); >+ >+ my $messagenumber = $messages->{'11A001@example.com'}->{message_id}; >+ >+ $driver->get_ok($path => {Accept => 'text/json'}); >+ $driver->status_is(200); >+ >+ $driver->json_has("message_id", "Message id in JSON."); >+ >+ t::lib::TestObjects::ObjectFactory->tearDownTestContext($testContext); >+ return 1; >+} >+ >+sub get404 { >+ my ($class, $restTest, $driver) = @_; >+ my $path = $restTest->get_routePath(); >+ my $testContext = $restTest->get_testContext(); >+ >+ # clear test context before checking for 404 >+ t::lib::TestObjects::ObjectFactory->tearDownTestContext($testContext); >+ >+ $driver->get_ok($path => {Accept => 'text/json'}); >+ $driver->status_is(404); >+ >+ return 1; >+} >+ >+sub get_n_200 { >+ my ($class, $restTest, $driver) = @_; >+ my $testContext = $restTest->get_testContext(); >+ my $activeUser = $restTest->get_activeBorrower(); >+ my $path = $restTest->get_routePath(); >+ >+ #Create the test context. >+ my $messages = t::lib::TestObjects::MessageQueueFactory->createTestGroup( >+ { >+ subject => "The quick brown fox", >+ content => "Jumps over the lazy dog.", >+ cardnumber => $activeUser->{'_result'}->{'_column_data'}->{cardnumber}, >+ message_transport_type => 'sms', >+ from_address => '11A002@example.com', >+ }, undef, $testContext, undef, undef); >+ >+ my $messagenumber = $messages->{'11A002@example.com'}->{message_id}; >+ $path =~ s/\{messagenumber\}/$messagenumber/; >+ >+ $driver->get_ok($path => {Accept => 'text/json'}); >+ $driver->status_is(200); >+ >+ $driver->json_is('/message_id' => $messagenumber, "Message $messagenumber found!"); >+ >+ t::lib::TestObjects::ObjectFactory->tearDownTestContext($testContext); >+ return 1; >+} >+ >+sub get_n_404 { >+ my ($class, $restTest, $driver) = @_; >+ my $path = $restTest->get_routePath(); >+ >+ $path =~ s/\{messagenumber\}/12349329003007/; >+ $driver->get_ok($path => {Accept => 'text/json'}); >+ $driver->status_is(404); >+ >+ return 1; >+} >+ >+sub post201 { >+ my ($class, $restTest, $driver) = @_; >+ my $path = $restTest->get_routePath(); >+ my $activeUser = $restTest->get_activeBorrower(); >+ >+ $driver->post_ok($path => {Accept => 'text/json'} => json => { >+ subject => "hello", >+ content => "world", >+ message_transport_type => "email", >+ borrowernumber => $activeUser->{'_result'}->{'_column_data'}->{borrowernumber}, >+ }); >+ $driver->status_is(201); >+ >+ # dequeue the message right after so that get 404 tests will work >+ my $json = $driver->tx->res->json(); >+ C4::Letters::DequeueLetter({ message_id => $json->{message_id} }); >+ >+ return 1; >+} >+ >+sub post400 { >+ my ($class, $restTest, $driver) = @_; >+ my $path = $restTest->get_routePath(); >+ my $activeUser = $restTest->get_activeBorrower(); >+ >+ #post with missing mandatory parameters >+ $driver->post_ok($path => {Accept => 'text/json'} => json => { >+ subject => "hello" >+ }); >+ $driver->status_is(400); >+ >+ return 1; >+} >+ >+sub post_n_resend204 { >+ my ($class, $restTest, $driver) = @_; >+ my $testContext = $restTest->get_testContext(); >+ my $activeUser = $restTest->get_activeBorrower(); >+ my $path = $restTest->get_routePath(); >+ >+ #Create the test context. >+ my $messages = t::lib::TestObjects::MessageQueueFactory->createTestGroup( >+ { >+ subject => "The quick brown fox", >+ content => "Jumps over the lazy dog.", >+ cardnumber => $activeUser->{'_result'}->{'_column_data'}->{cardnumber}, >+ message_transport_type => 'sms', >+ from_address => '11A003@example.com', >+ }, undef, $testContext, undef, undef); >+ >+ # send and get the message >+ C4::Letters::SendQueuedMessages(); >+ my $message = C4::Letters::GetMessage($messages->{'11A003@example.com'}->{message_id}); >+ my $messagenumber = $messages->{'11A003@example.com'}->{message_id}; >+ $path =~ s/\{messagenumber\}/$messagenumber/; >+ >+ # sms status should be failed >+ is($message->{status}, "failed", "Send failed correctly"); >+ >+ $driver->post_ok($path => {Accept => 'text/json'}); >+ $driver->status_is(204); >+ >+ $message = C4::Letters::GetMessage($messages->{'11A003@example.com'}->{message_id}); >+ is($message->{status}, "pending", "Resend set message status to pending correctly"); >+ >+ t::lib::TestObjects::ObjectFactory->tearDownTestContext($testContext); >+ >+ return 1; >+} >+ >+sub post_n_resend404 { >+ my ($class, $restTest, $driver) = @_; >+ my $path = $restTest->get_routePath(); >+ >+ $path =~ s/\{messagenumber\}/12349329003007/; >+ $driver->post_ok($path => {Accept => 'text/json'}); >+ $driver->status_is(404); >+ >+ return 1; >+} >+ >+sub put_n_200 { >+ my ($class, $restTest, $driver) = @_; >+ my $testContext = $restTest->get_testContext(); >+ my $activeUser = $restTest->get_activeBorrower(); >+ my $path = $restTest->get_routePath(); >+ >+ #Create the test context. >+ my $messages = t::lib::TestObjects::MessageQueueFactory->createTestGroup( >+ { >+ subject => "The quick brown fox", >+ content => "Jumps over the lazy dog.", >+ cardnumber => $activeUser->{'_result'}->{'_column_data'}->{cardnumber}, >+ message_transport_type => 'sms', >+ from_address => '11A003@example.com', >+ }, undef, $testContext, undef, undef); >+ >+ my $messagenumber = $messages->{'11A003@example.com'}->{message_id}; >+ $path =~ s/\{messagenumber\}/$messagenumber/; >+ >+ $driver->put_ok($path => {Accept => 'text/json'} => json => { >+ subject => "hello", >+ content => "world", >+ }); >+ $driver->status_is(200); >+ >+ my $json = $driver->tx->res->json(); >+ is($json->{subject}, "hello", "Put updated message subject correctly"); >+ >+ t::lib::TestObjects::ObjectFactory->tearDownTestContext($testContext); >+ >+ return 1; >+} >+ >+sub put_n_400 { >+ my ($class, $restTest, $driver) = @_; >+ my $testContext = $restTest->get_testContext(); >+ my $activeUser = $restTest->get_activeBorrower(); >+ my $path = $restTest->get_routePath(); >+ >+ $path =~ s/\{messagenumber\}/12349329003007/; >+ $driver->put_ok($path => {Accept => 'text/json'} => json => { >+ message_transport_type => "hello", #invalid transport type >+ }); >+ $driver->status_is(400); >+ >+ return 1; >+} >+ >+sub put_n_404 { >+ my ($class, $restTest, $driver) = @_; >+ my $path = $restTest->get_routePath(); >+ >+ $path =~ s/\{messagenumber\}/12349329003007/; >+ $driver->put_ok($path => {Accept => 'text/json'}); >+ $driver->status_is(404); >+ >+ return 1; >+} >+ >+sub delete_n_204 { >+ my ($class, $restTest, $driver) = @_; >+ my $testContext = $restTest->get_testContext(); >+ my $activeUser = $restTest->get_activeBorrower(); >+ my $path = $restTest->get_routePath(); >+ >+ #Create the test context. >+ my $messages = t::lib::TestObjects::MessageQueueFactory->createTestGroup( >+ { >+ subject => "The quick brown fox", >+ content => "Jumps over the lazy dog.", >+ cardnumber => $activeUser->{'_result'}->{'_column_data'}->{cardnumber}, >+ message_transport_type => 'sms', >+ from_address => '11A004@example.com', >+ }, undef, $testContext, undef, undef); >+ >+ my $messagenumber = $messages->{'11A004@example.com'}->{message_id}; >+ $path =~ s/\{messagenumber\}/$messagenumber/; >+ >+ $driver->delete_ok($path => {Accept => 'text/json'}); >+ $driver->status_is(204); >+ >+ # if DELETE was successfull, delete it from testContext too. >+ if ($driver->{tx}->{res}->{code} == 204) { >+ delete $restTest->{testContext}->{messagequeue}->{'11A004@example.com'}; >+ } >+ >+ return 1; >+} >+ >+sub delete_n_404 { >+ my ($class, $restTest, $driver) = @_; >+ my $path = $restTest->get_routePath(); >+ >+ $path =~ s/\{messagenumber\}/12349329003007/; >+ $driver->delete_ok($path => {Accept => 'text/json'}); >+ $driver->status_is(404); >+ >+ return 1; >+} >+ >+1; >\ No newline at end of file >diff --git a/t/db_dependent/Letters.t b/t/db_dependent/Letters.t >index ad02c04..2f03a0f 100644 >--- a/t/db_dependent/Letters.t >+++ b/t/db_dependent/Letters.t >@@ -18,7 +18,7 @@ > # along with Koha; if not, see <http://www.gnu.org/licenses>. > > use Modern::Perl; >-use Test::More tests => 74; >+use Test::More tests => 79; > use Test::MockModule; > use Test::Warn; > >@@ -134,6 +134,9 @@ is( $messages->[0]->{message_transport_type}, $my_message->{message_transport_ty > is( $messages->[0]->{status}, 'pending', 'EnqueueLetter stores the status pending correctly' ); > is( $messages->[0]->{delivery_note}, '', 'Delivery note for successful message correctly empty'); > >+my $message_by_id = C4::Letters::GetQueuedMessages({ message_id => $messages->[0]->{message_id} }); >+is ($messages->[0]->{message_id}, $message_by_id->[0]->{message_id}, "GetQueuedMessages by message_id gets correct one"); >+ > # SendQueuedMessages > my $messages_processed = C4::Letters::SendQueuedMessages(); > is($messages_processed, 1, 'all queued messages processed'); >@@ -158,6 +161,11 @@ is( $resent, undef, 'ResendMessage should return undef if not message_id given' > # Delivery notes > is($messages->[0]->{delivery_note}, 'Missing SMS number', 'Delivery note for no smsalertnumber correctly set'); > >+# UpdateQueuedMessage >+is(C4::Letters::UpdateQueuedMessage({ message_id => $messages->[0]->{message_id}, content => "changed content" } ), 1, "Message updated correctly"); >+$messages = C4::Letters::GetQueuedMessages(); >+is($messages->[0]->{content}, "changed content", "Message content was changed correctly"); >+ > # Test connectivity Exception (Bug 14791) > ModMember(borrowernumber => $borrowernumber, smsalertnumber => "+1234567890"); > warning_is { $messages_processed = C4::Letters::SendQueuedMessages(); } >@@ -169,6 +177,11 @@ is( $messages->[0]->{status}, 'pending', > is( $messages->[0]->{delivery_note}, 'Connection failed. Attempting to resend.', > 'Message has correct delivery note about resending' ); > >+#DequeueLetter >+is(C4::Letters::DequeueLetter( { message_id => $messages->[0]->{message_id} } ), 1, "message successfully dequeued"); >+$messages = C4::Letters::GetQueuedMessages(); >+is( @$messages, 0, 'no messages left after dequeue' ); >+ > # GetLetters > my $letters = C4::Letters::GetLetters(); > is( @$letters, 0, 'GetLetters returns the correct number of letters' ); >-- >1.9.1
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 14843
:
42645
|
42693
|
42694
|
42719
|
62791