diff --git a/app/Http/Controllers/Api/HetznerController.php b/app/Http/Controllers/Api/HetznerController.php index 2645c2df1..ed91b4475 100644 --- a/app/Http/Controllers/Api/HetznerController.php +++ b/app/Http/Controllers/Api/HetznerController.php @@ -586,7 +586,8 @@ public function createServer(Request $request) } // Check server limit - if (Team::serverLimitReached()) { + $team = Team::find($teamId); + if (Team::serverLimitReached($team)) { return response()->json(['message' => 'Server limit reached for your subscription.'], 400); } diff --git a/app/Models/Team.php b/app/Models/Team.php index 10b22b4e1..5a7b377b6 100644 --- a/app/Models/Team.php +++ b/app/Models/Team.php @@ -89,10 +89,13 @@ protected static function booted() }); } - public static function serverLimitReached() + public static function serverLimitReached(?Team $team = null) { - $serverLimit = Team::serverLimit(); - $team = currentTeam(); + $team = $team ?? currentTeam(); + if (! $team) { + return true; + } + $serverLimit = Team::serverLimit($team); $servers = $team->servers->count(); return $servers >= $serverLimit; @@ -109,19 +112,23 @@ public function subscriptionPastOverDue() public function serverOverflow() { - if ($this->serverLimit() < $this->servers->count()) { + if (Team::serverLimit($this) < $this->servers->count()) { return true; } return false; } - public static function serverLimit() + public static function serverLimit(?Team $team = null) { - if (currentTeam()->id === 0 && isDev()) { + $team = $team ?? currentTeam(); + if (! $team) { + return 0; + } + if ($team->id === 0 && isDev()) { return 9999999; } - $team = Team::find(currentTeam()->id); + $team = Team::find($team->id); if (! $team) { return 0; } diff --git a/tests/Feature/TeamServerLimitTest.php b/tests/Feature/TeamServerLimitTest.php new file mode 100644 index 000000000..11d7f09d1 --- /dev/null +++ b/tests/Feature/TeamServerLimitTest.php @@ -0,0 +1,53 @@ +set('constants.coolify.self_hosted', true); +}); + +it('returns server limit when team is passed directly without session', function () { + $team = Team::factory()->create(); + + $limit = Team::serverLimit($team); + + // self_hosted returns 999999999999 + expect($limit)->toBe(999999999999); +}); + +it('returns 0 when no team is provided and no session exists', function () { + $limit = Team::serverLimit(); + + expect($limit)->toBe(0); +}); + +it('returns true for serverLimitReached when no team and no session', function () { + $result = Team::serverLimitReached(); + + expect($result)->toBeTrue(); +}); + +it('returns false for serverLimitReached when team has servers under limit', function () { + $team = Team::factory()->create(); + Server::factory()->create(['team_id' => $team->id]); + + $result = Team::serverLimitReached($team); + + // self_hosted has very high limit, 1 server is well under + expect($result)->toBeFalse(); +}); + +it('returns true for serverLimitReached when team has servers at limit', function () { + config()->set('constants.coolify.self_hosted', false); + + $team = Team::factory()->create(['custom_server_limit' => 1]); + Server::factory()->create(['team_id' => $team->id]); + + $result = Team::serverLimitReached($team); + + expect($result)->toBeTrue(); +});