First round of test

This commit is contained in:
2026-05-24 01:07:39 +02:00
parent e2da4773bd
commit 2d898f6818
5 changed files with 94 additions and 59 deletions
+13
View File
@@ -275,8 +275,21 @@ Hooks.once("ready", () => {
if (adapter.users.isGM()) {
directorsBoard = new DirectorsBoard(stateStore, scryingPoolController, adapter, scenePresetManager, playerPrivacyManager);
directorsBoard.init();
window.directorsBoard = directorsBoard;
}
// Pre-load participant-card as a Handlebars partial for directors-board
// ApplicationV2 requires partials to be registered explicitly
(async () => {
try {
const resp = await fetch('modules/video-view-manager/templates/participant-card.hbs');
const source = await resp.text();
Handlebars.registerPartial('modules/video-view-manager/templates/participant-card.hbs', source);
} catch (err) {
console.warn('[ScryingPool] Failed to register participant-card partial:', err);
}
})();
// Story 4.1: Initialize PlayerPrivacyPanelMenu with DI dependencies
// Story 4.2: Pass portraitFallbackHandler for portrait selection
initPlayerPrivacyPanelMenu(adapter, playerPrivacyManager, portraitFallbackHandler);
+19 -1
View File
@@ -49,11 +49,29 @@ export function isInitialized() {
return _isInitialized;
}
/**
* Conditional base class — test environment lacks foundry globals.
*/
const _MenuAppBase =
typeof foundry !== 'undefined' &&
foundry.applications?.api?.ApplicationV2
? foundry.applications.api.ApplicationV2
: class _FallbackMenuApp {
static DEFAULT_OPTIONS = {};
get rendered() { return this._rendered ?? false; }
set rendered(v) { this._rendered = v; }
get element() { return this._element ?? null; }
set element(v) { this._element = v; }
async render() { this._rendered = true; }
async close() { this._rendered = false; }
};
/**
* PlayerPrivacyPanelMenu - Wrapper for Foundry settings menu.
* When instantiated by Foundry, it creates a PlayerPrivacyPanel with the current user as target.
* Extends ApplicationV2 so it passes Foundry's registerMenu validation.
*/
export class PlayerPrivacyPanelMenu {
export class PlayerPrivacyPanelMenu extends _MenuAppBase {
/**
* @param {object} [options] - Foundry options (unused, but required by settings menu API)
*/
+4
View File
@@ -1,4 +1,6 @@
{{!-- Director's Board — GM camera-management overview window --}}
<div class="directors-board__inner">
<section class="scrying-pool directors-board__content"
role="list"
aria-label="{{localize "video-view-manager.directorsBoard.title"}}">
@@ -55,3 +57,5 @@
{{!-- Scene Preset Panel - rendered via JavaScript, not Handlebars --}}
{{!-- Panel is appended dynamically in DirectorsBoard._appendPresetPanel() --}}
</div>
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

+6 -6
View File
@@ -322,10 +322,10 @@ describe('DirectorsBoard', () => {
expect(controller.action).toHaveBeenCalledWith('board', 'u2', 'active', expect.any(String), expect.any(Number));
});
it('clears _undoSnapshot after use (single-step only)', () => {
it('clears _undoSnapshot after use (single-step only)', async () => {
board._undoSnapshot = new Map([['u1', 'hidden']]);
stateStore.getState.mockReturnValue('active');
board.undo();
await board.undo();
expect(board._undoSnapshot).toBeNull();
});
@@ -335,10 +335,10 @@ describe('DirectorsBoard', () => {
expect(controller.action).not.toHaveBeenCalled();
});
it('second undo is unavailable after first (no-op)', () => {
it('second undo is unavailable after first (no-op)', async () => {
board._undoSnapshot = new Map([['u1', 'hidden']]);
stateStore.getState.mockReturnValue('active');
board.undo();
await board.undo();
board.undo();
expect(controller.action).toHaveBeenCalledTimes(1);
});
@@ -430,10 +430,10 @@ describe('DirectorsBoard spotlight', () => {
expect(controller.action).toHaveBeenCalledWith('board', 'u2', 'active', expect.any(String), expect.any(Number));
});
it('clears _spotlightSnapshot after restore', () => {
it('clears _spotlightSnapshot after restore', async () => {
board._spotlightSnapshot = new Map([['u1', 'active']]);
stateStore.getState.mockReturnValue('active');
board.restoreSpotlight();
await board.restoreSpotlight();
expect(board._spotlightSnapshot).toBeNull();
});