diff --git a/Boot.php b/Boot.php index feaa74e..c347fe0 100644 --- a/Boot.php +++ b/Boot.php @@ -4,10 +4,20 @@ declare(strict_types=1); namespace Core\Tenant; +use App\Services\UserStatsService; +use App\Services\WorkspaceCacheManager; +use App\Services\WorkspaceManager; +use App\Services\WorkspaceService; use Core\Events\AdminPanelBooting; use Core\Events\ApiRoutesRegistering; use Core\Events\ConsoleBooting; use Core\Events\WebRoutesRegistering; +use Core\Tenant\Contracts\TwoFactorAuthenticationProvider; +use Core\Tenant\Services\EntitlementService; +use Core\Tenant\Services\EntitlementWebhookService; +use Core\Tenant\Services\TotpService; +use Core\Tenant\Services\UsageAlertService; +use Core\Tenant\Services\WorkspaceTeamService; use Illuminate\Support\Facades\Route; use Illuminate\Support\ServiceProvider; @@ -40,48 +50,48 @@ class Boot extends ServiceProvider public function register(): void { $this->app->singleton( - \Core\Tenant\Contracts\TwoFactorAuthenticationProvider::class, - \Core\Tenant\Services\TotpService::class + TwoFactorAuthenticationProvider::class, + TotpService::class ); $this->app->singleton( - \Core\Tenant\Services\EntitlementService::class, - \Core\Tenant\Services\EntitlementService::class + EntitlementService::class, + EntitlementService::class ); $this->app->singleton( - \Core\Tenant\Services\WorkspaceManager::class, - \Core\Tenant\Services\WorkspaceManager::class + Services\WorkspaceManager::class, + Services\WorkspaceManager::class ); $this->app->singleton( - \Core\Tenant\Services\UserStatsService::class, - \Core\Tenant\Services\UserStatsService::class + Services\UserStatsService::class, + Services\UserStatsService::class ); $this->app->singleton( - \Core\Tenant\Services\WorkspaceService::class, - \Core\Tenant\Services\WorkspaceService::class + Services\WorkspaceService::class, + Services\WorkspaceService::class ); $this->app->singleton( - \Core\Tenant\Services\WorkspaceCacheManager::class, - \Core\Tenant\Services\WorkspaceCacheManager::class + Services\WorkspaceCacheManager::class, + Services\WorkspaceCacheManager::class ); $this->app->singleton( - \Core\Tenant\Services\UsageAlertService::class, - \Core\Tenant\Services\UsageAlertService::class + UsageAlertService::class, + UsageAlertService::class ); $this->app->singleton( - \Core\Tenant\Services\EntitlementWebhookService::class, - \Core\Tenant\Services\EntitlementWebhookService::class + EntitlementWebhookService::class, + EntitlementWebhookService::class ); $this->app->singleton( - \Core\Tenant\Services\WorkspaceTeamService::class, - \Core\Tenant\Services\WorkspaceTeamService::class + WorkspaceTeamService::class, + WorkspaceTeamService::class ); $this->registerBackwardCompatAliases(); @@ -89,31 +99,31 @@ class Boot extends ServiceProvider protected function registerBackwardCompatAliases(): void { - if (! class_exists(\App\Services\WorkspaceManager::class)) { + if (! class_exists(WorkspaceManager::class)) { class_alias( - \Core\Tenant\Services\WorkspaceManager::class, - \App\Services\WorkspaceManager::class + Services\WorkspaceManager::class, + WorkspaceManager::class ); } - if (! class_exists(\App\Services\UserStatsService::class)) { + if (! class_exists(UserStatsService::class)) { class_alias( - \Core\Tenant\Services\UserStatsService::class, - \App\Services\UserStatsService::class + Services\UserStatsService::class, + UserStatsService::class ); } - if (! class_exists(\App\Services\WorkspaceService::class)) { + if (! class_exists(WorkspaceService::class)) { class_alias( - \Core\Tenant\Services\WorkspaceService::class, - \App\Services\WorkspaceService::class + Services\WorkspaceService::class, + WorkspaceService::class ); } - if (! class_exists(\App\Services\WorkspaceCacheManager::class)) { + if (! class_exists(WorkspaceCacheManager::class)) { class_alias( - \Core\Tenant\Services\WorkspaceCacheManager::class, - \App\Services\WorkspaceCacheManager::class + Services\WorkspaceCacheManager::class, + WorkspaceCacheManager::class ); } } diff --git a/Controllers/ReferralController.php b/Controllers/ReferralController.php index fa1272a..59194f0 100644 --- a/Controllers/ReferralController.php +++ b/Controllers/ReferralController.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace Core\Tenant\Controllers; +use Core\Front\Controller; use Core\Helpers\PrivacyHelper; use Core\Mod\Trees\Models\TreePlanting; use Core\Mod\Trees\Models\TreePlantingStats; @@ -21,7 +22,7 @@ use Illuminate\Support\Facades\Cookie; * * On signup, PlantTreeForAgentReferral listener plants a tree for the referrer. */ -class ReferralController extends \Core\Front\Controller +class ReferralController extends Controller { /** * Cookie name for agent referral tracking. diff --git a/Controllers/WorkspaceController.php b/Controllers/WorkspaceController.php index f2da608..bc63131 100644 --- a/Controllers/WorkspaceController.php +++ b/Controllers/WorkspaceController.php @@ -9,6 +9,8 @@ use Core\Tenant\Models\User; use Core\Tenant\Models\Workspace; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; +use Illuminate\Support\Facades\DB; +use Illuminate\Support\Str; use Mod\Api\Controllers\Concerns\HasApiResponses; use Mod\Api\Controllers\Concerns\ResolvesWorkspace; use Mod\Api\Resources\PaginatedCollection; @@ -133,7 +135,7 @@ class WorkspaceController extends Controller // Generate slug if not provided if (empty($validated['slug'])) { - $validated['slug'] = \Illuminate\Support\Str::slug($validated['name']).'-'.\Illuminate\Support\Str::random(6); + $validated['slug'] = Str::slug($validated['name']).'-'.Str::random(6); } // Set default domain @@ -252,9 +254,9 @@ class WorkspaceController extends Controller // Use a single transaction with optimised query: // Clear all defaults and set the new one in one operation using raw update - \Illuminate\Support\Facades\DB::transaction(function () use ($user, $workspace) { + DB::transaction(function () use ($user, $workspace) { // Clear all existing defaults for this user's hub workspaces - \Illuminate\Support\Facades\DB::table('user_workspace') + DB::table('user_workspace') ->where('user_id', $user->id) ->whereIn('workspace_id', function ($query) { $query->select('id') @@ -264,7 +266,7 @@ class WorkspaceController extends Controller ->update(['is_default' => false]); // Set the new default - \Illuminate\Support\Facades\DB::table('user_workspace') + DB::table('user_workspace') ->where('user_id', $user->id) ->where('workspace_id', $workspace->id) ->update(['is_default' => true]); diff --git a/Database/Factories/UserFactory.php b/Database/Factories/UserFactory.php index 69affd1..fd5513b 100644 --- a/Database/Factories/UserFactory.php +++ b/Database/Factories/UserFactory.php @@ -1,13 +1,16 @@ + * @extends Factory */ class UserFactory extends Factory { @@ -17,7 +20,7 @@ class UserFactory extends Factory * Uses the backward-compatible alias class to ensure type compatibility * with existing code that expects Mod\Tenant\Models\User. */ - protected $model = \Core\Tenant\Models\User::class; + protected $model = User::class; /** * The current password being used by the factory. diff --git a/Database/Factories/WaitlistEntryFactory.php b/Database/Factories/WaitlistEntryFactory.php index 23fd696..570817b 100644 --- a/Database/Factories/WaitlistEntryFactory.php +++ b/Database/Factories/WaitlistEntryFactory.php @@ -8,7 +8,7 @@ use Core\Tenant\Models\WaitlistEntry; use Illuminate\Database\Eloquent\Factories\Factory; /** - * @extends \Illuminate\Database\Eloquent\Factories\Factory<\Core\Tenant\Models\WaitlistEntry> + * @extends Factory */ class WaitlistEntryFactory extends Factory { diff --git a/Database/Factories/WorkspaceFactory.php b/Database/Factories/WorkspaceFactory.php index 460fef6..e84dbee 100644 --- a/Database/Factories/WorkspaceFactory.php +++ b/Database/Factories/WorkspaceFactory.php @@ -1,12 +1,14 @@ + * @extends Factory */ class WorkspaceFactory extends Factory { diff --git a/Database/Factories/WorkspaceInvitationFactory.php b/Database/Factories/WorkspaceInvitationFactory.php index d351281..5d811d9 100644 --- a/Database/Factories/WorkspaceInvitationFactory.php +++ b/Database/Factories/WorkspaceInvitationFactory.php @@ -9,7 +9,7 @@ use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Support\Str; /** - * @extends \Illuminate\Database\Eloquent\Factories\Factory<\Core\Tenant\Models\WorkspaceInvitation> + * @extends Factory */ class WorkspaceInvitationFactory extends Factory { diff --git a/Database/Seeders/DemoTestUserSeeder.php b/Database/Seeders/DemoTestUserSeeder.php index 10d703b..bf9a58e 100644 --- a/Database/Seeders/DemoTestUserSeeder.php +++ b/Database/Seeders/DemoTestUserSeeder.php @@ -1,7 +1,10 @@ id) + $existingPage = Page::where('workspace_id', $workspace->id) ->where('url', 'nyx-test') ->first(); @@ -106,7 +109,7 @@ class DemoTestUserSeeder extends Seeder return; } - \Core\Mod\Web\Models\Page::create([ + Page::create([ 'workspace_id' => $workspace->id, 'user_id' => $user->id, 'url' => 'nyx-test', @@ -146,11 +149,11 @@ class DemoTestUserSeeder extends Seeder protected function createTestShortLink(Workspace $workspace, User $user): void { // Only create if Web Page model exists - if (! class_exists(\Core\Mod\Web\Models\Page::class)) { + if (! class_exists(Page::class)) { return; } - $existingLink = \Core\Mod\Web\Models\Page::where('workspace_id', $workspace->id) + $existingLink = Page::where('workspace_id', $workspace->id) ->where('url', 'nyx-short') ->first(); @@ -158,7 +161,7 @@ class DemoTestUserSeeder extends Seeder return; } - \Core\Mod\Web\Models\Page::create([ + Page::create([ 'workspace_id' => $workspace->id, 'user_id' => $user->id, 'url' => 'nyx-short', diff --git a/Database/Seeders/DemoWorkspaceSeeder.php b/Database/Seeders/DemoWorkspaceSeeder.php index 70c26ca..25b5135 100644 --- a/Database/Seeders/DemoWorkspaceSeeder.php +++ b/Database/Seeders/DemoWorkspaceSeeder.php @@ -1,5 +1,7 @@ + * @return array */ public function attachments(): array { diff --git a/Models/AccountDeletionRequest.php b/Models/AccountDeletionRequest.php index 430b902..0e940b4 100644 --- a/Models/AccountDeletionRequest.php +++ b/Models/AccountDeletionRequest.php @@ -1,5 +1,7 @@ notify(new \Illuminate\Auth\Notifications\VerifyEmail); + $this->notify(new VerifyEmail); } /** diff --git a/Models/UserToken.php b/Models/UserToken.php index 734ad26..6aa9064 100644 --- a/Models/UserToken.php +++ b/Models/UserToken.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace Core\Tenant\Models; +use Core\Tenant\Database\Factories\UserTokenFactory; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -18,9 +19,9 @@ class UserToken extends Model { use HasFactory; - protected static function newFactory(): \Core\Tenant\Database\Factories\UserTokenFactory + protected static function newFactory(): UserTokenFactory { - return \Core\Tenant\Database\Factories\UserTokenFactory::new(); + return UserTokenFactory::new(); } /** diff --git a/Models/WaitlistEntry.php b/Models/WaitlistEntry.php index 1ca8b47..48509d7 100644 --- a/Models/WaitlistEntry.php +++ b/Models/WaitlistEntry.php @@ -1,7 +1,10 @@ hasMany(\Core\Mod\Social\Models\Account::class); + return $this->hasMany(Account::class); } /** @@ -243,7 +281,7 @@ class Workspace extends Model */ public function socialPosts(): HasMany { - return $this->hasMany(\Core\Mod\Social\Models\Post::class); + return $this->hasMany(Post::class); } /** @@ -251,7 +289,7 @@ class Workspace extends Model */ public function socialTemplates(): HasMany { - return $this->hasMany(\Core\Mod\Social\Models\Template::class); + return $this->hasMany(Template::class); } /** @@ -259,7 +297,7 @@ class Workspace extends Model */ public function socialMedia(): HasMany { - return $this->hasMany(\Core\Mod\Social\Models\Media::class); + return $this->hasMany(Media::class); } /** @@ -267,7 +305,7 @@ class Workspace extends Model */ public function socialHashtagGroups(): HasMany { - return $this->hasMany(\Core\Mod\Social\Models\HashtagGroup::class); + return $this->hasMany(HashtagGroup::class); } /** @@ -275,7 +313,7 @@ class Workspace extends Model */ public function socialWebhooks(): HasMany { - return $this->hasMany(\Core\Mod\Social\Models\Webhook::class); + return $this->hasMany(Webhook::class); } /** @@ -283,7 +321,7 @@ class Workspace extends Model */ public function socialAnalytics(): HasMany { - return $this->hasMany(\Core\Mod\Social\Models\Analytics::class); + return $this->hasMany(Analytics::class); } /** @@ -291,7 +329,7 @@ class Workspace extends Model */ public function socialVariables(): HasMany { - return $this->hasMany(\Core\Mod\Social\Models\Variable::class); + return $this->hasMany(Variable::class); } /** @@ -299,7 +337,7 @@ class Workspace extends Model */ public function socialPostingSchedule(): HasMany { - return $this->hasMany(\Core\Mod\Social\Models\PostingSchedule::class); + return $this->hasMany(PostingSchedule::class); } /** @@ -307,7 +345,7 @@ class Workspace extends Model */ public function socialImportedPosts(): HasMany { - return $this->hasMany(\Core\Mod\Social\Models\ImportedPost::class); + return $this->hasMany(ImportedPost::class); } /** @@ -315,7 +353,7 @@ class Workspace extends Model */ public function socialMetrics(): HasMany { - return $this->hasMany(\Core\Mod\Social\Models\Metric::class); + return $this->hasMany(Metric::class); } /** @@ -323,7 +361,7 @@ class Workspace extends Model */ public function socialAudience(): HasMany { - return $this->hasMany(\Core\Mod\Social\Models\Audience::class); + return $this->hasMany(Audience::class); } /** @@ -331,7 +369,7 @@ class Workspace extends Model */ public function socialFacebookInsights(): HasMany { - return $this->hasMany(\Core\Mod\Social\Models\FacebookInsight::class); + return $this->hasMany(FacebookInsight::class); } /** @@ -339,7 +377,7 @@ class Workspace extends Model */ public function socialInstagramInsights(): HasMany { - return $this->hasMany(\Core\Mod\Social\Models\InstagramInsight::class); + return $this->hasMany(InstagramInsight::class); } /** @@ -347,7 +385,7 @@ class Workspace extends Model */ public function socialPinterestAnalytics(): HasMany { - return $this->hasMany(\Core\Mod\Social\Models\PinterestAnalytic::class); + return $this->hasMany(PinterestAnalytic::class); } /** @@ -376,7 +414,7 @@ class Workspace extends Model */ public function analyticsSites(): HasMany { - return $this->hasMany(\Core\Mod\Analytics\Models\Website::class); + return $this->hasMany(Website::class); } /** @@ -384,7 +422,7 @@ class Workspace extends Model */ public function socialAnalyticsWebsites(): HasMany { - return $this->hasMany(\Core\Mod\Analytics\Models\AnalyticsWebsite::class); + return $this->hasMany(AnalyticsWebsite::class); } /** @@ -392,7 +430,7 @@ class Workspace extends Model */ public function analyticsGoals(): HasMany { - return $this->hasMany(\Core\Mod\Analytics\Models\Goal::class); + return $this->hasMany(Goal::class); } /** @@ -400,7 +438,7 @@ class Workspace extends Model */ public function socialAnalyticsGoals(): HasMany { - return $this->hasMany(\Core\Mod\Analytics\Models\AnalyticsGoal::class); + return $this->hasMany(AnalyticsGoal::class); } // TrustHost Relationships @@ -410,7 +448,7 @@ class Workspace extends Model */ public function trustWidgets(): HasMany { - return $this->hasMany(\Core\Mod\Trust\Models\Campaign::class); + return $this->hasMany(Campaign::class); } /** @@ -418,7 +456,7 @@ class Workspace extends Model */ public function trustNotifications(): HasMany { - return $this->hasMany(\Core\Mod\Trust\Models\Notification::class); + return $this->hasMany(Notification::class); } // NotifyHost Relationships @@ -428,7 +466,7 @@ class Workspace extends Model */ public function notificationSites(): HasMany { - return $this->hasMany(\Core\Mod\Notify\Models\PushWebsite::class); + return $this->hasMany(PushWebsite::class); } /** @@ -436,7 +474,7 @@ class Workspace extends Model */ public function pushCampaigns(): HasMany { - return $this->hasMany(\Core\Mod\Notify\Models\PushCampaign::class); + return $this->hasMany(PushCampaign::class); } /** @@ -444,7 +482,7 @@ class Workspace extends Model */ public function pushFlows(): HasMany { - return $this->hasMany(\Core\Mod\Notify\Models\PushFlow::class); + return $this->hasMany(PushFlow::class); } /** @@ -452,7 +490,7 @@ class Workspace extends Model */ public function pushSegments(): HasMany { - return $this->hasMany(\Core\Mod\Notify\Models\PushSegment::class); + return $this->hasMany(PushSegment::class); } // API & Webhooks Relationships @@ -462,7 +500,7 @@ class Workspace extends Model */ public function apiKeys(): HasMany { - return $this->hasMany(\Core\Mod\Api\Models\ApiKey::class); + return $this->hasMany(ApiKey::class); } /** @@ -470,7 +508,7 @@ class Workspace extends Model */ public function webhookEndpoints(): HasMany { - return $this->hasMany(\Core\Mod\Api\Models\WebhookEndpoint::class); + return $this->hasMany(WebhookEndpoint::class); } /** @@ -488,7 +526,7 @@ class Workspace extends Model */ public function treePlantings(): HasMany { - return $this->hasMany(\Core\Mod\Trees\Models\TreePlanting::class); + return $this->hasMany(TreePlanting::class); } /** @@ -519,7 +557,7 @@ class Workspace extends Model */ public function contentItems(): HasMany { - return $this->hasMany(\Core\Mod\Content\Models\ContentItem::class); + return $this->hasMany(ContentItem::class); } /** @@ -527,7 +565,7 @@ class Workspace extends Model */ public function contentAuthors(): HasMany { - return $this->hasMany(\Core\Mod\Content\Models\ContentAuthor::class); + return $this->hasMany(ContentAuthor::class); } // Commerce Relationships (defined in app Mod\Commerce) @@ -537,7 +575,7 @@ class Workspace extends Model */ public function subscriptions(): HasMany { - return $this->hasMany(\Mod\Commerce\Models\Subscription::class); + return $this->hasMany(Subscription::class); } /** @@ -545,7 +583,7 @@ class Workspace extends Model */ public function invoices(): HasMany { - return $this->hasMany(\Mod\Commerce\Models\Invoice::class); + return $this->hasMany(Invoice::class); } /** @@ -553,7 +591,7 @@ class Workspace extends Model */ public function paymentMethods(): HasMany { - return $this->hasMany(\Mod\Commerce\Models\PaymentMethod::class); + return $this->hasMany(PaymentMethod::class); } /** @@ -561,7 +599,7 @@ class Workspace extends Model */ public function orders(): MorphMany { - return $this->morphMany(\Mod\Commerce\Models\Order::class, 'orderable'); + return $this->morphMany(Order::class, 'orderable'); } // Helper Methods @@ -579,12 +617,12 @@ class Workspace extends Model } // Try to get from authenticated user's default workspace - if (auth()->check() && auth()->user() instanceof \Core\Tenant\Models\User) { + if (auth()->check() && auth()->user() instanceof User) { return auth()->user()->defaultHostWorkspace(); } // Try to resolve from subdomain via WorkspaceService - $workspaceService = app(\App\Services\WorkspaceService::class); + $workspaceService = app(WorkspaceService::class); $slug = $workspaceService->currentSlug(); return static::where('slug', $slug)->first(); @@ -609,7 +647,7 @@ class Workspace extends Model /** * Get usage summary for all features. */ - public function getUsageSummary(): \Illuminate\Support\Collection + public function getUsageSummary(): Collection { return app(EntitlementService::class)->getUsageSummary($this); } @@ -675,7 +713,7 @@ class Workspace extends Model $existing->save(); // Send notification with the new plaintext token - $existing->notify(new \Core\Tenant\Notifications\WorkspaceInvitationNotification($existing, $plaintextToken)); + $existing->notify(new WorkspaceInvitationNotification($existing, $plaintextToken)); return $existing; } @@ -693,7 +731,7 @@ class Workspace extends Model ]); // Send notification with the plaintext token (not the hashed one) - $invitation->notify(new \Core\Tenant\Notifications\WorkspaceInvitationNotification($invitation, $plaintextToken)); + $invitation->notify(new WorkspaceInvitationNotification($invitation, $plaintextToken)); return $invitation; } diff --git a/Models/WorkspaceInvitation.php b/Models/WorkspaceInvitation.php index 8212cda..a832d10 100644 --- a/Models/WorkspaceInvitation.php +++ b/Models/WorkspaceInvitation.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace Core\Tenant\Models; +use Core\Tenant\Database\Factories\WorkspaceInvitationFactory; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -16,9 +17,9 @@ class WorkspaceInvitation extends Model use HasFactory; use Notifiable; - protected static function newFactory(): \Core\Tenant\Database\Factories\WorkspaceInvitationFactory + protected static function newFactory(): WorkspaceInvitationFactory { - return \Core\Tenant\Database\Factories\WorkspaceInvitationFactory::new(); + return WorkspaceInvitationFactory::new(); } protected $fillable = [ diff --git a/Models/WorkspaceMember.php b/Models/WorkspaceMember.php index b813580..1d04a9c 100644 --- a/Models/WorkspaceMember.php +++ b/Models/WorkspaceMember.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace Core\Tenant\Models; +use Carbon\Carbon; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -20,10 +21,10 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo; * @property int|null $team_id * @property array|null $custom_permissions * @property bool $is_default - * @property \Carbon\Carbon|null $joined_at + * @property Carbon|null $joined_at * @property int|null $invited_by - * @property \Carbon\Carbon $created_at - * @property \Carbon\Carbon $updated_at + * @property Carbon $created_at + * @property Carbon $updated_at */ class WorkspaceMember extends Model { diff --git a/Models/WorkspacePackage.php b/Models/WorkspacePackage.php index ccd4c6f..d87e60e 100644 --- a/Models/WorkspacePackage.php +++ b/Models/WorkspacePackage.php @@ -1,5 +1,7 @@ prefix('admin/tenant')->name('hub.admin.tenant.')->group(function () { // Team Manager - Route::get('/teams', \Core\Tenant\View\Modal\Admin\TeamManager::class) + Route::get('/teams', TeamManager::class) ->name('teams'); // Member Manager - Route::get('/members', \Core\Tenant\View\Modal\Admin\MemberManager::class) + Route::get('/members', MemberManager::class) ->name('members'); }); diff --git a/Routes/web.php b/Routes/web.php index c673767..6a41eb5 100644 --- a/Routes/web.php +++ b/Routes/web.php @@ -8,6 +8,7 @@ declare(strict_types=1); * Account management and workspace routes. */ +use Core\Tenant\Controllers\WorkspaceInvitationController; use Core\Tenant\View\Modal\Web\CancelDeletion; use Core\Tenant\View\Modal\Web\ConfirmDeletion; use Core\Tenant\View\Modal\Web\WorkspaceHome; @@ -41,7 +42,7 @@ Route::prefix('account')->name('account.')->group(function () { | */ -Route::get('/workspace/invitation/{token}', \Core\Tenant\Controllers\WorkspaceInvitationController::class) +Route::get('/workspace/invitation/{token}', WorkspaceInvitationController::class) ->name('workspace.invitation.accept'); /* diff --git a/Services/EntitlementResult.php b/Services/EntitlementResult.php index 187d9bc..40bd45f 100644 --- a/Services/EntitlementResult.php +++ b/Services/EntitlementResult.php @@ -1,5 +1,7 @@ forWorkspace($workspace) @@ -437,7 +438,7 @@ class EntitlementWebhookService /** * Get delivery history for a webhook. */ - public function getDeliveryHistory(EntitlementWebhook $webhook, int $limit = 50): \Illuminate\Database\Eloquent\Collection + public function getDeliveryHistory(EntitlementWebhook $webhook, int $limit = 50): Collection { return $webhook->deliveries() ->latest('created_at') diff --git a/Services/UserStatsService.php b/Services/UserStatsService.php index 71bc3ac..c4ddece 100644 --- a/Services/UserStatsService.php +++ b/Services/UserStatsService.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace Core\Tenant\Services; use Core\Tenant\Enums\UserTier; +use Core\Tenant\Jobs\ComputeUserStats; use Core\Tenant\Models\User; use Illuminate\Support\Facades\Cache; @@ -44,7 +45,7 @@ class UserStatsService // For page loads, return cached data immediately and queue refresh if ($user->cached_stats) { // Queue background refresh - dispatch(new \Core\Tenant\Jobs\ComputeUserStats($user->id))->onQueue('stats'); + dispatch(new ComputeUserStats($user->id))->onQueue('stats'); return $user->cached_stats; } diff --git a/View/Modal/Admin/MemberManager.php b/View/Modal/Admin/MemberManager.php index 4c08a29..38eb816 100644 --- a/View/Modal/Admin/MemberManager.php +++ b/View/Modal/Admin/MemberManager.php @@ -7,7 +7,9 @@ namespace Core\Tenant\View\Modal\Admin; use Core\Tenant\Models\Workspace; use Core\Tenant\Models\WorkspaceMember; use Core\Tenant\Models\WorkspaceTeam; +use Illuminate\Contracts\Pagination\LengthAwarePaginator; use Illuminate\Contracts\View\View; +use Illuminate\Database\Eloquent\Collection; use Livewire\Attributes\Computed; use Livewire\Component; use Livewire\WithPagination; @@ -287,7 +289,7 @@ class MemberManager extends Component // ───────────────────────────────────────────────────────────────────────── #[Computed] - public function members(): \Illuminate\Contracts\Pagination\LengthAwarePaginator + public function members(): LengthAwarePaginator { return WorkspaceMember::query() ->with(['user', 'workspace', 'team', 'inviter']) @@ -308,13 +310,13 @@ class MemberManager extends Component } #[Computed] - public function workspaces(): \Illuminate\Database\Eloquent\Collection + public function workspaces(): Collection { return Workspace::orderBy('name')->get(); } #[Computed] - public function teamsForFilter(): \Illuminate\Database\Eloquent\Collection + public function teamsForFilter(): Collection { $query = WorkspaceTeam::query(); @@ -326,7 +328,7 @@ class MemberManager extends Component } #[Computed] - public function teamsForAssignment(): \Illuminate\Database\Eloquent\Collection + public function teamsForAssignment(): Collection { if ($this->assignMemberId) { $member = WorkspaceMember::find($this->assignMemberId); @@ -337,11 +339,11 @@ class MemberManager extends Component } } - return new \Illuminate\Database\Eloquent\Collection; + return new Collection; } #[Computed] - public function teamsForBulkAssignment(): \Illuminate\Database\Eloquent\Collection + public function teamsForBulkAssignment(): Collection { // Only show teams from the current workspace filter if ($this->workspaceFilter) { @@ -350,7 +352,7 @@ class MemberManager extends Component ->get(); } - return new \Illuminate\Database\Eloquent\Collection; + return new Collection; } #[Computed] diff --git a/View/Modal/Admin/TeamManager.php b/View/Modal/Admin/TeamManager.php index 213f060..a6533a0 100644 --- a/View/Modal/Admin/TeamManager.php +++ b/View/Modal/Admin/TeamManager.php @@ -8,7 +8,9 @@ use Core\Tenant\Models\Workspace; use Core\Tenant\Models\WorkspaceMember; use Core\Tenant\Models\WorkspaceTeam; use Core\Tenant\Services\WorkspaceTeamService; +use Illuminate\Contracts\Pagination\LengthAwarePaginator; use Illuminate\Contracts\View\View; +use Illuminate\Database\Eloquent\Collection; use Livewire\Attributes\Computed; use Livewire\Component; use Livewire\WithPagination; @@ -219,7 +221,7 @@ class TeamManager extends Component // ───────────────────────────────────────────────────────────────────────── #[Computed] - public function teams(): \Illuminate\Contracts\Pagination\LengthAwarePaginator + public function teams(): LengthAwarePaginator { return WorkspaceTeam::query() ->with(['workspace']) @@ -239,7 +241,7 @@ class TeamManager extends Component } #[Computed] - public function workspaces(): \Illuminate\Database\Eloquent\Collection + public function workspaces(): Collection { return Workspace::orderBy('name')->get(); } diff --git a/View/Modal/Admin/WorkspaceDetails.php b/View/Modal/Admin/WorkspaceDetails.php index a01d2e4..edab949 100644 --- a/View/Modal/Admin/WorkspaceDetails.php +++ b/View/Modal/Admin/WorkspaceDetails.php @@ -1,9 +1,29 @@ 'bioPages', 'label' => 'Bio Pages', 'icon' => 'link', 'color' => 'blue', 'model' => \Core\Mod\Web\Models\Page::class], - ['relation' => 'bioProjects', 'label' => 'Bio Projects', 'icon' => 'folder', 'color' => 'indigo', 'model' => \Core\Mod\Web\Models\Project::class], - ['relation' => 'socialAccounts', 'label' => 'Social Accounts', 'icon' => 'share-nodes', 'color' => 'purple', 'model' => \Core\Mod\Social\Models\Account::class], - ['relation' => 'socialPosts', 'label' => 'Social Posts', 'icon' => 'paper-plane', 'color' => 'pink', 'model' => \Core\Mod\Social\Models\Post::class], - ['relation' => 'analyticsSites', 'label' => 'Analytics Sites', 'icon' => 'chart-line', 'color' => 'cyan', 'model' => \Core\Mod\Analytics\Models\Website::class], - ['relation' => 'trustWidgets', 'label' => 'Trust Campaigns', 'icon' => 'shield-check', 'color' => 'emerald', 'model' => \Core\Mod\Trust\Models\Campaign::class], - ['relation' => 'notificationSites', 'label' => 'Notification Sites', 'icon' => 'bell', 'color' => 'amber', 'model' => \Core\Mod\Notify\Models\PushWebsite::class], - ['relation' => 'contentItems', 'label' => 'Content Items', 'icon' => 'file-lines', 'color' => 'slate', 'model' => \Core\Mod\Content\Models\ContentItem::class], - ['relation' => 'apiKeys', 'label' => 'API Keys', 'icon' => 'key', 'color' => 'rose', 'model' => \Core\Mod\Api\Models\ApiKey::class], + ['relation' => 'bioPages', 'label' => 'Bio Pages', 'icon' => 'link', 'color' => 'blue', 'model' => Page::class], + ['relation' => 'bioProjects', 'label' => 'Bio Projects', 'icon' => 'folder', 'color' => 'indigo', 'model' => Project::class], + ['relation' => 'socialAccounts', 'label' => 'Social Accounts', 'icon' => 'share-nodes', 'color' => 'purple', 'model' => Account::class], + ['relation' => 'socialPosts', 'label' => 'Social Posts', 'icon' => 'paper-plane', 'color' => 'pink', 'model' => Post::class], + ['relation' => 'analyticsSites', 'label' => 'Analytics Sites', 'icon' => 'chart-line', 'color' => 'cyan', 'model' => Website::class], + ['relation' => 'trustWidgets', 'label' => 'Trust Campaigns', 'icon' => 'shield-check', 'color' => 'emerald', 'model' => Campaign::class], + ['relation' => 'notificationSites', 'label' => 'Notification Sites', 'icon' => 'bell', 'color' => 'amber', 'model' => PushWebsite::class], + ['relation' => 'contentItems', 'label' => 'Content Items', 'icon' => 'file-lines', 'color' => 'slate', 'model' => ContentItem::class], + ['relation' => 'apiKeys', 'label' => 'API Keys', 'icon' => 'key', 'color' => 'rose', 'model' => ApiKey::class], ]; foreach ($resources as $resource) { @@ -125,7 +145,7 @@ class WorkspaceDetails extends Component $activities = collect(); // Entitlement logs - if (class_exists(\Core\Tenant\Models\EntitlementLog::class)) { + if (class_exists(EntitlementLog::class)) { try { $logs = $this->workspace->entitlementLogs() ->with('user', 'feature') @@ -147,7 +167,7 @@ class WorkspaceDetails extends Component } // Usage records - if (class_exists(\Core\Tenant\Models\UsageRecord::class)) { + if (class_exists(UsageRecord::class)) { try { $usage = $this->workspace->usageRecords() ->with('user', 'feature') @@ -325,7 +345,7 @@ class WorkspaceDetails extends Component #[Computed] public function allPackages() { - return \Core\Tenant\Models\Package::active() + return Package::active() ->ordered() ->get(); } @@ -333,7 +353,7 @@ class WorkspaceDetails extends Component #[Computed] public function allFeatures() { - return \Core\Tenant\Models\Feature::active() + return Feature::active() ->orderBy('category') ->orderBy('sort_order') ->get(); @@ -403,7 +423,7 @@ class WorkspaceDetails extends Component public function resolvedEntitlements() { try { - return app(\Core\Tenant\Services\EntitlementService::class) + return app(EntitlementService::class) ->getUsageSummary($this->workspace); } catch (\Exception $e) { return collect(); @@ -431,7 +451,7 @@ class WorkspaceDetails extends Component return; } - $package = \Core\Tenant\Models\Package::findOrFail($this->selectedPackageId); + $package = Package::findOrFail($this->selectedPackageId); // Check if already assigned $existing = $this->workspace->workspacePackages() @@ -446,7 +466,7 @@ class WorkspaceDetails extends Component return; } - \Core\Tenant\Models\WorkspacePackage::create([ + WorkspacePackage::create([ 'workspace_id' => $this->workspace->id, 'package_id' => $package->id, 'status' => 'active', @@ -461,7 +481,7 @@ class WorkspaceDetails extends Component public function removePackage(int $workspacePackageId): void { - $wp = \Core\Tenant\Models\WorkspacePackage::where('workspace_id', $this->workspace->id) + $wp = WorkspacePackage::where('workspace_id', $this->workspace->id) ->findOrFail($workspacePackageId); $packageName = $wp->package?->name ?? 'Package'; @@ -474,7 +494,7 @@ class WorkspaceDetails extends Component public function suspendPackage(int $workspacePackageId): void { - $wp = \Core\Tenant\Models\WorkspacePackage::where('workspace_id', $this->workspace->id) + $wp = WorkspacePackage::where('workspace_id', $this->workspace->id) ->findOrFail($workspacePackageId); $wp->suspend(); @@ -486,7 +506,7 @@ class WorkspaceDetails extends Component public function reactivatePackage(int $workspacePackageId): void { - $wp = \Core\Tenant\Models\WorkspacePackage::where('workspace_id', $this->workspace->id) + $wp = WorkspacePackage::where('workspace_id', $this->workspace->id) ->findOrFail($workspacePackageId); $wp->reactivate(); @@ -523,7 +543,7 @@ class WorkspaceDetails extends Component return; } - $feature = \Core\Tenant\Models\Feature::where('code', $this->selectedFeatureCode)->first(); + $feature = Feature::where('code', $this->selectedFeatureCode)->first(); if (! $feature) { $this->actionMessage = 'Feature not found.'; @@ -534,26 +554,26 @@ class WorkspaceDetails extends Component // Map type to boost type constant $boostType = match ($this->entitlementType) { - 'enable' => \Core\Tenant\Models\Boost::BOOST_TYPE_ENABLE, - 'add_limit' => \Core\Tenant\Models\Boost::BOOST_TYPE_ADD_LIMIT, - 'unlimited' => \Core\Tenant\Models\Boost::BOOST_TYPE_UNLIMITED, - default => \Core\Tenant\Models\Boost::BOOST_TYPE_ENABLE, + 'enable' => Boost::BOOST_TYPE_ENABLE, + 'add_limit' => Boost::BOOST_TYPE_ADD_LIMIT, + 'unlimited' => Boost::BOOST_TYPE_UNLIMITED, + default => Boost::BOOST_TYPE_ENABLE, }; $durationType = $this->entitlementDuration === 'permanent' - ? \Core\Tenant\Models\Boost::DURATION_PERMANENT - : \Core\Tenant\Models\Boost::DURATION_DURATION; + ? Boost::DURATION_PERMANENT + : Boost::DURATION_DURATION; - \Core\Tenant\Models\Boost::create([ + Boost::create([ 'workspace_id' => $this->workspace->id, 'feature_code' => $this->selectedFeatureCode, 'boost_type' => $boostType, 'duration_type' => $durationType, 'limit_value' => $this->entitlementType === 'add_limit' ? $this->entitlementLimit : null, 'consumed_quantity' => 0, - 'status' => \Core\Tenant\Models\Boost::STATUS_ACTIVE, + 'status' => Boost::STATUS_ACTIVE, 'starts_at' => now(), - 'expires_at' => $this->entitlementExpiresAt ? \Carbon\Carbon::parse($this->entitlementExpiresAt) : null, + 'expires_at' => $this->entitlementExpiresAt ? Carbon::parse($this->entitlementExpiresAt) : null, 'metadata' => ['granted_by' => auth()->id(), 'granted_at' => now()->toDateTimeString()], ]); @@ -565,7 +585,7 @@ class WorkspaceDetails extends Component public function removeBoost(int $boostId): void { - $boost = \Core\Tenant\Models\Boost::where('workspace_id', $this->workspace->id) + $boost = Boost::where('workspace_id', $this->workspace->id) ->findOrFail($boostId); $featureCode = $boost->feature_code; diff --git a/View/Modal/Admin/WorkspaceManager.php b/View/Modal/Admin/WorkspaceManager.php index 52a2484..7614b22 100644 --- a/View/Modal/Admin/WorkspaceManager.php +++ b/View/Modal/Admin/WorkspaceManager.php @@ -1,10 +1,20 @@ ['model' => \Core\Mod\Web\Models\Page::class, 'table' => 'pages'], - 'bioProjects' => ['model' => \Core\Mod\Web\Models\Project::class, 'table' => 'page_projects'], - 'socialAccounts' => ['model' => \Core\Mod\Social\Models\Account::class, 'table' => 'social_accounts'], - 'analyticsSites' => ['model' => \Core\Mod\Analytics\Models\Website::class, 'table' => 'analytics_websites'], - 'trustWidgets' => ['model' => \Core\Mod\Trust\Models\Campaign::class, 'table' => 'trust_campaigns'], - 'notificationSites' => ['model' => \Core\Mod\Notify\Models\PushWebsite::class, 'table' => 'push_websites'], + 'bioPages' => ['model' => Page::class, 'table' => 'pages'], + 'bioProjects' => ['model' => Project::class, 'table' => 'page_projects'], + 'socialAccounts' => ['model' => Account::class, 'table' => 'social_accounts'], + 'analyticsSites' => ['model' => Website::class, 'table' => 'analytics_websites'], + 'trustWidgets' => ['model' => Campaign::class, 'table' => 'trust_campaigns'], + 'notificationSites' => ['model' => PushWebsite::class, 'table' => 'push_websites'], ]; - $schema = \Illuminate\Support\Facades\Schema::getFacadeRoot(); + $schema = Schema::getFacadeRoot(); foreach ($checks as $relation => $info) { if (class_exists($info['model'])) { @@ -153,16 +163,16 @@ class WorkspaceManager extends Component public function resourceTypes(): array { $types = []; - $schema = \Illuminate\Support\Facades\Schema::getFacadeRoot(); + $schema = Schema::getFacadeRoot(); // Only include resource types for models that exist and have valid relations $checks = [ - 'bio_pages' => ['model' => \Core\Mod\Web\Models\Page::class, 'table' => 'pages', 'label' => 'Bio Pages', 'relation' => 'bioPages', 'icon' => 'link'], - 'bio_projects' => ['model' => \Core\Mod\Web\Models\Project::class, 'table' => 'page_projects', 'label' => 'Bio Projects', 'relation' => 'bioProjects', 'icon' => 'folder'], - 'social_accounts' => ['model' => \Core\Mod\Social\Models\Account::class, 'table' => 'social_accounts', 'label' => 'Social Accounts', 'relation' => 'socialAccounts', 'icon' => 'share-nodes'], - 'analytics_sites' => ['model' => \Core\Mod\Analytics\Models\Website::class, 'table' => 'analytics_websites', 'label' => 'Analytics Sites', 'relation' => 'analyticsSites', 'icon' => 'chart-line'], - 'trust_widgets' => ['model' => \Core\Mod\Trust\Models\Campaign::class, 'table' => 'trust_campaigns', 'label' => 'Trust Campaigns', 'relation' => 'trustWidgets', 'icon' => 'shield-check'], - 'notification_sites' => ['model' => \Core\Mod\Notify\Models\PushWebsite::class, 'table' => 'push_websites', 'label' => 'Notification Sites', 'relation' => 'notificationSites', 'icon' => 'bell'], + 'bio_pages' => ['model' => Page::class, 'table' => 'pages', 'label' => 'Bio Pages', 'relation' => 'bioPages', 'icon' => 'link'], + 'bio_projects' => ['model' => Project::class, 'table' => 'page_projects', 'label' => 'Bio Projects', 'relation' => 'bioProjects', 'icon' => 'folder'], + 'social_accounts' => ['model' => Account::class, 'table' => 'social_accounts', 'label' => 'Social Accounts', 'relation' => 'socialAccounts', 'icon' => 'share-nodes'], + 'analytics_sites' => ['model' => Website::class, 'table' => 'analytics_websites', 'label' => 'Analytics Sites', 'relation' => 'analyticsSites', 'icon' => 'chart-line'], + 'trust_widgets' => ['model' => Campaign::class, 'table' => 'trust_campaigns', 'label' => 'Trust Campaigns', 'relation' => 'trustWidgets', 'icon' => 'shield-check'], + 'notification_sites' => ['model' => PushWebsite::class, 'table' => 'push_websites', 'label' => 'Notification Sites', 'relation' => 'notificationSites', 'icon' => 'bell'], ]; foreach ($checks as $key => $info) { @@ -530,7 +540,7 @@ class WorkspaceManager extends Component 'icon' => 'link', 'color' => 'blue', 'fields' => ['name', 'slug'], - 'model' => \Core\Mod\Web\Models\Page::class, + 'model' => Page::class, 'defaults' => ['type' => 'page', 'is_enabled' => true], ], 'social_accounts' => [ @@ -538,7 +548,7 @@ class WorkspaceManager extends Component 'icon' => 'share-nodes', 'color' => 'purple', 'fields' => ['name'], - 'model' => \Core\Mod\Social\Models\Account::class, + 'model' => Account::class, 'defaults' => ['provider' => 'manual', 'status' => 'active'], ], 'analytics_sites' => [ @@ -546,7 +556,7 @@ class WorkspaceManager extends Component 'icon' => 'chart-line', 'color' => 'cyan', 'fields' => ['name', 'url'], - 'model' => \Core\Mod\Analytics\Models\Website::class, + 'model' => Website::class, 'defaults' => ['tracking_enabled' => true, 'is_enabled' => true], ], 'trust_widgets' => [ @@ -554,7 +564,7 @@ class WorkspaceManager extends Component 'icon' => 'shield-check', 'color' => 'emerald', 'fields' => ['name'], - 'model' => \Core\Mod\Trust\Models\Campaign::class, + 'model' => Campaign::class, 'defaults' => ['status' => 'draft'], ], 'notification_sites' => [ @@ -562,7 +572,7 @@ class WorkspaceManager extends Component 'icon' => 'bell', 'color' => 'amber', 'fields' => ['name', 'url'], - 'model' => \Core\Mod\Notify\Models\PushWebsite::class, + 'model' => PushWebsite::class, 'defaults' => ['status' => 'active'], ], ]; @@ -615,7 +625,7 @@ class WorkspaceManager extends Component // Add slug for bio pages if (in_array('slug', $config['fields']) && $this->provisionSlug) { - $data['url'] = \Illuminate\Support\Str::slug($this->provisionSlug); + $data['url'] = Str::slug($this->provisionSlug); } // Add URL-related fields if applicable diff --git a/View/Modal/Web/CancelDeletion.php b/View/Modal/Web/CancelDeletion.php index b3eba1b..1012a4f 100644 --- a/View/Modal/Web/CancelDeletion.php +++ b/View/Modal/Web/CancelDeletion.php @@ -1,5 +1,7 @@ getAttributes(\Core\Api\RateLimit\RateLimit::class); + $reflection = new ReflectionClass(EntitlementApiController::class); + $attributes = $reflection->getAttributes(RateLimit::class); expect($attributes)->toHaveCount(1); diff --git a/tests/Feature/EntitlementServiceTest.php b/tests/Feature/EntitlementServiceTest.php index 09fb853..a465ac3 100644 --- a/tests/Feature/EntitlementServiceTest.php +++ b/tests/Feature/EntitlementServiceTest.php @@ -15,9 +15,11 @@ use Core\Tenant\Models\Workspace; use Core\Tenant\Models\WorkspacePackage; use Core\Tenant\Services\EntitlementResult; use Core\Tenant\Services\EntitlementService; +use Illuminate\Foundation\Testing\RefreshDatabase; +use Illuminate\Support\Collection; use Illuminate\Support\Facades\Cache; -uses(\Illuminate\Foundation\Testing\RefreshDatabase::class); +uses(RefreshDatabase::class); beforeEach(function () { // Clear cache before each test @@ -426,7 +428,7 @@ describe('EntitlementService', function () { $summary = $this->service->getUsageSummary($this->workspace); - expect($summary)->toBeInstanceOf(\Illuminate\Support\Collection::class) + expect($summary)->toBeInstanceOf(Collection::class) ->and($summary->has('ai'))->toBeTrue() ->and($summary->has('tier'))->toBeTrue() ->and($summary->has('social'))->toBeTrue(); @@ -1101,7 +1103,7 @@ describe('Namespace Entitlements', function () { $summary = $this->service->getNamespaceUsageSummary($this->userNamespace); - expect($summary)->toBeInstanceOf(\Illuminate\Support\Collection::class) + expect($summary)->toBeInstanceOf(Collection::class) ->and($summary->has('content'))->toBeTrue() ->and($summary->has('features'))->toBeTrue(); }); diff --git a/tests/Feature/Guards/AccessTokenGuardTest.php b/tests/Feature/Guards/AccessTokenGuardTest.php index d038806..3447834 100644 --- a/tests/Feature/Guards/AccessTokenGuardTest.php +++ b/tests/Feature/Guards/AccessTokenGuardTest.php @@ -2,16 +2,18 @@ declare(strict_types=1); +use Core\Mod\Api\Guards\AccessTokenGuard; use Core\Tenant\Models\User; use Core\Tenant\Models\UserToken; +use Illuminate\Http\Request; test('can authenticate with valid bearer token', function () { $user = User::factory()->create(); $result = $user->createToken('Test Token'); // Test the guard directly by invoking it with a mock request - $guard = new \Core\Mod\Api\Guards\AccessTokenGuard(app('auth')); - $request = \Illuminate\Http\Request::create('/test', 'GET'); + $guard = new AccessTokenGuard(app('auth')); + $request = Request::create('/test', 'GET'); $request->headers->set('Authorization', "Bearer {$result['token']}"); $authenticatedUser = $guard($request); @@ -57,8 +59,8 @@ test('token last_used_at is updated on successful authentication', function () { expect($tokenModel->last_used_at)->toBeNull(); // Test the guard directly by invoking it with a mock request - $guard = new \Core\Mod\Api\Guards\AccessTokenGuard(app('auth')); - $request = \Illuminate\Http\Request::create('/test', 'GET'); + $guard = new AccessTokenGuard(app('auth')); + $request = Request::create('/test', 'GET'); $request->headers->set('Authorization', "Bearer {$result['token']}"); $guard($request); diff --git a/tests/Feature/ProfileTest.php b/tests/Feature/ProfileTest.php index 53d8111..0a135d4 100644 --- a/tests/Feature/ProfileTest.php +++ b/tests/Feature/ProfileTest.php @@ -1,5 +1,7 @@ user->twoFactorAuth())->toBeInstanceOf( - \Illuminate\Database\Eloquent\Relations\HasOne::class + HasOne::class ); }); @@ -315,7 +319,7 @@ describe('UserTwoFactorAuth Model', function () { 'recovery_codes' => $codes, ]); - expect($twoFactorAuth->recovery_codes)->toBeInstanceOf(\Illuminate\Support\Collection::class) + expect($twoFactorAuth->recovery_codes)->toBeInstanceOf(Collection::class) ->and($twoFactorAuth->recovery_codes->toArray())->toBe($codes); }); @@ -329,7 +333,7 @@ describe('UserTwoFactorAuth Model', function () { 'confirmed_at' => $confirmedAt, ]); - expect($twoFactorAuth->confirmed_at)->toBeInstanceOf(\Carbon\Carbon::class); + expect($twoFactorAuth->confirmed_at)->toBeInstanceOf(Carbon::class); }); it('encrypts secret at rest', function () { @@ -348,7 +352,7 @@ describe('UserTwoFactorAuth Model', function () { // But the raw database value should be encrypted (base64 JSON with iv, value, mac) // Note: DB column is 'secret', not 'secret_key' - $rawValue = \Illuminate\Support\Facades\DB::table('user_two_factor_auth') + $rawValue = DB::table('user_two_factor_auth') ->where('id', $twoFactorAuth->id) ->value('secret'); @@ -372,7 +376,7 @@ describe('UserTwoFactorAuth Model', function () { expect($twoFactorAuth->recovery_codes->toArray())->toBe($codes); // But the raw database value should be encrypted - $rawValue = \Illuminate\Support\Facades\DB::table('user_two_factor_auth') + $rawValue = DB::table('user_two_factor_auth') ->where('id', $twoFactorAuth->id) ->value('recovery_codes'); diff --git a/tests/Feature/WaitlistTest.php b/tests/Feature/WaitlistTest.php index 5f0ef39..7941f91 100644 --- a/tests/Feature/WaitlistTest.php +++ b/tests/Feature/WaitlistTest.php @@ -7,6 +7,7 @@ use Core\Tenant\Notifications\WaitlistInviteNotification; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Facades\Notification; use Illuminate\Support\Facades\RateLimiter; +use Illuminate\Support\Str; use Livewire\Livewire; use Website\Host\View\Modal\Waitlist; @@ -130,7 +131,7 @@ describe('Waitlist Entry Model', function () { expect($entry->invite_code)->toBeNull(); $entry->update([ - 'invite_code' => \Illuminate\Support\Str::random(16), + 'invite_code' => Str::random(16), 'invited_at' => now(), ]); diff --git a/tests/Feature/WorkspaceSecurityTest.php b/tests/Feature/WorkspaceSecurityTest.php index 644fa17..7c73c8f 100644 --- a/tests/Feature/WorkspaceSecurityTest.php +++ b/tests/Feature/WorkspaceSecurityTest.php @@ -14,6 +14,7 @@ use Core\Tenant\Scopes\WorkspaceScope; use Illuminate\Database\Eloquent\Model; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Http\Request; +use Illuminate\Support\Str; use Tests\TestCase; /** @@ -208,7 +209,7 @@ class WorkspaceSecurityTest extends TestCase $this->expectExceptionMessage('create'); Account::create([ - 'uuid' => \Illuminate\Support\Str::uuid(), + 'uuid' => Str::uuid(), 'provider' => 'twitter', 'provider_id' => '12345', 'name' => 'Test Account', @@ -223,7 +224,7 @@ class WorkspaceSecurityTest extends TestCase // Should succeed because workspace_id is explicitly provided $account = Account::create([ - 'uuid' => \Illuminate\Support\Str::uuid(), + 'uuid' => Str::uuid(), 'workspace_id' => $this->workspace->id, 'provider' => 'twitter', 'provider_id' => '12345', @@ -240,7 +241,7 @@ class WorkspaceSecurityTest extends TestCase request()->attributes->set('workspace_model', $this->workspace); $account = Account::create([ - 'uuid' => \Illuminate\Support\Str::uuid(), + 'uuid' => Str::uuid(), 'provider' => 'twitter', 'provider_id' => '12345', 'name' => 'Test Account', diff --git a/tests/Feature/WorkspaceTenancyTest.php b/tests/Feature/WorkspaceTenancyTest.php index 85e9beb..e83a488 100644 --- a/tests/Feature/WorkspaceTenancyTest.php +++ b/tests/Feature/WorkspaceTenancyTest.php @@ -1,12 +1,16 @@ create(); // Test that all relationship methods exist and return correct type - $this->assertInstanceOf(\Illuminate\Database\Eloquent\Relations\HasMany::class, $workspace->socialAccounts()); - $this->assertInstanceOf(\Illuminate\Database\Eloquent\Relations\HasMany::class, $workspace->socialPosts()); - $this->assertInstanceOf(\Illuminate\Database\Eloquent\Relations\HasMany::class, $workspace->analyticsSites()); - $this->assertInstanceOf(\Illuminate\Database\Eloquent\Relations\HasMany::class, $workspace->trustWidgets()); - $this->assertInstanceOf(\Illuminate\Database\Eloquent\Relations\HasMany::class, $workspace->notificationSites()); - $this->assertInstanceOf(\Illuminate\Database\Eloquent\Relations\HasMany::class, $workspace->pushCampaigns()); + $this->assertInstanceOf(HasMany::class, $workspace->socialAccounts()); + $this->assertInstanceOf(HasMany::class, $workspace->socialPosts()); + $this->assertInstanceOf(HasMany::class, $workspace->analyticsSites()); + $this->assertInstanceOf(HasMany::class, $workspace->trustWidgets()); + $this->assertInstanceOf(HasMany::class, $workspace->notificationSites()); + $this->assertInstanceOf(HasMany::class, $workspace->pushCampaigns()); // NOTE: bioPages relationship has been moved to Host UK app's Mod\Bio module } @@ -114,7 +118,7 @@ class WorkspaceTenancyTest extends TestCase // When creating a model with BelongsToWorkspace trait, // it should auto-assign the current user's workspace $account = Account::create([ - 'uuid' => \Illuminate\Support\Str::uuid(), + 'uuid' => Str::uuid(), 'provider' => 'twitter', 'provider_id' => '12345', 'name' => 'Test Account', diff --git a/tests/TestCase.php b/tests/TestCase.php index 40b172f..d561fd7 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace Tests; +use Core\Tenant\Boot; use Orchestra\Testbench\TestCase as BaseTestCase; abstract class TestCase extends BaseTestCase @@ -11,7 +12,7 @@ abstract class TestCase extends BaseTestCase protected function getPackageProviders($app): array { return [ - \Core\Tenant\Boot::class, + Boot::class, ]; } }