tanggal_kadaluarsa = Carbon::now()->addDays(30)->toDateString(); // Cast manually to trigger accessor $obat->setRawAttributes(['tanggal_kadaluarsa' => Carbon::now()->addDays(30)->toDateString()]); $this->assertGreaterThan(0, $obat->sisa_hari); } public function test_sisa_hari_is_negative_for_past_expiry(): void { $obat = new ObatMasuk(); $obat->setRawAttributes(['tanggal_kadaluarsa' => Carbon::now()->subDays(5)->toDateString()]); $this->assertLessThan(0, $obat->sisa_hari); } public function test_sisa_hari_is_zero_or_very_small_for_today_expiry(): void { $obat = new ObatMasuk(); $obat->setRawAttributes(['tanggal_kadaluarsa' => Carbon::now()->toDateString()]); // Bisa 0 atau 1 tergantung waktu persis $this->assertLessThanOrEqual(1, abs($obat->sisa_hari)); } // ───────────────────────────────────────── // getStatusKadaluarsaAttribute() // ───────────────────────────────────────── public function test_status_kadaluarsa_is_kritis_when_less_than_or_equal_30_days(): void { $obat = new ObatMasuk(); $obat->setRawAttributes(['tanggal_kadaluarsa' => Carbon::now()->addDays(25)->toDateString()]); $this->assertEquals('kritis', $obat->status_kadaluarsa); } public function test_status_kadaluarsa_is_kritis_when_already_expired(): void { $obat = new ObatMasuk(); $obat->setRawAttributes(['tanggal_kadaluarsa' => Carbon::now()->subDays(1)->toDateString()]); $this->assertEquals('kritis', $obat->status_kadaluarsa); } public function test_status_kadaluarsa_is_kritis_when_exactly_30_days(): void { $obat = new ObatMasuk(); $obat->setRawAttributes(['tanggal_kadaluarsa' => Carbon::now()->addDays(30)->toDateString()]); $this->assertEquals('kritis', $obat->status_kadaluarsa); } public function test_status_kadaluarsa_is_waspada_when_between_31_and_60_days(): void { $obat = new ObatMasuk(); $obat->setRawAttributes(['tanggal_kadaluarsa' => Carbon::now()->addDays(45)->toDateString()]); $this->assertEquals('waspada', $obat->status_kadaluarsa); } public function test_status_kadaluarsa_is_aman_when_more_than_60_days(): void { $obat = new ObatMasuk(); $obat->setRawAttributes(['tanggal_kadaluarsa' => Carbon::now()->addDays(90)->toDateString()]); $this->assertEquals('aman', $obat->status_kadaluarsa); } public function test_status_kadaluarsa_is_aman_when_more_than_60_days_away(): void { $obat = new ObatMasuk(); $obat->setRawAttributes(['tanggal_kadaluarsa' => Carbon::now()->addDays(65)->toDateString()]); $this->assertEquals('aman', $obat->status_kadaluarsa); } // ───────────────────────────────────────── // getStatusStokAttribute() // ───────────────────────────────────────── public function test_status_stok_is_tersedia_when_stok_greater_than_zero(): void { $obat = new ObatMasuk(); $obat->setRawAttributes(['stok' => 10]); $this->assertEquals('tersedia', $obat->status_stok); } public function test_status_stok_is_habis_when_stok_is_zero(): void { $obat = new ObatMasuk(); $obat->setRawAttributes(['stok' => 0]); $this->assertEquals('habis', $obat->status_stok); } public function test_status_stok_is_tersedia_when_stok_is_one(): void { $obat = new ObatMasuk(); $obat->setRawAttributes(['stok' => 1]); $this->assertEquals('tersedia', $obat->status_stok); } // ───────────────────────────────────────── // Fillable & Casts // ───────────────────────────────────────── public function test_obat_masuk_has_correct_fillable_fields(): void { $obat = new ObatMasuk(); $this->assertContains('nama_obat', $obat->getFillable()); $this->assertContains('kode_batch', $obat->getFillable()); $this->assertContains('stok', $obat->getFillable()); $this->assertContains('tanggal_kadaluarsa', $obat->getFillable()); } public function test_tanggal_columns_are_cast_as_date(): void { $obat = new ObatMasuk(); $casts = $obat->getCasts(); $this->assertEquals('date', $casts['tanggal_penerimaan']); $this->assertEquals('date', $casts['tanggal_kadaluarsa']); } }