2e86a723c6
* feat(fileimport-service): add next gen file importer * feat(fileimports): integrate server and fileimporter * chore(dui3): remove leftover artifacts * fix(server): test typing fixes * fix(fileimports): test and pr comment fixes * feat(fileimports: moare test fixes * fix(fileimports): tests and yarn dedupe
140 lines
5.0 KiB
TypeScript
140 lines
5.0 KiB
TypeScript
import cryptoRandomString from 'crypto-random-string'
|
|
import { db } from '@/db/knex'
|
|
import { getStreamBranchByNameFactory } from '@/modules/core/repositories/branches'
|
|
import {
|
|
getFileInfoFactory,
|
|
saveUploadFileFactory
|
|
} from '@/modules/fileuploads/repositories/fileUploads'
|
|
import { insertNewUploadAndNotifyFactory } from '@/modules/fileuploads/services/management'
|
|
import { publish } from '@/modules/shared/utils/subscriptions'
|
|
import { testLogger as logger } from '@/observability/logging'
|
|
import { sleep } from '@/test/helpers'
|
|
import { expect } from 'chai'
|
|
import { FileUploadConvertedStatus } from '@/modules/fileuploads/helpers/types'
|
|
import { TIME } from '@speckle/shared'
|
|
import { initUploadTestEnvironment } from '@/modules/fileuploads/tests/helpers/init'
|
|
import { pushJobToFileImporterFactory } from '@/modules/fileuploads/services/createFileImport'
|
|
import { assign } from 'lodash'
|
|
import { buildFileUploadMessage } from '@/modules/fileuploads/tests/helpers/creation'
|
|
import { getFeatureFlags } from '@speckle/shared/environment'
|
|
import { JobPayload } from '@speckle/shared/workers/fileimport'
|
|
|
|
const { createStream, createUser, garbageCollector } = initUploadTestEnvironment()
|
|
|
|
const { FF_NEXT_GEN_FILE_IMPORTER_ENABLED } = getFeatureFlags()
|
|
|
|
describe('FileUploads @fileuploads', () => {
|
|
const userOne = {
|
|
name: cryptoRandomString({ length: 10 }),
|
|
email: `${cryptoRandomString({ length: 10 })}@example.org`,
|
|
password: cryptoRandomString({ length: 10 })
|
|
}
|
|
|
|
let userOneId: string
|
|
let createdStreamId: string
|
|
|
|
before(async () => {
|
|
userOneId = await createUser(userOne)
|
|
})
|
|
|
|
beforeEach(async () => {
|
|
createdStreamId = await createStream({ ownerId: userOneId })
|
|
})
|
|
afterEach(async () => {
|
|
createdStreamId = ''
|
|
})
|
|
|
|
describe('Convert files', () => {
|
|
it('Should garbage collect expired files', async () => {
|
|
const insertNewUploadAndNotify = insertNewUploadAndNotifyFactory({
|
|
getStreamBranchByName: getStreamBranchByNameFactory({ db }),
|
|
saveUploadFile: saveUploadFileFactory({ db }),
|
|
publish
|
|
})
|
|
const fileId = cryptoRandomString({ length: 10 })
|
|
await insertNewUploadAndNotify({
|
|
streamId: createdStreamId,
|
|
branchName: 'main',
|
|
userId: userOneId,
|
|
fileId,
|
|
fileName: 'testfile.txt',
|
|
fileSize: 100,
|
|
fileType: 'text/plain'
|
|
})
|
|
await sleep(2000)
|
|
await garbageCollector({ logger, timeoutThresholdSeconds: 1 })
|
|
const results = await getFileInfoFactory({ db })({ fileId })
|
|
if (!results) {
|
|
expect(results).to.not.be.undefined
|
|
return //HACK to appease typescript
|
|
}
|
|
expect(results.convertedStatus).to.be.equal(FileUploadConvertedStatus.Error)
|
|
})
|
|
|
|
it('Should not garbage collect files that are not expired', async () => {
|
|
const insertNewUploadAndNotify = insertNewUploadAndNotifyFactory({
|
|
getStreamBranchByName: getStreamBranchByNameFactory({ db }),
|
|
saveUploadFile: saveUploadFileFactory({ db }),
|
|
publish
|
|
})
|
|
const fileId = cryptoRandomString({ length: 10 })
|
|
await insertNewUploadAndNotify({
|
|
streamId: createdStreamId,
|
|
branchName: 'main',
|
|
userId: userOneId,
|
|
fileId,
|
|
fileName: 'testfile.txt',
|
|
fileSize: 100,
|
|
fileType: 'text/plain'
|
|
})
|
|
// timeout far in the future, so it won't be garbage collected
|
|
await garbageCollector({ logger, timeoutThresholdSeconds: 1 * TIME.hour })
|
|
const results = await getFileInfoFactory({ db })({ fileId })
|
|
if (!results) {
|
|
expect(results).to.not.be.undefined
|
|
return //HACK to appease typescript
|
|
}
|
|
expect(results.convertedStatus).to.be.equal(FileUploadConvertedStatus.Queued)
|
|
})
|
|
})
|
|
;(FF_NEXT_GEN_FILE_IMPORTER_ENABLED ? describe : describe.skip)(
|
|
'how file upload pushes a message to file-import service',
|
|
() => {
|
|
it('uses a fn that given the necessary ids, tokens and url pushes a message to the queue', async () => {
|
|
let usedUserId = undefined
|
|
const result = {}
|
|
const token = cryptoRandomString({ length: 40 })
|
|
const serverOrigin = `https://${cryptoRandomString({ length: 10 })}`
|
|
const upload = buildFileUploadMessage()
|
|
|
|
const pushJobToFileImporter = pushJobToFileImporterFactory({
|
|
getServerOrigin: () => serverOrigin,
|
|
scheduleJob: async (jobData) => {
|
|
assign(result, jobData)
|
|
},
|
|
createAppToken: (args) => {
|
|
usedUserId = args.userId
|
|
return Promise.resolve(token)
|
|
}
|
|
})
|
|
|
|
await pushJobToFileImporter(upload)
|
|
|
|
expect(usedUserId).to.equal(upload.userId)
|
|
const expected: JobPayload = {
|
|
jobId: upload.jobId,
|
|
fileName: upload.fileName,
|
|
token,
|
|
serverUrl: serverOrigin,
|
|
modelId: upload.modelId,
|
|
fileType: upload.fileType,
|
|
projectId: upload.projectId,
|
|
timeOutSeconds: 1200,
|
|
blobId: upload.blobId
|
|
}
|
|
expect(result).to.deep.equal(expected)
|
|
})
|
|
}
|
|
)
|
|
})
|