Skip to content

Commit

Permalink
Avoid exceptions on invalid values, uses empty array instead
Browse files Browse the repository at this point in the history
  • Loading branch information
erikn69 committed Nov 8, 2021
1 parent 0e8b8e3 commit 8394a54
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 5 deletions.
20 changes: 16 additions & 4 deletions src/Casts/SchemalessAttributes.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,31 @@ public function get($model, $key, $value, $attributes)
*/
public function set($model, $key, $value, $attributes)
{
if ($this->isJson($value)) {
if ($this->isJsonArray($value)) {
return $value;
}

return json_encode($value);
$json = json_encode($value);

if (! is_array(json_decode($json, true))) {
return null;
}

return $json;
}

protected function isJson($value): bool
protected function isJsonArray($value): bool
{
if (! is_string($value)) {
return false;
}

return $value === json_encode(json_decode($value));
$array = json_decode($value, true);

if (! is_array($array)) {
return false;
}

return $value === json_encode($array);
}
}
4 changes: 3 additions & 1 deletion src/SchemalessAttributes.php
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,9 @@ protected function getRawSchemalessAttributes(): array
{
$attributes = $this->model->getAttributes()[$this->sourceAttributeName] ?? '{}';

return $attributes === '""' ? [] : $this->model->fromJson($attributes);
$array = $this->model->fromJson($attributes);

return is_array($array) ? $array : [];
}

protected function override(iterable $collection): static
Expand Down
50 changes: 50 additions & 0 deletions tests/HasSchemalessAttributesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,31 @@ public function an_schemaless_attribute_can_be_set_from_json()
$this->assertEquals('value', $this->testModel->schemaless_attributes->name);
}

/** @test */
public function an_schemaless_attribute_uses_fallback_empty_array_on_non_valid_values()
{
$this->testModel->schemaless_attributes = 'string';
$this->assertEquals([], $this->testModel->schemaless_attributes->all());

$this->testModel->schemaless_attributes = '""'; // not array json
$this->assertEquals([], $this->testModel->schemaless_attributes->all());

$this->testModel->schemaless_attributes = "{'name':'value'}"; // invalid json format
$this->assertEquals([], $this->testModel->schemaless_attributes->all());

$this->testModel->schemaless_attributes = null;
$this->assertEquals([], $this->testModel->schemaless_attributes->all());

$this->testModel->schemaless_attributes = false;
$this->assertEquals([], $this->testModel->schemaless_attributes->all());

$this->testModel->schemaless_attributes = 1;
$this->assertEquals([], $this->testModel->schemaless_attributes->all());

$this->testModel->schemaless_attributes = 0.1;
$this->assertEquals([], $this->testModel->schemaless_attributes->all());
}

/** @test */
public function it_can_determine_if_it_has_a_schemaless_attribute()
{
Expand Down Expand Up @@ -266,6 +291,31 @@ public function it_can_and_save_schemaless_attributes_from_json()
$this->assertEquals($array, $testModel->schemaless_attributes->all());
}

/** @test */
public function it_can_and_save_schemaless_attributes_as_null_when_non_valid_values()
{
$testModel = TestModel::create(['schemaless_attributes' => 'string']);
$this->assertEquals(null, $testModel->getAttributes()['schemaless_attributes']);

$testModel = TestModel::create(['schemaless_attributes' => '""']); // not array json
$this->assertEquals(null, $testModel->getAttributes()['schemaless_attributes']);

$testModel = TestModel::create(['schemaless_attributes' => "{'name':'value'}"]); // invalid json format
$this->assertEquals(null, $testModel->getAttributes()['schemaless_attributes']);

$testModel = TestModel::create(['schemaless_attributes' => null]);
$this->assertEquals(null, $testModel->getAttributes()['schemaless_attributes']);

$testModel = TestModel::create(['schemaless_attributes' => false]);
$this->assertEquals(null, $testModel->getAttributes()['schemaless_attributes']);

$testModel = TestModel::create(['schemaless_attributes' => 1]);
$this->assertEquals(null, $testModel->getAttributes()['schemaless_attributes']);

$testModel = TestModel::create(['schemaless_attributes' => 0.1]);
$this->assertEquals(null, $testModel->getAttributes()['schemaless_attributes']);
}

/** @test */
public function it_has_a_scope_to_get_models_with_the_given_schemaless_attributes()
{
Expand Down

0 comments on commit 8394a54

Please sign in to comment.