Skip to content

Commit

Permalink
Merge pull request #55 from cjmellor/54-issue-when-rolling-back-model…
Browse files Browse the repository at this point in the history
…s-that-contain-json-fields
  • Loading branch information
cjmellor authored Feb 27, 2024
2 parents 06fe07e + 7d58247 commit f417cec
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 7 deletions.
12 changes: 10 additions & 2 deletions src/Concerns/MustBeApproved.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ protected static function insertApprovalRequest($model)
{
$filteredDirty = $model->getDirtyAttributes();

if (auth()->check()) {
$filteredDirty['user_id'] = auth()->id();
foreach ($filteredDirty as $key => $value) {
if (isset($model->casts[$key]) && $model->casts[$key] === 'json') {
$filteredDirty[$key] = json_decode(json: $value, associative: true);
}
}

if ($model->isApprovalBypassed() || empty($filteredDirty)) {
Expand Down Expand Up @@ -141,6 +143,12 @@ public function withoutApproval(): static
public function callCastAttribute($key, $value): mixed
{
if (array_key_exists($key, $this->casts)) {
// If the value is already an array, return it as is
if (is_array($value)) {
return $value;
}

// Otherwise, cast the attribute to its defined type
return $this->castAttribute($key, $value);
}

Expand Down
67 changes: 62 additions & 5 deletions tests/Feature/MustBeApprovedTraitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,7 @@
});

test(description: 'an approvals model is created when a model is created with MustBeApproved trait set and has the approvalInclude array set', closure: function () {
$model = new class extends Model
{
$model = new class extends Model {
use MustBeApproved;

protected $table = 'fake_models';
Expand Down Expand Up @@ -179,8 +178,7 @@
$table->json('data')->nullable();
});

$model = new class extends Model
{
$model = new class extends Model {
use MustBeApproved;

protected $table = 'fake_models_with_array';
Expand Down Expand Up @@ -219,9 +217,68 @@
'data' => json_encode(['foo', 'bar']),
]);

// double check the model
// double-check the model
$modelFromDatabase = $model->firstWhere('name', 'Neo');

expect($modelFromDatabase->data)
->toBe(['foo', 'bar']);
});

test(description: 'a Model can be rolled back when the data contains JSON fields', closure: function () {
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->string('content');
$table->json('config');
$table->timestamps();
});

$model = new class extends Model {
use MustBeApproved;

protected $table = 'posts';

protected $guarded = [];

protected $casts = ['config' => 'json'];
};

// create a model
$model->create([
'title' => 'My First Post',
'content' => 'This is my first post',
'config' => ['checked' => true],
]);

// check if the data is stored correctly in the approval table
$this->assertDatabaseHas(table: Approval::class, data: [
'new_data' => json_encode([
'title' => 'My First Post',
'content' => 'This is my first post',
'config' => ['checked' => true],
]),
'original_data' => json_encode([]),
]);

// nothing should be in the 'posts' table
$this->assertDatabaseCount('posts', 0);

// approve the model
Approval::first()->approve();

// after approval, there should be in an entry in the 'posts' table
$this->assertDatabaseCount('posts', 1);

// After Approval, the contents of the database should look like this
$this->assertDatabaseHas(table: 'posts', data: [
'title' => 'My First Post',
'content' => 'This is my first post',
'config' => json_encode(['checked' => true]),
]);

// double-check the model
$modelFromDatabase = $model->firstWhere('title', 'My First Post');

expect($modelFromDatabase->config)
->toBe(['checked' => true]);
});

0 comments on commit f417cec

Please sign in to comment.