Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
186 changes: 82 additions & 104 deletions cypress/e2e/editor/blocks/unsupported_block.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { AuthTestUtils } from '../../../support/auth-utils';
import { waitForReactUpdate } from '../../../support/selectors';
import { generateRandomEmail } from '../../../support/test-config';

// This test requires __TEST_DOC__ which is only exposed in dev mode
// Tests will be skipped in CI where production builds are used
describe('Unsupported Block Display', () => {
const authUtils = new AuthTestUtils();
const testEmail = generateRandomEmail();
Expand Down Expand Up @@ -57,51 +59,60 @@ describe('Unsupported Block Display', () => {
waitForReactUpdate(500);
});

// Helper to check if test utilities are available
const getTestUtilities = () => {
return cy.window().then((win) => {
const testWindow = win as Window & {
__TEST_DOC__?: {
getMap: (key: string) => unknown;
transact: (fn: () => void) => void;
};
Y?: {
Map: new () => Map<string, unknown>;
Text: new () => unknown;
Array: new <T>() => { push: (items: T[]) => void };
};
};

return {
doc: testWindow.__TEST_DOC__,
Y: testWindow.Y,
available: !!(testWindow.__TEST_DOC__ && testWindow.Y),
};
});
};

describe('Unsupported Block Rendering', () => {
it('should display unsupported block message for unknown block types', () => {
it('should display unsupported block message for unknown block types', function () {
// Wait for editor to be ready
waitForReactUpdate(500);

// Insert an unsupported block type via the exposed Yjs document
cy.window().then((win) => {
const testWindow = win as Window & {
__TEST_DOC__?: {
getMap: (key: string) => unknown;
transact: (fn: () => void) => void;
};
Y?: {
Map: new () => Map<string, unknown>;
Text: new () => unknown;
Array: new <T>() => { push: (items: T[]) => void };
};
};
getTestUtilities().then((utils) => {
if (!utils.available) {
cy.log('⚠️ Test utilities not available (expected in CI/production builds) - skipping');
this.skip();

const doc = testWindow.__TEST_DOC__;
const Y = testWindow.Y;

if (!doc || !Y) {
throw new Error('Test utilities not found. Ensure app is running in dev mode.');
return;
}

const { doc, Y } = utils;

// Get the document structure
// Structure: doc.getMap('data').get('document') -> { blocks, meta, page_id }
const sharedRoot = doc.getMap('data') as Map<string, unknown>;
const sharedRoot = doc!.getMap('data') as Map<string, unknown>;
const document = sharedRoot.get('document') as Map<string, unknown>;
const blocks = document.get('blocks') as Map<string, unknown>;
const meta = document.get('meta') as Map<string, unknown>;
const pageId = document.get('page_id') as string;
const childrenMap = meta.get('children_map') as Map<string, unknown>;
const textMap = meta.get('text_map') as Map<string, unknown>;

// Generate a unique block ID
const blockId = `test_unsupported_${Date.now()}`;

// Insert an unsupported block type
doc.transact(() => {
const block = new Y.Map();
doc!.transact(() => {
const block = new Y!.Map();

block.set('id', blockId);
block.set('ty', 'future_block_type_not_yet_implemented'); // Unknown block type
block.set('ty', 'future_block_type_not_yet_implemented');
block.set('children', blockId);
block.set('external_id', blockId);
block.set('external_type', 'text');
Expand All @@ -110,63 +121,45 @@ describe('Unsupported Block Display', () => {

(blocks as Map<string, unknown>).set(blockId, block);

// Add to page children
const pageChildren = childrenMap.get(pageId) as { push: (items: string[]) => void };

if (pageChildren) {
pageChildren.push([blockId]);
}

// Create empty text for the block
const blockText = new Y.Text();
const blockText = new Y!.Text();

(textMap as Map<string, unknown>).set(blockId, blockText);

// Create empty children array
const blockChildren = new Y.Array<string>();
const blockChildren = new Y!.Array<string>();

(childrenMap as Map<string, unknown>).set(blockId, blockChildren);
});
});

waitForReactUpdate(1000);
waitForReactUpdate(1000);

// Verify the unsupported block component is rendered
cy.get('[data-testid="unsupported-block"]').should('exist');
cy.get('[data-testid="unsupported-block"]').should('be.visible');

// Verify it shows the correct message
cy.get('[data-testid="unsupported-block"]')
.should('contain.text', 'not supported yet')
.and('contain.text', 'future_block_type_not_yet_implemented');
cy.get('[data-testid="unsupported-block"]').should('exist');
cy.get('[data-testid="unsupported-block"]').should('be.visible');
cy.get('[data-testid="unsupported-block"]')
.should('contain.text', 'not supported yet')
.and('contain.text', 'future_block_type_not_yet_implemented');
});
});

it('should display warning icon and block type name', () => {
// Insert an unsupported block with a specific type name
it('should display warning icon and block type name', function () {
const testBlockType = 'my_custom_unknown_block';

cy.window().then((win) => {
const testWindow = win as Window & {
__TEST_DOC__?: {
getMap: (key: string) => unknown;
transact: (fn: () => void) => void;
};
Y?: {
Map: new () => Map<string, unknown>;
Text: new () => unknown;
Array: new <T>() => { push: (items: T[]) => void };
};
};

const doc = testWindow.__TEST_DOC__;
const Y = testWindow.Y;
getTestUtilities().then((utils) => {
if (!utils.available) {
cy.log('⚠️ Test utilities not available (expected in CI/production builds) - skipping');
this.skip();

if (!doc || !Y) {
throw new Error('Test utilities not found. Ensure app is running in dev mode.');
return;
}

// Structure: doc.getMap('data').get('document') -> { blocks, meta, page_id }
const sharedRoot = doc.getMap('data') as Map<string, unknown>;
const { doc, Y } = utils;

const sharedRoot = doc!.getMap('data') as Map<string, unknown>;
const document = sharedRoot.get('document') as Map<string, unknown>;
const blocks = document.get('blocks') as Map<string, unknown>;
const meta = document.get('meta') as Map<string, unknown>;
Expand All @@ -176,8 +169,8 @@ describe('Unsupported Block Display', () => {

const blockId = `test_${Date.now()}`;

doc.transact(() => {
const block = new Y.Map();
doc!.transact(() => {
const block = new Y!.Map();

block.set('id', blockId);
block.set('ty', testBlockType);
Expand All @@ -195,51 +188,37 @@ describe('Unsupported Block Display', () => {
pageChildren.push([blockId]);
}

const blockText = new Y.Text();
const blockText = new Y!.Text();

(textMap as Map<string, unknown>).set(blockId, blockText);

const blockChildren = new Y.Array<string>();
const blockChildren = new Y!.Array<string>();

(childrenMap as Map<string, unknown>).set(blockId, blockChildren);
});
});

waitForReactUpdate(1000);
waitForReactUpdate(1000);

// Verify the unsupported block shows the type name
cy.get('[data-testid="unsupported-block"]')
.should('be.visible')
.and('contain.text', testBlockType);
cy.get('[data-testid="unsupported-block"]')
.should('be.visible')
.and('contain.text', testBlockType);

// Verify it has the warning styling (contains an SVG icon)
cy.get('[data-testid="unsupported-block"] svg').should('exist');
cy.get('[data-testid="unsupported-block"] svg').should('exist');
});
});

it('should be non-editable', () => {
// Insert an unsupported block
cy.window().then((win) => {
const testWindow = win as Window & {
__TEST_DOC__?: {
getMap: (key: string) => unknown;
transact: (fn: () => void) => void;
};
Y?: {
Map: new () => Map<string, unknown>;
Text: new () => unknown;
Array: new <T>() => { push: (items: T[]) => void };
};
};

const doc = testWindow.__TEST_DOC__;
const Y = testWindow.Y;
it('should be non-editable', function () {
getTestUtilities().then((utils) => {
if (!utils.available) {
cy.log('⚠️ Test utilities not available (expected in CI/production builds) - skipping');
this.skip();

if (!doc || !Y) {
throw new Error('Test utilities not found.');
return;
}

// Structure: doc.getMap('data').get('document') -> { blocks, meta, page_id }
const sharedRoot = doc.getMap('data') as Map<string, unknown>;
const { doc, Y } = utils;

const sharedRoot = doc!.getMap('data') as Map<string, unknown>;
const document = sharedRoot.get('document') as Map<string, unknown>;
const blocks = document.get('blocks') as Map<string, unknown>;
const meta = document.get('meta') as Map<string, unknown>;
Expand All @@ -249,8 +228,8 @@ describe('Unsupported Block Display', () => {

const blockId = `test_readonly_${Date.now()}`;

doc.transact(() => {
const block = new Y.Map();
doc!.transact(() => {
const block = new Y!.Map();

block.set('id', blockId);
block.set('ty', 'readonly_test_block');
Expand All @@ -268,21 +247,20 @@ describe('Unsupported Block Display', () => {
pageChildren.push([blockId]);
}

const blockText = new Y.Text();
const blockText = new Y!.Text();

(textMap as Map<string, unknown>).set(blockId, blockText);

const blockChildren = new Y.Array<string>();
const blockChildren = new Y!.Array<string>();

(childrenMap as Map<string, unknown>).set(blockId, blockChildren);
});
});

waitForReactUpdate(1000);
waitForReactUpdate(1000);

// Verify the unsupported block has contentEditable=false
cy.get('[data-testid="unsupported-block"]')
.should('have.attr', 'contenteditable', 'false');
cy.get('[data-testid="unsupported-block"]')
.should('have.attr', 'contenteditable', 'false');
});
});
});
});
Loading