run(); $welcome = NotificationDefinition::where('type', 'welcome')->first(); $this->assertNotNull($welcome); $this->assertNull($welcome->user_overrides); } public function test_user_modification_records_name_in_user_overrides(): void { (new NotificationDefinitionSeeder)->run(); $definition = NotificationDefinition::where('type', 'welcome')->first(); $definition->name = ['ko' => '커스텀 회원가입 환영', 'en' => 'Custom Welcome']; $definition->save(); // 다국어 JSON 컬럼은 sub-key dot-path 단위로 기록된다 (HasUserOverrides @since 7.0.0-beta.4) $this->assertEqualsCanonicalizing(['name.ko', 'name.en'], $definition->fresh()->user_overrides); } public function test_seeder_re_run_preserves_user_modified_name(): void { (new NotificationDefinitionSeeder)->run(); $definition = NotificationDefinition::where('type', 'welcome')->first(); $definition->name = ['ko' => '커스텀 회원가입 환영', 'en' => 'Custom Welcome']; $definition->save(); // 시더 재실행 — syncOrCreateFromUpgrade 가 trackable 필드는 보존해야 함 (new NotificationDefinitionSeeder)->run(); $fresh = $definition->fresh(); $this->assertEquals(['ko' => '커스텀 회원가입 환영', 'en' => 'Custom Welcome'], $fresh->name); $this->assertEqualsCanonicalizing(['name.ko', 'name.en'], $fresh->user_overrides); } public function test_seeder_re_run_updates_non_trackable_fields(): void { (new NotificationDefinitionSeeder)->run(); $definition = NotificationDefinition::where('type', 'welcome')->first(); // hooks 는 trackable 외 필드 — 시더 재실행 시 항상 갱신되어야 함 $definition->hooks = ['legacy.hook']; // hooks 수정은 user_overrides 에 기록되지 않아야 함 $definition->save(); $this->assertNull($definition->fresh()->user_overrides); (new NotificationDefinitionSeeder)->run(); // 시더 정의값으로 갱신 $this->assertEquals(['core.auth.after_register'], $definition->fresh()->hooks); } }