Changeset View
Changeset View
Standalone View
Standalone View
src/tests/Browser/SharedFolderTest.php
<?php | <?php | ||||
namespace Tests\Browser; | namespace Tests\Browser; | ||||
use App\SharedFolder; | use App\SharedFolder; | ||||
use Tests\Browser; | use Tests\Browser; | ||||
use Tests\Browser\Components\AclInput; | use Tests\Browser\Components\AclInput; | ||||
use Tests\Browser\Components\ListInput; | |||||
use Tests\Browser\Components\Status; | use Tests\Browser\Components\Status; | ||||
use Tests\Browser\Components\Toast; | use Tests\Browser\Components\Toast; | ||||
use Tests\Browser\Pages\Dashboard; | use Tests\Browser\Pages\Dashboard; | ||||
use Tests\Browser\Pages\Home; | use Tests\Browser\Pages\Home; | ||||
use Tests\Browser\Pages\SharedFolderInfo; | use Tests\Browser\Pages\SharedFolderInfo; | ||||
use Tests\Browser\Pages\SharedFolderList; | use Tests\Browser\Pages\SharedFolderList; | ||||
use Tests\TestCaseDusk; | use Tests\TestCaseDusk; | ||||
▲ Show 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | public function testList(): void | ||||
// Test shared folders lists page | // Test shared folders lists page | ||||
$this->browse(function (Browser $browser) { | $this->browse(function (Browser $browser) { | ||||
$browser->visit(new Dashboard()) | $browser->visit(new Dashboard()) | ||||
->assertSeeIn('@links .link-shared-folders', 'Shared folders') | ->assertSeeIn('@links .link-shared-folders', 'Shared folders') | ||||
->click('@links .link-shared-folders') | ->click('@links .link-shared-folders') | ||||
->on(new SharedFolderList()) | ->on(new SharedFolderList()) | ||||
->whenAvailable('@table', function (Browser $browser) { | ->whenAvailable('@table', function (Browser $browser) { | ||||
$browser->waitFor('tbody tr') | $browser->waitFor('tbody tr') | ||||
->assertElementsCount('thead th', 2) | |||||
->assertSeeIn('thead tr th:nth-child(1)', 'Name') | ->assertSeeIn('thead tr th:nth-child(1)', 'Name') | ||||
->assertSeeIn('thead tr th:nth-child(2)', 'Type') | ->assertSeeIn('thead tr th:nth-child(2)', 'Type') | ||||
->assertSeeIn('thead tr th:nth-child(3)', 'Email Address') | |||||
->assertElementsCount('tbody tr', 2) | ->assertElementsCount('tbody tr', 2) | ||||
->assertSeeIn('tbody tr:nth-child(1) td:nth-child(1) a', 'Calendar') | ->assertSeeIn('tbody tr:nth-child(1) td:nth-child(1) a', 'Calendar') | ||||
->assertSeeIn('tbody tr:nth-child(1) td:nth-child(2)', 'Calendar') | ->assertSeeIn('tbody tr:nth-child(1) td:nth-child(2)', 'Calendar') | ||||
->assertSeeIn('tbody tr:nth-child(1) td:nth-child(3) a', 'folder-event@kolab.org') | |||||
->assertText('tbody tr:nth-child(1) td:nth-child(1) svg.text-success title', 'Active') | ->assertText('tbody tr:nth-child(1) td:nth-child(1) svg.text-success title', 'Active') | ||||
->assertSeeIn('tbody tr:nth-child(2) td:nth-child(1) a', 'Contacts') | ->assertSeeIn('tbody tr:nth-child(2) td:nth-child(1) a', 'Contacts') | ||||
->assertSeeIn('tbody tr:nth-child(2) td:nth-child(2)', 'Address Book') | ->assertSeeIn('tbody tr:nth-child(2) td:nth-child(2)', 'Address Book') | ||||
->assertSeeIn('tbody tr:nth-child(2) td:nth-child(3) a', 'folder-contact@kolab.org') | |||||
->assertMissing('tfoot'); | ->assertMissing('tfoot'); | ||||
}); | }); | ||||
}); | }); | ||||
} | } | ||||
/** | /** | ||||
* Test shared folder creation/editing/deleting | * Test shared folder creation/editing/deleting | ||||
* | * | ||||
Show All 30 Lines | public function testCreateUpdateDelete(): void | ||||
->assertSelectHasOptions( | ->assertSelectHasOptions( | ||||
'div.row:nth-child(2) select', | 'div.row:nth-child(2) select', | ||||
['mail', 'event', 'task', 'contact', 'note', 'file'] | ['mail', 'event', 'task', 'contact', 'note', 'file'] | ||||
) | ) | ||||
->assertValue('div.row:nth-child(2) select', 'mail') | ->assertValue('div.row:nth-child(2) select', 'mail') | ||||
->assertSeeIn('div.row:nth-child(3) label', 'Domain') | ->assertSeeIn('div.row:nth-child(3) label', 'Domain') | ||||
->assertSelectHasOptions('div.row:nth-child(3) select', ['kolab.org']) | ->assertSelectHasOptions('div.row:nth-child(3) select', ['kolab.org']) | ||||
->assertValue('div.row:nth-child(3) select', 'kolab.org') | ->assertValue('div.row:nth-child(3) select', 'kolab.org') | ||||
->assertSeeIn('div.row:nth-child(4) label', 'Email Addresses') | |||||
->with(new ListInput('#aliases'), function (Browser $browser) { | |||||
$browser->assertListInputValue([]) | |||||
->assertValue('@input', ''); | |||||
}) | |||||
->assertSeeIn('button[type=submit]', 'Submit'); | ->assertSeeIn('button[type=submit]', 'Submit'); | ||||
}) | }) | ||||
// Test error conditions | // Test error conditions | ||||
->type('#name', str_repeat('A', 192)) | ->type('#name', str_repeat('A', 192)) | ||||
->select('#type', 'event') | |||||
->assertMissing('#aliases') | |||||
->click('@general button[type=submit]') | ->click('@general button[type=submit]') | ||||
->waitFor('#name + .invalid-feedback') | ->waitFor('#name + .invalid-feedback') | ||||
->assertSeeIn('#name + .invalid-feedback', 'The name may not be greater than 191 characters.') | ->assertSeeIn('#name + .invalid-feedback', 'The name may not be greater than 191 characters.') | ||||
->assertFocused('#name') | ->assertFocused('#name') | ||||
->assertToast(Toast::TYPE_ERROR, 'Form validation error') | ->assertToast(Toast::TYPE_ERROR, 'Form validation error') | ||||
// Test successful folder creation | // Test error handling on aliases input | ||||
->type('#name', 'Test Folder') | ->type('#name', 'Test Folder') | ||||
->select('#type', 'mail') | |||||
->with(new ListInput('#aliases'), function (Browser $browser) { | |||||
$browser->addListEntry('folder-alias@unknown'); | |||||
}) | |||||
->click('@general button[type=submit]') | |||||
->assertMissing('#name + .invalid-feedback') | |||||
->waitFor('#aliases + .invalid-feedback') | |||||
->with(new ListInput('#aliases'), function (Browser $browser) { | |||||
$browser->assertFormError(1, "The specified domain is invalid.", true); | |||||
}) | |||||
->assertToast(Toast::TYPE_ERROR, 'Form validation error') | |||||
// Test successful folder creation | |||||
->select('#type', 'event') | ->select('#type', 'event') | ||||
->click('@general button[type=submit]') | ->click('@general button[type=submit]') | ||||
->assertToast(Toast::TYPE_SUCCESS, 'Shared folder created successfully.') | ->assertToast(Toast::TYPE_SUCCESS, 'Shared folder created successfully.') | ||||
->on(new SharedFolderList()) | ->on(new SharedFolderList()) | ||||
->assertElementsCount('@table tbody tr', 3); | ->assertElementsCount('@table tbody tr', 3); | ||||
$this->assertSame(1, SharedFolder::where('name', 'Test Folder')->count()); | |||||
$this->assertSame(0, SharedFolder::where('name', 'Test Folder')->first()->aliases()->count()); | |||||
// Test folder update | // Test folder update | ||||
$browser->click('@table tr:nth-child(3) td:first-child a') | $browser->click('@table tr:nth-child(3) td:first-child a') | ||||
->on(new SharedFolderInfo()) | ->on(new SharedFolderInfo()) | ||||
->assertSeeIn('#folder-info .card-title', 'Shared folder') | ->assertSeeIn('#folder-info .card-title', 'Shared folder') | ||||
->with('@general', function (Browser $browser) { | ->with('@general', function (Browser $browser) { | ||||
// Assert form content | // Assert form content | ||||
$browser->assertFocused('#name') | $browser->assertFocused('#name') | ||||
->assertSeeIn('div.row:nth-child(1) label', 'Status') | ->assertSeeIn('div.row:nth-child(1) label', 'Status') | ||||
->assertSeeIn('div.row:nth-child(1) span.text-danger', 'Not Ready') | ->assertSeeIn('div.row:nth-child(1) span.text-danger', 'Not Ready') | ||||
->assertSeeIn('div.row:nth-child(2) label', 'Name') | ->assertSeeIn('div.row:nth-child(2) label', 'Name') | ||||
->assertValue('div.row:nth-child(2) input[type=text]', 'Test Folder') | ->assertValue('div.row:nth-child(2) input[type=text]', 'Test Folder') | ||||
->assertSeeIn('div.row:nth-child(3) label', 'Type') | ->assertSeeIn('div.row:nth-child(3) label', 'Type') | ||||
->assertSelected('div.row:nth-child(3) select:disabled', 'event') | ->assertSelected('div.row:nth-child(3) select:disabled', 'event') | ||||
->assertSeeIn('div.row:nth-child(4) label', 'Email Address') | ->assertMissing('#aliases') | ||||
->assertAttributeRegExp( | |||||
'div.row:nth-child(4) input[type=text]:disabled', | |||||
'value', | |||||
'/^event-[0-9]+@kolab\.org$/' | |||||
) | |||||
->assertSeeIn('button[type=submit]', 'Submit'); | ->assertSeeIn('button[type=submit]', 'Submit'); | ||||
}) | }) | ||||
// Test error handling | // Test error handling | ||||
->type('#name', str_repeat('A', 192)) | ->type('#name', str_repeat('A', 192)) | ||||
->click('@general button[type=submit]') | ->click('@general button[type=submit]') | ||||
->waitFor('#name + .invalid-feedback') | ->waitFor('#name + .invalid-feedback') | ||||
->assertSeeIn('#name + .invalid-feedback', 'The name may not be greater than 191 characters.') | ->assertSeeIn('#name + .invalid-feedback', 'The name may not be greater than 191 characters.') | ||||
->assertVisible('#name.is-invalid') | ->assertVisible('#name.is-invalid') | ||||
Show All 15 Lines | public function testCreateUpdateDelete(): void | ||||
->assertSeeIn('button.button-delete', 'Delete folder') | ->assertSeeIn('button.button-delete', 'Delete folder') | ||||
->click('button.button-delete') | ->click('button.button-delete') | ||||
->assertToast(Toast::TYPE_SUCCESS, 'Shared folder deleted successfully.') | ->assertToast(Toast::TYPE_SUCCESS, 'Shared folder deleted successfully.') | ||||
->on(new SharedFolderList()) | ->on(new SharedFolderList()) | ||||
->assertElementsCount('@table tbody tr', 2); | ->assertElementsCount('@table tbody tr', 2); | ||||
$this->assertNull(SharedFolder::where('name', 'Test Folder Update')->first()); | $this->assertNull(SharedFolder::where('name', 'Test Folder Update')->first()); | ||||
}); | }); | ||||
// Test creation/updating a mail folder with mail aliases | |||||
$this->browse(function (Browser $browser) { | |||||
$browser->on(new SharedFolderList()) | |||||
->click('button.shared-folder-new') | |||||
->on(new SharedFolderInfo()) | |||||
->type('#name', 'Test Folder2') | |||||
->with(new ListInput('#aliases'), function (Browser $browser) { | |||||
$browser->addListEntry('folder-alias1@kolab.org') | |||||
->addListEntry('folder-alias2@kolab.org'); | |||||
}) | |||||
->click('@general button[type=submit]') | |||||
->assertToast(Toast::TYPE_SUCCESS, 'Shared folder created successfully.') | |||||
->on(new SharedFolderList()) | |||||
->assertElementsCount('@table tbody tr', 3); | |||||
$folder = SharedFolder::where('name', 'Test Folder2')->first(); | |||||
$this->assertSame( | |||||
['folder-alias1@kolab.org', 'folder-alias2@kolab.org'], | |||||
$folder->aliases()->pluck('alias')->all() | |||||
); | |||||
// Test folder update | |||||
$browser->click('@table tr:nth-child(3) td:first-child a') | |||||
->on(new SharedFolderInfo()) | |||||
->with('@general', function (Browser $browser) { | |||||
// Assert form content | |||||
$browser->assertFocused('#name') | |||||
->assertValue('div.row:nth-child(2) input[type=text]', 'Test Folder2') | |||||
->assertSelected('div.row:nth-child(3) select:disabled', 'mail') | |||||
->with(new ListInput('#aliases'), function (Browser $browser) { | |||||
$browser->assertListInputValue(['folder-alias1@kolab.org', 'folder-alias2@kolab.org']) | |||||
->assertValue('@input', ''); | |||||
}); | |||||
}) | |||||
// change folder name, and remove one alias | |||||
->type('#name', 'Test Folder Update2') | |||||
->with(new ListInput('#aliases'), function (Browser $browser) { | |||||
$browser->removeListEntry(2); | |||||
}) | |||||
->click('@general button[type=submit]') | |||||
->assertToast(Toast::TYPE_SUCCESS, 'Shared folder updated successfully.'); | |||||
$folder->refresh(); | |||||
$this->assertSame('Test Folder Update2', $folder->name); | |||||
$this->assertSame(['folder-alias1@kolab.org'], $folder->aliases()->pluck('alias')->all()); | |||||
}); | |||||
} | } | ||||
/** | /** | ||||
* Test shared folder status | * Test shared folder status | ||||
* | * | ||||
* @depends testList | * @depends testList | ||||
*/ | */ | ||||
public function testStatus(): void | public function testStatus(): void | ||||
▲ Show 20 Lines • Show All 104 Lines • Show Last 20 Lines |