test-media-list.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import { eq } from 'drizzle-orm';
  2. import { listMedia } from '../src/actions/media';
  3. import { db } from '../src/db';
  4. import { users } from '../src/db/schema/auth';
  5. import { media } from '../src/db/schema/media';
  6. import { resources } from '../src/db/schema/resource';
  7. import { cleanupMediaRecord } from './helpers/media-cleanup';
  8. async function upsertUser(email: string, name: string) {
  9. const [existing] = await db.select().from(users).where(eq(users.email, email)).limit(1);
  10. if (existing) {
  11. return existing;
  12. }
  13. const [created] = await db.insert(users).values({
  14. email,
  15. name,
  16. passwordHash: 'test_password_hash',
  17. }).returning();
  18. return created;
  19. }
  20. async function runTest() {
  21. console.log('Testing media list visibility and filters...');
  22. const createdMediaIds: string[] = [];
  23. const owner = await upsertUser('media-list-owner@ekb.com', 'Media List Owner');
  24. const outsider = await upsertUser('media-list-outsider@ekb.com', 'Media List Outsider');
  25. const suffix = Date.now();
  26. const [resource] = await db.insert(resources).values({
  27. name: `media-list-${suffix}.mp4`,
  28. path: `/media-list/${suffix}.mp4`,
  29. type: 'file',
  30. ownerId: owner.id,
  31. }).returning();
  32. const [createdMedia] = await db.insert(media).values({
  33. resourceId: resource.id,
  34. filename: `media-list-${suffix}.mp4`,
  35. storageKey: `uploads/media-list-${suffix}.mp4`,
  36. mimeType: 'video/mp4',
  37. size: BigInt(1),
  38. status: 'pending',
  39. }).returning();
  40. createdMediaIds.push(createdMedia.id);
  41. const [completedResource] = await db.insert(resources).values({
  42. name: `media-list-filter-${suffix}.mp4`,
  43. path: `/media-list/filter-${suffix}.mp4`,
  44. type: 'file',
  45. ownerId: owner.id,
  46. }).returning();
  47. const [completedMedia] = await db.insert(media).values({
  48. resourceId: completedResource.id,
  49. filename: `media-list-filter-${suffix}.mp4`,
  50. storageKey: `uploads/media-list-filter-${suffix}.mp4`,
  51. mimeType: 'video/mp4',
  52. size: BigInt(1),
  53. status: 'completed',
  54. }).returning();
  55. createdMediaIds.push(completedMedia.id);
  56. try {
  57. const ownerList = await listMedia({ auth: { userId: owner.id, groupIds: [] } });
  58. const outsiderList = await listMedia({ auth: { userId: outsider.id, groupIds: [] } });
  59. const ownerCanSee = ownerList.some((item) => item.id === createdMedia.id);
  60. const outsiderCanSee = outsiderList.some((item) => item.id === createdMedia.id);
  61. if (!ownerCanSee || outsiderCanSee) {
  62. throw new Error('Media list visibility did not respect ownership permissions.');
  63. }
  64. const queryList = await listMedia({
  65. auth: { userId: owner.id, groupIds: [] },
  66. query: `filter-${suffix}`,
  67. });
  68. const completedList = await listMedia({
  69. auth: { userId: owner.id, groupIds: [] },
  70. status: 'completed',
  71. });
  72. const queryMatched = queryList.some((item) => item.id === completedMedia.id)
  73. && !queryList.some((item) => item.id === createdMedia.id);
  74. const statusMatched = completedList.some((item) => item.id === completedMedia.id)
  75. && !completedList.some((item) => item.id === createdMedia.id);
  76. if (!queryMatched || !statusMatched) {
  77. throw new Error('Media list filters did not match expected results.');
  78. }
  79. } finally {
  80. for (const mediaId of createdMediaIds) {
  81. await cleanupMediaRecord(mediaId);
  82. }
  83. }
  84. console.log('Media list visibility and filters passed.');
  85. process.exit(0);
  86. }
  87. runTest().catch((error) => {
  88. console.error('Test failed with error:', error);
  89. process.exit(1);
  90. });