From 89385801d1322d3649d9b91c009408b14c967255 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Tue, 12 Aug 2025 09:33:02 +0200 Subject: [PATCH 1/3] Add aliases for @shlinkio/dashboard-server to src folder --- tsconfig.json | 5 +++++ vite.config.ts | 10 ++++++++++ 2 files changed, 15 insertions(+) diff --git a/tsconfig.json b/tsconfig.json index ed5ab55c..e4385688 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,6 +8,11 @@ "**/.client/**/*.tsx" ], "compilerOptions": { + "baseUrl": ".", + "paths": { + "@shlinkio/dashboard-server": ["src"], + "@shlinkio/dashboard-server/*": ["src/*"] + }, "lib": ["dom", "dom.iterable", "esnext"], "types": ["@react-router/node", "vite/client", "vitest/globals"], "rootDirs": [".", "./.react-router/types"], diff --git a/vite.config.ts b/vite.config.ts index 961b2c17..1697adcd 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -13,6 +13,16 @@ export default defineConfig({ build: { target: 'esnext', + rollupOptions: { + // @shlinkio/dashboard-server (src) is bundled separately as its own package + external: ['@shlinkio/dashboard-server', '@shlinkio/dashboard-server/*'], + }, + }, + + resolve: { + alias: { + '@shlinkio/dashboard-server': resolve(__dirname, 'src'), + }, }, server: { From 644ad2dc91cfccb5a0ba4e2fa2d038049d8dd874 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Tue, 12 Aug 2025 09:36:07 +0200 Subject: [PATCH 2/3] Move app tests under test/app --- .../api/ShlinkApiProxyClient.client.test.ts | 2 +- test/{ => app}/auth/auth-helper.server.test.ts | 4 ++-- test/{ => app}/auth/auth.server.test.ts | 4 ++-- test/{ => app}/auth/passwords.server.test.ts | 2 +- test/{ => app}/auth/session.server.test.ts | 2 +- test/{ => app}/common/CopyToClipbord.test.tsx | 4 ++-- test/{ => app}/common/MainHeader.test.tsx | 10 +++++----- .../middleware/middleware.server.test.ts | 8 ++++---- test/{ => app}/routes/change-password.test.tsx | 14 +++++++------- test/{ => app}/routes/index/NoServers.test.tsx | 8 ++++---- test/{ => app}/routes/index/ServersList.test.tsx | 6 +++--- test/{ => app}/routes/index/WelcomeCard.test.tsx | 6 +++--- test/{ => app}/routes/index/home.test.tsx | 10 +++++----- test/{ => app}/routes/login.test.tsx | 6 +++--- test/{ => app}/routes/logout.test.ts | 4 ++-- .../routes/profile/ChangePasswordForm.test.tsx | 4 ++-- .../routes/profile/EditProfileForm.test.tsx | 6 +++--- .../routes/profile/ProfileForm.test.tsx | 10 +++++----- .../change-password-action.server.test.ts | 10 +++++----- .../profile/edit-profile-action.server.test.ts | 6 +++--- test/{ => app}/routes/profile/profile.test.tsx | 12 ++++++------ test/{ => app}/routes/save-tags-colors.test.ts | 6 +++--- .../routes/servers/DeleteServerModal.test.tsx | 8 ++++---- .../routes/servers/ServerFormFields.test.tsx | 6 +++--- .../routes/servers/create-server.test.tsx | 8 ++++---- .../routes/servers/delete-server.test.ts | 4 ++-- .../routes/servers/edit-server.test.tsx | 12 ++++++------ .../routes/servers/list-servers.test.tsx | 14 +++++++------- test/{ => app}/routes/settings.test.tsx | 6 +++--- .../routes/shlink-api-rpc-proxy.test.ts | 6 +++--- .../routes/users/DeleteUserModal.test.tsx | 8 ++++---- test/{ => app}/routes/users/RoleBadge.test.tsx | 6 +++--- .../routes/users/UserFormFields.test.tsx | 10 +++++----- test/{ => app}/routes/users/UserServers.test.tsx | 8 ++++---- .../users/__snapshots__/RoleBadge.test.tsx.snap | 0 test/{ => app}/routes/users/create-user.test.tsx | 12 ++++++------ test/{ => app}/routes/users/delete-user.test.ts | 4 ++-- .../routes/users/edit-user-servers.test.tsx | 10 +++++----- test/{ => app}/routes/users/edit-user.test.tsx | 12 ++++++------ test/{ => app}/routes/users/list-users.test.tsx | 12 ++++++------ .../routes/users/reset-user-password.test.tsx | 10 +++++----- .../servers/ServersService.server.test.ts | 12 ++++++------ .../settings/SettingsService.server.test.ts | 10 +++++----- test/{ => app}/tags/TagStorage.client.test.ts | 2 +- test/{ => app}/tags/TagsService.server.test.ts | 14 +++++++------- test/{ => app}/users/UsersService.server.test.ts | 16 ++++++++-------- 46 files changed, 177 insertions(+), 177 deletions(-) rename test/{ => app}/api/ShlinkApiProxyClient.client.test.ts (96%) rename test/{ => app}/auth/auth-helper.server.test.ts (97%) rename test/{ => app}/auth/auth.server.test.ts (94%) rename test/{ => app}/auth/passwords.server.test.ts (97%) rename test/{ => app}/auth/session.server.test.ts (81%) rename test/{ => app}/common/CopyToClipbord.test.tsx (82%) rename test/{ => app}/common/MainHeader.test.tsx (87%) rename test/{ => app}/middleware/middleware.server.test.ts (90%) rename test/{ => app}/routes/change-password.test.tsx (87%) rename test/{ => app}/routes/index/NoServers.test.tsx (78%) rename test/{ => app}/routes/index/ServersList.test.tsx (79%) rename test/{ => app}/routes/index/WelcomeCard.test.tsx (82%) rename test/{ => app}/routes/index/home.test.tsx (85%) rename test/{ => app}/routes/login.test.tsx (94%) rename test/{ => app}/routes/logout.test.ts (78%) rename test/{ => app}/routes/profile/ChangePasswordForm.test.tsx (89%) rename test/{ => app}/routes/profile/EditProfileForm.test.tsx (81%) rename test/{ => app}/routes/profile/ProfileForm.test.tsx (86%) rename test/{ => app}/routes/profile/change-password-action.server.test.ts (82%) rename test/{ => app}/routes/profile/edit-profile-action.server.test.ts (68%) rename test/{ => app}/routes/profile/profile.test.tsx (88%) rename test/{ => app}/routes/save-tags-colors.test.ts (87%) rename test/{ => app}/routes/servers/DeleteServerModal.test.tsx (85%) rename test/{ => app}/routes/servers/ServerFormFields.test.tsx (86%) rename test/{ => app}/routes/servers/create-server.test.tsx (88%) rename test/{ => app}/routes/servers/delete-server.test.ts (81%) rename test/{ => app}/routes/servers/edit-server.test.tsx (86%) rename test/{ => app}/routes/servers/list-servers.test.tsx (93%) rename test/{ => app}/routes/settings.test.tsx (93%) rename test/{ => app}/routes/shlink-api-rpc-proxy.test.ts (96%) rename test/{ => app}/routes/users/DeleteUserModal.test.tsx (85%) rename test/{ => app}/routes/users/RoleBadge.test.tsx (72%) rename test/{ => app}/routes/users/UserFormFields.test.tsx (79%) rename test/{ => app}/routes/users/UserServers.test.tsx (91%) rename test/{ => app}/routes/users/__snapshots__/RoleBadge.test.tsx.snap (100%) rename test/{ => app}/routes/users/create-user.test.tsx (90%) rename test/{ => app}/routes/users/delete-user.test.ts (81%) rename test/{ => app}/routes/users/edit-user-servers.test.tsx (90%) rename test/{ => app}/routes/users/edit-user.test.tsx (88%) rename test/{ => app}/routes/users/list-users.test.tsx (96%) rename test/{ => app}/routes/users/reset-user-password.test.tsx (90%) rename test/{ => app}/servers/ServersService.server.test.ts (92%) rename test/{ => app}/settings/SettingsService.server.test.ts (89%) rename test/{ => app}/tags/TagStorage.client.test.ts (95%) rename test/{ => app}/tags/TagsService.server.test.ts (89%) rename test/{ => app}/users/UsersService.server.test.ts (95%) diff --git a/test/api/ShlinkApiProxyClient.client.test.ts b/test/app/api/ShlinkApiProxyClient.client.test.ts similarity index 96% rename from test/api/ShlinkApiProxyClient.client.test.ts rename to test/app/api/ShlinkApiProxyClient.client.test.ts index 38e62838..8aa2eea0 100644 --- a/test/api/ShlinkApiProxyClient.client.test.ts +++ b/test/app/api/ShlinkApiProxyClient.client.test.ts @@ -7,7 +7,7 @@ import type { ShlinkShortUrlIdentifier, } from '@shlinkio/shlink-js-sdk/api-contract'; import { fromPartial } from '@total-typescript/shoehorn'; -import { ShlinkApiProxyClient } from '../../app/api/ShlinkApiProxyClient.client'; +import { ShlinkApiProxyClient } from '../../../app/api/ShlinkApiProxyClient.client'; describe('ShlinkApiProxyClient', () => { let proxyClient: ShlinkApiProxyClient; diff --git a/test/auth/auth-helper.server.test.ts b/test/app/auth/auth-helper.server.test.ts similarity index 97% rename from test/auth/auth-helper.server.test.ts rename to test/app/auth/auth-helper.server.test.ts index 0cc0ac55..e4804ea9 100644 --- a/test/auth/auth-helper.server.test.ts +++ b/test/app/auth/auth-helper.server.test.ts @@ -1,8 +1,8 @@ import { fromPartial } from '@total-typescript/shoehorn'; import type { SessionStorage } from 'react-router'; import type { Authenticator } from 'remix-auth'; -import { AuthHelper } from '../../app/auth/auth-helper.server'; -import type { SessionData, ShlinkSessionData } from '../../app/auth/session-context'; +import { AuthHelper } from '../../../app/auth/auth-helper.server'; +import type { SessionData, ShlinkSessionData } from '../../../app/auth/session-context'; describe('AuthHelper', () => { const authenticate = vi.fn(); diff --git a/test/auth/auth.server.test.ts b/test/app/auth/auth.server.test.ts similarity index 94% rename from test/auth/auth.server.test.ts rename to test/app/auth/auth.server.test.ts index a03e6407..5db0b6fa 100644 --- a/test/auth/auth.server.test.ts +++ b/test/app/auth/auth.server.test.ts @@ -1,7 +1,7 @@ import { fromPartial } from '@total-typescript/shoehorn'; import { Authenticator } from 'remix-auth'; -import { createAuthenticator, CREDENTIALS_STRATEGY } from '../../app/auth/auth.server'; -import type { UsersService } from '../../app/users/UsersService.server'; +import { createAuthenticator, CREDENTIALS_STRATEGY } from '../../../app/auth/auth.server'; +import type { UsersService } from '../../../app/users/UsersService.server'; describe('auth', () => { const getUserByCredentials = vi.fn(); diff --git a/test/auth/passwords.server.test.ts b/test/app/auth/passwords.server.test.ts similarity index 97% rename from test/auth/passwords.server.test.ts rename to test/app/auth/passwords.server.test.ts index 0d2fbfe9..0d0733fb 100644 --- a/test/auth/passwords.server.test.ts +++ b/test/app/auth/passwords.server.test.ts @@ -1,4 +1,4 @@ -import { generatePassword, hashPassword, verifyPassword } from '../../app/auth/passwords.server'; +import { generatePassword, hashPassword, verifyPassword } from '../../../app/auth/passwords.server'; describe('passwords', () => { it('can hash and then verify a password', async () => { diff --git a/test/auth/session.server.test.ts b/test/app/auth/session.server.test.ts similarity index 81% rename from test/auth/session.server.test.ts rename to test/app/auth/session.server.test.ts index fd3d46a5..58c4c0b5 100644 --- a/test/auth/session.server.test.ts +++ b/test/app/auth/session.server.test.ts @@ -1,4 +1,4 @@ -import { createSessionStorage } from '../../app/auth/session.server'; +import { createSessionStorage } from '../../../app/auth/session.server'; describe('createSessionStorage', () => { it('creates a session storage', () => { diff --git a/test/common/CopyToClipbord.test.tsx b/test/app/common/CopyToClipbord.test.tsx similarity index 82% rename from test/common/CopyToClipbord.test.tsx rename to test/app/common/CopyToClipbord.test.tsx index 2b19c6b4..97cb7be7 100644 --- a/test/common/CopyToClipbord.test.tsx +++ b/test/app/common/CopyToClipbord.test.tsx @@ -1,7 +1,7 @@ import { render } from '@testing-library/react'; import type { ReactNode } from 'react'; -import { CopyToClipboard } from '../../app/common/CopyToClipboard'; -import { checkAccessibility } from '../__helpers__/accessibility'; +import { CopyToClipboard } from '../../../app/common/CopyToClipboard'; +import { checkAccessibility } from '../../__helpers__/accessibility'; describe('', () => { const setUp = (children?: ReactNode) => render({children}); diff --git a/test/common/MainHeader.test.tsx b/test/app/common/MainHeader.test.tsx similarity index 87% rename from test/common/MainHeader.test.tsx rename to test/app/common/MainHeader.test.tsx index aa73cbec..65f4fb16 100644 --- a/test/common/MainHeader.test.tsx +++ b/test/app/common/MainHeader.test.tsx @@ -1,11 +1,11 @@ import { screen } from '@testing-library/react'; import { fromPartial } from '@total-typescript/shoehorn'; import { MemoryRouter } from 'react-router'; -import type { SessionData } from '../../app/auth/session-context'; -import { SessionProvider } from '../../app/auth/session-context'; -import { MainHeader } from '../../app/common/MainHeader'; -import { checkAccessibility } from '../__helpers__/accessibility'; -import { renderWithEvents } from '../__helpers__/set-up-test'; +import type { SessionData } from '../../../app/auth/session-context'; +import { SessionProvider } from '../../../app/auth/session-context'; +import { MainHeader } from '../../../app/common/MainHeader'; +import { checkAccessibility } from '../../__helpers__/accessibility'; +import { renderWithEvents } from '../../__helpers__/set-up-test'; describe('', () => { const setUp = (session: SessionData | null = null) => renderWithEvents( diff --git a/test/middleware/middleware.server.test.ts b/test/app/middleware/middleware.server.test.ts similarity index 90% rename from test/middleware/middleware.server.test.ts rename to test/app/middleware/middleware.server.test.ts index d1818dee..947e41ef 100644 --- a/test/middleware/middleware.server.test.ts +++ b/test/app/middleware/middleware.server.test.ts @@ -1,13 +1,13 @@ import { fromPartial } from '@total-typescript/shoehorn'; import type { unstable_RouterContextProvider } from 'react-router'; -import type { AuthHelper } from '../../app/auth/auth-helper.server'; -import type { SessionData } from '../../app/auth/session-context'; -import type { Role } from '../../app/entities/User'; +import type { AuthHelper } from '../../../app/auth/auth-helper.server'; +import type { SessionData } from '../../../app/auth/session-context'; +import type { Role } from '../../../app/entities/User'; import { authMiddleware, ensureAdminMiddleware, ensureNotManagedMiddleware, -} from '../../app/middleware/middleware.server'; +} from '../../../app/middleware/middleware.server'; describe('middleware', () => { const next = vi.fn().mockResolvedValue(new Response('Success', { status: 200 })); diff --git a/test/routes/change-password.test.tsx b/test/app/routes/change-password.test.tsx similarity index 87% rename from test/routes/change-password.test.tsx rename to test/app/routes/change-password.test.tsx index fa523d3c..09f4ce13 100644 --- a/test/routes/change-password.test.tsx +++ b/test/app/routes/change-password.test.tsx @@ -1,13 +1,13 @@ import { screen } from '@testing-library/react'; import { fromPartial } from '@total-typescript/shoehorn'; import { createRoutesStub } from 'react-router'; -import type { AuthHelper } from '../../app/auth/auth-helper.server'; -import ChangePassword, { action, loader } from '../../app/routes/change-password'; -import { INVALID_PASSWORD_FORMAT } from '../../app/routes/profile/change-password-action.server'; -import { PasswordMismatchError } from '../../app/users/PasswordMismatchError.server'; -import type { UsersService } from '../../app/users/UsersService.server'; -import { ValidationError } from '../../app/validation/ValidationError.server'; -import { renderWithEvents } from '../__helpers__/set-up-test'; +import type { AuthHelper } from '../../../app/auth/auth-helper.server'; +import ChangePassword, { action, loader } from '../../../app/routes/change-password'; +import { INVALID_PASSWORD_FORMAT } from '../../../app/routes/profile/change-password-action.server'; +import { PasswordMismatchError } from '../../../app/users/PasswordMismatchError.server'; +import type { UsersService } from '../../../app/users/UsersService.server'; +import { ValidationError } from '../../../app/validation/ValidationError.server'; +import { renderWithEvents } from '../../__helpers__/set-up-test'; describe('change-password', () => { describe('loader', () => { diff --git a/test/routes/index/NoServers.test.tsx b/test/app/routes/index/NoServers.test.tsx similarity index 78% rename from test/routes/index/NoServers.test.tsx rename to test/app/routes/index/NoServers.test.tsx index ba553fc8..13cb2f2f 100644 --- a/test/routes/index/NoServers.test.tsx +++ b/test/app/routes/index/NoServers.test.tsx @@ -1,10 +1,10 @@ import { render, screen } from '@testing-library/react'; import { fromPartial } from '@total-typescript/shoehorn'; import { MemoryRouter } from 'react-router'; -import type { SessionData } from '../../../app/auth/session-context'; -import { SessionProvider } from '../../../app/auth/session-context'; -import { NoServers } from '../../../app/routes/index/NoServers'; -import { checkAccessibility } from '../../__helpers__/accessibility'; +import type { SessionData } from '../../../../app/auth/session-context'; +import { SessionProvider } from '../../../../app/auth/session-context'; +import { NoServers } from '../../../../app/routes/index/NoServers'; +import { checkAccessibility } from '../../../__helpers__/accessibility'; describe('', () => { const setUp = (session: SessionData | null = null) => render( diff --git a/test/routes/index/ServersList.test.tsx b/test/app/routes/index/ServersList.test.tsx similarity index 79% rename from test/routes/index/ServersList.test.tsx rename to test/app/routes/index/ServersList.test.tsx index 7e4b0222..57360ff3 100644 --- a/test/routes/index/ServersList.test.tsx +++ b/test/app/routes/index/ServersList.test.tsx @@ -1,9 +1,9 @@ import { render, screen } from '@testing-library/react'; import { fromPartial } from '@total-typescript/shoehorn'; import { MemoryRouter } from 'react-router'; -import type { Server } from '../../../app/entities/Server'; -import { ServersList } from '../../../app/routes/index/ServersList'; -import { checkAccessibility } from '../../__helpers__/accessibility'; +import type { Server } from '../../../../app/entities/Server'; +import { ServersList } from '../../../../app/routes/index/ServersList'; +import { checkAccessibility } from '../../../__helpers__/accessibility'; describe('', () => { const setUp = (servers: Server[]) => render( diff --git a/test/routes/index/WelcomeCard.test.tsx b/test/app/routes/index/WelcomeCard.test.tsx similarity index 82% rename from test/routes/index/WelcomeCard.test.tsx rename to test/app/routes/index/WelcomeCard.test.tsx index 174a702b..b3df9958 100644 --- a/test/routes/index/WelcomeCard.test.tsx +++ b/test/app/routes/index/WelcomeCard.test.tsx @@ -1,9 +1,9 @@ import { render, screen } from '@testing-library/react'; import { fromPartial } from '@total-typescript/shoehorn'; import { MemoryRouter } from 'react-router'; -import type { Server } from '../../../app/entities/Server'; -import { WelcomeCard } from '../../../app/routes/index/WelcomeCard'; -import { checkAccessibility } from '../../__helpers__/accessibility'; +import type { Server } from '../../../../app/entities/Server'; +import { WelcomeCard } from '../../../../app/routes/index/WelcomeCard'; +import { checkAccessibility } from '../../../__helpers__/accessibility'; describe('', () => { const setUp = (servers: Server[]) => render( diff --git a/test/routes/index/home.test.tsx b/test/app/routes/index/home.test.tsx similarity index 85% rename from test/routes/index/home.test.tsx rename to test/app/routes/index/home.test.tsx index c953eccf..002b6745 100644 --- a/test/routes/index/home.test.tsx +++ b/test/app/routes/index/home.test.tsx @@ -1,11 +1,11 @@ import { render, screen, waitFor } from '@testing-library/react'; import { fromPartial } from '@total-typescript/shoehorn'; import { createRoutesStub } from 'react-router'; -import type { AuthHelper } from '../../../app/auth/auth-helper.server'; -import type { SessionData } from '../../../app/auth/session-context'; -import type { Server } from '../../../app/entities/Server'; -import Home, { loader } from '../../../app/routes/index/home'; -import type { ServersService } from '../../../app/servers/ServersService.server'; +import type { AuthHelper } from '../../../../app/auth/auth-helper.server'; +import type { SessionData } from '../../../../app/auth/session-context'; +import type { Server } from '../../../../app/entities/Server'; +import Home, { loader } from '../../../../app/routes/index/home'; +import type { ServersService } from '../../../../app/servers/ServersService.server'; describe('home', () => { describe('loader', () => { diff --git a/test/routes/login.test.tsx b/test/app/routes/login.test.tsx similarity index 94% rename from test/routes/login.test.tsx rename to test/app/routes/login.test.tsx index d6a4b891..e5e4c589 100644 --- a/test/routes/login.test.tsx +++ b/test/app/routes/login.test.tsx @@ -1,9 +1,9 @@ import { screen, waitFor } from '@testing-library/react'; import { fromPartial } from '@total-typescript/shoehorn'; import { createRoutesStub } from 'react-router'; -import type { AuthHelper } from '../../app/auth/auth-helper.server'; -import Login, { action, loader } from '../../app/routes/login'; -import { renderWithEvents } from '../__helpers__/set-up-test'; +import type { AuthHelper } from '../../../app/auth/auth-helper.server'; +import Login, { action, loader } from '../../../app/routes/login'; +import { renderWithEvents } from '../../__helpers__/set-up-test'; describe('login', () => { const login = vi.fn().mockResolvedValue(fromPartial({})); diff --git a/test/routes/logout.test.ts b/test/app/routes/logout.test.ts similarity index 78% rename from test/routes/logout.test.ts rename to test/app/routes/logout.test.ts index 62b0f974..4a4d11da 100644 --- a/test/routes/logout.test.ts +++ b/test/app/routes/logout.test.ts @@ -1,7 +1,7 @@ import { fromPartial } from '@total-typescript/shoehorn'; import type { LoaderFunctionArgs } from 'react-router'; -import type { AuthHelper } from '../../app/auth/auth-helper.server'; -import { loader as logoutLoader } from '../../app/routes/logout'; +import type { AuthHelper } from '../../../app/auth/auth-helper.server'; +import { loader as logoutLoader } from '../../../app/routes/logout'; describe('logout', () => { const logout = vi.fn(); diff --git a/test/routes/profile/ChangePasswordForm.test.tsx b/test/app/routes/profile/ChangePasswordForm.test.tsx similarity index 89% rename from test/routes/profile/ChangePasswordForm.test.tsx rename to test/app/routes/profile/ChangePasswordForm.test.tsx index 6e560767..5dbf2059 100644 --- a/test/routes/profile/ChangePasswordForm.test.tsx +++ b/test/app/routes/profile/ChangePasswordForm.test.tsx @@ -1,8 +1,8 @@ import { render, screen } from '@testing-library/react'; import { fromPartial } from '@total-typescript/shoehorn'; import type { FC, PropsWithChildren, RefAttributes } from 'react'; -import { ChangePasswordForm } from '../../../app/routes/profile/ChangePasswordForm'; -import { checkAccessibility } from '../../__helpers__/accessibility'; +import { ChangePasswordForm } from '../../../../app/routes/profile/ChangePasswordForm'; +import { checkAccessibility } from '../../../__helpers__/accessibility'; describe('', () => { const Form: FC>> = ({ children, ref }) => ( diff --git a/test/routes/profile/EditProfileForm.test.tsx b/test/app/routes/profile/EditProfileForm.test.tsx similarity index 81% rename from test/routes/profile/EditProfileForm.test.tsx rename to test/app/routes/profile/EditProfileForm.test.tsx index af3c3c7c..5079eedc 100644 --- a/test/routes/profile/EditProfileForm.test.tsx +++ b/test/app/routes/profile/EditProfileForm.test.tsx @@ -1,9 +1,9 @@ import { render, screen } from '@testing-library/react'; import { fromPartial } from '@total-typescript/shoehorn'; import type { FC, PropsWithChildren, RefAttributes } from 'react'; -import type { SessionData } from '../../../app/auth/session-context'; -import { EditProfileForm } from '../../../app/routes/profile/EditProfileForm'; -import { checkAccessibility } from '../../__helpers__/accessibility'; +import type { SessionData } from '../../../../app/auth/session-context'; +import { EditProfileForm } from '../../../../app/routes/profile/EditProfileForm'; +import { checkAccessibility } from '../../../__helpers__/accessibility'; describe('', () => { const Form: FC>> = ({ children, ref }) => ( diff --git a/test/routes/profile/ProfileForm.test.tsx b/test/app/routes/profile/ProfileForm.test.tsx similarity index 86% rename from test/routes/profile/ProfileForm.test.tsx rename to test/app/routes/profile/ProfileForm.test.tsx index 6d3388fe..e437abe8 100644 --- a/test/routes/profile/ProfileForm.test.tsx +++ b/test/app/routes/profile/ProfileForm.test.tsx @@ -2,11 +2,11 @@ import { screen } from '@testing-library/react'; import { fromPartial } from '@total-typescript/shoehorn'; import type { FC, PropsWithChildren, RefAttributes } from 'react'; import { useState } from 'react'; -import type { ProfileFormProps } from '../../../app/routes/profile/ProfileForm'; -import { ProfileForm } from '../../../app/routes/profile/ProfileForm'; -import { PROFILE_ACTION } from '../../../app/users/user-profile-actions'; -import { checkAccessibility } from '../../__helpers__/accessibility'; -import { renderWithEvents } from '../../__helpers__/set-up-test'; +import type { ProfileFormProps } from '../../../../app/routes/profile/ProfileForm'; +import { ProfileForm } from '../../../../app/routes/profile/ProfileForm'; +import { PROFILE_ACTION } from '../../../../app/users/user-profile-actions'; +import { checkAccessibility } from '../../../__helpers__/accessibility'; +import { renderWithEvents } from '../../../__helpers__/set-up-test'; type Fetcher = ProfileFormProps['fetcher']; type SetUpOptions = Partial> & { diff --git a/test/routes/profile/change-password-action.server.test.ts b/test/app/routes/profile/change-password-action.server.test.ts similarity index 82% rename from test/routes/profile/change-password-action.server.test.ts rename to test/app/routes/profile/change-password-action.server.test.ts index 9a3df49f..a57cd443 100644 --- a/test/routes/profile/change-password-action.server.test.ts +++ b/test/app/routes/profile/change-password-action.server.test.ts @@ -2,11 +2,11 @@ import { fromPartial } from '@total-typescript/shoehorn'; import { changePasswordAction, INVALID_PASSWORD_FORMAT, -} from '../../../app/routes/profile/change-password-action.server'; -import { IncorrectPasswordError } from '../../../app/users/IncorrectPasswordError.server'; -import { PasswordMismatchError } from '../../../app/users/PasswordMismatchError.server'; -import type { UsersService } from '../../../app/users/UsersService.server'; -import { ValidationError } from '../../../app/validation/ValidationError.server'; +} from '../../../../app/routes/profile/change-password-action.server'; +import { IncorrectPasswordError } from '../../../../app/users/IncorrectPasswordError.server'; +import { PasswordMismatchError } from '../../../../app/users/PasswordMismatchError.server'; +import type { UsersService } from '../../../../app/users/UsersService.server'; +import { ValidationError } from '../../../../app/validation/ValidationError.server'; describe('change-password-action', () => { const editUserPassword = vi.fn(); diff --git a/test/routes/profile/edit-profile-action.server.test.ts b/test/app/routes/profile/edit-profile-action.server.test.ts similarity index 68% rename from test/routes/profile/edit-profile-action.server.test.ts rename to test/app/routes/profile/edit-profile-action.server.test.ts index ab126f99..41b4acb7 100644 --- a/test/routes/profile/edit-profile-action.server.test.ts +++ b/test/app/routes/profile/edit-profile-action.server.test.ts @@ -1,8 +1,8 @@ import { fromPartial } from '@total-typescript/shoehorn'; import { expect } from 'vitest'; -import type { User } from '../../../app/entities/User'; -import { editProfileAction } from '../../../app/routes/profile/edit-profile-action.server'; -import type { UsersService } from '../../../app/users/UsersService.server'; +import type { User } from '../../../../app/entities/User'; +import { editProfileAction } from '../../../../app/routes/profile/edit-profile-action.server'; +import type { UsersService } from '../../../../app/users/UsersService.server'; describe('edit-profile-action', () => { const editUser = vi.fn(); diff --git a/test/routes/profile/profile.test.tsx b/test/app/routes/profile/profile.test.tsx similarity index 88% rename from test/routes/profile/profile.test.tsx rename to test/app/routes/profile/profile.test.tsx index 626d949d..25768159 100644 --- a/test/routes/profile/profile.test.tsx +++ b/test/app/routes/profile/profile.test.tsx @@ -2,12 +2,12 @@ import { render, screen } from '@testing-library/react'; import { fromPartial } from '@total-typescript/shoehorn'; import type { UNSAFE_DataWithResponseInit } from 'react-router'; import { createRoutesStub } from 'react-router'; -import type { AuthHelper } from '../../../app/auth/auth-helper.server'; -import { SessionProvider } from '../../../app/auth/session-context'; -import type { User } from '../../../app/entities/User'; -import Profile, { action } from '../../../app/routes/profile/profile'; -import { CHANGE_PASSWORD_ACTION, PROFILE_ACTION } from '../../../app/users/user-profile-actions'; -import type { UsersService } from '../../../app/users/UsersService.server'; +import type { AuthHelper } from '../../../../app/auth/auth-helper.server'; +import { SessionProvider } from '../../../../app/auth/session-context'; +import type { User } from '../../../../app/entities/User'; +import Profile, { action } from '../../../../app/routes/profile/profile'; +import { CHANGE_PASSWORD_ACTION, PROFILE_ACTION } from '../../../../app/users/user-profile-actions'; +import type { UsersService } from '../../../../app/users/UsersService.server'; describe('profile', () => { describe('action', () => { diff --git a/test/routes/save-tags-colors.test.ts b/test/app/routes/save-tags-colors.test.ts similarity index 87% rename from test/routes/save-tags-colors.test.ts rename to test/app/routes/save-tags-colors.test.ts index dd19961c..2adba6b0 100644 --- a/test/routes/save-tags-colors.test.ts +++ b/test/app/routes/save-tags-colors.test.ts @@ -1,8 +1,8 @@ import { fromPartial } from '@total-typescript/shoehorn'; import type { ActionFunctionArgs } from 'react-router'; -import type { AuthHelper } from '../../app/auth/auth-helper.server'; -import { action } from '../../app/routes/save-tags-colors'; -import type { TagsService } from '../../app/tags/TagsService.server'; +import type { AuthHelper } from '../../../app/auth/auth-helper.server'; +import { action } from '../../../app/routes/save-tags-colors'; +import type { TagsService } from '../../../app/tags/TagsService.server'; describe('save-tags-colors', () => { const updateTagColors = vi.fn(); diff --git a/test/routes/servers/DeleteServerModal.test.tsx b/test/app/routes/servers/DeleteServerModal.test.tsx similarity index 85% rename from test/routes/servers/DeleteServerModal.test.tsx rename to test/app/routes/servers/DeleteServerModal.test.tsx index 20045db6..d2480c15 100644 --- a/test/routes/servers/DeleteServerModal.test.tsx +++ b/test/app/routes/servers/DeleteServerModal.test.tsx @@ -1,10 +1,10 @@ import { screen } from '@testing-library/react'; import { fromPartial } from '@total-typescript/shoehorn'; import { createRoutesStub } from 'react-router'; -import { type PlainServer } from '../../../app/entities/Server'; -import { DeleteServerModal } from '../../../app/routes/servers/DeleteServerModal'; -import { checkAccessibility } from '../../__helpers__/accessibility'; -import { renderWithEvents } from '../../__helpers__/set-up-test'; +import { type PlainServer } from '../../../../app/entities/Server'; +import { DeleteServerModal } from '../../../../app/routes/servers/DeleteServerModal'; +import { checkAccessibility } from '../../../__helpers__/accessibility'; +import { renderWithEvents } from '../../../__helpers__/set-up-test'; describe('', () => { const onClose = vi.fn(); diff --git a/test/routes/servers/ServerFormFields.test.tsx b/test/app/routes/servers/ServerFormFields.test.tsx similarity index 86% rename from test/routes/servers/ServerFormFields.test.tsx rename to test/app/routes/servers/ServerFormFields.test.tsx index 3a14bded..cfc697a1 100644 --- a/test/routes/servers/ServerFormFields.test.tsx +++ b/test/app/routes/servers/ServerFormFields.test.tsx @@ -1,9 +1,9 @@ import { render, screen } from '@testing-library/react'; import { fromPartial } from '@total-typescript/shoehorn'; import { MemoryRouter } from 'react-router'; -import type { ServerFormFieldsProps } from '../../../app/routes/servers/ServerFormFields'; -import { ServerFormFields } from '../../../app/routes/servers/ServerFormFields'; -import { checkAccessibility } from '../../__helpers__/accessibility'; +import type { ServerFormFieldsProps } from '../../../../app/routes/servers/ServerFormFields'; +import { ServerFormFields } from '../../../../app/routes/servers/ServerFormFields'; +import { checkAccessibility } from '../../../__helpers__/accessibility'; describe('', () => { const setUp = (props: Partial = {}) => render( diff --git a/test/routes/servers/create-server.test.tsx b/test/app/routes/servers/create-server.test.tsx similarity index 88% rename from test/routes/servers/create-server.test.tsx rename to test/app/routes/servers/create-server.test.tsx index cb84f1e9..3eaf174e 100644 --- a/test/routes/servers/create-server.test.tsx +++ b/test/app/routes/servers/create-server.test.tsx @@ -1,10 +1,10 @@ import { screen, waitFor } from '@testing-library/react'; import { fromPartial } from '@total-typescript/shoehorn'; import { createRoutesStub } from 'react-router'; -import CreateServer, { action } from '../../../app/routes/servers/create-server'; -import type { ServersService } from '../../../app/servers/ServersService.server'; -import { checkAccessibility } from '../../__helpers__/accessibility'; -import { renderWithEvents } from '../../__helpers__/set-up-test'; +import CreateServer, { action } from '../../../../app/routes/servers/create-server'; +import type { ServersService } from '../../../../app/servers/ServersService.server'; +import { checkAccessibility } from '../../../__helpers__/accessibility'; +import { renderWithEvents } from '../../../__helpers__/set-up-test'; describe('create-server', () => { describe('action', () => { diff --git a/test/routes/servers/delete-server.test.ts b/test/app/routes/servers/delete-server.test.ts similarity index 81% rename from test/routes/servers/delete-server.test.ts rename to test/app/routes/servers/delete-server.test.ts index a7941428..b7c2a358 100644 --- a/test/routes/servers/delete-server.test.ts +++ b/test/app/routes/servers/delete-server.test.ts @@ -1,6 +1,6 @@ import { fromPartial } from '@total-typescript/shoehorn'; -import { action } from '../../../app/routes/servers/delete-server'; -import type { ServersService } from '../../../app/servers/ServersService.server'; +import { action } from '../../../../app/routes/servers/delete-server'; +import type { ServersService } from '../../../../app/servers/ServersService.server'; describe('delete-server', () => { describe('action', () => { diff --git a/test/routes/servers/edit-server.test.tsx b/test/app/routes/servers/edit-server.test.tsx similarity index 86% rename from test/routes/servers/edit-server.test.tsx rename to test/app/routes/servers/edit-server.test.tsx index 3304d160..18eb008d 100644 --- a/test/routes/servers/edit-server.test.tsx +++ b/test/app/routes/servers/edit-server.test.tsx @@ -1,12 +1,12 @@ import { screen } from '@testing-library/react'; import { fromPartial } from '@total-typescript/shoehorn'; import { createRoutesStub } from 'react-router'; -import type { Server } from '../../../app/entities/Server'; -import EditServer, { action, loader } from '../../../app/routes/servers/edit-server'; -import type { ServersService } from '../../../app/servers/ServersService.server'; -import { NotFoundError } from '../../../app/validation/NotFoundError.server'; -import { checkAccessibility } from '../../__helpers__/accessibility'; -import { renderWithEvents } from '../../__helpers__/set-up-test'; +import type { Server } from '../../../../app/entities/Server'; +import EditServer, { action, loader } from '../../../../app/routes/servers/edit-server'; +import type { ServersService } from '../../../../app/servers/ServersService.server'; +import { NotFoundError } from '../../../../app/validation/NotFoundError.server'; +import { checkAccessibility } from '../../../__helpers__/accessibility'; +import { renderWithEvents } from '../../../__helpers__/set-up-test'; describe('edit-server', () => { const getByPublicIdAndUser = vi.fn(); diff --git a/test/routes/servers/list-servers.test.tsx b/test/app/routes/servers/list-servers.test.tsx similarity index 93% rename from test/routes/servers/list-servers.test.tsx rename to test/app/routes/servers/list-servers.test.tsx index c2775f71..829585a1 100644 --- a/test/routes/servers/list-servers.test.tsx +++ b/test/app/routes/servers/list-servers.test.tsx @@ -2,13 +2,13 @@ import { Collection } from '@mikro-orm/core'; import { screen, waitFor } from '@testing-library/react'; import { fromPartial } from '@total-typescript/shoehorn'; import { createRoutesStub } from 'react-router'; -import type { SessionData } from '../../../app/auth/session-context'; -import { SessionProvider } from '../../../app/auth/session-context'; -import type { PlainServer, Server } from '../../../app/entities/Server'; -import type { Role, User } from '../../../app/entities/User'; -import ListServers, { loader } from '../../../app/routes/servers/list-servers'; -import type { ServersService } from '../../../app/servers/ServersService.server'; -import { renderWithEvents } from '../../__helpers__/set-up-test'; +import type { SessionData } from '../../../../app/auth/session-context'; +import { SessionProvider } from '../../../../app/auth/session-context'; +import type { PlainServer, Server } from '../../../../app/entities/Server'; +import type { Role, User } from '../../../../app/entities/User'; +import ListServers, { loader } from '../../../../app/routes/servers/list-servers'; +import type { ServersService } from '../../../../app/servers/ServersService.server'; +import { renderWithEvents } from '../../../__helpers__/set-up-test'; // Mock the useNavigate hook so that we can test programmatic navigations const navigate = vi.fn(); diff --git a/test/routes/settings.test.tsx b/test/app/routes/settings.test.tsx similarity index 93% rename from test/routes/settings.test.tsx rename to test/app/routes/settings.test.tsx index 9e5725ad..e3a187cc 100644 --- a/test/routes/settings.test.tsx +++ b/test/app/routes/settings.test.tsx @@ -3,9 +3,9 @@ import { render, screen, waitFor } from '@testing-library/react'; import { fromPartial } from '@total-typescript/shoehorn'; import type { ActionFunctionArgs } from 'react-router'; import { createRoutesStub } from 'react-router'; -import type { AuthHelper } from '../../app/auth/auth-helper.server'; -import SettingsComp, { action as settingsAction, loader } from '../../app/routes/settings'; -import type { SettingsService } from '../../app/settings/SettingsService.server'; +import type { AuthHelper } from '../../../app/auth/auth-helper.server'; +import SettingsComp, { action as settingsAction, loader } from '../../../app/routes/settings'; +import type { SettingsService } from '../../../app/settings/SettingsService.server'; describe('settings', () => { const getSession = vi.fn(); diff --git a/test/routes/shlink-api-rpc-proxy.test.ts b/test/app/routes/shlink-api-rpc-proxy.test.ts similarity index 96% rename from test/routes/shlink-api-rpc-proxy.test.ts rename to test/app/routes/shlink-api-rpc-proxy.test.ts index eb7c513d..76686e55 100644 --- a/test/routes/shlink-api-rpc-proxy.test.ts +++ b/test/app/routes/shlink-api-rpc-proxy.test.ts @@ -2,9 +2,9 @@ import type { ShlinkApiClient } from '@shlinkio/shlink-js-sdk/api-contract'; import { ErrorType } from '@shlinkio/shlink-js-sdk/api-contract'; import { fromPartial } from '@total-typescript/shoehorn'; import type { ActionFunctionArgs } from 'react-router'; -import type { AuthHelper } from '../../app/auth/auth-helper.server'; -import { action } from '../../app/routes/shlink-api-rpc-proxy'; -import type { ServersService } from '../../app/servers/ServersService.server'; +import type { AuthHelper } from '../../../app/auth/auth-helper.server'; +import { action } from '../../../app/routes/shlink-api-rpc-proxy'; +import type { ServersService } from '../../../app/servers/ServersService.server'; describe('shlink-api-rpc-proxy', () => { const getByPublicIdAndUser = vi.fn(); diff --git a/test/routes/users/DeleteUserModal.test.tsx b/test/app/routes/users/DeleteUserModal.test.tsx similarity index 85% rename from test/routes/users/DeleteUserModal.test.tsx rename to test/app/routes/users/DeleteUserModal.test.tsx index 9e02fb04..54c3c4d1 100644 --- a/test/routes/users/DeleteUserModal.test.tsx +++ b/test/app/routes/users/DeleteUserModal.test.tsx @@ -1,10 +1,10 @@ import { screen } from '@testing-library/react'; import { fromPartial } from '@total-typescript/shoehorn'; import { createRoutesStub } from 'react-router'; -import type { User } from '../../../app/entities/User'; -import { DeleteUserModal } from '../../../app/routes/users/DeleteUserModal'; -import { checkAccessibility } from '../../__helpers__/accessibility'; -import { renderWithEvents } from '../../__helpers__/set-up-test'; +import type { User } from '../../../../app/entities/User'; +import { DeleteUserModal } from '../../../../app/routes/users/DeleteUserModal'; +import { checkAccessibility } from '../../../__helpers__/accessibility'; +import { renderWithEvents } from '../../../__helpers__/set-up-test'; describe('', () => { const onClose = vi.fn(); diff --git a/test/routes/users/RoleBadge.test.tsx b/test/app/routes/users/RoleBadge.test.tsx similarity index 72% rename from test/routes/users/RoleBadge.test.tsx rename to test/app/routes/users/RoleBadge.test.tsx index 079c9ebf..f03fff76 100644 --- a/test/routes/users/RoleBadge.test.tsx +++ b/test/app/routes/users/RoleBadge.test.tsx @@ -1,7 +1,7 @@ import { render } from '@testing-library/react'; -import type { Role } from '../../../app/entities/User'; -import { RoleBadge } from '../../../app/routes/users/RoleBadge'; -import { checkAccessibility } from '../../__helpers__/accessibility'; +import type { Role } from '../../../../app/entities/User'; +import { RoleBadge } from '../../../../app/routes/users/RoleBadge'; +import { checkAccessibility } from '../../../__helpers__/accessibility'; describe('', () => { const setUp = (role: Role) => render(); diff --git a/test/routes/users/UserFormFields.test.tsx b/test/app/routes/users/UserFormFields.test.tsx similarity index 79% rename from test/routes/users/UserFormFields.test.tsx rename to test/app/routes/users/UserFormFields.test.tsx index cc22d9c3..732057c5 100644 --- a/test/routes/users/UserFormFields.test.tsx +++ b/test/app/routes/users/UserFormFields.test.tsx @@ -1,11 +1,11 @@ import { screen } from '@testing-library/react'; import { fromPartial } from '@total-typescript/shoehorn'; import { MemoryRouter } from 'react-router'; -import type { User } from '../../../app/entities/User'; -import type { UserFormFieldsProps } from '../../../app/routes/users/UserFormFields'; -import { UserFormFields } from '../../../app/routes/users/UserFormFields'; -import { checkAccessibility } from '../../__helpers__/accessibility'; -import { renderWithEvents } from '../../__helpers__/set-up-test'; +import type { User } from '../../../../app/entities/User'; +import type { UserFormFieldsProps } from '../../../../app/routes/users/UserFormFields'; +import { UserFormFields } from '../../../../app/routes/users/UserFormFields'; +import { checkAccessibility } from '../../../__helpers__/accessibility'; +import { renderWithEvents } from '../../../__helpers__/set-up-test'; describe('', () => { const setUp = (props: Partial = {}) => renderWithEvents( diff --git a/test/routes/users/UserServers.test.tsx b/test/app/routes/users/UserServers.test.tsx similarity index 91% rename from test/routes/users/UserServers.test.tsx rename to test/app/routes/users/UserServers.test.tsx index 717c1563..99d1795b 100644 --- a/test/routes/users/UserServers.test.tsx +++ b/test/app/routes/users/UserServers.test.tsx @@ -1,9 +1,9 @@ import { screen } from '@testing-library/react'; import { fromPartial } from '@total-typescript/shoehorn'; -import type { MinimalServer, UserServersProps } from '../../../app/routes/users/UserServers'; -import { UserServers } from '../../../app/routes/users/UserServers'; -import { checkAccessibility } from '../../__helpers__/accessibility'; -import { renderWithEvents } from '../../__helpers__/set-up-test'; +import type { MinimalServer, UserServersProps } from '../../../../app/routes/users/UserServers'; +import { UserServers } from '../../../../app/routes/users/UserServers'; +import { checkAccessibility } from '../../../__helpers__/accessibility'; +import { renderWithEvents } from '../../../__helpers__/set-up-test'; describe('', () => { const onSearch = vi.fn(); diff --git a/test/routes/users/__snapshots__/RoleBadge.test.tsx.snap b/test/app/routes/users/__snapshots__/RoleBadge.test.tsx.snap similarity index 100% rename from test/routes/users/__snapshots__/RoleBadge.test.tsx.snap rename to test/app/routes/users/__snapshots__/RoleBadge.test.tsx.snap diff --git a/test/routes/users/create-user.test.tsx b/test/app/routes/users/create-user.test.tsx similarity index 90% rename from test/routes/users/create-user.test.tsx rename to test/app/routes/users/create-user.test.tsx index 05468620..0019af05 100644 --- a/test/routes/users/create-user.test.tsx +++ b/test/app/routes/users/create-user.test.tsx @@ -2,12 +2,12 @@ import { screen, waitFor } from '@testing-library/react'; import type { UserEvent } from '@testing-library/user-event'; import { fromPartial } from '@total-typescript/shoehorn'; import { createRoutesStub } from 'react-router'; -import CreateUser, { action } from '../../../app/routes/users/create-user'; -import type { UsersService } from '../../../app/users/UsersService.server'; -import { DuplicatedEntryError } from '../../../app/validation/DuplicatedEntryError.server'; -import { ValidationError } from '../../../app/validation/ValidationError.server'; -import { checkAccessibility } from '../../__helpers__/accessibility'; -import { renderWithEvents } from '../../__helpers__/set-up-test'; +import CreateUser, { action } from '../../../../app/routes/users/create-user'; +import type { UsersService } from '../../../../app/users/UsersService.server'; +import { DuplicatedEntryError } from '../../../../app/validation/DuplicatedEntryError.server'; +import { ValidationError } from '../../../../app/validation/ValidationError.server'; +import { checkAccessibility } from '../../../__helpers__/accessibility'; +import { renderWithEvents } from '../../../__helpers__/set-up-test'; describe('create-user', () => { describe('action', () => { diff --git a/test/routes/users/delete-user.test.ts b/test/app/routes/users/delete-user.test.ts similarity index 81% rename from test/routes/users/delete-user.test.ts rename to test/app/routes/users/delete-user.test.ts index edfe0f61..49f83c84 100644 --- a/test/routes/users/delete-user.test.ts +++ b/test/app/routes/users/delete-user.test.ts @@ -1,6 +1,6 @@ import { fromPartial } from '@total-typescript/shoehorn'; -import { action } from '../../../app/routes/users/delete-user'; -import type { UsersService } from '../../../app/users/UsersService.server'; +import { action } from '../../../../app/routes/users/delete-user'; +import type { UsersService } from '../../../../app/users/UsersService.server'; describe('delete-user', () => { describe('action', () => { diff --git a/test/routes/users/edit-user-servers.test.tsx b/test/app/routes/users/edit-user-servers.test.tsx similarity index 90% rename from test/routes/users/edit-user-servers.test.tsx rename to test/app/routes/users/edit-user-servers.test.tsx index 62d4dacf..1ce67ca2 100644 --- a/test/routes/users/edit-user-servers.test.tsx +++ b/test/app/routes/users/edit-user-servers.test.tsx @@ -1,11 +1,11 @@ import { screen, waitFor } from '@testing-library/react'; import { fromPartial } from '@total-typescript/shoehorn'; import { createRoutesStub } from 'react-router'; -import type { User } from '../../../app/entities/User'; -import EditUserServers, { action, loader } from '../../../app/routes/users/edit-user-servers'; -import type { ServersService } from '../../../app/servers/ServersService.server'; -import type { UsersService } from '../../../app/users/UsersService.server'; -import { renderWithEvents } from '../../__helpers__/set-up-test'; +import type { User } from '../../../../app/entities/User'; +import EditUserServers, { action, loader } from '../../../../app/routes/users/edit-user-servers'; +import type { ServersService } from '../../../../app/servers/ServersService.server'; +import type { UsersService } from '../../../../app/users/UsersService.server'; +import { renderWithEvents } from '../../../__helpers__/set-up-test'; describe('edit-user-servers', () => { const getUserServers= vi.fn().mockResolvedValue([]); diff --git a/test/routes/users/edit-user.test.tsx b/test/app/routes/users/edit-user.test.tsx similarity index 88% rename from test/routes/users/edit-user.test.tsx rename to test/app/routes/users/edit-user.test.tsx index 5ea89cb0..11c1afc0 100644 --- a/test/routes/users/edit-user.test.tsx +++ b/test/app/routes/users/edit-user.test.tsx @@ -2,12 +2,12 @@ import { screen } from '@testing-library/react'; import { fromPartial } from '@total-typescript/shoehorn'; import type { ActionFunctionArgs, LoaderFunctionArgs } from 'react-router'; import { createRoutesStub } from 'react-router'; -import type { User } from '../../../app/entities/User'; -import EditUser, { action, loader } from '../../../app/routes/users/edit-user'; -import type { UsersService } from '../../../app/users/UsersService.server'; -import { NotFoundError } from '../../../app/validation/NotFoundError.server'; -import { checkAccessibility } from '../../__helpers__/accessibility'; -import { renderWithEvents } from '../../__helpers__/set-up-test'; +import type { User } from '../../../../app/entities/User'; +import EditUser, { action, loader } from '../../../../app/routes/users/edit-user'; +import type { UsersService } from '../../../../app/users/UsersService.server'; +import { NotFoundError } from '../../../../app/validation/NotFoundError.server'; +import { checkAccessibility } from '../../../__helpers__/accessibility'; +import { renderWithEvents } from '../../../__helpers__/set-up-test'; describe('edit-user', () => { const getUserById = vi.fn(); diff --git a/test/routes/users/list-users.test.tsx b/test/app/routes/users/list-users.test.tsx similarity index 96% rename from test/routes/users/list-users.test.tsx rename to test/app/routes/users/list-users.test.tsx index 1888a81d..629c31d0 100644 --- a/test/routes/users/list-users.test.tsx +++ b/test/app/routes/users/list-users.test.tsx @@ -4,12 +4,12 @@ import type { UserEvent } from '@testing-library/user-event'; import { fromPartial } from '@total-typescript/shoehorn'; import type { LoaderFunctionArgs } from 'react-router'; import { createRoutesStub } from 'react-router'; -import { SessionProvider } from '../../../app/auth/session-context'; -import type { User } from '../../../app/entities/User'; -import ListUsers, { loader } from '../../../app/routes/users/list-users'; -import type { UserOrderableFields, UsersService } from '../../../app/users/UsersService.server'; -import { checkAccessibility } from '../../__helpers__/accessibility'; -import { renderWithEvents } from '../../__helpers__/set-up-test'; +import { SessionProvider } from '../../../../app/auth/session-context'; +import type { User } from '../../../../app/entities/User'; +import ListUsers, { loader } from '../../../../app/routes/users/list-users'; +import type { UserOrderableFields, UsersService } from '../../../../app/users/UsersService.server'; +import { checkAccessibility } from '../../../__helpers__/accessibility'; +import { renderWithEvents } from '../../../__helpers__/set-up-test'; // Mock the useNavigate hook so that we can test programmatic navigations const navigate = vi.fn(); diff --git a/test/routes/users/reset-user-password.test.tsx b/test/app/routes/users/reset-user-password.test.tsx similarity index 90% rename from test/routes/users/reset-user-password.test.tsx rename to test/app/routes/users/reset-user-password.test.tsx index 000a202b..595c267a 100644 --- a/test/routes/users/reset-user-password.test.tsx +++ b/test/app/routes/users/reset-user-password.test.tsx @@ -1,11 +1,11 @@ import { screen, waitFor } from '@testing-library/react'; import { fromPartial } from '@total-typescript/shoehorn'; import { createRoutesStub } from 'react-router'; -import type { User } from '../../../app/entities/User'; -import ResetUserPassword, { action, loader } from '../../../app/routes/users/reset-user-password'; -import type { UsersService } from '../../../app/users/UsersService.server'; -import { checkAccessibility } from '../../__helpers__/accessibility'; -import { renderWithEvents } from '../../__helpers__/set-up-test'; +import type { User } from '../../../../app/entities/User'; +import ResetUserPassword, { action, loader } from '../../../../app/routes/users/reset-user-password'; +import type { UsersService } from '../../../../app/users/UsersService.server'; +import { checkAccessibility } from '../../../__helpers__/accessibility'; +import { renderWithEvents } from '../../../__helpers__/set-up-test'; describe('reset-user-password', () => { const getUserById = vi.fn(); diff --git a/test/servers/ServersService.server.test.ts b/test/app/servers/ServersService.server.test.ts similarity index 92% rename from test/servers/ServersService.server.test.ts rename to test/app/servers/ServersService.server.test.ts index f935a9cb..7946fc4c 100644 --- a/test/servers/ServersService.server.test.ts +++ b/test/app/servers/ServersService.server.test.ts @@ -1,10 +1,10 @@ import { fromPartial } from '@total-typescript/shoehorn'; -import type { Server } from '../../app/entities/Server'; -import type { FindServersOptions, ServersRepository } from '../../app/servers/ServersRepository.server'; -import type { ListServersOptions } from '../../app/servers/ServersService.server'; -import { ServersService } from '../../app/servers/ServersService.server'; -import { NotFoundError } from '../../app/validation/NotFoundError.server'; -import { createFormData } from '../__helpers__/utils'; +import type { Server } from '../../../app/entities/Server'; +import type { FindServersOptions, ServersRepository } from '../../../app/servers/ServersRepository.server'; +import type { ListServersOptions } from '../../../app/servers/ServersService.server'; +import { ServersService } from '../../../app/servers/ServersService.server'; +import { NotFoundError } from '../../../app/validation/NotFoundError.server'; +import { createFormData } from '../../__helpers__/utils'; describe('ServersService', () => { const findByPublicIdAndUserId = vi.fn(); diff --git a/test/settings/SettingsService.server.test.ts b/test/app/settings/SettingsService.server.test.ts similarity index 89% rename from test/settings/SettingsService.server.test.ts rename to test/app/settings/SettingsService.server.test.ts index 6bf830ce..886d2165 100644 --- a/test/settings/SettingsService.server.test.ts +++ b/test/app/settings/SettingsService.server.test.ts @@ -1,11 +1,11 @@ import type { EntityManager } from '@mikro-orm/core'; import type { Settings as ShlinkSettingsConfig } from '@shlinkio/shlink-web-component/settings'; import { fromPartial } from '@total-typescript/shoehorn'; -import type { Settings } from '../../app/entities/Settings'; -import { Settings as SettingsEntity } from '../../app/entities/Settings'; -import type { User } from '../../app/entities/User'; -import { User as UserEntity } from '../../app/entities/User'; -import { SettingsService } from '../../app/settings/SettingsService.server'; +import type { Settings } from '../../../app/entities/Settings'; +import { Settings as SettingsEntity } from '../../../app/entities/Settings'; +import type { User } from '../../../app/entities/User'; +import { User as UserEntity } from '../../../app/entities/User'; +import { SettingsService } from '../../../app/settings/SettingsService.server'; describe('SettingsService', () => { const findOne = vi.fn(); diff --git a/test/tags/TagStorage.client.test.ts b/test/app/tags/TagStorage.client.test.ts similarity index 95% rename from test/tags/TagStorage.client.test.ts rename to test/app/tags/TagStorage.client.test.ts index 5946529d..024a3a3a 100644 --- a/test/tags/TagStorage.client.test.ts +++ b/test/app/tags/TagStorage.client.test.ts @@ -1,4 +1,4 @@ -import { TagsStorage } from '../../app/tags/TagsStorage.client'; +import { TagsStorage } from '../../../app/tags/TagsStorage.client'; describe('TagsStorage', () => { const fetch = vi.fn().mockResolvedValue(undefined); diff --git a/test/tags/TagsService.server.test.ts b/test/app/tags/TagsService.server.test.ts similarity index 89% rename from test/tags/TagsService.server.test.ts rename to test/app/tags/TagsService.server.test.ts index 758aea28..d724c6dd 100644 --- a/test/tags/TagsService.server.test.ts +++ b/test/app/tags/TagsService.server.test.ts @@ -1,12 +1,12 @@ import type { EntityManager } from '@mikro-orm/core'; import { fromPartial } from '@total-typescript/shoehorn'; -import type { Server } from '../../app/entities/Server'; -import type { Tag } from '../../app/entities/Tag'; -import { Tag as TagEntity } from '../../app/entities/Tag'; -import type { User } from '../../app/entities/User'; -import { User as UserEntity } from '../../app/entities/User'; -import type { ServersService } from '../../app/servers/ServersService.server'; -import { TagsService } from '../../app/tags/TagsService.server'; +import type { Server } from '../../../app/entities/Server'; +import type { Tag } from '../../../app/entities/Tag'; +import { Tag as TagEntity } from '../../../app/entities/Tag'; +import type { User } from '../../../app/entities/User'; +import { User as UserEntity } from '../../../app/entities/User'; +import type { ServersService } from '../../../app/servers/ServersService.server'; +import { TagsService } from '../../../app/tags/TagsService.server'; describe('TagsService', () => { const find = vi.fn(); diff --git a/test/users/UsersService.server.test.ts b/test/app/users/UsersService.server.test.ts similarity index 95% rename from test/users/UsersService.server.test.ts rename to test/app/users/UsersService.server.test.ts index 83a11120..1f9dff37 100644 --- a/test/users/UsersService.server.test.ts +++ b/test/app/users/UsersService.server.test.ts @@ -1,13 +1,13 @@ import { UniqueConstraintViolationException } from '@mikro-orm/core'; import { fromPartial } from '@total-typescript/shoehorn'; -import { hashPassword, verifyPassword } from '../../app/auth/passwords.server'; -import type { User } from '../../app/entities/User'; -import { IncorrectPasswordError } from '../../app/users/IncorrectPasswordError.server'; -import type { UsersRepository } from '../../app/users/UsersRepository.server'; -import { UsersService } from '../../app/users/UsersService.server'; -import { DuplicatedEntryError } from '../../app/validation/DuplicatedEntryError.server'; -import { NotFoundError } from '../../app/validation/NotFoundError.server'; -import { createFormData } from '../__helpers__/utils'; +import { hashPassword, verifyPassword } from '../../../app/auth/passwords.server'; +import type { User } from '../../../app/entities/User'; +import { IncorrectPasswordError } from '../../../app/users/IncorrectPasswordError.server'; +import type { UsersRepository } from '../../../app/users/UsersRepository.server'; +import { UsersService } from '../../../app/users/UsersService.server'; +import { DuplicatedEntryError } from '../../../app/validation/DuplicatedEntryError.server'; +import { NotFoundError } from '../../../app/validation/NotFoundError.server'; +import { createFormData } from '../../__helpers__/utils'; describe('UsersService', () => { const findOne = vi.fn(); From 00a9a060044b2de91046e3afaa7adc9f7fcd8c87 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Wed, 20 Aug 2025 08:41:17 +0200 Subject: [PATCH 3/3] Move built src to node modules as if it was an external package --- Dockerfile | 1 + scripts/create-dist-file.ts | 3 +++ tsconfig.build-server.json | 6 ++++-- vite.config.ts | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index e44ee17d..12d3834e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,6 +25,7 @@ COPY README.md /shlink-dashboard/README.md WORKDIR /shlink-dashboard RUN npm ci --omit dev && npm cache clean --force +RUN mv src node_modules/@shlinkio/dashboard-server RUN mkdir data && chown $UID:0 data # Install tini diff --git a/scripts/create-dist-file.ts b/scripts/create-dist-file.ts index 2910b11b..8fb4813d 100644 --- a/scripts/create-dist-file.ts +++ b/scripts/create-dist-file.ts @@ -29,6 +29,9 @@ try { // Install prod dependencies inside build dir execSync('npm ci --omit=dev', { cwd: './build' }); + // Move bundled src to node_modules, so that it is treated as an external package + fs.renameSync('./build/src', './build/node_modules/@shlinkio/dashboard-server'); + zip.addLocalFolder('./build', fileBaseName); zip.writeZip(versionFileName); console.log(chalk.green('Dist file properly generated')); diff --git a/tsconfig.build-server.json b/tsconfig.build-server.json index 609b0709..53741ac2 100644 --- a/tsconfig.build-server.json +++ b/tsconfig.build-server.json @@ -1,8 +1,10 @@ { "extends": "./tsconfig.json", - "include": ["./server.ts"], + "include": ["./server.ts", "src"], "compilerOptions": { "noEmit": false, - "outDir": "./build" + "outDir": "./build", + "moduleResolution": "NodeNext", + "module": "NodeNext" } } diff --git a/vite.config.ts b/vite.config.ts index 1697adcd..ba29429e 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -15,7 +15,7 @@ export default defineConfig({ target: 'esnext', rollupOptions: { // @shlinkio/dashboard-server (src) is bundled separately as its own package - external: ['@shlinkio/dashboard-server', '@shlinkio/dashboard-server/*'], + external: [/^@shlinkio\/dashboard-server(\/.*)?$/], }, },