diff --git a/src/app/Handlers/Activesync.php b/src/app/Handlers/Activesync.php --- a/src/app/Handlers/Activesync.php +++ b/src/app/Handlers/Activesync.php @@ -25,7 +25,7 @@ { $data = parent::metadata($sku); - $data['required'] = ['groupware']; + $data['required'] = ['Groupware']; return $data; } diff --git a/src/app/Handlers/Auth2F.php b/src/app/Handlers/Auth2F.php --- a/src/app/Handlers/Auth2F.php +++ b/src/app/Handlers/Auth2F.php @@ -25,7 +25,7 @@ { $data = parent::metadata($sku); - $data['forbidden'] = ['activesync']; + $data['forbidden'] = ['Activesync']; return $data; } diff --git a/src/app/Handlers/Base.php b/src/app/Handlers/Base.php --- a/src/app/Handlers/Base.php +++ b/src/app/Handlers/Base.php @@ -44,17 +44,11 @@ */ public static function metadata(\App\Sku $sku): array { - $handler = explode('\\', static::class); - $handler = strtolower(end($handler)); - - $type = explode('\\', static::entitleableClass()); - $type = strtolower(end($type)); - return [ // entitleable type - 'type' => $type, - // handler (as a keyword) - 'handler' => $handler, + 'type' => \lcfirst(\class_basename(static::entitleableClass())), + // handler + 'handler' => str_replace("App\\Handlers\\", '', static::class), // readonly entitlement state cannot be changed 'readonly' => false, // is entitlement enabled by default? diff --git a/src/app/Handlers/Beta/Base.php b/src/app/Handlers/Beta/Base.php --- a/src/app/Handlers/Beta/Base.php +++ b/src/app/Handlers/Beta/Base.php @@ -44,7 +44,7 @@ { $data = parent::metadata($sku); - $data['required'] = ['beta']; + $data['required'] = ['Beta']; return $data; } diff --git a/src/app/Handlers/Distlist.php b/src/app/Handlers/Beta/Distlists.php rename from src/app/Handlers/Distlist.php rename to src/app/Handlers/Beta/Distlists.php --- a/src/app/Handlers/Distlist.php +++ b/src/app/Handlers/Beta/Distlists.php @@ -1,8 +1,8 @@ $isController && $hasCustomDomain, // TODO: Make 'enableDistlists' working for wallet controllers that aren't account owners - 'enableDistlists' => $isController && $hasCustomDomain && in_array('distlist', $skus), + 'enableDistlists' => $isController && $hasCustomDomain && in_array('beta-distlists', $skus), // TODO: Make 'enableFolders' working for wallet controllers that aren't account owners 'enableFolders' => $isController && $hasCustomDomain && in_array('beta-shared-folders', $skus), // TODO: Make 'enableResources' working for wallet controllers that aren't account owners diff --git a/src/database/migrations/2021_12_15_100000_rename_beta_skus.php b/src/database/migrations/2021_12_15_100000_rename_beta_skus.php new file mode 100644 --- /dev/null +++ b/src/database/migrations/2021_12_15_100000_rename_beta_skus.php @@ -0,0 +1,37 @@ +get()->each(function ($sku) { + $sku->title = 'beta-distlists'; + $sku->handler_class = 'App\Handlers\Beta\Distlists'; + $sku->save(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + \App\Sku::where('title', 'beta-distlists')->get()->each(function ($sku) { + $sku->title = 'distlist'; + $sku->handler_class = 'App\Handlers\Distlist'; + $sku->save(); + }); + } +} diff --git a/src/database/seeds/local/SkuSeeder.php b/src/database/seeds/local/SkuSeeder.php --- a/src/database/seeds/local/SkuSeeder.php +++ b/src/database/seeds/local/SkuSeeder.php @@ -207,18 +207,18 @@ } // Check existence because migration might have added this already - $sku = Sku::where(['title' => 'distlist', 'tenant_id' => \config('app.tenant_id')])->first(); + $sku = Sku::where(['title' => 'beta-distlists', 'tenant_id' => \config('app.tenant_id')])->first(); if (!$sku) { Sku::create( [ - 'title' => 'distlist', + 'title' => 'beta-distlists', 'name' => 'Distribution lists', 'description' => 'Access to mail distribution lists', 'cost' => 0, 'units_free' => 0, 'period' => 'monthly', - 'handler_class' => 'App\Handlers\Distlist', + 'handler_class' => 'App\Handlers\Beta\Distlists', 'active' => true, ] ); diff --git a/src/database/seeds/production/SkuSeeder.php b/src/database/seeds/production/SkuSeeder.php --- a/src/database/seeds/production/SkuSeeder.php +++ b/src/database/seeds/production/SkuSeeder.php @@ -201,15 +201,15 @@ } // Check existence because migration might have added this already - if (!Sku::where('title', 'distlist')->first()) { + if (!Sku::where('title', 'beta-distlists')->first()) { Sku::create([ - 'title' => 'distlist', + 'title' => 'beta-distlists', 'name' => 'Distribution lists', 'description' => 'Access to mail distribution lists', 'cost' => 0, 'units_free' => 0, 'period' => 'monthly', - 'handler_class' => 'App\Handlers\Distlist', + 'handler_class' => 'App\Handlers\Beta\Distlists', 'active' => true, ]); } diff --git a/src/resources/vue/Admin/User.vue b/src/resources/vue/Admin/User.vue --- a/src/resources/vue/Admin/User.vue +++ b/src/resources/vue/Admin/User.vue @@ -217,7 +217,7 @@ {{ sku.name }} - {{ sku.price }} + {{ sku.price }} @@ -606,10 +606,10 @@ this.skus.push(item) - if (sku.handler == 'auth2f') { + if (sku.handler == 'Auth2F') { this.has2FA = true this.sku2FA = sku.id - } else if (sku.handler == 'beta') { + } else if (sku.handler == 'Beta') { this.hasBeta = true } } diff --git a/src/resources/vue/Widgets/SubscriptionSelect.vue b/src/resources/vue/Widgets/SubscriptionSelect.vue --- a/src/resources/vue/Widgets/SubscriptionSelect.vue +++ b/src/resources/vue/Widgets/SubscriptionSelect.vue @@ -134,11 +134,10 @@ if (input.checked) { // Check if a required SKU is selected, alert the user if not - (sku.required || []).forEach(title => { + (sku.required || []).forEach(requiredHandler => { this.skus.forEach(item => { - let checkbox - if (item.handler == title && (checkbox = $('#s' + item.id).find('input[type=checkbox]')[0])) { - if (!checkbox.checked) { + if (item.handler == requiredHandler) { + if (!$('#s' + item.id).find('input[type=checkbox]:checked').length) { required.push(item.name) } } @@ -160,10 +159,10 @@ } // Uncheck+lock/unlock conflicting SKUs - (sku.forbidden || []).forEach(title => { + (sku.forbidden || []).forEach(forbiddenHandler => { this.skus.forEach(item => { let checkbox - if (item.handler == title && (checkbox = $('#s' + item.id).find('input[type=checkbox]')[0])) { + if (item.handler == forbiddenHandler && (checkbox = $('#s' + item.id).find('input[type=checkbox]')[0])) { if (input.checked) { checkbox.checked = false checkbox.readOnly = true diff --git a/src/tests/Browser/DistlistTest.php b/src/tests/Browser/DistlistTest.php --- a/src/tests/Browser/DistlistTest.php +++ b/src/tests/Browser/DistlistTest.php @@ -73,7 +73,7 @@ ->assertMissing('@links .link-distlists'); }); - // Test that Distribution lists page is not accessible without the 'distlist' entitlement + // Test that Distribution lists page is not accessible without the 'beta-distlists' entitlement $this->browse(function (Browser $browser) { $browser->visit('/distlists') ->assertErrorPage(403); @@ -81,7 +81,7 @@ // Create a single group, add beta+distlist entitlements $john = $this->getTestUser('john@kolab.org'); - $this->addDistlistEntitlement($john); + $this->addBetaEntitlement($john, 'beta-distlists'); $group = $this->getTestGroup('group-test@kolab.org', ['name' => 'Test Group']); $group->assignToWallet($john->wallets->first()); @@ -111,7 +111,7 @@ */ public function testCreateUpdateDelete(): void { - // Test that the page is not available accessible without the 'distlist' entitlement + // Test that the page is not available accessible without the 'beta-distlists' entitlement $this->browse(function (Browser $browser) { $browser->visit('/distlist/new') ->assertErrorPage(403); @@ -119,7 +119,7 @@ // Add beta+distlist entitlements $john = $this->getTestUser('john@kolab.org'); - $this->addDistlistEntitlement($john); + $this->addBetaEntitlement($john, 'beta-distlists'); $this->browse(function (Browser $browser) { // Create a group @@ -233,7 +233,7 @@ public function testStatus(): void { $john = $this->getTestUser('john@kolab.org'); - $this->addDistlistEntitlement($john); + $this->addBetaEntitlement($john, 'beta-distlists'); $group = $this->getTestGroup('group-test@kolab.org'); $group->assignToWallet($john->wallets->first()); $group->status = Group::STATUS_NEW | Group::STATUS_ACTIVE; @@ -270,7 +270,7 @@ public function testSettings(): void { $john = $this->getTestUser('john@kolab.org'); - $this->addDistlistEntitlement($john); + $this->addBetaEntitlement($john, 'beta-distlists'); $group = $this->getTestGroup('group-test@kolab.org'); $group->assignToWallet($john->wallets->first()); $group->status = Group::STATUS_NEW | Group::STATUS_ACTIVE; @@ -311,16 +311,4 @@ }); }); } - - /** - * Register the beta + distlist entitlements for the user - */ - private function addDistlistEntitlement($user): void - { - // Add beta+distlist entitlements - $beta_sku = Sku::where('title', 'beta')->first(); - $distlist_sku = Sku::where('title', 'distlist')->first(); - $user->assignSku($beta_sku); - $user->assignSku($distlist_sku); - } } diff --git a/src/tests/Browser/UsersTest.php b/src/tests/Browser/UsersTest.php --- a/src/tests/Browser/UsersTest.php +++ b/src/tests/Browser/UsersTest.php @@ -730,52 +730,52 @@ 'tbody tr:nth-child(7) td.buttons button', 'Access to the private beta program subscriptions' ) - // Resources SKU - ->assertSeeIn('tbody tr:nth-child(8) td.name', 'Calendaring resources') + // Distlists SKU + ->assertSeeIn('tbody tr:nth-child(8) td.name', 'Distribution lists') ->assertSeeIn('tr:nth-child(8) td.price', '0,00 CHF/month') ->assertNotChecked('tbody tr:nth-child(8) td.selection input') ->assertEnabled('tbody tr:nth-child(8) td.selection input') ->assertTip( 'tbody tr:nth-child(8) td.buttons button', - 'Access to calendaring resources' + 'Access to mail distribution lists' ) - // Shared folders SKU - ->assertSeeIn('tbody tr:nth-child(9) td.name', 'Shared folders') + // Resources SKU + ->assertSeeIn('tbody tr:nth-child(9) td.name', 'Calendaring resources') ->assertSeeIn('tr:nth-child(9) td.price', '0,00 CHF/month') ->assertNotChecked('tbody tr:nth-child(9) td.selection input') ->assertEnabled('tbody tr:nth-child(9) td.selection input') ->assertTip( 'tbody tr:nth-child(9) td.buttons button', - 'Access to shared folders' + 'Access to calendaring resources' ) - // Distlist SKU - ->assertSeeIn('tbody tr:nth-child(10) td.name', 'Distribution lists') + // Shared folders SKU + ->assertSeeIn('tbody tr:nth-child(10) td.name', 'Shared folders') ->assertSeeIn('tr:nth-child(10) td.price', '0,00 CHF/month') ->assertNotChecked('tbody tr:nth-child(10) td.selection input') ->assertEnabled('tbody tr:nth-child(10) td.selection input') ->assertTip( 'tbody tr:nth-child(10) td.buttons button', - 'Access to mail distribution lists' + 'Access to shared folders' ) // Check Distlist, Uncheck Beta, expect Distlist unchecked - ->click('#sku-input-distlist') + ->click('#sku-input-beta-distlists') ->click('#sku-input-beta') ->assertNotChecked('#sku-input-beta') - ->assertNotChecked('#sku-input-distlist') - // Click Distlist expect an alert - ->click('#sku-input-distlist') + ->assertNotChecked('#sku-input-beta-distlists') + // Click Distlists expect an alert + ->click('#sku-input-beta-distlists') ->assertDialogOpened('Distribution lists requires Private Beta (invitation only).') ->acceptDialog() // Enable Beta and Distlist and submit ->click('#sku-input-beta') - ->click('#sku-input-distlist'); + ->click('#sku-input-beta-distlists'); }) ->click('@general button[type=submit]') ->assertToast(Toast::TYPE_SUCCESS, 'User data updated successfully.'); $expected = [ 'beta', - 'distlist', + 'beta-distlists', 'groupware', 'mailbox', 'storage', 'storage', 'storage', 'storage', 'storage' @@ -799,7 +799,7 @@ $this->assertEntitlements($john, $expected); }); - // TODO: Test that the Distlist SKU is not available for users that aren't a group account owners + // TODO: Test that the Distlists SKU is not available for users that aren't a group account owners // TODO: Test that entitlements change has immediate effect on the available items in dashboard // i.e. does not require a page reload nor re-login. } diff --git a/src/tests/Feature/Controller/Admin/SkusTest.php b/src/tests/Feature/Controller/Admin/SkusTest.php --- a/src/tests/Feature/Controller/Admin/SkusTest.php +++ b/src/tests/Feature/Controller/Admin/SkusTest.php @@ -94,7 +94,7 @@ $this->assertSame($sku->period, $json[0]['period']); $this->assertSame($sku->active, $json[0]['active']); $this->assertSame('user', $json[0]['type']); - $this->assertSame('mailbox', $json[0]['handler']); + $this->assertSame('Mailbox', $json[0]['handler']); } /** diff --git a/src/tests/Feature/Controller/Reseller/SkusTest.php b/src/tests/Feature/Controller/Reseller/SkusTest.php --- a/src/tests/Feature/Controller/Reseller/SkusTest.php +++ b/src/tests/Feature/Controller/Reseller/SkusTest.php @@ -111,7 +111,7 @@ $this->assertSame($sku->period, $json[0]['period']); $this->assertSame($sku->active, $json[0]['active']); $this->assertSame('user', $json[0]['type']); - $this->assertSame('mailbox', $json[0]['handler']); + $this->assertSame('Mailbox', $json[0]['handler']); // Test with another tenant $sku = Sku::where('title', 'mailbox')->where('tenant_id', $reseller2->tenant_id)->first(); @@ -132,7 +132,7 @@ $this->assertSame($sku->period, $json[0]['period']); $this->assertSame($sku->active, $json[0]['active']); $this->assertSame('user', $json[0]['type']); - $this->assertSame('mailbox', $json[0]['handler']); + $this->assertSame('Mailbox', $json[0]['handler']); } /** diff --git a/src/tests/Feature/Controller/SkusTest.php b/src/tests/Feature/Controller/SkusTest.php --- a/src/tests/Feature/Controller/SkusTest.php +++ b/src/tests/Feature/Controller/SkusTest.php @@ -69,7 +69,7 @@ $this->assertSkuElement('domain-hosting', $json[0], [ 'prio' => 0, 'type' => 'domain', - 'handler' => 'domainhosting', + 'handler' => 'DomainHosting', 'enabled' => false, 'readonly' => false, ]); @@ -117,7 +117,7 @@ $this->assertSame($sku->period, $json[0]['period']); $this->assertSame($sku->active, $json[0]['active']); $this->assertSame('user', $json[0]['type']); - $this->assertSame('mailbox', $json[0]['handler']); + $this->assertSame('Mailbox', $json[0]['handler']); } /** @@ -138,7 +138,7 @@ 'description' => '', 'active' => true, 'cost' => 100, - 'handler_class' => 'App\Handlers\Mailbox', + 'handler_class' => 'Mailbox', ]); $tenant = Tenant::whereNotIn('id', [\config('app.tenant_id')])->first(); $nsku->tenant_id = $tenant->id; @@ -154,7 +154,7 @@ $this->assertSkuElement('mailbox', $json[0], [ 'prio' => 100, 'type' => 'user', - 'handler' => 'mailbox', + 'handler' => 'Mailbox', 'enabled' => true, 'readonly' => true, ]); @@ -162,7 +162,7 @@ $this->assertSkuElement('storage', $json[1], [ 'prio' => 90, 'type' => 'user', - 'handler' => 'storage', + 'handler' => 'Storage', 'enabled' => true, 'readonly' => true, 'range' => [ @@ -175,7 +175,7 @@ $this->assertSkuElement('groupware', $json[2], [ 'prio' => 80, 'type' => 'user', - 'handler' => 'groupware', + 'handler' => 'Groupware', 'enabled' => false, 'readonly' => false, ]); @@ -183,28 +183,28 @@ $this->assertSkuElement('activesync', $json[3], [ 'prio' => 70, 'type' => 'user', - 'handler' => 'activesync', + 'handler' => 'Activesync', 'enabled' => false, 'readonly' => false, - 'required' => ['groupware'], + 'required' => ['Groupware'], ]); $this->assertSkuElement('2fa', $json[4], [ 'prio' => 60, 'type' => 'user', - 'handler' => 'auth2f', + 'handler' => 'Auth2F', 'enabled' => false, 'readonly' => false, - 'forbidden' => ['activesync'], + 'forbidden' => ['Activesync'], ]); $this->assertSkuElement('meet', $json[5], [ 'prio' => 50, 'type' => 'user', - 'handler' => 'meet', + 'handler' => 'Meet', 'enabled' => false, 'readonly' => false, - 'required' => ['groupware'], + 'required' => ['Groupware'], ]); // Test inclusion of beta SKUs @@ -220,36 +220,36 @@ $this->assertSkuElement('beta', $json[6], [ 'prio' => 10, 'type' => 'user', - 'handler' => 'beta', + 'handler' => 'Beta', 'enabled' => false, 'readonly' => false, ]); - $this->assertSkuElement('beta-resources', $json[7], [ + $this->assertSkuElement('beta-distlists', $json[7], [ 'prio' => 10, 'type' => 'user', - 'handler' => 'resources', // TODO: shouldn't it be beta-resources or beta/resources? + 'handler' => 'Beta\Distlists', 'enabled' => false, 'readonly' => false, - 'required' => ['beta'], + 'required' => ['Beta'], ]); - $this->assertSkuElement('beta-shared-folders', $json[8], [ + $this->assertSkuElement('beta-resources', $json[8], [ 'prio' => 10, 'type' => 'user', - 'handler' => 'sharedfolders', + 'handler' => 'Beta\Resources', 'enabled' => false, 'readonly' => false, - 'required' => ['beta'], + 'required' => ['Beta'], ]); - $this->assertSkuElement('distlist', $json[9], [ + $this->assertSkuElement('beta-shared-folders', $json[9], [ 'prio' => 10, 'type' => 'user', - 'handler' => 'distlist', + 'handler' => 'Beta\SharedFolders', 'enabled' => false, 'readonly' => false, - 'required' => ['beta'], + 'required' => ['Beta'], ]); } diff --git a/src/tests/TestCaseTrait.php b/src/tests/TestCaseTrait.php --- a/src/tests/TestCaseTrait.php +++ b/src/tests/TestCaseTrait.php @@ -154,9 +154,9 @@ { $beta_handlers = [ 'App\Handlers\Beta', + 'App\Handlers\Beta\Distlists', 'App\Handlers\Beta\Resources', 'App\Handlers\Beta\SharedFolders', - 'App\Handlers\Distlist', ]; $betas = Sku::whereIn('handler_class', $beta_handlers)->pluck('id')->all();