-
+
-
-
-
-
-
-
-
-
-
-
+
+
+ -
+ Room Id:
+
{{ room }}
+
+ -
+ Mediaserver Room Id:
+
{{ stats.roomId }}
+
+ -
+ Send Transport state:
+
{{ stats.sendTransportState }}
+ {{ toText(stats.sendTransportStats) }}
+
+ -
+ Receive Transport state:
+
{{ stats.receiveTransportState }}
+ {{ toText(stats.receiveTransportStats) }}
+
+ -
+ Consumers:
+
{{ toText(stats.consumerStats) }}
+
+ -
+ Camera Producer:
+
{{ toText(stats.camProducerStats) }}
+
+ -
+ Mic Producer:
+
{{ toText(stats.micProducerStats) }}
+
+ -
+ Screen Producer:
+
{{ toText(stats.screenProducerStats) }}
+
+
diff --git a/src/resources/vue/PasswordReset.vue b/src/resources/vue/PasswordReset.vue
index a71d58bd..d3a45f78 100644
--- a/src/resources/vue/PasswordReset.vue
+++ b/src/resources/vue/PasswordReset.vue
@@ -1,173 +1,173 @@
{{ $t('password.reset') }} - {{ $t('nav.step', { i: 1, n: 3 }) }}
{{ $t('password.reset-step1') }}
{{ $t('password.reset-step1-hint', { email: fromEmail }) }}
{{ $t('password.reset') }} - {{ $t('nav.step', { i: 2, n: 3 }) }}
{{ $t('password.reset-step2') }}
{{ $t('password.reset') }} - {{ $t('nav.step', { i: 3, n: 3 }) }}
diff --git a/src/resources/vue/Reseller/Dashboard.vue b/src/resources/vue/Reseller/Dashboard.vue
index 83ad2142..8c5f197e 100644
--- a/src/resources/vue/Reseller/Dashboard.vue
+++ b/src/resources/vue/Reseller/Dashboard.vue
@@ -1,51 +1,51 @@
- {{ $t('dashboard.wallet') }}
+ {{ $t('dashboard.wallet') }}
{{ $root.price(balance) }}
- {{ $t('dashboard.invitations') }}
+ {{ $t('dashboard.invitations') }}
- {{ $t('dashboard.stats') }}
+ {{ $t('dashboard.stats') }}
diff --git a/src/resources/vue/Resource/Info.vue b/src/resources/vue/Resource/Info.vue
index eb420ccb..00cf6fc8 100644
--- a/src/resources/vue/Resource/Info.vue
+++ b/src/resources/vue/Resource/Info.vue
@@ -1,187 +1,188 @@
{{ $tc('resource.list-title', 1) }}
{{ $t('resource.delete') }}
{{ $t('resource.new') }}
diff --git a/src/resources/vue/SharedFolder/Info.vue b/src/resources/vue/SharedFolder/Info.vue
index 737f5ff3..52e1a749 100644
--- a/src/resources/vue/SharedFolder/Info.vue
+++ b/src/resources/vue/SharedFolder/Info.vue
@@ -1,181 +1,182 @@
{{ $tc('shf.list-title', 1) }}
{{ $t('shf.delete') }}
{{ $t('shf.new') }}
diff --git a/src/resources/vue/Signup.vue b/src/resources/vue/Signup.vue
index 6bff675b..987a921c 100644
--- a/src/resources/vue/Signup.vue
+++ b/src/resources/vue/Signup.vue
@@ -1,302 +1,297 @@
{{ $t('signup.title') }} - {{ $t('nav.step', { i: 1, n: 3 }) }}
{{ $t('signup.step1') }}
{{ $t('signup.title') }} - {{ $t('nav.step', { i: 2, n: 3 }) }}
{{ $t('signup.step2') }}
{{ $t('signup.title') }} - {{ $t('nav.step', { i: 3, n: 3 }) }}
{{ $t('signup.step3') }}
diff --git a/src/resources/vue/User/Info.vue b/src/resources/vue/User/Info.vue
index a9a36b6a..9c7ddb61 100644
--- a/src/resources/vue/User/Info.vue
+++ b/src/resources/vue/User/Info.vue
@@ -1,326 +1,326 @@
{{ $t('user.title') }}
{{ $t('user.delete') }}
{{ $t('user.new') }}
{{ $t('user.delete-text') }}
diff --git a/src/resources/vue/User/Profile.vue b/src/resources/vue/User/Profile.vue
index 1f5171d7..36232f28 100644
--- a/src/resources/vue/User/Profile.vue
+++ b/src/resources/vue/User/Profile.vue
@@ -1,114 +1,114 @@
{{ $t('user.profile-title') }}
{{ $t('user.profile-delete') }}
diff --git a/src/resources/vue/Wallet.vue b/src/resources/vue/Wallet.vue
index 601bc83c..773e1b97 100644
--- a/src/resources/vue/Wallet.vue
+++ b/src/resources/vue/Wallet.vue
@@ -1,430 +1,438 @@
{{ $t('wallet.title') }} {{ $root.price(wallet.balance, wallet.currency) }}
{{ wallet.notice }}
{{ $t('wallet.pending-payments-warning') }}
{{ $t('wallet.add-credit') }}
{{ $t('wallet.auto-payment-disabled') }}
{{ $t('wallet.payment-method', { method: mandate.method }) }}
{{ $t('wallet.auto-payment-inprogress') }}
{{ $t('wallet.auto-payment-cancel') }}
{{ $t('wallet.auto-payment-change') }}
{{ $t('wallet.receipts-hint') }}
{{ $t('btn.download') }}
{{ $t('wallet.receipts-none') }}
{{ $t('wallet.currency-conv', { wc: wallet.currency, pc: selectedPaymentMethod.currency }) }}
{{ $t('wallet.banktransfer-hint') }}
{{ $t('wallet.payment-amount-hint') }}
diff --git a/src/tests/Browser/Reseller/WalletTest.php b/src/tests/Browser/Reseller/WalletTest.php
index 2df1d124..e2f8ab85 100644
--- a/src/tests/Browser/Reseller/WalletTest.php
+++ b/src/tests/Browser/Reseller/WalletTest.php
@@ -1,248 +1,248 @@
getTestUser('reseller@' . \config('app.domain'));
$wallet = $reseller->wallets()->first();
$wallet->balance = 0;
$wallet->save();
$wallet->payments()->delete();
$wallet->transactions()->delete();
parent::tearDown();
}
/**
* Test wallet page (unauthenticated)
*/
public function testWalletUnauth(): void
{
// Test that the page requires authentication
$this->browse(function (Browser $browser) {
$browser->visit('/wallet')->on(new Home());
});
}
/**
* Test wallet "box" on Dashboard
*/
public function testDashboard(): void
{
$reseller = $this->getTestUser('reseller@' . \config('app.domain'));
Wallet::where('user_id', $reseller->id)->update(['balance' => 125]);
// Positive balance
$this->browse(function (Browser $browser) {
$browser->visit(new Home())
->submitLogon('reseller@' . \config('app.domain'), \App\Utils::generatePassphrase(), true)
->on(new Dashboard())
- ->assertSeeIn('@links .link-wallet .name', 'Wallet')
+ ->assertSeeIn('@links .link-wallet svg + span', 'Wallet')
->assertSeeIn('@links .link-wallet .badge.bg-success', '1,25 CHF');
});
Wallet::where('user_id', $reseller->id)->update(['balance' => -1234]);
// Negative balance
$this->browse(function (Browser $browser) {
$browser->visit(new Dashboard())
- ->assertSeeIn('@links .link-wallet .name', 'Wallet')
+ ->assertSeeIn('@links .link-wallet svg + span', 'Wallet')
->assertSeeIn('@links .link-wallet .badge.bg-danger', '-12,34 CHF');
});
}
/**
* Test wallet page
*
* @depends testDashboard
*/
public function testWallet(): void
{
$reseller = $this->getTestUser('reseller@' . \config('app.domain'));
Wallet::where('user_id', $reseller->id)->update(['balance' => -1234]);
$this->browse(function (Browser $browser) {
$browser->click('@links .link-wallet')
->on(new WalletPage())
->assertSeeIn('#wallet .card-title', 'Account balance -12,34 CHF')
->assertSeeIn('#wallet .card-title .text-danger', '-12,34 CHF')
->assertSeeIn('#wallet .card-text', 'You are out of credit');
});
}
/**
* Test Receipts tab
*
* @depends testWallet
*/
public function testReceipts(): void
{
$user = $this->getTestUser('reseller@' . \config('app.domain'));
$wallet = $user->wallets()->first();
$wallet->payments()->delete();
// Assert Receipts tab content when there's no receipts available
$this->browse(function (Browser $browser) {
$browser->visit(new WalletPage())
->assertSeeIn('#wallet .card-title', 'Account balance 0,00 CHF')
->assertSeeIn('#wallet .card-title .text-success', '0,00 CHF')
->assertSeeIn('#wallet .card-text', 'You are in your free trial period.') // TODO
->assertSeeIn('@nav #tab-receipts', 'Receipts')
->with('@receipts-tab', function (Browser $browser) {
$browser->waitUntilMissing('.app-loader')
->assertSeeIn('p', 'There are no receipts for payments')
->assertDontSeeIn('p', 'Here you can download')
->assertMissing('select')
->assertMissing('button');
});
});
// Create some sample payments
$receipts = [];
$date = Carbon::create(intval(date('Y')) - 1, 3, 30);
$payment = Payment::create([
'id' => 'AAA1',
'status' => PaymentProvider::STATUS_PAID,
'type' => PaymentProvider::TYPE_ONEOFF,
'description' => 'Paid in March',
'wallet_id' => $wallet->id,
'provider' => 'stripe',
'amount' => 1111,
'currency_amount' => 1111,
'currency' => 'CHF',
]);
$payment->updated_at = $date;
$payment->save();
$receipts[] = $date->format('Y-m');
$date = Carbon::create(intval(date('Y')) - 1, 4, 30);
$payment = Payment::create([
'id' => 'AAA2',
'status' => PaymentProvider::STATUS_PAID,
'type' => PaymentProvider::TYPE_ONEOFF,
'description' => 'Paid in April',
'wallet_id' => $wallet->id,
'provider' => 'stripe',
'amount' => 1111,
'currency_amount' => 1111,
'currency' => 'CHF',
]);
$payment->updated_at = $date;
$payment->save();
$receipts[] = $date->format('Y-m');
// Assert Receipts tab with receipts available
$this->browse(function (Browser $browser) use ($receipts) {
$browser->refresh()
->on(new WalletPage())
->assertSeeIn('@nav #tab-receipts', 'Receipts')
->with('@receipts-tab', function (Browser $browser) use ($receipts) {
$browser->waitUntilMissing('.app-loader')
->assertDontSeeIn('p', 'There are no receipts for payments')
->assertSeeIn('p', 'Here you can download')
->assertSeeIn('button', 'Download')
->assertElementsCount('select > option', 2)
->assertSeeIn('select > option:nth-child(1)', $receipts[1])
->assertSeeIn('select > option:nth-child(2)', $receipts[0]);
// Download a receipt file
$browser->select('select', $receipts[0])
->click('button')
->pause(2000);
$files = glob(__DIR__ . '/../downloads/*.pdf');
$filename = pathinfo($files[0], PATHINFO_BASENAME);
$this->assertTrue(strpos($filename, $receipts[0]) !== false);
$content = $browser->readDownloadedFile($filename, 0);
$this->assertStringStartsWith("%PDF-1.", $content);
$browser->removeDownloadedFile($filename);
});
});
}
/**
* Test History tab
*
* @depends testWallet
*/
public function testHistory(): void
{
$user = $this->getTestUser('reseller@' . \config('app.domain'));
$wallet = $user->wallets()->first();
$wallet->transactions()->delete();
// Create some sample transactions
$transactions = $this->createTestTransactions($wallet);
$transactions = array_reverse($transactions);
$pages = array_chunk($transactions, 10 /* page size*/);
$this->browse(function (Browser $browser) use ($pages) {
$browser->on(new WalletPage())
->assertSeeIn('@nav #tab-history', 'History')
->click('@nav #tab-history')
->with('@history-tab', function (Browser $browser) use ($pages) {
$browser->waitUntilMissing('.app-loader')
->assertElementsCount('table tbody tr', 10)
->assertMissing('table td.email')
->assertSeeIn('.more-loader button', 'Load more');
foreach ($pages[0] as $idx => $transaction) {
$selector = 'table tbody tr:nth-child(' . ($idx + 1) . ')';
$priceStyle = $transaction->type == Transaction::WALLET_AWARD ? 'text-success' : 'text-danger';
$browser->assertSeeIn("$selector td.description", $transaction->shortDescription())
->assertMissing("$selector td.selection button")
->assertVisible("$selector td.price.{$priceStyle}");
// TODO: Test more transaction details
}
// Load the next page
$browser->click('.more-loader button')
->waitUntilMissing('.app-loader')
->assertElementsCount('table tbody tr', 12)
->assertMissing('.more-loader button');
$debitEntry = null;
foreach ($pages[1] as $idx => $transaction) {
$selector = 'table tbody tr:nth-child(' . ($idx + 1 + 10) . ')';
$priceStyle = $transaction->type == Transaction::WALLET_CREDIT ? 'text-success' : 'text-danger';
$browser->assertSeeIn("$selector td.description", $transaction->shortDescription());
if ($transaction->type == Transaction::WALLET_DEBIT) {
$debitEntry = $selector;
} else {
$browser->assertMissing("$selector td.selection button");
}
}
});
});
}
}
diff --git a/src/tests/Browser/SettingsTest.php b/src/tests/Browser/SettingsTest.php
index 98a1ddaf..25505bc4 100644
--- a/src/tests/Browser/SettingsTest.php
+++ b/src/tests/Browser/SettingsTest.php
@@ -1,120 +1,120 @@
browse(function (Browser $browser) {
$browser->visit('/settings')->on(new Home());
});
}
/**
* Test settings "box" on Dashboard
*/
public function testDashboard(): void
{
$this->browse(function (Browser $browser) {
// Test a user that is not an account owner
$browser->visit(new Home())
->submitLogon('jack@kolab.org', 'simple123', true)
->on(new Dashboard())
- ->assertMissing('@links .link-settings .name')
+ ->assertMissing('@links .link-settings')
->visit('/settings')
->assertErrorPage(403)
->within(new Menu(), function (Browser $browser) {
$browser->clickMenuItem('logout');
});
// Test the account owner
$browser->waitForLocation('/login')
->on(new Home())
->submitLogon('john@kolab.org', 'simple123', true)
->on(new Dashboard())
- ->assertSeeIn('@links .link-settings .name', 'Settings');
+ ->assertSeeIn('@links .link-settings svg + span', 'Settings');
});
}
/**
* Test Settings page
*
* @depends testDashboard
*/
public function testSettings(): void
{
$john = $this->getTestUser('john@kolab.org');
$john->setSetting('password_policy', 'min:5,max:100,lower');
$john->setSetting('max_password_age', null);
$this->browse(function (Browser $browser) {
$browser->click('@links .link-settings')
->on(new Settings())
->assertSeeIn('#settings .card-title', 'Settings')
// Password policy
->assertSeeIn('@form .row:nth-child(1) > label', 'Password Policy')
->with('@form #password_policy', function (Browser $browser) {
$browser->assertElementsCount('li', 7)
->assertSeeIn('li:nth-child(1) label', 'Minimum password length')
->assertChecked('li:nth-child(1) input[type=checkbox]')
->assertDisabled('li:nth-child(1) input[type=checkbox]')
->assertValue('li:nth-child(1) input[type=text]', '5')
->assertSeeIn('li:nth-child(2) label', 'Maximum password length')
->assertChecked('li:nth-child(2) input[type=checkbox]')
->assertDisabled('li:nth-child(2) input[type=checkbox]')
->assertValue('li:nth-child(2) input[type=text]', '100')
->assertSeeIn('li:nth-child(3) label', 'Password contains a lower-case character')
->assertChecked('li:nth-child(3) input[type=checkbox]')
->assertMissing('li:nth-child(3) input[type=text]')
->assertSeeIn('li:nth-child(4) label', 'Password contains an upper-case character')
->assertNotChecked('li:nth-child(4) input[type=checkbox]')
->assertMissing('li:nth-child(4) input[type=text]')
->assertSeeIn('li:nth-child(5) label', 'Password contains a digit')
->assertNotChecked('li:nth-child(5) input[type=checkbox]')
->assertMissing('li:nth-child(5) input[type=text]')
->assertSeeIn('li:nth-child(6) label', 'Password contains a special character')
->assertNotChecked('li:nth-child(6) input[type=checkbox]')
->assertMissing('li:nth-child(6) input[type=text]')
->assertSeeIn('li:nth-child(7) label', 'Password cannot be the same as the last')
->assertNotChecked('li:nth-child(7) input[type=checkbox]')
->assertMissing('li:nth-child(7) input[type=text]')
->assertSelected('li:nth-child(7) select', 3)
->assertSelectHasOptions('li:nth-child(7) select', [1,2,3,4,5,6])
// Change the policy
->type('li:nth-child(1) input[type=text]', '11')
->type('li:nth-child(2) input[type=text]', '120')
->click('li:nth-child(3) input[type=checkbox]')
->click('li:nth-child(4) input[type=checkbox]');
})
->assertSeeIn('@form .row:nth-child(2) > label', 'Password Retention')
->with('@form #password_retention', function (Browser $browser) {
$browser->assertElementsCount('li', 1)
->assertSeeIn('li:nth-child(1) label', 'Require a password change every')
->assertNotChecked('li:nth-child(1) input[type=checkbox]')
->assertSelected('li:nth-child(1) select', 3)
->assertSelectHasOptions('li:nth-child(1) select', [3, 6, 9, 12])
// change the policy
->check('li:nth-child(1) input[type=checkbox]')
->select('li:nth-child(1) select', 6);
})
->click('button[type=submit]')
->assertToast(Toast::TYPE_SUCCESS, 'User settings updated successfully.');
});
$this->assertSame('min:11,max:120,upper', $john->getSetting('password_policy'));
$this->assertSame('6', $john->getSetting('max_password_age'));
}
}
diff --git a/src/tests/Browser/WalletTest.php b/src/tests/Browser/WalletTest.php
index df2149ee..bcf89dc0 100644
--- a/src/tests/Browser/WalletTest.php
+++ b/src/tests/Browser/WalletTest.php
@@ -1,275 +1,275 @@
deleteTestUser('wallets-controller@kolabnow.com');
$john = $this->getTestUser('john@kolab.org');
Wallet::where('user_id', $john->id)->update(['balance' => -1234]);
}
/**
* {@inheritDoc}
*/
public function tearDown(): void
{
$this->deleteTestUser('wallets-controller@kolabnow.com');
$john = $this->getTestUser('john@kolab.org');
Wallet::where('user_id', $john->id)->update(['balance' => 0]);
parent::tearDown();
}
/**
* Test wallet page (unauthenticated)
*/
public function testWalletUnauth(): void
{
// Test that the page requires authentication
$this->browse(function (Browser $browser) {
$browser->visit('/wallet')->on(new Home());
});
}
/**
* Test wallet "box" on Dashboard
*/
public function testDashboard(): void
{
// Test that the page requires authentication
$this->browse(function (Browser $browser) {
$browser->visit(new Home())
->submitLogon('john@kolab.org', 'simple123', true)
->on(new Dashboard())
- ->assertSeeIn('@links .link-wallet .name', 'Wallet')
+ ->assertSeeIn('@links .link-wallet svg + span', 'Wallet')
->assertSeeIn('@links .link-wallet .badge', '-12,34 CHF');
});
}
/**
* Test wallet page
*
* @depends testDashboard
*/
public function testWallet(): void
{
$this->browse(function (Browser $browser) {
$browser->click('@links .link-wallet')
->on(new WalletPage())
->assertSeeIn('#wallet .card-title', 'Account balance -12,34 CHF')
->assertSeeIn('#wallet .card-title .text-danger', '-12,34 CHF')
->assertSeeIn('#wallet .card-text', 'You are out of credit');
});
}
/**
* Test Receipts tab
*/
public function testReceipts(): void
{
$user = $this->getTestUser('wallets-controller@kolabnow.com', ['password' => 'simple123']);
$wallet = $user->wallets()->first();
$wallet->payments()->delete();
// Log out John and log in the test user
$this->browse(function (Browser $browser) {
$browser->visit('/logout')
->waitForLocation('/login')
->on(new Home())
->submitLogon('wallets-controller@kolabnow.com', 'simple123', true);
});
// Assert Receipts tab content when there's no receipts available
$this->browse(function (Browser $browser) {
$browser->on(new Dashboard())
->click('@links .link-wallet')
->on(new WalletPage())
->assertSeeIn('#wallet .card-title', 'Account balance 0,00 CHF')
->assertSeeIn('#wallet .card-title .text-success', '0,00 CHF')
->assertSeeIn('#wallet .card-text', 'You are in your free trial period.')
->assertSeeIn('@nav #tab-receipts', 'Receipts')
->with('@receipts-tab', function (Browser $browser) {
$browser->waitUntilMissing('.app-loader')
->assertSeeIn('p', 'There are no receipts for payments')
->assertDontSeeIn('p', 'Here you can download')
->assertMissing('select')
->assertMissing('button');
});
});
// Create some sample payments
$receipts = [];
$date = Carbon::create(intval(date('Y')) - 1, 3, 30);
$payment = Payment::create([
'id' => 'AAA1',
'status' => PaymentProvider::STATUS_PAID,
'type' => PaymentProvider::TYPE_ONEOFF,
'description' => 'Paid in March',
'wallet_id' => $wallet->id,
'provider' => 'stripe',
'amount' => 1111,
'currency_amount' => 1111,
'currency' => 'CHF',
]);
$payment->updated_at = $date;
$payment->save();
$receipts[] = $date->format('Y-m');
$date = Carbon::create(intval(date('Y')) - 1, 4, 30);
$payment = Payment::create([
'id' => 'AAA2',
'status' => PaymentProvider::STATUS_PAID,
'type' => PaymentProvider::TYPE_ONEOFF,
'description' => 'Paid in April',
'wallet_id' => $wallet->id,
'provider' => 'stripe',
'amount' => 1111,
'currency_amount' => 1111,
'currency' => 'CHF',
]);
$payment->updated_at = $date;
$payment->save();
$receipts[] = $date->format('Y-m');
// Assert Receipts tab with receipts available
$this->browse(function (Browser $browser) use ($receipts) {
$browser->refresh()
->on(new WalletPage())
->assertSeeIn('@nav #tab-receipts', 'Receipts')
->with('@receipts-tab', function (Browser $browser) use ($receipts) {
$browser->waitUntilMissing('.app-loader')
->assertDontSeeIn('p', 'There are no receipts for payments')
->assertSeeIn('p', 'Here you can download')
->assertSeeIn('button', 'Download')
->assertElementsCount('select > option', 2)
->assertSeeIn('select > option:nth-child(1)', $receipts[1])
->assertSeeIn('select > option:nth-child(2)', $receipts[0]);
// Download a receipt file
$browser->select('select', $receipts[0])
->click('button')
->pause(2000);
$files = glob(__DIR__ . '/downloads/*.pdf');
$filename = pathinfo($files[0], PATHINFO_BASENAME);
$this->assertTrue(strpos($filename, $receipts[0]) !== false);
$content = $browser->readDownloadedFile($filename, 0);
$this->assertStringStartsWith("%PDF-1.", $content);
$browser->removeDownloadedFile($filename);
});
});
}
/**
* Test History tab
*/
public function testHistory(): void
{
$user = $this->getTestUser('wallets-controller@kolabnow.com', ['password' => 'simple123']);
// Log out John and log in the test user
$this->browse(function (Browser $browser) {
$browser->visit('/logout')
->waitForLocation('/login')
->on(new Home())
->submitLogon('wallets-controller@kolabnow.com', 'simple123', true);
});
$package_kolab = \App\Package::where('title', 'kolab')->first();
$user->assignPackage($package_kolab);
$wallet = $user->wallets()->first();
// Create some sample transactions
$transactions = $this->createTestTransactions($wallet);
$transactions = array_reverse($transactions);
$pages = array_chunk($transactions, 10 /* page size*/);
$this->browse(function (Browser $browser) use ($pages) {
$browser->on(new Dashboard())
->click('@links .link-wallet')
->on(new WalletPage())
->assertSeeIn('@nav #tab-history', 'History')
->click('@nav #tab-history')
->with('@history-tab', function (Browser $browser) use ($pages) {
$browser->waitUntilMissing('.app-loader')
->assertElementsCount('table tbody tr', 10)
->assertMissing('table td.email')
->assertSeeIn('.more-loader button', 'Load more');
foreach ($pages[0] as $idx => $transaction) {
$selector = 'table tbody tr:nth-child(' . ($idx + 1) . ')';
$priceStyle = $transaction->type == Transaction::WALLET_AWARD ? 'text-success' : 'text-danger';
$browser->assertSeeIn("$selector td.description", $transaction->shortDescription())
->assertMissing("$selector td.selection button")
->assertVisible("$selector td.price.{$priceStyle}");
// TODO: Test more transaction details
}
// Load the next page
$browser->click('.more-loader button')
->waitUntilMissing('.app-loader')
->assertElementsCount('table tbody tr', 12)
->assertMissing('.more-loader button');
$debitEntry = null;
foreach ($pages[1] as $idx => $transaction) {
$selector = 'table tbody tr:nth-child(' . ($idx + 1 + 10) . ')';
$priceStyle = $transaction->type == Transaction::WALLET_CREDIT ? 'text-success' : 'text-danger';
$browser->assertSeeIn("$selector td.description", $transaction->shortDescription());
if ($transaction->type == Transaction::WALLET_DEBIT) {
$debitEntry = $selector;
} else {
$browser->assertMissing("$selector td.selection button");
}
}
// Load sub-transactions
$browser->click("$debitEntry td.selection button")
->waitUntilMissing('.app-loader')
->assertElementsCount("$debitEntry td.description ul li", 2)
->assertMissing("$debitEntry td.selection button");
});
});
}
/**
* Test that non-controller user has no access to wallet
*/
public function testAccessDenied(): void
{
$this->browse(function (Browser $browser) {
$browser->visit('/logout')
->on(new Home())
->submitLogon('jack@kolab.org', 'simple123', true)
->on(new Dashboard())
->assertMissing('@links .link-wallet')
->visit('/wallet')
->assertErrorPage(403, "Only account owners can access a wallet.");
});
}
}