mirror of
https://github.com/snipe/snipe-it.git
synced 2024-12-24 21:24:13 -08:00
REST API - Refactoring of routes file, more tests added (#3345)
* Toggles the disabled state of auto_increment_prefix To insert a prefix you had to toggle the checkbox, save the settings and reload. With this script it is immediate. Fixes #1390 * Delete asset image: made checkbox more visible Related to #3153 * Added personal-access-token component * Created basic API testing configuration * First version of /components endpoind cest * On-the-fly bearer token generation * Completed testing of PATCH and PUT methods * Added /components/{id}/assets route with tests * Updated route and dataTable in view * Completed test assertion * Added links to assets in ComponentsAssets view * Linked Company in AssetView page * Fixed purchase_cost format expectation in ApiComponentsCest * Refactored api routes file Sorted all prefixes in alphabetical order, removed duplicate routes. For every prefix I placed first Route::resource and then any additional route in a Route::group. Expanded arrays for readability and consistency. Removed useless calls as create and edit everywhere. * Refactored and added one more test to ApiComponentsAssetsCest * Marked one test as incomplete, 404 response should return json * Fixed value expectation * Refactored getToken() * Added API debugging routes * Added more information to ValidationException reporting Now the payload contains the validation errors for each invalid attribute. * /apitests: refactored expectations in component assertions * Created ApiAssetsCest * /apitests: Cleanup in Exceptions/Handler * Reverted change to use * Marked two tests as incomplete, looking for solutions
This commit is contained in:
parent
9ccaad8b9c
commit
c0c02eebd2
|
@ -6,6 +6,7 @@ use Exception;
|
|||
use Illuminate\Auth\AuthenticationException;
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use App\Helpers\Helper;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
|
@ -40,7 +41,7 @@ class Handler extends ExceptionHandler
|
|||
* Render an exception into an HTTP response.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Exception $exception
|
||||
* @param \Exception $e
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function render($request, Exception $e)
|
||||
|
@ -61,6 +62,10 @@ class Handler extends ExceptionHandler
|
|||
return response()->json(Helper::formatStandardApiResponse('error', null, $className . ' not found'), 200);
|
||||
}
|
||||
|
||||
if ($e instanceof \Illuminate\Validation\ValidationException) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', $e->response['messages'], $e->getMessage(), 400));
|
||||
}
|
||||
|
||||
if ($this->isHttpException($e)) {
|
||||
|
||||
$statusCode = $e->getStatusCode();
|
||||
|
|
794
routes/api.php
794
routes/api.php
|
@ -1,9 +1,6 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\CheckoutRequest;
|
||||
use App\Models\Location;
|
||||
use App\Models\Statuslabel;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
@ -18,273 +15,8 @@ use App\Models\Statuslabel;
|
|||
|
||||
|
||||
Route::group(['prefix' => 'v1','namespace' => 'Api'], function () {
|
||||
/*---Hardware API---*/
|
||||
|
||||
Route::resource('users', 'UsersController',
|
||||
['names' =>
|
||||
[
|
||||
'index' => 'api.users.index',
|
||||
'show' => 'api.users.show',
|
||||
'update' => 'api.users.update',
|
||||
'store' => 'api.users.store',
|
||||
'destroy' => 'api.users.destroy'
|
||||
],
|
||||
'except' => ['edit'],
|
||||
'parameters' => ['user' => 'user_id']
|
||||
]
|
||||
);
|
||||
|
||||
Route::resource('licenses', 'LicensesController',
|
||||
['names' =>
|
||||
[
|
||||
'index' => 'api.licenses.index',
|
||||
'show' => 'api.licenses.show',
|
||||
'update' => 'api.licenses.update',
|
||||
'store' => 'api.licenses.store',
|
||||
'destroy' => 'api.licenses.destroy'
|
||||
],
|
||||
'except' => ['edit'],
|
||||
'parameters' => ['license' => 'license_id']
|
||||
]
|
||||
);
|
||||
Route::post('imports/process/{import_id}', [ 'as' => 'api.imports.importFile', 'uses'=> 'ImportController@process']);
|
||||
|
||||
Route::resource('imports', 'ImportController',
|
||||
['names' =>
|
||||
[
|
||||
'index' => 'api.imports.index',
|
||||
'show' => 'api.imports.show',
|
||||
'update' => 'api.imports.update',
|
||||
'store' => 'api.imports.store',
|
||||
'destroy' => 'api.imports.destroy'
|
||||
],
|
||||
'except' => ['edit']
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
Route::get('models/{id}/assets',
|
||||
[
|
||||
'as' => 'api.models.assets',
|
||||
'uses'=> 'AssetModelsController@assets'
|
||||
]);
|
||||
|
||||
|
||||
Route::resource('models', 'AssetModelsController',
|
||||
['names' =>
|
||||
[
|
||||
'index' => 'api.models.index',
|
||||
'show' => 'api.models.show',
|
||||
'update' => 'api.models.update',
|
||||
'store' => 'api.models.store',
|
||||
'destroy' => 'api.models.destroy'
|
||||
],
|
||||
'except' => ['edit', 'create'],
|
||||
'parameters' => ['model' => 'model_id']
|
||||
]
|
||||
);
|
||||
|
||||
Route::resource('categories', 'CategoriesController',
|
||||
['names' =>
|
||||
[
|
||||
'index' => 'api.categories.index',
|
||||
'show' => 'api.categories.asset.show',
|
||||
'update' => 'api.categories.update',
|
||||
'store' => 'api.categories.store',
|
||||
'destroy' => 'api.categories.destroy'
|
||||
],
|
||||
'except' => ['edit', 'create'],
|
||||
'parameters' => ['category' => 'category_id']
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
Route::resource('companies', 'CompaniesController',
|
||||
['names' =>
|
||||
[
|
||||
'index' => 'api.companies.index',
|
||||
'show' => 'api.companies.show',
|
||||
'update' => 'api.companies.update',
|
||||
'store' => 'api.companies.store',
|
||||
'destroy' => 'api.companies.destroy'
|
||||
],
|
||||
'except' => ['edit'],
|
||||
'parameters' => ['component' => 'component_id']
|
||||
]
|
||||
);
|
||||
|
||||
Route::resource('locations', 'LocationsController',
|
||||
['names' =>
|
||||
[
|
||||
'index' => 'api.locations.index',
|
||||
'show' => 'api.locations.show',
|
||||
'update' => 'api.locations.update',
|
||||
'store' => 'api.locations.store',
|
||||
'destroy' => 'api.locations.destroy'
|
||||
],
|
||||
'except' => ['edit'],
|
||||
'parameters' => ['locations' => 'locations_id']
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
Route::resource('components', 'ComponentsController',
|
||||
['names' =>
|
||||
[
|
||||
'index' => 'api.components.index',
|
||||
'show' => 'api.components.show',
|
||||
'update' => 'api.components.update',
|
||||
'store' => 'api.components.store',
|
||||
'destroy' => 'api.components.destroy'
|
||||
],
|
||||
'parameters' =>
|
||||
['component' => 'component_id']
|
||||
]
|
||||
);
|
||||
|
||||
Route::get('components/{id}/assets', [
|
||||
'as' =>'api.components.assets',
|
||||
'uses' => 'ComponentsController@getAssets',
|
||||
]);
|
||||
|
||||
|
||||
Route::resource('suppliers', 'SuppliersController',
|
||||
['names' =>
|
||||
[
|
||||
'index' => 'api.suppliers.index',
|
||||
'create' => 'api.suppliers.create',
|
||||
'destroy' => 'api.suppliers.destroy'
|
||||
],
|
||||
'parameters' =>
|
||||
['supplier' => 'supplier_id']
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
Route::resource('groups', 'GroupsController',
|
||||
['names' =>
|
||||
[
|
||||
'index' => 'api.groups.index',
|
||||
'create' => 'api.groups.create',
|
||||
'store' => 'api.groups.store',
|
||||
'destroy' => 'api.groups.destroy'
|
||||
],
|
||||
'parameters' =>
|
||||
['group' => 'group_id']
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
Route::resource('depreciations', 'DepreciationsController',
|
||||
['names' =>
|
||||
[
|
||||
'index' => 'api.depreciations.index',
|
||||
'create' => 'api.depreciations.create',
|
||||
'destroy' => 'api.depreciations.destroy'
|
||||
],
|
||||
'parameters' =>
|
||||
['depreciation' => 'depreciation_id']
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
Route::resource('users', 'UsersController',
|
||||
['names' =>
|
||||
[
|
||||
'index' => 'api.users.index',
|
||||
'create' => 'api.users.create',
|
||||
'destroy' => 'api.users.destroy'
|
||||
],
|
||||
'parameters' =>
|
||||
['user' => 'user_id']
|
||||
]
|
||||
);
|
||||
|
||||
Route::resource('settings', 'SettingsController',
|
||||
['names' =>
|
||||
[
|
||||
'index' => 'api.settings.index',
|
||||
'create' => 'api.settings.create'
|
||||
],
|
||||
'parameters' =>
|
||||
['setting' => 'setting_id']
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*---Status Label API---*/
|
||||
Route::group([ 'prefix' => 'statuslabels'], function () {
|
||||
|
||||
|
||||
Route::get('{id}/assetlist',
|
||||
[ 'as' => 'api.statuslabels.assets', 'uses' => 'StatuslabelsController@assets' ]);
|
||||
|
||||
Route::get('{id}/deployable',
|
||||
[ 'as' => 'api.statuslabels.deployable', 'uses' => 'StatuslabelsController@checkIfDeployable' ]);
|
||||
|
||||
|
||||
|
||||
// Pie chart for dashboard
|
||||
Route::get('assets', [ 'as' => 'api.statuslabels.assets.bytype', 'uses' => 'StatuslabelsController@getAssetCountByStatuslabel' ]);
|
||||
|
||||
});
|
||||
|
||||
|
||||
Route::resource('statuslabels', 'StatuslabelsController',
|
||||
['names' =>
|
||||
[
|
||||
'index' => 'api.statuslabels.index',
|
||||
'create' => 'api.statuslabels.create',
|
||||
'destroy' => 'api.statuslabels.destroy'
|
||||
],
|
||||
'parameters' =>
|
||||
['statuslabel' => 'statuslabel_id']
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
|
||||
Route::resource('consumables', 'ConsumablesController',
|
||||
['names' =>
|
||||
[
|
||||
'index' => 'api.consumables.index',
|
||||
'create' => 'api.consumables.create',
|
||||
'show' => 'api.consumables.show',
|
||||
'destroy' => 'api.consumables.destroy'
|
||||
],
|
||||
'parameters' =>
|
||||
['consumable' => 'consumable_id']
|
||||
]
|
||||
);
|
||||
|
||||
Route::resource('manufacturers', 'ManufacturersController',
|
||||
['names' =>
|
||||
[
|
||||
'index' => 'api.manufacturers.index',
|
||||
'show' => 'api.manufacturers.show',
|
||||
'update' => 'api.manufacturers.update',
|
||||
'store' => 'api.manufacturers.store',
|
||||
'destroy' => 'api.manufacturers.destroy'
|
||||
],
|
||||
'except' => ['edit'],
|
||||
'parameters' => ['manufacturer' => 'manufacturer_id']
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
Route::group([ 'prefix' => 'accessories' ], function () {
|
||||
Route::match(['DELETE'], '{id}', ['uses' => 'AccessoriesController@destroy','as' => 'api.accessories.destroy']);
|
||||
Route::get(
|
||||
'{id}/checkedout',
|
||||
[ 'as' => 'api.accessories.checkedout', 'uses' => 'AccessoriesController@checkedout' ]
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
|
||||
/*--- Accessories API ---*/
|
||||
|
||||
Route::resource('accessories', 'AccessoriesController',
|
||||
['names' =>
|
||||
|
@ -295,72 +27,478 @@ Route::group(['prefix' => 'v1','namespace' => 'Api'], function () {
|
|||
'store' => 'api.accessories.store',
|
||||
'destroy' => 'api.accessories.destroy'
|
||||
],
|
||||
'except' => ['edit'],
|
||||
'except' => ['create', 'edit'],
|
||||
'parameters' => ['accessory' => 'accessory_id']
|
||||
]
|
||||
); // Accessories resource
|
||||
|
||||
Route::group(['prefix' => 'accessories'], function () {
|
||||
|
||||
Route::get('{accessory}/checkedout',
|
||||
[
|
||||
'as' => 'api.accessories.checkedout',
|
||||
'uses' => 'AccessoriesController@checkedout'
|
||||
]
|
||||
);
|
||||
}); // Accessories group
|
||||
|
||||
|
||||
/*--- Categories API ---*/
|
||||
|
||||
Route::resource('categories', 'CategoriesController',
|
||||
[
|
||||
'names' =>
|
||||
[
|
||||
'index' => 'api.categories.index',
|
||||
'show' => 'api.categories.show',
|
||||
'store' => 'api.categories.store',
|
||||
'update' => 'api.categories.update',
|
||||
'destroy' => 'api.categories.destroy'
|
||||
],
|
||||
'except' => ['edit', 'create'],
|
||||
'parameters' => ['category' => 'category_id']
|
||||
]
|
||||
); // Categories resource
|
||||
|
||||
|
||||
/*--- Companies API ---*/
|
||||
|
||||
Route::resource('companies', 'CompaniesController',
|
||||
[
|
||||
'names' =>
|
||||
[
|
||||
'index' => 'api.companies.index',
|
||||
'show' => 'api.companies.show',
|
||||
'store' => 'api.companies.store',
|
||||
'update' => 'api.companies.update',
|
||||
'destroy' => 'api.companies.destroy'
|
||||
],
|
||||
'except' => ['create', 'edit'],
|
||||
'parameters' => ['component' => 'component_id']
|
||||
]
|
||||
); // Companies resource
|
||||
|
||||
|
||||
/*--- Components API ---*/
|
||||
|
||||
Route::resource('components', 'ComponentsController',
|
||||
[
|
||||
'names' =>
|
||||
[
|
||||
'index' => 'api.components.index',
|
||||
'show' => 'api.components.show',
|
||||
'store' => 'api.components.store',
|
||||
'update' => 'api.components.update',
|
||||
'destroy' => 'api.components.destroy'
|
||||
],
|
||||
'except' => ['create', 'edit'],
|
||||
'parameters' => ['component' => 'component_id']
|
||||
]
|
||||
); // Components resource
|
||||
|
||||
Route::group(['prefix' => 'components'], function () {
|
||||
|
||||
Route::get('{component}/assets',
|
||||
[
|
||||
'as' =>'api.components.assets',
|
||||
'uses' => 'ComponentsController@getAssets',
|
||||
]
|
||||
);
|
||||
}); // Components group
|
||||
|
||||
|
||||
/*--- Consumables API ---*/
|
||||
|
||||
Route::resource('consumables', 'ConsumablesController',
|
||||
[
|
||||
'names' =>
|
||||
[
|
||||
'index' => 'api.consumables.index',
|
||||
'show' => 'api.consumables.show',
|
||||
'store' => 'api.consumables.store',
|
||||
'update' => 'api.consumables.update',
|
||||
'destroy' => 'api.consumables.destroy'
|
||||
],
|
||||
'except' => ['create', 'edit'],
|
||||
'parameters' => ['consumable' => 'consumable_id']
|
||||
]
|
||||
); // Consumables resource
|
||||
|
||||
|
||||
/*--- Depreciations API ---*/
|
||||
|
||||
Route::resource('depreciations', 'DepreciationsController',
|
||||
[
|
||||
'names' =>
|
||||
[
|
||||
'index' => 'api.depreciations.index',
|
||||
'show' => 'api.depreciations.show',
|
||||
'store' => 'api.depreciations.store',
|
||||
'update' => 'api.depreciations.update',
|
||||
'destroy' => 'api.depreciations.destroy'
|
||||
],
|
||||
'except' => ['create', 'edit'],
|
||||
'parameters' => ['depreciation' => 'depreciation_id']
|
||||
]
|
||||
); // Depreciations resource
|
||||
|
||||
|
||||
/*--- Fields API ---*/
|
||||
|
||||
Route::group(['prefix' => 'fields'], function () {
|
||||
Route::post('fieldsets/{id}/order',
|
||||
[
|
||||
'as' => 'api.customfields.order',
|
||||
'uses' => 'CustomFieldsController@postReorder'
|
||||
]
|
||||
);
|
||||
}); // Fields group
|
||||
|
||||
|
||||
/*--- Groups API ---*/
|
||||
|
||||
Route::resource('groups', 'GroupsController',
|
||||
[
|
||||
'names' =>
|
||||
[
|
||||
'index' => 'api.groups.index',
|
||||
'show' => 'api.groups.show',
|
||||
'store' => 'api.groups.store',
|
||||
'update' => 'api.groups.update',
|
||||
'destroy' => 'api.groups.destroy'
|
||||
],
|
||||
'except' => ['create', 'edit'],
|
||||
'parameters' => ['group' => 'group_id']
|
||||
]
|
||||
); // Groups resource
|
||||
|
||||
|
||||
/*--- Hardware API ---*/
|
||||
|
||||
Route::resource('hardware', 'AssetsController',
|
||||
[
|
||||
'names' =>
|
||||
[
|
||||
'index' => 'api.assets.index',
|
||||
'show' => 'api.assets.show',
|
||||
'store' => 'api.assets.store',
|
||||
'update' => 'api.assets.update',
|
||||
'destroy' => 'api.assets.destroy'
|
||||
],
|
||||
'except' => ['create', 'edit'],
|
||||
'parameters' => ['asset' => 'asset_id']
|
||||
]
|
||||
); // Hardware resource
|
||||
|
||||
|
||||
/*--- Imports API ---*/
|
||||
|
||||
Route::resource('imports', 'ImportController',
|
||||
[
|
||||
'names' =>
|
||||
[
|
||||
'index' => 'api.imports.index',
|
||||
'show' => 'api.imports.show',
|
||||
'store' => 'api.imports.store',
|
||||
'update' => 'api.imports.update',
|
||||
'destroy' => 'api.imports.destroy'
|
||||
],
|
||||
'except' => ['create', 'edit'],
|
||||
'parameters' => ['import' => 'import_id']
|
||||
]
|
||||
); // Imports resource
|
||||
|
||||
Route::group(['prefix' => 'imports'], function () {
|
||||
|
||||
Route::post('process/{import}',
|
||||
[
|
||||
'as' => 'api.imports.importFile',
|
||||
'uses'=> 'ImportController@process'
|
||||
]
|
||||
);
|
||||
}); // Imports group
|
||||
|
||||
|
||||
|
||||
|
||||
/*--- Licenses API ---*/
|
||||
|
||||
Route::resource('licenses', 'LicensesController',
|
||||
[
|
||||
'names' =>
|
||||
[
|
||||
'index' => 'api.licenses.index',
|
||||
'show' => 'api.licenses.show',
|
||||
'store' => 'api.licenses.store',
|
||||
'update' => 'api.licenses.update',
|
||||
'destroy' => 'api.licenses.destroy'
|
||||
],
|
||||
'except' => ['create', 'edit'],
|
||||
'parameters' => ['license' => 'license_id']
|
||||
]
|
||||
); // Licenses resource
|
||||
|
||||
|
||||
/*--- Locations API ---*/
|
||||
|
||||
Route::resource('locations', 'LocationsController',
|
||||
[
|
||||
'names' =>
|
||||
[
|
||||
'index' => 'api.locations.index',
|
||||
'show' => 'api.locations.show',
|
||||
'store' => 'api.locations.store',
|
||||
'update' => 'api.locations.update',
|
||||
'destroy' => 'api.locations.destroy'
|
||||
],
|
||||
'except' => ['create', 'edit'],
|
||||
'parameters' => ['location' => 'location_id']
|
||||
]
|
||||
); // Locations resource
|
||||
|
||||
Route::group(['prefix' => 'locations'], function () {
|
||||
|
||||
Route::get('{location}/users',
|
||||
[
|
||||
'as'=>'api.locations.viewusers',
|
||||
'uses'=>'LocationsController@getDataViewUsers'
|
||||
]
|
||||
);
|
||||
|
||||
Route::get('{location}/assets',
|
||||
[
|
||||
'as'=>'api.locations.viewassets',
|
||||
'uses'=>'LocationsController@getDataViewAssets'
|
||||
]
|
||||
);
|
||||
|
||||
// Do we actually still need this, now that we have an API?
|
||||
Route::get('{location}/check',
|
||||
[
|
||||
'as' => 'api.locations.check',
|
||||
'uses' => 'LocationsController@show'
|
||||
]
|
||||
);
|
||||
}); // Locations group
|
||||
|
||||
|
||||
/*--- Manufacturers API ---*/
|
||||
|
||||
Route::resource('manufacturers', 'ManufacturersController',
|
||||
[
|
||||
'names' =>
|
||||
[
|
||||
'index' => 'api.manufacturers.index',
|
||||
'show' => 'api.manufacturers.show',
|
||||
'store' => 'api.manufacturers.store',
|
||||
'update' => 'api.manufacturers.update',
|
||||
'destroy' => 'api.manufacturers.destroy'
|
||||
],
|
||||
'except' => ['create', 'edit'],
|
||||
'parameters' => ['manufacturer' => 'manufacturer_id']
|
||||
]
|
||||
); // Manufacturers resource
|
||||
|
||||
|
||||
/*--- Models API ---*/
|
||||
|
||||
Route::resource('models', 'AssetModelsController',
|
||||
[
|
||||
'names' =>
|
||||
[
|
||||
'index' => 'api.models.index',
|
||||
'show' => 'api.models.show',
|
||||
'store' => 'api.models.store',
|
||||
'update' => 'api.models.update',
|
||||
'destroy' => 'api.models.destroy'
|
||||
],
|
||||
'except' => ['create', 'edit'],
|
||||
'parameters' => ['model' => 'model_id']
|
||||
]
|
||||
); // Models resource
|
||||
|
||||
Route::group(['prefix' => 'models'], function () {
|
||||
|
||||
Route::get('assets',
|
||||
[
|
||||
'as' => 'api.models.assets',
|
||||
'uses'=> 'AssetModelsController@assets'
|
||||
]
|
||||
);
|
||||
}); // Models group
|
||||
|
||||
|
||||
/*--- Settings API ---*/
|
||||
|
||||
Route::resource('settings', 'SettingsController',
|
||||
[
|
||||
'names' =>
|
||||
[
|
||||
'index' => 'api.settings.index',
|
||||
'store' => 'api.settings.store',
|
||||
'show' => 'api.settings.show',
|
||||
'update' => 'api.settings.update'
|
||||
],
|
||||
'except' => ['create', 'edit', 'destroy'],
|
||||
'parameters' => ['setting' => 'setting_id']
|
||||
]
|
||||
); // Settings resource
|
||||
|
||||
|
||||
/*--- Status Labels API ---*/
|
||||
|
||||
Route::resource('statuslabels', 'StatuslabelsController',
|
||||
[
|
||||
'names' =>
|
||||
[
|
||||
'index' => 'api.statuslabels.index',
|
||||
'store' => 'api.statuslabels.store',
|
||||
'show' => 'api.statuslabels.show',
|
||||
'update' => 'api.statuslabels.update',
|
||||
'destroy' => 'api.statuslabels.destroy'
|
||||
],
|
||||
'except' => ['create', 'edit'],
|
||||
'parameters' => ['statuslabel' => 'statuslabel_id']
|
||||
]
|
||||
);
|
||||
|
||||
Route::group(['prefix' => 'statuslabels'], function () {
|
||||
|
||||
|
||||
|
||||
/*---Hardware API---*/
|
||||
|
||||
Route::match(['DELETE'], 'hardware/{id}', ['uses' => 'AssetsController@destroy','as' => 'api.assets.destroy']);
|
||||
|
||||
|
||||
Route::resource('hardware', 'AssetsController',
|
||||
['names' =>
|
||||
Route::get('{statuslabel}/assetlist',
|
||||
[
|
||||
'index' => 'api.assets.index',
|
||||
'create' => 'api.assets.create',
|
||||
'destroy' => 'api.assets.destroy'
|
||||
],
|
||||
'parameters' =>
|
||||
['asset' => 'asset_id']
|
||||
]);
|
||||
|
||||
|
||||
/*---Locations API---*/
|
||||
Route::group(array('prefix'=>'locations'), function () {
|
||||
|
||||
Route::get('{locationID}/users', array('as'=>'api.locations.viewusers', 'uses'=>'LocationsController@getDataViewUsers'));
|
||||
Route::get('{locationID}/assets', array('as'=>'api.locations.viewassets', 'uses'=>'LocationsController@getDataViewAssets'));
|
||||
|
||||
// Do we actually still need this, now that we have an API?
|
||||
Route::get('{id}/check',
|
||||
[ 'as' => 'api.locations.check', 'uses' => 'LocationsController@show' ]);
|
||||
|
||||
});
|
||||
|
||||
|
||||
/*---Suppliers API---*/
|
||||
Route::group(array('prefix'=>'suppliers'), function () {
|
||||
Route::get('list', array('as'=>'api.suppliers.list', 'uses'=>'SuppliersController@getDatatable'));
|
||||
});
|
||||
|
||||
/*---Users API---*/
|
||||
Route::group([ 'prefix' => 'users' ], function () {
|
||||
Route::post('/', [ 'as' => 'api.users.store', 'uses' => 'UsersController@store' ]);
|
||||
Route::post('two_factor_reset', [ 'as' => 'api.users.two_factor_reset', 'uses' => 'UsersController@postTwoFactorReset' ]);
|
||||
Route::get('list/{status?}', [ 'as' => 'api.users.list', 'uses' => 'UsersController@getDatatable' ]);
|
||||
Route::get('{userId}/assets', [ 'as' => 'api.users.assetlist', 'uses' => 'UsersController@getAssetList' ]);
|
||||
Route::post('{userId}/upload', [ 'as' => 'upload/user', 'uses' => 'UsersController@postUpload' ]);
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
Route::group([ 'prefix' => 'fields' ], function () {
|
||||
|
||||
Route::post(
|
||||
'fieldsets/{id}/order',
|
||||
[ 'as' => 'api.customfields.order', 'uses' => 'CustomFieldsController@postReorder' ]
|
||||
'as' => 'api.statuslabels.assets',
|
||||
'uses' => 'StatuslabelsController@assets'
|
||||
]
|
||||
);
|
||||
|
||||
Route::get('{statuslabel}/deployable',
|
||||
[
|
||||
'as' => 'api.statuslabels.deployable',
|
||||
'uses' => 'StatuslabelsController@checkIfDeployable'
|
||||
]
|
||||
);
|
||||
|
||||
// Pie chart for dashboard
|
||||
Route::get('assets',
|
||||
[
|
||||
'as' => 'api.statuslabels.assets.bytype',
|
||||
'uses' => 'StatuslabelsController@getAssetCountByStatuslabel'
|
||||
]
|
||||
);
|
||||
}); // Status labels group
|
||||
|
||||
|
||||
/*--- Suppliers API ---*/
|
||||
|
||||
Route::resource('suppliers', 'SuppliersController',
|
||||
[
|
||||
'names' =>
|
||||
[
|
||||
'index' => 'api.suppliers.index',
|
||||
'show' => 'api.suppliers.show',
|
||||
'store' => 'api.suppliers.store',
|
||||
'update' => 'api.suppliers.update',
|
||||
'destroy' => 'api.suppliers.destroy'
|
||||
],
|
||||
'except' => ['create', 'edit'],
|
||||
'parameters' => ['supplier' => 'supplier_id']
|
||||
]
|
||||
); // Suppliers resource
|
||||
|
||||
Route::group(['prefix' => 'suppliers'], function () {
|
||||
|
||||
Route::get('list',
|
||||
[
|
||||
'as'=>'api.suppliers.list',
|
||||
'uses'=>'SuppliersController@getDatatable'
|
||||
]
|
||||
);
|
||||
}); // Suppliers group
|
||||
|
||||
|
||||
/*--- Users API ---*/
|
||||
|
||||
Route::resource('users', 'UsersController',
|
||||
[
|
||||
'names' =>
|
||||
[
|
||||
'index' => 'api.users.index',
|
||||
'show' => 'api.users.show',
|
||||
'store' => 'api.users.store',
|
||||
'update' => 'api.users.update',
|
||||
'destroy' => 'api.users.destroy'
|
||||
],
|
||||
'except' => ['create', 'edit'],
|
||||
'parameters' => ['user' => 'user_id']
|
||||
]
|
||||
); // Users resource
|
||||
|
||||
Route::group([ 'prefix' => 'users' ], function () {
|
||||
|
||||
Route::post('two_factor_reset',
|
||||
[
|
||||
'as' => 'api.users.two_factor_reset',
|
||||
'uses' => 'UsersController@postTwoFactorReset'
|
||||
]
|
||||
);
|
||||
|
||||
Route::get('list/{status?}',
|
||||
[
|
||||
'as' => 'api.users.list',
|
||||
'uses' => 'UsersController@getDatatable'
|
||||
]
|
||||
);
|
||||
|
||||
Route::get('{user}/assets',
|
||||
[
|
||||
'as' => 'api.users.assetlist',
|
||||
'uses' => 'UsersController@getAssetList'
|
||||
]
|
||||
);
|
||||
|
||||
Route::post('{user}/upload',
|
||||
[
|
||||
'as' => 'api.users.uploads',
|
||||
'uses' => 'UsersController@postUpload'
|
||||
]
|
||||
);
|
||||
}); // Users group
|
||||
|
||||
|
||||
### DEBUG ROUTES ###
|
||||
|
||||
Route::group(['prefix' => 'me'], function () {
|
||||
|
||||
if (env('APP_ENV') == 'production') {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
Route::get('/profile', function () {
|
||||
return json_encode([
|
||||
'name' => \Auth::user()->first_name . ' ' . \Auth::user()->last_name,
|
||||
'email' => \Auth::user()->email,
|
||||
]);
|
||||
});
|
||||
|
||||
Route::get('/authenticated', function () {
|
||||
return json_encode([
|
||||
'authenticated' => \Auth::check()
|
||||
]);
|
||||
});
|
||||
|
||||
Route::get('/permissions/{scope}/{action}', function ($scope, $action) {
|
||||
return json_encode([
|
||||
'permission' => $scope . '.' . $action,
|
||||
'authorized' => \Auth::user()->hasAccess($scope . '.' . $action),
|
||||
]);
|
||||
});
|
||||
|
||||
Route::get('/permissions', function () {
|
||||
return json_encode([
|
||||
'permissions' => Auth::user()->permissions
|
||||
]);
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -24,23 +24,23 @@ class ApiTester extends \Codeception\Actor
|
|||
* Define custom actions here
|
||||
*/
|
||||
|
||||
public function getToken(\App\Models\User $user)
|
||||
{
|
||||
$client_repository = new \Laravel\Passport\ClientRepository();
|
||||
$client = $client_repository->createPersonalAccessClient($user->id, 'Codeception API Test Client',
|
||||
public function getToken(\App\Models\User $user)
|
||||
{
|
||||
$client_repository = new \Laravel\Passport\ClientRepository();
|
||||
$client = $client_repository->createPersonalAccessClient($user->id, 'Codeception API Test Client',
|
||||
'http://localhost/');
|
||||
|
||||
\Illuminate\Support\Facades\DB::table('oauth_personal_access_clients')->insert([
|
||||
\Illuminate\Support\Facades\DB::table('oauth_personal_access_clients')->insert([
|
||||
'client_id' => $client->id,
|
||||
'created_at' => new DateTime,
|
||||
'updated_at' => new DateTime,
|
||||
]);
|
||||
]);
|
||||
|
||||
$user->permissions = json_encode(['superuser' => true]);
|
||||
$user->save();
|
||||
$user->permissions = json_encode(['superuser' => true]);
|
||||
$user->save();
|
||||
|
||||
$token = $user->createToken('CodeceptionAPItestToken')->accessToken;
|
||||
$token = $user->createToken('CodeceptionAPItestToken')->accessToken;
|
||||
|
||||
return $token;
|
||||
}
|
||||
return $token;
|
||||
}
|
||||
}
|
||||
|
|
210
tests/api/ApiAssetsCest.php
Normal file
210
tests/api/ApiAssetsCest.php
Normal file
|
@ -0,0 +1,210 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class ApiAssetsCest
|
||||
{
|
||||
protected $faker;
|
||||
protected $user;
|
||||
|
||||
public function _before(ApiTester $I)
|
||||
{
|
||||
$this->faker = \Faker\Factory::create();
|
||||
$this->user = \App\Models\User::find(1);
|
||||
|
||||
$I->amBearerAuthenticated($I->getToken($this->user));
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function indexAssets(ApiTester $I)
|
||||
{
|
||||
$I->wantTo('Get a list of assets');
|
||||
|
||||
// setup
|
||||
$assets = factory(\App\Models\Asset::class, 'asset', 10)->create([
|
||||
'user_id' => $this->user->id,
|
||||
]);
|
||||
|
||||
// call
|
||||
$I->sendGET('/hardware');
|
||||
$I->seeResponseIsJson();
|
||||
$I->seeResponseCodeIs(200);
|
||||
|
||||
$response = json_decode($I->grabResponse());
|
||||
|
||||
// sample verify
|
||||
$asset = $assets->random();
|
||||
|
||||
$I->seeResponseContainsJson([
|
||||
'id' => $asset->id,
|
||||
'name' => e($asset->name),
|
||||
'asset_tag' => $asset->asset_tag,
|
||||
'serial' => $asset->serial,
|
||||
'model' => [
|
||||
'id' => $asset->model_id,
|
||||
'name' => e($asset->model->name),
|
||||
],
|
||||
// TODO: model_label
|
||||
'last_checkout' => $asset->last_checkout,
|
||||
// TODO: category [id, name]
|
||||
// TODO: manufacturer [id, name]
|
||||
'notes' => $asset->notes,
|
||||
'expected_checkin' => $asset->expected_checkin,
|
||||
'order_number' => $asset->order_number,
|
||||
'company' => [
|
||||
'id' => $asset->company->id,
|
||||
'name' => $asset->company->name,
|
||||
],
|
||||
// TODO: location [id, name]
|
||||
// TODO: rtd_location [id, name]
|
||||
'image' => $asset->image,
|
||||
'assigned_to' => $asset->assigned_to,
|
||||
'warranty' => $asset->warranty,
|
||||
'warranty_expires' => $asset->warranty_expires,
|
||||
// TODO: created_at
|
||||
'purchase_date' => $asset->purchase_date->format('Y-m-d'),
|
||||
'purchase_cost' => \App\Helpers\Helper::formatCurrencyOutput($asset->purchase_cost),
|
||||
// TODO: can_checkout
|
||||
// TODO: available actions
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function createAsset(ApiTester $I, $scenario)
|
||||
{
|
||||
$I->wantTo('Create a new asset');
|
||||
|
||||
$temp_asset = factory(\App\Models\Asset::class, 'asset')->make();
|
||||
|
||||
// setup
|
||||
$data = [
|
||||
'asset_tag' => $temp_asset->tag,
|
||||
'assigned_to' => $temp_asset->assigned_to,
|
||||
'company_id' => $temp_asset->company->id,
|
||||
'image' => $temp_asset->image,
|
||||
'model_id' => $temp_asset->model_id,
|
||||
'name' => $temp_asset->name,
|
||||
'notes' => $temp_asset->notes,
|
||||
'purchase_cost' => $temp_asset->purchase_cost,
|
||||
'purchase_date' => $temp_asset->purchase_date,
|
||||
'rtd_location_id' => $temp_asset->rtd_location_id,
|
||||
'serial' => $temp_asset->serial,
|
||||
'status_id' => $temp_asset->status_id,
|
||||
'supplier_id' => $temp_asset->supplier_id,
|
||||
'warranty_months' => $temp_asset->warranty_months,
|
||||
];
|
||||
|
||||
$scenario->incomplete('When I POST to /hardware i am redirected to html login page 😰');
|
||||
// create
|
||||
$I->sendPOST('/hardware', $data);
|
||||
$I->seeResponseIsJson();
|
||||
$I->seeResponseCodeIs(200);
|
||||
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function updateAssetWithPatch(ApiTester $I, $scenario)
|
||||
{
|
||||
$I->wantTo('Update an asset with PATCH');
|
||||
|
||||
// create and store an asset
|
||||
$asset = factory(\App\Models\Asset::class, 'asset')->create();
|
||||
$I->assertInstanceOf(\App\Models\Asset::class, $asset);
|
||||
|
||||
// create a temporary asset to grab new data
|
||||
$temp_asset = factory(\App\Models\Asset::class, 'asset')->make();
|
||||
$data = [
|
||||
'asset_tag' => $temp_asset->tag,
|
||||
'assigned_to' => $temp_asset->assigned_to,
|
||||
'company_id' => $temp_asset->company->id,
|
||||
'image' => $temp_asset->image,
|
||||
'model_id' => $temp_asset->model_id,
|
||||
'name' => $temp_asset->name,
|
||||
'notes' => $temp_asset->notes,
|
||||
'purchase_cost' => $temp_asset->purchase_cost,
|
||||
'purchase_date' => $temp_asset->purchase_date->format('Y-m-d'),
|
||||
'rtd_location_id' => $temp_asset->rtd_location_id,
|
||||
'serial' => $temp_asset->serial,
|
||||
'status_id' => $temp_asset->status_id,
|
||||
'supplier_id' => $temp_asset->supplier_id,
|
||||
'warranty_months' => $temp_asset->warranty_months,
|
||||
];
|
||||
|
||||
// the asset name should be different
|
||||
$I->assertNotEquals($asset->name, $data['name']);
|
||||
|
||||
// update
|
||||
$I->sendPATCH('/hardware/' . $asset->id, $data);
|
||||
$I->seeResponseIsJson();
|
||||
$I->seeResponseCodeIs(200);
|
||||
|
||||
$response = json_decode($I->grabResponse());
|
||||
$I->assertEquals('success', $response->status);
|
||||
|
||||
// verify
|
||||
$scenario->incomplete('[BadMethodCallException] Call to undefined method Illuminate\Database\Query\Builder::detail() 🤔');
|
||||
$I->sendGET('/hardware/' . $asset->id);
|
||||
|
||||
$I->seeResponseIsJson();
|
||||
$I->seeResponseCodeIs(200);
|
||||
$I->seeResponseContainsJson([
|
||||
'name' => $data['name'],
|
||||
'id' => $asset->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
/* public function updateAssetWithPut(ApiTester $I)
|
||||
{
|
||||
$I->wantTo('Update a asset with PUT');
|
||||
|
||||
// create
|
||||
$asset = factory(\App\Models\Asset::class, 'asset')->create();
|
||||
$I->assertInstanceOf(\App\Models\Asset::class, $asset);
|
||||
|
||||
$data = [
|
||||
'name' => $this->faker->sentence(3),
|
||||
];
|
||||
|
||||
$I->assertNotEquals($asset->name, $data['name']);
|
||||
|
||||
// update
|
||||
$I->sendPUT('/hardware/' . $asset->id, $data);
|
||||
$I->seeResponseIsJson();
|
||||
$I->seeResponseCodeIs(200);
|
||||
|
||||
$response = json_decode($I->grabResponse());
|
||||
$I->assertEquals('success', $response->status);
|
||||
|
||||
// verify
|
||||
$I->sendGET('/hardware/' . $asset->id);
|
||||
$I->seeResponseIsJson();
|
||||
$I->seeResponseCodeIs(200);
|
||||
$I->seeResponseContainsJson([
|
||||
'name' => e($data['name']),
|
||||
'id' => e($asset->id),
|
||||
'qty' => e($asset->qty),
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
/* public function deleteAssetTest(ApiTester $I, $scenario)
|
||||
{
|
||||
$I->wantTo('Delete an asset');
|
||||
|
||||
// create
|
||||
$asset = factory(\App\Models\Asset::class, 'asset')->create();
|
||||
$I->assertInstanceOf(\App\Models\Asset::class, $asset);
|
||||
|
||||
// delete
|
||||
$I->sendDELETE('/hardware/' . $asset->id);
|
||||
$I->seeResponseIsJson();
|
||||
$I->seeResponseCodeIs(200);
|
||||
|
||||
// verify, expect a 404
|
||||
$I->sendGET('/hardware/' . $asset->id);
|
||||
$I->seeResponseCodeIs(404);
|
||||
// $I->seeResponseIsJson(); // @todo: response is not JSON
|
||||
$scenario->incomplete('404 response should be JSON, receiving HTML instead');
|
||||
} // */
|
||||
}
|
|
@ -18,10 +18,11 @@ class ApiComponentsAssetsCest
|
|||
{
|
||||
$I->wantTo('Get a list of assets related to a component');
|
||||
|
||||
// generate
|
||||
// generate component
|
||||
$component = factory(\App\Models\Component::class, 'component')
|
||||
->create(['user_id' => $this->user->id, 'qty' => 20]);
|
||||
|
||||
// generate assets and associate component
|
||||
$assets = factory(\App\Models\Asset::class, 'asset', 2)
|
||||
->create(['user_id' => $this->user->id])
|
||||
->each(function ($asset) use ($component) {
|
||||
|
@ -34,12 +35,14 @@ class ApiComponentsAssetsCest
|
|||
]);
|
||||
});
|
||||
|
||||
// verify
|
||||
$I->sendGET('/components/' . $component->id . '/assets/');
|
||||
$I->seeResponseIsJson();
|
||||
$I->seeResponseCodeIs(200);
|
||||
$response = json_decode($I->grabResponse());
|
||||
|
||||
$response = json_decode($I->grabResponse());
|
||||
$I->assertEquals(2, $response->total);
|
||||
|
||||
$I->assertInstanceOf(\Illuminate\Database\Eloquent\Collection::class, $assets);
|
||||
|
||||
$I->seeResponseContainsJson(['rows' => [
|
||||
|
@ -56,4 +59,22 @@ class ApiComponentsAssetsCest
|
|||
]
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function expectEmptyResponseWithoutAssociatedAssets(ApiTester $I, $scenario)
|
||||
{
|
||||
$I->wantTo('See an empty response when there are no associated assets to a component');
|
||||
|
||||
$component = factory(\App\Models\Component::class, 'component')
|
||||
->create(['user_id' => $this->user->id, 'qty' => 20]);
|
||||
|
||||
$I->sendGET('/components/' . $component->id . '/assets');
|
||||
$I->seeResponseCodeIs(200);
|
||||
$I->seeResponseIsJson();
|
||||
|
||||
$response = json_decode($I->grabResponse());
|
||||
$I->assertEquals(0, $response->total);
|
||||
$I->assertEquals([], $response->rows);
|
||||
$I->seeResponseContainsJson(['total' => 0, 'rows' => []]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ class ApiComponentsCest
|
|||
$I->wantTo('Get a list of components');
|
||||
|
||||
// setup
|
||||
$components = factory(\App\Models\Component::class, 'component', 10)->create(['user_id' => $this->user->id]);
|
||||
$components = factory(\App\Models\Component::class, 'component', 10)->create();
|
||||
|
||||
// call
|
||||
$I->sendGET('/components');
|
||||
|
@ -34,6 +34,10 @@ class ApiComponentsCest
|
|||
'name' => $component->name,
|
||||
'qty' => $component->qty,
|
||||
]);
|
||||
|
||||
$I->seeResponseContainsJson([
|
||||
'total' => \App\Models\Component::count(),
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
|
@ -74,19 +78,19 @@ class ApiComponentsCest
|
|||
'id' => $id,
|
||||
'category' => [
|
||||
'id' => $data['category_id'],
|
||||
'name' => $category->name,
|
||||
'name' => e($category->name),
|
||||
],
|
||||
'company' => [
|
||||
'id' => $data['company_id'],
|
||||
'name' => $company->name,
|
||||
'name' => e($company->name),
|
||||
],
|
||||
'location' => [
|
||||
'id' => $data['location_id'],
|
||||
'name' => $location->name,
|
||||
'name' => e($location->name),
|
||||
],
|
||||
'name' => $data['name'],
|
||||
'qty' => $data['qty'],
|
||||
'purchase_cost' => $data['purchase_cost'],
|
||||
'purchase_cost' => \App\Helpers\Helper::formatCurrencyOutput($data['purchase_cost']),
|
||||
'purchase_date' => $data['purchase_date'],
|
||||
]);
|
||||
}
|
||||
|
@ -161,7 +165,7 @@ class ApiComponentsCest
|
|||
}
|
||||
|
||||
/** @test */
|
||||
public function deleteComponentTest(ApiTester $I)
|
||||
public function deleteComponentTest(ApiTester $I, $scenario)
|
||||
{
|
||||
$I->wantTo('Delete a component');
|
||||
|
||||
|
@ -178,5 +182,6 @@ class ApiComponentsCest
|
|||
$I->sendGET('/components/' . $component->id);
|
||||
$I->seeResponseCodeIs(404);
|
||||
// $I->seeResponseIsJson(); // @todo: response is not JSON
|
||||
$scenario->incomplete('404 response should be JSON, receiving HTML instead');
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue