Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/raceliciouss/YUSEN-LIMO-WAREHOUSE/llms.txt

Use this file to discover all available pages before exploring further.

The tests/auth.test.js file contains a self-contained unit test suite that exercises every public method of AuthService — the authentication and user management module defined in assets/auth.js. Because the harness constructs its own in-memory LocalStorage mock and loads auth.js into an isolated Node.js vm context, no browser, no DOM, and no real LocalStorage are required. The tests run entirely in Node.js and complete synchronously.

Running the Tests

node tests/auth.test.js
Expected output on a clean run:
Auth service tests passed.
Node.js’s built-in assert module is used for all assertions. A failing assertion throws an AssertionError with the test’s description string, terminates the process with a non-zero exit code, and prints the error to stderr — making the suite compatible with CI pipelines without any additional test runner.

How the Test Harness Works

The harness uses only Node.js built-in modules — assert, fs, path, and vm — so there are no dependencies to install. In-memory LocalStorage mock — A plain JavaScript object (storage) acts as the backing store. The harness wraps it in createStorage(), which returns an object with getItem, setItem, and removeItem methods matching the localStorage interface. This mock is injected into the vm context as localStorage. Isolated vm contextauth.js is read from disk with fs.readFileSync and executed inside a context created by vm.createContext(). The context exposes console, localStorage, window, and globalThis. Because auth.js wraps its entire body in an IIFE that targets window or globalThis as the global, AuthService surfaces on the context object after execution and is extracted as context.AuthService. resetStorage() helper — Between test groups, the harness calls resetStorage(), which deletes every key from the backing storage object and then replaces context.localStorage, context.window.localStorage, and context.globalThis.localStorage with a fresh mock instance. This guarantees that each group starts with no pre-existing accounts or session data. Synchronous execution — All AuthService methods are synchronous. There are no Promises, timers, or async callbacks involved, so every assertion follows immediately after the call it checks.

What Is Tested

The suite covers all public AuthService methods in a sequence that mirrors realistic usage:
AreaWhat is asserted
Account seedingAuthService.initializeAuth() returns an array that includes an account with userId === 'admin001'
Valid loginauthenticateUser('admin001', 'Admin@123') returns { success: true } with role === 'admin'
Password changechangePassword('Admin@123', 'NewAdmin@123') succeeds; subsequent login with NewAdmin@123 succeeds; login with Admin@123 returns success: false
Re-initialization preserves passwordCalling initializeAuth() again returns the account with the updated password, not the hardcoded seed value
Create usercreateUser({ employeeId: 'EMP-002', ... }) returns success: true; the account is retrievable via getAccounts() with the correct role
Duplicate employee IDA second createUser call using the same employeeId: 'EMP-002' returns success: false
Login timestampAfter a successful authenticateUser call, getAccounts() shows a non-null lastLogin on the account
Password resetresetPassword('emp002') succeeds and sets the stored password to 'Password123' (the DEFAULT_PASSWORD constant in auth.js)
Status toggletoggleUserStatus('emp002') returns success: true; the account’s status flips from 'active' to 'inactive'
Update userupdateUser('emp002', { name: 'Jane Smith', role: 'employee' }) succeeds; getAccounts() reflects the new name
Self role-change protectionupdateUser('admin001', { role: 'employee' }) while logged in as admin001 returns success: false
Delete userdeleteUser('emp002') succeeds; getAccounts() no longer contains the account
Delete last admin blockeddeleteUser('admin001') when admin001 is the only remaining admin returns success: false
Invalid credentials — unknown userauthenticateUser('unknown', '123') returns { success: false, message: 'Invalid User ID.' }
Invalid credentials — wrong passwordauthenticateUser('emp001', 'wrong') returns { success: false, message: 'Incorrect password.' }
Invalid credentials — empty fieldsauthenticateUser('', '') returns { success: false, message: 'Please enter your User ID and Password.' }
Session stateisAuthenticated() returns true after a successful login; getCurrentUser().userId equals 'admin001'
Logoutlogout() removes the session; isAuthenticated() returns false

Adding New Tests

Follow the established pattern: call an AuthService method, then use assert.strictEqual or assert.ok to verify the result. Call resetStorage() between logically independent test groups so earlier state cannot influence later assertions. A minimal example that tests an edge case not yet covered — login behaviour for an inactive account:
// Example: test that inactive users cannot log in
const newUser = AuthService.createUser({
  employeeId: 'EMP-003',
  name: 'Test User',
  userId: 'testuser',
  password: 'Test@123',
  role: 'employee',
  status: 'inactive'
});
assert.strictEqual(newUser.success, true);

// Attempt login as inactive user
const inactiveLogin = AuthService.authenticateUser('testuser', 'Test@123');
// Note: the current authenticateUser() implementation does not check the
// account's status field before authenticating. The login succeeds.
// Extend this assertion once inactive-user blocking is implemented:
// assert.strictEqual(inactiveLogin.success, false);
To add this test to the suite, append it to tests/auth.test.js before the final console.log line. If the new test group modifies accounts or session state, prepend a resetStorage() call and re-run AuthService.initializeAuth() to reseed the default admin.
The test suite covers only the logic inside assets/auth.js. The following areas are not tested by auth.test.js and require manual verification or a browser automation tool such as Playwright or Cypress:
  • UI rendering and DOM interactions in the authenticated pages
  • QR scanning via navigator.mediaDevices.getUserMedia() and the jsQR decode loop
  • LocalStorage side effects in a real browser context (storage quota limits, private-browsing restrictions)
  • Navigation and redirect behaviour triggered by assets/login.js
  • Shipment save/load workflows managed by assets/app.js

Build docs developers (and LLMs) love