diff --git a/src/app/Entitlement.php b/src/app/Entitlement.php index 494b7f2f..cf147f72 100644 --- a/src/app/Entitlement.php +++ b/src/app/Entitlement.php @@ -1,161 +1,159 @@ 'integer', 'fee' => 'integer' ]; /** * Return the costs per day for this entitlement. * * @return float */ public function costsPerDay() { if ($this->cost == 0) { return (float) 0; } $discount = $this->wallet->getDiscountRate(); $daysInLastMonth = \App\Utils::daysInLastMonth(); $costsPerDay = (float) ($this->cost * $discount) / $daysInLastMonth; return $costsPerDay; } /** * Create a transaction record for this entitlement. * * @param string $type The type of transaction ('created', 'billed', 'deleted'), but use the * \App\Transaction constants. * @param int $amount The amount involved in cents * * @return string The transaction ID */ public function createTransaction($type, $amount = null) { $transaction = \App\Transaction::create( [ 'object_id' => $this->id, 'object_type' => \App\Entitlement::class, 'type' => $type, 'amount' => $amount ] ); return $transaction->id; } /** * Principally entitleable objects such as 'Domain' or 'User'. * * @return mixed */ public function entitleable() { return $this->morphTo(); } /** * Returns entitleable object title (e.g. email or domain name). * * @return string|null An object title/name */ public function entitleableTitle(): ?string { - if ($this->entitleable instanceof \App\User) { - return $this->entitleable->email; - } - if ($this->entitleable instanceof \App\Domain) { return $this->entitleable->namespace; } + + return $this->entitleable->email; } /** * The SKU concerned. * * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function sku() { return $this->belongsTo('App\Sku'); } /** * The wallet this entitlement is being billed to * * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function wallet() { return $this->belongsTo('App\Wallet'); } /** * Cost mutator. Make sure cost is integer. */ public function setCostAttribute($cost): void { $this->attributes['cost'] = round($cost); } } diff --git a/src/tests/Feature/EntitlementTest.php b/src/tests/Feature/EntitlementTest.php index e6f03802..4ddd7293 100644 --- a/src/tests/Feature/EntitlementTest.php +++ b/src/tests/Feature/EntitlementTest.php @@ -1,130 +1,175 @@ deleteTestUser('entitlement-test@kolabnow.com'); $this->deleteTestUser('entitled-user@custom-domain.com'); + $this->deleteTestGroup('test-group@custom-domain.com'); $this->deleteTestDomain('custom-domain.com'); } /** * {@inheritDoc} */ public function tearDown(): void { $this->deleteTestUser('entitlement-test@kolabnow.com'); $this->deleteTestUser('entitled-user@custom-domain.com'); + $this->deleteTestGroup('test-group@custom-domain.com'); $this->deleteTestDomain('custom-domain.com'); parent::tearDown(); } /** * Test for Entitlement::costsPerDay() */ public function testCostsPerDay(): void { // 444 // 28 days: 15.86 // 31 days: 14.32 $user = $this->getTestUser('entitlement-test@kolabnow.com'); $package = Package::where('title', 'kolab')->first(); $mailbox = Sku::where('title', 'mailbox')->first(); $user->assignPackage($package); $entitlement = $user->entitlements->where('sku_id', $mailbox->id)->first(); $costsPerDay = $entitlement->costsPerDay(); $this->assertTrue($costsPerDay < 15.86); $this->assertTrue($costsPerDay > 14.32); } /** * Tests for entitlements * @todo This really should be in User or Wallet tests file */ public function testEntitlements(): void { $packageDomain = Package::where('title', 'domain-hosting')->first(); $packageKolab = Package::where('title', 'kolab')->first(); $skuDomain = Sku::where('title', 'domain-hosting')->first(); $skuMailbox = Sku::where('title', 'mailbox')->first(); $owner = $this->getTestUser('entitlement-test@kolabnow.com'); $user = $this->getTestUser('entitled-user@custom-domain.com'); $domain = $this->getTestDomain( 'custom-domain.com', [ 'status' => Domain::STATUS_NEW, 'type' => Domain::TYPE_EXTERNAL, ] ); $domain->assignPackage($packageDomain, $owner); $owner->assignPackage($packageKolab); $owner->assignPackage($packageKolab, $user); $wallet = $owner->wallets->first(); $this->assertCount(4, $owner->entitlements()->get()); $this->assertCount(1, $skuDomain->entitlements()->where('wallet_id', $wallet->id)->get()); $this->assertCount(2, $skuMailbox->entitlements()->where('wallet_id', $wallet->id)->get()); $this->assertCount(9, $wallet->entitlements); $this->backdateEntitlements( $owner->entitlements, Carbon::now()->subMonthsWithoutOverflow(1) ); $wallet->chargeEntitlements(); $this->assertTrue($wallet->fresh()->balance < 0); } /** * @todo This really should be in User tests file */ public function testEntitlementFunctions(): void { $user = $this->getTestUser('entitlement-test@kolabnow.com'); $package = \App\Package::where('title', 'kolab')->first(); $user->assignPackage($package); $wallet = $user->wallets()->first(); $this->assertNotNull($wallet); $sku = \App\Sku::where('title', 'mailbox')->first(); $entitlement = Entitlement::where('wallet_id', $wallet->id) ->where('sku_id', $sku->id)->first(); $this->assertNotNull($entitlement); $this->assertSame($sku->id, $entitlement->sku->id); $this->assertSame($wallet->id, $entitlement->wallet->id); $this->assertEquals($user->id, $entitlement->entitleable->id); $this->assertTrue($entitlement->entitleable instanceof \App\User); } + + /** + * Test Entitlement::entitlementTitle() + */ + public function testEntitlementTitle(): void + { + $packageDomain = Package::where('title', 'domain-hosting')->first(); + $packageKolab = Package::where('title', 'kolab')->first(); + $user = $this->getTestUser('entitled-user@custom-domain.com'); + $group = $this->getTestGroup('test-group@custom-domain.com'); + + $domain = $this->getTestDomain( + 'custom-domain.com', + [ + 'status' => Domain::STATUS_NEW, + 'type' => Domain::TYPE_EXTERNAL, + ] + ); + + $wallet = $user->wallets->first(); + $domain->assignPackage($packageDomain, $user); + $user->assignPackage($packageKolab); + $group->assignToWallet($wallet); + + $sku_mailbox = \App\Sku::where('title', 'mailbox')->first(); + $sku_group = \App\Sku::where('title', 'group')->first(); + $sku_domain = \App\Sku::where('title', 'domain-hosting')->first(); + + $entitlement = Entitlement::where('wallet_id', $wallet->id) + ->where('sku_id', $sku_mailbox->id)->first(); + + $this->assertSame($user->email, $entitlement->entitleableTitle()); + + $entitlement = Entitlement::where('wallet_id', $wallet->id) + ->where('sku_id', $sku_group->id)->first(); + + $this->assertSame($group->email, $entitlement->entitleableTitle()); + + $entitlement = Entitlement::where('wallet_id', $wallet->id) + ->where('sku_id', $sku_domain->id)->first(); + + $this->assertSame($domain->namespace, $entitlement->entitleableTitle()); + } }