-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #150 from sorrell/carrier-testing
Carrier testing
- Loading branch information
Showing
6 changed files
with
307 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?php | ||
|
||
namespace App\Rules; | ||
|
||
use Propaganistas\LaravelPhone\Rules\Phone; | ||
|
||
class ValidPhoneNumber extends Phone | ||
{ | ||
public function __construct() | ||
{ | ||
$this->countries = explode(',', trim(config('phones.valid_countries'))); | ||
} | ||
|
||
public function message() | ||
{ | ||
return 'The :attribute field must be a valid phone number within a supported country (' . implode(', ', $this->countries) .')'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<?php | ||
|
||
return [ | ||
/* | ||
|-------------------------------------------------------------------------- | ||
| Valid Countries for Phone Numbers | ||
|-------------------------------------------------------------------------- | ||
| | ||
| A comma-separated list of ISO 3166-1 alpha-2 country codes that are | ||
| considered valid for phone number validation. | ||
| | ||
*/ | ||
'valid_countries' => env('VALID_PHONE_COUNTRIES', 'US,CA'), | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
<?php | ||
|
||
namespace Tests\Feature\Carriers; | ||
|
||
use App\Actions\Carriers\CreateCarrier; | ||
use App\Models\Location; | ||
use App\Models\Organizations\Organization; | ||
use App\Models\User; | ||
use App\Models\Carrier; | ||
use Illuminate\Support\Facades\Context; | ||
use Inertia\Testing\AssertableInertia; | ||
|
||
beforeEach(function () { | ||
$this->setUpOrganization(); | ||
|
||
$this->location = Location::factory()->create(); | ||
|
||
// Set up second organization and user | ||
$this->secondUser = User::factory()->create(); | ||
$this->secondOrg = Organization::create([ | ||
'name' => 'Second Test Organization', | ||
'owner_id' => $this->secondUser->id, | ||
]); | ||
$this->secondUser->organizations()->attach($this->secondOrg); | ||
$this->secondUser->current_organization_id = $this->secondOrg->id; | ||
$this->secondUser->save(); | ||
|
||
// Store organization IDs and initial active user | ||
$this->firstOrgId = $this->organization->id; | ||
$this->secondOrgId = $this->secondOrg->id; | ||
$this->activeUser = $this->user; | ||
|
||
// Helper functions to make tests more readable | ||
$this->switchToFirstOrg = function () { | ||
Context::addHidden('current_organization_id', $this->firstOrgId); | ||
$this->activeUser = $this->user; | ||
}; | ||
|
||
$this->switchToSecondOrg = function () { | ||
Context::addHidden('current_organization_id', $this->secondOrgId); | ||
$this->activeUser = $this->secondUser; | ||
}; | ||
|
||
$this->createTestCarrier = function ($name = 'Test Carrier') { | ||
return CreateCarrier::run(name: $name); | ||
}; | ||
}); | ||
|
||
test('it prevents access to carriers from other organizations', function () { | ||
$carrier = ($this->createTestCarrier)(); | ||
|
||
// Verify first organization access | ||
$response = $this->actingAs($this->activeUser)->get(route('carriers.show', $carrier)); | ||
expect($response->status())->toBe(200); | ||
|
||
// Verify second organization cannot access | ||
($this->switchToSecondOrg)(); | ||
$response = $this->actingAs($this->activeUser)->get(route('carriers.show', $carrier)); | ||
expect($response->status())->toBe(404); | ||
|
||
// Verify first organization still has access | ||
($this->switchToFirstOrg)(); | ||
$response = $this->actingAs($this->activeUser)->get(route('carriers.show', $carrier)); | ||
expect($response->status())->toBe(200); | ||
}); | ||
|
||
test('it prevents updating carriers from other organizations', function () { | ||
// Create carrier in first organization | ||
$response = $this->actingAs($this->activeUser) | ||
->withHeaders(['Accept' => 'application/json']) | ||
->post(route('carriers.store'), [ | ||
'name' => 'Test Carrier', | ||
]); | ||
expect($response->status())->toBe(201); | ||
|
||
$carrier = Carrier::findOrFail($response->json('id')); | ||
$updateData = [ | ||
'name' => 'Updated Name', | ||
'mc_number' => 'MC123456', | ||
'dot_number' => 'DOT789012', | ||
'physical_location_id' => $this->location->id, | ||
'contact_email' => '[email protected]', | ||
'contact_phone' => '(513) 731-4567', | ||
]; | ||
|
||
// Test update with second organization | ||
($this->switchToSecondOrg)(); | ||
$response = $this->actingAs($this->activeUser)->put(route('carriers.update', $carrier), $updateData); | ||
expect($response->status())->toBe(404); | ||
|
||
// Verify first organization can still update | ||
($this->switchToFirstOrg)(); | ||
$response = $this->actingAs($this->activeUser)->put(route('carriers.update', $carrier), $updateData); | ||
expect($response->status())->toBe(200); | ||
}); | ||
|
||
test('it prevents deleting carriers from other organizations', function () { | ||
$carrier = ($this->createTestCarrier)(); | ||
|
||
// Attempt delete from second organization | ||
($this->switchToSecondOrg)(); | ||
$response = $this->actingAs($this->activeUser)->delete(route('carriers.destroy', $carrier)); | ||
expect($response->status())->toBe(404); | ||
|
||
// Verify carrier still exists | ||
($this->switchToFirstOrg)(); | ||
expect(Carrier::find($carrier->id))->not->toBeNull(); | ||
|
||
// Verify first organization can delete | ||
$response = $this->actingAs($this->activeUser)->delete(route('carriers.destroy', $carrier)); | ||
expect($response->status())->toBe(200); | ||
}); | ||
|
||
test('it prevents listing carriers from other organizations', function () { | ||
// Create carriers in first organization | ||
($this->createTestCarrier)('First Org Carrier 1'); | ||
($this->createTestCarrier)('First Org Carrier 2'); | ||
|
||
// Create carrier in second organization | ||
($this->switchToSecondOrg)(); | ||
($this->createTestCarrier)('Second Org Carrier'); | ||
|
||
// Verify second organization only sees its carrier | ||
$response = $this->actingAs($this->activeUser)->get(route('carriers.search')); | ||
$carriers = $response->json(); | ||
expect(count($carriers))->toBe(1); | ||
expect($carriers[0]['name'])->toBe('Second Org Carrier'); | ||
|
||
// Verify first organization only sees its carriers | ||
($this->switchToFirstOrg)(); | ||
$response = $this->actingAs($this->activeUser)->get(route('carriers.search')); | ||
$carriers = $response->json(); | ||
expect(count($carriers))->toBe(2); | ||
$names = array_column($carriers, 'name'); | ||
expect($names)->toContain('First Org Carrier 1'); | ||
expect($names)->toContain('First Org Carrier 2'); | ||
}); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
<?php | ||
|
||
namespace Tests\Unit\Actions\Carriers; | ||
|
||
use App\Actions\Carriers\CreateCarrier; | ||
use App\Actions\Carriers\UpdateCarrierGeneral; | ||
use App\Models\Carrier; | ||
use App\Models\Location; | ||
use Illuminate\Support\Facades\DB; | ||
|
||
beforeEach(function () { | ||
$this->location = Location::factory()->create(); | ||
}); | ||
|
||
test('it creates basic carrier with required fields', function () { | ||
// Act | ||
$carrier = CreateCarrier::run( | ||
name: 'Test Carrier', | ||
); | ||
|
||
// Assert | ||
expect($carrier)->toBeInstanceOf(Carrier::class); | ||
|
||
expect(DB::table('carriers')->where([ | ||
'id' => $carrier->id, | ||
'name' => 'Test Carrier', | ||
])->exists())->toBeTrue(); | ||
}); | ||
|
||
test('it creates carrier with all optional fields', function () { | ||
// Act | ||
$carrier = CreateCarrier::run( | ||
name: 'Full Details Carrier', | ||
); | ||
|
||
// Act | ||
$updatedCarrier = UpdateCarrierGeneral::run( | ||
carrier: $carrier, | ||
name: 'Updated Carrier Name', | ||
mc_number: 'MC123456', | ||
dot_number: 'DOT789012', | ||
physical_location_id: $this->location->id, | ||
contact_email: '[email protected]', | ||
contact_phone: '(555) 123-4567', | ||
); | ||
|
||
// Assert | ||
expect($updatedCarrier)->toBeInstanceOf(Carrier::class); | ||
|
||
expect(DB::table('carriers')->where([ | ||
'id' => $updatedCarrier->id, | ||
'name' => 'Updated Carrier Name', | ||
'mc_number' => 'MC123456', | ||
'dot_number' => 'DOT789012', | ||
'physical_location_id' => $this->location->id, | ||
'contact_email' => '[email protected]', | ||
'contact_phone' => '(555) 123-4567', | ||
])->exists())->toBeTrue(); | ||
}); | ||
|
||
test('it updates carrier general details partially', function () { | ||
// Create initial carrier | ||
$carrier = CreateCarrier::run( | ||
name: 'Initial Carrier', | ||
); | ||
|
||
// Act - update only some fields | ||
$updatedCarrier = UpdateCarrierGeneral::run( | ||
carrier: $carrier, | ||
name: 'New Name', | ||
mc_number: 'MC999999', | ||
); | ||
|
||
// Assert | ||
expect(DB::table('carriers')->where([ | ||
'id' => $carrier->id, | ||
'name' => 'New Name', | ||
'mc_number' => 'MC999999', | ||
])->exists())->toBeTrue(); | ||
|
||
// Verify other fields remain null | ||
expect($updatedCarrier->dot_number)->toBeNull(); | ||
expect($updatedCarrier->physical_location_id)->toBeNull(); | ||
expect($updatedCarrier->contact_email)->toBeNull(); | ||
expect($updatedCarrier->contact_phone)->toBeNull(); | ||
}); | ||
|
||
test('it updates carrier contact information', function () { | ||
// Create initial carrier | ||
$carrier = CreateCarrier::run( | ||
name: 'Contact Test Carrier', | ||
); | ||
|
||
// Act | ||
$updatedCarrier = UpdateCarrierGeneral::run( | ||
carrier: $carrier, | ||
contact_email: '[email protected]', | ||
contact_phone: '(555) 999-8888', | ||
); | ||
|
||
// Assert | ||
expect(DB::table('carriers')->where([ | ||
'id' => $carrier->id, | ||
'contact_email' => '[email protected]', | ||
'contact_phone' => '(555) 999-8888', | ||
])->exists())->toBeTrue(); | ||
}); | ||
|
||
test('it updates carrier location', function () { | ||
// Create initial carrier | ||
$carrier = CreateCarrier::run( | ||
name: 'Location Test Carrier', | ||
); | ||
|
||
$newLocation = Location::factory()->create(); | ||
|
||
// Act | ||
$updatedCarrier = UpdateCarrierGeneral::run( | ||
carrier: $carrier, | ||
physical_location_id: $newLocation->id, | ||
); | ||
|
||
// Assert | ||
expect($updatedCarrier->physical_location_id)->toBe($newLocation->id); | ||
expect(DB::table('carriers')->where([ | ||
'id' => $carrier->id, | ||
'physical_location_id' => $newLocation->id, | ||
])->exists())->toBeTrue(); | ||
}); |