Mock requests no longer supported in 3.1.2-4

Hey,
in the Fidus Writer plugin, we allow users to do some action on the OJS site while they are really on the Fidus Writer site. For this to work with the various built-in OJS functions, we created a fake request as a mock object that contains all the functions and attributes that the request would normally have. See here: ojs-fiduswriter/FidusWriterGatewayPlugin.inc.php at 3088f24ced4d98e1cf27014d669d497b1552b45e · fiduswriter/ojs-fiduswriter · GitHub

That worked fine until fairly recently. But now I see that a user who is on OJS 3.1.2-4 sees an error message saying

PHP Fatal error:  Uncaught TypeError: Argument 1 passed to NotificationManagerDelegate::createNotification() must be an instance of PKPRequest, instance of MockObject given,

See Notification error · Issue #10 · fiduswriter/ojs-fiduswriter · GitHub

What is the preferred way to create such fake requests currently? Is there a way to write it so that it can work at least with all sub versions of OJS 3.1.2?

Hi @Johannes_Wilm,

The issue is that the stable-3_1_2 branch includes a type declaration in lib/pkp/classes/notification/PKPNotificationOperationManager.inc.php in the createNotification function:

public function createNotification(PKPRequest $request, $userId = null, $notificationType, $contextId = null, $assocType = null, $assocId = null, $level = NOTIFICATION_LEVEL_NORMAL, $params = null, $suppressEmail = false, callable $mailConfigurator = null)

That was introduced in https://github.com/pkp/pkp-lib/issues/4844 and while that was also ported to more recent branches it appears that the type declaration is not in more recent releases (e.g. stable-3_2_1).

However, I suspect this will be a problem in future releases too as we make more use of type declarations. You might need to actually instantiate a Request object rather than mocking it, or you might find some guidance here: symfony - How to unit test functions that use type hinting - Stack Overflow

Regards,
Alec Smecher
Public Knowledge Project Team

Hey @asmecher,
thanks for clarifying.

Hey again @asmecher,
I’m not exactly a PHP developer, but as far as I can tell, there is no simple way to get around the problem while the typechecking is enforced there. And unfortunately it seems that PHP cannot disable type checking if the type is specified.

The problem is that if I use an instance of PKPRequest, I need to override some of the methods, and that is apparently not possible. And the getMockBuilder method seems to only be something that is available within a unit test and not outside of it.

I can see a few different ways of fixing this:

  1. I believe you either have or wanted to implement a REST API. If that is there now, then I can possibly replace the OJS plugin entirely with this REST API.

  2. I could copy all the notification functions that use type specifications and remove just the type specification. That would result in a lot of code duplication, but it would likely work.

  3. Maybe the PKPRequest class could be modified so that it permits overriding methods on it. If there are other plugins that have a similar problem, then that might be a way around it.

  4. Maybe the type checking could just be left disabled for the notification methods to avoid this issue. Or it could be written in a way so that it doesn’t require the request object. My basic problem is that the end user does something in Fidus Writer and the Fidus Writer server then makes a request to the OJS server which should also result in notifications being sent out to editors, etc. . So the original request is not of much use as it is not the end user making it.

  5. Someone could tell me that this is all possible and the problem is just me and my lack of PHP knowledge.