Have you tried mocking it?
Jan 24, 2020
6
Level 9
How do I test encrypted database fields?
I'm encrypting database fields using a custom Encryptable trait:
Encryptable.php
<?php
namespace App;
use Illuminate\Support\Facades\Crypt;
trait Encryptable
{
public function getAttribute($key)
{
$value = parent::getAttribute($key);
if (in_array($key, $this->encryptable)) {
$value = Crypt::decrypt($value);
return $value;
} else {
return $value;
}
}
public function setAttribute($key, $value)
{
if (in_array($key, $this->encryptable)) {
$value = Crypt::encrypt($value);
}
return parent::setAttribute($key, $value);
}
}
This allows me to specify in my model what fields I would like encrypted:
Post
use Encryptable;
protected $encryptable = ['title'];
I've learned that Crypt doesn't create a reproducible hash which makes it problematic in my assertDatabaseHas() assertions:
CreatePostTest.php
/** @test */
public function a_user_can_create_a_thought_record()
{
//$this->withoutExceptionHandling();
$this->actingAs($creator = factory('App\User')->create());
$post = factory('App\Post')->make(['user_id' => $creator->id]);
//You can't use $post->toArray() because toArray() encrypts fields.
$decryptedPost = [
'title' => $post->title,
];
$response = $this->json('POST', '/api/posts', $decryptedPost )
->assertStatus(201);
$this->assertDatabaseHas('posts', [
'title' => $post->title,
]);
}
As said this doesn't work:
$this->assertDatabaseHas('posts', [
'title' => $post->title,
]);
What other test can I use to assert that the posts title is the same in the database as what I'm sending through the request and how do I do this?
Please or to participate in this conversation.