Skip to content

Commit f407634

Browse files
authored
Merge pull request #7 from TappNetwork/tenancy
Multi-tenancy support
2 parents 55987e4 + 2a9cedc commit f407634

38 files changed

Lines changed: 1394 additions & 35 deletions

.github/workflows/run-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ jobs:
4949
COMPOSER_AUTH: ${{ secrets.COMPOSER_AUTH }}
5050
run: |
5151
composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" --no-interaction --no-update
52-
composer update --${{ matrix.stability }} --prefer-dist --no-interaction
52+
composer update --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress
5353
5454
- name: List Installed Dependencies
5555
run: composer show -D

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,4 @@ phpstan.neon
3030
testbench.yaml
3131
/docs
3232
/coverage
33+
.DS_Store

PUBLISH_TESTS.md

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
# Test Integration Guide
2+
3+
This guide explains how the test stubs integrate with your Laravel application.
4+
5+
## How It Works
6+
7+
When you run `php artisan filament-forum:install-tests`, the command copies test files from the plugin's `stubs/tests` directory to your application's `tests/Feature` directory.
8+
9+
### Configuration Integration
10+
11+
The tests automatically read from your application's configuration:
12+
13+
```php
14+
// In the test files
15+
$userModel = config('filament-forum.user.model');
16+
$tenantModel = config('filament-forum.tenancy.model');
17+
```
18+
19+
This means the tests will use **your** User and Tenant models, not the plugin's internal test models.
20+
21+
## Test Structure
22+
23+
### FilamentForumTest.php
24+
25+
Tests basic forum functionality that works with or without tenancy:
26+
27+
```php
28+
it('can create a forum', function () {
29+
$user = $this->userModel::factory()->create();
30+
$this->actingAs($user);
31+
32+
$forum = Forum::factory()->create([
33+
'name' => 'Test Forum',
34+
]);
35+
36+
expect($forum->name)->toBe('Test Forum');
37+
});
38+
```
39+
40+
### FilamentForumTenancyTest.php
41+
42+
Tests multi-tenancy features and automatically skips if tenancy is disabled:
43+
44+
```php
45+
beforeEach(function () {
46+
if (! config('filament-forum.tenancy.enabled')) {
47+
$this->markTestSkipped('Tenancy is not enabled');
48+
}
49+
// ...
50+
});
51+
```
52+
53+
## Dynamic Tenant Column Names
54+
55+
The tests use the plugin's helper methods to get the correct tenant relationship and column names:
56+
57+
```php
58+
// Get the tenant relationship name (e.g., 'team', 'organization', 'company')
59+
$tenantRelationship = Forum::getTenantRelationshipName();
60+
61+
// Get the tenant column name (e.g., 'team_id', 'organization_id', 'company_id')
62+
$tenantColumn = Forum::getTenantRelationshipName() . '_id';
63+
```
64+
65+
This ensures tests work regardless of what you name your tenant model.
66+
67+
## Example Scenarios
68+
69+
### Scenario 1: Using Team Model
70+
71+
```php
72+
// config/filament-forum.php
73+
'tenancy' => [
74+
'enabled' => true,
75+
'model' => App\Models\Team::class,
76+
],
77+
```
78+
79+
Tests will:
80+
- Use `App\Models\Team::factory()` to create tenants
81+
- Look for `team_id` column in tables
82+
- Use `team()` relationship method
83+
84+
### Scenario 2: Using Organization Model
85+
86+
```php
87+
// config/filament-forum.php
88+
'tenancy' => [
89+
'enabled' => true,
90+
'model' => App\Models\Organization::class,
91+
],
92+
```
93+
94+
Tests will:
95+
- Use `App\Models\Organization::factory()` to create tenants
96+
- Look for `organization_id` column in tables
97+
- Use `organization()` relationship method
98+
99+
### Scenario 3: No Tenancy
100+
101+
```php
102+
// config/filament-forum.php
103+
'tenancy' => [
104+
'enabled' => false,
105+
],
106+
```
107+
108+
Tests will:
109+
- Run all basic tests from `FilamentForumTest.php`
110+
- Skip all tests in `FilamentForumTenancyTest.php`
111+
112+
## Customizing Tests
113+
114+
The published tests are meant to be modified for your needs. Here are some common customizations:
115+
116+
### Adding Custom Fields
117+
118+
```php
119+
it('can create a forum with custom fields', function () {
120+
$user = $this->userModel::factory()->create();
121+
$this->actingAs($user);
122+
123+
$forum = Forum::factory()->create([
124+
'name' => 'Test Forum',
125+
'slug' => 'test-forum',
126+
'custom_field' => 'custom value', // Your custom field
127+
]);
128+
129+
expect($forum->custom_field)->toBe('custom value');
130+
});
131+
```
132+
133+
### Testing Custom Permissions
134+
135+
```php
136+
it('respects forum permissions', function () {
137+
$user = $this->userModel::factory()->create();
138+
$admin = $this->userModel::factory()->create(['role' => 'admin']);
139+
140+
$this->actingAs($user);
141+
142+
$this->assertDatabaseMissing('forums', ['name' => 'Admin Forum']);
143+
144+
$this->actingAs($admin);
145+
146+
$forum = Forum::factory()->create(['name' => 'Admin Forum']);
147+
148+
expect($forum)->toBeInstanceOf(Forum::class);
149+
});
150+
```
151+
152+
### Testing with Multiple Tenants
153+
154+
```php
155+
it('can handle multiple tenant memberships', function () {
156+
$user = $this->userModel::factory()->create();
157+
$tenant1 = $this->tenantModel::factory()->create();
158+
$tenant2 = $this->tenantModel::factory()->create();
159+
160+
// Add user to both tenants (implement based on your membership logic)
161+
$user->teams()->attach([$tenant1->id, $tenant2->id]);
162+
163+
$this->actingAs($user);
164+
165+
// Test tenant switching
166+
Filament::setTenant($tenant1);
167+
expect(Filament::getTenant()->id)->toBe($tenant1->id);
168+
169+
Filament::setTenant($tenant2);
170+
expect(Filament::getTenant()->id)->toBe($tenant2->id);
171+
});
172+
```
173+
174+
## Best Practices
175+
176+
1. **Run tests after publishing**: Immediately after running `filament-forum:install-tests`, run the tests to verify they work with your setup
177+
2. **Customize for your needs**: The stubs are a starting point - modify them to match your application's requirements
178+
3. **Keep tests in sync**: When you upgrade the plugin, review the test stubs for any changes
179+
4. **Use factories**: Ensure your User and Tenant models have proper factories for reliable testing
180+
5. **Test edge cases**: Add tests for your specific business logic and edge cases
181+
182+
## Troubleshooting
183+
184+
### Tests fail with "Factory not found"
185+
186+
Create factories for your models:
187+
188+
```bash
189+
php artisan make:factory UserFactory --model=User
190+
php artisan make:factory TeamFactory --model=Team
191+
```
192+
193+
### Tests fail with "Table not found"
194+
195+
Run migrations in your test environment:
196+
197+
```bash
198+
php artisan migrate --env=testing
199+
```
200+
201+
Or configure in-memory SQLite in `phpunit.xml`:
202+
203+
```xml
204+
<env name="DB_CONNECTION" value="sqlite"/>
205+
<env name="DB_DATABASE" value=":memory:"/>
206+
```
207+
208+
Or add your test database in `phpunit.xml`:
209+
210+
```xml
211+
<env name="APP_ENV" value="testing"/>
212+
<env name="DB_DATABASE" value="myapp_test"/>
213+
```
214+
215+
### Tenancy tests always skip
216+
217+
Verify configuration:
218+
219+
```bash
220+
php artisan config:clear
221+
php artisan tinker
222+
>>> config('filament-forum.tenancy.enabled')
223+
=> true
224+
```

0 commit comments

Comments
 (0)