2017-09-20 11:38:35 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
use Kahlan\Plugin\Stub;
|
|
|
|
use Kahlan\Plugin\Monkey;
|
|
|
|
|
|
|
|
use api\core\Request;
|
2017-09-21 12:42:02 +00:00
|
|
|
use api\core\Checker;
|
2017-09-20 12:47:17 +00:00
|
|
|
use api\core\AuthSystem;
|
|
|
|
use api\core\AuthSystemDefault;
|
2017-09-20 11:38:35 +00:00
|
|
|
use error\core\Error;
|
|
|
|
use error\core\Err;
|
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
describe('api', function(){
|
|
|
|
describe('core', function(){
|
|
|
|
describe('Request', function(){
|
2017-09-20 11:38:35 +00:00
|
|
|
|
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
beforeEach(function(){
|
|
|
|
$_SERVER = [
|
|
|
|
'REQUEST_METHOD' => 'POST'
|
|
|
|
];
|
|
|
|
});
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
describe('[check] config file', function(){
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
it('pass when config file exists', function(){
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
expect( file_exists(Request::config_path()) )->toBeTruthy();
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
});
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
it('pass when we can read the config file', function(){
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
expect( @file_get_contents(Request::config_path()) )->not->toBe(false);
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
});
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
it('pass when the config file is valid json', function(){
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
$read = @file_get_contents(Request::config_path());
|
|
|
|
expect($read)->not->toBe(false);
|
|
|
|
expect( json_decode($read, true) )->not->toBeNull();
|
|
|
|
expect( json_decode($read, true) )->toBeA('array');
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
});
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
});
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-21 00:05:13 +00:00
|
|
|
describe('__construct(@path, @params)', function(){
|
2017-09-20 12:47:17 +00:00
|
|
|
|
2017-09-21 00:05:13 +00:00
|
|
|
it('fail if no HTTP_METHOD', function(){
|
|
|
|
unset($_SERVER);
|
2017-09-20 12:47:17 +00:00
|
|
|
|
2017-09-21 00:05:13 +00:00
|
|
|
$req = new Request('someString');
|
|
|
|
expect($req->error->get())->toBe(Err::UnknownHttpMethod);
|
2017-09-20 12:47:17 +00:00
|
|
|
});
|
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
context('with argument combinations', function(){
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
it('fail if @path is missing', function(){
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
$req = new Request();
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
expect($req->error->get())->toBe(Err::MissingPath);
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
});
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
it('fail if @path is not a string', function(){
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
expect('is_string')->toBeCalled();
|
|
|
|
$req = new Request(1);
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
expect($req->error->get())->toBe(Err::WrongPathModule);
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
});
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
it('pass if @params is an array', function(){
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
unset($_SERVER);
|
|
|
|
expect('is_array')->toBeCalled();
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
$req = new Request('someString', ['a', 'b']);
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
expect($req->error->get())->toBe(Err::UnknownHttpMethod);
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
});
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
it('pass if @params is not an array (default: [])', function(){
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
unset($_SERVER);
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
expect('is_array')->toBeCalled();
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
$types = [true, false, null, 1, 2.3, -1.2, 0, 'blabla'];
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
foreach($types as $type){
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
$req = new Request('someString', true);
|
|
|
|
expect($req->error->get())->toBe(Err::UnknownHttpMethod);
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
}
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
});
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
});
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
context('with config errors', function(){
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-21 00:05:13 +00:00
|
|
|
it('fail if the config file doesn\'t exist', function(){
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
// Request::config_path -> 'aa'
|
|
|
|
allow(Request::class)->toReceive('::config_path')->andReturn('invalid_fname');
|
|
|
|
expect(Request::config_path())->toBe('invalid_fname');
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
// file_exists -> false
|
|
|
|
allow('file_exists')->toBeCalled()->andReturn(false);
|
|
|
|
expect('file_exists')->toBeCalled();
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
$req = new Request('a/b');
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
expect($req->error->get())->toBe(Err::UnreachableResource);
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
});
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
it('fail if the config file cannot be read', function(){
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
// file_get_contents -> false
|
|
|
|
allow('file_get_contents')->toBeCalled()->andReturn(false);
|
|
|
|
expect('file_get_contents')->toBeCalled();
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
$req = new Request('a/b');
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
expect($req->error->get())->toBe(Err::UnreachableResource);
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
});
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
it('fail if the json format is not valid', function(){
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
// file_exists -> true
|
|
|
|
allow('file_exists')->toBeCalled()->andReturn(true);
|
|
|
|
expect('file_exists')->toBeCalled();
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
// file_get_contents -> false
|
|
|
|
allow('file_get_contents')->toBeCalled()->andReturn('{incorrect_json');
|
|
|
|
expect('file_get_contents')->toBeCalled();
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
// json_decode -> called
|
|
|
|
expect('json_decode')->toBeCalled();
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
$req = new Request('a/b');
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
expect($req->error->get())->toBe(Err::ParsingFailed);
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
});
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
});
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
context('with checks errors', function(){
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
it('fail with checkPath() fails', function(){
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
allow(Request::class)->toReceive('checkPath')->andRun(function(){
|
|
|
|
$this->error->set(Err::UnknownError);
|
|
|
|
return false;
|
|
|
|
});
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
$req = new Request('a/b');
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
expect($req->error->get())->toBe(Err::UnknownError);
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
});
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
it('fail with checkPermission() fails', function(){
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
// bypass checkPath();
|
|
|
|
allow(Request::class)->toReceive('checkPath')->andReturn(true);
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
allow(Request::class)->toReceive('checkPermission')->andRun(function(){
|
|
|
|
$this->error->set(Err::UnknownError);
|
|
|
|
return false;
|
|
|
|
});
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
$req = new Request('a/b');
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
expect($req->error->get())->toBe(Err::UnknownError);
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
});
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
it('fail with checkParams() fails', function(){
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
// bypass checkPath(); + checkPermission();
|
|
|
|
allow(Request::class)->toReceive('checkPath')->andReturn(true);
|
|
|
|
allow(Request::class)->toReceive('checkPermission')->andReturn(true);
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
allow(Request::class)->toReceive('checkParams')->andRun(function(){
|
|
|
|
$this->error->set(Err::UnknownError);
|
|
|
|
return false;
|
|
|
|
});
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
$req = new Request('a/b');
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
expect($req->error->get())->toBe(Err::UnknownError);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
it('pass with all checks ok', function(){
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
// bypass all checks
|
|
|
|
allow(Request::class)->toReceive('checkPath')->andReturn(true);
|
|
|
|
allow(Request::class)->toReceive('checkPermission')->andReturn(true);
|
|
|
|
allow(Request::class)->toReceive('checkParams')->andReturn(true);
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
// bypass buildOptions();
|
|
|
|
allow(Request::class)->toReceive('buildOptions')->andReturn(true);
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
$req = new Request('a/b');
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
expect($req->error->get())->toBe(Err::Success);
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
});
|
2017-09-20 11:38:35 +00:00
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
describe('checkPath(@path)', function(){
|
|
|
|
|
|
|
|
it('fail when wrong path format: \'module/method\'', function(){
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
$values = ['a-b', 'a /b', 'a/b '];
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
foreach($values as $value){
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
$req = new Request($value);
|
|
|
|
expect($req->error->get())->toBe(Err::WrongPathModule);
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
}
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
});
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
it('pass when valid path format: letter/number/-/_', function(){
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
$values = ['a_b-c/d-e_f', 'abc/def', '_a_/_b_'];
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
foreach($values as $value){
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
$req = new Request($value);
|
|
|
|
expect($req->error->get())->not->toBe(Err::WrongPathModule);
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
}
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
});
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
it('fail when unknown module', function(){
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
allow('json_decode')->toBeCalled()->andReturn([
|
|
|
|
'mo-du_leA' => [],
|
|
|
|
'moduleB' => []
|
|
|
|
]);
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
$values = ['modulea/method', 'MODULEA/method', 'moduleC/method'];
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
foreach($values as $value){
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
$req = new Request($value);
|
|
|
|
expect($req->error->get())->toBe(Err::UnknownModule);
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
}
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
});
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
it('fail when unknown method', function(){
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
allow('json_decode')->toBeCalled()->andReturn([
|
|
|
|
'mo-du_leA' => [ 'POST::me-th_odA' => [] ],
|
|
|
|
'moduleB' => []
|
|
|
|
]);
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
$values = ['mo-du_leA/me-thodA', 'mo-du_leA/meth_odA', 'mo-du_leA/me-th_oda'];
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
foreach($values as $value){
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
$req = new Request($value);
|
|
|
|
expect($req->error->get())->toBe(Err::UnknownMethod);
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
}
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
});
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-20 12:47:17 +00:00
|
|
|
it('pass all right', function(){
|
|
|
|
|
|
|
|
// bypass all checks
|
|
|
|
allow(Request::class)->toReceive('checkPermission')->andReturn(true);
|
|
|
|
allow(Request::class)->toReceive('checkParams')->andReturn(true);
|
|
|
|
|
|
|
|
// bypass buildOptions();
|
|
|
|
allow(Request::class)->toReceive('buildOptions')->andReturn(true);
|
|
|
|
|
|
|
|
allow('json_decode')->toBeCalled()->andReturn([
|
|
|
|
'mo-du_leA' => [ 'POST::me-th_odA' => [] ],
|
|
|
|
'moduleB' => []
|
|
|
|
]);
|
|
|
|
|
|
|
|
$req = new Request('mo-du_leA/me-th_odA');
|
|
|
|
expect($req->error->get())->toBe(Err::Success);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('checkPermission()', function(){
|
|
|
|
|
|
|
|
it('pass when no permission', function(){
|
|
|
|
|
|
|
|
// bypass checkers
|
|
|
|
allow(Request::class)->toReceive('checkParams')->andReturn(true);
|
|
|
|
allow(Request::class)->toReceive('buildOptions')->andReturn(true);
|
|
|
|
|
|
|
|
allow('json_decode')->toBeCalled()->andReturn([
|
|
|
|
'moduleA' => [
|
|
|
|
'POST::methodA' => []
|
|
|
|
]
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
|
|
$req = new Request('moduleA/methodA');
|
|
|
|
expect($req->error->get())->toBe(Err::Success);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
it('pass when permission is not an array', function(){
|
|
|
|
|
|
|
|
// bypass checkers
|
|
|
|
allow(Request::class)->toReceive('checkParams')->andReturn(true);
|
|
|
|
allow(Request::class)->toReceive('buildOptions')->andReturn(true);
|
|
|
|
|
|
|
|
allow('json_decode')->toBeCalled()->andReturn([
|
|
|
|
'moduleA' => [
|
|
|
|
'POST::methodA' => [
|
|
|
|
'permissions' => 23.2
|
|
|
|
]
|
|
|
|
]
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
|
|
$req = new Request('moduleA/methodA');
|
|
|
|
expect($req->error->get())->toBe(Err::Success);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
2017-09-21 00:05:13 +00:00
|
|
|
it('pass when permission is an empty array', function(){
|
2017-09-20 12:47:17 +00:00
|
|
|
|
|
|
|
// bypass checkers
|
|
|
|
allow(Request::class)->toReceive('checkParams')->andReturn(true);
|
|
|
|
allow(Request::class)->toReceive('buildOptions')->andReturn(true);
|
|
|
|
|
|
|
|
allow('json_decode')->toBeCalled()->andReturn([
|
|
|
|
'moduleA' => [
|
|
|
|
'POST::methodA' => [
|
|
|
|
'permissions' => []
|
|
|
|
]
|
|
|
|
]
|
|
|
|
]);
|
|
|
|
|
2017-09-21 00:05:13 +00:00
|
|
|
|
2017-09-20 12:47:17 +00:00
|
|
|
$req = new Request('moduleA/methodA');
|
2017-09-21 00:05:13 +00:00
|
|
|
expect($req->error->get())->toBe(Err::Success);
|
2017-09-20 12:47:17 +00:00
|
|
|
|
|
|
|
});
|
|
|
|
|
2017-09-21 00:05:13 +00:00
|
|
|
it('fail if neither AuthSystem nor AuthSystemDefault', function(){
|
2017-09-20 12:47:17 +00:00
|
|
|
|
|
|
|
// bypass checkers
|
|
|
|
allow(Request::class)->toReceive('checkParams')->andReturn(true);
|
|
|
|
allow(Request::class)->toReceive('buildOptions')->andReturn(true);
|
|
|
|
|
2017-09-21 00:05:13 +00:00
|
|
|
allow('file_exists')->toBeCalled()->andReturn(true, false);
|
|
|
|
expect('file_exists')->toBeCalled()->times(2);
|
|
|
|
|
2017-09-20 12:47:17 +00:00
|
|
|
allow('json_decode')->toBeCalled()->andReturn([
|
|
|
|
'moduleA' => [
|
|
|
|
'POST::methodA' => [
|
2017-09-21 00:05:13 +00:00
|
|
|
'permissions' => ['a']
|
2017-09-20 12:47:17 +00:00
|
|
|
]
|
|
|
|
]
|
|
|
|
]);
|
|
|
|
|
|
|
|
$req = new Request('moduleA/methodA');
|
2017-09-21 00:05:13 +00:00
|
|
|
expect($req->error->get())->toBe(Err::UnreachableResource);
|
2017-09-20 12:47:17 +00:00
|
|
|
|
|
|
|
});
|
|
|
|
|
2017-09-21 00:05:13 +00:00
|
|
|
it('pass if no AuthSystem but AuthSystemDefault (Success)', function(){
|
|
|
|
|
2017-09-20 12:47:17 +00:00
|
|
|
// bypass checkers
|
|
|
|
allow(Request::class)->toReceive('checkParams')->andReturn(true);
|
|
|
|
allow(Request::class)->toReceive('buildOptions')->andReturn(true);
|
|
|
|
|
|
|
|
allow('json_decode')->toBeCalled()->andReturn([
|
|
|
|
'moduleA' => [
|
|
|
|
'POST::methodA' => [
|
|
|
|
'permissions' => ['a']
|
|
|
|
]
|
|
|
|
]
|
|
|
|
]);
|
|
|
|
|
2017-09-21 00:05:13 +00:00
|
|
|
allow(AuthSystemDefault::class)->toReceive('::permission')->andReturn(new Error(Err::Success));
|
2017-09-20 12:47:17 +00:00
|
|
|
$req = new Request('moduleA/methodA');
|
2017-09-21 00:05:13 +00:00
|
|
|
expect($req->error->get())->toBe(Err::Success);
|
|
|
|
|
2017-09-20 12:47:17 +00:00
|
|
|
});
|
|
|
|
|
2017-09-21 00:05:13 +00:00
|
|
|
it('pass if no AuthSystem but AuthSystemDefault (PermissionError)', function(){
|
|
|
|
|
2017-09-20 12:47:17 +00:00
|
|
|
// bypass checkers
|
|
|
|
allow(Request::class)->toReceive('checkParams')->andReturn(true);
|
|
|
|
allow(Request::class)->toReceive('buildOptions')->andReturn(true);
|
|
|
|
|
|
|
|
allow('json_decode')->toBeCalled()->andReturn([
|
|
|
|
'moduleA' => [
|
|
|
|
'POST::methodA' => [
|
2017-09-21 00:05:13 +00:00
|
|
|
'permissions' => ['a']
|
2017-09-20 12:47:17 +00:00
|
|
|
]
|
|
|
|
]
|
|
|
|
]);
|
|
|
|
|
2017-09-21 00:05:13 +00:00
|
|
|
allow(AuthSystemDefault::class)->toReceive('::permission')->andReturn(new Error(Err::PermissionError));
|
2017-09-20 12:47:17 +00:00
|
|
|
$req = new Request('moduleA/methodA');
|
|
|
|
expect($req->error->get())->toBe(Err::PermissionError);
|
2017-09-21 00:05:13 +00:00
|
|
|
|
2017-09-20 12:47:17 +00:00
|
|
|
});
|
|
|
|
|
2017-09-21 00:05:13 +00:00
|
|
|
});
|
2017-09-20 12:47:17 +00:00
|
|
|
|
2017-09-21 00:05:13 +00:00
|
|
|
describe('setAuthSystem(@instance)', function(){
|
2017-09-20 12:47:17 +00:00
|
|
|
|
2017-09-21 00:05:13 +00:00
|
|
|
it('pass when instance of AuthSystem', function(){
|
2017-09-20 12:47:17 +00:00
|
|
|
|
2017-09-21 00:05:13 +00:00
|
|
|
$instance = new AuthSystemDefault();
|
2017-09-20 12:47:17 +00:00
|
|
|
|
2017-09-21 00:05:13 +00:00
|
|
|
expect($instance)->toBeAnInstanceOf('api\core\AuthSystem');
|
|
|
|
expect(Request::setAuthSystem($instance))->toBeTruthy();
|
2017-09-20 12:47:17 +00:00
|
|
|
|
|
|
|
});
|
|
|
|
|
2017-09-21 00:05:13 +00:00
|
|
|
it('fail when not instance of AuthSystem', function(){
|
2017-09-20 12:47:17 +00:00
|
|
|
|
2017-09-21 00:05:13 +00:00
|
|
|
$instance = new Error(Err::Success);
|
|
|
|
|
|
|
|
expect($instance)->not->toBeAnInstanceOf('api\core\AuthSystem');
|
|
|
|
expect(Request::setAuthSystem($instance))->toBeFalsy();
|
2017-09-20 12:47:17 +00:00
|
|
|
|
|
|
|
});
|
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
});
|
2017-09-20 11:38:35 +00:00
|
|
|
|
2017-09-21 00:23:50 +00:00
|
|
|
describe('checkParams(@params)', function(){
|
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
beforeEach(function(){
|
2017-09-21 00:23:50 +00:00
|
|
|
|
|
|
|
// bypass checkers
|
|
|
|
allow(Request::class)->toReceive('checkPermission')->andReturn(true);
|
|
|
|
allow(Request::class)->toReceive('buildOptions')->andReturn(true);
|
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
$this->json = [
|
2017-09-21 00:23:50 +00:00
|
|
|
'moduleA' => [
|
|
|
|
'POST::methodA' => []
|
|
|
|
]
|
2017-09-21 13:01:10 +00:00
|
|
|
];
|
2017-09-21 00:23:50 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
// dispatch() -> return $this->params
|
|
|
|
allow(Request::class)->toReceive('dispatch')->andRun(function(){ return $this->params; });
|
2017-09-21 00:23:50 +00:00
|
|
|
|
|
|
|
});
|
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
context('config error', function(){
|
2017-09-21 00:23:50 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
it('fail if @params is not an array', function(){
|
2017-09-21 00:23:50 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
allow('is_array')->toBeCalled()->andReturn(false);
|
2017-09-21 00:23:50 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
allow('json_decode')->toBeCalled()->andReturn($this->json);
|
2017-09-21 00:23:50 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
$req = new Request('moduleA/methodA');
|
2017-09-21 00:23:50 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
expect($req->error->get())->toBe(Err::MissingParam);
|
|
|
|
});
|
2017-09-21 00:23:50 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
it('fail if array \'parameters\' is missing in config', function(){
|
2017-09-21 00:23:50 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
allow('json_decode')->toBeCalled()->andReturn($this->json);
|
2017-09-21 00:23:50 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
$req = new Request('moduleA/methodA');
|
|
|
|
expect($req->error->get())->toBe(Err::ConfigError);
|
2017-09-21 00:23:50 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
});
|
2017-09-21 00:23:50 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
it('fail if \'parameters\' has no <string> name', function(){
|
2017-09-21 00:23:50 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
$this->json['moduleA']['POST::methodA']['parameters'] = [
|
|
|
|
1 => []
|
|
|
|
];
|
|
|
|
allow('json_decode')->toBeCalled()->andReturn($this->json);
|
2017-09-21 00:23:50 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
$req = new Request('moduleA/methodA');
|
|
|
|
expect($req->error->get())->toBe(Err::ConfigError);
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
});
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
it('fail if \'parameters\' has no <array> specification', function(){
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
$this->json['moduleA']['POST::methodA']['parameters'] = [
|
|
|
|
'paramName' => 1
|
|
|
|
];
|
|
|
|
allow('json_decode')->toBeCalled()->andReturn($this->json);
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
$req = new Request('moduleA/methodA');
|
|
|
|
expect($req->error->get())->toBe(Err::ConfigError);
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
});
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
it('fail if one \'parameters\' have no \'type\' clause', function(){
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
$this->json['moduleA']['POST::methodA']['parameters'] = [
|
|
|
|
'paramName' => [
|
|
|
|
'optional' => false
|
2017-09-21 12:42:02 +00:00
|
|
|
]
|
2017-09-21 13:01:10 +00:00
|
|
|
];
|
|
|
|
allow('json_decode')->toBeCalled()->andReturn($this->json);
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
$req = new Request('moduleA/methodA');
|
|
|
|
expect($req->error->get())->toBe(Err::ConfigError);
|
2017-09-21 12:42:02 +00:00
|
|
|
|
|
|
|
});
|
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
it('fail if one \'parameters\' have incorrect \'type\' clause', function(){
|
|
|
|
|
|
|
|
$this->json['moduleA']['POST::methodA']['parameters'] = [
|
|
|
|
'paramName' => [
|
|
|
|
'optional' => false,
|
|
|
|
'type' => 12
|
2017-09-21 12:42:02 +00:00
|
|
|
]
|
2017-09-21 13:01:10 +00:00
|
|
|
];
|
|
|
|
allow('json_decode')->toBeCalled()->andReturn($this->json);
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
$req = new Request('moduleA/methodA');
|
|
|
|
expect($req->error->get())->toBe(Err::ConfigError);
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
});
|
2017-09-21 12:42:02 +00:00
|
|
|
|
|
|
|
});
|
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
context('optional/required parameters', function(){
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
it('pass if missing optional parameter -> set to null by default', function(){
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
$this->json['moduleA']['POST::methodA']['parameters'] = [
|
|
|
|
'paramName' => [
|
|
|
|
'optional' => true,
|
|
|
|
'type' => 'text'
|
2017-09-21 12:42:02 +00:00
|
|
|
]
|
2017-09-21 13:01:10 +00:00
|
|
|
];
|
|
|
|
allow('json_decode')->toBeCalled()->andReturn($this->json);
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
$req = new Request('moduleA/methodA');
|
|
|
|
expect($req->error->get())->toBe(Err::Success);
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
// check param created with 'null' value
|
|
|
|
$params = $req->dispatch();
|
|
|
|
expect($params)->toContainKey('paramName');
|
|
|
|
expect($params['paramName'])->toBeNull();
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
});
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
it('fail if optional param wrong type ', function(){
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
$this->json['moduleA']['POST::methodA']['parameters'] = [
|
|
|
|
'paramName' => [
|
|
|
|
'optional' => true,
|
|
|
|
'type' => 'id'
|
2017-09-21 12:42:02 +00:00
|
|
|
]
|
2017-09-21 13:01:10 +00:00
|
|
|
];
|
|
|
|
allow('json_decode')->toBeCalled()->andReturn($this->json);
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
expect(Checker::class)->toReceive('::run')->with('id', 'bla');
|
|
|
|
$req = new Request('moduleA/methodA', ['paramName' => 'bla']);
|
|
|
|
expect($req->error->get())->toBe(Err::WrongParam);
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
});
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
it('pass if optional param matching type ', function(){
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
$this->json['moduleA']['POST::methodA']['parameters'] = [
|
|
|
|
'paramName' => [
|
|
|
|
'optional' => true,
|
|
|
|
'type' => 'id'
|
2017-09-21 12:42:02 +00:00
|
|
|
]
|
2017-09-21 13:01:10 +00:00
|
|
|
];
|
|
|
|
allow('json_decode')->toBeCalled()->andReturn($this->json);
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
expect(Checker::class)->toReceive('::run')->with('id', '12');
|
|
|
|
$req = new Request('moduleA/methodA', ['paramName' => '12']);
|
|
|
|
expect($req->error->get())->toBe(Err::Success);
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
});
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
it('fail if required param missing ', function(){
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
$this->json['moduleA']['POST::methodA']['parameters'] = [
|
|
|
|
'paramName' => [
|
|
|
|
'optional' => false,
|
|
|
|
'type' => 'id'
|
2017-09-21 12:42:02 +00:00
|
|
|
]
|
2017-09-21 13:01:10 +00:00
|
|
|
];
|
|
|
|
allow('json_decode')->toBeCalled()->andReturn($this->json);
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
$req = new Request('moduleA/methodA', []);
|
|
|
|
expect($req->error->get())->toBe(Err::MissingParam);
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
});
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
it('fail if required param wrong type ', function(){
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
$this->json['moduleA']['POST::methodA']['parameters'] = [
|
|
|
|
'paramName' => [
|
|
|
|
'optional' => false,
|
|
|
|
'type' => 'id'
|
2017-09-21 12:42:02 +00:00
|
|
|
]
|
2017-09-21 13:01:10 +00:00
|
|
|
];
|
|
|
|
allow('json_decode')->toBeCalled()->andReturn($this->json);
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
expect(Checker::class)->toReceive('::run')->with('id', 'bla');
|
|
|
|
$req = new Request('moduleA/methodA', ['paramName' => 'bla']);
|
|
|
|
expect($req->error->get())->toBe(Err::WrongParam);
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
});
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
it('pass if required param matching type ', function(){
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
$this->json['moduleA']['POST::methodA']['parameters'] = [
|
|
|
|
'paramName' => [
|
|
|
|
'optional' => false,
|
|
|
|
'type' => 'id'
|
|
|
|
]
|
|
|
|
];
|
|
|
|
allow('json_decode')->toBeCalled()->andReturn($this->json);
|
|
|
|
|
|
|
|
expect(Checker::class)->toReceive('::run')->with('id', '12');
|
|
|
|
$req = new Request('moduleA/methodA', ['paramName' => '12']);
|
|
|
|
expect($req->error->get())->toBe(Err::Success);
|
2017-09-21 12:42:02 +00:00
|
|
|
|
|
|
|
});
|
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
});
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
context('file parameters', function(){
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
it('fail if FILE param required + file does not exist', function(){
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
$this->json['moduleA']['POST::methodA']['parameters'] = [
|
|
|
|
'paramName' => [
|
|
|
|
'type' => 'FILE'
|
|
|
|
]
|
|
|
|
];
|
|
|
|
allow('json_decode')->toBeCalled()->andReturn($this->json);
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
$_FILES = [];
|
|
|
|
$req = new Request('moduleA/methodA');
|
|
|
|
expect($req->error->get())->toBe(Err::MissingParam);
|
2017-09-21 12:42:02 +00:00
|
|
|
|
|
|
|
});
|
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
it('pass if FILE param required + file exists -> create ref', function(){
|
|
|
|
|
|
|
|
$this->json['moduleA']['POST::methodA']['parameters'] = [
|
|
|
|
'paramName' => [
|
|
|
|
'type' => 'FILE'
|
2017-09-21 12:42:02 +00:00
|
|
|
]
|
2017-09-21 13:01:10 +00:00
|
|
|
];
|
|
|
|
allow('json_decode')->toBeCalled()->andReturn($this->json);
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
$_FILES = [ 'paramName' => 'some_file_value' ];
|
|
|
|
$req = new Request('moduleA/methodA');
|
|
|
|
expect($req->error->get())->toBe(Err::Success);
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
// check param created with 'null' value
|
|
|
|
$params = $req->dispatch();
|
|
|
|
expect($params)->toContainKey('paramName');
|
|
|
|
expect($params['paramName'])->toBe('some_file_value');
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
});
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
it('pass if FILE optional param missing -> null', function(){
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
$this->json['moduleA']['POST::methodA']['parameters'] = [
|
|
|
|
'paramName' => [
|
|
|
|
'optional' => true,
|
|
|
|
'type' => 'FILE'
|
|
|
|
]
|
|
|
|
];
|
|
|
|
allow('json_decode')->toBeCalled()->andReturn($this->json);
|
|
|
|
|
|
|
|
$_FILES = [ ];
|
|
|
|
$req = new Request('moduleA/methodA');
|
|
|
|
expect($req->error->get())->toBe(Err::Success);
|
|
|
|
|
|
|
|
// check param created with 'null' value
|
|
|
|
$params = $req->dispatch();
|
|
|
|
expect($params)->toContainKey('paramName');
|
|
|
|
expect($params['paramName'])->toBeNull();
|
2017-09-21 12:42:02 +00:00
|
|
|
|
|
|
|
});
|
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
it('pass if FILE optional param + file exists -> create ref', function(){
|
|
|
|
|
|
|
|
$this->json['moduleA']['POST::methodA']['parameters'] = [
|
|
|
|
'paramName' => [
|
|
|
|
'optional' => true,
|
|
|
|
'type' => 'FILE'
|
2017-09-21 12:42:02 +00:00
|
|
|
]
|
2017-09-21 13:01:10 +00:00
|
|
|
];
|
|
|
|
allow('json_decode')->toBeCalled()->andReturn($this->json);
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
$_FILES = [ 'paramName' => 'some_file_value' ];
|
|
|
|
$req = new Request('moduleA/methodA');
|
|
|
|
expect($req->error->get())->toBe(Err::Success);
|
2017-09-21 12:42:02 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
// check param created with 'null' value
|
|
|
|
$params = $req->dispatch();
|
|
|
|
expect($params)->toContainKey('paramName');
|
|
|
|
expect($params['paramName'])->toBe('some_file_value');
|
|
|
|
|
|
|
|
});
|
2017-09-21 12:42:02 +00:00
|
|
|
|
|
|
|
});
|
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
});
|
2017-09-21 00:23:50 +00:00
|
|
|
|
2017-09-21 13:01:10 +00:00
|
|
|
describe('dispatch()', function(){
|
2017-09-21 00:23:50 +00:00
|
|
|
});
|
|
|
|
|
2017-09-20 11:45:07 +00:00
|
|
|
});
|
2017-09-20 11:38:35 +00:00
|
|
|
});
|
|
|
|
});
|