add tests for create article

This commit is contained in:
Hongbo Wu 2022-02-16 16:14:14 +08:00
parent 77ba7531f3
commit d53e94aeb2
5 changed files with 151 additions and 78 deletions

View file

@ -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

View file

@ -196,3 +196,7 @@ export const getDeviceToken = async (
export const getUser = async (id: string): Promise<User | undefined> => {
return getRepository(User).findOne(id)
}
export const getLink = async (id: string): Promise<Link | undefined> => {
return getRepository(Link).findOne(id)
}

View file

@ -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
})
})
})

View file

@ -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;

View file

@ -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;