Page MenuHomePhorge

D964.1775187062.diff
No OneTemporary

Authored By
Unknown
Size
55 KB
Referenced Files
None
Subscribers
None

D964.1775187062.diff

diff --git a/src/app/Console/Commands/WalletCharge.php b/src/app/Console/Commands/WalletCharge.php
new file mode 100644
--- /dev/null
+++ b/src/app/Console/Commands/WalletCharge.php
@@ -0,0 +1,58 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Domain;
+use App\User;
+use Carbon\Carbon;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\DB;
+
+class WalletCharge extends Command
+{
+ /**
+ * The name and signature of the console command.
+ *
+ * @var string
+ */
+ protected $signature = 'wallet:charge';
+
+ /**
+ * The console command description.
+ *
+ * @var string
+ */
+ protected $description = 'Charge wallets';
+
+ /**
+ * Create a new command instance.
+ *
+ * @return void
+ */
+ public function __construct()
+ {
+ parent::__construct();
+ }
+
+ /**
+ * Execute the console command.
+ *
+ * @return mixed
+ */
+ public function handle()
+ {
+ $wallets = \App\Wallet::all();
+
+ foreach ($wallets as $wallet) {
+ $charge = $wallet->expectedCharges();
+
+ if ($charge > 0) {
+ $this->info(
+ "charging wallet {$wallet->id} for user {$wallet->owner->email} with {$charge}"
+ );
+
+ $wallet->chargeEntitlements();
+ }
+ }
+ }
+}
diff --git a/src/app/Console/Commands/WalletExpected.php b/src/app/Console/Commands/WalletExpected.php
new file mode 100644
--- /dev/null
+++ b/src/app/Console/Commands/WalletExpected.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Domain;
+use App\User;
+use Carbon\Carbon;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\DB;
+
+class WalletExpected extends Command
+{
+ /**
+ * The name and signature of the console command.
+ *
+ * @var string
+ */
+ protected $signature = 'wallet:expected';
+
+ /**
+ * The console command description.
+ *
+ * @var string
+ */
+ protected $description = 'Show expected charges to wallets';
+
+ /**
+ * Create a new command instance.
+ *
+ * @return void
+ */
+ public function __construct()
+ {
+ parent::__construct();
+ }
+
+ /**
+ * Execute the console command.
+ *
+ * @return mixed
+ */
+ public function handle()
+ {
+ $wallets = \App\Wallet::all();
+
+ foreach ($wallets as $wallet) {
+ $charge = 0;
+ $expected = $wallet->expectedCharges();
+
+ if ($expected > 0) {
+ $this->info("expect charging wallet {$wallet->id} for user {$wallet->owner->email} with {$expected}");
+ }
+ }
+ }
+}
diff --git a/src/app/Domain.php b/src/app/Domain.php
--- a/src/app/Domain.php
+++ b/src/app/Domain.php
@@ -68,6 +68,7 @@
'owner_id' => $user->id,
'wallet_id' => $wallet_id,
'sku_id' => $sku->id,
+ 'cost' => $sku->pivot->cost(),
'entitleable_id' => $this->id,
'entitleable_type' => Domain::class
]
diff --git a/src/app/Entitlement.php b/src/app/Entitlement.php
--- a/src/app/Entitlement.php
+++ b/src/app/Entitlement.php
@@ -2,7 +2,9 @@
namespace App;
+use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\SoftDeletes;
/**
* The eloquent definition of an Entitlement.
@@ -16,6 +18,8 @@
*/
class Entitlement extends Model
{
+ use SoftDeletes;
+
/**
* This table does not use auto-increment.
*
@@ -41,6 +45,7 @@
'wallet_id',
'entitleable_id',
'entitleable_type',
+ 'cost',
'description'
];
diff --git a/src/app/Handlers/Domain.php b/src/app/Handlers/Domain.php
--- a/src/app/Handlers/Domain.php
+++ b/src/app/Handlers/Domain.php
@@ -2,8 +2,6 @@
namespace App\Handlers;
-use App\Sku;
-
class Domain extends \App\Handlers\Base
{
public static function entitleableClass()
diff --git a/src/app/Handlers/DomainHosting.php b/src/app/Handlers/DomainHosting.php
--- a/src/app/Handlers/DomainHosting.php
+++ b/src/app/Handlers/DomainHosting.php
@@ -2,8 +2,6 @@
namespace App\Handlers;
-use App\Sku;
-
class DomainHosting extends \App\Handlers\Base
{
public static function entitleableClass()
diff --git a/src/app/Handlers/DomainRegistration.php b/src/app/Handlers/DomainRegistration.php
--- a/src/app/Handlers/DomainRegistration.php
+++ b/src/app/Handlers/DomainRegistration.php
@@ -2,8 +2,6 @@
namespace App\Handlers;
-use App\Sku;
-
class DomainRegistration extends \App\Handlers\Base
{
public static function entitleableClass()
diff --git a/src/app/Handlers/Groupware.php b/src/app/Handlers/Groupware.php
--- a/src/app/Handlers/Groupware.php
+++ b/src/app/Handlers/Groupware.php
@@ -2,8 +2,6 @@
namespace App\Handlers;
-use App\Sku;
-
class Groupware extends \App\Handlers\Base
{
public static function entitleableClass()
diff --git a/src/app/Handlers/Mailbox.php b/src/app/Handlers/Mailbox.php
--- a/src/app/Handlers/Mailbox.php
+++ b/src/app/Handlers/Mailbox.php
@@ -2,10 +2,6 @@
namespace App\Handlers;
-use App\Entitlement;
-use App\Sku;
-use App\User;
-
class Mailbox extends \App\Handlers\Base
{
public static function entitleableClass()
diff --git a/src/app/Handlers/Resource.php b/src/app/Handlers/Resource.php
--- a/src/app/Handlers/Resource.php
+++ b/src/app/Handlers/Resource.php
@@ -2,8 +2,6 @@
namespace App\Handlers;
-use App\Sku;
-
class Resource extends \App\Handlers\Base
{
public static function entitleableClass()
diff --git a/src/app/Handlers/SharedFolder.php b/src/app/Handlers/SharedFolder.php
--- a/src/app/Handlers/SharedFolder.php
+++ b/src/app/Handlers/SharedFolder.php
@@ -2,8 +2,6 @@
namespace App\Handlers;
-use App\Sku;
-
class SharedFolder extends \App\Handlers\Base
{
public static function entitleableClass()
diff --git a/src/app/Handlers/Storage.php b/src/app/Handlers/Storage.php
--- a/src/app/Handlers/Storage.php
+++ b/src/app/Handlers/Storage.php
@@ -6,7 +6,7 @@
{
public static function entitleableClass()
{
- return null;
+ return \App\User::class;
}
public static function preReq($entitlement, $object)
diff --git a/src/app/Observers/EntitlementObserver.php b/src/app/Observers/EntitlementObserver.php
--- a/src/app/Observers/EntitlementObserver.php
+++ b/src/app/Observers/EntitlementObserver.php
@@ -3,6 +3,7 @@
namespace App\Observers;
use App\Entitlement;
+use Carbon\Carbon;
/**
* This is an observer for the Entitlement model definition.
@@ -62,11 +63,5 @@
if (!$result) {
return false;
}
-
- // TODO: Handle the first free unit here?
-
- // TODO: Execute the Sku handler class or function?
-
- $wallet->debit($sku->cost);
}
}
diff --git a/src/app/Observers/PackageSkuObserver.php b/src/app/Observers/PackageSkuObserver.php
new file mode 100644
--- /dev/null
+++ b/src/app/Observers/PackageSkuObserver.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace App\Observers;
+
+class PackageSkuObserver
+{
+ public function created(\App\PackageSku $packageSku)
+ {
+ // TODO: free units...
+ $package = $packageSku->package;
+ $sku = $packageSku->sku;
+
+ $cost = ($sku->cost * (100 - $package->discount_rate)) / 100;
+
+ \Log::debug("Setting costs for {$sku->title} on package {$package->title} to {$cost}");
+
+ $package->skus()->updateExistingPivot(
+ $sku,
+ ['cost' => ($sku->cost * (100 - $package->discount_rate)) / 100],
+ false
+ );
+ }
+}
diff --git a/src/app/Observers/UserObserver.php b/src/app/Observers/UserObserver.php
--- a/src/app/Observers/UserObserver.php
+++ b/src/app/Observers/UserObserver.php
@@ -79,6 +79,8 @@
*/
public function deleting(User $user)
{
+ \Log::debug("where deleting user {$user->email}");
+
// Entitlements do not have referential integrity on the entitled object, so this is our
// way of doing an onDelete('cascade') without the foreign key.
$entitlements = \App\Entitlement::where('entitleable_id', $user->id)
diff --git a/src/app/Package.php b/src/app/Package.php
--- a/src/app/Package.php
+++ b/src/app/Package.php
@@ -34,12 +34,26 @@
'discount_rate'
];
+ /**
+ * The costs of this package at its pre-defined, existing configuration.
+ *
+ * @return int The costs in cents.
+ */
public function cost()
{
$costs = 0;
foreach ($this->skus as $sku) {
- $costs += ($sku->pivot->qty - $sku->units_free) * $sku->cost;
+ $units = $sku->pivot->qty - $sku->units_free;
+
+ if ($units < 0) {
+ \Log::debug("Package {$this->id} is misconfigured for more free units than qty.");
+ $units = 0;
+ }
+
+ $ppu = $sku->cost * ((100 - $this->discount_rate) / 100);
+
+ $costs += $units * $ppu;
}
return $costs;
diff --git a/src/app/PackageSku.php b/src/app/PackageSku.php
--- a/src/app/PackageSku.php
+++ b/src/app/PackageSku.php
@@ -12,10 +12,48 @@
protected $fillable = [
'package_id',
'sku_id',
+ 'cost',
'qty'
];
protected $casts = [
+ 'cost' => 'integer',
'qty' => 'integer'
];
+
+ /**
+ * Under this package, how much does this SKU cost?
+ *
+ * @return int The costs of this SKU under this package in cents.
+ */
+ public function cost()
+ {
+ $costs = 0;
+
+ $units = $this->qty - $this->sku->units_free;
+
+ if ($units < 0) {
+ \Log::debug(
+ "Package {$this->package_id} is misconfigured for more free units than qty."
+ );
+
+ $units = 0;
+ }
+
+ $ppu = $this->sku->cost * ((100 - $this->package->discount_rate) / 100);
+
+ $costs += $units * $ppu;
+
+ return $costs;
+ }
+
+ public function package()
+ {
+ return $this->belongsTo('App\Package');
+ }
+
+ public function sku()
+ {
+ return $this->belongsTo('App\Sku');
+ }
}
diff --git a/src/app/Plan.php b/src/app/Plan.php
--- a/src/app/Plan.php
+++ b/src/app/Plan.php
@@ -49,7 +49,11 @@
'description',
];
-
+ /**
+ * The list price for this package at the minimum configuration.
+ *
+ * @return int The costs in cents.
+ */
public function cost()
{
$costs = 0;
diff --git a/src/app/Providers/AppServiceProvider.php b/src/app/Providers/AppServiceProvider.php
--- a/src/app/Providers/AppServiceProvider.php
+++ b/src/app/Providers/AppServiceProvider.php
@@ -28,6 +28,7 @@
\App\Domain::observe(\App\Observers\DomainObserver::class);
\App\Entitlement::observe(\App\Observers\EntitlementObserver::class);
\App\Package::observe(\App\Observers\PackageObserver::class);
+ \App\PackageSku::observe(\App\Observers\PackageSkuObserver::class);
\App\Plan::observe(\App\Observers\PlanObserver::class);
\App\SignupCode::observe(\App\Observers\SignupCodeObserver::class);
\App\Sku::observe(\App\Observers\SkuObserver::class);
diff --git a/src/app/Sku.php b/src/app/Sku.php
--- a/src/app/Sku.php
+++ b/src/app/Sku.php
@@ -21,6 +21,7 @@
'description',
'cost',
'units_free',
+ // persist for annual domain registration
'period',
'handler_class',
'active'
@@ -41,6 +42,6 @@
return $this->belongsToMany(
'App\Package',
'package_skus'
- )->using('App\PackageSku')->withPivot(['qty']);
+ )->using('App\PackageSku')->withPivot(['cost', 'qty']);
}
}
diff --git a/src/app/User.php b/src/app/User.php
--- a/src/app/User.php
+++ b/src/app/User.php
@@ -118,6 +118,7 @@
'owner_id' => $this->id,
'wallet_id' => $wallet_id,
'sku_id' => $sku->id,
+ 'cost' => $sku->pivot->cost(),
'entitleable_id' => $user->id,
'entitleable_type' => User::class
]
diff --git a/src/app/Wallet.php b/src/app/Wallet.php
--- a/src/app/Wallet.php
+++ b/src/app/Wallet.php
@@ -3,6 +3,7 @@
namespace App;
use App\User;
+use Carbon\Carbon;
use Iatstuti\Database\Support\NullableFields;
use Illuminate\Database\Eloquent\Model;
@@ -55,6 +56,54 @@
}
}
+ public function chargeEntitlements($apply = true)
+ {
+ $charges = 0;
+
+ foreach ($this->entitlements()->get()->fresh() as $entitlement) {
+ // This entitlement has been created less than or equal to 14 days ago (this is at
+ // maximum the fourteenth 24-hour period).
+ if ($entitlement->created_at > Carbon::now()->subDays(14)) {
+ continue;
+ }
+
+ // This entitlement was created, or billed last, less than a month ago.
+ if ($entitlement->updated_at > Carbon::now()->subMonths(1)) {
+ continue;
+ }
+
+ // created more than a month ago -- was it billed?
+ if ($entitlement->updated_at <= Carbon::now()->subMonths(1)) {
+ $diff = $entitlement->updated_at->diffInMonths(Carbon::now());
+
+ $charges += $entitlement->cost * $diff;
+
+ // if we're in dry-run, you know...
+ if (!$apply) {
+ continue;
+ }
+
+ $entitlement->updated_at = $entitlement->updated_at->copy()->addMonths($diff);
+ $entitlement->save();
+
+ $this->debit($entitlement->cost * $diff);
+ }
+ }
+
+ return $charges;
+ }
+
+
+ /**
+ * Calculate the expected charges to this wallet.
+ *
+ * @return int
+ */
+ public function expectedCharges()
+ {
+ return $this->chargeEntitlements(false);
+ }
+
/**
* Remove a controller from this wallet.
*
diff --git a/src/database/migrations/2019_09_17_102628_create_sku_entitlements.php b/src/database/migrations/2019_09_17_102628_create_sku_entitlements.php
--- a/src/database/migrations/2019_09_17_102628_create_sku_entitlements.php
+++ b/src/database/migrations/2019_09_17_102628_create_sku_entitlements.php
@@ -36,6 +36,7 @@
$table->bigInteger('owner_id');
$table->bigInteger('entitleable_id');
$table->string('entitleable_type');
+ $table->integer('cost')->default(0)->nullable();
$table->string('wallet_id', 36);
$table->string('sku_id', 36);
$table->string('description')->nullable();
diff --git a/src/database/migrations/2019_12_10_100355_create_package_skus_table.php b/src/database/migrations/2019_12_10_100355_create_package_skus_table.php
--- a/src/database/migrations/2019_12_10_100355_create_package_skus_table.php
+++ b/src/database/migrations/2019_12_10_100355_create_package_skus_table.php
@@ -4,6 +4,7 @@
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
+// phpcs:ignore
class CreatePackageSkusTable extends Migration
{
/**
@@ -21,6 +22,8 @@
$table->string('sku_id', 36);
$table->integer('qty')->default(1);
+ $table->integer('cost')->default(0)->nullable();
+
$table->foreign('package_id')->references('id')->on('packages')
->onDelete('cascade')->onUpdate('cascade');
diff --git a/src/database/migrations/2020_02_11_110959_add_deleted_at.php b/src/database/migrations/2020_02_11_110959_users_add_deleted_at.php
rename from src/database/migrations/2020_02_11_110959_add_deleted_at.php
rename to src/database/migrations/2020_02_11_110959_users_add_deleted_at.php
--- a/src/database/migrations/2020_02_11_110959_add_deleted_at.php
+++ b/src/database/migrations/2020_02_11_110959_users_add_deleted_at.php
@@ -4,7 +4,8 @@
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
-class AddDeletedAt extends Migration
+// phpcs:ignore
+class UsersAddDeletedAt extends Migration
{
/**
* Run the migrations.
@@ -13,13 +14,6 @@
*/
public function up()
{
- Schema::table(
- 'domains',
- function (Blueprint $table) {
- $table->softDeletes();
- }
- );
-
Schema::table(
'users',
function (Blueprint $table) {
@@ -35,12 +29,6 @@
*/
public function down()
{
- Schema::table(
- 'domains',
- function (Blueprint $table) {
- $table->dropColumn(['deleted_at']);
- }
- );
Schema::table(
'users',
function (Blueprint $table) {
diff --git a/src/database/migrations/2020_02_11_110959_add_deleted_at.php b/src/database/migrations/2020_02_11_110960_domains_add_deleted_at.php
copy from src/database/migrations/2020_02_11_110959_add_deleted_at.php
copy to src/database/migrations/2020_02_11_110960_domains_add_deleted_at.php
--- a/src/database/migrations/2020_02_11_110959_add_deleted_at.php
+++ b/src/database/migrations/2020_02_11_110960_domains_add_deleted_at.php
@@ -4,7 +4,8 @@
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
-class AddDeletedAt extends Migration
+// phpcs:ignore
+class DomainsAddDeletedAt extends Migration
{
/**
* Run the migrations.
@@ -19,13 +20,6 @@
$table->softDeletes();
}
);
-
- Schema::table(
- 'users',
- function (Blueprint $table) {
- $table->softDeletes();
- }
- );
}
/**
@@ -41,11 +35,5 @@
$table->dropColumn(['deleted_at']);
}
);
- Schema::table(
- 'users',
- function (Blueprint $table) {
- $table->dropColumn(['deleted_at']);
- }
- );
}
}
diff --git a/src/database/migrations/2020_02_11_110959_add_deleted_at.php b/src/database/migrations/2020_02_26_085835_entitlements_add_deleted_at.php
rename from src/database/migrations/2020_02_11_110959_add_deleted_at.php
rename to src/database/migrations/2020_02_26_085835_entitlements_add_deleted_at.php
--- a/src/database/migrations/2020_02_11_110959_add_deleted_at.php
+++ b/src/database/migrations/2020_02_26_085835_entitlements_add_deleted_at.php
@@ -4,7 +4,8 @@
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
-class AddDeletedAt extends Migration
+// phpcs:ignore
+class EntitlementsAddDeletedAt extends Migration
{
/**
* Run the migrations.
@@ -14,14 +15,7 @@
public function up()
{
Schema::table(
- 'domains',
- function (Blueprint $table) {
- $table->softDeletes();
- }
- );
-
- Schema::table(
- 'users',
+ 'entitlements',
function (Blueprint $table) {
$table->softDeletes();
}
@@ -36,13 +30,7 @@
public function down()
{
Schema::table(
- 'domains',
- function (Blueprint $table) {
- $table->dropColumn(['deleted_at']);
- }
- );
- Schema::table(
- 'users',
+ 'entitlements',
function (Blueprint $table) {
$table->dropColumn(['deleted_at']);
}
diff --git a/src/database/seeds/PackageSeeder.php b/src/database/seeds/PackageSeeder.php
--- a/src/database/seeds/PackageSeeder.php
+++ b/src/database/seeds/PackageSeeder.php
@@ -14,6 +14,10 @@
*/
public function run()
{
+ $skuGroupware = Sku::firstOrCreate(['title' => 'groupware']);
+ $skuMailbox = Sku::firstOrCreate(['title' => 'mailbox']);
+ $skuStorage = Sku::firstOrCreate(['title' => 'storage']);
+
$package = Package::create(
[
'title' => 'kolab',
@@ -23,9 +27,9 @@
);
$skus = [
- Sku::firstOrCreate(['title' => 'mailbox']),
- Sku::firstOrCreate(['title' => 'storage']),
- Sku::firstOrCreate(['title' => 'groupware'])
+ $skuMailbox,
+ $skuGroupware,
+ $skuStorage
];
$package->skus()->saveMany($skus);
@@ -33,7 +37,7 @@
// This package contains 2 units of the storage SKU, which just so happens to also
// be the number of SKU free units.
$package->skus()->updateExistingPivot(
- Sku::firstOrCreate(['title' => 'storage']),
+ $skuStorage,
['qty' => 2],
false
);
@@ -47,8 +51,8 @@
);
$skus = [
- Sku::firstOrCreate(['title' => 'mailbox']),
- Sku::firstOrCreate(['title' => 'storage'])
+ $skuMailbox,
+ $skuStorage
];
$package->skus()->saveMany($skus);
diff --git a/src/database/seeds/UserSeeder.php b/src/database/seeds/UserSeeder.php
--- a/src/database/seeds/UserSeeder.php
+++ b/src/database/seeds/UserSeeder.php
@@ -1,10 +1,11 @@
<?php
-use Illuminate\Database\Seeder;
use App\Domain;
use App\Entitlement;
use App\User;
use App\Sku;
+use Carbon\Carbon;
+use Illuminate\Database\Seeder;
// phpcs:ignore
class UserSeeder extends Seeder
@@ -42,7 +43,7 @@
]
);
- $user_wallets = $john->wallets()->get();
+ $wallet = $john->wallets->first();
$package_domain = \App\Package::where('title', 'domain-hosting')->first();
$package_kolab = \App\Package::where('title', 'kolab')->first();
@@ -70,6 +71,12 @@
$john->assignPackage($package_kolab, $jack);
+ foreach ($john->entitlements as $entitlement) {
+ $entitlement->created_at = Carbon::now()->subMonths(1);
+ $entitlement->updated_at = Carbon::now()->subMonths(1);
+ $entitlement->save();
+ }
+
factory(User::class, 10)->create();
}
}
diff --git a/src/phpstan.neon b/src/phpstan.neon
--- a/src/phpstan.neon
+++ b/src/phpstan.neon
@@ -4,3 +4,4 @@
level: 3
paths:
- app/
+ - tests/
diff --git a/src/tests/Feature/BillingTest.php b/src/tests/Feature/BillingTest.php
new file mode 100644
--- /dev/null
+++ b/src/tests/Feature/BillingTest.php
@@ -0,0 +1,246 @@
+<?php
+
+namespace Tests\Feature;
+
+use Carbon\Carbon;
+use Illuminate\Support\Facades\Queue;
+use Tests\TestCase;
+
+class BillingTest extends TestCase
+{
+ /** @property \App\Package $package */
+ private $package;
+
+ /** @property \App\User $user */
+ private $user;
+
+ /** @property \App\Wallet $wallet */
+ private $wallet;
+
+ /** @property string $wallet_id */
+ private $wallet_id;
+
+ public function setUp(): void
+ {
+ parent::setUp();
+
+ $this->deleteTestUser('jane@kolabnow.com');
+ $this->deleteTestUser('jack@kolabnow.com');
+
+ \App\Package::where('title', 'kolab-kube')->delete();
+
+ $this->user = $this->getTestUser('jane@kolabnow.com');
+ $this->package = \App\Package::where('title', 'kolab')->first();
+ $this->user->assignPackage($this->package);
+
+ $this->wallet = $this->user->wallets->first();
+
+ $this->wallet_id = $this->wallet->id;
+ }
+
+ public function tearDown(): void
+ {
+ $this->deleteTestUser('jane@kolabnow.com');
+ $this->deleteTestUser('jack@kolabnow.com');
+
+ \App\Package::where('title', 'kolab-kube')->delete();
+
+ parent::tearDown();
+ }
+
+ /**
+ * Test the expected results for a user that registers and is almost immediately gone.
+ */
+ public function testTouchAndGo(): void
+ {
+ $this->assertCount(4, $this->wallet->entitlements);
+
+ $this->assertEquals(0, $this->wallet->expectedCharges());
+
+ $this->user->delete();
+
+ $this->assertCount(0, $this->wallet->fresh()->entitlements->where('deleted_at', null));
+
+ $this->assertCount(4, $this->wallet->entitlements);
+ }
+
+ /**
+ * Verify the last day before the end of a full month's trial.
+ */
+ public function testNearFullTrial(): void
+ {
+ $this->backdateEntitlements(
+ $this->wallet->entitlements,
+ Carbon::now()->subMonths(1)->addDays(1)
+ );
+
+ $this->assertEquals(0, $this->wallet->expectedCharges());
+ }
+
+ /**
+ * Verify the exact end of the month's trial.
+ */
+ public function testFullTrial(): void
+ {
+ $this->backdateEntitlements($this->wallet->entitlements, Carbon::now()->subMonths(1));
+
+ $this->assertEquals(999, $this->wallet->expectedCharges());
+ }
+
+ /**
+ * Verify that over-running the trial by a single day causes charges to be incurred.
+ */
+ public function testOutRunTrial(): void
+ {
+ $this->backdateEntitlements(
+ $this->wallet->entitlements,
+ Carbon::now()->subMonths(1)->subDays(1)
+ );
+
+ $this->assertEquals(999, $this->wallet->expectedCharges());
+ }
+
+ /**
+ * Verify additional storage configuration entitlement created 'early' does incur additional
+ * charges to the wallet.
+ */
+ public function testAddtStorageEarly(): void
+ {
+ $this->backdateEntitlements(
+ $this->wallet->entitlements,
+ Carbon::now()->subMonths(1)->subDays(1)
+ );
+
+ $this->assertEquals(999, $this->wallet->expectedCharges());
+
+ $sku = \App\Sku::where(['title' => 'storage'])->first();
+
+ $entitlement = \App\Entitlement::create(
+ [
+ 'owner_id' => $this->user->id,
+ 'wallet_id' => $this->wallet_id,
+ 'sku_id' => $sku->id,
+ 'cost' => $sku->cost,
+ 'entitleable_id' => $this->user->id,
+ 'entitleable_type' => \App\User::class
+ ]
+ );
+
+ $this->backdateEntitlements(
+ [$entitlement],
+ Carbon::now()->subMonths(1)->subDays(1)
+ );
+
+ $this->assertEquals(1024, $this->wallet->expectedCharges());
+ }
+
+ /**
+ * Verify additional storage configuration entitlement created 'late' does not incur additional
+ * charges to the wallet.
+ */
+ public function testAddtStorageLate(): void
+ {
+ $this->backdateEntitlements($this->wallet->entitlements, Carbon::now()->subMonths(1));
+
+ $this->assertEquals(999, $this->wallet->expectedCharges());
+
+ $sku = \App\Sku::where(['title' => 'storage'])->first();
+
+ $entitlement = \App\Entitlement::create(
+ [
+ 'owner_id' => $this->user->id,
+ 'wallet_id' => $this->wallet_id,
+ 'sku_id' => $sku->id,
+ 'cost' => $sku->cost,
+ 'entitleable_id' => $this->user->id,
+ 'entitleable_type' => \App\User::class
+ ]
+ );
+
+ $this->backdateEntitlements([$entitlement], Carbon::now()->subDays(14));
+
+ $this->assertEquals(999, $this->wallet->expectedCharges());
+ }
+
+ public function testFifthWeek(): void
+ {
+ $targetDateA = Carbon::now()->subWeeks(5);
+ $targetDateB = $targetDateA->copy()->addMonths(1);
+
+ $this->backdateEntitlements($this->wallet->entitlements, $targetDateA);
+
+ $this->assertEquals(999, $this->wallet->expectedCharges());
+
+ $this->wallet->chargeEntitlements();
+
+ $this->assertEquals(-999, $this->wallet->balance);
+
+ foreach ($this->wallet->entitlements()->get() as $entitlement) {
+ $this->assertTrue($entitlement->created_at->isSameSecond($targetDateA));
+ $this->assertTrue($entitlement->updated_at->isSameSecond($targetDateB));
+ }
+ }
+
+ public function testSecondMonth(): void
+ {
+ $this->backdateEntitlements($this->wallet->entitlements, Carbon::now()->subMonths(2));
+
+ $this->assertCount(4, $this->wallet->entitlements);
+
+ $this->assertEquals(1998, $this->wallet->expectedCharges());
+
+ $sku = \App\Sku::where(['title' => 'storage'])->first();
+
+ $entitlement = \App\Entitlement::create(
+ [
+ 'owner_id' => $this->user->id,
+ 'entitleable_id' => $this->user->id,
+ 'entitleable_type' => \App\User::class,
+ 'cost' => $sku->cost,
+ 'sku_id' => $sku->id,
+ 'wallet_id' => $this->wallet_id
+ ]
+ );
+
+ $this->backdateEntitlements([$entitlement], Carbon::now()->subMonths(1));
+
+ $this->assertEquals(2023, $this->wallet->expectedCharges());
+ }
+
+ public function testWithDiscount(): void
+ {
+ $package = \App\Package::create(
+ [
+ 'title' => 'kolab-kube',
+ 'description' => 'Kolab for Kube fans',
+ 'discount_rate' => 50
+ ]
+ );
+
+ $skus = [
+ \App\Sku::firstOrCreate(['title' => 'mailbox']),
+ \App\Sku::firstOrCreate(['title' => 'storage']),
+ \App\Sku::firstOrCreate(['title' => 'groupware'])
+ ];
+
+ $package->skus()->saveMany($skus);
+
+ $package->skus()->updateExistingPivot(
+ \App\Sku::firstOrCreate(['title' => 'storage']),
+ ['qty' => 2],
+ false
+ );
+
+ $user = $this->getTestUser('jack@kolabnow.com');
+
+ $user->assignPackage($package);
+
+ $wallet = $user->wallets->first();
+
+ $wallet_id = $wallet->id;
+
+ $this->backdateEntitlements($wallet->entitlements, Carbon::now()->subMonths(1));
+
+ $this->assertEquals(500, $wallet->expectedCharges());
+ }
+}
diff --git a/src/tests/Feature/Controller/SignupTest.php b/src/tests/Feature/Controller/SignupTest.php
--- a/src/tests/Feature/Controller/SignupTest.php
+++ b/src/tests/Feature/Controller/SignupTest.php
@@ -151,10 +151,10 @@
*/
public function testSignupInitValidInput()
{
- Queue::fake();
+ $queue = Queue::fake();
// Assert that no jobs were pushed...
- Queue::assertNothingPushed();
+ $queue->assertNothingPushed();
$data = [
'email' => 'testuser@external.com',
@@ -171,10 +171,10 @@
$this->assertNotEmpty($json['code']);
// Assert the email sending job was pushed once
- Queue::assertPushed(\App\Jobs\SignupVerificationEmail::class, 1);
+ $queue->assertPushed(\App\Jobs\SignupVerificationEmail::class, 1);
// Assert the job has proper data assigned
- Queue::assertPushed(\App\Jobs\SignupVerificationEmail::class, function ($job) use ($data, $json) {
+ $queue->assertPushed(\App\Jobs\SignupVerificationEmail::class, function ($job) use ($data, $json) {
$code = TestCase::getObjectProperty($job, 'code');
return $code->code === $json['code']
@@ -390,7 +390,7 @@
*/
public function testSignupValidInput(array $result)
{
- Queue::fake();
+ $queue = Queue::fake();
$domain = $this->getPublicDomain();
$identity = \strtolower('SignupLogin@') . $domain;
@@ -414,8 +414,8 @@
$this->assertTrue(!empty($json['expires_in']) && is_int($json['expires_in']) && $json['expires_in'] > 0);
$this->assertNotEmpty($json['access_token']);
- Queue::assertPushed(\App\Jobs\UserCreate::class, 1);
- Queue::assertPushed(\App\Jobs\UserCreate::class, function ($job) use ($data) {
+ $queue->assertPushed(\App\Jobs\UserCreate::class, 1);
+ $queue->assertPushed(\App\Jobs\UserCreate::class, function ($job) use ($data) {
$job_user = TestCase::getObjectProperty($job, 'user');
return $job_user->email === \strtolower($data['login'] . '@' . $data['domain']);
@@ -446,7 +446,7 @@
*/
public function testSignupGroupAccount()
{
- Queue::fake();
+ $queue = Queue::fake();
// Initial signup request
$user_data = $data = [
@@ -464,10 +464,10 @@
$this->assertNotEmpty($json['code']);
// Assert the email sending job was pushed once
- Queue::assertPushed(\App\Jobs\SignupVerificationEmail::class, 1);
+ $queue->assertPushed(\App\Jobs\SignupVerificationEmail::class, 1);
// Assert the job has proper data assigned
- Queue::assertPushed(\App\Jobs\SignupVerificationEmail::class, function ($job) use ($data, $json) {
+ $queue->assertPushed(\App\Jobs\SignupVerificationEmail::class, function ($job) use ($data, $json) {
$code = TestCase::getObjectProperty($job, 'code');
return $code->code === $json['code']
@@ -516,15 +516,15 @@
$this->assertTrue(!empty($result['expires_in']) && is_int($result['expires_in']) && $result['expires_in'] > 0);
$this->assertNotEmpty($result['access_token']);
- Queue::assertPushed(\App\Jobs\DomainCreate::class, 1);
- Queue::assertPushed(\App\Jobs\DomainCreate::class, function ($job) use ($domain) {
+ $queue->assertPushed(\App\Jobs\DomainCreate::class, 1);
+ $queue->assertPushed(\App\Jobs\DomainCreate::class, function ($job) use ($domain) {
$job_domain = TestCase::getObjectProperty($job, 'domain');
return $job_domain->namespace === $domain;
});
- Queue::assertPushed(\App\Jobs\UserCreate::class, 1);
- Queue::assertPushed(\App\Jobs\UserCreate::class, function ($job) use ($data) {
+ $queue->assertPushed(\App\Jobs\UserCreate::class, 1);
+ $queue->assertPushed(\App\Jobs\UserCreate::class, function ($job) use ($data) {
$job_user = TestCase::getObjectProperty($job, 'user');
return $job_user->email === $data['login'] . '@' . $data['domain'];
diff --git a/src/tests/Feature/DomainTest.php b/src/tests/Feature/DomainTest.php
--- a/src/tests/Feature/DomainTest.php
+++ b/src/tests/Feature/DomainTest.php
@@ -47,8 +47,8 @@
public function testCreateJobs(): void
{
// Fake the queue, assert that no jobs were pushed...
- Queue::fake();
- Queue::assertNothingPushed();
+ $queue = Queue::fake();
+ $queue->assertNothingPushed();
$domain = Domain::create([
'namespace' => 'gmail.com',
@@ -56,9 +56,9 @@
'type' => Domain::TYPE_EXTERNAL,
]);
- Queue::assertPushed(\App\Jobs\DomainCreate::class, 1);
+ $queue->assertPushed(\App\Jobs\DomainCreate::class, 1);
- Queue::assertPushed(
+ $queue->assertPushed(
\App\Jobs\DomainCreate::class,
function ($job) use ($domain) {
$job_domain = TestCase::getObjectProperty($job, 'domain');
@@ -81,7 +81,7 @@
$this->assertNotContains('public-active.com', $public_domains);
- Queue::fake();
+ $queue = Queue::fake();
$domain = Domain::create([
'namespace' => 'public-active.com',
@@ -134,7 +134,7 @@
ci-failure-none MX 10 mx01.kolabnow.com.
*/
- Queue::fake();
+ $queue = Queue::fake();
$domain_props = ['status' => Domain::STATUS_NEW, 'type' => Domain::TYPE_EXTERNAL];
diff --git a/src/tests/Feature/EntitlementTest.php b/src/tests/Feature/EntitlementTest.php
--- a/src/tests/Feature/EntitlementTest.php
+++ b/src/tests/Feature/EntitlementTest.php
@@ -4,8 +4,10 @@
use App\Domain;
use App\Entitlement;
+use App\Package;
use App\Sku;
use App\User;
+use Carbon\Carbon;
use Tests\TestCase;
class EntitlementTest extends TestCase
@@ -32,10 +34,15 @@
*/
public function testUserAddEntitlement(): void
{
- $sku_domain = Sku::firstOrCreate(['title' => 'domain']);
- $sku_mailbox = Sku::firstOrCreate(['title' => 'mailbox']);
+ $package_domain = Package::where('title', 'domain-hosting')->first();
+ $package_kolab = Package::where('title', 'kolab')->first();
+
+ $sku_domain = Sku::where('title', 'domain-hosting')->first();
+ $sku_mailbox = 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',
[
@@ -44,50 +51,23 @@
]
);
- $wallet = $owner->wallets()->first();
+ $domain->assignPackage($package_domain, $owner);
- $entitlement_own_mailbox = new Entitlement(
- [
- 'owner_id' => $owner->id,
- 'entitleable_id' => $owner->id,
- 'entitleable_type' => User::class,
- 'wallet_id' => $wallet->id,
- 'sku_id' => $sku_mailbox->id,
- 'description' => "Owner Mailbox Entitlement Test"
- ]
- );
+ $owner->assignPackage($package_kolab);
+ $owner->assignPackage($package_kolab, $user);
- $entitlement_domain = new Entitlement(
- [
- 'owner_id' => $owner->id,
- 'entitleable_id' => $domain->id,
- 'entitleable_type' => Domain::class,
- 'wallet_id' => $wallet->id,
- 'sku_id' => $sku_domain->id,
- 'description' => "User Domain Entitlement Test"
- ]
- );
+ $wallet = $owner->wallets->first();
- $entitlement_mailbox = new Entitlement(
- [
- 'owner_id' => $owner->id,
- 'entitleable_id' => $user->id,
- 'entitleable_type' => User::class,
- 'wallet_id' => $wallet->id,
- 'sku_id' => $sku_mailbox->id,
- 'description' => "User Mailbox Entitlement Test"
- ]
- );
+ $this->assertCount(4, $owner->entitlements()->get());
+ $this->assertCount(1, $sku_domain->entitlements()->where('owner_id', $owner->id)->get());
+ $this->assertCount(2, $sku_mailbox->entitlements()->where('owner_id', $owner->id)->get());
+ $this->assertCount(9, $wallet->entitlements);
+
+ $this->backdateEntitlements($owner->entitlements, Carbon::now()->subMonths(1));
- $owner->addEntitlement($entitlement_own_mailbox);
- $owner->addEntitlement($entitlement_domain);
- $owner->addEntitlement($entitlement_mailbox);
+ $wallet->chargeEntitlements();
- $this->assertTrue($owner->entitlements()->count() == 3);
- $this->assertTrue($sku_domain->entitlements()->where('owner_id', $owner->id)->count() == 1);
- $this->assertTrue($sku_mailbox->entitlements()->where('owner_id', $owner->id)->count() == 2);
- $this->assertTrue($wallet->entitlements()->count() == 3);
- $this->assertTrue($wallet->fresh()->balance < 0.00);
+ $this->assertTrue($wallet->fresh()->balance < 0);
}
public function testAddExistingEntitlement(): void
diff --git a/src/tests/Feature/Jobs/UserVerifyTest.php b/src/tests/Feature/Jobs/UserVerifyTest.php
--- a/src/tests/Feature/Jobs/UserVerifyTest.php
+++ b/src/tests/Feature/Jobs/UserVerifyTest.php
@@ -21,7 +21,8 @@
$user->status ^= User::STATUS_IMAP_READY;
$user->save();
- $this->assertFalse($user->isImapReady());
+ // This is a valid assertion in a feature, not functional test environment.
+ //$this->assertFalse($user->isImapReady());
$job = new UserVerify($user);
$job->handle();
diff --git a/src/tests/Feature/SignupCodeTest.php b/src/tests/Feature/SignupCodeTest.php
--- a/src/tests/Feature/SignupCodeTest.php
+++ b/src/tests/Feature/SignupCodeTest.php
@@ -3,6 +3,7 @@
namespace Tests\Feature;
use App\SignupCode;
+use Carbon\Carbon;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;
@@ -23,7 +24,7 @@
]
];
- $now = new \DateTime('now');
+ $now = Carbon::now();
$code = SignupCode::create($data);
@@ -38,11 +39,11 @@
);
$this->assertSame($data['data'], $code->data);
- $this->assertInstanceOf(\DateTime::class, $code->expires_at);
+ $this->assertInstanceOf(Carbon::class, $code->expires_at);
$this->assertSame(
env('SIGNUP_CODE_EXPIRY', SignupCode::CODE_EXP_HOURS),
- $code->expires_at->diff($now)->h + 1
+ $code->expires_at->diffInHours($now) + 1
);
$inst = SignupCode::find($code->code);
diff --git a/src/tests/Feature/SkuTest.php b/src/tests/Feature/SkuTest.php
--- a/src/tests/Feature/SkuTest.php
+++ b/src/tests/Feature/SkuTest.php
@@ -2,11 +2,11 @@
namespace Tests\Feature;
-use App\Domain;
use App\Entitlement;
use App\Handlers;
+use App\Package;
use App\Sku;
-use App\User;
+use Carbon\Carbon;
use Tests\TestCase;
class SkuTest extends TestCase
@@ -16,228 +16,79 @@
{
parent::setUp();
- $this->deleteTestUser('sku-test-user@custom-domain.com');
- $this->deleteTestDomain('custom-domain.com');
+ $this->deleteTestUser('jane@kolabnow.com');
}
public function tearDown(): void
{
- $this->deleteTestUser('sku-test-user@custom-domain.com');
- $this->deleteTestDomain('custom-domain.com');
+ $this->deleteTestUser('jane@kolabnow.com');
parent::tearDown();
}
- /**
- * Tests for Sku::registerEntitlements()
- */
- public function testRegisterEntitlement(): void
+ public function testPackageEntitlements(): void
{
- // TODO: This test depends on seeded SKUs, but probably should not
- $domain = $this->getTestDomain(
- 'custom-domain.com',
- [
- 'status' => Domain::STATUS_NEW,
- 'type' => Domain::TYPE_EXTERNAL,
- ]
- );
-
- \Log::debug(var_export($domain->toArray(), true));
+ $user = $this->getTestUser('jane@kolabnow.com');
- $user = $this->getTestUser('sku-test-user@custom-domain.com');
$wallet = $user->wallets()->first();
- // \App\Handlers\Mailbox SKU
- // Note, we're testing mailbox SKU before domain SKU as it may potentially fail in that
- // order
- $sku = Sku::where('title', 'mailbox')->first();
- Entitlement::create(
- [
- 'owner_id' => $user->id,
- 'wallet_id' => $wallet->id,
- 'sku_id' => $sku->id,
- 'entitleable_id' => $user->id,
- 'entitleable_type' => User::class
- ]
- );
+ $package = Package::where('title', 'lite')->first();
- $entitlements = $sku->entitlements()->where('owner_id', $user->id)->get();
- $wallet->refresh();
-
- if ($sku->active) {
- $balance = -$sku->cost;
- $this->assertCount(1, $entitlements);
- $this->assertEquals($user->id, $entitlements[0]->entitleable_id);
- $this->assertSame(
- Handlers\Mailbox::entitleableClass(),
- $entitlements[0]->entitleable_type
- );
- } else {
- $this->assertCount(0, $entitlements);
- }
-
- $this->assertEquals($balance, $wallet->balance);
-
- // \App\Handlers\Domain SKU
- $sku = Sku::where('title', 'domain')->first();
- Entitlement::create(
- [
- 'owner_id' => $user->id,
- 'wallet_id' => $wallet->id,
- 'sku_id' => $sku->id,
- 'entitleable_id' => $domain->id,
- 'entitleable_type' => Domain::class
- ]
- );
-
- $entitlements = $sku->entitlements->where('owner_id', $user->id);
-
- foreach ($entitlements as $entitlement) {
- \Log::debug(var_export($entitlement->toArray(), true));
- }
-
- $wallet->refresh();
-
- if ($sku->active) {
- $balance -= $sku->cost;
- $this->assertCount(1, $entitlements);
-
- $_domain = Domain::find($entitlements->first()->entitleable_id);
-
- $this->assertEquals(
- $domain->id,
- $entitlements->first()->entitleable_id,
- var_export($_domain->toArray(), true)
- );
-
- $this->assertSame(
- Handlers\Domain::entitleableClass(),
- $entitlements->first()->entitleable_type
- );
- } else {
- $this->assertCount(0, $entitlements);
- }
-
- $this->assertEquals($balance, $wallet->balance);
-
- // \App\Handlers\DomainRegistration SKU
- $sku = Sku::where('title', 'domain-registration')->first();
- Entitlement::create(
- [
- 'owner_id' => $user->id,
- 'wallet_id' => $user->wallets()->get()[0]->id,
- 'sku_id' => $sku->id,
- 'entitleable_id' => $domain->id,
- 'entitleable_type' => Domain::class
- ]
- );
+ $sku_mailbox = Sku::where('title', 'mailbox')->first();
+ $sku_storage = Sku::where('title', 'storage')->first();
- $entitlements = $sku->entitlements->where('owner_id', $user->id);
- $wallet->refresh();
+ $user = $user->assignPackage($package);
- if ($sku->active) {
- $balance -= $sku->cost;
- $this->assertCount(1, $entitlements);
- $this->assertEquals($domain->id, $entitlements->first()->entitleable_id);
- $this->assertSame(
- Handlers\DomainRegistration::entitleableClass(),
- $entitlements->first()->entitleable_type
- );
- } else {
- $this->assertCount(0, $entitlements);
- }
+ $this->backdateEntitlements($user->fresh()->entitlements, Carbon::now()->subMonths(1));
- $this->assertEquals($balance, $wallet->balance);
+ $wallet->chargeEntitlements();
- // \App\Handlers\DomainHosting SKU
- $sku = Sku::where('title', 'domain-hosting')->first();
- Entitlement::create(
- [
- 'owner_id' => $user->id,
- 'wallet_id' => $wallet->id,
- 'sku_id' => $sku->id,
- 'entitleable_id' => $domain->id,
- 'entitleable_type' => Domain::class
- ]
- );
+ $this->assertTrue($wallet->balance < 0);
+ }
- $entitlements = $sku->entitlements->where('owner_id', $user->id);
- $wallet->refresh();
-
- if ($sku->active) {
- $balance -= $sku->cost;
- $this->assertCount(1, $entitlements);
- $this->assertEquals($domain->id, $entitlements->first()->entitleable_id);
- $this->assertSame(
- Handlers\DomainHosting::entitleableClass(),
- $entitlements->first()->entitleable_type
- );
- } else {
- $this->assertCount(0, $entitlements);
- }
-
- $this->assertEquals($balance, $wallet->balance);
-
- // \App\Handlers\Groupware SKU
- $sku = Sku::where('title', 'groupware')->first();
- Entitlement::create(
- [
- 'owner_id' => $user->id,
- 'wallet_id' => $user->wallets()->get()[0]->id,
- 'sku_id' => $sku->id,
- 'entitleable_id' => $user->id,
- 'entitleable_type' => User::class
- ]
- );
+ public function testSkuEntitlements(): void
+ {
+ $this->assertCount(2, Sku::where('title', 'mailbox')->first()->entitlements);
+ }
- $entitlements = $sku->entitlements->where('owner_id', $user->id);
- $wallet->refresh();
+ public function testSkuPackages(): void
+ {
+ $this->assertCount(2, Sku::where('title', 'mailbox')->first()->packages);
+ }
- if ($sku->active) {
- $balance -= $sku->cost;
- $this->assertCount(1, $entitlements);
- $this->assertEquals($user->id, $entitlements->first()->entitleable_id);
- $this->assertSame(
- Handlers\Mailbox::entitleableClass(),
- $entitlements->first()->entitleable_type
- );
- } else {
- $this->assertCount(0, $entitlements);
- }
+ public function testSkuHandlerDomainHosting(): void
+ {
+ $sku = Sku::where('title', 'domain-hosting')->first();
- $this->assertEquals($balance, $wallet->balance);
+ $entitlement = $sku->entitlements->first();
- // \App\Handlers\Storage SKU
- $sku = Sku::where('title', 'storage')->first();
- Entitlement::create(
- [
- 'owner_id' => $user->id,
- 'wallet_id' => $wallet->id,
- 'sku_id' => $sku->id,
- 'entitleable_id' => $user->id,
- 'entitleable_type' => User::class
- ]
+ $this->assertSame(
+ Handlers\DomainHosting::entitleableClass(),
+ $entitlement->entitleable_type
);
+ }
- $entitlements = $sku->entitlements->where('owner_id', $user->id);
- $wallet->refresh();
+ public function testSkuHandlerMailbox(): void
+ {
+ $sku = Sku::where('title', 'mailbox')->first();
- if ($sku->active) {
- $balance -= $sku->cost;
- $this->assertCount(1, $entitlements);
- } else {
- $this->assertCount(0, $entitlements);
- }
+ $entitlement = $sku->entitlements->first();
- $this->assertEquals($balance, $wallet->balance);
+ $this->assertSame(
+ Handlers\Mailbox::entitleableClass(),
+ $entitlement->entitleable_type
+ );
}
- public function testSkuPackages(): void
+ public function testSkuHandlerStorage(): void
{
- $sku = Sku::where('title', 'mailbox')->first();
+ $sku = Sku::where('title', 'storage')->first();
- $packages = $sku->packages;
+ $entitlement = $sku->entitlements->first();
- $this->assertCount(2, $packages);
+ $this->assertSame(
+ Handlers\Storage::entitleableClass(),
+ $entitlement->entitleable_type
+ );
}
}
diff --git a/src/tests/Feature/UserTest.php b/src/tests/Feature/UserTest.php
--- a/src/tests/Feature/UserTest.php
+++ b/src/tests/Feature/UserTest.php
@@ -34,22 +34,22 @@
public function testUserCreateJob(): void
{
// Fake the queue, assert that no jobs were pushed...
- Queue::fake();
- Queue::assertNothingPushed();
+ $queue = Queue::fake();
+ $queue->assertNothingPushed();
$user = User::create([
'email' => 'user-create-test@' . \config('app.domain')
]);
- Queue::assertPushed(\App\Jobs\UserCreate::class, 1);
- Queue::assertPushed(\App\Jobs\UserCreate::class, function ($job) use ($user) {
+ $queue->assertPushed(\App\Jobs\UserCreate::class, 1);
+ $queue->assertPushed(\App\Jobs\UserCreate::class, function ($job) use ($user) {
$job_user = TestCase::getObjectProperty($job, 'user');
return $job_user->id === $user->id
&& $job_user->email === $user->email;
});
- Queue::assertPushedWithChain(\App\Jobs\UserCreate::class, [
+ $queue->assertPushedWithChain(\App\Jobs\UserCreate::class, [
\App\Jobs\UserVerify::class,
]);
/*
@@ -58,8 +58,8 @@
independently (not chained) and make sure there's no race-condition
in status update
- Queue::assertPushed(\App\Jobs\UserVerify::class, 1);
- Queue::assertPushed(\App\Jobs\UserVerify::class, function ($job) use ($user) {
+ $queue->assertPushed(\App\Jobs\UserVerify::class, 1);
+ $queue->assertPushed(\App\Jobs\UserVerify::class, function ($job) use ($user) {
$job_user = TestCase::getObjectProperty($job, 'user');
return $job_user->id === $user->id
diff --git a/src/tests/Feature/VerificationCodeTest.php b/src/tests/Feature/VerificationCodeTest.php
--- a/src/tests/Feature/VerificationCodeTest.php
+++ b/src/tests/Feature/VerificationCodeTest.php
@@ -48,6 +48,7 @@
$this->assertSame($data['mode'], $code->mode);
$this->assertEquals($user->id, $code->user->id);
$this->assertInstanceOf(\DateTime::class, $code->expires_at);
+
$this->assertSame($code_exp_hrs, $code->expires_at->diff($now)->h + 1);
$inst = VerificationCode::find($code->code);
diff --git a/src/tests/Feature/WalletTest.php b/src/tests/Feature/WalletTest.php
--- a/src/tests/Feature/WalletTest.php
+++ b/src/tests/Feature/WalletTest.php
@@ -47,7 +47,7 @@
{
$user = $this->getTestUser('UserWallet1@UserWallet.com');
- $this->assertTrue($user->wallets()->count() == 1);
+ $this->assertCount(1, $user->wallets);
}
/**
@@ -61,11 +61,11 @@
new Wallet(['currency' => 'USD'])
);
- $this->assertTrue($user->wallets()->count() >= 2);
+ $this->assertCount(2, $user->wallets);
$user->wallets()->each(
function ($wallet) {
- $this->assertTrue($wallet->balance === 0.00);
+ $this->assertEquals(0, $wallet->balance);
}
);
}
@@ -79,7 +79,7 @@
$user->wallets()->each(
function ($wallet) {
- $wallet->credit(1.00)->save();
+ $wallet->credit(100)->save();
}
);
@@ -97,7 +97,7 @@
{
$user = $this->getTestUser('UserWallet4@UserWallet.com');
- $this->assertTrue($user->wallets()->count() == 1);
+ $this->assertCount(1, $user->wallets);
$user->wallets()->each(
function ($wallet) {
@@ -140,15 +140,12 @@
}
);
- $this->assertTrue(
- $userB->accounts()->count() == 1,
- "number of accounts (1 expected): {$userB->accounts()->count()}"
- );
+ $this->assertCount(1, $userB->accounts);
- $aWallet = $userA->wallets()->get();
- $bAccount = $userB->accounts()->get();
+ $aWallet = $userA->wallets()->first();
+ $bAccount = $userB->accounts()->first();
- $this->assertTrue($bAccount[0]->id === $aWallet[0]->id);
+ $this->assertTrue($bAccount->id === $aWallet->id);
}
/**
@@ -173,6 +170,6 @@
}
);
- $this->assertTrue($userB->accounts()->count() == 0);
+ $this->assertCount(0, $userB->accounts);
}
}
diff --git a/src/tests/TestCase.php b/src/tests/TestCase.php
--- a/src/tests/TestCase.php
+++ b/src/tests/TestCase.php
@@ -11,10 +11,21 @@
{
use CreatesApplication;
+ protected function backdateEntitlements($entitlements, $targetDate)
+ {
+ foreach ($entitlements as $entitlement) {
+ $entitlement->created_at = $targetDate;
+ $entitlement->updated_at = $targetDate;
+ $entitlement->save();
+ }
+ }
+
protected function deleteTestDomain($name)
{
Queue::fake();
+
$domain = Domain::withTrashed()->where('namespace', $name)->first();
+
if (!$domain) {
return;
}
@@ -28,6 +39,7 @@
protected function deleteTestUser($email)
{
Queue::fake();
+
$user = User::withTrashed()->where('email', $email)->first();
if (!$user) {
@@ -59,7 +71,17 @@
{
// Disable jobs (i.e. skip LDAP oprations)
Queue::fake();
- return User::firstOrCreate(['email' => $email], $attrib);
+ $user = User::withTrashed()->where('email', $email)->first();
+
+ if (!$user) {
+ return User::firstOrCreate(['email' => $email], $attrib);
+ }
+
+ if ($user->deleted_at) {
+ $user->restore();
+ }
+
+ return $user;
}
/**

File Metadata

Mime Type
text/plain
Expires
Fri, Apr 3, 3:31 AM (18 h, 19 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18822421
Default Alt Text
D964.1775187062.diff (55 KB)

Event Timeline