Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F117751853
D964.1775187062.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
55 KB
Referenced Files
None
Subscribers
None
D964.1775187062.diff
View Options
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
Details
Attached
Mime Type
text/plain
Expires
Fri, Apr 3, 3:31 AM (21 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18822421
Default Alt Text
D964.1775187062.diff (55 KB)
Attached To
Mode
D964: Implement a changelog to further the debiting of wallet balances
Attached
Detach File
Event Timeline