From f1c4bc6a745c5110b16aff92cfa5851302df2c5d Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Thu, 12 Oct 2023 10:46:12 +0800 Subject: [PATCH 1/3] fix email attachment not being saved as item --- packages/api/src/routers/svc/email_attachment.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/api/src/routers/svc/email_attachment.ts b/packages/api/src/routers/svc/email_attachment.ts index 361a5b16f..d73f1b52c 100644 --- a/packages/api/src/routers/svc/email_attachment.ts +++ b/packages/api/src/routers/svc/email_attachment.ts @@ -61,10 +61,10 @@ export function emailAttachmentRouter() { (tx) => tx.getRepository(UploadFile).save({ url: '', - userId: user.id, - fileName: fileName, + fileName, status: UploadFileStatus.Initialized, contentType: contentType, + user: { id: user.id }, }), undefined, user.id From ebb45f1973b52edf0666ad7241b8f2c4e9995861 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Thu, 12 Oct 2023 10:47:20 +0800 Subject: [PATCH 2/3] fix email attachment not being saved as item --- packages/api/src/routers/svc/email_attachment.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/api/src/routers/svc/email_attachment.ts b/packages/api/src/routers/svc/email_attachment.ts index d73f1b52c..b6c79b33d 100644 --- a/packages/api/src/routers/svc/email_attachment.ts +++ b/packages/api/src/routers/svc/email_attachment.ts @@ -150,7 +150,7 @@ export function emailAttachmentRouter() { ? PageType.File : PageType.Book const title = subject || uploadFileData.fileName - const articleToSave: DeepPartial = { + const itemToCreate: DeepPartial = { originalUrl: uploadFileUrlOverride, itemType, textContentHash: uploadFileHash, @@ -159,9 +159,10 @@ export function emailAttachmentRouter() { readableContent: '', slug: generateSlug(title), state: LibraryItemState.Succeeded, + user: { id: user.id }, } - const pageId = await createLibraryItem(articleToSave, user.id) + const pageId = await createLibraryItem(itemToCreate, user.id) // update received email type await updateReceivedEmail(receivedEmailId, 'article', user.id) From 039632556b1b7f25901ead685d04d60696fdbba9 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Thu, 12 Oct 2023 11:56:54 +0800 Subject: [PATCH 3/3] add more method in mock cloud storage and update test cases for email-attachment rest api --- .../api/src/routers/svc/email_attachment.ts | 6 +-- packages/api/test/mock_storage.ts | 16 +++++++ ...ents.test.ts => email_attachments.test.ts} | 46 +++++++++++++------ 3 files changed, 51 insertions(+), 17 deletions(-) rename packages/api/test/routers/{pdf_attachments.test.ts => email_attachments.test.ts} (54%) diff --git a/packages/api/src/routers/svc/email_attachment.ts b/packages/api/src/routers/svc/email_attachment.ts index b6c79b33d..fde4be36d 100644 --- a/packages/api/src/routers/svc/email_attachment.ts +++ b/packages/api/src/routers/svc/email_attachment.ts @@ -63,7 +63,7 @@ export function emailAttachmentRouter() { url: '', fileName, status: UploadFileStatus.Initialized, - contentType: contentType, + contentType, user: { id: user.id }, }), undefined, @@ -162,12 +162,12 @@ export function emailAttachmentRouter() { user: { id: user.id }, } - const pageId = await createLibraryItem(itemToCreate, user.id) + const item = await createLibraryItem(itemToCreate, user.id) // update received email type await updateReceivedEmail(receivedEmailId, 'article', user.id) - res.send({ id: pageId }) + res.send({ id: item.id }) } catch (err) { logger.info(err) res.status(500).send(err) diff --git a/packages/api/test/mock_storage.ts b/packages/api/test/mock_storage.ts index 00415ab6b..57d0aaf2b 100644 --- a/packages/api/test/mock_storage.ts +++ b/packages/api/test/mock_storage.ts @@ -38,6 +38,22 @@ class MockFile { createWriteStream() { return new MockWriteStream(this) } + + getSignedUrl() { + return ['https://signed-url.upload.omnivore.app'] + } + + getMetadata() { + return [{ md5Hash: 'md5Hash' }] + } + + publicUrl() { + return 'https://public-url.upload.omnivore.app' + } + + makePublic() { + return + } } class MockWriteStream extends Writable { diff --git a/packages/api/test/routers/pdf_attachments.test.ts b/packages/api/test/routers/email_attachments.test.ts similarity index 54% rename from packages/api/test/routers/pdf_attachments.test.ts rename to packages/api/test/routers/email_attachments.test.ts index 80a92be04..f699b6a55 100644 --- a/packages/api/test/routers/pdf_attachments.test.ts +++ b/packages/api/test/routers/email_attachments.test.ts @@ -1,15 +1,19 @@ +import { Storage } from '@google-cloud/storage' import { expect } from 'chai' import * as jwt from 'jsonwebtoken' import 'mocha' +import sinon from 'sinon' +import { NewsletterEmail } from '../../src/entity/newsletter_email' import { User } from '../../src/entity/user' +import { getRepository } from '../../src/repository' import { findLibraryItemById } from '../../src/services/library_item' -import { createNewsletterEmail } from '../../src/services/newsletters' import { deleteUser } from '../../src/services/user' import { createTestUser } from '../db' +import { MockBucket } from '../mock_storage' import { request } from '../util' -describe('PDF attachments Router', () => { - const newsletterEmail = 'fakeEmail@omnivore.app' +describe('Email attachments Router', () => { + const newsletterEmailAddress = 'fakeEmail@omnivore.app' let user: User let authToken: string @@ -18,25 +22,38 @@ describe('PDF attachments Router', () => { // create test user and login user = await createTestUser('fakeUser') - await createNewsletterEmail(user.id, newsletterEmail) - authToken = jwt.sign(newsletterEmail, process.env.JWT_SECRET || '') + await getRepository(NewsletterEmail).save({ + address: newsletterEmailAddress, + user: { id: user.id }, + }) + authToken = jwt.sign(newsletterEmailAddress, process.env.JWT_SECRET || '') + + // mock cloud storage + const mockBucket = new MockBucket('test') + sinon.replace( + Storage.prototype, + 'bucket', + sinon.fake.returns(mockBucket as never) + ) }) after(async () => { // clean up await deleteUser(user.id) + sinon.restore() }) describe('upload', () => { - xit('create upload file request and return id and url', async () => { + it('create upload file request and return id and url', async () => { const testFile = 'testFile.pdf' const res = await request - .post('/svc/pdf-attachments/upload') + .post('/svc/email-attachment/upload') .set('Authorization', `${authToken}`) .send({ - email: newsletterEmail, + email: newsletterEmailAddress, fileName: testFile, + contentType: 'application/pdf', }) .expect(200) @@ -52,22 +69,23 @@ describe('PDF attachments Router', () => { // upload file first const testFile = 'testFile.pdf' const res = await request - .post('/svc/pdf-attachments/upload') + .post('/svc/email-attachment/upload') .set('Authorization', `${authToken}`) .send({ - email: newsletterEmail, + email: newsletterEmailAddress, fileName: testFile, + contentType: 'application/pdf', }) uploadFileId = res.body.id }) - xit('create article with uploaded file id and url', async () => { + it('create article with uploaded file id and url', async () => { // create article const res2 = await request - .post('/svc/pdf-attachments/create-article') + .post('/svc/email-attachment/create-article') .send({ - email: newsletterEmail, - uploadFileId: uploadFileId, + email: newsletterEmailAddress, + uploadFileId, }) .set('Authorization', `${authToken}`) .expect(200)