From 2183329aaae9a47a50d96f91d4cb192de4c76553 Mon Sep 17 00:00:00 2001 From: Zach Leigh Date: Mon, 6 Jun 2016 17:46:10 +0900 Subject: [PATCH] Store all values as JSON to avoid type issues. --- ..._000000_create_user_property_bag_table.php | 2 +- src/Settings/Settings.php | 19 ++- src/UserSettings/UserPropertyBag.php | 9 ++ tests/Classes/GroupPropertyBag.php | 9 ++ tests/Migrations/CreateGroupSettingsTable.php | 2 +- tests/PropertyBagTest.php | 112 +++--------------- tests/TypeTest.php | 99 ++++++++++++++++ 7 files changed, 149 insertions(+), 103 deletions(-) create mode 100644 tests/TypeTest.php diff --git a/src/Migrations/2016_06_03_000000_create_user_property_bag_table.php b/src/Migrations/2016_06_03_000000_create_user_property_bag_table.php index ff57b51..49920dc 100644 --- a/src/Migrations/2016_06_03_000000_create_user_property_bag_table.php +++ b/src/Migrations/2016_06_03_000000_create_user_property_bag_table.php @@ -16,7 +16,7 @@ public function up() $table->increments('id'); $table->integer('user_id')->unsigned()->index(); $table->string('key'); - $table->boolean('value'); + $table->json('value'); $table->timestamps(); $table->foreign('user_id')->references('id')->on('users'); diff --git a/src/Settings/Settings.php b/src/Settings/Settings.php index ed8e62c..c292a6e 100644 --- a/src/Settings/Settings.php +++ b/src/Settings/Settings.php @@ -211,7 +211,12 @@ public function flagAsChanged($key, $syncType) */ public function refreshSettings() { - $this->settings = $this->resource->allSettings(); + $this->resource->load('propertyBag'); + + $this->settings = $this->resource->allSettings() + ->flatMap(function ($model) { + return [$model->key => json_decode($model->value)[0]]; + }); } /** @@ -244,7 +249,7 @@ protected function newRecord($key) return $model::create([ $this->primaryKey => $this->resource->id(), 'key' => $key, - 'value' => $this->get($key), + 'value' => json_encode([$this->get($key)]), ]); } @@ -259,9 +264,15 @@ protected function updateRecord($key) { $model = $this->resource->getPropertyBagClass(); - return $model::where($this->primaryKey, '=', $this->resource->id()) + $record = $model::where($this->primaryKey, '=', $this->resource->id()) ->where('key', '=', $key) - ->update(['value' => $this->get($key)]); + ->first(); + + $record->value = json_encode([$this->get($key)]); + + $record->save(); + + return $record; } /** diff --git a/src/UserSettings/UserPropertyBag.php b/src/UserSettings/UserPropertyBag.php index 9ac69b0..d68f05d 100644 --- a/src/UserSettings/UserPropertyBag.php +++ b/src/UserSettings/UserPropertyBag.php @@ -17,6 +17,15 @@ class UserPropertyBag extends Model 'value' ]; + /** + * The attributes that should be casted to native types. + * + * @var array + */ + protected $casts = [ + 'value' => 'array' + ]; + /** * The table associated with the model. * diff --git a/tests/Classes/GroupPropertyBag.php b/tests/Classes/GroupPropertyBag.php index 8344e7e..63cd076 100644 --- a/tests/Classes/GroupPropertyBag.php +++ b/tests/Classes/GroupPropertyBag.php @@ -17,6 +17,15 @@ class GroupPropertyBag extends Model 'value' ]; + /** + * The attributes that should be casted to native types. + * + * @var array + */ + protected $casts = [ + 'value' => 'array' + ]; + /** * The table associated with the model. * diff --git a/tests/Migrations/CreateGroupSettingsTable.php b/tests/Migrations/CreateGroupSettingsTable.php index 949fcba..e3e1373 100644 --- a/tests/Migrations/CreateGroupSettingsTable.php +++ b/tests/Migrations/CreateGroupSettingsTable.php @@ -19,7 +19,7 @@ public function up() $table->increments('id'); $table->integer('group_id')->unsigned()->index(); $table->string('key'); - $table->boolean('value'); + $table->json('value'); $table->timestamps(); $table->foreign('group_id')->references('id')->on('users'); diff --git a/tests/PropertyBagTest.php b/tests/PropertyBagTest.php index 71d11d0..a3c2068 100644 --- a/tests/PropertyBagTest.php +++ b/tests/PropertyBagTest.php @@ -5,7 +5,7 @@ use Illuminate\Support\Collection; use LaravelPropertyBag\UserSettings\UserSettings; -class SettingsTest extends TestCase +class PropertyBagTest extends TestCase { /** * @test @@ -103,7 +103,7 @@ public function adding_a_new_setting_creates_a_new_user_setting_record() $this->seeInDatabase('user_property_bag', [ 'user_id' => $user->id(), 'key' => 'test_settings2', - 'value' => 1 + 'value' => json_encode('[true]') ]); } @@ -127,7 +127,7 @@ public function updating_a_setting_updates_the_setting() $this->seeInDatabase('user_property_bag', [ 'user_id' => $user->id(), 'key' => 'test_settings2', - 'value' => 0 + 'value' => json_encode('[false]') ]); } @@ -156,7 +156,7 @@ public function a_user_can_set_many_settings_at_once() $this->seeInDatabase('user_property_bag', [ 'user_id' => $user->id(), 'key' => 'test_settings1', - 'value' => 'grapes' + 'value' => json_encode('["grapes"]') ]); $this->assertContains('test_settings2', $settings->all()); @@ -166,7 +166,7 @@ public function a_user_can_set_many_settings_at_once() $this->seeInDatabase('user_property_bag', [ 'user_id' => $user->id(), 'key' => 'test_settings2', - 'value' => 1 + 'value' => json_encode('[true]') ]); } @@ -178,6 +178,14 @@ public function only_changed_settings_are_updated() // TODO } + /** + * @test + */ + public function settings_on_the_object_match_the_settings_in_the_database() + { + // TODO + } + /** * @test */ @@ -266,7 +274,7 @@ public function a_resource_can_access_and_use_the_property_bag() $this->seeInDatabase('group_settings', [ 'group_id' => $group->id(), 'key' => 'test_settings1', - 'value' => 'grapes' + 'value' => json_encode('["grapes"]') ]); $this->assertContains('test_settings2', $settings->all()); @@ -276,7 +284,7 @@ public function a_resource_can_access_and_use_the_property_bag() $this->seeInDatabase('group_settings', [ 'group_id' => $group->id(), 'key' => 'test_settings2', - 'value' => 1 + 'value' => json_encode('[true]') ]); } @@ -292,96 +300,6 @@ public function settings_can_be_registered_on_settings_class() $this->assertTrue($settings->isRegistered('test_settings1')); } - /** - * @test - */ - public function it_distinguishes_between_bool_and_int_types() - { - $user = $this->makeUser(); - - $this->actingAs($user); - - $user->settings($this->registered)->set(['test_settings3' => true]); - - settings()->refreshSettings(); - - $result = settings()->get('test_settings3'); - - $this->assertTrue($result === true); - - $this->assertTrue($result !== 1); - - $user->settings($this->registered)->set(['test_settings3' => 1]); - - settings()->refreshSettings(); - - $result = settings()->get('test_settings3'); - - $this->assertTrue($result === 1); - - $this->assertTrue($result !== true); - } - - /** - * @test - */ - public function it_distinguishes_between_bool_and_string_types() - { - $user = $this->makeUser(); - - $this->actingAs($user); - - $user->settings($this->registered)->set(['test_settings3' => 'true']); - - settings()->refreshSettings(); - - $result = settings()->get('test_settings3'); - - $this->assertTrue($result === 'true'); - - $this->assertTrue($result !== true); - - $user->settings($this->registered)->set(['test_settings3' => false]); - - settings()->refreshSettings(); - - $result = settings()->get('test_settings3'); - - $this->assertTrue($result === false); - - $this->assertTrue($result !== 'false'); - } - - /** - * @test - */ - public function it_distinguishes_between_int_and_string_types() - { - $user = $this->makeUser(); - - $this->actingAs($user); - - $user->settings($this->registered)->set(['test_settings3' => 1]); - - settings()->refreshSettings(); - - $result = settings()->get('test_settings3'); - - $this->assertTrue($result === 1); - - $this->assertTrue($result !== '1'); - - $user->settings($this->registered)->set(['test_settings3' => '0']); - - settings()->refreshSettings(); - - $result = settings()->get('test_settings3'); - - $this->assertTrue($result === '0'); - - $this->assertTrue($result !== 0); - } - /** * @test */ diff --git a/tests/TypeTest.php b/tests/TypeTest.php new file mode 100644 index 0000000..0541979 --- /dev/null +++ b/tests/TypeTest.php @@ -0,0 +1,99 @@ +makeUser(); + + $this->actingAs($user); + + $user->settings($this->registered)->set(['test_settings3' => true]); + + settings()->refreshSettings(); + + $result = settings()->get('test_settings3'); + + $this->assertTrue($result === true); + + $this->assertTrue($result !== 1); + + $user->settings($this->registered)->set(['test_settings3' => 1]); + + settings()->refreshSettings(); + + $result = settings()->get('test_settings3'); + + $this->assertTrue($result === 1); + + $this->assertTrue($result !== true); + } + + /** + * @test + */ + public function it_distinguishes_between_bool_and_string_types() + { + $user = $this->makeUser(); + + $this->actingAs($user); + + $user->settings($this->registered)->set(['test_settings3' => 'true']); + + settings()->refreshSettings(); + + $result = settings()->get('test_settings3'); + + $this->assertTrue($result === 'true'); + + $this->assertTrue($result !== true); + + $user->settings($this->registered)->set(['test_settings3' => false]); + + settings()->refreshSettings(); + + $result = settings()->get('test_settings3'); + + $this->assertTrue($result === false); + + $this->assertTrue($result !== 'false'); + } + + /** + * @test + */ + public function it_distinguishes_between_int_and_string_types() + { + $user = $this->makeUser(); + + $this->actingAs($user); + + $user->settings($this->registered)->set(['test_settings3' => 1]); + + settings()->refreshSettings(); + + $result = settings()->get('test_settings3'); + + $this->assertTrue($result === 1); + + $this->assertTrue($result !== '1'); + + $user->settings($this->registered)->set(['test_settings3' => '0']); + + settings()->refreshSettings(); + + $result = settings()->get('test_settings3'); + + $this->assertTrue($result === '0'); + + $this->assertTrue($result !== 0); + } +}