* Use the formated date helper to clean up verifications.

* Add Checkin/Checkout api tests.

* Accessories api test

* Add Companies API Test.

* Return ModelNotFound as a 404.

* Cleanups/simplficiations/updates.

* Locations api test.

* currency and image should be fillable on location.

* Update components api test.

* Use findOrFail so we return a 404 instead of a 200.  Matches other item types.

* order_number should be fillable in component.

* Add updated_at and permissions to information returned from api for a user.

* Add users test and flesh out factory and fillable fields.

* Add test for assets method

* API status label test.

* Disable php7.2 for now on travis until the count(null) issues are remedied

* Add serial to update.

* API model not found should return a 200
This commit is contained in:
Daniel Meltzer 2018-02-24 22:01:34 -05:00 committed by snipe
parent b6a75093b7
commit 7de8f71f58
20 changed files with 1226 additions and 477 deletions

View file

@ -16,7 +16,7 @@ services:
php: php:
- 5.6 - 5.6
- 7.0 - 7.0
- 7.2 # - 7.2 DISABLE Temporarily until we fix the count(null) bugs
- 7.1.4 - 7.1.4
# execute any number of scripts before the test run, custom env's are available as variables # execute any number of scripts before the test run, custom env's are available as variables

View file

@ -93,13 +93,11 @@ class ComponentsController extends Controller
public function show($id) public function show($id)
{ {
$this->authorize('view', Component::class); $this->authorize('view', Component::class);
$component = Component::find($id); $component = Component::findOrFail($id);
if ($component) { if ($component) {
return (new ComponentsTransformer)->transformComponent($component); return (new ComponentsTransformer)->transformComponent($component);
} }
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/components/message.does_not_exist')));
} }

View file

@ -56,7 +56,7 @@ class StatuslabelsController extends Controller
$request->except('deployable', 'pending','archived'); $request->except('deployable', 'pending','archived');
if (!$request->has('type')) { if (!$request->has('type')) {
return response()->json(Helper::formatStandardApiResponse('error', null, ["type" => ["Status label type is required."]])); return response()->json(Helper::formatStandardApiResponse('error', null, ["type" => ["Status label type is required."]]),500);
} }
$statuslabel = new Statuslabel; $statuslabel = new Statuslabel;

View file

@ -28,30 +28,32 @@ class UsersController extends Controller
$this->authorize('view', User::class); $this->authorize('view', User::class);
$users = User::select([ $users = User::select([
'users.id', 'users.activated',
'users.employee_num',
'users.two_factor_enrolled',
'users.jobtitle',
'users.email',
'users.phone',
'users.address', 'users.address',
'users.avatar',
'users.city', 'users.city',
'users.state',
'users.country',
'users.zip',
'users.username',
'users.location_id',
'users.manager_id',
'users.first_name',
'users.last_name',
'users.created_at',
'users.notes',
'users.company_id', 'users.company_id',
'users.last_login', 'users.country',
'users.created_at',
'users.deleted_at', 'users.deleted_at',
'users.department_id', 'users.department_id',
'users.activated', 'users.email',
'users.avatar', 'users.employee_num',
'users.first_name',
'users.id',
'users.jobtitle',
'users.last_login',
'users.last_name',
'users.location_id',
'users.manager_id',
'users.notes',
'users.permissions',
'users.phone',
'users.state',
'users.two_factor_enrolled',
'users.updated_at',
'users.username',
'users.zip',
])->with('manager', 'groups', 'userloc', 'company', 'department','assets','licenses','accessories','consumables') ])->with('manager', 'groups', 'userloc', 'company', 'department','assets','licenses','accessories','consumables')
->withCount('assets','licenses','accessories','consumables'); ->withCount('assets','licenses','accessories','consumables');
@ -69,7 +71,7 @@ class UsersController extends Controller
if ($request->has('location_id')) { if ($request->has('location_id')) {
$users = $users->where('users.location_id', '=', $request->input('location_id')); $users = $users->where('users.location_id', '=', $request->input('location_id'));
} }
if ($request->has('group_id')) { if ($request->has('group_id')) {
$users = $users->ByGroup($request->get('group_id')); $users = $users->ByGroup($request->get('group_id'));
} }

View file

@ -32,7 +32,7 @@ class AccessoriesTransformer
'notes' => ($accessory->notes) ? e($accessory->notes) : null, 'notes' => ($accessory->notes) ? e($accessory->notes) : null,
'qty' => ($accessory->qty) ? (int) $accessory->qty : null, 'qty' => ($accessory->qty) ? (int) $accessory->qty : null,
'purchase_date' => ($accessory->purchase_date) ? Helper::getFormattedDateObject($accessory->purchase_date, 'date') : null, 'purchase_date' => ($accessory->purchase_date) ? Helper::getFormattedDateObject($accessory->purchase_date, 'date') : null,
'purchase_cost' => ($accessory->purchase_cost) ? e($accessory->purchase_cost) : null, 'purchase_cost' => Helper::formatCurrencyOutput($accessory->purchase_cost),
'order_number' => ($accessory->order_number) ? e($accessory->order_number) : null, 'order_number' => ($accessory->order_number) ? e($accessory->order_number) : null,
'min_qty' => ($accessory->min_amt) ? (int) $accessory->min_amt : null, 'min_qty' => ($accessory->min_amt) ? (int) $accessory->min_amt : null,
'remaining_qty' => $accessory->numRemaining(), 'remaining_qty' => $accessory->numRemaining(),

View file

@ -54,8 +54,9 @@ class Component extends SnipeModel
'purchase_cost', 'purchase_cost',
'purchase_date', 'purchase_date',
'min_amt', 'min_amt',
'order_number',
'qty', 'qty',
'serial' 'serial',
]; ];
public function location() public function location()

View file

@ -50,10 +50,12 @@ class Consumable extends SnipeModel
protected $fillable = [ protected $fillable = [
'category_id', 'category_id',
'company_id', 'company_id',
'item_no',
'location_id', 'location_id',
'manufacturer_id', 'manufacturer_id',
'name', 'name',
'order_number', 'order_number',
'model_number',
'purchase_cost', 'purchase_cost',
'purchase_date', 'purchase_date',
'qty', 'qty',

View file

@ -45,7 +45,19 @@ class Location extends SnipeModel
* *
* @var array * @var array
*/ */
protected $fillable = ['name','parent_id','address','address2','city','state', 'country','zip','ldap_ou']; protected $fillable = [
'name',
'parent_id',
'address',
'address2',
'city',
'state',
'country',
'zip',
'ldap_ou',
'currency',
'image',
];
protected $hidden = ['user_id']; protected $hidden = ['user_id'];
public function users() public function users()

View file

@ -27,7 +27,13 @@ class Statuslabel extends SnipeModel
'archived' => 'required', 'archived' => 'required',
); );
protected $fillable = ['name', 'deployable', 'pending', 'archived']; protected $fillable = [
'archived',
'deployable',
'name',
'notes',
'pending',
];
/** /**

View file

@ -28,24 +28,25 @@ class User extends SnipeModel implements AuthenticatableContract, CanResetPasswo
protected $table = 'users'; protected $table = 'users';
protected $injectUniqueIdentifier = true; protected $injectUniqueIdentifier = true;
protected $fillable = [ protected $fillable = [
'email', 'activated',
'last_name',
'company_id',
'department_id',
'employee_num',
'jobtitle',
'location_id',
'password',
'phone',
'username',
'first_name',
'address', 'address',
'city', 'city',
'state', 'company_id',
'country', 'country',
'zip', 'department_id',
'activated', 'email',
'employee_num',
'first_name',
'jobtitle',
'last_name',
'locale',
'location_id',
'manager_id', 'manager_id',
'password',
'phone',
'state',
'username',
'zip',
]; ];
protected $casts = [ protected $casts = [

View file

@ -6,21 +6,26 @@ $password = bcrypt('password');
$factory->define(App\Models\User::class, function (Faker\Generator $faker) use ($password) { $factory->define(App\Models\User::class, function (Faker\Generator $faker) use ($password) {
return [ return [
'activated' => 1,
'address' => $faker->address,
'city' => $faker->city,
'company_id' => rand(1,4),
'country' => $faker->country,
'department_id' => rand(1,6),
'email' => $faker->safeEmail,
'employee_num' => $faker->numberBetween(3500, 35050),
'first_name' => $faker->firstName, 'first_name' => $faker->firstName,
'jobtitle' => $faker->jobTitle,
'last_name' => $faker->lastName, 'last_name' => $faker->lastName,
'username' => $faker->username, 'locale' => $faker->locale,
'location_id' => rand(1,5),
'notes' => 'Created by DB seeder',
'password' => $password, 'password' => $password,
'permissions' => '{"user":"0"}', 'permissions' => '{"user":"0"}',
'email' => $faker->safeEmail,
'company_id' => rand(1,4),
'locale' => $faker->locale,
'employee_num' => $faker->numberBetween(3500, 35050),
'jobtitle' => $faker->jobTitle,
'department_id' => rand(1,6),
'phone' => $faker->phoneNumber, 'phone' => $faker->phoneNumber,
'notes' => 'Created by DB seeder', 'state' => $faker->stateAbbr,
'location_id' => rand(1,5), 'username' => $faker->username,
'activated' => 1, 'zip' => $faker->postcode
]; ];
}); });

View file

@ -0,0 +1,154 @@
<?php
use App\Helpers\Helper;
use App\Http\Transformers\AccessoriesTransformer;
use App\Models\Accessory;
use App\Models\Setting;
use Illuminate\Support\Facades\Auth;
class ApiAccessoriesCest
{
protected $user;
protected $timeFormat;
public function _before(ApiTester $I)
{
$this->user = \App\Models\User::find(1);
$I->haveHttpHeader('Accept', 'application/json');
$I->amBearerAuthenticated($I->getToken($this->user));
}
/** @test */
public function indexAccessories(ApiTester $I)
{
$I->wantTo('Get a list of accessories');
// call
$I->sendGET('/accessories?limit=10');
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
$response = json_decode($I->grabResponse(), true);
// sample verify
$accessory = App\Models\Accessory::orderByDesc('created_at')->take(10)->get()->shuffle()->first();
$I->seeResponseContainsJson((new AccessoriesTransformer)->transformAccessory($accessory));
}
/** @test */
public function createAccessory(ApiTester $I, $scenario)
{
$I->wantTo('Create a new accessory');
$temp_accessory = factory(\App\Models\Accessory::class)->states('apple-bt-keyboard')->make([
'name' => "Test Accessory Name",
'company_id' => 2
]);
// setup
$data = [
'category_id' => $temp_accessory->category_id,
'company_id' => $temp_accessory->company->id,
'location_id' => $temp_accessory->location_id,
'name' => $temp_accessory->name,
'order_number' => $temp_accessory->order_number,
'purchase_cost' => $temp_accessory->purchase_cost,
'purchase_date' => $temp_accessory->purchase_date,
'model_number' => $temp_accessory->model_number,
'manufacturer_id' => $temp_accessory->manufacturer_id,
'supplier_id' => $temp_accessory->supplier_id,
'qty' => $temp_accessory->qty,
];
// create
$I->sendPOST('/accessories', $data);
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
}
// Put is routed to the same method in the controller
// DO we actually need to test both?
/** @test */
public function updateAccessoryWithPatch(ApiTester $I, $scenario)
{
$I->wantTo('Update an accessory with PATCH');
// create
$accessory = factory(\App\Models\Accessory::class)->states('apple-bt-keyboard')->create([
'name' => 'Original Accessory Name',
'company_id' => 2,
'location_id' => 3
]);
$I->assertInstanceOf(\App\Models\Accessory::class, $accessory);
$temp_accessory = factory(\App\Models\Accessory::class)->states('microsoft-mouse')->make([
'company_id' => 3,
'name' => "updated accessory name",
'location_id' => 1,
]);
$data = [
'category_id' => $temp_accessory->category_id,
'company_id' => $temp_accessory->company->id,
'location_id' => $temp_accessory->location_id,
'name' => $temp_accessory->name,
'order_number' => $temp_accessory->order_number,
'purchase_cost' => $temp_accessory->purchase_cost,
'purchase_date' => $temp_accessory->purchase_date,
'model_number' => $temp_accessory->model_number,
'manufacturer_id' => $temp_accessory->manufacturer_id,
'supplier_id' => $temp_accessory->supplier_id,
'qty' => $temp_accessory->qty,
];
$I->assertNotEquals($accessory->name, $data['name']);
// update
$I->sendPATCH('/accessories/' . $accessory->id, $data);
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
$response = json_decode($I->grabResponse());
$I->assertEquals('success', $response->status);
$I->assertEquals(trans('admin/accessories/message.update.success'), $response->messages);
$I->assertEquals($accessory->id, $response->payload->id); // accessory id does not change
$I->assertEquals($temp_accessory->company_id, $response->payload->company_id); // company_id updated
$I->assertEquals($temp_accessory->name, $response->payload->name); // accessory name updated
$I->assertEquals($temp_accessory->location_id, $response->payload->location_id); // accessory location_id updated
$temp_accessory->created_at = Carbon::parse($response->payload->created_at);
$temp_accessory->updated_at = Carbon::parse($response->payload->updated_at);
$temp_accessory->id = $accessory->id;
// verify
$I->sendGET('/accessories/' . $accessory->id);
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
$I->seeResponseContainsJson((new AccessoriesTransformer)->transformAccessory($temp_accessory));
}
/** @test */
public function deleteAccessoryTest(ApiTester $I, $scenario)
{
$I->wantTo('Delete an accessory');
// create
$accessory = factory(\App\Models\Accessory::class)->states('apple-bt-keyboard')->create([
'name' => "Soon to be deleted"
]);
$I->assertInstanceOf(\App\Models\Accessory::class, $accessory);
// delete
$I->sendDELETE('/accessories/' . $accessory->id);
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
$response = json_decode($I->grabResponse());
$I->assertEquals('success', $response->status);
$I->assertEquals(trans('admin/accessories/message.delete.success'), $response->messages);
// verify, expect a 200
$I->sendGET('/accessories/' . $accessory->id);
$I->seeResponseCodeIs(200);
$I->seeResponseIsJson();
}
}

View file

@ -1,5 +1,8 @@
<?php <?php
use App\Helpers\Helper;
use App\Http\Transformers\AssetsTransformer;
use App\Models\Asset;
use App\Models\Setting; use App\Models\Setting;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
@ -11,10 +14,9 @@ class ApiAssetsCest
public function _before(ApiTester $I) public function _before(ApiTester $I)
{ {
// $I->setupDatabase();
$this->faker = \Faker\Factory::create(); $this->faker = \Faker\Factory::create();
$this->user = \App\Models\User::find(1); $this->user = \App\Models\User::find(1);
$this->timeFormat = Setting::getSettings()->date_display_format .' '. Setting::getSettings()->time_display_format; Setting::getSettings()->time_display_format = "H:i";
$I->amBearerAuthenticated($I->getToken($this->user)); $I->amBearerAuthenticated($I->getToken($this->user));
} }
@ -24,105 +26,15 @@ class ApiAssetsCest
$I->wantTo('Get a list of assets'); $I->wantTo('Get a list of assets');
// We rely on the seeded database for this. No need to create new assets.
// $assets = factory(\App\Models\Asset::class, 10)->create();
// call // call
$I->sendGET('/hardware?limit=10'); $I->sendGET('/hardware?limit=20&sort=id&order=desc');
$I->seeResponseIsJson(); $I->seeResponseIsJson();
$I->seeResponseCodeIs(200); $I->seeResponseCodeIs(200);
$response = json_decode($I->grabResponse(), true); $response = json_decode($I->grabResponse(), true);
// sample verify // sample verify
$asset = App\Models\Asset::orderByDesc('created_at')->first(); $asset = Asset::orderByDesc('id')->take(20)->get()->first();
$I->seeResponseContainsJson((new AssetsTransformer)->transformAsset($asset));
$I->seeResponseContainsJson([
'id' => (int) $asset->id,
'name' => e($asset->name),
'asset_tag' => e($asset->asset_tag),
'serial' => e($asset->serial),
'model' => ($asset->model) ? [
'id' => (int) $asset->model->id,
'name'=> e($asset->model->name)
] : null,
'model_number' => ($asset->model) ? e($asset->model->model_number) : null,
'status_label' => ($asset->assetstatus) ? [
'id' => (int) $asset->assetstatus->id,
'name'=> e($asset->assetstatus->name)
] : null,
'category' => ($asset->model->category) ? [
'id' => (int) $asset->model->category->id,
'name'=> e($asset->model->category->name)
] : null,
'manufacturer' => ($asset->model->manufacturer) ? [
'id' => (int) $asset->model->manufacturer->id,
'name'=> e($asset->model->manufacturer->name)
] : null,
'supplier' => ($asset->supplier) ? [
'id' => (int) $asset->supplier->id,
'name'=> e($asset->supplier->name)
] : null,
'notes' => e($asset->notes),
'order_number' => e($asset->order_number),
'company' => ($asset->company) ? [
'id' => (int) $asset->company->id,
'name'=> e($asset->company->name)
] : null,
'location' => ($asset->location) ? [
'id' => (int) $asset->location->id,
'name'=> e($asset->location->name)
] : null,
'rtd_location' => ($asset->defaultLoc) ? [
'id' => (int) $asset->defaultLoc->id,
'name'=> e($asset->defaultLoc->name)
] : null,
'image' => ($asset->getImageUrl()) ? $asset->getImageUrl() : null,
'assigned_to' => ($asset->assigneduser) ? [
'id' => (int) $asset->assigneduser->id,
'name' => e($asset->assigneduser->getFullNameAttribute()),
'first_name'=> e($asset->assigneduser->first_name),
'last_name'=> e($asset->assigneduser->last_name)
] : null,
'warranty_months' => ($asset->warranty_months > 0) ? e($asset->warranty_months . ' ' . trans('admin/hardware/form.months')) : null,
'warranty_expires' => ($asset->warranty_months > 0) ? [
'datetime' => $asset->created_at->format('Y-m-d'),
'formatted' => $asset->created_at->format('Y-m-d'),
] : null,
// I have no idea why these cause the test to fail. I think it's something about nested json.
// 'created_at' => ($asset->created_at) ? [
// 'datetime' => $asset->created_at->format('Y-m-d H:i:s'),
// 'formatted' => $asset->created_at->format('Y-m-d H:i a'),
// ] : null,
// 'updated_at' => ($asset->updated_at) ? [
// 'datetime' => $asset->updated_at->format('Y-m-d H:i:s'),
// 'formatted' => $asset->updated_at->format('Y-m-d H:i a'),
// ] : null,
// // TODO: Implement last_audit_date and next_audit_date
// 'purchase_date' => ($asset->purchase_date) ? [
// 'datetime' => $asset->purchase_date->format('Y-m-d'),
// 'formatted' => $asset->purchase_date->format('Y-m-d'),
// ] : null,
// 'last_checkout' => ($asset->last_checkout) ? [
// 'datetime' => $asset->last_checkout->format('Y-m-d'),
// 'formatted' => $asset->last_checkout->format('Y-m-d'),
// ] : null,
// 'expected_checkin' => ($asset->created_at) ? [
// 'date' => $asset->created_at->format('Y-m-d'),
// 'formatted' => $asset->created_at->format('Y-m-d'),
// ] : null,
'purchase_cost' => (float) $asset->purchase_cost,
'user_can_checkout' => (bool) $asset->availableForCheckout(),
'available_actions' => [
'checkout' => (bool) Gate::allows('checkout', Asset::class),
'checkin' => (bool) Gate::allows('checkin', Asset::class),
'clone' => (bool) Gate::allows('create', Asset::class),
'restore' => (bool) false, // FIXME: when this gets implemented in assetstransformer it should be updated here
'update' => (bool) Gate::allows('update', Asset::class),
'delete' => (bool) Gate::allows('delete', Asset::class),
],
]);
} }
/** @test */ /** @test */
@ -185,6 +97,7 @@ class ApiAssetsCest
'model_id' => $temp_asset->model_id, 'model_id' => $temp_asset->model_id,
'name' => $temp_asset->name, 'name' => $temp_asset->name,
'notes' => $temp_asset->notes, 'notes' => $temp_asset->notes,
'order_number' => $temp_asset->order_number,
'purchase_cost' => $temp_asset->purchase_cost, 'purchase_cost' => $temp_asset->purchase_cost,
'purchase_date' => $temp_asset->purchase_date->format('Y-m-d'), 'purchase_date' => $temp_asset->purchase_date->format('Y-m-d'),
'rtd_location_id' => $temp_asset->rtd_location_id, 'rtd_location_id' => $temp_asset->rtd_location_id,
@ -202,227 +115,23 @@ class ApiAssetsCest
$I->seeResponseCodeIs(200); $I->seeResponseCodeIs(200);
$response = json_decode($I->grabResponse()); $response = json_decode($I->grabResponse());
// dd($response);
$I->assertEquals('success', $response->status); $I->assertEquals('success', $response->status);
$I->assertEquals(trans('admin/hardware/message.update.success'), $response->messages); $I->assertEquals(trans('admin/hardware/message.update.success'), $response->messages);
$I->assertEquals($asset->id, $response->payload->id); // asset id does not change $I->assertEquals($asset->id, $response->payload->id); // asset id does not change
$I->assertEquals($temp_asset->asset_tag, $response->payload->asset_tag); // asset tag updated $I->assertEquals($temp_asset->asset_tag, $response->payload->asset_tag); // asset tag updated
$I->assertEquals($temp_asset->name, $response->payload->name); // asset name updated $I->assertEquals($temp_asset->name, $response->payload->name); // asset name updated
$I->assertEquals($temp_asset->rtd_location_id, $response->payload->rtd_location_id); // asset rtd_location_id updated $I->assertEquals($temp_asset->rtd_location_id, $response->payload->rtd_location_id); // asset rtd_location_id updated
$temp_asset->created_at = Carbon::parse($response->payload->created_at);
// verify $temp_asset->updated_at = Carbon::parse($response->payload->updated_at);
$I->sendGET('/hardware/' . $asset->id); $temp_asset->id = $asset->id;
// dd($I->grabResponse()); $temp_asset->location_id = $response->payload->rtd_location_id;
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
$I->seeResponseContainsJson([
'id' => (int) $asset->id,
'name' => e($temp_asset->name),
'asset_tag' => e($temp_asset->asset_tag),
'serial' => e($temp_asset->serial),
'model' => ($temp_asset->model) ? [
'id' => (int) $temp_asset->model->id,
'name'=> e($temp_asset->model->name)
] : null,
'model_number' => ($temp_asset->model) ? e($temp_asset->model->model_number) : null,
'status_label' => ($temp_asset->assetstatus) ? [
'id' => (int) $temp_asset->assetstatus->id,
'name'=> e($temp_asset->assetstatus->name),
'status_type' => $temp_asset->assetstatus->getStatuslabelType(),
'status_meta' => $temp_asset->present()->statusMeta
] : null,
'category' => ($temp_asset->model->category) ? [
'id' => (int) $temp_asset->model->category->id,
'name'=> e($temp_asset->model->category->name)
] : null,
'manufacturer' => ($temp_asset->model->manufacturer) ? [
'id' => (int) $temp_asset->model->manufacturer->id,
'name'=> e($temp_asset->model->manufacturer->name)
] : null,
'notes' => e($temp_asset->notes),
'order_number' => e($asset->order_number),
'company' => ($asset->company) ? [
'id' => (int) $temp_asset->company->id,
'name'=> e($temp_asset->company->name)
] : null,
'rtd_location' => ($temp_asset->defaultLoc) ? [
'id' => (int) $temp_asset->defaultLoc->id,
'name'=> e($temp_asset->defaultLoc->name)
] : null,
'image' => ($temp_asset->getImageUrl()) ? $temp_asset->getImageUrl() : null,
'assigned_to' => ($temp_asset->assigneduser) ? [
'id' => (int) $temp_asset->assigneduser->id,
'name' => e($temp_asset->assigneduser->getFullNameAttribute()),
'first_name'=> e($temp_asset->assigneduser->first_name),
'last_name'=> e($temp_asset->assigneduser->last_name)
] : null,
'warranty_months' => ($asset->warranty_months > 0) ? e($asset->warranty_months . ' ' . trans('admin/hardware/form.months')) : null,
'warranty_expires' => ($asset->warranty_months > 0) ? [
'datetime' => $asset->created_at->format('Y-m-d'),
'formatted' => $asset->created_at->format('Y-m-d'),
] : null,
// 'created_at' => ($asset->created_at) ? [
// 'datetime' => $asset->created_at->format('Y-m-d H:i:s'),
// 'formatted' => $asset->created_at->format($this->timeFormat),
// ] : null,
// 'updated_at' => ($asset->updated_at) ? [
// 'datetime' => $asset->updated_at->format('Y-m-d H:i:s'),
// 'formatted' => $asset->updated_at->format($this->timeFormat),
// ] : null,
'purchase_date' => ($asset->purchase_date) ? [
'date' => $temp_asset->purchase_date->format('Y-m-d'),
'formatted' => $temp_asset->purchase_date->format('Y-m-d'),
] : null,
// 'last_checkout' => ($asset->last_checkout) ? [
// 'datetime' => $asset->last_checkout->format('Y-m-d'),
// 'formatted' => $asset->last_checkout->format('Y-m-d'),
// ] : null,
// 'expected_checkin' => ($asset->created_at) ? [
// 'date' => $asset->created_at->format('Y-m-d'),
// 'formatted' => $asset->created_at->format('Y-m-d'),
// ] : null,
// 'purchase_cost' => (float) $asset->purchase_cost,
'user_can_checkout' => (bool) $temp_asset->availableForCheckout(),
'available_actions' => [
'checkout' => (bool) Gate::allows('checkout', Asset::class),
'checkin' => (bool) Gate::allows('checkin', Asset::class),
'update' => (bool) Gate::allows('update', Asset::class),
'delete' => (bool) Gate::allows('delete', Asset::class),
],
]);
}
/** @test */
public function updateAssetWithPut(ApiTester $I)
{
$I->wantTo('Update a asset with PUT');
// create
$asset = factory(\App\Models\Asset::class)->states('laptop-mbp')->create([
'company_id' => 2,
'name' => "Original name"
]);
$I->assertInstanceOf(\App\Models\Asset::class, $asset);
$temp_asset = factory(\App\Models\Asset::class)->states('laptop-air')->make([
'company_id' => 1,
'name' => "Updated Name"
]);
$I->assertNotNull($temp_asset->asset_tag);
$data = [
'asset_tag' => $temp_asset->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,
];
$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);
$I->assertEquals(trans('admin/hardware/message.update.success'), $response->messages);
$I->assertEquals($asset->id, $response->payload->id); // asset id does not change
$I->assertEquals($temp_asset->asset_tag, $response->payload->asset_tag); // asset tag updated
$I->assertEquals($temp_asset->name, $response->payload->name); // asset name updated
$I->assertEquals($temp_asset->rtd_location_id, $response->payload->rtd_location_id); // asset rtd_location_id updated
// verify // verify
$I->sendGET('/hardware/' . $asset->id); $I->sendGET('/hardware/' . $asset->id);
$I->seeResponseIsJson(); $I->seeResponseIsJson();
$I->seeResponseCodeIs(200); $I->seeResponseCodeIs(200);
$I->seeResponseContainsJson([ $I->seeResponseContainsJson((new AssetsTransformer)->transformAsset($temp_asset));
'id' => (int) $asset->id,
'name' => e($temp_asset->name),
'asset_tag' => e($temp_asset->asset_tag),
'serial' => e($temp_asset->serial),
'model' => ($temp_asset->model) ? [
'id' => (int) $temp_asset->model->id,
'name'=> e($temp_asset->model->name)
] : null,
'model_number' => ($temp_asset->model) ? e($temp_asset->model->model_number) : null,
'status_label' => ($temp_asset->assetstatus) ? [
'id' => (int) $temp_asset->assetstatus->id,
'name'=> e($temp_asset->assetstatus->name)
] : null,
'category' => ($temp_asset->model->category) ? [
'id' => (int) $temp_asset->model->category->id,
'name'=> e($temp_asset->model->category->name)
] : null,
'manufacturer' => ($temp_asset->model->manufacturer) ? [
'id' => (int) $temp_asset->model->manufacturer->id,
'name'=> e($temp_asset->model->manufacturer->name)
] : null,
'notes' => e($temp_asset->notes),
'order_number' => e($asset->order_number),
'company' => ($asset->company) ? [
'id' => (int) $temp_asset->company->id,
'name'=> e($temp_asset->company->name)
] : null,
// 'location' => ($temp_asset->location) ? [
// 'id' => (int) $temp_asset->location->id,
// 'name'=> e($temp_asset->location->name)
// ] : null,
'rtd_location' => ($temp_asset->defaultLoc) ? [
'id' => (int) $temp_asset->defaultLoc->id,
'name'=> e($temp_asset->defaultLoc->name)
] : null,
'image' => ($temp_asset->getImageUrl()) ? $temp_asset->getImageUrl() : null,
'assigned_to' => ($temp_asset->assigneduser) ? [
'id' => (int) $temp_asset->assigneduser->id,
'name' => e($temp_asset->assigneduser->getFullNameAttribute()),
'first_name'=> e($temp_asset->assigneduser->first_name),
'last_name'=> e($temp_asset->assigneduser->last_name)
] : null,
'warranty_months' => ($asset->warranty_months > 0) ? e($asset->warranty_months . ' ' . trans('admin/hardware/form.months')) : null,
'warranty_expires' => ($asset->warranty_months > 0) ? [
'datetime' => $asset->created_at->format('Y-m-d'),
'formatted' => $asset->created_at->format('Y-m-d'),
] : null,
// 'created_at' => ($asset->created_at) ? [
// 'datetime' => $asset->created_at->format('Y-m-d H:i:s'),
// 'formatted' => $asset->created_at->format('Y-m-d H:i a'),
// ] : null,
// 'updated_at' => ($asset->updated_at) ? [
// 'datetime' => $asset->updated_at->format('Y-m-d H:i:s'),
// 'formatted' => $asset->updated_at->format('Y-m-d H:i a'),
// ] : null,
'purchase_date' => ($asset->purchase_date) ? [
'date' => $temp_asset->purchase_date->format('Y-m-d'),
'formatted' => $temp_asset->purchase_date->format('Y-m-d'),
] : null,
// 'last_checkout' => ($asset->last_checkout) ? [
// 'datetime' => $asset->last_checkout->format('Y-m-d'),
// 'formatted' => $asset->last_checkout->format('Y-m-d'),
// ] : null,
// 'expected_checkin' => ($asset->created_at) ? [
// 'date' => $asset->created_at->format('Y-m-d'),
// 'formatted' => $asset->created_at->format('Y-m-d'),
// ] : null,
// 'purchase_cost' => (float) $asset->purchase_cost,
'user_can_checkout' => (bool) $temp_asset->availableForCheckout(),
'available_actions' => [
'checkout' => (bool) Gate::allows('checkout', Asset::class),
'checkin' => (bool) Gate::allows('checkin', Asset::class),
'update' => (bool) Gate::allows('update', Asset::class),
'delete' => (bool) Gate::allows('delete', Asset::class),
],
]);
} }
/** @test */ /** @test */
@ -446,9 +155,10 @@ class ApiAssetsCest
// verify, expect a 200 // verify, expect a 200
$I->sendGET('/hardware/' . $asset->id); $I->sendGET('/hardware/' . $asset->id);
$I->seeResponseCodeIs(200); $I->seeResponseCodeIs(200);
$I->seeResponseIsJson(); // @todo: response is not JSON $I->seeResponseIsJson();
// Make sure we're soft deleted.
// $scenario->incomplete('not found response should be JSON, receiving HTML instead'); $response = json_decode($I->grabResponse());
$I->assertNotNull($response->deleted_at);
} }
} }

View file

@ -0,0 +1,141 @@
<?php
use App\Exceptions\CheckoutNotAllowed;
use App\Helpers\Helper;
use App\Models\Asset;
use App\Models\Setting;
use Illuminate\Support\Facades\Auth;
class ApiCheckoutAssetsCest
{
protected $faker;
protected $user;
protected $timeFormat;
public function _before(ApiTester $I)
{
$this->user = \App\Models\User::find(1);
$I->amBearerAuthenticated($I->getToken($this->user));
}
/** @test */
public function checkoutAssetToUser(ApiTester $I) {
$I->wantTo('Check out an asset to a user');
//Grab an asset from the database that isn't checked out.
$asset = Asset::whereNull('assigned_to')->first();
$targetUser = factory('App\Models\User')->create();
$data = [
'assigned_user' => $targetUser->id,
'note' => "This is a test checkout note",
'expected_checkin' => "2018-05-24",
'name' => "Updated Asset Name",
'checkout_to_type' => 'user'
];
$I->sendPOST("/hardware/{$asset->id}/checkout", $data);
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
$response = json_decode($I->grabResponse());
$I->assertEquals('success', $response->status);
$I->assertEquals(trans('admin/hardware/message.checkout.success'), $response->messages);
// Confirm results.
$I->sendGET("/hardware/{$asset->id}");
$I->seeResponseContainsJson([
'assigned_to' => [
'id' => $targetUser->id,
'type' => 'user'
],
'name' => "Updated Asset Name",
'expected_checkin' => Helper::getFormattedDateObject('2018-05-24', 'date')
]);
}
/** @test */
public function checkoutAssetToAsset(ApiTester $I) {
$I->wantTo('Check out an asset to an asset');
//Grab an asset from the database that isn't checked out.
$asset = Asset::whereNull('assigned_to')->where('model_id',8)->first(); // We need to make sure that this is an asset/model that doesn't require acceptance
$targetAsset = factory('App\Models\Asset')->states('desktop-macpro')->create([
'name' => "Test Asset For Checkout to"
]);
// dd($targetAsset->model->category);
$data = [
'assigned_asset' => $targetAsset->id,
'checkout_to_type' => 'asset'
];
$I->sendPOST("/hardware/{$asset->id}/checkout", $data);
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
$response = json_decode($I->grabResponse());
$I->assertEquals('success', $response->status);
$I->assertEquals(trans('admin/hardware/message.checkout.success'), $response->messages);
// Confirm results.
$I->sendGET("/hardware/{$asset->id}");
$I->seeResponseContainsJson([
'assigned_to' => [
'id' => $targetAsset->id,
'type' => 'asset'
]
]);
}
/** @test */
public function checkoutAssetToLocation(ApiTester $I) {
$I->wantTo('Check out an asset to an asset');
//Grab an asset from the database that isn't checked out.
$asset = Asset::whereNull('assigned_to')->where('model_id',8)->first();
$targetLocation = factory('App\Models\Location')->create([
'name' => "Test Location for Checkout"
]);
// dd($targetAsset->model->category);
$data = [
'assigned_location' => $targetLocation->id,
'checkout_to_type' => 'location'
];
$I->sendPOST("/hardware/{$asset->id}/checkout", $data);
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
$response = json_decode($I->grabResponse());
$I->assertEquals('success', $response->status);
$I->assertEquals(trans('admin/hardware/message.checkout.success'), $response->messages);
// Confirm results.
$I->sendGET("/hardware/{$asset->id}");
$I->seeResponseContainsJson([
'assigned_to' => [
'id' => $targetLocation->id,
'type' => 'location'
]
]);
}
/** @test */
public function checkinAsset(ApiTester $I) {
$I->wantTo('Checkin an asset that is currently checked out');
$asset = Asset::whereNotNull('assigned_to')->first();
$I->sendPOST("/hardware/{$asset->id}/checkin", [
"note" => "Checkin Note"
]);
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
$response = json_decode($I->grabResponse());
$I->assertEquals('success', $response->status);
$I->assertEquals(trans('admin/hardware/message.checkin.success'), $response->messages);
// Verify
$I->sendGET("/hardware/{$asset->id}");
$I->seeResponseContainsJson([
'assigned_to' => null
]);
}
}

View file

@ -0,0 +1,133 @@
<?php
use App\Helpers\Helper;
use App\Http\Transformers\CompaniesTransformer;
use App\Models\Company;
use App\Models\Setting;
use Illuminate\Support\Facades\Auth;
class ApiCompaniesCest
{
protected $user;
protected $timeFormat;
public function _before(ApiTester $I)
{
$this->user = \App\Models\User::find(1);
$I->haveHttpHeader('Accept', 'application/json');
$I->amBearerAuthenticated($I->getToken($this->user));
}
/** @test */
public function indexCompanys(ApiTester $I)
{
$I->wantTo('Get a list of companies');
// call
$I->sendGET('/companies?order_by=id&limit=10');
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
$response = json_decode($I->grabResponse(), true);
// dd($response);
// sample verify
$company = App\Models\Company::withCount('assets','licenses','accessories','consumables','components','users')
->orderByDesc('created_at')->take(10)->get()->shuffle()->first();
$I->seeResponseContainsJson((new CompaniesTransformer)->transformCompany($company));
}
/** @test */
public function createCompany(ApiTester $I, $scenario)
{
$I->wantTo('Create a new company');
$temp_company = factory(\App\Models\Company::class)->make([
'name' => "Test Company Tag",
]);
// setup
$data = [
'name' => $temp_company->name,
];
// create
$I->sendPOST('/companies', $data);
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
}
// Put is routed to the same method in the controller
// DO we actually need to test both?
/** @test */
public function updateCompanyWithPatch(ApiTester $I, $scenario)
{
$I->wantTo('Update an company with PATCH');
// create
$company = factory(\App\Models\Company::class)->create([
'name' => 'Original Company Name',
]);
$I->assertInstanceOf(\App\Models\Company::class, $company);
$temp_company = factory(\App\Models\Company::class)->make([
'name' => "updated company name",
]);
$data = [
'name' => $temp_company->name,
];
$I->assertNotEquals($company->name, $data['name']);
// update
$I->sendPATCH('/companies/' . $company->id, $data);
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
$response = json_decode($I->grabResponse());
$I->assertEquals('success', $response->status);
$I->assertEquals(trans('admin/companies/message.update.success'), $response->messages);
$I->assertEquals($company->id, $response->payload->id); // company id does not change
$I->assertEquals($temp_company->name, $response->payload->name); // company name updated
// Some manual copying to compare against
$temp_company->created_at = Carbon::parse($response->payload->created_at->datetime);
$temp_company->updated_at = Carbon::parse($response->payload->updated_at->datetime);
$temp_company->id = $company->id;
// verify
$I->sendGET('/companies/' . $company->id);
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
$I->seeResponseContainsJson((new CompaniesTransformer)->transformCompany($temp_company));
}
/** @test */
public function deleteCompanyTest(ApiTester $I, $scenario)
{
$I->wantTo('Delete an company');
// create
$company = factory(\App\Models\Company::class)->create([
'name' => "Soon to be deleted"
]);
$I->assertInstanceOf(\App\Models\Company::class, $company);
// delete
$I->sendDELETE('/companies/' . $company->id);
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
$response = json_decode($I->grabResponse());
$I->assertEquals('success', $response->status);
$I->assertEquals(trans('admin/companies/message.delete.success'), $response->messages);
// verify, expect a 200
$I->sendGET('/companies/' . $company->id);
$I->seeResponseCodeIs(200);
$I->seeResponseIsJson();
}
}

View file

@ -1,18 +1,20 @@
<?php <?php
use App\Helpers\Helper;
use App\Http\Transformers\ComponentsTransformer;
use App\Models\Component; use App\Models\Component;
use App\Models\Setting;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
class ApiComponentsCest class ApiComponentsCest
{ {
protected $faker;
protected $user; protected $user;
protected $timeFormat;
public function _before(ApiTester $I) public function _before(ApiTester $I)
{ {
$this->faker = \Faker\Factory::create();
$this->user = \App\Models\User::find(1); $this->user = \App\Models\User::find(1);
$I->haveHttpHeader('Accept', 'application/json');
$I->amBearerAuthenticated($I->getToken($this->user)); $I->amBearerAuthenticated($I->getToken($this->user));
} }
@ -21,104 +23,81 @@ class ApiComponentsCest
{ {
$I->wantTo('Get a list of components'); $I->wantTo('Get a list of components');
// setup
// $components = factory(\App\Models\Component::class, 10)->create();
// call // call
$I->sendGET('/components?limit=10&order=desc'); $I->sendGET('/components?limit=10');
$I->seeResponseIsJson(); $I->seeResponseIsJson();
$I->seeResponseCodeIs(200); $I->seeResponseCodeIs(200);
$response = json_decode($I->grabResponse(), true);
// sample verify // sample verify
$component = Component::orderByDesc('created_at')->first(); $component = App\Models\Component::orderByDesc('created_at')->take(10)->get()->shuffle()->first();
$I->seeResponseContainsJson([
'name' => $component->name,
'qty' => $component->qty,
]);
$I->seeResponseContainsJson([ $I->seeResponseContainsJson((new ComponentsTransformer)->transformComponent($component));
'total' => \App\Models\Component::count(),
]);
} }
/** @test */ /** @test */
public function createComponent(ApiTester $I) public function createComponent(ApiTester $I, $scenario)
{ {
$I->wantTo('Create a new component'); $I->wantTo('Create a new component');
// setup $temp_component = factory(\App\Models\Component::class)->states('ram-crucial4')->make([
$category = factory(\App\Models\Category::class)->states('asset-laptop-category')->create([ 'name' => "Test Component Name",
'name' => "Test Category Name", 'company_id' => 2
'user_id' => $this->user->id
]); ]);
$location = factory(\App\Models\Location::class)->create(['user_id' => $this->user->id]);
$company = factory(\App\Models\Company::class)->create();
// setup
$data = [ $data = [
'category_id' => $category->id, 'category_id' => $temp_component->category_id,
'company_id' => $company->id, 'company_id' => $temp_component->company->id,
'location_id' => $location->id, 'location_id' => $temp_component->location_id,
'name' => $this->faker->sentence(3), 'manufacturer_id' => $temp_component->manufacturer_id,
'purchase_cost' => $this->faker->randomFloat(2, 0), 'model_number' => $temp_component->model_number,
'purchase_date' => $this->faker->dateTime->format('Y-m-d'), 'name' => $temp_component->name,
'qty' => rand(1, 10), 'order_number' => $temp_component->order_number,
'purchase_cost' => $temp_component->purchase_cost,
'purchase_date' => $temp_component->purchase_date,
'qty' => $temp_component->qty,
'serial' => $temp_component->serial
]; ];
// create // create
$I->sendPOST('/components', $data); $I->sendPOST('/components', $data);
$I->seeResponseIsJson(); $I->seeResponseIsJson();
$I->seeResponseCodeIs(200); $I->seeResponseCodeIs(200);
$response = json_decode($I->grabResponse());
$id = $response->payload->id;
$I->assertEquals('success', $response->status);
// verify
$I->sendGET('/components/' . $id);
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
$I->seeResponseContainsJson([
'id' => (int) $id,
'name' => e($data['name']),
// 'serial_number' => e($component->serial),
'location' => [
'id' => (int) $data['location_id'],
'name' => e($location->name),
],
'qty' => number_format($data['qty']),
// 'min_amt' => e($component->min_amt),
'category' => [
'id' => (int) $data['category_id'],
'name' => e($category->name),
],
// 'order_number' => e($component->order_number),
'purchase_date' => \App\Helpers\Helper::getFormattedDateObject($data['purchase_date'], 'date'),
'purchase_cost' => \App\Helpers\Helper::formatCurrencyOutput($data['purchase_cost']),
// 'remaining' => (int) $component->numRemaining(),
'company' => [
'id' => (int) $data['company_id'],
'name' => e($company->name),
],
// 'created_at' => Helper::getFormattedDateObject($component->created_at, 'datetime'),
// 'updated_at' => Helper::getFormattedDateObject($component->updated_at, 'datetime'),
]);
} }
// Put is routed to the same method in the controller
// DO we actually need to test both?
/** @test */ /** @test */
public function updateComponentWithPatch(ApiTester $I) public function updateComponentWithPatch(ApiTester $I, $scenario)
{ {
$I->wantTo('Update a component with PATCH'); $I->wantTo('Update an component with PATCH');
// create // create
$component = factory(\App\Models\Component::class)->states('ram-crucial4')->create([ $component = factory(\App\Models\Component::class)->states('ram-crucial4')->create([
'name' => "Test Component" 'name' => 'Original Component Name',
'company_id' => 2,
'location_id' => 3
]); ]);
$I->assertInstanceOf(\App\Models\Component::class, $component); $I->assertInstanceOf(\App\Models\Component::class, $component);
$temp_component = factory(\App\Models\Component::class)->states('ssd-crucial240')->make([
'company_id' => 3,
'name' => "updated component name",
'location_id' => 1,
]);
$data = [ $data = [
'name' => $this->faker->sentence(3), 'category_id' => $temp_component->category_id,
'qty' => $this->faker->randomDigit + 1, 'company_id' => $temp_component->company->id,
'location_id' => $temp_component->location_id,
'min_amt' => $temp_component->min_amt,
'name' => $temp_component->name,
'order_number' => $temp_component->order_number,
'purchase_cost' => $temp_component->purchase_cost,
'purchase_date' => $temp_component->purchase_date,
'qty' => $temp_component->qty,
'serial' => $temp_component->serial,
]; ];
$I->assertNotEquals($component->name, $data['name']); $I->assertNotEquals($component->name, $data['name']);
@ -129,63 +108,31 @@ class ApiComponentsCest
$I->seeResponseCodeIs(200); $I->seeResponseCodeIs(200);
$response = json_decode($I->grabResponse()); $response = json_decode($I->grabResponse());
$I->assertEquals('success', $response->status);
$I->assertEquals('success', $response->status);
$I->assertEquals(trans('admin/components/message.update.success'), $response->messages);
$I->assertEquals($component->id, $response->payload->id); // component id does not change
$I->assertEquals($temp_component->company_id, $response->payload->company_id); // company_id updated
$I->assertEquals($temp_component->name, $response->payload->name); // component name updated
$I->assertEquals($temp_component->location_id, $response->payload->location_id); // component location_id updated
$temp_component->created_at = Carbon::parse($response->payload->created_at);
$temp_component->updated_at = Carbon::parse($response->payload->updated_at);
$temp_component->id = $component->id;
// verify // verify
$I->sendGET('/components/' . $component->id); $I->sendGET('/components/' . $component->id);
$I->seeResponseIsJson(); $I->seeResponseIsJson();
$I->seeResponseCodeIs(200); $I->seeResponseCodeIs(200);
$I->seeResponseContainsJson([ $I->seeResponseContainsJson((new ComponentsTransformer)->transformComponent($temp_component));
'name' => $data['name'],
'id' => $component->id,
'qty' => $data['qty'],
]);
}
/** @test */
public function updateComponentWithPut(ApiTester $I)
{
$I->wantTo('Update a component with PUT');
// create
$component = factory(\App\Models\Component::class)->states('ram-crucial4')->create([
'name' => "Test Component"
]);
$I->assertInstanceOf(\App\Models\Component::class, $component);
$data = [
'name' => $this->faker->sentence(3),
];
$I->assertNotEquals($component->name, $data['name']);
// update
$I->sendPUT('/components/' . $component->id, $data);
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
$response = json_decode($I->grabResponse());
$I->assertEquals('success', $response->status);
// verify
$I->sendGET('/components/' . $component->id);
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
$I->seeResponseContainsJson([
'name' => e($data['name']),
'id' => e($component->id),
'qty' => e($component->qty),
]);
} }
/** @test */ /** @test */
public function deleteComponentTest(ApiTester $I, $scenario) public function deleteComponentTest(ApiTester $I, $scenario)
{ {
$I->wantTo('Delete a component'); $I->wantTo('Delete an component');
// create // create
$component = factory(\App\Models\Component::class)->states('ram-crucial4')->create([ $component = factory(\App\Models\Component::class)->states('ram-crucial4')->create([
'name' => "Test Component" 'name' => "Soon to be deleted"
]); ]);
$I->assertInstanceOf(\App\Models\Component::class, $component); $I->assertInstanceOf(\App\Models\Component::class, $component);
@ -194,10 +141,15 @@ class ApiComponentsCest
$I->seeResponseIsJson(); $I->seeResponseIsJson();
$I->seeResponseCodeIs(200); $I->seeResponseCodeIs(200);
// verify, expect a 200 with an error message $response = json_decode($I->grabResponse());
// dd($response);
$I->assertEquals('success', $response->status);
$I->assertEquals(trans('admin/components/message.delete.success'), $response->messages);
// verify, expect a 200
$I->sendGET('/components/' . $component->id); $I->sendGET('/components/' . $component->id);
$I->seeResponseCodeIs(200); $I->seeResponseCodeIs(200);
$I->seeResponseIsJson(); // @todo: response is not JSON $I->seeResponseIsJson();
// $scenario->incomplete('Resource not found response should be JSON, receiving HTML instead');
} }
} }

View file

@ -0,0 +1,154 @@
<?php
use App\Helpers\Helper;
use App\Http\Transformers\ConsumablesTransformer;
use App\Models\Consumable;
use App\Models\Setting;
use Illuminate\Support\Facades\Auth;
class ApiConsumablesCest
{
protected $user;
protected $timeFormat;
public function _before(ApiTester $I)
{
$this->user = \App\Models\User::find(1);
$I->haveHttpHeader('Accept', 'application/json');
$I->amBearerAuthenticated($I->getToken($this->user));
}
/** @test */
public function indexConsumables(ApiTester $I)
{
$I->wantTo('Get a list of consumables');
// call
$I->sendGET('/consumables?limit=10');
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
$response = json_decode($I->grabResponse(), true);
// sample verify
$consumable = App\Models\Consumable::orderByDesc('created_at')->take(10)->get()->shuffle()->first();
$I->seeResponseContainsJson((new ConsumablesTransformer)->transformConsumable($consumable));
}
/** @test */
public function createConsumable(ApiTester $I, $scenario)
{
$I->wantTo('Create a new consumable');
$temp_consumable = factory(\App\Models\Consumable::class)->states('ink')->make([
'name' => "Test Consumable Name",
'company_id' => 2
]);
// setup
$data = [
'category_id' => $temp_consumable->category_id,
'company_id' => $temp_consumable->company->id,
'location_id' => $temp_consumable->location_id,
'manufacturer_id' => $temp_consumable->manufacturer_id,
'name' => $temp_consumable->name,
'order_number' => $temp_consumable->order_number,
'purchase_cost' => $temp_consumable->purchase_cost,
'purchase_date' => $temp_consumable->purchase_date,
'qty' => $temp_consumable->qty,
'model_number' => $temp_consumable->model_number,
];
// create
$I->sendPOST('/consumables', $data);
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
}
// Put is routed to the same method in the controller
// DO we actually need to test both?
/** @test */
public function updateConsumableWithPatch(ApiTester $I, $scenario)
{
$I->wantTo('Update an consumable with PATCH');
// create
$consumable = factory(\App\Models\Consumable::class)->states('ink')->create([
'name' => 'Original Consumable Name',
'company_id' => 2,
'location_id' => 3
]);
$I->assertInstanceOf(\App\Models\Consumable::class, $consumable);
$temp_consumable = factory(\App\Models\Consumable::class)->states('cardstock')->make([
'company_id' => 3,
'name' => "updated consumable name",
'location_id' => 1,
]);
$data = [
'category_id' => $temp_consumable->category_id,
'company_id' => $temp_consumable->company->id,
'item_no' => $temp_consumable->item_no,
'location_id' => $temp_consumable->location_id,
'name' => $temp_consumable->name,
'order_number' => $temp_consumable->order_number,
'purchase_cost' => $temp_consumable->purchase_cost,
'purchase_date' => $temp_consumable->purchase_date,
'model_number' => $temp_consumable->model_number,
'manufacturer_id' => $temp_consumable->manufacturer_id,
'supplier_id' => $temp_consumable->supplier_id,
'qty' => $temp_consumable->qty,
];
$I->assertNotEquals($consumable->name, $data['name']);
// update
$I->sendPATCH('/consumables/' . $consumable->id, $data);
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
$response = json_decode($I->grabResponse());
$I->assertEquals('success', $response->status);
$I->assertEquals(trans('admin/consumables/message.update.success'), $response->messages);
$I->assertEquals($consumable->id, $response->payload->id); // consumable id does not change
$I->assertEquals($temp_consumable->company_id, $response->payload->company_id); // company_id updated
$I->assertEquals($temp_consumable->name, $response->payload->name); // consumable name updated
$I->assertEquals($temp_consumable->location_id, $response->payload->location_id); // consumable location_id updated
$temp_consumable->created_at = Carbon::parse($response->payload->created_at);
$temp_consumable->updated_at = Carbon::parse($response->payload->updated_at);
$temp_consumable->id = $consumable->id;
// verify
$I->sendGET('/consumables/' . $consumable->id);
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
$I->seeResponseContainsJson((new ConsumablesTransformer)->transformConsumable($temp_consumable));
}
/** @test */
public function deleteConsumableTest(ApiTester $I, $scenario)
{
$I->wantTo('Delete an consumable');
// create
$consumable = factory(\App\Models\Consumable::class)->states('ink')->create([
'name' => "Soon to be deleted"
]);
$I->assertInstanceOf(\App\Models\Consumable::class, $consumable);
// delete
$I->sendDELETE('/consumables/' . $consumable->id);
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
$response = json_decode($I->grabResponse());
$I->assertEquals('success', $response->status);
$I->assertEquals(trans('admin/consumables/message.delete.success'), $response->messages);
// verify, expect a 200
$I->sendGET('/consumables/' . $consumable->id);
$I->seeResponseCodeIs(200);
$I->seeResponseIsJson();
}
}

View file

@ -0,0 +1,145 @@
<?php
use App\Helpers\Helper;
use App\Http\Transformers\LocationsTransformer;
use App\Models\Location;
use App\Models\Setting;
use Illuminate\Support\Facades\Auth;
class ApiLocationsCest
{
protected $user;
protected $timeFormat;
public function _before(ApiTester $I)
{
$this->user = \App\Models\User::find(1);
$this->timeFormat = Setting::getSettings()->date_display_format .' '. Setting::getSettings()->time_display_format;
$this->dateFormat = Setting::getSettings()->date_display_format;
$I->haveHttpHeader('Accept', 'application/json');
$I->amBearerAuthenticated($I->getToken($this->user));
}
/** @test */
public function indexLocations(ApiTester $I)
{
$I->wantTo('Get a list of locations');
// call
$I->sendGET('/locations?limit=1');
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
$response = json_decode($I->grabResponse(), true);
// sample verify
$location = App\Models\Location::orderByDesc('created_at')
->withCount('assignedAssets', 'assets', 'users')
->take(1)->get()->shuffle()->first();
$I->seeResponseContainsJson((new LocationsTransformer)->transformLocation($location));
}
/** @test */
public function createLocation(ApiTester $I, $scenario)
{
$I->wantTo('Create a new location');
$temp_location = factory(\App\Models\Location::class)->make([
'name' => "Test Location Tag",
]);
// setup
$data = [
'name' => $temp_location->name,
];
// create
$I->sendPOST('/locations', $data);
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
}
// Put is routed to the same method in the controller
// DO we actually need to test both?
/** @test */
public function updateLocationWithPatch(ApiTester $I, $scenario)
{
$I->wantTo('Update an location with PATCH');
// create
$location = factory(\App\Models\Location::class)->create([
'name' => 'Original Location Name',
]);
$I->assertInstanceOf(\App\Models\Location::class, $location);
$temp_location = factory(\App\Models\Location::class)->make([
'name' => "updated location name",
]);
$data = [
'name' => $temp_location->name,
'image' => $temp_location->image,
'address' => $temp_location->address,
'address2' => $temp_location->address2,
'city' => $temp_location->city,
'state' => $temp_location->state,
'country' => $temp_location->country,
'zip' => $temp_location->zip,
'parent_id' => $temp_location->parent_id,
'parent_id' => $temp_location->parent_id,
'manager_id' => $temp_location->manager_id,
'currency' => $temp_location->currency
];
$I->assertNotEquals($location->name, $data['name']);
// update
$I->sendPATCH('/locations/' . $location->id, $data);
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
$response = json_decode($I->grabResponse());
$I->assertEquals('success', $response->status);
$I->assertEquals(trans('admin/locations/message.update.success'), $response->messages);
$I->assertEquals($location->id, $response->payload->id); // location id does not change
$I->assertEquals($temp_location->name, $response->payload->name); // location name updated
// Some necessary manual copying
$temp_location->created_at = Carbon::parse($response->payload->created_at->datetime);
$temp_location->updated_at = Carbon::parse($response->payload->updated_at->datetime);
$temp_location->id = $location->id;
// verify
$I->sendGET('/locations/' . $location->id);
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
$I->seeResponseContainsJson((new LocationsTransformer)->transformLocation($temp_location));
// $I->seeResponseContainsJson($this->generateJsonResponse($temp_location, $location));
}
/** @test */
public function deleteLocationTest(ApiTester $I, $scenario)
{
$I->wantTo('Delete an location');
// create
$location = factory(\App\Models\Location::class)->create([
'name' => "Soon to be deleted"
]);
$I->assertInstanceOf(\App\Models\Location::class, $location);
// delete
$I->sendDELETE('/locations/' . $location->id);
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
$response = json_decode($I->grabResponse());
$I->assertEquals('success', $response->status);
$I->assertEquals(trans('admin/locations/message.delete.success'), $response->messages);
// verify, expect a 200
$I->sendGET('/locations/' . $location->id);
$I->seeResponseCodeIs(200);
$I->seeResponseIsJson();
}
}

View file

@ -0,0 +1,143 @@
<?php
use App\Helpers\Helper;
use App\Http\Transformers\StatuslabelsTransformer;
use App\Models\Statuslabel;
use App\Models\Setting;
use Illuminate\Support\Facades\Auth;
class ApiStatuslabelsCest
{
protected $user;
protected $timeFormat;
public function _before(ApiTester $I)
{
$this->user = \App\Models\User::find(1);
$I->haveHttpHeader('Accept', 'application/json');
$I->amBearerAuthenticated($I->getToken($this->user));
}
/** @test */
public function indexStatuslabels(ApiTester $I)
{
$I->wantTo('Get a list of statuslabels');
// call
$I->sendGET('/statuslabels?limit=10');
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
$response = json_decode($I->grabResponse(), true);
// sample verify
$statuslabel = App\Models\Statuslabel::orderByDesc('created_at')
->withCount('assets')
->take(10)->get()->shuffle()->first();
$I->seeResponseContainsJson((new StatuslabelsTransformer)->transformStatuslabel($statuslabel));
}
/** @test */
public function createStatuslabel(ApiTester $I, $scenario)
{
$I->wantTo('Create a new statuslabel');
$temp_statuslabel = factory(\App\Models\Statuslabel::class)->make([
'name' => "Test Statuslabel Tag",
]);
// setup
$data = [
'name' => $temp_statuslabel->name,
'archived' => $temp_statuslabel->archived,
'deployable' => $temp_statuslabel->deployable,
'notes' => $temp_statuslabel->notes,
'pending' => $temp_statuslabel->pending,
'type' => 'deployable'
];
// create
$I->sendPOST('/statuslabels', $data);
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
}
// Put is routed to the same method in the controller
// DO we actually need to test both?
/** @test */
public function updateStatuslabelWithPatch(ApiTester $I, $scenario)
{
$I->wantTo('Update an statuslabel with PATCH');
// create
$statuslabel = factory(\App\Models\Statuslabel::class)->states('rtd')->create([
'name' => 'Original Statuslabel Name',
]);
$I->assertInstanceOf(\App\Models\Statuslabel::class, $statuslabel);
$temp_statuslabel = factory(\App\Models\Statuslabel::class)->states('pending')->make([
'name' => "updated statuslabel name",
'type' => 'pending'
]);
$data = [
'name' => $temp_statuslabel->name,
'archived' => $temp_statuslabel->archived,
'deployable' => $temp_statuslabel->deployable,
'notes' => $temp_statuslabel->notes,
'pending' => $temp_statuslabel->pending,
'type' => $temp_statuslabel->type
];
$I->assertNotEquals($statuslabel->name, $data['name']);
// update
$I->sendPATCH('/statuslabels/' . $statuslabel->id, $data);
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
$response = json_decode($I->grabResponse());
// dd($response);
$I->assertEquals('success', $response->status);
$I->assertEquals(trans('admin/statuslabels/message.update.success'), $response->messages);
$I->assertEquals($statuslabel->id, $response->payload->id); // statuslabel id does not change
$I->assertEquals($temp_statuslabel->name, $response->payload->name); // statuslabel name updated
// Some manual copying to compare against
$temp_statuslabel->created_at = Carbon::parse($response->payload->created_at);
$temp_statuslabel->updated_at = Carbon::parse($response->payload->updated_at);
$temp_statuslabel->id = $statuslabel->id;
// verify
$I->sendGET('/statuslabels/' . $statuslabel->id);
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
$I->seeResponseContainsJson((new StatuslabelsTransformer)->transformStatuslabel($temp_statuslabel));
}
/** @test */
public function deleteStatuslabelTest(ApiTester $I, $scenario)
{
$I->wantTo('Delete an statuslabel');
// create
$statuslabel = factory(\App\Models\Statuslabel::class)->create([
'name' => "Soon to be deleted"
]);
$I->assertInstanceOf(\App\Models\Statuslabel::class, $statuslabel);
// delete
$I->sendDELETE('/statuslabels/' . $statuslabel->id);
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
$response = json_decode($I->grabResponse());
$I->assertEquals('success', $response->status);
$I->assertEquals(trans('admin/statuslabels/message.delete.success'), $response->messages);
// verify, expect a 200
$I->sendGET('/statuslabels/' . $statuslabel->id);
$I->seeResponseCodeIs(200);
$I->seeResponseIsJson();
}
}

190
tests/api/ApiUsersCest.php Normal file
View file

@ -0,0 +1,190 @@
<?php
use App\Helpers\Helper;
use App\Http\Transformers\UsersTransformer;
use App\Models\User;
use App\Models\Setting;
use Illuminate\Support\Facades\Auth;
class ApiUsersCest
{
protected $user;
protected $timeFormat;
public function _before(ApiTester $I)
{
$this->user = \App\Models\User::find(1);
$I->haveHttpHeader('Accept', 'application/json');
$I->amBearerAuthenticated($I->getToken($this->user));
}
/** @test */
public function indexUsers(ApiTester $I)
{
$I->wantTo('Get a list of users');
// call
$I->sendGET('/users?limit=10&sort=created_at');
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
$response = json_decode($I->grabResponse(), true);
// sample verify
$user = App\Models\User::orderByDesc('created_at')
->withCount('assets', 'licenses', 'accessories', 'consumables')
->take(10)->get()->shuffle()->first();
$I->seeResponseContainsJson((new UsersTransformer)->transformUser($user));
}
/** @test */
public function createUser(ApiTester $I, $scenario)
{
$I->wantTo('Create a new user');
$temp_user = factory(\App\Models\User::class)->make([
'name' => "Test User Name",
]);
// setup
$data = [
'activated' => $temp_user->activated,
'address' => $temp_user->address,
'city' => $temp_user->city,
'company_id' => $temp_user->company_id,
'country' => $temp_user->country,
'department_id' => $temp_user->department_id,
'email' => $temp_user->email,
'employee_num' => $temp_user->employee_num,
'first_name' => $temp_user->first_name,
'jobtitle' => $temp_user->jobtitle,
'last_name' => $temp_user->last_name,
'locale' => $temp_user->locale,
'location_id' => $temp_user->location_id,
'notes' => $temp_user->notes,
'manager_id' => $temp_user->manager_id,
'password' => $temp_user->password,
'phone' => $temp_user->phone,
'state' => $temp_user->state,
'username' => $temp_user->username,
'zip' => $temp_user->zip,
];
// create
$I->sendPOST('/users', $data);
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
}
// Put is routed to the same method in the controller
// DO we actually need to test both?
/** @test */
public function updateUserWithPatch(ApiTester $I, $scenario)
{
$I->wantTo('Update an user with PATCH');
// create
$user = factory(\App\Models\User::class)->create([
'first_name' => 'Original User Name',
'company_id' => 2,
'location_id' => 3
]);
$I->assertInstanceOf(\App\Models\User::class, $user);
$temp_user = factory(\App\Models\User::class)->make([
'company_id' => 3,
'first_name' => "updated user name",
'location_id' => 1,
]);
$data = [
'activated' => $temp_user->activated,
'address' => $temp_user->address,
'city' => $temp_user->city,
'company_id' => $temp_user->company_id,
'country' => $temp_user->country,
'department_id' => $temp_user->department_id,
'email' => $temp_user->email,
'employee_num' => $temp_user->employee_num,
'first_name' => $temp_user->first_name,
'jobtitle' => $temp_user->jobtitle,
'last_name' => $temp_user->last_name,
'locale' => $temp_user->locale,
'location_id' => $temp_user->location_id,
'notes' => $temp_user->notes,
'manager_id' => $temp_user->manager_id,
'password' => $temp_user->password,
'phone' => $temp_user->phone,
'state' => $temp_user->state,
'username' => $temp_user->username,
'zip' => $temp_user->zip,
];
$I->assertNotEquals($user->first_name, $data['first_name']);
// update
$I->sendPATCH('/users/' . $user->id, $data);
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
$response = json_decode($I->grabResponse());
$I->assertEquals('success', $response->status);
$I->assertEquals(trans('admin/users/message.success.update'), $response->messages);
$I->assertEquals($user->id, $response->payload->id); // user id does not change
$I->assertEquals($temp_user->company_id, $response->payload->company->id); // company_id updated
$I->assertEquals($temp_user->first_name, $response->payload->first_name); // user name updated
$I->assertEquals($temp_user->location_id, $response->payload->location->id); // user location_id updated
$temp_user->created_at = Carbon::parse($response->payload->created_at->datetime);
$temp_user->updated_at = Carbon::parse($response->payload->updated_at->datetime);
$temp_user->id = $user->id;
// verify
$I->sendGET('/users/' . $user->id);
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
$I->seeResponseContainsJson((new UsersTransformer)->transformUser($temp_user));
}
/** @test */
public function deleteUserTest(ApiTester $I, $scenario)
{
$I->wantTo('Delete an user');
// create
$user = factory(\App\Models\User::class)->create([
'first_name' => "Soon to be deleted"
]);
$I->assertInstanceOf(\App\Models\User::class, $user);
// delete
$I->sendDELETE('/users/' . $user->id);
$I->seeResponseIsJson();
$I->seeResponseCodeIs(200);
$response = json_decode($I->grabResponse());
// dd($response);
$I->assertEquals('success', $response->status);
$I->assertEquals(trans('admin/users/message.success.delete'), $response->messages);
// verify, expect a 200
$I->sendGET('/users/' . $user->id);
$I->seeResponseCodeIs(200);
$I->seeResponseIsJson();
}
/** @test */
public function fetchUserAssetsTest(ApiTester $I, $scenario) {
$I->wantTo("Fetch assets for a user");
$user = User::has('assets')->first();
$asset = $user->assets->shuffle()->first();
$I->sendGET("/users/{$user->id}/assets");
$response = json_decode($I->grabResponse());
$I->seeResponseCodeIs(200);
$I->seeResponseIsJson();
// Just test a random one.
$I->seeResponseContainsJson([
'asset_tag' => $asset->asset_tag,
]);
}
}