I'm writing some tests to my models in laravel and i've getting some troubles when i enable Activity Log by using spatie/laravel-activitylog.
So, i create a user, using Factory
, i authenticate in system, and when i'll try to logout, i get this error:
1) Tests\Feature\Usuario\CriarUsuarioTest::testAcessaPaginaDeRegistro Illuminate\Database\Eloquent\JsonEncodingException: Unable to encode attribute [properties] for model [Spatie\Activitylog\Models\Activity] to JSON: Type is not supported.
My test TestCase.php
:
protected function setUp()
{
parent::setUp();
$this->user = create('App\Models\Usuario');
$this->singIn($this->user)
->disableExceptionHandling();
}
...
...
...
protected function singIn($user)
{
$this->actingAs($user);
return $this;
}
protected function singOut()
{
// routeLogout() goes to '/logout' route.
$this->post(routeLogout()); // <- Here, where the error occurs
return $this;
}
My App/Models/Usuario.php
model:
namespace App\Models;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Webpatser\Uuid\Uuid;
use Spatie\Activitylog\Traits\LogsActivity;
class Usuario extends Authenticatable
{
use LogsActivity, Notifiable, SoftDeletes;
protected $table = 'usuario';
protected $fillable = [/*...*/] ; // I remove this to post here on SO
protected static $logFillable = true;
public $timestamps = true;
protected $dates = [
'created_at',
'updated_at',
'deleted_at'
];
protected static function boot()
{
// Handle the \LogsActivity boot method
parent::boot();
static::saving(function ($usuario){
$usuario->uuid = Uuid::generate()->string;
});
}
public function getRouteKeyName()
{
return 'uuid';
}
}
My config/activitylog.php
file:
return [
'enabled' => env('ACTIVITY_LOGGER_ENABLED', true),
'delete_records_older_than_days' => 365,
'default_log_name' => 'default',
'default_auth_driver' => null,
'subject_returns_soft_deleted_models' => false,
'activity_model' => \Spatie\Activitylog\Models\Activity::class,
];
My phpunit.xml
file:
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="Feature">
<directory suffix="Test.php">./tests/Feature</directory>
</testsuite>
<testsuite name="Unit">
<directory suffix="Test.php">./tests/Unit</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">./app</directory>
</whitelist>
</filter>
<php>
<env name="APP_ENV" value="testing"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="QUEUE_DRIVER" value="sync"/>
<env name="API_DEBUG" value="true"/>
<env name="memory_limit" value="512M"/>
<env name="APP_DATABASE" value="test"/>
</php>
</phpunit>
My create_activity_log_migration
file:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateActivityLogTable extends Migration
{
/**
* Run the migrations.
*/
public function up()
{
Schema::create('activity_log', function (Blueprint $table) {
$table->increments('id');
$table->string('log_name')->nullable();
$table->string('description');
$table->integer('subject_id')->nullable();
$table->string('subject_type')->nullable();
$table->integer('causer_id')->nullable();
$table->string('causer_type')->nullable();
$table->text('properties')->nullable();
$table->timestamps();
$table->index('log_name');
});
}
/**
* Reverse the migrations.
*/
public function down()
{
Schema::drop('activity_log');
}
}
I notice then when i disable Activity Log for model, its work fine. And, when i use the system by tinker or browser, logs also work as well.
I haven't been able to reproduce the error, but I do have some considerations:
created
, updated
or deleted
events are triggered there.created
event is indeed triggered when you create the user with the factory. That in turn triggers the activity log.Activity
you get the exception Illuminate\Database\Eloquent\JsonEncodingException: Unable to encode attribute [properties] for model [Spatie\Activitylog\Models\Activity] to JSON: Type is not supported.
. That is almost definitely thrown in Illuminate\Database\Eloquent\Concerns\HasAttributes@castAttributeAsJson
method, which does a simple json_encode
on the attribute value.properties
to be logged? try dd($user->attributeValuesToBeLogged('created'))
just after creating the User.