@rimori/playwright-testing 0.3.3 → 0.3.4-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -55,8 +55,10 @@ export declare class RimoriTestEnvironment {
55
55
  */
56
56
  private setupSettingsRoutes;
57
57
  /**
58
- * Sets up default handlers for shared_content and shared_content_completed routes.
59
- * These provide sensible defaults so tests don't need to mock every shared content call.
58
+ * Sets up default handlers for shared content routes.
59
+ * Note: Shared content tables are now plugin-specific with format: `${pluginId}_sc_${tableName}`
60
+ * This method no longer sets up generic routes since each plugin has its own tables.
61
+ * Use the community.sharedContent mock methods to set up specific table mocks.
60
62
  */
61
63
  private setupSharedContentRoutes;
62
64
  /**
@@ -287,46 +289,124 @@ export declare class RimoriTestEnvironment {
287
289
  readonly runtime: {
288
290
  mockFetchBackend: () => void;
289
291
  };
290
- readonly community: {
291
- sharedContent: {
292
- /**
293
- * Mock the shared_content GET endpoint for fetching a single item.
294
- * Used by SharedContentController.getSharedContent()
295
- */
296
- mockGet: (value: unknown, options?: MockOptions) => void;
297
- /**
298
- * Mock the shared_content GET endpoint for fetching multiple items.
299
- * Used by SharedContentController.getSharedContentList() and getCompletedTopics()
300
- */
301
- mockGetList: (value: unknown[], options?: MockOptions) => void;
302
- /**
303
- * Mock the shared_content POST endpoint for creating new content.
304
- * Used by SharedContentController.createSharedContent() after AI generation.
305
- * Note: getNewSharedContent() first calls ai.getObject() (mock via env.ai.mockGetObject),
306
- * then calls createSharedContent() which hits this endpoint.
307
- */
308
- mockCreate: (value: unknown, options?: MockOptions) => void;
309
- /**
310
- * Mock the shared_content PATCH endpoint for updating content.
311
- * Used by SharedContentController.updateSharedContent() and removeSharedContent() (soft delete)
312
- */
313
- mockUpdate: (value: unknown, options?: MockOptions) => void;
314
- /**
315
- * Mock the shared_content_completed POST endpoint (upsert).
316
- * Used by SharedContentController.completeSharedContent() and updateSharedContentState()
317
- */
318
- mockComplete: (value?: unknown, options?: MockOptions) => void;
319
- /**
320
- * Mock the shared_content_completed POST endpoint for state updates.
321
- * Alias for mockComplete since both use upsert via POST.
322
- */
323
- mockUpdateState: (value?: unknown, options?: MockOptions) => void;
324
- /**
325
- * Mock removing shared content (soft delete via PATCH).
326
- * Alias for mockUpdate since removeSharedContent uses PATCH to set deleted_at.
327
- */
328
- mockRemove: (value: unknown, options?: MockOptions) => void;
329
- };
292
+ readonly sharedContent: {
293
+ /**
294
+ * Mock the /shared-content/generate backend endpoint.
295
+ * Used by SharedContentController.getNew() to generate new content with AI.
296
+ * @param value - The generated content to return
297
+ * @param options - Optional mock options
298
+ */
299
+ mockGenerate: (value: unknown, options?: MockOptions) => void;
300
+ /**
301
+ * Mock embedding generation endpoint for RAG search.
302
+ * Used by SharedContentController.searchByTopic() to generate query embedding.
303
+ * @param value - Object with embedding array: { embedding: number[] }
304
+ * @param options - Optional mock options
305
+ */
306
+ mockEmbedding: (value: {
307
+ embedding: number[];
308
+ }, options?: MockOptions) => void;
309
+ /**
310
+ * Mock RPC call for vector similarity search.
311
+ * Used by SharedContentController.searchByTopic() for RAG-based content search.
312
+ * @param value - Array of search results
313
+ * @param options - Optional mock options
314
+ */
315
+ mockSearchByTopic: (value: unknown, options?: MockOptions) => void;
316
+ /**
317
+ * Mock fetching bookmarked shared content.
318
+ * Used by SharedContentController.getBookmarked().
319
+ * Note: The actual query uses a join with the completion table, so the response should include
320
+ * the completed relation structure.
321
+ * @param tableName - Table name WITHOUT plugin prefix (e.g., 'grammar_exercises')
322
+ * The full table name `${pluginId}_sc_${tableName}` is automatically added
323
+ * @param value - Array of content items with completed relation
324
+ * @param options - Optional mock options
325
+ */
326
+ mockGetBookmarked: (tableName: string, value: unknown, options?: MockOptions) => void;
327
+ /**
328
+ * Mock fetching ongoing shared content.
329
+ * Used by SharedContentController.getOngoing().
330
+ * Note: The actual query uses a join with the completion table.
331
+ * @param tableName - Table name WITHOUT plugin prefix (e.g., 'grammar_exercises')
332
+ * @param value - Array of content items with completed relation
333
+ * @param options - Optional mock options
334
+ */
335
+ mockGetOngoing: (tableName: string, value: unknown, options?: MockOptions) => void;
336
+ /**
337
+ * Mock fetching completed shared content.
338
+ * Used by SharedContentController.getCompleted().
339
+ * Note: The actual query uses a join with the completion table.
340
+ * @param tableName - Table name WITHOUT plugin prefix (e.g., 'grammar_exercises')
341
+ * @param value - Array of content items with completed relation
342
+ * @param options - Optional mock options
343
+ */
344
+ mockGetCompleted: (tableName: string, value: unknown, options?: MockOptions) => void;
345
+ /**
346
+ * Mock getting a specific shared content item by ID.
347
+ * Used by SharedContentController.get().
348
+ * @param tableName - Table name WITHOUT plugin prefix (e.g., 'grammar_exercises')
349
+ * @param value - Single content item (not an array)
350
+ * @param options - Optional mock options
351
+ */
352
+ mockGet: (tableName: string, value: unknown, options?: MockOptions) => void;
353
+ /**
354
+ * Mock creating new shared content manually.
355
+ * Used by SharedContentController.create().
356
+ * @param tableName - Table name WITHOUT plugin prefix (e.g., 'grammar_exercises')
357
+ * @param value - Created content item (single object, not array)
358
+ * @param options - Optional mock options
359
+ */
360
+ mockCreate: (tableName: string, value: unknown, options?: MockOptions) => void;
361
+ /**
362
+ * Mock updating shared content.
363
+ * Used by SharedContentController.update().
364
+ * @param tableName - Table name WITHOUT plugin prefix (e.g., 'grammar_exercises')
365
+ * @param value - Updated content item (single object, not array)
366
+ * @param options - Optional mock options
367
+ */
368
+ mockUpdate: (tableName: string, value: unknown, options?: MockOptions) => void;
369
+ /**
370
+ * Mock completing shared content (marks as completed in completion table).
371
+ * Used by SharedContentController.complete().
372
+ * @param tableName - Table name WITHOUT plugin prefix (e.g., 'grammar_exercises')
373
+ * The completion table name `${pluginId}_sc_${tableName}_completed` is automatically added
374
+ * @param value - Optional response value (defaults to empty object for upsert)
375
+ * @param options - Optional mock options
376
+ */
377
+ mockComplete: (tableName: string, value?: unknown, options?: MockOptions) => void;
378
+ /**
379
+ * Mock updating shared content state (ongoing/hidden/completed).
380
+ * Used by SharedContentController.updateState().
381
+ * @param tableName - Table name WITHOUT plugin prefix (e.g., 'grammar_exercises')
382
+ * @param value - Optional response value (defaults to empty object for upsert)
383
+ * @param options - Optional mock options
384
+ */
385
+ mockUpdateState: (tableName: string, value?: unknown, options?: MockOptions) => void;
386
+ /**
387
+ * Mock bookmarking shared content.
388
+ * Used by SharedContentController.bookmark().
389
+ * @param tableName - Table name WITHOUT plugin prefix (e.g., 'grammar_exercises')
390
+ * @param value - Optional response value (defaults to empty object for upsert)
391
+ * @param options - Optional mock options
392
+ */
393
+ mockBookmark: (tableName: string, value?: unknown, options?: MockOptions) => void;
394
+ /**
395
+ * Mock reacting to shared content (like/dislike).
396
+ * Used by SharedContentController.react().
397
+ * @param tableName - Table name WITHOUT plugin prefix (e.g., 'grammar_exercises')
398
+ * @param value - Optional response value (defaults to empty object for upsert)
399
+ * @param options - Optional mock options
400
+ */
401
+ mockReact: (tableName: string, value?: unknown, options?: MockOptions) => void;
402
+ /**
403
+ * Mock removing shared content (DELETE).
404
+ * Used by SharedContentController.remove().
405
+ * @param tableName - Table name WITHOUT plugin prefix (e.g., 'grammar_exercises')
406
+ * @param value - Optional response value (DELETE typically returns empty)
407
+ * @param options - Optional mock options
408
+ */
409
+ mockRemove: (tableName: string, value: unknown, options?: MockOptions) => void;
330
410
  };
331
411
  readonly exercise: {
332
412
  mockView: () => void;
@@ -341,59 +341,160 @@ class RimoriTestEnvironment {
341
341
  this.runtime = {
342
342
  mockFetchBackend: () => { },
343
343
  };
344
- this.community = {
345
- sharedContent: {
346
- /**
347
- * Mock the shared_content GET endpoint for fetching a single item.
348
- * Used by SharedContentController.getSharedContent()
349
- */
350
- mockGet: (value, options) => {
351
- this.addSupabaseRoute('shared_content', value, { ...options, method: 'GET' });
352
- },
353
- /**
354
- * Mock the shared_content GET endpoint for fetching multiple items.
355
- * Used by SharedContentController.getSharedContentList() and getCompletedTopics()
356
- */
357
- mockGetList: (value, options) => {
358
- this.addSupabaseRoute('shared_content', value, { ...options, method: 'GET' });
359
- },
360
- /**
361
- * Mock the shared_content POST endpoint for creating new content.
362
- * Used by SharedContentController.createSharedContent() after AI generation.
363
- * Note: getNewSharedContent() first calls ai.getObject() (mock via env.ai.mockGetObject),
364
- * then calls createSharedContent() which hits this endpoint.
365
- */
366
- mockCreate: (value, options) => {
367
- this.addSupabaseRoute('shared_content', value, { ...options, method: 'POST' });
368
- },
369
- /**
370
- * Mock the shared_content PATCH endpoint for updating content.
371
- * Used by SharedContentController.updateSharedContent() and removeSharedContent() (soft delete)
372
- */
373
- mockUpdate: (value, options) => {
374
- this.addSupabaseRoute('shared_content', value, { ...options, method: 'PATCH' });
375
- },
376
- /**
377
- * Mock the shared_content_completed POST endpoint (upsert).
378
- * Used by SharedContentController.completeSharedContent() and updateSharedContentState()
379
- */
380
- mockComplete: (value = {}, options) => {
381
- this.addSupabaseRoute('shared_content_completed', value, { ...options, method: 'POST' });
382
- },
383
- /**
384
- * Mock the shared_content_completed POST endpoint for state updates.
385
- * Alias for mockComplete since both use upsert via POST.
386
- */
387
- mockUpdateState: (value = {}, options) => {
388
- this.addSupabaseRoute('shared_content_completed', value, { ...options, method: 'POST' });
389
- },
390
- /**
391
- * Mock removing shared content (soft delete via PATCH).
392
- * Alias for mockUpdate since removeSharedContent uses PATCH to set deleted_at.
393
- */
394
- mockRemove: (value, options) => {
395
- this.addSupabaseRoute('shared_content', value, { ...options, method: 'PATCH' });
396
- },
344
+ this.sharedContent = {
345
+ /**
346
+ * Mock the /shared-content/generate backend endpoint.
347
+ * Used by SharedContentController.getNew() to generate new content with AI.
348
+ * @param value - The generated content to return
349
+ * @param options - Optional mock options
350
+ */
351
+ mockGenerate: (value, options) => {
352
+ this.addBackendRoute('/shared-content/generate', value, { ...options, method: 'POST' });
353
+ },
354
+ /**
355
+ * Mock embedding generation endpoint for RAG search.
356
+ * Used by SharedContentController.searchByTopic() to generate query embedding.
357
+ * @param value - Object with embedding array: { embedding: number[] }
358
+ * @param options - Optional mock options
359
+ */
360
+ mockEmbedding: (value, options) => {
361
+ this.addBackendRoute('/ai/embedding', value, { ...options, method: 'POST' });
362
+ },
363
+ /**
364
+ * Mock RPC call for vector similarity search.
365
+ * Used by SharedContentController.searchByTopic() for RAG-based content search.
366
+ * @param value - Array of search results
367
+ * @param options - Optional mock options
368
+ */
369
+ mockSearchByTopic: (value, options) => {
370
+ this.addSupabaseRoute('rpc/search_shared_content', value, { ...options, method: 'POST' });
371
+ },
372
+ /**
373
+ * Mock fetching bookmarked shared content.
374
+ * Used by SharedContentController.getBookmarked().
375
+ * Note: The actual query uses a join with the completion table, so the response should include
376
+ * the completed relation structure.
377
+ * @param tableName - Table name WITHOUT plugin prefix (e.g., 'grammar_exercises')
378
+ * The full table name `${pluginId}_sc_${tableName}` is automatically added
379
+ * @param value - Array of content items with completed relation
380
+ * @param options - Optional mock options
381
+ */
382
+ mockGetBookmarked: (tableName, value, options) => {
383
+ const fullTableName = `${this.pluginId}_sc_${tableName}`;
384
+ this.addSupabaseRoute(fullTableName, value, { ...options, method: 'GET' });
385
+ },
386
+ /**
387
+ * Mock fetching ongoing shared content.
388
+ * Used by SharedContentController.getOngoing().
389
+ * Note: The actual query uses a join with the completion table.
390
+ * @param tableName - Table name WITHOUT plugin prefix (e.g., 'grammar_exercises')
391
+ * @param value - Array of content items with completed relation
392
+ * @param options - Optional mock options
393
+ */
394
+ mockGetOngoing: (tableName, value, options) => {
395
+ const fullTableName = `${this.pluginId}_sc_${tableName}`;
396
+ this.addSupabaseRoute(fullTableName, value, { ...options, method: 'GET' });
397
+ },
398
+ /**
399
+ * Mock fetching completed shared content.
400
+ * Used by SharedContentController.getCompleted().
401
+ * Note: The actual query uses a join with the completion table.
402
+ * @param tableName - Table name WITHOUT plugin prefix (e.g., 'grammar_exercises')
403
+ * @param value - Array of content items with completed relation
404
+ * @param options - Optional mock options
405
+ */
406
+ mockGetCompleted: (tableName, value, options) => {
407
+ const fullTableName = `${this.pluginId}_sc_${tableName}`;
408
+ this.addSupabaseRoute(fullTableName, value, { ...options, method: 'GET' });
409
+ },
410
+ /**
411
+ * Mock getting a specific shared content item by ID.
412
+ * Used by SharedContentController.get().
413
+ * @param tableName - Table name WITHOUT plugin prefix (e.g., 'grammar_exercises')
414
+ * @param value - Single content item (not an array)
415
+ * @param options - Optional mock options
416
+ */
417
+ mockGet: (tableName, value, options) => {
418
+ const fullTableName = `${this.pluginId}_sc_${tableName}`;
419
+ this.addSupabaseRoute(fullTableName, value, { ...options, method: 'GET' });
420
+ },
421
+ /**
422
+ * Mock creating new shared content manually.
423
+ * Used by SharedContentController.create().
424
+ * @param tableName - Table name WITHOUT plugin prefix (e.g., 'grammar_exercises')
425
+ * @param value - Created content item (single object, not array)
426
+ * @param options - Optional mock options
427
+ */
428
+ mockCreate: (tableName, value, options) => {
429
+ const fullTableName = `${this.pluginId}_sc_${tableName}`;
430
+ this.addSupabaseRoute(fullTableName, value, { ...options, method: 'POST' });
431
+ },
432
+ /**
433
+ * Mock updating shared content.
434
+ * Used by SharedContentController.update().
435
+ * @param tableName - Table name WITHOUT plugin prefix (e.g., 'grammar_exercises')
436
+ * @param value - Updated content item (single object, not array)
437
+ * @param options - Optional mock options
438
+ */
439
+ mockUpdate: (tableName, value, options) => {
440
+ const fullTableName = `${this.pluginId}_sc_${tableName}`;
441
+ this.addSupabaseRoute(fullTableName, value, { ...options, method: 'PATCH' });
442
+ },
443
+ /**
444
+ * Mock completing shared content (marks as completed in completion table).
445
+ * Used by SharedContentController.complete().
446
+ * @param tableName - Table name WITHOUT plugin prefix (e.g., 'grammar_exercises')
447
+ * The completion table name `${pluginId}_sc_${tableName}_completed` is automatically added
448
+ * @param value - Optional response value (defaults to empty object for upsert)
449
+ * @param options - Optional mock options
450
+ */
451
+ mockComplete: (tableName, value = {}, options) => {
452
+ const fullTableName = `${this.pluginId}_sc_${tableName}_completed`;
453
+ this.addSupabaseRoute(fullTableName, value, { ...options, method: 'POST' });
454
+ },
455
+ /**
456
+ * Mock updating shared content state (ongoing/hidden/completed).
457
+ * Used by SharedContentController.updateState().
458
+ * @param tableName - Table name WITHOUT plugin prefix (e.g., 'grammar_exercises')
459
+ * @param value - Optional response value (defaults to empty object for upsert)
460
+ * @param options - Optional mock options
461
+ */
462
+ mockUpdateState: (tableName, value = {}, options) => {
463
+ const fullTableName = `${this.pluginId}_sc_${tableName}_completed`;
464
+ this.addSupabaseRoute(fullTableName, value, { ...options, method: 'POST' });
465
+ },
466
+ /**
467
+ * Mock bookmarking shared content.
468
+ * Used by SharedContentController.bookmark().
469
+ * @param tableName - Table name WITHOUT plugin prefix (e.g., 'grammar_exercises')
470
+ * @param value - Optional response value (defaults to empty object for upsert)
471
+ * @param options - Optional mock options
472
+ */
473
+ mockBookmark: (tableName, value = {}, options) => {
474
+ const fullTableName = `${this.pluginId}_sc_${tableName}_completed`;
475
+ this.addSupabaseRoute(fullTableName, value, { ...options, method: 'POST' });
476
+ },
477
+ /**
478
+ * Mock reacting to shared content (like/dislike).
479
+ * Used by SharedContentController.react().
480
+ * @param tableName - Table name WITHOUT plugin prefix (e.g., 'grammar_exercises')
481
+ * @param value - Optional response value (defaults to empty object for upsert)
482
+ * @param options - Optional mock options
483
+ */
484
+ mockReact: (tableName, value = {}, options) => {
485
+ const fullTableName = `${this.pluginId}_sc_${tableName}_completed`;
486
+ this.addSupabaseRoute(fullTableName, value, { ...options, method: 'POST' });
487
+ },
488
+ /**
489
+ * Mock removing shared content (DELETE).
490
+ * Used by SharedContentController.remove().
491
+ * @param tableName - Table name WITHOUT plugin prefix (e.g., 'grammar_exercises')
492
+ * @param value - Optional response value (DELETE typically returns empty)
493
+ * @param options - Optional mock options
494
+ */
495
+ mockRemove: (tableName, value, options) => {
496
+ const fullTableName = `${this.pluginId}_sc_${tableName}`;
497
+ this.addSupabaseRoute(fullTableName, value, { ...options, method: 'DELETE' });
397
498
  },
398
499
  };
399
500
  this.exercise = {
@@ -591,49 +692,14 @@ class RimoriTestEnvironment {
591
692
  });
592
693
  }
593
694
  /**
594
- * Sets up default handlers for shared_content and shared_content_completed routes.
595
- * These provide sensible defaults so tests don't need to mock every shared content call.
695
+ * Sets up default handlers for shared content routes.
696
+ * Note: Shared content tables are now plugin-specific with format: `${pluginId}_sc_${tableName}`
697
+ * This method no longer sets up generic routes since each plugin has its own tables.
698
+ * Use the community.sharedContent mock methods to set up specific table mocks.
596
699
  */
597
700
  setupSharedContentRoutes() {
598
- // GET: Return empty array for getCompletedTopics and getSharedContentList
599
- this.addSupabaseRoute('shared_content', [], { method: 'GET' });
600
- // POST: Return created content with generated ID for createSharedContent
601
- this.addSupabaseRoute('shared_content', async (request) => {
602
- try {
603
- const postData = request.postData();
604
- if (postData) {
605
- const content = JSON.parse(postData);
606
- // Return the content with a generated ID
607
- return [
608
- {
609
- id: `shared-content-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`,
610
- ...content,
611
- created_at: new Date().toISOString(),
612
- },
613
- ];
614
- }
615
- return [];
616
- }
617
- catch {
618
- return [];
619
- }
620
- }, { method: 'POST' });
621
- // PATCH: Return updated content for updateSharedContent and removeSharedContent
622
- this.addSupabaseRoute('shared_content', async (request) => {
623
- try {
624
- const postData = request.postData();
625
- if (postData) {
626
- const updates = JSON.parse(postData);
627
- return [{ id: 'updated-content', ...updates }];
628
- }
629
- return [];
630
- }
631
- catch {
632
- return [];
633
- }
634
- }, { method: 'PATCH' });
635
- // POST: Handle shared_content_completed upserts
636
- this.addSupabaseRoute('shared_content_completed', {}, { method: 'POST' });
701
+ // No longer setting up generic routes - each plugin has its own prefixed tables
702
+ // Tests should use env.community.sharedContent.mock* methods for specific tables
637
703
  }
638
704
  /**
639
705
  * Formats text as SSE (Server-Sent Events) response.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rimori/playwright-testing",
3
- "version": "0.3.3",
3
+ "version": "0.3.4-next.0",
4
4
  "description": "Playwright testing utilities for Rimori plugins and workers",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -23,11 +23,11 @@
23
23
  },
24
24
  "peerDependencies": {
25
25
  "@playwright/test": "^1.40.0",
26
- "@rimori/client": "^2.5.3"
26
+ "@rimori/client": "^2.5.6"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@playwright/test": "^1.40.0",
30
- "@rimori/client": "^2.5.3",
30
+ "@rimori/client": "^2.5.6",
31
31
  "@types/node": "^20.12.7",
32
32
  "rimraf": "^5.0.7",
33
33
  "typescript": "^5.7.2"