mirror of
https://github.com/archtechx/tenancy.git
synced 2026-02-05 03:14:04 +00:00
Ignore routes that are already considered tenant routes from cloning, update test accordingly
This commit is contained in:
parent
410165e7ba
commit
efc0e11e73
2 changed files with 66 additions and 61 deletions
|
|
@ -111,6 +111,11 @@ class CloneRoutesAsTenant
|
||||||
|
|
||||||
protected function shouldBeCloned(Route $route): bool
|
protected function shouldBeCloned(Route $route): bool
|
||||||
{
|
{
|
||||||
|
// Don't clone routes that already have tenant parameter or prefix
|
||||||
|
if ($this->routeIsTenant($route)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->shouldClone) {
|
if ($this->shouldClone) {
|
||||||
return ($this->shouldClone)($route);
|
return ($this->shouldClone)($route);
|
||||||
}
|
}
|
||||||
|
|
@ -166,40 +171,12 @@ class CloneRoutesAsTenant
|
||||||
->setDefaults($originalRoute->defaults);
|
->setDefaults($originalRoute->defaults);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Removes top-level cloneRoutesWithMiddleware and adds 'tenant' middleware. */
|
||||||
* Process middleware for cloning, handling middleware groups properly.
|
|
||||||
* This extracts middleware from groups (up to 3 levels deep), filters out
|
|
||||||
* cloneRoutesWithMiddleware, and adds the 'tenant' middleware.
|
|
||||||
*
|
|
||||||
* Uses approach similar to getRouteMiddleware() in DealsWithRouteContexts for consistency.
|
|
||||||
*/
|
|
||||||
protected function processMiddlewareForCloning(array $middlewares): array
|
protected function processMiddlewareForCloning(array $middlewares): array
|
||||||
{
|
{
|
||||||
$middlewareGroups = $this->router->getMiddlewareGroups();
|
// Filter out top-level cloneRoutesWithMiddleware and add the 'tenant' flag
|
||||||
|
|
||||||
$unpackGroupMiddleware = function (array $middleware) use ($middlewareGroups) {
|
|
||||||
$innerMiddleware = [];
|
|
||||||
|
|
||||||
foreach ($middleware as $inner) {
|
|
||||||
if (isset($middlewareGroups[$inner])) {
|
|
||||||
$innerMiddleware = array_merge($innerMiddleware, $middlewareGroups[$inner]);
|
|
||||||
} else {
|
|
||||||
// Actual middleware, not a group
|
|
||||||
$innerMiddleware[] = $inner;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $innerMiddleware;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Extract all middleware from groups (up to 3 levels deep)
|
|
||||||
$firstLevelUnpacked = $unpackGroupMiddleware($middlewares);
|
|
||||||
$secondLevelUnpacked = $unpackGroupMiddleware($firstLevelUnpacked);
|
|
||||||
$thirdLevelUnpacked = $unpackGroupMiddleware($secondLevelUnpacked);
|
|
||||||
|
|
||||||
// Filter out MW in cloneRoutesWithMiddleware and add the 'tenant' flag
|
|
||||||
$processedMiddleware = array_filter(
|
$processedMiddleware = array_filter(
|
||||||
$thirdLevelUnpacked,
|
$middlewares,
|
||||||
fn ($mw) => ! in_array($mw, $this->cloneRoutesWithMiddleware)
|
fn ($mw) => ! in_array($mw, $this->cloneRoutesWithMiddleware)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -207,4 +184,13 @@ class CloneRoutesAsTenant
|
||||||
|
|
||||||
return array_unique($processedMiddleware);
|
return array_unique($processedMiddleware);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Check if route already has tenant parameter or name prefix. */
|
||||||
|
protected function routeIsTenant(Route $route): bool
|
||||||
|
{
|
||||||
|
$routeHasTenantParameter = in_array(PathTenantResolver::tenantParameterName(), $route->parameterNames());
|
||||||
|
$routeHasTenantPrefix = $route->getName() && str_starts_with($route->getName(), PathTenantResolver::tenantRouteNamePrefix());
|
||||||
|
|
||||||
|
return $routeHasTenantParameter || $routeHasTenantPrefix;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -215,43 +215,62 @@ test('clone action trims trailing slashes from prefixes given to nested route gr
|
||||||
->toBe("http://localhost/prefix/{$tenant->getTenantKey()}/home");
|
->toBe("http://localhost/prefix/{$tenant->getTenantKey()}/home");
|
||||||
});
|
});
|
||||||
|
|
||||||
test('clone middleware within middleware groups is properly handled during cloning', function () {
|
test('tenant routes are ignored from cloning and clone middleware in groups causes no issues', function () {
|
||||||
// Simple MW group with 'clone' flag
|
// Should NOT be cloned, already has tenant parameter
|
||||||
RouteFacade::middlewareGroup('simple-group', ['auth', 'clone']);
|
RouteFacade::get("/{tenant}/route-with-tenant-parameter", fn () => true)
|
||||||
|
->middleware(['clone'])
|
||||||
|
->name("tenant.route-with-tenant-parameter");
|
||||||
|
|
||||||
// Define nested middleware groups 3 levels deep
|
// Should NOT be cloned
|
||||||
RouteFacade::middlewareGroup('level-3-group', ['clone']);
|
// The route already has tenant name prefix
|
||||||
RouteFacade::middlewareGroup('level-2-group', ['auth', 'level-3-group']);
|
RouteFacade::get("/route-with-tenant-name-prefix", fn () => true)
|
||||||
RouteFacade::middlewareGroup('nested-group', ['web', 'level-2-group']);
|
->middleware(['clone'])
|
||||||
|
->name("tenant.route-with-tenant-name-prefix");
|
||||||
|
|
||||||
// Create routes using both simple and nested middleware groups
|
// Should NOT be cloned
|
||||||
RouteFacade::get('/simple', fn () => true)
|
// The route already has a tenant parameter + 'clone' middleware in group
|
||||||
->middleware('simple-group')
|
// 'clone' MW in groups won't be removed, this also doesn't cause any issues
|
||||||
->name('simple');
|
RouteFacade::middlewareGroup('group', ['auth', 'clone']);
|
||||||
|
RouteFacade::get("/{tenant}/route-with-clone-in-mw-group", fn () => true)
|
||||||
|
->middleware('group')
|
||||||
|
->name("tenant.route-with-clone-in-mw-group");
|
||||||
|
|
||||||
RouteFacade::get('/nested', fn () => true)
|
// SHOULD be cloned (with clone middleware)
|
||||||
->middleware('nested-group')
|
RouteFacade::get('/foo', fn () => true)
|
||||||
->name('nested');
|
->middleware(['clone'])
|
||||||
|
->name('foo');
|
||||||
|
|
||||||
app(CloneRoutesAsTenant::class)->handle();
|
// SHOULD be cloned (with nested clone middleware)
|
||||||
|
RouteFacade::get('/bar', fn () => true)
|
||||||
|
->middleware(['group'])
|
||||||
|
->name('bar');
|
||||||
|
|
||||||
// Test simple middleware group handling
|
$cloneAction = app(CloneRoutesAsTenant::class);
|
||||||
$clonedSimpleRoute = RouteFacade::getRoutes()->getByName('tenant.simple');
|
$initialRouteCount = count(RouteFacade::getRoutes()->get());
|
||||||
expect($clonedSimpleRoute)->not()->toBeNull();
|
|
||||||
|
|
||||||
$simpleRouteMiddleware = tenancy()->getRouteMiddleware($clonedSimpleRoute);
|
// Run clone action multiple times
|
||||||
expect($simpleRouteMiddleware)
|
$cloneAction->handle();
|
||||||
->toContain('auth', 'tenant')
|
$firstRunCount = count(RouteFacade::getRoutes()->get());
|
||||||
->not()->toContain('clone', 'simple-group');
|
|
||||||
|
|
||||||
// Test nested middleware group handling (3 levels deep)
|
$cloneAction->handle();
|
||||||
$clonedNestedRoute = RouteFacade::getRoutes()->getByName('tenant.nested');
|
$secondRunCount = count(RouteFacade::getRoutes()->get());
|
||||||
expect($clonedNestedRoute)->not()->toBeNull();
|
|
||||||
|
|
||||||
$nestedRouteMiddleware = tenancy()->getRouteMiddleware($clonedNestedRoute);
|
$cloneAction->handle();
|
||||||
|
$thirdRunCount = count(RouteFacade::getRoutes()->get());
|
||||||
|
|
||||||
expect($nestedRouteMiddleware)
|
// Two route should have been cloned, and only once
|
||||||
->toContain('web', 'auth', 'tenant')
|
expect($firstRunCount)->toBe($initialRouteCount + 2);
|
||||||
// Shouldn't contain 'clone' or any nested group names
|
// No new routes on subsequent runs
|
||||||
->not()->toContain('clone', 'nested-group', 'level-2-group', 'level-3-group');
|
expect($secondRunCount)->toBe($firstRunCount);
|
||||||
|
expect($thirdRunCount)->toBe($firstRunCount);
|
||||||
|
|
||||||
|
// Verify the correct routes were cloned
|
||||||
|
expect(RouteFacade::getRoutes()->getByName('tenant.foo'))->not()->toBeNull();
|
||||||
|
expect(RouteFacade::getRoutes()->getByName('tenant.bar'))->not()->toBeNull();
|
||||||
|
|
||||||
|
// Tenant routes were not duplicated
|
||||||
|
$allRouteNames = collect(RouteFacade::getRoutes()->get())->map->getName()->filter();
|
||||||
|
expect($allRouteNames->filter(fn($name) => str_contains($name, 'route-with-tenant-parameter'))->count())->toBe(1);
|
||||||
|
expect($allRouteNames->filter(fn($name) => str_contains($name, 'route-with-tenant-name-prefix'))->count())->toBe(1);
|
||||||
|
expect($allRouteNames->filter(fn($name) => str_contains($name, 'route-with-clone-in-mw-group'))->count())->toBe(1);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue