Skip to content

Commit e05f443

Browse files
authored
Merge pull request #15864 from marcusmoore/testing/api-component-checkout
Added tests for component checkout api endpoint
2 parents 0a3bca0 + d65254c commit e05f443

File tree

2 files changed

+161
-0
lines changed

2 files changed

+161
-0
lines changed
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
<?php
2+
3+
namespace Tests\Feature\Checkouts\Api;
4+
5+
use App\Models\Asset;
6+
use App\Models\Company;
7+
use App\Models\Component;
8+
use App\Models\Location;
9+
use App\Models\User;
10+
use Carbon\Carbon;
11+
use Tests\Concerns\TestsFullMultipleCompaniesSupport;
12+
use Tests\Concerns\TestsPermissionsRequirement;
13+
use Tests\TestCase;
14+
15+
class ComponentCheckoutTest extends TestCase implements TestsFullMultipleCompaniesSupport, TestsPermissionsRequirement
16+
{
17+
public function testRequiresPermission()
18+
{
19+
$component = Component::factory()->create();
20+
21+
$this->actingAsForApi(User::factory()->create())
22+
->postJson(route('api.components.checkout', $component->id))
23+
->assertForbidden();
24+
}
25+
26+
public function testCannotCheckoutNonExistentComponent()
27+
{
28+
$this->actingAsForApi(User::factory()->checkoutComponents()->create())
29+
->postJson(route('api.components.checkout', 1000))
30+
->assertOk()
31+
->assertStatusMessageIs('error')
32+
->assertMessagesAre('Component does not exist.');
33+
}
34+
35+
public function testCheckingOutComponentRequiresValidFields()
36+
{
37+
$component = Component::factory()->create();
38+
39+
$this->actingAsForApi(User::factory()->checkoutComponents()->create())
40+
->postJson(route('api.components.checkout', $component->id), [
41+
//
42+
])
43+
->assertOk()
44+
->assertStatusMessageIs('error')
45+
->assertPayloadContains('assigned_to')
46+
->assertPayloadContains('assigned_qty');
47+
}
48+
49+
public function testCannotCheckoutComponentIfRequestedAmountIsMoreThanComponentQuantity()
50+
{
51+
$asset = Asset::factory()->create();
52+
$component = Component::factory()->create(['qty' => 2]);
53+
54+
$this->actingAsForApi(User::factory()->checkoutComponents()->create())
55+
->postJson(route('api.components.checkout', $component->id), [
56+
'assigned_to' => $asset->id,
57+
'assigned_qty' => 3,
58+
])
59+
->assertOk()
60+
->assertStatusMessageIs('error')
61+
->assertMessagesAre(trans('admin/components/message.checkout.unavailable', ['remaining' => 2, 'requested' => 3]));
62+
}
63+
64+
public function testCannotCheckoutComponentIfRequestedAmountIsMoreThanWhatIsRemaining()
65+
{
66+
$asset = Asset::factory()->create();
67+
$component = Component::factory()->create(['qty' => 2]);
68+
$component->assets()->attach($component->id, [
69+
'component_id' => $component->id,
70+
'created_at' => Carbon::now(),
71+
'assigned_qty' => 1,
72+
'asset_id' => $asset->id,
73+
]);
74+
75+
$this->actingAsForApi(User::factory()->checkoutComponents()->create())
76+
->postJson(route('api.components.checkout', $component->id), [
77+
'assigned_to' => $asset->id,
78+
'assigned_qty' => 3,
79+
])
80+
->assertOk()
81+
->assertStatusMessageIs('error');
82+
}
83+
84+
public function testCanCheckoutComponent()
85+
{
86+
$user = User::factory()->checkoutComponents()->create();
87+
$asset = Asset::factory()->create();
88+
$component = Component::factory()->create();
89+
90+
$this->actingAsForApi($user)
91+
->postJson(route('api.components.checkout', $component->id), [
92+
'assigned_to' => $asset->id,
93+
'assigned_qty' => 1,
94+
])
95+
->assertOk()
96+
->assertStatusMessageIs('success');
97+
98+
$this->assertTrue($component->assets->first()->is($asset));
99+
}
100+
101+
public function testComponentCheckoutIsLogged()
102+
{
103+
$user = User::factory()->checkoutComponents()->create();
104+
$location = Location::factory()->create();
105+
$asset = Asset::factory()->create(['location_id' => $location->id]);
106+
$component = Component::factory()->create();
107+
108+
$this->actingAsForApi($user)
109+
->postJson(route('api.components.checkout', $component->id), [
110+
'assigned_to' => $asset->id,
111+
'assigned_qty' => 1,
112+
]);
113+
114+
$this->assertDatabaseHas('action_logs', [
115+
'created_by' => $user->id,
116+
'action_type' => 'checkout',
117+
'target_id' => $asset->id,
118+
'target_type' => Asset::class,
119+
'location_id' => $location->id,
120+
'item_type' => Component::class,
121+
'item_id' => $component->id,
122+
]);
123+
}
124+
125+
public function testAdheresToFullMultipleCompaniesSupportScoping()
126+
{
127+
[$companyA, $companyB] = Company::factory()->count(2)->create();
128+
129+
$userForCompanyA = User::factory()->for($companyA)->create();
130+
$assetForCompanyB = Asset::factory()->for($companyB)->create();
131+
$componentForCompanyB = Component::factory()->for($companyB)->create();
132+
133+
$this->actingAsForApi($userForCompanyA)
134+
->postJson(route('api.components.checkout', $componentForCompanyB->id), [
135+
'assigned_to' => $assetForCompanyB->id,
136+
'assigned_qty' => 1,
137+
])
138+
->assertForbidden();
139+
}
140+
}

tests/Support/CustomTestMacros.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,5 +121,26 @@ function (array|string $keys) {
121121
return $this;
122122
}
123123
);
124+
125+
TestResponse::macro(
126+
'assertPayloadContains',
127+
function (array|string $keys) {
128+
Assert::assertArrayHasKey('payload', $this, 'Response did not contain a payload');
129+
130+
if (is_string($keys)) {
131+
$keys = [$keys];
132+
}
133+
134+
foreach ($keys as $key) {
135+
Assert::assertArrayHasKey(
136+
$key,
137+
$this['payload'],
138+
"Response messages did not contain the key: {$key}"
139+
);
140+
}
141+
142+
return $this;
143+
}
144+
);
124145
}
125146
}

0 commit comments

Comments
 (0)