Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NET-10]: Test/e2e #120

Open
wants to merge 28 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
fb54eff
feat(buckets-router): add validation for parameters in getFileInfo
fabioespinosa Jul 9, 2022
1168e7a
feat(buckets-router): add validation for empty array in startUpload
fabioespinosa Jul 9, 2022
16d76e8
fix(buckets-router): fix error message for multipart
fabioespinosa Jul 9, 2022
6e5c40f
feat(buckets-router): contemplate special error case for multiparts
fabioespinosa Jul 9, 2022
dd74c3e
fix(buckets-router): remove detailed error message on usecase for mul…
fabioespinosa Jul 9, 2022
9738d3e
test(e2e): add config for e2e tests
fabioespinosa Jul 9, 2022
bcafd15
test(e2e): add setup for e2e tests
fabioespinosa Jul 9, 2022
a30fec2
test(e2e): add validation and functional tests for startUpload
fabioespinosa Jul 9, 2022
8be870d
test(e2e): add validation and functional tests for finishUpload
fabioespinosa Jul 9, 2022
e99a961
test(e2e): add e2e tests for download v1 and v2
fabioespinosa Jul 9, 2022
e38092a
test(finishUpload): add test for successful upload
fabioespinosa Jul 12, 2022
0b9ded9
Merge branch 'master' into test/e2e
fabioespinosa Jul 13, 2022
9376e98
Revert "[_]: Test/repositories"
fabioespinosa Jul 13, 2022
534e279
Merge pull request #121 from internxt/revert-114-test/repositories
fabioespinosa Jul 13, 2022
2824c2c
finishUpload
fabioespinosa Jul 13, 2022
01b27fe
Merge branch 'master' of https://github.com/internxt/bridge
fabioespinosa Jul 13, 2022
eecafd1
chore(e2e): remove .test from files so that they only work with e2e-s…
fabioespinosa Jul 14, 2022
b11e5ab
feat(e2e): add reusable method of starting upload correctly
fabioespinosa Jul 14, 2022
cad71da
test(e2e): test multipart working correctly
fabioespinosa Jul 14, 2022
0da939e
test(e2e): test getFiles (used in photos)
fabioespinosa Jul 14, 2022
1660585
test(e2e): test download links v1 and v2
fabioespinosa Jul 14, 2022
4ee336e
test(e2e): test finishUpload
fabioespinosa Jul 14, 2022
94cd29a
feat(e2e): setup for uploading a random file
fabioespinosa Jul 14, 2022
4afd861
fix(buckets-router): remove wrongly made validtaion
fabioespinosa Jul 14, 2022
e71cda5
Merge branch 'master' into test/e2e
fabioespinosa Jul 14, 2022
62f8058
Revert "Merge pull request #121 from internxt/revert-114-test/reposit…
fabioespinosa Jul 14, 2022
6b25a18
feat(ci): service-containers mongo and redis
fabioespinosa Jul 15, 2022
541a8eb
fix(ci): adds pinging to see if bridge is up and fixes CI
fabioespinosa Jul 18, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/core/buckets/usecase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export class InvalidUploadIndexes extends Error {
}
export class InvalidMultiPartValueError extends Error {
constructor() {
super('Multipart is not allowed for files smaller than 500MB');
super('Multipart is not allowed for small files');

Object.setPrototypeOf(this, InvalidMultiPartValueError.prototype);
}
Expand Down
23 changes: 20 additions & 3 deletions lib/server/routes/buckets.js
Original file line number Diff line number Diff line change
Expand Up @@ -1428,19 +1428,29 @@ BucketsRouter.prototype.getFileId = function (req, res, next) {


BucketsRouter.prototype.getFileInfo = function (req, res, next) {
const { id: bucketId, file: fileId } = req.params;

if (!bucketId) {
return next(new errors.BadRequestError('No bucket id'));
}

if (!fileId) {
return next(new errors.BadRequestError('No file id'));
}

this._getBucketUnregistered(req, res, (err, bucket) => {
if (err) {
return next(err);
}

this.usecase.getFileInfo(bucket._id, req.params.file).then((fileInfo) => {
this.usecase.getFileInfo(bucket._id, fileId).then((fileInfo) => {
return res.status(200).send(fileInfo);
}).catch((err) => {
if (err instanceof BucketEntryNotFoundError || err instanceof BucketEntryFrameNotFoundError) {
return next(new errors.NotFoundError(err.message));
}

log.error('getFileInfo: Error for file %s: %s. %s', req.params.file, err.message, err.stack);
log.error('getFileInfo: Error for file %s: %s. %s', fileId, err.message, err.stack);

return next(new errors.InternalError(err.message));
});
Expand Down Expand Up @@ -1519,6 +1529,10 @@ BucketsRouter.prototype.startUpload = async function (req, res, next) {
return next(new errors.BadRequestError('Uploads is not an array'));
}

if (uploads.length === 0) {
return next(new errors.BadRequestError('Uploads is empty'));
}

for (const { index, size } of uploads) {
if (typeof size !== 'number' || size < 0) {
return next(new errors.BadRequestError('Invalid size'));
Expand Down Expand Up @@ -1609,11 +1623,14 @@ BucketsRouter.prototype.finishUpload = async function (req, res, next) {
return next(new errors.BadRequestError('Missing hash'));
}
if (UploadId && !parts) {
return next(new errors.BadRequestError('For multipart: must provide also an array of parts for this upload'));
return next(new errors.BadRequestError('For multipart: must provide also the number of parts'));
}
if (parts && !UploadId) {
return next(new errors.BadRequestError('For multipart: must provide also the UploadId for this upload'));
}
if (parts && !Number.isInteger(parts) || parts < 1) {
return next(new errors.BadRequestError('For multipart: Invalid number of parts'));
}
}

const { username, password } = this.config.nodes;
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
"publish-docs": "gh-pages -d jsdoc --repo [email protected]:internxt/bridge.git",
"build": "tsc",
"test-mongo-init": "DATABASE_URI=mongodb://admin:password@localhost:27017/bridge-test ts-node ./tests/lib/mongo/init",
"test-mongo": "DATABASE_URI=mongodb://admin:password@localhost:27017/bridge-test jest ./tests/lib/mongo --testTimeout 30000 --runInBand"
"test-mongo": "DATABASE_URI=mongodb://admin:password@localhost:27017/bridge-test jest ./tests/lib/mongo --testTimeout 30000 --runInBand",
"test:e2e": "NODE_ENV=test jest --config ./tests/lib/e2e/jest-e2e.json"
},
"repository": {
"type": "git",
Expand Down Expand Up @@ -59,6 +60,7 @@
"@types/node": "^17.0.23",
"@types/node-mongodb-fixtures": "^3.2.3",
"@types/sinon": "^10.0.11",
"@types/supertest": "^2.0.12",
"@types/uuid": "^8.3.4",
"chai": "^4.2.0",
"coveralls": "^2.11.6",
Expand All @@ -83,6 +85,7 @@
"redis-mock": "^0.16.0",
"rimraf": "^2.6.3",
"sinon": "^13.0.1",
"supertest": "^6.2.4",
"ts-jest": "^27.1.4",
"ts-node": "^10.7.0"
},
Expand Down
285 changes: 285 additions & 0 deletions tests/lib/e2e/bucket/finishUpload.e2e-spec.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,285 @@
import { v4 as uuidv4, v3 as uuidv3 } from 'uuid';
import { startUploadEndpoint } from './startUpload.e2e-spec.test';
import {
api,
AuthorizationHeader,
registerSampleUserAndGetBucketId,
} from '../setup';

let bucketId: string;
let FINISH_UPLOAD_PATH: string;

export const finishUploadEndpoint = (bucketId: string) =>
`/v2/buckets/${bucketId}/files/finish`;

describe('Finish Upload v2', () => {
beforeAll(async () => {
bucketId = await registerSampleUserAndGetBucketId();
FINISH_UPLOAD_PATH = finishUploadEndpoint(bucketId);
});

describe('Validation Finish Upload (non-multipart)', () => {
it('Mising body', async () => {
const response = await api
.post(FINISH_UPLOAD_PATH)
.send({})
.set(AuthorizationHeader);

expect(response.status).toBe(400);
expect(response.body.error).toBe('Missing parameters');
});

it('Mising index', async () => {
const response = await api
.post(FINISH_UPLOAD_PATH)
.send({
shards: [
{
hash: 'ba20c3927245283f1fddaf94be044227724600df',
uuid: uuidv4(),
},
],
})
.set(AuthorizationHeader);

expect(response.status).toBe(400);
expect(response.body.error).toBe('Missing parameters');
});

it('Invalid index', async () => {
const response = await api
.post(FINISH_UPLOAD_PATH)
.send({
index:
'c34695282e2fc4bf58833d9fc607c61da69b5b5c74e6224ec30f559c9a27043',
shards: [
{
hash: 'ba20c3927245283f1fddaf94be044227724600df',
uuid: uuidv4(),
},
],
})
.set(AuthorizationHeader);

expect(response.status).toBe(400);
expect(response.body.error).toBe('Invalid index');
});

it('Missing shards', async () => {
const response = await api
.post(FINISH_UPLOAD_PATH)
.send({
index:
'0c34695282e2fc4bf58833d9fc607c61da69b5b5c74e6224ec30f559c9a27043',
})
.set(AuthorizationHeader);

expect(response.status).toBe(400);
expect(response.body.error).toBe('Missing parameters');
});

it('Shards is not an array', async () => {
const response = await api
.post(FINISH_UPLOAD_PATH)
.send({
index:
'0c34695282e2fc4bf58833d9fc607c61da69b5b5c74e6224ec30f559c9a27043',
shards: true,
})
.set(AuthorizationHeader);

expect(response.status).toBe(400);
expect(response.body.error).toBe('Shards is not an array');
});

it('Shards Invalid uuid', async () => {
const response = await api
.post(FINISH_UPLOAD_PATH)
.send({
index:
'0c34695282e2fc4bf58833d9fc607c61da69b5b5c74e6224ec30f559c9a27043',
shards: [
{
hash: 'ba20c3927245283f1fddaf94be044227724600df',
uuid: 'uuid-fake',
},
],
})
.set(AuthorizationHeader);

expect(response.status).toBe(400);
expect(response.body.error).toBe('Invalid UUID');
});

it('Shards Missing hash', async () => {
const response = await api
.post(FINISH_UPLOAD_PATH)
.send({
index:
'0c34695282e2fc4bf58833d9fc607c61da69b5b5c74e6224ec30f559c9a27043',
shards: [
{
uuid: uuidv4(),
},
],
})
.set(AuthorizationHeader);

expect(response.status).toBe(400);
expect(response.body.error).toBe('Missing hash');
});

it('Shards Missing uuid', async () => {
const response = await api
.post(FINISH_UPLOAD_PATH)
.send({
index:
'0c34695282e2fc4bf58833d9fc607c61da69b5b5c74e6224ec30f559c9a27043',
shards: [
{
hash: 'ba20c3927245283f1fddaf94be044227724600df',
},
],
})
.set(AuthorizationHeader);

expect(response.status).toBe(400);
expect(response.body.error).toBe('Invalid UUID');
});
});

describe('Validation Finish Upload - Multipart', () => {
it('Invalid multipart value, missing parts', async () => {
const response = await api
.post(FINISH_UPLOAD_PATH)
.send({
index:
'0c34695282e2fc4bf58833d9fc607c61da69b5b5c74e6224ec30f559c9a27043',
shards: [
{
hash: 'ba20c3927245283f1fddaf94be044227724600df',
uuid: uuidv4(),
UploadId: 'some_id',
},
],
})
.set(AuthorizationHeader);

expect(response.status).toBe(400);
expect(response.body.error).toBe(
'For multipart: must provide also the number of parts'
);
});

it('Invalid multipart value, missing UploadId', async () => {
const response = await api
.post(FINISH_UPLOAD_PATH)
.send({
index:
'0c34695282e2fc4bf58833d9fc607c61da69b5b5c74e6224ec30f559c9a27043',
shards: [
{
hash: 'ba20c3927245283f1fddaf94be044227724600df',
uuid: uuidv4(),
parts: 4,
},
],
})
.set(AuthorizationHeader);

expect(response.status).toBe(400);
expect(response.body.error).toBe(
'For multipart: must provide also the UploadId for this upload'
);
});

it('Negative multipart value', async () => {
const response = await api
.post(FINISH_UPLOAD_PATH)
.send({
index:
'0c34695282e2fc4bf58833d9fc607c61da69b5b5c74e6224ec30f559c9a27043',
shards: [
{
hash: 'ba20c3927245283f1fddaf94be044227724600df',
uuid: uuidv4(),
UploadId: 'some_id',
parts: -4,
},
],
})
.set(AuthorizationHeader);

expect(response.status).toBe(400);
expect(response.body.error).toBe(
'For multipart: Invalid number of parts'
);
});
});

describe('Finish Upload functionality', () => {
describe('Normal (non-multipart)', () => {
it('Non existing bucket', async () => {
const response = await api
.post(finishUploadEndpoint('f701d5cc906a6f7e294d50f7'))
.send({
index:
'0c34695282e2fc4bf58833d9fc607c61da69b5b5c74e6224ec30f559c9a27043',
shards: [
{
hash: 'ba20c3927245283f1fddaf94be044227724600df',
uuid: uuidv4(),
},
],
})
.set(AuthorizationHeader);

expect(response.status).toBe(404);
expect(response.body.error).toBe('Bucket not found');
});

it('Missing uploads', async () => {
const startUploadResponse = await api
.post(startUploadEndpoint(bucketId))
.send({
uploads: [
{
index: 0,
size: 1000,
},
{
index: 1,
size: 10000,
},
],
})
.set(AuthorizationHeader);

const { uploads } = startUploadResponse.body;

const response = await api
.post(FINISH_UPLOAD_PATH)
.send({
index:
'0c34695282e2fc4bf58833d9fc607c61da69b5b5c74e6224ec30f559c9a27043',
shards: [
{
hash: 'ba20c3927245283f1fddaf94be044227724600df',
uuid: uploads[0].uuid,
},
],
})
.set(AuthorizationHeader);

expect(response.status).toBe(404);
expect(response.body.error).toBe(
'Missing uploads to complete the upload'
);
});
});

describe('Multipart', () => {
it('', async () => {});
});
});
});
Loading