Return tests to passing now that we don't ignore a critical event...

This commit is contained in:
DaneEveritt 2022-05-29 17:52:14 -04:00
parent 09832cc558
commit 0621d8475d
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
14 changed files with 44 additions and 60 deletions

View file

@ -7,6 +7,7 @@ use Illuminate\Support\Str;
use Illuminate\Validation\Rule; use Illuminate\Validation\Rule;
use Illuminate\Container\Container; use Illuminate\Container\Container;
use Illuminate\Contracts\Validation\Factory; use Illuminate\Contracts\Validation\Factory;
use Illuminate\Validation\ValidationException;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Pterodactyl\Exceptions\Model\DataValidationException; use Pterodactyl\Exceptions\Model\DataValidationException;
use Illuminate\Database\Eloquent\Model as IlluminateModel; use Illuminate\Database\Eloquent\Model as IlluminateModel;
@ -30,13 +31,6 @@ abstract class Model extends IlluminateModel
*/ */
protected $skipValidation = false; protected $skipValidation = false;
/**
* The validator instance used by this model.
*
* @var \Illuminate\Validation\Validator
*/
protected $validator;
/** /**
* @var \Illuminate\Contracts\Validation\Factory * @var \Illuminate\Contracts\Validation\Factory
*/ */
@ -60,8 +54,10 @@ abstract class Model extends IlluminateModel
static::$validatorFactory = Container::getInstance()->make(Factory::class); static::$validatorFactory = Container::getInstance()->make(Factory::class);
static::saving(function (Model $model) { static::saving(function (Model $model) {
if (!$model->validate()) { try {
throw new DataValidationException($model->getValidator()); $model->validate();
} catch (ValidationException $exception) {
throw new DataValidationException($exception->validator);
} }
return true; return true;
@ -101,14 +97,9 @@ abstract class Model extends IlluminateModel
*/ */
public function getValidator() public function getValidator()
{ {
$rules = $this->getKey() ? static::getRulesForUpdate($this) : static::getRules(); $rules = $this->exists ? static::getRulesForUpdate($this) : static::getRules();
return $this->validator ?: $this->validator = static::$validatorFactory->make( return static::$validatorFactory->make([], $rules, [], []);
[],
$rules,
[],
[]
);
} }
/** /**
@ -139,14 +130,14 @@ abstract class Model extends IlluminateModel
* Returns the rules associated with the model, specifically for updating the given model * Returns the rules associated with the model, specifically for updating the given model
* rather than just creating it. * rather than just creating it.
* *
* @param \Illuminate\Database\Eloquent\Model|int|string $id * @param \Illuminate\Database\Eloquent\Model|int|string $model
* *
* @return array * @return array
*/ */
public static function getRulesForUpdate($id, string $primaryKey = 'id') public static function getRulesForUpdate($model, string $column = 'id')
{ {
if ($id instanceof Model) { if ($model instanceof Model) {
[$primaryKey, $id] = [$id->getKeyName(), $id->getKey()]; [$id, $column] = [$model->getKey(), $model->getKeyName()];
} }
$rules = static::getRules(); $rules = static::getRules();
@ -163,7 +154,7 @@ abstract class Model extends IlluminateModel
[, $args] = explode(':', $datum); [, $args] = explode(':', $datum);
$args = explode(',', $args); $args = explode(',', $args);
$datum = Rule::unique($args[0], $args[1] ?? $key)->ignore($id, $primaryKey)->__toString(); $datum = Rule::unique($args[0], $args[1] ?? $key)->ignore($id ?? $model, $column);
} }
} }
@ -172,16 +163,15 @@ abstract class Model extends IlluminateModel
/** /**
* Determines if the model is in a valid state or not. * Determines if the model is in a valid state or not.
*
* @return bool
*/ */
public function validate() public function validate(): void
{ {
if ($this->skipValidation) { if ($this->skipValidation) {
return true; return;
} }
return $this->getValidator()->setData( $validator = $this->getValidator();
$validator->setData(
// Trying to do self::toArray() here will leave out keys based on the whitelist/blacklist // Trying to do self::toArray() here will leave out keys based on the whitelist/blacklist
// for that model. Doing this will return all of the attributes in a format that can // for that model. Doing this will return all of the attributes in a format that can
// properly be validated. // properly be validated.
@ -189,7 +179,11 @@ abstract class Model extends IlluminateModel
$this->getAttributes(), $this->getAttributes(),
$this->getMutatedAttributes() $this->getMutatedAttributes()
) )
)->passes(); );
if (!$validator->passes()) {
throw new ValidationException($validator);
}
} }
/** /**

View file

@ -2,7 +2,6 @@
namespace Pterodactyl\Services\Activity; namespace Pterodactyl\Services\Activity;
use InvalidArgumentException;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
class ActivityLogTargetableService class ActivityLogTargetableService
@ -13,19 +12,11 @@ class ActivityLogTargetableService
public function setActor(Model $actor): void public function setActor(Model $actor): void
{ {
if (!is_null($this->actor)) {
throw new InvalidArgumentException('Cannot call ' . __METHOD__ . ' when an actor is already set on the instance.');
}
$this->actor = $actor; $this->actor = $actor;
} }
public function setSubject(Model $subject): void public function setSubject(Model $subject): void
{ {
if (!is_null($this->subject)) {
throw new InvalidArgumentException('Cannot call ' . __METHOD__ . ' when a target is already set on the instance.');
}
$this->subject = $subject; $this->subject = $subject;
} }

View file

@ -40,8 +40,8 @@ class ServerFactory extends Factory
'oom_disabled' => 0, 'oom_disabled' => 0,
'startup' => '/bin/bash echo "hello world"', 'startup' => '/bin/bash echo "hello world"',
'image' => 'foo/bar:latest', 'image' => 'foo/bar:latest',
'allocation_limit' => 0, 'allocation_limit' => null,
'database_limit' => 0, 'database_limit' => null,
'backup_limit' => 0, 'backup_limit' => 0,
'created_at' => Carbon::now(), 'created_at' => Carbon::now(),
'updated_at' => Carbon::now(), 'updated_at' => Carbon::now(),

View file

@ -2,25 +2,17 @@
namespace Database\Factories; namespace Database\Factories;
use Pterodactyl\Models\Task;
use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Database\Eloquent\Factories\Factory;
class TaskFactory extends Factory class TaskFactory extends Factory
{ {
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = Task::class;
/** /**
* Define the model's default state. * Define the model's default state.
*/ */
public function definition(): array public function definition(): array
{ {
return [ return [
'sequence_id' => $this->faker->randomNumber(1), 'sequence_id' => $this->faker->numberBetween(1, 10),
'action' => 'command', 'action' => 'command',
'payload' => 'test command', 'payload' => 'test command',
'time_offset' => 120, 'time_offset' => 120,

View file

@ -4,6 +4,7 @@ namespace Database\Factories;
use Carbon\Carbon; use Carbon\Carbon;
use Ramsey\Uuid\Uuid; use Ramsey\Uuid\Uuid;
use Illuminate\Support\Str;
use Pterodactyl\Models\User; use Pterodactyl\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Database\Eloquent\Factories\Factory;
@ -24,10 +25,10 @@ class UserFactory extends Factory
static $password; static $password;
return [ return [
'external_id' => $this->faker->unique()->isbn10, 'external_id' => null,
'uuid' => Uuid::uuid4()->toString(), 'uuid' => Uuid::uuid4()->toString(),
'username' => $this->faker->unique()->userName, 'username' => $this->faker->unique()->userName,
'email' => $this->faker->unique()->safeEmail, 'email' => Str::random(32) . '@example.com',
'name_first' => $this->faker->firstName, 'name_first' => $this->faker->firstName,
'name_last' => $this->faker->lastName, 'name_last' => $this->faker->lastName,
'password' => $password ?: $password = bcrypt('password'), 'password' => $password ?: $password = bcrypt('password'),

View file

@ -2,6 +2,7 @@
namespace Pterodactyl\Tests\Integration\Api\Application\Users; namespace Pterodactyl\Tests\Integration\Api\Application\Users;
use Illuminate\Support\Str;
use Pterodactyl\Models\User; use Pterodactyl\Models\User;
use Illuminate\Http\Response; use Illuminate\Http\Response;
use Pterodactyl\Tests\Integration\Api\Application\ApplicationApiIntegrationTestCase; use Pterodactyl\Tests\Integration\Api\Application\ApplicationApiIntegrationTestCase;
@ -13,7 +14,7 @@ class ExternalUserControllerTest extends ApplicationApiIntegrationTestCase
*/ */
public function testGetRemoteUser() public function testGetRemoteUser()
{ {
$user = User::factory()->create(); $user = User::factory()->create(['external_id' => Str::random()]);
$response = $this->getJson('/api/application/users/external/' . $user->external_id); $response = $this->getJson('/api/application/users/external/' . $user->external_id);
$response->assertStatus(Response::HTTP_OK); $response->assertStatus(Response::HTTP_OK);
@ -60,7 +61,7 @@ class ExternalUserControllerTest extends ApplicationApiIntegrationTestCase
*/ */
public function testErrorReturnedIfNoPermission() public function testErrorReturnedIfNoPermission()
{ {
$user = User::factory()->create(); $user = User::factory()->create(['external_id' => Str::random()]);
$this->createNewDefaultApiKey($this->getApiUser(), ['r_users' => 0]); $this->createNewDefaultApiKey($this->getApiUser(), ['r_users' => 0]);
$response = $this->getJson('/api/application/users/external/' . $user->external_id); $response = $this->getJson('/api/application/users/external/' . $user->external_id);

View file

@ -2,6 +2,7 @@
namespace Pterodactyl\Tests\Integration\Api\Client; namespace Pterodactyl\Tests\Integration\Api\Client;
use Illuminate\Support\Str;
use Pterodactyl\Models\User; use Pterodactyl\Models\User;
use Illuminate\Http\Response; use Illuminate\Http\Response;
use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Hash;
@ -41,13 +42,13 @@ class AccountControllerTest extends ClientApiIntegrationTestCase
$user = User::factory()->create(); $user = User::factory()->create();
$response = $this->actingAs($user)->putJson('/api/client/account/email', [ $response = $this->actingAs($user)->putJson('/api/client/account/email', [
'email' => 'hodor@example.com', 'email' => $email = Str::random() . '@example.com',
'password' => 'password', 'password' => 'password',
]); ]);
$response->assertStatus(Response::HTTP_NO_CONTENT); $response->assertStatus(Response::HTTP_NO_CONTENT);
$this->assertDatabaseHas('users', ['id' => $user->id, 'email' => 'hodor@example.com']); $this->assertDatabaseHas('users', ['id' => $user->id, 'email' => $email]);
} }
/** /**

View file

@ -50,7 +50,7 @@ class DeleteServerScheduleTest extends ClientApiIntegrationTestCase
public function testNotFoundErrorIsReturnedIfScheduleDoesNotBelongToServer() public function testNotFoundErrorIsReturnedIfScheduleDoesNotBelongToServer()
{ {
[$user, $server] = $this->generateTestAccount(); [$user, $server] = $this->generateTestAccount();
[, $server2] = $this->generateTestAccount(['user_id' => $user->id]); $server2 = $this->createServerModel(['owner_id' => $user->id]);
$schedule = Schedule::factory()->create(['server_id' => $server2->id]); $schedule = Schedule::factory()->create(['server_id' => $server2->id]);

View file

@ -64,7 +64,7 @@ class GetServerSchedulesTest extends ClientApiIntegrationTestCase
public function testScheduleBelongingToAnotherServerCannotBeViewed() public function testScheduleBelongingToAnotherServerCannotBeViewed()
{ {
[$user, $server] = $this->generateTestAccount(); [$user, $server] = $this->generateTestAccount();
[, $server2] = $this->generateTestAccount(['user_id' => $user->id]); $server2 = $this->createServerModel(['owner_id' => $user->id]);
$schedule = Schedule::factory()->create(['server_id' => $server2->id]); $schedule = Schedule::factory()->create(['server_id' => $server2->id]);

View file

@ -58,7 +58,7 @@ class UpdateServerScheduleTest extends ClientApiIntegrationTestCase
public function testErrorIsReturnedIfScheduleDoesNotBelongToServer() public function testErrorIsReturnedIfScheduleDoesNotBelongToServer()
{ {
[$user, $server] = $this->generateTestAccount(); [$user, $server] = $this->generateTestAccount();
[, $server2] = $this->generateTestAccount(['user_id' => $user->id]); $server2 = $this->createServerModel(['owner_id' => $user->id]);
$schedule = Schedule::factory()->create(['server_id' => $server2->id]); $schedule = Schedule::factory()->create(['server_id' => $server2->id]);

View file

@ -145,7 +145,7 @@ class CreateServerScheduleTaskTest extends ClientApiIntegrationTestCase
public function testErrorIsReturnedIfScheduleDoesNotBelongToServer() public function testErrorIsReturnedIfScheduleDoesNotBelongToServer()
{ {
[$user, $server] = $this->generateTestAccount(); [$user, $server] = $this->generateTestAccount();
[, $server2] = $this->generateTestAccount(['user_id' => $user->id]); $server2 = $this->createServerModel(['owner_id' => $user->id]);
/** @var \Pterodactyl\Models\Schedule $schedule */ /** @var \Pterodactyl\Models\Schedule $schedule */
$schedule = Schedule::factory()->create(['server_id' => $server2->id]); $schedule = Schedule::factory()->create(['server_id' => $server2->id]);

View file

@ -32,8 +32,9 @@ class DeleteSubuserTest extends ClientApiIntegrationTestCase
/** @var \Pterodactyl\Models\User $differentUser */ /** @var \Pterodactyl\Models\User $differentUser */
$differentUser = User::factory()->create(); $differentUser = User::factory()->create();
$real = Uuid::uuid4()->toString();
// Generate a UUID that lines up with a user in the database if it were to be cast to an int. // Generate a UUID that lines up with a user in the database if it were to be cast to an int.
$uuid = $differentUser->id . str_repeat('a', strlen((string) $differentUser->id)) . substr(Uuid::uuid4()->toString(), 8); $uuid = $differentUser->id . substr($real, strlen((string) $differentUser->id));
/** @var \Pterodactyl\Models\User $subuser */ /** @var \Pterodactyl\Models\User $subuser */
$subuser = User::factory()->create(['uuid' => $uuid]); $subuser = User::factory()->create(['uuid' => $uuid]);

View file

@ -28,7 +28,11 @@ class TestResponse extends IlluminateTestResponse
if ($actual !== $status && $status !== 500) { if ($actual !== $status && $status !== 500) {
$this->dump(); $this->dump();
if (!is_null($this->exception) && !$this->exception instanceof DisplayException && !$this->exception instanceof ValidationException) { if (!is_null($this->exception) && !$this->exception instanceof DisplayException && !$this->exception instanceof ValidationException) {
dump($this->exception); dump([
'exception_class' => get_class($this->exception),
'message' => $this->exception->getMessage(),
'trace' => $this->exception->getTrace(),
]);
} }
} }

View file

@ -94,7 +94,6 @@ trait CreatesTestModels
return [$user, $this->createServerModel(['user_id' => $user->id])]; return [$user, $this->createServerModel(['user_id' => $user->id])];
} }
/** @var \Pterodactyl\Models\Server $server */
$server = $this->createServerModel(); $server = $this->createServerModel();
Subuser::query()->create([ Subuser::query()->create([