From d53e94aeb21cba30761c8528a1e661c4d0adfb4f Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Wed, 16 Feb 2022 16:14:14 +0800 Subject: [PATCH] add tests for create article --- .../api/src/routers/svc/pdf_attachments.ts | 165 ++++++++++-------- packages/api/test/db.ts | 4 + .../api/test/routers/pdf_attachments.test.ts | 33 +++- ...ete_cascade_on_upload_file_id_to_pages.sql | 14 ++ ...ete_cascade_on_upload_file_id_to_pages.sql | 13 ++ 5 files changed, 151 insertions(+), 78 deletions(-) create mode 100755 packages/db/migrations/0069.do.add_delete_cascade_on_upload_file_id_to_pages.sql create mode 100755 packages/db/migrations/0069.undo.add_delete_cascade_on_upload_file_id_to_pages.sql diff --git a/packages/api/src/routers/svc/pdf_attachments.ts b/packages/api/src/routers/svc/pdf_attachments.ts index 356589267..6ec01d68a 100644 --- a/packages/api/src/routers/svc/pdf_attachments.ts +++ b/packages/api/src/routers/svc/pdf_attachments.ts @@ -11,7 +11,6 @@ import { import { initModels } from '../../server' import { kx } from '../../datalayer/knex_config' import { analytics } from '../../utils/analytics' -import normalizeUrl from 'normalize-url' import { getNewsletterEmail } from '../../services/newsletters' export function pdfAttachmentsRouter() { @@ -46,31 +45,36 @@ export function pdfAttachmentsRouter() { }, }) - const contentType = 'application/pdf' - const models = initModels(kx, false) - const uploadFileData = await models.uploadFile.create({ - url: '', - userId: user.id, - fileName: fileName, - status: UploadFileStatus.Initialized, - contentType: contentType, - }) - - if (uploadFileData.id) { - const uploadFilePathName = generateUploadFilePathName( - uploadFileData.id, - fileName - ) - const uploadSignedUrl = - env.server.apiEnv === 'prod' - ? await generateUploadSignedUrl(uploadFilePathName, contentType) - : 'http://localhost:3000/uploads/' + uploadFilePathName - res.send({ - id: uploadFileData.id, - url: uploadSignedUrl, + try { + const contentType = 'application/pdf' + const models = initModels(kx, false) + const uploadFileData = await models.uploadFile.create({ + url: '', + userId: user.id, + fileName: fileName, + status: UploadFileStatus.Initialized, + contentType: contentType, }) - } else { - res.status(400).send('BAD REQUEST') + + if (uploadFileData.id) { + const uploadFilePathName = generateUploadFilePathName( + uploadFileData.id, + fileName + ) + const uploadSignedUrl = + env.server.apiEnv === 'prod' + ? await generateUploadSignedUrl(uploadFilePathName, contentType) + : 'http://localhost:3000/uploads/' + uploadFilePathName + res.send({ + id: uploadFileData.id, + url: uploadSignedUrl, + }) + } else { + res.status(400).send('BAD REQUEST') + } + } catch (err) { + console.error(err) + return res.status(500).send('INTERNAL_SERVER_ERROR') } }) @@ -103,63 +107,70 @@ export function pdfAttachmentsRouter() { }, }) - const models = initModels(kx, false) - const uploadFile = await models.uploadFile.getWhere({ - id: uploadFileId, - userId: user.id, - }) - if (!uploadFile) { - return res.status(400).send('BAD REQUEST') - } - const uploadFileDetails = await getStorageFileDetails( - uploadFileId, - uploadFile.fileName - ) - const uploadFileHash = uploadFileDetails.md5Hash - const canonicalUrl = uploadFile.url - const pageType = PageType.File + try { + const models = initModels(kx, false) + const uploadFile = await models.uploadFile.getWhere({ + id: uploadFileId, + userId: user.id, + }) + if (!uploadFile) { + return res.status(400).send('BAD REQUEST') + } - const saveTime = new Date() - const articleToSave = { - url: normalizeUrl(canonicalUrl, { - stripHash: true, - stripWWW: false, - }), - pageType: pageType, - hash: uploadFileHash, - uploadFileId: uploadFileId, - title: uploadFile.fileName, - content: '', - } + const uploadFileDetails = + env.server.apiEnv === 'prod' + ? await getStorageFileDetails(uploadFileId, uploadFile.fileName) + : { md5Hash: '', size: 0 } + const uploadFileHash = uploadFileDetails.md5Hash + const pageType = PageType.File - const uploadFileData = await models.uploadFile.setFileUploadComplete( - uploadFileId - ) - if (!uploadFileData || !uploadFileData.id || !uploadFileData.fileName) { - return res.status(400).send('BAD REQUEST') - } + const saveTime = new Date() + const articleToSave = { + url: '', + pageType: pageType, + hash: uploadFileHash, + uploadFileId: uploadFileId, + title: uploadFile.fileName, + content: '', + } - const uploadFileUrlOverride = await makeStorageFilePublic( - uploadFileData.id, - uploadFileData.fileName - ) - - await kx.transaction(async (tx) => { - const articleRecord = await models.article.create(articleToSave, tx) - await models.userArticle.create( - { - userId: user.id, - slug: '', - savedAt: saveTime, - articleId: articleRecord.id, - articleUrl: uploadFileUrlOverride, - articleHash: articleRecord.hash, - }, - tx + const uploadFileData = await models.uploadFile.setFileUploadComplete( + uploadFileId ) - }) + if (!uploadFileData || !uploadFileData.id || !uploadFileData.fileName) { + return res.status(400).send('BAD REQUEST') + } - res.send('OK') + const uploadFileUrlOverride = + env.server.apiEnv === 'prod' + ? await makeStorageFilePublic( + uploadFileData.id, + uploadFileData.fileName + ) + : 'http://localhost:3000/uploads/' + + uploadFileData.id + + '/' + + uploadFileData.fileName + + const link = await kx.transaction(async (tx) => { + const articleRecord = await models.article.create(articleToSave, tx) + return models.userArticle.create( + { + userId: user.id, + slug: '', + savedAt: saveTime, + articleId: articleRecord.id, + articleUrl: uploadFileUrlOverride, + articleHash: articleRecord.hash, + }, + tx + ) + }) + res.send({ id: link.id }) + } catch (err) { + console.log(err) + res.status(500).send(err) + } }) return router diff --git a/packages/api/test/db.ts b/packages/api/test/db.ts index d405472aa..68596e748 100644 --- a/packages/api/test/db.ts +++ b/packages/api/test/db.ts @@ -196,3 +196,7 @@ export const getDeviceToken = async ( export const getUser = async (id: string): Promise => { return getRepository(User).findOne(id) } + +export const getLink = async (id: string): Promise => { + return getRepository(Link).findOne(id) +} diff --git a/packages/api/test/routers/pdf_attachments.test.ts b/packages/api/test/routers/pdf_attachments.test.ts index ee1ee0152..6e9756f41 100644 --- a/packages/api/test/routers/pdf_attachments.test.ts +++ b/packages/api/test/routers/pdf_attachments.test.ts @@ -2,6 +2,7 @@ import { createTestNewsletterEmail, createTestUser, deleteTestUser, + getLink, } from '../db' import { request } from '../util' import { User } from '../../src/entity/user' @@ -35,15 +36,45 @@ describe('PDF attachments Router', () => { const res = await request .post('/svc/pdf-attachments/upload') + .set('Authorization', `${authToken}`) .send({ email: newsletterEmail, fileName: testFile, }) - .set('Authorization', `${authToken}`) .expect(200) expect(res.body.id).to.be.a('string') expect(res.body.url).to.be.a('string') }) }) + + describe('create article', () => { + it('create article with uploaded file id and url', async () => { + // upload file first + const testFile = 'testFile.pdf' + const res = await request + .post('/svc/pdf-attachments/upload') + .set('Authorization', `${authToken}`) + .send({ + email: newsletterEmail, + fileName: testFile, + }) + const uploadFileId = res.body.id + + // create article + const res2 = await request + .post('/svc/pdf-attachments/create-article') + .send({ + email: newsletterEmail, + uploadFileId: uploadFileId, + }) + .set('Authorization', `${authToken}`) + .expect(200) + + expect(res2.body.id).to.be.a('string') + const link = await getLink(res2.body.id) + + expect(link).to.exist + }) + }) }) diff --git a/packages/db/migrations/0069.do.add_delete_cascade_on_upload_file_id_to_pages.sql b/packages/db/migrations/0069.do.add_delete_cascade_on_upload_file_id_to_pages.sql new file mode 100755 index 000000000..0249065f3 --- /dev/null +++ b/packages/db/migrations/0069.do.add_delete_cascade_on_upload_file_id_to_pages.sql @@ -0,0 +1,14 @@ +-- Type: DO +-- Name: add_delete_cascade_on_upload_file_id_to_pages +-- Description: Add delete cascade on upload_file_id field on pages table + +BEGIN; + +ALTER TABLE omnivore.pages + DROP CONSTRAINT article_upload_file_id_fkey, + ADD CONSTRAINT pages_upload_file_id_fkey + FOREIGN KEY (upload_file_id) + REFERENCES omnivore.upload_files (id) + ON DELETE CASCADE; + +COMMIT; diff --git a/packages/db/migrations/0069.undo.add_delete_cascade_on_upload_file_id_to_pages.sql b/packages/db/migrations/0069.undo.add_delete_cascade_on_upload_file_id_to_pages.sql new file mode 100755 index 000000000..d9006dcf0 --- /dev/null +++ b/packages/db/migrations/0069.undo.add_delete_cascade_on_upload_file_id_to_pages.sql @@ -0,0 +1,13 @@ +-- Type: UNDO +-- Name: add_delete_cascade_on_upload_file_id_to_pages +-- Description: Add delete cascade on upload_file_id field on pages table + +BEGIN; + +ALTER TABLE omnivore.pages + DROP CONSTRAINT pages_upload_file_id_fkey, + ADD CONSTRAINT article_upload_file_id_fkey + FOREIGN KEY (upload_file_id) + REFERENCES omnivore.upload_files (id); + +COMMIT;