DarkGhostHunter / Laraconfig

Per-user settings repository system for Laravel
MIT License
173 stars 49 forks source link

Test failed, Property does not exist on this collection instance #25

Open KevinYobeth opened 3 years ago

KevinYobeth commented 3 years ago

The functionality works perfectly on browser. But it keeps failing on feature test.

Here is my controller snippet.

public function update(Request $request)
{
    $settings = [ 
        'DARK_MODE',
        'SEND_NOTIFICATION_ON_NEW_PROJECT_REQUEST',
        'SEND_NOTIFICATION_ON_NEW_JOB_REQUEST'
    ];
    $user = auth()->user();
    $updatedReq = $request->only($settings);

    foreach ($updatedReq as $key => $value) {
        $user->settings->set($key, $value);
    }

    return Redirect::back();
}

Test Snippet

$response = $this->actingAs($this->creator)
            ->from('/settings')
            ->put('/settings', [
                'DARK_MODE' => 'LIGHT',
                'SEND_NOTIFICATION_ON_NEW_PROJECT_REQUEST' => false,
                'SEND_NOTIFICATION_ON_NEW_JOB_REQUEST' => true,
            ]);

Test Setup

public function setUp(): void
{
       parent::setUp();

       Metadata::forceCreate([
           'name'    => 'DARK_MODE',
           'type'    => 'string',
           'default' => 'AUTO',
       ]);
       Metadata::forceCreate([
           'name'    => 'SEND_NOTIFICATION_ON_NEW_PROJECT_REQUEST',
           'type'    => 'boolean',
           'default' => true,
       ]);
       Metadata::forceCreate([
           'name'    => 'SEND_NOTIFICATION_ON_NEW_JOB_REQUEST',
           'type'    => 'boolean',
           'default' => true,
       ]);
       $this->creator = User::factory()->create();
       $this->user = User::factory()->create();

       $this->creator->assignRole('CREATOR');
}

I can assure you, all the database seeded and migrated properly. I can do dd($user->settings) and it shows me all 3 items. But when I tried to update it using $user->settings->set($key, $value) on for each, it fails with the error

 Property [DARK_MODE] does not exist on this collection instance.

  at D:\Project\_kevinyobeth\SynchV2\vendor\laravel\framework\src\Illuminate\Collections\Traits\EnumeratesValues.php:912
    908▕      */
    909▕     public function __get($key)
    910▕     {
    911▕         if (! in_array($key, static::$proxies)) {
  ➜ 912▕             throw new Exception("Property [{$key}] does not exist on this collection instance.");
    913▕         }
    914▕
    915▕         return new HigherOrderCollectionProxy($this, $key);
    916▕     }

  1   D:\Project\_kevinyobeth\SynchV2\vendor\darkghosthunter\laraconfig\src\SettingsCollection.php:326
      DarkGhostHunter\Laraconfig\SettingsCollection::__dynamicGet("DARK_MODE")

  2   D:\Project\_kevinyobeth\SynchV2\tests\Feature\SettingsTest.php:68
      DarkGhostHunter\Laraconfig\SettingsCollection::__get("DARK_MODE")

Update 1

I tried getting the keys from the test, and real browser test, it returns different keys. When I ran this $user->settings->keys() Result ["DARK_MODE","SEND_NOTIFICATION_ON_NEW_PROJECT_REQUEST","SEND_NOTIFICATION_ON_NEW_JOB_REQUEST"]

While on the test when I ran it, it returns Result [0,1,2]

My Workaround

To overcome this problem, I came up with this solution. I search the user setting manually in the controller and it works!

foreach ($updatedReq as $key => $value) {
    $setting = $user->settings->where('name', $key)->first();     
    $setting->value = $value;
    $setting->save();
}
ricventu commented 2 years ago

Same issue here. In my case the problem is that settings:migrate stores settable_type, in user_settings table, to AppModelsUser instead of App\Models\User

divdax commented 2 years ago

Issue #29