mirror of
https://github.com/archtechx/tenancy.git
synced 2026-02-05 01:14:03 +00:00
minor refactor in PathIdentificationTest, expand CLAUDE.md to include early identification section
This commit is contained in:
parent
b6ae810e20
commit
e51678b21c
2 changed files with 36 additions and 6 deletions
30
CLAUDE.md
30
CLAUDE.md
|
|
@ -77,6 +77,36 @@ All of these work as flags, i.e. middleware groups that are empty arrays with a
|
||||||
- `universal` - Routes working in both contexts
|
- `universal` - Routes working in both contexts
|
||||||
- `clone` - Tells route cloning logic to clone the route
|
- `clone` - Tells route cloning logic to clone the route
|
||||||
|
|
||||||
|
### Early Identification
|
||||||
|
|
||||||
|
**Early identification** ensures tenancy is initialized before controller instantiation, which is critical for certain scenarios.
|
||||||
|
|
||||||
|
**When needed:**
|
||||||
|
- Controllers using constructor dependency injection
|
||||||
|
- Integration with packages that inject dependencies in constructors
|
||||||
|
|
||||||
|
**The Problem:**
|
||||||
|
Laravel executes controller constructors and route model binding before route-level middleware runs, causing services to use central context instead of tenant context.
|
||||||
|
|
||||||
|
**Solutions:**
|
||||||
|
1. **Avoid Constructor Injection** - Use method injection instead
|
||||||
|
2. **Laravel's Native Solution** - Use controllers that implement `HasMiddleware` interface
|
||||||
|
3. **Kernel Identification** - Add middleware to HTTP Kernel's global stack:
|
||||||
|
|
||||||
|
```php
|
||||||
|
// In HttpKernel.php
|
||||||
|
protected $middleware = [
|
||||||
|
\Stancl\Tenancy\Middleware\InitializeTenancyByDomain::class,
|
||||||
|
// other middleware...
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
Note you also need to flag the route with the `'tenant'` middleware if default route mode (set in config) isn't set to TENANT.
|
||||||
|
|
||||||
|
**Benefits:**
|
||||||
|
- Constructor dependency injection receives tenant-aware services
|
||||||
|
- Seamless integration with existing Laravel applications
|
||||||
|
|
||||||
### Testing Environment
|
### Testing Environment
|
||||||
|
|
||||||
Tests use Docker with MySQL/PostgreSQL/Redis. The `./test` script runs Pest tests inside containers with proper database isolation.
|
Tests use Docker with MySQL/PostgreSQL/Redis. The `./test` script runs Pest tests inside containers with proper database isolation.
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,11 @@ beforeEach(function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterEach(function () {
|
||||||
|
InitializeTenancyByPath::$onFail = null;
|
||||||
|
Tenant::$extraCustomColumns = [];
|
||||||
|
});
|
||||||
|
|
||||||
test('tenant can be identified by path', function () {
|
test('tenant can be identified by path', function () {
|
||||||
Tenant::create([
|
Tenant::create([
|
||||||
'id' => 'acme',
|
'id' => 'acme',
|
||||||
|
|
@ -150,6 +155,7 @@ test('central route can have a parameter with the same name as the tenant parame
|
||||||
config(['tenancy.identification.resolvers.' . PathTenantResolver::class . '.tenant_parameter_name' => 'team']);
|
config(['tenancy.identification.resolvers.' . PathTenantResolver::class . '.tenant_parameter_name' => 'team']);
|
||||||
$tenantKey = Tenant::create()->getTenantKey();
|
$tenantKey = Tenant::create()->getTenantKey();
|
||||||
|
|
||||||
|
// The route is flagged as central (while using kernel identification) so the {team} parameter should not be used for tenancy initialization
|
||||||
Route::get('/central/route/{team}/{a}/{b}', function ($team, $a, $b) {
|
Route::get('/central/route/{team}/{a}/{b}', function ($team, $a, $b) {
|
||||||
return "$a + $b + $team";
|
return "$a + $b + $team";
|
||||||
})->middleware('central')->name('central-route');
|
})->middleware('central')->name('central-route');
|
||||||
|
|
@ -185,8 +191,6 @@ test('the tenant model column can be customized in the config', function () {
|
||||||
$this->withoutExceptionHandling();
|
$this->withoutExceptionHandling();
|
||||||
pest()->get('/acme/foo')->assertSee($tenant->getTenantKey());
|
pest()->get('/acme/foo')->assertSee($tenant->getTenantKey());
|
||||||
expect(fn () => pest()->get($tenant->id . '/foo'))->toThrow(TenantCouldNotBeIdentifiedByPathException::class);
|
expect(fn () => pest()->get($tenant->id . '/foo'))->toThrow(TenantCouldNotBeIdentifiedByPathException::class);
|
||||||
|
|
||||||
Tenant::$extraCustomColumns = []; // static property reset
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('the tenant model column can be customized in the route definition', function () {
|
test('the tenant model column can be customized in the route definition', function () {
|
||||||
|
|
@ -218,8 +222,6 @@ test('the tenant model column can be customized in the route definition', functi
|
||||||
// Binding field defined
|
// Binding field defined
|
||||||
pest()->get('/acme/bar')->assertSee($tenant->getTenantKey());
|
pest()->get('/acme/bar')->assertSee($tenant->getTenantKey());
|
||||||
expect(fn () => pest()->get($tenant->id . '/bar'))->toThrow(TenantCouldNotBeIdentifiedByPathException::class);
|
expect(fn () => pest()->get($tenant->id . '/bar'))->toThrow(TenantCouldNotBeIdentifiedByPathException::class);
|
||||||
|
|
||||||
Tenant::$extraCustomColumns = []; // static property reset
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('any extra model column needs to be whitelisted', function () {
|
test('any extra model column needs to be whitelisted', function () {
|
||||||
|
|
@ -243,6 +245,4 @@ test('any extra model column needs to be whitelisted', function () {
|
||||||
// After whitelisting the column it works
|
// After whitelisting the column it works
|
||||||
config(['tenancy.identification.resolvers.' . PathTenantResolver::class . '.allowed_extra_model_columns' => ['slug']]);
|
config(['tenancy.identification.resolvers.' . PathTenantResolver::class . '.allowed_extra_model_columns' => ['slug']]);
|
||||||
pest()->get('/acme/foo')->assertSee($tenant->getTenantKey());
|
pest()->get('/acme/foo')->assertSee($tenant->getTenantKey());
|
||||||
|
|
||||||
Tenant::$extraCustomColumns = []; // static property reset
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue