Skip to content

[4.x] Change tenant storage listeners into jobs#1446

Merged
stancl merged 11 commits intomasterfrom
storage-listeners
Apr 22, 2026
Merged

[4.x] Change tenant storage listeners into jobs#1446
stancl merged 11 commits intomasterfrom
storage-listeners

Conversation

@lukinovec
Copy link
Copy Markdown
Contributor

@lukinovec lukinovec commented Mar 26, 2026

The CreateTenantStorage and DeleteTenantStorage listeners were used alongside JobPipelines. When the TenantCreated JobPipeline had shouldBeQueued(true) and the Listeners\CreateTenantStorage was uncommented, the listener would throw an exception (Stancl\Tenancy\Database\Exceptions\TenantDatabaseDoesNotExistException Database tenantX.sqlite does not exist.) because at the time of executing the listener, the tenant DB wasn't created yet.

The same issue could likely also occur in the DeleteTenantStorage listener as it uses tenancy()->run() to resolve the tenant's storage path which wouldn't work if the tenant's database (or other resources) was already deleted, making initialization impossible.

This PR changes DeleteTenantStorage into a job and puts it (commented) into the job pipeline, so that it can be queued with the rest of the jobs. It also removes CreateTenantStorage because it should be redundant with the FilesystemTenancyBootstrapper creating the same paths automatically when storage path is suffixed.

The old classes are kept but deprecated for backwards compatibility.

We've also added some edge case hardening to DeleteTenantStorage to make sure it never deletes the central storage path directory, which previously could in theory occur due to a misconfiguration if a user enabled this job/listener but disabled storage path suffixing.

Summary by CodeRabbit

  • New Features

    • Added queued job support for tenant storage deletion.
  • Improvements

    • Safer storage deletion: extra checks prevent accidental removal of central/shared storage and only remove tenant-scoped directories when appropriate.
    • Event listener configuration updated to favor job pipelines.
  • Tests

    • Updated tests to verify deletion behavior across configuration scenarios.
  • Deprecations

    • Storage operation listeners marked deprecated in favor of job-based pipeline.

lukinovec and others added 2 commits March 26, 2026 15:34
Also move the commented jobs to the JobPipelines and update FilesystemTenancyBootstrapperTest accordingly.
@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 26, 2026

Codecov Report

❌ Patch coverage is 57.89474% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.84%. Comparing base (c32f52c) to head (3f9f7cd).
⚠️ Report is 2 commits behind head on master.

Files with missing lines Patch % Lines
src/Listeners/DeleteTenantStorage.php 0.00% 8 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master    #1446      +/-   ##
============================================
- Coverage     86.03%   85.84%   -0.20%     
- Complexity     1156     1163       +7     
============================================
  Files           184      185       +1     
  Lines          3381     3397      +16     
============================================
+ Hits           2909     2916       +7     
- Misses          472      481       +9     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@lukinovec lukinovec marked this pull request as ready for review March 27, 2026 13:40
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 12, 2026

📝 Walkthrough

Walkthrough

Adds a queued job to remove tenant storage, updates the existing listener to a deprecated, safer implementation that avoids deleting central storage, adjusts the service provider stub comments to recommend the job pipeline, and updates tests to exercise deletion behavior across tenancy.filesystem.suffix_storage_path configurations. (50 words)

Changes

Cohort / File(s) Summary
Job Implementation
src/Jobs/DeleteTenantStorage.php
Added queued job DeleteTenantStorage accepting a Tenant; checks tenancy.filesystem.suffix_storage_path, resolves central vs tenant storage paths, avoids deleting central path, and deletes tenant storage directory via File::deleteDirectory().
Listeners
src/Listeners/DeleteTenantStorage.php, src/Listeners/CreateTenantStorage.php
DeleteTenantStorage listener now early-returns when suffixing is disabled, resolves central and tenant storage_path() to prevent deleting shared storage, and is marked @deprecated in favor of the job pipeline. CreateTenantStorage PHPDoc updated to a deprecation note; no behavior changes.
Provider Stub & Tests
assets/TenancyServiceProvider.stub.php, tests/Bootstrappers/FilesystemTenancyBootstrapperTest.php
Provider stub comment lines updated to show using JobsPipeline entries (commented). Test updated to register deletion via a JobPipeline-converted listener and to assert real filesystem directory state across three suffix_storage_path scenarios.

Sequence Diagram

sequenceDiagram
    participant Event as DeletingTenant Event
    participant Pipeline as JobPipeline
    participant Job as DeleteTenantStorage Job
    participant Config as Config
    participant FS as Filesystem

    Event->>Pipeline: map $event->tenant -> DeleteTenantStorage
    Pipeline->>Job: invoke job (queued or sync)
    Job->>Config: read tenancy.filesystem.suffix_storage_path
    alt suffix disabled
        Job-->>Job: return early (no deletion)
    else suffix enabled
        Job->>Job: resolve central storage path (tenancy()->central)
        Job->>Job: resolve tenant storage path (tenancy()->run)
        alt paths equal
            Job-->>Job: return early (protect central storage)
        else paths differ
            Job->>FS: check tenant path is directory
            alt exists
                Job->>FS: delete tenant directory
            end
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped through code with a whisker and wink,
Queued jobs tidy burrows before anyone blink,
Listeners bow out with a deprecated cheer,
Central nests safe while tenant paths clear—hop, hop, dear! 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: converting storage event listeners into jobs, which is the primary objective of the PR.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch storage-listeners

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/Bootstrappers/FilesystemTenancyBootstrapperTest.php (1)

188-206: Make suffix assumptions explicit in the new creation test.

The assertion on Line 203 assumes default tenant suffix behavior. Pinning the relevant config in this test will make it less brittle to future default changes.

✅ Suggested test hardening
 test('tenant storage gets created when TenantCreated listens to CreateTenantStorage', function() {
     config([
         'tenancy.bootstrappers' => [
             FilesystemTenancyBootstrapper::class,
         ],
+        'tenancy.filesystem.suffix_storage_path' => true,
+        'tenancy.filesystem.suffix_base' => 'tenant',
     ]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/Bootstrappers/FilesystemTenancyBootstrapperTest.php` around lines 188 -
206, The test assumes a hard-coded "tenant" suffix when building
$tenantStoragePath; make that explicit by pinning the suffix in the test (e.g.
add config(['tenancy.storage.suffix' => 'tenant']);) and/or build
$tenantStoragePath from the config value instead of the literal string so
FilesystemTenancyBootstrapperTest's test('tenant storage gets created when
TenantCreated listens to CreateTenantStorage', ...) and the final
$this->assertDirectoryExists(...) no longer rely on implicit defaults.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/Jobs/DeleteTenantStorage.php`:
- Around line 25-29: DeleteTenantStorage currently calls
tenancy()->run($this->tenant, fn () => storage_path()) and then
File::deleteDirectory($path) which can remove the central storage when
tenancy.filesystem.suffix_storage_path is false; change the logic in
DeleteTenantStorage so you first resolve both the tenant-specific path and the
central storage path and verify the tenant path is not identical to the central
one (or contains the tenant identifier) before calling File::deleteDirectory;
use tenancy()->run($this->tenant, ...) and storage_path() for comparisons and
bail out / log and skip deletion if the resolved $path equals the default
storage_path() or fails a tenant-specific containment check.

---

Nitpick comments:
In `@tests/Bootstrappers/FilesystemTenancyBootstrapperTest.php`:
- Around line 188-206: The test assumes a hard-coded "tenant" suffix when
building $tenantStoragePath; make that explicit by pinning the suffix in the
test (e.g. add config(['tenancy.storage.suffix' => 'tenant']);) and/or build
$tenantStoragePath from the config value instead of the literal string so
FilesystemTenancyBootstrapperTest's test('tenant storage gets created when
TenantCreated listens to CreateTenantStorage', ...) and the final
$this->assertDirectoryExists(...) no longer rely on implicit defaults.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a284bf55-8fa0-481b-9971-86bdd3e8225d

📥 Commits

Reviewing files that changed from the base of the PR and between 60dd522 and dc659ed.

📒 Files selected for processing (5)
  • assets/TenancyServiceProvider.stub.php
  • src/Jobs/CreateTenantStorage.php
  • src/Jobs/DeleteTenantStorage.php
  • src/Listeners/DeleteTenantStorage.php
  • tests/Bootstrappers/FilesystemTenancyBootstrapperTest.php
💤 Files with no reviewable changes (1)
  • src/Listeners/DeleteTenantStorage.php

Comment thread src/Jobs/DeleteTenantStorage.php Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/Jobs/DeleteTenantStorage.php`:
- Around line 43-44: The directory deletion currently calls
File::deleteDirectory($path) and ignores its return value, so failures are
silent; update the DeleteTenantStorage job to capture the return from
File::deleteDirectory($path) (when is_dir($path) && ! $tenantPathIsCentral) and
if it returns false throw an exception (e.g., RuntimeException) including $path
in the message so the queue marks the job as failed and can be retried/alerted;
ensure you do this inside the method that performs the deletion (referencing
File::deleteDirectory, $path, and $tenantPathIsCentral).

In `@tests/Bootstrappers/FilesystemTenancyBootstrapperTest.php`:
- Line 203: The test hard-codes '/tenant' when building $tenantStoragePath;
change it to use the configured suffix base instead so it follows tenancy
configuration. Replace the literal '/tenant' with a dynamic value obtained from
config('tenancy.filesystem.suffix_base') (or the same helper used in
production), i.e. build $tenantStoragePath by concatenating $centralStoragePath
with the configured suffix base and $tenant->getTenantKey(); update any related
expectations to use that same config-derived value.
- Around line 195-199: The test currently registers listeners for TenantCreated
using Event::listen with
JobPipeline::make([...])->shouldBeQueued(false)->toListener(), which disables
queuing and therefore doesn't exercise serialization/queued execution order;
change the listeners for both storage and database jobs (e.g., the
JobPipeline::make([...]) entries for CreateTenantStorage and the corresponding
CreateTenantDatabase) to use queued execution (remove or set
shouldBeQueued(true) / omit shouldBeQueued(false)) and then assert the jobs are
dispatched to the queue and executed in the expected order (use the framework's
queue fake / assertions to assert queuing and execution order for TenantCreated
handling).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 899f92bb-5773-4f84-b10c-6703b0e57ea8

📥 Commits

Reviewing files that changed from the base of the PR and between dc659ed and 33c2840.

📒 Files selected for processing (2)
  • src/Jobs/DeleteTenantStorage.php
  • tests/Bootstrappers/FilesystemTenancyBootstrapperTest.php

Comment thread src/Jobs/DeleteTenantStorage.php Outdated
Comment thread tests/Bootstrappers/FilesystemTenancyBootstrapperTest.php Outdated
Comment thread tests/Bootstrappers/FilesystemTenancyBootstrapperTest.php Outdated
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
tests/Bootstrappers/FilesystemTenancyBootstrapperTest.php (1)

195-199: ⚠️ Potential issue | 🟠 Major

Queued JobPipeline path is still not exercised in tests.

Lines 195-199 and 210-214 force shouldBeQueued(false), so these tests only validate synchronous execution and miss the queue/serialization path that this PR targets.

#!/bin/bash
# Verify storage job tests are synchronous-only and lack queue assertions
rg -n -C2 'CreateTenantStorage|DeleteTenantStorage|shouldBeQueued\(' tests/Bootstrappers/FilesystemTenancyBootstrapperTest.php
rg -n -C2 'Queue::fake|Queue::assertPushed|Bus::fake|Bus::assertDispatched' tests/Bootstrappers/FilesystemTenancyBootstrapperTest.php

Expected verification outcome:

  • First command shows shouldBeQueued(false) for both storage job pipelines.
  • Second command returns no queue-fake/assert coverage in this file.

Also applies to: 210-214

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/Bootstrappers/FilesystemTenancyBootstrapperTest.php` around lines 195 -
199, Tests currently force synchronous execution by calling
shouldBeQueued(false) on the Event listener pipelines
(JobPipeline::make([...])->shouldBeQueued(false)), so the queue/serialization
path (CreateTenantStorage, DeleteTenantStorage) is never exercised; change the
tests to cover the queued path by removing or changing shouldBeQueued(false) for
the TenantCreated/TenantDeleted listeners and use a queue fake (e.g.,
Queue::fake()) around the event dispatch, then assert the job was queued
(Queue::assertPushed or similar) for CreateTenantStorage and DeleteTenantStorage
after dispatching TenantCreated/TenantDeleted events to validate the
serialized/queued behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@tests/Bootstrappers/FilesystemTenancyBootstrapperTest.php`:
- Around line 195-199: Tests currently force synchronous execution by calling
shouldBeQueued(false) on the Event listener pipelines
(JobPipeline::make([...])->shouldBeQueued(false)), so the queue/serialization
path (CreateTenantStorage, DeleteTenantStorage) is never exercised; change the
tests to cover the queued path by removing or changing shouldBeQueued(false) for
the TenantCreated/TenantDeleted listeners and use a queue fake (e.g.,
Queue::fake()) around the event dispatch, then assert the job was queued
(Queue::assertPushed or similar) for CreateTenantStorage and DeleteTenantStorage
after dispatching TenantCreated/TenantDeleted events to validate the
serialized/queued behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 5bf88f56-0bfa-4b2b-8dd5-223cb4f6d6ab

📥 Commits

Reviewing files that changed from the base of the PR and between 33c2840 and 5e0153c.

📒 Files selected for processing (1)
  • tests/Bootstrappers/FilesystemTenancyBootstrapperTest.php

@lukinovec
Copy link
Copy Markdown
Contributor Author

@coderabbitai resume

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 14, 2026

✅ Actions performed

Reviews resumed.

@lukinovec
Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 14, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@lukinovec
Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 14, 2026

✅ Actions performed

Full review triggered.

@stancl stancl marked this pull request as draft April 18, 2026 19:16
lukinovec and others added 2 commits April 20, 2026 09:05
Without this, updating Tenancy in existing projects would break TenancyServiceProvider. The logic of the deprecated versions is up-to-date with the changes made in the jobs up until now.
1. Remove the CreateTenantStorage job altogether since as the docblock
   says the class should be redundant now that
   FilesystemTenancyBootstrapper creates this path automatically when
   storage_path suffixing is enabled
2. Remove docblock on the DeleteTenantStorage job - a class's docblock
   should describe what it does, not how it handles edge cases. Here
   the former isn't even necessary and the latter is well explained by
   comments in the implementation.
3. Remove the CreateTenantStorage test following the class's removal,
   the test would pass on its own even without the job with just
   tenancy initialization as mentioned above.
4. Slightly improve the structure of the DeleteTenantStorage job and
   deprecated listener
5. Improve deprecation notices so they include full steps for upgrading
   to the new approach.
@stancl stancl marked this pull request as ready for review April 20, 2026 16:29
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/Bootstrappers/FilesystemTenancyBootstrapperTest.php`:
- Around line 194-201: The test assumes FilesystemTenancyBootstrapper is
disabled but never sets it explicitly, so make the scenario robust by explicitly
disabling that bootstrapper before calling
tenancy()->initialize(Tenant::create()); e.g. adjust the tenancy bootstrappers
config or call the config helper to remove/disable FilesystemTenancyBootstrapper
so the test no longer depends on package defaults and the subsequent expectation
comparing storage_path() values remains valid.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 3dbd449c-f66b-46ee-a4cb-e8439e2e4583

📥 Commits

Reviewing files that changed from the base of the PR and between 5e0153c and 5bb76e1.

📒 Files selected for processing (5)
  • assets/TenancyServiceProvider.stub.php
  • src/Jobs/DeleteTenantStorage.php
  • src/Listeners/CreateTenantStorage.php
  • src/Listeners/DeleteTenantStorage.php
  • tests/Bootstrappers/FilesystemTenancyBootstrapperTest.php

Comment thread tests/Bootstrappers/FilesystemTenancyBootstrapperTest.php
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
tests/Bootstrappers/FilesystemTenancyBootstrapperTest.php (1)

194-201: ⚠️ Potential issue | 🟡 Minor

Make scenario 1 explicit instead of relying on defaults.

Line 197 says FilesystemTenancyBootstrapper is not enabled, but this scenario never disables it explicitly. That makes the assertion fragile if default tenancy.bootstrappers changes.

Suggested hardening
 test('tenant storage gets deleted during tenant deletion when the DeletingTenant pipeline contains DeleteTenantStorage', function() {
     Event::listen(DeletingTenant::class,
         JobPipeline::make([DeleteTenantStorage::class])->send(function (DeletingTenant $event) {
             return $event->tenant;
         })->shouldBeQueued(false)->toListener()
     );

     $centralStoragePath = storage_path();
+    config([
+        'tenancy.bootstrappers' => [],
+    ]);
     tenancy()->initialize(Tenant::create());
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/Bootstrappers/FilesystemTenancyBootstrapperTest.php` around lines 194 -
201, The test relies on the default bootstrappers and should explicitly disable
the FilesystemTenancyBootstrapper for scenario 1: before calling
tenancy()->initialize(Tenant::create()), set the tenancy bootstrappers config or
call the relevant config helper to ensure FilesystemTenancyBootstrapper is not
present (e.g. adjust config('tenancy.bootstrappers') to remove the
FilesystemTenancyBootstrapper class), then proceed to capture
$centralStoragePath and assert $tenantStoragePath equals it; reference the
FilesystemTenancyBootstrapper and tenancy()->initialize(Tenant::create()) to
locate where to add this config change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@tests/Bootstrappers/FilesystemTenancyBootstrapperTest.php`:
- Around line 194-201: The test relies on the default bootstrappers and should
explicitly disable the FilesystemTenancyBootstrapper for scenario 1: before
calling tenancy()->initialize(Tenant::create()), set the tenancy bootstrappers
config or call the relevant config helper to ensure
FilesystemTenancyBootstrapper is not present (e.g. adjust
config('tenancy.bootstrappers') to remove the FilesystemTenancyBootstrapper
class), then proceed to capture $centralStoragePath and assert
$tenantStoragePath equals it; reference the FilesystemTenancyBootstrapper and
tenancy()->initialize(Tenant::create()) to locate where to add this config
change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 06cd283c-1022-49db-934d-e8d87529232b

📥 Commits

Reviewing files that changed from the base of the PR and between 5bb76e1 and 3f9f7cd.

📒 Files selected for processing (1)
  • tests/Bootstrappers/FilesystemTenancyBootstrapperTest.php

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
tests/Bootstrappers/FilesystemTenancyBootstrapperTest.php (1)

194-201: ⚠️ Potential issue | 🟡 Minor

Make scenario 1 deterministic instead of relying on implicit defaults.

Line [197] states FilesystemTenancyBootstrapper is not enabled, but that state is not explicitly set before Line [195]. If defaults change, this case can fail for the wrong reason.

♻️ Suggested hardening
     $centralStoragePath = storage_path();
+    config([
+        'tenancy.bootstrappers' => [],
+    ]);
     tenancy()->initialize(Tenant::create());
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/Bootstrappers/FilesystemTenancyBootstrapperTest.php` around lines 194 -
201, Make the test deterministic by explicitly disabling the
FilesystemTenancyBootstrapper before calling
tenancy()->initialize(Tenant::create()) so the test does not rely on implicit
defaults; in the FilesystemTenancyBootstrapperTest adjust the setup for this
scenario to remove or override the filesystem bootstrapper from the active
bootstrappers (e.g., update the tenancy bootstrappers config or call the
appropriate tenancy API to disable/remove FilesystemTenancyBootstrapper) prior
to initialization, then assert that storage_path() for tenant matches
centralStoragePath as before.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@tests/Bootstrappers/FilesystemTenancyBootstrapperTest.php`:
- Around line 194-201: Make the test deterministic by explicitly disabling the
FilesystemTenancyBootstrapper before calling
tenancy()->initialize(Tenant::create()) so the test does not rely on implicit
defaults; in the FilesystemTenancyBootstrapperTest adjust the setup for this
scenario to remove or override the filesystem bootstrapper from the active
bootstrappers (e.g., update the tenancy bootstrappers config or call the
appropriate tenancy API to disable/remove FilesystemTenancyBootstrapper) prior
to initialization, then assert that storage_path() for tenant matches
centralStoragePath as before.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 5669e154-d847-49f1-a287-fa34f574b2b9

📥 Commits

Reviewing files that changed from the base of the PR and between 5bb76e1 and 3f9f7cd.

📒 Files selected for processing (1)
  • tests/Bootstrappers/FilesystemTenancyBootstrapperTest.php

@stancl stancl merged commit 9849119 into master Apr 22, 2026
17 of 22 checks passed
@stancl stancl deleted the storage-listeners branch April 22, 2026 14:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants