Global Boomarks
This commit is contained in:
@@ -62,12 +62,11 @@ class FilterDrawerContractTest extends TestCase
|
||||
}
|
||||
}
|
||||
|
||||
public function testAddressBookSaveFilterReadsAppliedGridState(): void
|
||||
public function testAddressBookFilterChipsContract(): void
|
||||
{
|
||||
$content = $this->readProjectFile('pages/address-book/index(default).phtml');
|
||||
$moduleContent = $this->readProjectFile('web/js/pages/address-book-index.js');
|
||||
|
||||
$this->assertStringContainsString('new URL(gridConfig.baseUrl()).searchParams', $moduleContent);
|
||||
$this->assertStringNotContainsString('const state = collectFilterState();', $moduleContent);
|
||||
$this->assertStringContainsString('data-filter-chips-clear-all-label', $content);
|
||||
$this->assertStringContainsString('data-filter-chips-remove-label', $content);
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace MintyPHP\Tests\Service\Auth;
|
||||
|
||||
use MintyPHP\Http\SessionStore;
|
||||
use MintyPHP\Service\Auth\AuthSessionTenantContextService;
|
||||
use MintyPHP\Service\User\UserSavedFilterService;
|
||||
use MintyPHP\Service\Bookmark\BookmarkService;
|
||||
use MintyPHP\Service\User\UserTenantContextService;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
@@ -24,12 +24,12 @@ class AuthSessionTenantContextServiceTest extends TestCase
|
||||
$userTenantContextService->method('getAvailableDepartmentsByTenant')->willReturn([]);
|
||||
$userTenantContextService->expects($this->never())->method('getCurrentTenant');
|
||||
|
||||
$savedFilterGateway = $this->createMock(UserSavedFilterService::class);
|
||||
$savedFilterGateway->method('listForAddressBook')->willReturn([]);
|
||||
$bookmarkService = $this->createMock(BookmarkService::class);
|
||||
$bookmarkService->method('listGroupedForUser')->willReturn(['groups' => [], 'ungrouped' => []]);
|
||||
|
||||
$service = new AuthSessionTenantContextService(
|
||||
$userTenantContextService,
|
||||
$savedFilterGateway,
|
||||
$bookmarkService,
|
||||
new SessionStore()
|
||||
);
|
||||
|
||||
@@ -37,7 +37,7 @@ class AuthSessionTenantContextServiceTest extends TestCase
|
||||
|
||||
$this->assertSame([], $_SESSION['available_tenants']);
|
||||
$this->assertSame([], $_SESSION['available_departments_by_tenant']);
|
||||
$this->assertSame([], $_SESSION['address_book_saved_filters']);
|
||||
$this->assertSame(['groups' => [], 'ungrouped' => []], $_SESSION['user_bookmarks']);
|
||||
$this->assertTrue((bool) $_SESSION['no_active_tenant']);
|
||||
$this->assertArrayNotHasKey('current_tenant', $_SESSION);
|
||||
}
|
||||
@@ -49,19 +49,19 @@ class AuthSessionTenantContextServiceTest extends TestCase
|
||||
['id' => 8, 'uuid' => 'tenant-8'],
|
||||
];
|
||||
$availableDepartments = ['7' => [['id' => 11]]];
|
||||
$savedFilters = [['name' => 'Favorites']];
|
||||
$bookmarks = ['groups' => [['id' => 1, 'name' => 'Dev', 'bookmarks' => []]], 'ungrouped' => []];
|
||||
|
||||
$userTenantContextService = $this->createMock(UserTenantContextService::class);
|
||||
$userTenantContextService->method('getAvailableTenants')->willReturn($availableTenants);
|
||||
$userTenantContextService->method('getAvailableDepartmentsByTenant')->willReturn($availableDepartments);
|
||||
$userTenantContextService->method('getCurrentTenant')->willReturn(null);
|
||||
|
||||
$savedFilterGateway = $this->createMock(UserSavedFilterService::class);
|
||||
$savedFilterGateway->method('listForAddressBook')->willReturn($savedFilters);
|
||||
$bookmarkService = $this->createMock(BookmarkService::class);
|
||||
$bookmarkService->method('listGroupedForUser')->willReturn($bookmarks);
|
||||
|
||||
$service = new AuthSessionTenantContextService(
|
||||
$userTenantContextService,
|
||||
$savedFilterGateway,
|
||||
$bookmarkService,
|
||||
new SessionStore()
|
||||
);
|
||||
|
||||
@@ -69,7 +69,7 @@ class AuthSessionTenantContextServiceTest extends TestCase
|
||||
|
||||
$this->assertSame($availableTenants, $_SESSION['available_tenants']);
|
||||
$this->assertSame($availableDepartments, $_SESSION['available_departments_by_tenant']);
|
||||
$this->assertSame($savedFilters, $_SESSION['address_book_saved_filters']);
|
||||
$this->assertSame($bookmarks, $_SESSION['user_bookmarks']);
|
||||
$this->assertFalse((bool) $_SESSION['no_active_tenant']);
|
||||
$this->assertSame(7, (int) ($_SESSION['current_tenant']['id'] ?? 0));
|
||||
}
|
||||
@@ -90,12 +90,12 @@ class AuthSessionTenantContextServiceTest extends TestCase
|
||||
$userTenantContextService->method('getAvailableDepartmentsByTenant')->willReturn([]);
|
||||
$userTenantContextService->method('getCurrentTenant')->willReturn($availableTenants[0]);
|
||||
|
||||
$savedFilterGateway = $this->createMock(UserSavedFilterService::class);
|
||||
$savedFilterGateway->method('listForAddressBook')->willReturn([]);
|
||||
$bookmarkService = $this->createMock(BookmarkService::class);
|
||||
$bookmarkService->method('listGroupedForUser')->willReturn(['groups' => [], 'ungrouped' => []]);
|
||||
|
||||
$service = new AuthSessionTenantContextService(
|
||||
$userTenantContextService,
|
||||
$savedFilterGateway,
|
||||
$bookmarkService,
|
||||
new SessionStore()
|
||||
);
|
||||
|
||||
|
||||
423
tests/Service/Bookmark/BookmarkServiceTest.php
Normal file
423
tests/Service/Bookmark/BookmarkServiceTest.php
Normal file
@@ -0,0 +1,423 @@
|
||||
<?php
|
||||
|
||||
namespace MintyPHP\Tests\Service\Bookmark;
|
||||
|
||||
use MintyPHP\Repository\User\BookmarkGroupRepositoryInterface;
|
||||
use MintyPHP\Repository\User\BookmarkNavigationRepositoryInterface;
|
||||
use MintyPHP\Repository\User\BookmarkRepositoryInterface;
|
||||
use MintyPHP\Service\Bookmark\BookmarkService;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class BookmarkServiceTest extends TestCase
|
||||
{
|
||||
private BookmarkRepositoryInterface&MockObject $bookmarkRepo;
|
||||
private BookmarkGroupRepositoryInterface&MockObject $groupRepo;
|
||||
private BookmarkNavigationRepositoryInterface&MockObject $navigationRepo;
|
||||
private BookmarkService $service;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->bookmarkRepo = $this->createMock(BookmarkRepositoryInterface::class);
|
||||
$this->groupRepo = $this->createMock(BookmarkGroupRepositoryInterface::class);
|
||||
$this->navigationRepo = $this->createMock(BookmarkNavigationRepositoryInterface::class);
|
||||
$this->service = new BookmarkService($this->bookmarkRepo, $this->groupRepo, $this->navigationRepo);
|
||||
}
|
||||
|
||||
public function testSaveBookmarkHappyPath(): void
|
||||
{
|
||||
$this->bookmarkRepo->method('countByUser')->willReturn(0);
|
||||
$this->navigationRepo->expects($this->once())->method('nextRootSortOrder')->with(1)->willReturn(1);
|
||||
$this->bookmarkRepo->method('create')->willReturn(42);
|
||||
|
||||
$result = $this->service->saveBookmark(1, 'Home', 'admin', null);
|
||||
|
||||
$this->assertTrue($result['ok']);
|
||||
$this->assertSame('created', $result['mode']);
|
||||
$this->assertSame(42, $result['bookmark']['id']);
|
||||
$this->assertSame('Home', $result['bookmark']['name']);
|
||||
$this->assertSame('admin', $result['bookmark']['url']);
|
||||
$this->assertNull($result['bookmark']['group_id']);
|
||||
$this->assertArrayNotHasKey('icon', $result['bookmark']);
|
||||
}
|
||||
|
||||
public function testSaveBookmarkUpsertsExistingBookmarkByExactUrl(): void
|
||||
{
|
||||
$this->bookmarkRepo->expects($this->once())->method('findByUserAndUrl')->with(1, 'admin/users?a=1&b=2')->willReturn([
|
||||
'id' => 9,
|
||||
'url' => 'admin/users?a=1&b=2',
|
||||
]);
|
||||
$this->bookmarkRepo->expects($this->once())->method('update')->with(
|
||||
9,
|
||||
1,
|
||||
[
|
||||
'name' => 'Users',
|
||||
'group_id' => null,
|
||||
]
|
||||
)->willReturn(true);
|
||||
$this->bookmarkRepo->expects($this->never())->method('create');
|
||||
|
||||
$result = $this->service->saveBookmark(1, 'Users', 'admin/users?b=2&a=1', null);
|
||||
|
||||
$this->assertTrue($result['ok']);
|
||||
$this->assertSame('updated', $result['mode']);
|
||||
$this->assertSame(9, $result['bookmark']['id']);
|
||||
$this->assertSame('admin/users?a=1&b=2', $result['bookmark']['url']);
|
||||
}
|
||||
|
||||
public function testSaveBookmarkUpsertsExistingBookmarkAndMovesToNewGroupAtEnd(): void
|
||||
{
|
||||
$this->groupRepo->expects($this->once())->method('findById')->with(3, 1)->willReturn([
|
||||
'id' => 3,
|
||||
'name' => 'Sales',
|
||||
]);
|
||||
$this->bookmarkRepo->expects($this->once())->method('findByUserAndUrl')->with(1, 'admin/users')->willReturn([
|
||||
'id' => 9,
|
||||
'url' => 'admin/users',
|
||||
'group_id' => 1,
|
||||
]);
|
||||
$this->bookmarkRepo->expects($this->once())->method('nextBookmarkSortOrder')->with(1, 3)->willReturn(12);
|
||||
$this->bookmarkRepo->expects($this->once())->method('update')->with(
|
||||
9,
|
||||
1,
|
||||
[
|
||||
'name' => 'Users',
|
||||
'group_id' => 3,
|
||||
'sort_order' => 12,
|
||||
]
|
||||
)->willReturn(true);
|
||||
$this->bookmarkRepo->expects($this->never())->method('create');
|
||||
|
||||
$result = $this->service->saveBookmark(1, 'Users', 'admin/users', 3);
|
||||
|
||||
$this->assertTrue($result['ok']);
|
||||
$this->assertSame('updated', $result['mode']);
|
||||
}
|
||||
|
||||
public function testSaveBookmarkUpsertsLegacyBookmarkByCanonicalUrl(): void
|
||||
{
|
||||
$this->bookmarkRepo->expects($this->once())->method('findByUserAndUrl')->with(1, 'admin/users?a=1&b=2')->willReturn(false);
|
||||
$this->bookmarkRepo->expects($this->once())->method('listByUser')->with(1)->willReturn([
|
||||
['id' => 7, 'url' => 'admin/users?b=2&a=1'],
|
||||
]);
|
||||
$this->bookmarkRepo->expects($this->once())->method('update')->with(
|
||||
7,
|
||||
1,
|
||||
[
|
||||
'name' => 'Users',
|
||||
'group_id' => null,
|
||||
'url' => 'admin/users?a=1&b=2',
|
||||
]
|
||||
)->willReturn(true);
|
||||
$this->bookmarkRepo->expects($this->never())->method('create');
|
||||
|
||||
$result = $this->service->saveBookmark(1, 'Users', 'admin/users?a=1&b=2', null);
|
||||
|
||||
$this->assertTrue($result['ok']);
|
||||
$this->assertSame('updated', $result['mode']);
|
||||
$this->assertSame(7, $result['bookmark']['id']);
|
||||
}
|
||||
|
||||
public function testSaveBookmarkRejectsEmptyName(): void
|
||||
{
|
||||
$result = $this->service->saveBookmark(1, '', 'admin', null);
|
||||
|
||||
$this->assertFalse($result['ok']);
|
||||
$this->assertSame('name_required', $result['error']);
|
||||
}
|
||||
|
||||
public function testSaveBookmarkRejectsEmptyUrl(): void
|
||||
{
|
||||
$result = $this->service->saveBookmark(1, 'Test', '', null);
|
||||
|
||||
$this->assertFalse($result['ok']);
|
||||
$this->assertSame('url_required', $result['error']);
|
||||
}
|
||||
|
||||
public function testSaveBookmarkRejectsAbsoluteUrl(): void
|
||||
{
|
||||
$result = $this->service->saveBookmark(1, 'External', 'https://evil.com', null);
|
||||
|
||||
$this->assertFalse($result['ok']);
|
||||
$this->assertSame('url_required', $result['error']);
|
||||
}
|
||||
|
||||
public function testSaveBookmarkRejectsProtocolRelativeUrl(): void
|
||||
{
|
||||
$result = $this->service->saveBookmark(1, 'External', '//evil.com', null);
|
||||
|
||||
$this->assertFalse($result['ok']);
|
||||
$this->assertSame('url_required', $result['error']);
|
||||
}
|
||||
|
||||
public function testSaveBookmarkMaxLimitReached(): void
|
||||
{
|
||||
$this->bookmarkRepo->method('countByUser')->willReturn(50);
|
||||
|
||||
$result = $this->service->saveBookmark(1, 'Test', 'admin', null);
|
||||
|
||||
$this->assertFalse($result['ok']);
|
||||
$this->assertSame('max_reached', $result['error']);
|
||||
}
|
||||
|
||||
public function testSaveBookmarkWithGroupValidatesOwnership(): void
|
||||
{
|
||||
$this->bookmarkRepo->method('countByUser')->willReturn(0);
|
||||
$this->groupRepo->expects($this->any())->method('findById')->with(5, 1)->willReturn(false);
|
||||
|
||||
$result = $this->service->saveBookmark(1, 'Test', 'admin', 5);
|
||||
|
||||
$this->assertFalse($result['ok']);
|
||||
$this->assertSame('group_not_found', $result['error']);
|
||||
}
|
||||
|
||||
public function testSaveBookmarkWithValidGroup(): void
|
||||
{
|
||||
$this->bookmarkRepo->method('countByUser')->willReturn(0);
|
||||
$this->bookmarkRepo->expects($this->once())->method('nextBookmarkSortOrder')->with(1, 5)->willReturn(7);
|
||||
$this->bookmarkRepo->expects($this->once())->method('create')->with([
|
||||
'user_id' => 1,
|
||||
'group_id' => 5,
|
||||
'name' => 'Test',
|
||||
'url' => 'admin',
|
||||
'sort_order' => 7,
|
||||
])->willReturn(10);
|
||||
$this->groupRepo->expects($this->any())->method('findById')->with(5, 1)->willReturn(['id' => 5, 'name' => 'Dev']);
|
||||
|
||||
$result = $this->service->saveBookmark(1, 'Test', 'admin', 5);
|
||||
|
||||
$this->assertTrue($result['ok']);
|
||||
$this->assertSame(5, $result['bookmark']['group_id']);
|
||||
}
|
||||
|
||||
public function testUpdateBookmarkNotFound(): void
|
||||
{
|
||||
$this->bookmarkRepo->method('findById')->willReturn(false);
|
||||
|
||||
$result = $this->service->updateBookmark(1, 999, ['name' => 'New Name']);
|
||||
|
||||
$this->assertFalse($result['ok']);
|
||||
$this->assertSame('not_found', $result['error']);
|
||||
}
|
||||
|
||||
public function testUpdateBookmarkRejectsEmptyName(): void
|
||||
{
|
||||
$this->bookmarkRepo->method('findById')->willReturn(['id' => 1, 'name' => 'Old']);
|
||||
|
||||
$result = $this->service->updateBookmark(1, 1, ['name' => '']);
|
||||
|
||||
$this->assertFalse($result['ok']);
|
||||
$this->assertSame('name_required', $result['error']);
|
||||
}
|
||||
|
||||
public function testUpdateBookmarkNoChanges(): void
|
||||
{
|
||||
$this->bookmarkRepo->method('findById')->willReturn(['id' => 1, 'name' => 'Old']);
|
||||
|
||||
$result = $this->service->updateBookmark(1, 1, []);
|
||||
|
||||
$this->assertTrue($result['ok']);
|
||||
}
|
||||
|
||||
public function testUpdateBookmarkGroupChangeAppendsToTargetGroup(): void
|
||||
{
|
||||
$this->bookmarkRepo->expects($this->once())->method('findById')->with(5, 1)->willReturn([
|
||||
'id' => 5,
|
||||
'name' => 'Users',
|
||||
'group_id' => 1,
|
||||
]);
|
||||
$this->groupRepo->expects($this->once())->method('findById')->with(2, 1)->willReturn([
|
||||
'id' => 2,
|
||||
'name' => 'New',
|
||||
]);
|
||||
$this->bookmarkRepo->expects($this->once())->method('nextBookmarkSortOrder')->with(1, 2)->willReturn(9);
|
||||
$this->bookmarkRepo->expects($this->once())->method('update')->with(5, 1, [
|
||||
'group_id' => 2,
|
||||
'sort_order' => 9,
|
||||
])->willReturn(true);
|
||||
|
||||
$result = $this->service->updateBookmark(1, 5, ['group_id' => 2]);
|
||||
|
||||
$this->assertTrue($result['ok']);
|
||||
}
|
||||
|
||||
public function testUpdateBookmarkMoveToUngroupedUsesRootSortOrder(): void
|
||||
{
|
||||
$this->bookmarkRepo->expects($this->once())->method('findById')->with(5, 1)->willReturn([
|
||||
'id' => 5,
|
||||
'name' => 'Users',
|
||||
'group_id' => 2,
|
||||
]);
|
||||
$this->navigationRepo->expects($this->once())->method('nextRootSortOrder')->with(1)->willReturn(17);
|
||||
$this->bookmarkRepo->expects($this->once())->method('update')->with(5, 1, [
|
||||
'group_id' => null,
|
||||
'sort_order' => 17,
|
||||
])->willReturn(true);
|
||||
|
||||
$result = $this->service->updateBookmark(1, 5, ['group_id' => null]);
|
||||
|
||||
$this->assertTrue($result['ok']);
|
||||
}
|
||||
|
||||
public function testDeleteBookmark(): void
|
||||
{
|
||||
$this->bookmarkRepo->expects($this->any())->method('delete')->with(5, 1)->willReturn(true);
|
||||
|
||||
$this->assertTrue($this->service->deleteBookmark(1, 5));
|
||||
}
|
||||
|
||||
public function testSaveGroupHappyPath(): void
|
||||
{
|
||||
$this->groupRepo->method('countByUser')->willReturn(0);
|
||||
$this->navigationRepo->expects($this->once())->method('nextRootSortOrder')->with(1)->willReturn(4);
|
||||
$this->groupRepo->expects($this->once())->method('create')->with([
|
||||
'user_id' => 1,
|
||||
'name' => 'Development',
|
||||
'icon' => 'bi-people',
|
||||
'sort_order' => 4,
|
||||
])->willReturn(3);
|
||||
|
||||
$result = $this->service->saveGroup(1, 'Development', 'bi-people');
|
||||
|
||||
$this->assertTrue($result['ok']);
|
||||
$this->assertSame('created', $result['mode']);
|
||||
$this->assertSame(3, $result['group']['id']);
|
||||
$this->assertSame('Development', $result['group']['name']);
|
||||
$this->assertSame('bi-people', $result['group']['icon']);
|
||||
}
|
||||
|
||||
public function testSaveGroupRejectsEmptyName(): void
|
||||
{
|
||||
$result = $this->service->saveGroup(1, '', 'bi-folder');
|
||||
|
||||
$this->assertFalse($result['ok']);
|
||||
$this->assertSame('name_required', $result['error']);
|
||||
}
|
||||
|
||||
public function testSaveGroupFallsBackToDefaultIcon(): void
|
||||
{
|
||||
$this->groupRepo->method('countByUser')->willReturn(0);
|
||||
$this->navigationRepo->expects($this->once())->method('nextRootSortOrder')->with(1)->willReturn(1);
|
||||
$this->groupRepo->expects($this->once())->method('create')->with([
|
||||
'user_id' => 1,
|
||||
'name' => 'Development',
|
||||
'icon' => 'bi-folder',
|
||||
'sort_order' => 1,
|
||||
])->willReturn(11);
|
||||
|
||||
$result = $this->service->saveGroup(1, 'Development', 'invalid-icon');
|
||||
|
||||
$this->assertTrue($result['ok']);
|
||||
$this->assertSame('bi-folder', $result['group']['icon']);
|
||||
}
|
||||
|
||||
public function testSaveGroupMaxLimitReached(): void
|
||||
{
|
||||
$this->groupRepo->method('countByUser')->willReturn(10);
|
||||
|
||||
$result = $this->service->saveGroup(1, 'New Group', 'bi-folder');
|
||||
|
||||
$this->assertFalse($result['ok']);
|
||||
$this->assertSame('max_reached', $result['error']);
|
||||
}
|
||||
|
||||
public function testSaveGroupRenameExisting(): void
|
||||
{
|
||||
$this->groupRepo->expects($this->any())->method('findById')->with(5, 1)->willReturn(['id' => 5, 'name' => 'Old']);
|
||||
$this->groupRepo->expects($this->once())
|
||||
->method('update')
|
||||
->with(5, 1, ['name' => 'Renamed', 'icon' => 'bi-heart'])
|
||||
->willReturn(true);
|
||||
|
||||
$result = $this->service->saveGroup(1, 'Renamed', 'bi-heart', 5);
|
||||
|
||||
$this->assertTrue($result['ok']);
|
||||
$this->assertSame('updated', $result['mode']);
|
||||
$this->assertSame(5, $result['group']['id']);
|
||||
$this->assertSame('Renamed', $result['group']['name']);
|
||||
$this->assertSame('bi-heart', $result['group']['icon']);
|
||||
}
|
||||
|
||||
public function testDeleteGroupClearsBookmarks(): void
|
||||
{
|
||||
$this->bookmarkRepo->expects($this->once())->method('clearGroupId')->with(5, 1)->willReturn(true);
|
||||
$this->groupRepo->expects($this->any())->method('delete')->with(5, 1)->willReturn(true);
|
||||
|
||||
$this->assertTrue($this->service->deleteGroup(1, 5));
|
||||
}
|
||||
|
||||
public function testDeleteGroupReturnsFalseWhenClearFails(): void
|
||||
{
|
||||
$this->bookmarkRepo->expects($this->once())->method('clearGroupId')->with(5, 1)->willReturn(false);
|
||||
$this->groupRepo->expects($this->never())->method('delete');
|
||||
|
||||
$this->assertFalse($this->service->deleteGroup(1, 5));
|
||||
}
|
||||
|
||||
public function testReorderGroupsDelegatesToRepository(): void
|
||||
{
|
||||
$pairs = [
|
||||
['id' => 4, 'sort_order' => 1],
|
||||
['id' => 6, 'sort_order' => 2],
|
||||
];
|
||||
$this->groupRepo->expects($this->once())->method('updateSortOrders')->with(1, $pairs)->willReturn(true);
|
||||
|
||||
$this->assertTrue($this->service->reorderGroups(1, $pairs));
|
||||
}
|
||||
|
||||
public function testReorderBookmarksReturnsFalseOnRepositoryFailure(): void
|
||||
{
|
||||
$pairs = [
|
||||
['id' => 11, 'sort_order' => 1],
|
||||
['id' => 7, 'sort_order' => 2],
|
||||
];
|
||||
$this->bookmarkRepo->expects($this->once())->method('updateSortOrders')->with(1, $pairs)->willReturn(false);
|
||||
|
||||
$this->assertFalse($this->service->reorderBookmarks(1, $pairs));
|
||||
}
|
||||
|
||||
public function testReorderRootDelegatesToNavigationRepository(): void
|
||||
{
|
||||
$pairs = [
|
||||
['kind' => 'bookmark', 'id' => 11, 'sort_order' => 1],
|
||||
['kind' => 'group', 'id' => 2, 'sort_order' => 2],
|
||||
];
|
||||
$this->navigationRepo->expects($this->once())
|
||||
->method('updateRootSortOrders')
|
||||
->with(1, $pairs)
|
||||
->willReturn(true);
|
||||
|
||||
$this->assertTrue($this->service->reorderRoot(1, $pairs));
|
||||
}
|
||||
|
||||
public function testListGroupedForUser(): void
|
||||
{
|
||||
$this->groupRepo->method('listByUser')->willReturn([
|
||||
['id' => 1, 'name' => 'Dev', 'icon' => 'bi-folder', 'sort_order' => 0],
|
||||
]);
|
||||
$this->bookmarkRepo->method('listByUser')->willReturn([
|
||||
['id' => 10, 'name' => 'Home', 'url' => 'admin', 'group_id' => null, 'sort_order' => 0],
|
||||
['id' => 11, 'name' => 'Users', 'url' => 'admin/users', 'group_id' => 1, 'sort_order' => 0],
|
||||
]);
|
||||
|
||||
$result = $this->service->listGroupedForUser(1);
|
||||
|
||||
$this->assertCount(1, $result['groups']);
|
||||
$this->assertSame('Dev', $result['groups'][0]['name']);
|
||||
$this->assertSame('bi-folder', $result['groups'][0]['icon']);
|
||||
$this->assertCount(1, $result['groups'][0]['bookmarks']);
|
||||
$this->assertSame('Users', $result['groups'][0]['bookmarks'][0]['name']);
|
||||
$this->assertArrayNotHasKey('icon', $result['groups'][0]['bookmarks'][0]);
|
||||
$this->assertCount(1, $result['ungrouped']);
|
||||
$this->assertSame('Home', $result['ungrouped'][0]['name']);
|
||||
$this->assertArrayNotHasKey('icon', $result['ungrouped'][0]);
|
||||
}
|
||||
|
||||
public function testAllowedGroupIconsReturnsNonEmptyList(): void
|
||||
{
|
||||
$icons = BookmarkService::allowedGroupIcons();
|
||||
$this->assertNotEmpty($icons);
|
||||
$this->assertContains('bi-folder', $icons);
|
||||
$this->assertContains('bi-house', $icons);
|
||||
}
|
||||
}
|
||||
51
tests/Support/BookmarkUrlNormalizerTest.php
Normal file
51
tests/Support/BookmarkUrlNormalizerTest.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace MintyPHP\Tests\Support;
|
||||
|
||||
use MintyPHP\Support\BookmarkUrlNormalizer;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class BookmarkUrlNormalizerTest extends TestCase
|
||||
{
|
||||
public function testCanonicalizeRelativeNormalizesPathAndQueryOrder(): void
|
||||
{
|
||||
$actual = BookmarkUrlNormalizer::canonicalizeRelative('/admin//users/?b=2&a=1');
|
||||
|
||||
$this->assertSame('admin/users?a=1&b=2', $actual);
|
||||
}
|
||||
|
||||
public function testCanonicalizeRelativeSortsMultiValueQueryKeys(): void
|
||||
{
|
||||
$actual = BookmarkUrlNormalizer::canonicalizeRelative('admin/users?roles=2&roles=1&search=max');
|
||||
|
||||
$this->assertSame('admin/users?roles=1&roles=2&search=max', $actual);
|
||||
}
|
||||
|
||||
public function testCanonicalizeRelativeRejectsAbsoluteUrl(): void
|
||||
{
|
||||
$actual = BookmarkUrlNormalizer::canonicalizeRelative('https://example.com/admin/users');
|
||||
|
||||
$this->assertSame('', $actual);
|
||||
}
|
||||
|
||||
public function testCanonicalizeRelativeRemovesFragment(): void
|
||||
{
|
||||
$actual = BookmarkUrlNormalizer::canonicalizeRelative('admin/users?a=1#section-2');
|
||||
|
||||
$this->assertSame('admin/users?a=1', $actual);
|
||||
}
|
||||
|
||||
public function testCanonicalizeRequestUriStripsLocaleBaseAndSortsQuery(): void
|
||||
{
|
||||
$actual = BookmarkUrlNormalizer::canonicalizeRequestUri('/de/admin/users?b=2&a=1', '/de/');
|
||||
|
||||
$this->assertSame('admin/users?a=1&b=2', $actual);
|
||||
}
|
||||
|
||||
public function testCanonicalizeRequestUriHandlesAppBaseAndLocale(): void
|
||||
{
|
||||
$actual = BookmarkUrlNormalizer::canonicalizeRequestUri('/core/de/address-book?tenants=b&tenants=a', '/core/de/');
|
||||
|
||||
$this->assertSame('address-book?tenants=a&tenants=b', $actual);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user