Skip to content

Commit c1795a7

Browse files
committed
test: add comprehensive tenant resolver tests
1 parent 7dded7d commit c1795a7

File tree

1 file changed

+126
-0
lines changed

1 file changed

+126
-0
lines changed
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Illuminate\Support\Facades\Context;
6+
use Relaticle\CustomFields\CustomFields;
7+
use Relaticle\CustomFields\Models\CustomField;
8+
use Relaticle\CustomFields\Models\CustomFieldSection;
9+
use Relaticle\CustomFields\Services\TenantContextService;
10+
use Relaticle\CustomFields\Tests\Fixtures\Models\User;
11+
12+
beforeEach(function (): void {
13+
// Clean up any previous resolver
14+
TenantContextService::clearTenantResolver();
15+
});
16+
17+
afterEach(function (): void {
18+
// Always clean up after tests
19+
TenantContextService::clearTenantResolver();
20+
Context::flush();
21+
});
22+
23+
describe('Custom Tenant Resolver', function (): void {
24+
it('allows registering a custom tenant resolver', function (): void {
25+
$expectedTenantId = 42;
26+
27+
CustomFields::resolveTenantUsing(fn () => $expectedTenantId);
28+
29+
expect(TenantContextService::getCurrentTenantId())->toBe($expectedTenantId);
30+
});
31+
32+
it('custom resolver takes priority over Laravel Context', function (): void {
33+
$contextTenantId = 100;
34+
$customTenantId = 200;
35+
36+
// Set Laravel Context
37+
TenantContextService::setTenantId($contextTenantId);
38+
39+
// Register custom resolver
40+
CustomFields::resolveTenantUsing(fn () => $customTenantId);
41+
42+
// Custom resolver should win
43+
expect(TenantContextService::getCurrentTenantId())->toBe($customTenantId);
44+
});
45+
46+
it('falls back to Laravel Context when no custom resolver is set', function (): void {
47+
$tenantId = 150;
48+
49+
TenantContextService::setTenantId($tenantId);
50+
51+
expect(TenantContextService::getCurrentTenantId())->toBe($tenantId);
52+
});
53+
54+
it('returns null when no tenant context is available', function (): void {
55+
expect(TenantContextService::getCurrentTenantId())->toBeNull();
56+
});
57+
58+
it('can clear custom resolver', function (): void {
59+
CustomFields::resolveTenantUsing(fn () => 999);
60+
61+
expect(TenantContextService::getCurrentTenantId())->toBe(999);
62+
63+
TenantContextService::clearTenantResolver();
64+
65+
expect(TenantContextService::getCurrentTenantId())->toBeNull();
66+
});
67+
68+
it('works with dynamic tenant resolution based on auth', function (): void {
69+
auth()->logout();
70+
71+
$user = User::factory()->create();
72+
73+
CustomFields::resolveTenantUsing(fn () => auth()->user()?->id);
74+
75+
// Before login
76+
expect(TenantContextService::getCurrentTenantId())->toBeNull();
77+
78+
// After login
79+
$this->actingAs($user);
80+
expect(TenantContextService::getCurrentTenantId())->toBe($user->id);
81+
});
82+
});
83+
84+
describe('Tenant Resolver with Context Service', function (): void {
85+
it('resolver can access closure variables', function (): void {
86+
$companyId = 999;
87+
88+
CustomFields::resolveTenantUsing(fn () => $companyId);
89+
90+
expect(TenantContextService::getCurrentTenantId())->toBe($companyId);
91+
});
92+
93+
it('resolver can be changed dynamically', function (): void {
94+
$tenant1 = 111;
95+
$tenant2 = 222;
96+
97+
CustomFields::resolveTenantUsing(fn () => $tenant1);
98+
expect(TenantContextService::getCurrentTenantId())->toBe($tenant1);
99+
100+
CustomFields::resolveTenantUsing(fn () => $tenant2);
101+
expect(TenantContextService::getCurrentTenantId())->toBe($tenant2);
102+
});
103+
104+
it('resolver can return string tenant IDs', function (): void {
105+
$tenantUuid = 'org_12345';
106+
107+
CustomFields::resolveTenantUsing(fn () => $tenantUuid);
108+
109+
expect(TenantContextService::getCurrentTenantId())->toBe($tenantUuid);
110+
});
111+
112+
it('resolver can return null for no tenant', function (): void {
113+
CustomFields::resolveTenantUsing(fn () => null);
114+
115+
expect(TenantContextService::getCurrentTenantId())->toBeNull();
116+
});
117+
118+
it('handles resolver exceptions gracefully', function (): void {
119+
CustomFields::resolveTenantUsing(function () {
120+
throw new \RuntimeException('Tenant resolution failed');
121+
});
122+
123+
expect(fn () => TenantContextService::getCurrentTenantId())
124+
->toThrow(\RuntimeException::class, 'Tenant resolution failed');
125+
});
126+
});

0 commit comments

Comments
 (0)