diff --git a/packages/api/src/datalayer/pubsub.ts b/packages/api/src/datalayer/pubsub.ts index d9208bc9b..fa2e86625 100644 --- a/packages/api/src/datalayer/pubsub.ts +++ b/packages/api/src/datalayer/pubsub.ts @@ -37,8 +37,11 @@ export const createPubSubClient = (): PubsubClient => { Buffer.from(JSON.stringify({ userId, email, name, username })) ) }, - pageSaved: (page: Partial): Promise => { - return publish('pageSaved', Buffer.from(JSON.stringify(page))) + pageSaved: (page: Partial, userId: string): Promise => { + return publish( + 'pageSaved', + Buffer.from(JSON.stringify({ ...page, userId })) + ) }, pageCreated: (page: Page): Promise => { return publish('pageCreated', Buffer.from(JSON.stringify(page))) @@ -70,7 +73,7 @@ export interface PubsubClient { username: string ) => Promise pageCreated: (page: Page) => Promise - pageSaved: (page: Partial) => Promise + pageSaved: (page: Partial, userId: string) => Promise pageDeleted: (id: string, userId: string) => Promise reportSubmitted( submitterId: string | undefined, diff --git a/packages/api/src/elastic/index.ts b/packages/api/src/elastic/index.ts index dda100fa2..043f1d896 100644 --- a/packages/api/src/elastic/index.ts +++ b/packages/api/src/elastic/index.ts @@ -191,7 +191,7 @@ export const updatePage = async ( if (body.result !== 'updated') return false - await ctx.pubsub.pageSaved(page) + await ctx.pubsub.pageSaved(page, ctx.uid) return true } catch (e) { @@ -202,7 +202,6 @@ export const updatePage = async ( export const deletePage = async ( id: string, - userId: string, ctx: PageContext ): Promise => { try { @@ -214,7 +213,7 @@ export const deletePage = async ( if (body.deleted === 0) return false - await ctx.pubsub.pageDeleted(id, userId) + await ctx.pubsub.pageDeleted(id, ctx.uid) return true } catch (e) { diff --git a/packages/api/src/elastic/types.ts b/packages/api/src/elastic/types.ts index 77183312e..5b2649546 100644 --- a/packages/api/src/elastic/types.ts +++ b/packages/api/src/elastic/types.ts @@ -151,4 +151,5 @@ export type ParamSet = PickTuple export interface PageContext { pubsub: PubsubClient refresh?: boolean + uid: string } diff --git a/packages/api/src/resolvers/article/index.ts b/packages/api/src/resolvers/article/index.ts index 8a75be1de..16ec4633a 100644 --- a/packages/api/src/resolvers/article/index.ts +++ b/packages/api/src/resolvers/article/index.ts @@ -330,13 +330,13 @@ export const createArticleResolver = authorized< existingPage.url = uploadFileUrlOverride || articleToSave.url existingPage.hash = articleToSave.hash - await updatePage(existingPage.id, existingPage, ctx) + await updatePage(existingPage.id, existingPage, { ...ctx, uid }) log.info('page updated in elastic', existingPage.id) articleToSave = existingPage } else { // create new page in elastic - const pageId = await createPage(articleToSave, ctx) + const pageId = await createPage(articleToSave, { ...ctx, uid }) if (!pageId) { return articleSavingRequestError( @@ -626,7 +626,7 @@ export const setBookmarkArticleResolver = authorized< return { errorCodes: [SetBookmarkArticleErrorCode.NotFound] } } - await deletePage(userArticleRemoved.id, uid, { pubsub }) + await deletePage(userArticleRemoved.id, { pubsub, uid }) const highlightsUnshared = await authTrx(async (tx) => { return models.highlight.unshareAllHighlights(articleID, uid, tx) @@ -660,7 +660,7 @@ export const setBookmarkArticleResolver = authorized< userId: uid, slug: generateSlug(article.title), } - await updatePage(articleID, userArticle, { pubsub }) + await updatePage(articleID, userArticle, { pubsub, uid }) log.info('Article bookmarked', { article: Object.assign({}, article, { @@ -737,7 +737,7 @@ export const saveArticleReadingProgressResolver = authorized< : userArticleRecord.readingProgressAnchorIndex, }) - shouldUpdate && (await updatePage(id, updatedArticle, { pubsub })) + shouldUpdate && (await updatePage(id, updatedArticle, { pubsub, uid })) return { updatedArticle: { diff --git a/packages/api/src/resolvers/labels/index.ts b/packages/api/src/resolvers/labels/index.ts index f9fc48c26..35a73e483 100644 --- a/packages/api/src/resolvers/labels/index.ts +++ b/packages/api/src/resolvers/labels/index.ts @@ -79,6 +79,7 @@ export const createLabelResolver = authorized< // Check if label already exists ignoring case of name const existingLabel = await getRepository(Label).findOne({ where: { + user, name: ILike(name), }, }) @@ -161,7 +162,10 @@ export const deleteLabelResolver = authorized< } // delete label in elastic pages - await deleteLabelInPages(uid, label.name, { pubsub: createPubSubClient() }) + await deleteLabelInPages(uid, label.name, { + pubsub: createPubSubClient(), + uid, + }) analytics.track({ userId: uid, @@ -225,7 +229,7 @@ export const setLabelsResolver = authorized< { labels, }, - { pubsub } + { pubsub, uid } ) analytics.track({ diff --git a/packages/api/src/resolvers/links/index.ts b/packages/api/src/resolvers/links/index.ts index c1a762221..0f9705908 100644 --- a/packages/api/src/resolvers/links/index.ts +++ b/packages/api/src/resolvers/links/index.ts @@ -81,7 +81,7 @@ export const setLinkArchivedResolver = authorized< { archivedAt: args.input.archived ? new Date() : null, }, - { pubsub } + { pubsub, uid: claims.uid } ) } catch (e) { return { diff --git a/packages/api/src/resolvers/save/index.ts b/packages/api/src/resolvers/save/index.ts index 7b3e9e155..37e35e4bd 100644 --- a/packages/api/src/resolvers/save/index.ts +++ b/packages/api/src/resolvers/save/index.ts @@ -29,7 +29,7 @@ export const savePageResolver = authorized< } return savePage( - ctx, + { ...ctx, uid }, { userId: user.id, username: user.profile.username }, input ) @@ -70,5 +70,5 @@ export const saveFileResolver = authorized< return { errorCodes: [SaveErrorCode.Unauthorized] } } - return (await saveFile(ctx, user, input)) as SaveSuccess + return (await saveFile({ ...ctx, uid }, user, input)) as SaveSuccess }) diff --git a/packages/api/src/routers/svc/content.ts b/packages/api/src/routers/svc/content.ts index 4dfeeb08e..ec89afb85 100644 --- a/packages/api/src/routers/svc/content.ts +++ b/packages/api/src/routers/svc/content.ts @@ -67,6 +67,7 @@ export function contentServiceRouter() { const result = await updatePage(page.id, pageToUpdate, { pubsub: createPubSubClient(), + uid: page.userId, }) console.log( 'Updating article text', diff --git a/packages/api/src/routers/svc/pdf_attachments.ts b/packages/api/src/routers/svc/pdf_attachments.ts index df56c1acb..262a7ae9d 100644 --- a/packages/api/src/routers/svc/pdf_attachments.ts +++ b/packages/api/src/routers/svc/pdf_attachments.ts @@ -159,6 +159,7 @@ export function pdfAttachmentsRouter() { const pageId = await createPage(articleToSave, { pubsub: createPubSubClient(), + uid: user.id, }) res.send({ id: pageId }) diff --git a/packages/api/src/services/labels.ts b/packages/api/src/services/labels.ts index 2b630b373..a7f2a54c2 100644 --- a/packages/api/src/services/labels.ts +++ b/packages/api/src/services/labels.ts @@ -1,7 +1,10 @@ import DataLoader from 'dataloader' import { Label } from '../entity/label' -import { getRepository, In } from 'typeorm' +import { getRepository, ILike, In } from 'typeorm' import { Link } from '../entity/link' +import { updatePage } from '../elastic' +import { PageContext } from '../elastic/types' +import { User } from '../entity/user' const batchGetLabelsFromLinkIds = async ( linkIds: readonly string[] @@ -17,3 +20,41 @@ const batchGetLabelsFromLinkIds = async ( } export const labelsLoader = new DataLoader(batchGetLabelsFromLinkIds) + +export const addLabelToPage = async ( + ctx: PageContext, + pageId: string, + label: { + name: string + color: string + description?: string + } +): Promise => { + const user = await getRepository(User).findOne(ctx.uid) + + let labelEntity = await getRepository(Label).findOne({ + where: { + user: user, + name: ILike(label.name), + }, + }) + + if (!labelEntity) { + console.log('creating new label', label.name) + + labelEntity = await getRepository(Label).save({ + ...label, + user, + }) + } + + console.log('adding label to page', label.name, pageId) + + return updatePage( + pageId, + { + labels: [labelEntity], + }, + ctx + ) +} diff --git a/packages/api/src/services/save_email.ts b/packages/api/src/services/save_email.ts index b93d697f7..8d3799843 100644 --- a/packages/api/src/services/save_email.ts +++ b/packages/api/src/services/save_email.ts @@ -1,5 +1,3 @@ -import { PubsubClient } from '../datalayer/pubsub' -import { DataModels } from '../resolvers/types' import { generateSlug, stringToHash, validatedDate } from '../utils/helpers' import { parseOriginalContent, @@ -7,13 +5,13 @@ import { parseUrlMetadata, } from '../utils/parser' import normalizeUrl from 'normalize-url' -import { kx } from '../datalayer/knex_config' -import { UserArticleData } from '../datalayer/links/model' -import { setClaims } from '../datalayer/helpers' +import { PubsubClient } from '../datalayer/pubsub' +import { Page } from '../elastic/types' +import { createPage, getPageByParam, updatePage } from '../elastic' export type SaveContext = { pubsub: PubsubClient - models: DataModels + uid: string } export type SaveEmailInput = { @@ -25,9 +23,8 @@ export type SaveEmailInput = { export const saveEmail = async ( ctx: SaveContext, - saverId: string, input: SaveEmailInput -): Promise => { +): Promise => { const url = input.url const parseResult = await parsePreparedContent( url, @@ -47,7 +44,9 @@ export const saveEmail = async ( const pageType = parseOriginalContent(url, input.originalContent) const metadata = await parseUrlMetadata(url) - const articleToSave = { + const articleToSave: Page = { + id: '', + userId: ctx.uid, originalHtml: input.originalContent, content: content, description: metadata?.description || parseResult.parsedContent?.excerpt, @@ -62,58 +61,27 @@ export const saveEmail = async ( hash: stringToHash(content), image: metadata?.previewImage || parseResult.parsedContent?.previewImage, publishedAt: validatedDate(parseResult.parsedContent?.publishedDate), + slug: slug, + createdAt: new Date(), } - if (parseResult.canonicalUrl && parseResult.domContent) { - // await ctx.pubsub.pageSaved( - // saverId, - // parseResult.canonicalUrl, - // parseResult.domContent - // ) + const page = await getPageByParam({ url: articleToSave.url }) + if (page) { + const result = await updatePage(page.id, { archivedAt: null }, ctx) + console.log('updated page from email', result) + + return page } - const matchedUserArticleRecord = await ctx.models.userArticle.getByParameters( - saverId, - { - articleUrl: articleToSave.url, - } - ) + const pageId = await createPage(articleToSave, ctx) + if (!pageId) { + console.log('failed to create new page') - let result: UserArticleData | undefined = undefined - if (matchedUserArticleRecord) { - // await ctx.pubsub.pageCreated(saverId, url, input.originalContent) - - await kx.transaction(async (tx) => { - await setClaims(tx, saverId) - result = await ctx.models.userArticle.update( - matchedUserArticleRecord.id, - { - savedAt: new Date(), - archivedAt: null, - } - ) - }) - console.log('created matched email', result) - } else { - // await ctx.pubsub.pageCreated(saverId, url, input.originalContent) - - await kx.transaction(async (tx) => { - await setClaims(tx, saverId) - - const articleRecord = await ctx.models.article.create(articleToSave, tx) - result = await ctx.models.userArticle.create( - { - userId: saverId, - slug: slug, - articleId: articleRecord.id, - articleUrl: articleRecord.url, - articleHash: articleRecord.hash, - }, - tx - ) - console.log('created new email', result) - }) + return undefined } - return result + console.log('created new page from email', pageId) + articleToSave.id = pageId + + return articleToSave } diff --git a/packages/api/src/services/save_file.ts b/packages/api/src/services/save_file.ts index 21735a6eb..15a8ba49e 100644 --- a/packages/api/src/services/save_file.ts +++ b/packages/api/src/services/save_file.ts @@ -22,6 +22,7 @@ type SaveContext = { cb: (tx: Knex.Transaction) => TResult, userRole?: string ) => Promise + uid: string } export const saveFile = async ( @@ -44,11 +45,7 @@ export const saveFile = async ( } } - const savingRequest = await createSavingRequest( - ctx, - saver.id, - input.clientRequestId - ) + const savingRequest = await createSavingRequest(ctx, input.clientRequestId) const uploadFileDetails = await getStorageFileDetails( input.uploadFileId, diff --git a/packages/api/src/services/save_newsletter_email.ts b/packages/api/src/services/save_newsletter_email.ts index 777cfc62f..039082d34 100644 --- a/packages/api/src/services/save_newsletter_email.ts +++ b/packages/api/src/services/save_newsletter_email.ts @@ -1,17 +1,15 @@ import { MulticastMessage } from 'firebase-admin/messaging' -import { kx } from '../datalayer/knex_config' import { createPubSubClient } from '../datalayer/pubsub' import { UserDeviceToken } from '../entity/user_device_tokens' import { env } from '../env' import { ContentReader } from '../generated/graphql' -import { initModels } from '../server' import { analytics } from '../utils/analytics' import { sendMulticastPushNotifications } from '../utils/sendNotification' import { getNewsletterEmail } from './newsletters' import { SaveContext, saveEmail, SaveEmailInput } from './save_email' import { getDeviceTokensByUserId } from './user_device_tokens' -import { getPageByParam } from '../elastic' import { Page } from '../elastic/types' +import { addLabelToPage } from './labels' interface NewsletterMessage { email: string @@ -46,9 +44,10 @@ export const saveNewsletterEmail = async ( }) const ctx: SaveContext = { - models: initModels(kx, false), pubsub: createPubSubClient(), + uid: newsletterEmail.user.id, } + const input: SaveEmailInput = { url: data.url, originalContent: data.content, @@ -56,12 +55,19 @@ export const saveNewsletterEmail = async ( author: data.author, } - const result = await saveEmail(ctx, newsletterEmail.user.id, input) - if (!result) { + const page = await saveEmail(ctx, input) + if (!page) { console.log('newsletter not created:', input) return false } + // add newsletters label to page + const result = await addLabelToPage(ctx, page.id, { + name: 'Newsletter', + color: '#07D2D1', + }) + console.log('newsletter label added:', result) + // send push notification const deviceTokens = await getDeviceTokensByUserId(newsletterEmail.user.id) @@ -70,22 +76,8 @@ export const saveNewsletterEmail = async ( return true } - const link = await getPageByParam({ - _id: result.articleId, - userId: newsletterEmail.user.id, - }) - - if (!link) { - console.log( - 'Newsletter link not found:', - newsletterEmail.user.id, - result.articleId - ) - return true - } - if (deviceTokens.length) { - const multicastMessage = messageForLink(link, deviceTokens) + const multicastMessage = messageForLink(page, deviceTokens) await sendMulticastPushNotifications( newsletterEmail.user.id, multicastMessage, diff --git a/packages/api/src/services/save_page.ts b/packages/api/src/services/save_page.ts index e82b12acc..8672b1958 100644 --- a/packages/api/src/services/save_page.ts +++ b/packages/api/src/services/save_page.ts @@ -20,6 +20,7 @@ import { Page } from '../elastic/types' type SaveContext = { pubsub: PubsubClient models: DataModels + uid: string } type SaverUserData = { @@ -56,11 +57,10 @@ const shouldParseInBackend = (input: SavePageInput): boolean => { export const createSavingRequest = ( ctx: SaveContext, - userId: string, clientRequestId: string ) => { return ctx.models.articleSavingRequest.create({ - userId: userId, + userId: ctx.uid, id: clientRequestId, }) } @@ -70,11 +70,7 @@ export const savePage = async ( saver: SaverUserData, input: SavePageInput ): Promise => { - const savingRequest = await createSavingRequest( - ctx, - saver.userId, - input.clientRequestId - ) + const savingRequest = await createSavingRequest(ctx, input.clientRequestId) const [slug, croppedPathname] = createSlug(input.url, input.title) const parseResult = await parsePreparedContent(input.url, { diff --git a/packages/api/test/elastic/index.test.ts b/packages/api/test/elastic/index.test.ts index 2b1bb828c..a71a25193 100644 --- a/packages/api/test/elastic/index.test.ts +++ b/packages/api/test/elastic/index.test.ts @@ -14,8 +14,12 @@ import { Page, PageContext } from '../../src/elastic/types' import { createPubSubClient } from '../../src/datalayer/pubsub' describe('elastic api', () => { - const ctx: PageContext = { pubsub: createPubSubClient(), refresh: true } const userId = 'userId' + const ctx: PageContext = { + pubsub: createPubSubClient(), + refresh: true, + uid: userId, + } let page: Page @@ -59,7 +63,7 @@ describe('elastic api', () => { after(async () => { // delete the testing page - await deletePage(page.id, userId, ctx) + await deletePage(page.id, ctx) }) describe('createPage', () => { @@ -67,7 +71,7 @@ describe('elastic api', () => { after(async () => { if (newPageId) { - await deletePage(newPageId, userId, ctx) + await deletePage(newPageId, ctx) } }) diff --git a/packages/api/test/resolvers/article.test.ts b/packages/api/test/resolvers/article.test.ts index 540062baa..ecacfffc9 100644 --- a/packages/api/test/resolvers/article.test.ts +++ b/packages/api/test/resolvers/article.test.ts @@ -25,7 +25,6 @@ import { createPubSubClient } from '../../src/datalayer/pubsub' chai.use(chaiString) -const ctx: PageContext = { pubsub: createPubSubClient(), refresh: true } const archiveLink = async (authToken: string, linkId: string) => { const query = ` mutation { @@ -244,6 +243,7 @@ describe('Article API', () => { const username = 'fakeUser' let authToken: string let user: User + let ctx: PageContext before(async () => { // create test user and login @@ -253,6 +253,12 @@ describe('Article API', () => { .send({ fakeEmail: user.email }) authToken = res.body.authToken + + ctx = { + pubsub: createPubSubClient(), + refresh: true, + uid: user.id, + } }) after(async () => { @@ -281,7 +287,7 @@ describe('Article API', () => { }) after(async () => { - await deletePage(pageId, user.id, ctx) + await deletePage(pageId, ctx) }) it('should create an article', async () => { @@ -320,7 +326,7 @@ describe('Article API', () => { after(async () => { if (pageId) { - await deletePage(pageId, user.id, ctx) + await deletePage(pageId, ctx) } }) @@ -390,7 +396,6 @@ describe('Article API', () => { await updatePage( pages[0].id, { - ...pages[0], labels: [{ id: label.id, name: label.name, color: label.color }], }, ctx @@ -564,7 +569,7 @@ describe('Article API', () => { after(async () => { if (pageId) { - await deletePage(pageId, user.id, ctx) + await deletePage(pageId, ctx) } }) @@ -612,7 +617,7 @@ describe('Article API', () => { after(async () => { if (pageId) { - await deletePage(pageId, user.id, ctx) + await deletePage(pageId, ctx) } }) diff --git a/packages/api/test/resolvers/highlight.test.ts b/packages/api/test/resolvers/highlight.test.ts index d2bc559e4..b919a19fb 100644 --- a/packages/api/test/resolvers/highlight.test.ts +++ b/packages/api/test/resolvers/highlight.test.ts @@ -12,10 +12,10 @@ import { User } from '../../src/entity/user' import chaiString from 'chai-string' import { deletePage } from '../../src/elastic' import { createPubSubClient } from '../../src/datalayer/pubsub' +import { PageContext } from '../../src/elastic/types' chai.use(chaiString) -const ctx = { pubsub: createPubSubClient() } const createHighlightQuery = ( authToken: string, linkId: string, @@ -57,6 +57,7 @@ describe('Highlights API', () => { let authToken: string let user: User let pageId: string + let ctx: PageContext before(async () => { // create test user and login @@ -67,12 +68,13 @@ describe('Highlights API', () => { authToken = res.body.authToken pageId = (await createTestElasticPage(user)).id + ctx = { pubsub: createPubSubClient(), uid: user.id } }) after(async () => { await deleteTestUser(username) if (pageId) { - await deletePage(pageId, user.id, ctx) + await deletePage(pageId, ctx) } }) diff --git a/packages/api/test/services/save_email.test.ts b/packages/api/test/services/save_email.test.ts index 586a60dab..1f08cf75b 100644 --- a/packages/api/test/services/save_email.test.ts +++ b/packages/api/test/services/save_email.test.ts @@ -1,16 +1,10 @@ import 'mocha' import { expect } from 'chai' import 'chai/register-should' -import { - createTestUser, - deleteTestUser, -} from '../db' +import { createTestUser, deleteTestUser } from '../db' import { SaveContext, saveEmail } from '../../src/services/save_email' -import { getRepository } from 'typeorm' -import { Link } from '../../src/entity/link' -import { initModels } from '../../src/server' -import { kx } from '../../src/datalayer/knex_config' import { createPubSubClient } from '../../src/datalayer/pubsub' +import { getPageByParam } from '../../src/elastic' describe('saveEmail', () => { const username = 'fakeUser' @@ -21,11 +15,11 @@ describe('saveEmail', () => { it('doesnt fail if saved twice', async () => { const user = await createTestUser(username) const ctx: SaveContext = { - models: initModels(kx, false), pubsub: createPubSubClient(), + uid: user.id, } - await saveEmail(ctx, user.id, { + await saveEmail(ctx, { originalContent: 'fake content', url: 'https://example.com', title: 'fake title', @@ -34,7 +28,7 @@ describe('saveEmail', () => { // This ensures row level security doesnt prevent // resaving the same URL - const secondResult = await saveEmail(ctx, user.id, { + const secondResult = await saveEmail(ctx, { originalContent: 'fake content', url: 'https://example.com', title: 'fake title', @@ -42,17 +36,15 @@ describe('saveEmail', () => { }) expect(secondResult).to.not.be.undefined - const links = await getRepository(Link).find({ - where: { - user: user, - }, - relations: ['page'], + setTimeout(async () => { + const page = await getPageByParam({ userId: user.id }) + if (!page) { + expect.fail('page not found') + } + expect(page.url).to.equal('https://example.com') + expect(page.title).to.equal('fake title') + expect(page.author).to.equal('fake author') + expect(page.content).to.contain('fake content') }) - - expect(links.length).to.equal(1) - expect(links[0].page.url).to.equal('https://example.com') - expect(links[0].page.title).to.equal('fake title') - expect(links[0].page.author).to.equal('fake author') - expect(links[0].page.content).to.contain('fake content') - }).timeout(10000) + }) }) diff --git a/packages/api/test/services/save_newsletter_email.test.ts b/packages/api/test/services/save_newsletter_email.test.ts index bf29de3ac..c1bb7b287 100644 --- a/packages/api/test/services/save_newsletter_email.test.ts +++ b/packages/api/test/services/save_newsletter_email.test.ts @@ -1,14 +1,10 @@ import 'mocha' import { expect } from 'chai' import 'chai/register-should' -import { - createTestUser, - deleteTestUser, -} from '../db' +import { createTestUser, deleteTestUser } from '../db' import { createNewsletterEmail } from '../../src/services/newsletters' import { saveNewsletterEmail } from '../../src/services/save_newsletter_email' -import { getRepository } from 'typeorm' -import { Link } from '../../src/entity/link' +import { getPageByParam } from '../../src/elastic' describe('saveNewsletterEmail', () => { const username = 'fakeUser' @@ -28,17 +24,15 @@ describe('saveNewsletterEmail', () => { author: 'fake author', }) - const links = await getRepository(Link).find({ - where: { - user: user, - }, - relations: ['page'], + setTimeout(async () => { + const page = await getPageByParam({ userId: user.id }) + if (!page) { + expect.fail('page not found') + } + expect(page.url).to.equal('https://example.com') + expect(page.title).to.equal('fake title') + expect(page.author).to.equal('fake author') + expect(page.content).to.contain('fake content') }) - - expect(links.length).to.equal(1) - expect(links[0].page.url).to.equal('https://example.com') - expect(links[0].page.title).to.equal('fake title') - expect(links[0].page.author).to.equal('fake author') - expect(links[0].page.content).to.contain('fake content') - }).timeout(10000) + }) }) diff --git a/packages/api/test/util.ts b/packages/api/test/util.ts index 013c30f15..95c53eebf 100644 --- a/packages/api/test/util.ts +++ b/packages/api/test/util.ts @@ -55,6 +55,7 @@ export const createTestElasticPage = async ( const pageId = await createPage(page, { pubsub: createPubSubClient(), refresh: true, + uid: user.id, }) if (pageId) { page.id = pageId