Skip to content

[WIP] Add tests for object table and reporting components#309

Merged
hotlong merged 3 commits intomainfrom
copilot/test-object-table-and-components
Jan 31, 2026
Merged

[WIP] Add tests for object table and reporting components#309
hotlong merged 3 commits intomainfrom
copilot/test-object-table-and-components

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Jan 31, 2026

Extend MSW Testing Infrastructure

Building on PR #308, extend test coverage to additional components and server-driven definitions:

  • Create MSW test suite for ObjectGrid/Table component
    • Test grid rendering with data from MSW server
    • Test CRUD operations (create, read, update, delete)
    • Test column configuration and rendering
    • Test pagination and filtering
    • Fix timeout issues in grid tests (all 8 grid tests timeout - needs dataSource integration)
  • Create MSW test suite for Dashboard component
    • Test dashboard layout rendering (4/6 tests passing)
    • Test widget components (metrics, charts)
    • Test data loading from server
    • Fix duplicate title issue in 2 test expectations
  • Create MSW test suite for server-driven definitions
    • Test App layout definition (4/4 tests passing)
    • Test Page definition (2/3 tests passing)
    • Test component composition from server (3/4 tests passing)
    • Fixed 'div' and 'text' component registration for rendering ✅
  • Update package dependencies
    • Add @object-ui/plugin-grid dependency
    • Add @object-ui/plugin-dashboard dependency
    • Add @object-ui/components dependency
  • Update build configuration
    • Add packageManager field to root package.json
    • Add plugin-dashboard to pretest build script
  • Import required components in test setup
    • Added @object-ui/components to vitest.setup.ts
    • Added @object-ui/plugin-dashboard to vitest.setup.ts
    • Added @object-ui/plugin-grid to vitest.setup.ts

Test Results Summary

Overall: 23/38 tests passing (60.5%) 📊

Passing:

  • ✅ MSW Server Integration: 2/2 tests
  • ✅ Server-Driven Definitions: 9/11 tests (App layout, Page defs, Component composition)
  • ✅ Dashboard Integration: 4/6 tests (Layout rendering, widgets, server data)
  • ✅ Static Data tests: 8/8 tests

Remaining Issues:

  • ⏱️ ObjectGrid tests: 8/8 timeout (need dataSource integration fix)
  • ⚠️ Dashboard tests: 2 tests fail on duplicate text matching
  • ⚠️ ObjectForm tests: 5 pre-existing failures (not part of this PR's scope)
Original prompt

拉取请求: #308

相同的架构我还要测试对象表格,报表等组件,还需要测试从服务端传回的app布局定义,page定义,dashboard定义等。


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

@vercel
Copy link
Copy Markdown

vercel Bot commented Jan 31, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
objectui Ready Ready Preview, Comment Jan 31, 2026 6:58pm
objectui-components Ready Ready Preview, Comment Jan 31, 2026 6:58pm
objectui-crm-app Error Error Jan 31, 2026 6:58pm

Request Review

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
@hotlong hotlong merged commit 1d4f33a into main Jan 31, 2026
4 of 7 checks passed
Copilot AI requested a review from hotlong January 31, 2026 18:48
Copilot stopped work on behalf of hotlong due to an error January 31, 2026 18:48
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the MSW (Mock Service Worker) testing infrastructure established in PR #308 to cover additional ObjectUI components and server-driven definitions. It adds comprehensive test suites for ObjectGrid, Dashboard, and various server-driven layout schemas (app, page, and component composition).

Changes:

  • Adds three new test files covering ObjectGrid CRUD operations, Dashboard widgets, and server-driven schema definitions
  • Updates package dependencies to include @object-ui/components, @object-ui/plugin-dashboard, and @object-ui/plugin-grid
  • Configures component registration in vitest.setup.ts to ensure all necessary components (div, text, grid, dashboard) are available during tests
  • Updates build configuration to include plugin-dashboard in the pretest build step

Reviewed changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
pnpm-lock.yaml Adds workspace dependencies for components, plugin-dashboard, and plugin-grid packages to the msw-object-form example
package.json Adds packageManager field and includes plugin-dashboard in pretest build script
vitest.setup.ts Imports component packages to register div, text, grid, and dashboard components for testing
ServerDefinitions.test.tsx Tests server-driven app layouts, page definitions, and nested component composition using SchemaRenderer
ObjectGrid.test.tsx Tests ObjectGrid rendering, column configuration, CRUD operations, and data loading (contains critical initialization bug)
Dashboard.test.tsx Tests Dashboard layout rendering, widget components, and data-driven metrics
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported


import { describe, it, expect, beforeAll, afterAll, vi } from 'vitest';
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The userEvent import is unused. This import should be removed unless you plan to add user interaction tests (e.g., clicking buttons, selecting rows) in the near future.

Suggested change
import userEvent from '@testing-library/user-event';

Copilot uses AI. Check for mistakes.
import { render, screen, waitFor } from '@testing-library/react';
import '@testing-library/jest-dom';
import { SchemaRenderer } from '@object-ui/react';
import type { AppSchema, PageSchema } from '@object-ui/types';
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PageSchema import is unused. It should be removed to keep imports clean.

Suggested change
import type { AppSchema, PageSchema } from '@object-ui/types';
import type { AppSchema } from '@object-ui/types';

Copilot uses AI. Check for mistakes.
Comment on lines +112 to +114

// Get actual data from server
const contacts = await driver!.find('contact', {});
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using the non-null assertion operator (!) on getDriver() is unsafe. If the driver is null for any reason (e.g., server initialization fails), this will cause a runtime error.

Consider adding a null check:

const driver = getDriver();
if (!driver) {
  throw new Error('Driver not initialized');
}
const contacts = await driver.find('contact', {});

This makes the test more robust and provides clearer error messages if something goes wrong during setup.

Suggested change
// Get actual data from server
const contacts = await driver!.find('contact', {});
if (!driver) {
throw new Error('Driver not initialized');
}
// Get actual data from server
const contacts = await driver.find('contact', {});

Copilot uses AI. Check for mistakes.
Comment on lines +14 to +20

describe('ObjectGrid MSW Integration', () => {
let dataSource: ObjectStackDataSource;

beforeAll(async () => {
await startMockServer();
dataSource = new ObjectStackDataSource();
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ObjectStackDataSource constructor requires a client parameter but is being instantiated without arguments. This will cause a runtime error when the dataSource tries to access the client.

Looking at the working ObjectForm tests in the same directory, you need to:

  1. Declare a client: ObjectStackClient variable
  2. Initialize it in beforeAll with new ObjectStackClient({ baseUrl: 'http://localhost:3000' }) and call await client.connect()
  3. Pass it to the dataSource: dataSource = new ObjectStackDataSource(client)

Reference: examples/msw-object-form/src/tests/ObjectForm.test.tsx:25-28

Suggested change
describe('ObjectGrid MSW Integration', () => {
let dataSource: ObjectStackDataSource;
beforeAll(async () => {
await startMockServer();
dataSource = new ObjectStackDataSource();
import { ObjectStackClient } from '@objectstack/client';
describe('ObjectGrid MSW Integration', () => {
let dataSource: ObjectStackDataSource;
let client: ObjectStackClient;
beforeAll(async () => {
await startMockServer();
client = new ObjectStackClient({ baseUrl: 'http://localhost:3000' });
await client.connect();
dataSource = new ObjectStackDataSource(client);

Copilot uses AI. Check for mistakes.
Comment on lines +170 to +192
it('should trigger onDelete callback', async () => {
const onDelete = vi.fn();

render(
<ObjectGrid
schema={{
type: 'object-grid',
objectName: 'contact',
columns: ['name', 'email'],
actions: true,
}}
dataSource={dataSource}
onDelete={onDelete}
/>
);

await waitFor(() => {
expect(screen.getByText('John Doe')).toBeInTheDocument();
}, { timeout: 5000 });

// Look for delete buttons (implementation-specific)
// This is a placeholder for when delete actions are implemented
});
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is incomplete - it renders the grid with delete callback but doesn't actually test that clicking a delete button triggers the callback. The comment "This is a placeholder for when delete actions are implemented" indicates this is work in progress.

To complete this test, you should:

  1. Find and click a delete button in the rendered grid
  2. Verify that onDelete was called with the expected record data

Alternatively, if delete actions are not yet implemented in ObjectGrid, consider skipping this test with it.skip() or it.todo() to clearly indicate it's not yet functional.

Copilot uses AI. Check for mistakes.
Comment on lines +196 to +213
it('should show loading state initially', async () => {
const { container } = render(
<ObjectGrid
schema={{
type: 'object-grid',
objectName: 'contact',
columns: ['name', 'email'],
}}
dataSource={dataSource}
/>
);

// Check for loading indicator (implementation-specific)
// The grid should eventually show data
await waitFor(() => {
expect(screen.getByText('John Doe')).toBeInTheDocument();
}, { timeout: 5000 });
});
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test claims to check for a loading state but doesn't actually verify that a loading indicator appears. It only waits for the data to eventually load. The comment "Check for loading indicator (implementation-specific)" suggests this is incomplete.

To properly test loading states, you should:

  1. Check for a loading indicator immediately after render (before data loads)
  2. Then verify the loading indicator disappears and data appears

If the ObjectGrid component doesn't currently show a loading state, consider marking this test with it.skip() or it.todo(), or rename it to better reflect what it actually tests (e.g., "should eventually load and display data").

Copilot uses AI. Check for mistakes.
Comment on lines +14 to +20

describe('ObjectGrid MSW Integration', () => {
let dataSource: ObjectStackDataSource;

beforeAll(async () => {
await startMockServer();
dataSource = new ObjectStackDataSource();
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing import for ObjectStackClient. The ObjectStackDataSource requires an ObjectStackClient instance to be passed to its constructor.

Add this import:

import { ObjectStackClient } from '@objectstack/client';

Reference: examples/msw-object-form/src/tests/ObjectForm.test.tsx:11

Suggested change
describe('ObjectGrid MSW Integration', () => {
let dataSource: ObjectStackDataSource;
beforeAll(async () => {
await startMockServer();
dataSource = new ObjectStackDataSource();
import { ObjectStackClient } from '@objectstack/client';
describe('ObjectGrid MSW Integration', () => {
let dataSource: ObjectStackDataSource;
beforeAll(async () => {
await startMockServer();
const client = new ObjectStackClient();
dataSource = new ObjectStackDataSource(client);

Copilot uses AI. Check for mistakes.
Comment on lines +122 to +144
it('should support row selection', async () => {
const onRowSelect = vi.fn();

render(
<ObjectGrid
schema={{
type: 'object-grid',
objectName: 'contact',
columns: ['name', 'email'],
enableSelection: true,
}}
dataSource={dataSource}
onRowSelect={onRowSelect}
/>
);

await waitFor(() => {
expect(screen.getByText('John Doe')).toBeInTheDocument();
}, { timeout: 5000 });

// Note: Row selection UI depends on the actual grid implementation
// This is a placeholder for when selection is implemented
});
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is incomplete - it renders the grid with row selection enabled and waits for data to load, but doesn't actually verify that row selection works. The comment "This is a placeholder for when selection is implemented" indicates this is work in progress.

To complete this test, you should:

  1. Find and click on a row selection checkbox/control
  2. Verify that onRowSelect was called with the expected data
  3. Verify visual feedback for the selected row

Alternatively, if row selection is not yet implemented in ObjectGrid, consider skipping this test with it.skip() or it.todo() to clearly indicate it's not yet functional.

Copilot uses AI. Check for mistakes.
Comment on lines +146 to +168
it('should trigger onEdit callback', async () => {
const onEdit = vi.fn();

render(
<ObjectGrid
schema={{
type: 'object-grid',
objectName: 'contact',
columns: ['name', 'email'],
actions: true,
}}
dataSource={dataSource}
onEdit={onEdit}
/>
);

await waitFor(() => {
expect(screen.getByText('John Doe')).toBeInTheDocument();
}, { timeout: 5000 });

// Look for edit buttons (implementation-specific)
// This is a placeholder for when edit actions are implemented
});
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is incomplete - it renders the grid with edit callback but doesn't actually test that clicking an edit button triggers the callback. The comment "This is a placeholder for when edit actions are implemented" indicates this is work in progress.

To complete this test, you should:

  1. Find and click an edit button in the rendered grid
  2. Verify that onEdit was called with the expected record data

Alternatively, if edit actions are not yet implemented in ObjectGrid, consider skipping this test with it.skip() or it.todo() to clearly indicate it's not yet functional.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants