All Dingo routes return 404 when phpunit testing - lumen

original posted at https://github.com/dingo/api/issues/1472
I'm using Lumen 5.1 and DingoApi 1.0.x to do my api development, and now I'm trying to do some acceptance testing. Following the documentation of Lumen, here is how I do it:
Here is a simplified routes definition in app\Http\routes.php:
$app->get('/', function () use ($app) {
return "Welcome to mysite.com";
});
$api = app('Dingo\Api\Routing\Router');
$api->version('v1', function ($api) {
$api->group([
'prefix' => 'dealer',
'middleware' => 'checkH5ApiSign'
], function ($api) {
$api->get('list', 'App\Http\Controllers\Credit\DealerController#index');
$api->get('staff_list', 'App\Http\Controllers\Credit\DealerController#getStaffList');
});
}
I can access both routes defined using $app or $api(dingo) in browser or via postman, they both can return a 200 response. But whenever I'm trying to access those routes in phpunit, the $app defined route like / is responding okay with 200 code, but all routes defined with $api(dingo) will response with 404 status code. Here is my test code:
class DealerTest extends TestCase
{
public function testTest()
{
$this->get('/')->assertResponseOk();
$this->get('/dealer/list')->assertResponseOk();
$this->get('/dealer/staff_list')->assertResponseOk();
}
}
and ran result:
PHPUnit 5.7.5 by Sebastian Bergmann and contributors.
F 1 / 1 (100%)
Time: 590 ms, Memory: 6.00MB
There was 1 failure:
1) DealerTest::testTest
Expected status code 200, got 404.
Failed asserting that false is true.
E:\Gitrepos\api.fin.youxinjinrong.com\vendor\laravel\lumen-framework\src\Testing\AssertionsTrait.php:19
E:\Gitrepos\api.fin.youxinjinrong.com\tests\DealerTest.php:8
FAILURES!
Tests: 1, Assertions: 2, Failures: 1.
I tried ran through Dingo package code to find the cause, but failed. All other related issue could not solve my problem either. So please help me.
update
I followed the code flow, and see that FastRoute\DataGenerator\RegexBasedAbstract.php is doing the addRoute() operation, I dumped $this->staticRoutes) in that addRoute() method, see that it's doing okay both inside browser and under phpunit. But weird enough, the following call of ->getData() is behaving differenctly: in browser all static routes are returned, but not in phpunit.
Hope this can somehow be helpful. I'm still digging this problem...

So I got mine to work by doing this;
Using the example in the example used in creating the issue:
class DealerTest extends TestCase
{
public function testTest()
{
$this->get('/')->assertResponseOk();
$this->get('/dealer/list')->assertResponseOk();
$this->get('/dealer/staff_list')->assertResponseOk();
}
}
becomes
class DealerTest extends TestCase
{
public function testTest()
{
$this->get(getenv('API_DOMAIN') . '/v1/')->assertResponseOk();
$this->get(getenv('API_DOMAIN') . '/v1/dealer/list')->assertResponseOk();
$this->get(getenv('API_DOMAIN') . '/v1/dealer/staff_list')->assertResponseOk();
}
}
I hope this helps

Related

SuiteCRM v7.10.29 Custom API v4.1

I am creating a custom API for SuiteCRM. When I attempt to run the new API from {CRM Home}/custom/service/v4_1_custom I receive an 'HTTP ERROR 500'. There are not errors in the error_log file or the SuiteCRM.log file.
I have followed the method in the following two url's
https://fayebsg.com/2013/05/extending-the-sugarcrm-api-updating-dropdowns/
https://support.sugarcrm.com/Documentation/Sugar_Developer/Sugar_Developer_Guide_10.0/Integration/Web_Services/Legacy_API/Extending_Web_Services/
registry.php
<?php
require_once('service/v4_1/registry.php');
class registry_v4_1_custom extends registry_v4_1
{
protected function registerFunction()
{
parent::registerFunction();
$this->serviceClass->registerFunction('test', array(), array());
}
}
SugarWebServicesImplv4_1_custom.php
<?php
if(!defined('sugarEntry'))define('sugarEntry', true);
require_once('service/v4_1/SugarWebServiceImplv4_1.php');
class SugarWebServiceImplv4_1_custom extends SugarWebServiceImplv4_1
{
/**
* #return string
*/
public function test()
{
LoggerManager::getLogger()->warn('SugerWebServiceImplv4_1_custom test()');
return ("Test Worked");
} // test
} // SugarWebServiceImplv4_1_custom
I found the answer to this issue.
In the file {SuiteCRM}/include/entryPoint.php there are many files that are included thru require_once. In this list of require_once files, there were 4 files that were set as require not require_once. These were classes and therefore could not be included a second time. I changed these to require_once and the HTTP Error 500 went away and the custom APIs started working.

How to fix error "Cannot dispatch middleware Application\Middleware\IndexMiddleware"?

I've set up a Zend Application as normal, except in my case the difference is that I set it up over an existing legacy web application.
I still want to call my existing legacy application over the ZF3 app. It was suggested I can do so using Middleware. I went over https://docs.zendframework.com/zend-mvc/middleware/ and set up my routing as described there.
However, when I run the application, I am greeted by this:
Cannot dispatch middleware Application\Middleware\IndexMiddleware
#0 zend-mvc\src\MiddlewareListener.php(146):
Zend\Mvc\Exception\InvalidMiddlewareException::fromMiddlewareName('Application\\Mid...')
Here is where the exception happens:
https://github.com/zendframework/zend-mvc/blob/release-3.1.0/src/MiddlewareListener.php#L146
Just to note:
$middlewareToBePiped; //'Application\Middleware\IndexMiddleware'
is_string($middlewareToBePiped); // true
$serviceLocator->has($middlewareToBePiped);//false
$middlewareToBePiped instanceof MiddlewareInterface; //false
is_callable($middlewareToBePiped);//false
My class is:
namespace Application\Middleware;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Interop\Http\ServerMiddleware\MiddlewareInterface;
use Interop\Http\ServerMiddleware\DelegateInterface;
use Zend\Http\Response;
class IndexMiddleware implements MiddlewareInterface
{
public function __invoke(ServerRequestInterface $request, ResponseInterface $response)
{}
public function process(ServerRequestInterface $request, DelegateInterface $delegate)
{}
}
I am thinking that my issue is that my IndexMiddleware class is not being found in ServiceLocator... (line 142 of linked API). How do I get it in there?
I put this into my application.config.php file:
'service_manager' => [
'invokables' => array(
'middleware' => IndexMiddleware::class
)
]
onto the next error it is.. (Last middleware executed did not return a response.)
but looks like it has executed)

Laravel Mail::Send works on local apache but complains about mime on nginx

I have installed a laravel package for user verification
https://github.com/jrean/laravel-user-verification
Register Controller needs to be changed to work like below.
public function register(Request $request)
{
$this->validator($request->all())->validate();
$user = $this->create($request->all());
$this->guard()->login($user);
UserVerification::generate($user);
UserVerification::send($user, 'Verification Mail from example.com');
return redirect()->intended('/home');
}
Used mailgun to send mails.It worked fine on local apache. sent mails successfully to gmail and others.
Installed on nginx production(ubuntu 16.04 VPS ). It throws following error.
FatalThrowableError in SimpleMessage.php line 33:
Type error: Argument 1 passed to Swift_Mime_SimpleMessage::__construct() must
be an instance of Swift_Mime_HeaderSet, none given, called in /var/www/example.com/
html/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Message.php on line 48
To check if it is a package problem I have also done the following which works on local apache but throws the same error on nginx.
Route::get('/mailsend', function() {
$data = [
'title' => 'hello user',
'content' => 'Thanks for joining us'
];
Mail::send('mails.test', $data , function($message) {
$message->to('example#gmail.com','example')->subject('Testing from example');
});
});
The code as shown in error /Swift/Message.php in line 48 as follows
call_user_func_array(
array($this, 'Swift_Mime_SimpleMessage::__construct'),
Swift_DependencyContainer::getInstance()
->createDependenciesFor('mime.message')
);
Could not figure out the problem with nginx. Any help would be greatly appreciated.
Try uncomment line: extension=php_openssl.dll on php.ini
and check this https://laravel.io/forum/05-13-2014-smtp-mail-not-working-in-live-server

Errors in codeigniter-restserver library

I want to use restful in my ci 3.03 application:
I found this tutplus tutorial
I downloaded codeigniter-restserver-master.zip file and copied Format.php and REST_Controller.php(#version 3.0.0) files into /application/libraries/REST directory
I created control application/controllers/api/Users.php :
require_once("application/libraries/REST/REST_Controller.php");
require_once("application/libraries/REST/Format.php");
class Users extends REST_Controller
{
//protected $rest_format = 'json';
function users_get()
{
//$users = $this->user_model->get_all();
$filter_username= $this->get('filter_username');
$filter_user_group= $this->get('filter_user_group');
$filter_active= $this->get('filter_active');
$sort= $this->get('sort');
$sort_direction= $this->get('sort_direction');
//, $filter_user_group, $filter_active, $sort, $sort_direction
$users_list = $this->muser->getUsersList(false, ''/*, $filter_username, $filter_user_group, $filter_active, $sort, $sort_direction, ''*/);
echo '<pre>'.count($users_list).'::$users_lists::'.print_r($users_list,true).'</pre>';
if($users_list)
{
$this->response($users, 200);
}
else
{
$this->response(NULL, 404);
}
}
AND RUNNING URL http://local-ci3.com/api/users I got many errors:
A PHP Error was encountered
Severity: Notice
Message: Undefined property: Users::$format
Filename: REST/REST_Controller.php
Line Number: 734
Backtrace:
File: /mnt/diskD_Work/wwwroot/ci3/application/libraries/REST/REST_Controller.php
Line: 734
Function: _error_handler
File: /mnt/diskD_Work/wwwroot/ci3/application/libraries/REST/REST_Controller.php
Line: 649
Function: response
File: /mnt/diskD_Work/wwwroot/ci3/index.php
Line: 292
Function: require_once
A PHP Error was encountered
Severity: Notice
Message: Undefined property: Users::$format
Filename: REST/REST_Controller.php
Line Number: 752
Backtrace:
File: /mnt/diskD_Work/wwwroot/ci3/application/libraries/REST/REST_Controller.php
Line: 752
Function: _error_handler
File: /mnt/diskD_Work/wwwroot/ci3/application/libraries/REST/REST_Controller.php
Line: 649
Function: response
File: /mnt/diskD_Work/wwwroot/ci3/index.php
Line: 292
Function: require_once
Actually I wanted to get some workable library to help me with REST api creation. I think that is preferable way istead of making from zero.
But is this library not workable or does it needs for some fixing? Sorry, what I missed is if this library only for ci 2?
I made search on this forum and found such hint :
I have the same problem when I load both Format.php and
Rest_Controller.php into a controller. After have a quick glance at
Format.php, it appears to be a standalone format conversion helper.
Try to just load Rest_Controller.php and see if your problem goes
away.
I commented line
//require_once("application/libraries/REST/Format.php");
in my controller, but I still get errors like :
Message: Undefined property: Users::$format.
I tried to review code of this library and see that invalid block when data are converted to json format, line 731-757 :
elseif ($data !== NULL)
{
// If the format method exists, call and return the output in that format
if (method_exists($this->format, 'to_' . $this->response->format))
{
// Set the format header
$this->output->set_content_type($this->_supported_formats[$this->response->format], strtolower($this->config->item('charset')));
$output = $this->format->factory($data)->{'to_' . $this->response->format}();
// An array must be parsed as a string, so as not to cause an array to string error
// Json is the most appropriate form for such a datatype
if ($this->response->format === 'array')
{
$output = $this->format->factory($output)->{'to_json'}();
}
}
else
{
// If an array or object, then parse as a json, so as to be a 'string'
if (is_array($data) || is_object($data))
{
$data = $this->format->factory($data)->{'to_json'}();
}
// Format is not supported, so output the raw data as a string
$output = $data;
}
}
If I tried to commented this block, but get error
Message: Array to string conversion
Looks like data are not converted in this case...
Is is possible to fix these errors?
Or can you, please, to tell me advice some codeigniter 3 REST api workable library with similar interface like library above?
Thanks!
I use that lib, work just fine. My suggestion is follow the more relevant installation instruction on github .
you also wrong place the lib file :
Tutorial say :
require(APPPATH'.libraries/REST_Controller.php');
You try :
require_once("application/libraries/REST/REST_Controller.php");
require_once("application/libraries/REST/Format.php");
No need to include the format because on line 407 the lib will load it. And also good to know on line 404 it will load the configuration (application/config/rest.php) it will be your default configuration, and also you can change it to suit your need.
Please let me know if you still got error using my answer :)

How to get http request header info from the server side with spray RestAPI

I am new to Scala and Spray. I have written a simple REST API according to the instructions given in this blog post.
http://www.smartjava.org/content/first-steps-rest-spray-and-scala
And all are working as expected.
Now I want to modify the program to print the HTTP headers like Encoding, Language, remote-address, etc.. I would like to print all the header information (purpose is to log these information)
But I could not find a proper documentation or examples. Could anyone please help me to get this done.
If you need to extract a specific header:
optionalHeaderValueByName("Encoding") { encodingHeader =>
println(encodingHeader)
complete("hello")
}
alternatively you can access the raw request object and directly extractive the headers. Here's a custom directive that logs all the headers:
def logHeaders(): Directive0 = extract(_.request.headers).map(println)
Usage
logHeaders() {
complete("hello")
}
Here's how I got it working.
Directive:
def logHeaders(innerRoute: Route): (RequestContext => Unit) = extract(_.request.headers) { headers =>
headers.foreach(h => logger.info("header: {} = {}", h.name, h.value))
innerRoute
}
Usage:
logHeaders() {
complete("hello")
}