Skip to content
This repository has been archived by the owner on Nov 3, 2020. It is now read-only.

Commit

Permalink
feat: new addFiles and addLinks methods (#47)
Browse files Browse the repository at this point in the history
* chore: refactor module internals II

* Unit tests for model items

* Unit tests for item actions

* Better text for adding files

* Refactor duplicated code

* Use snapshot for error check
  • Loading branch information
arkaitzgarro authored Jun 26, 2018
1 parent b9ffa54 commit cde6562
Show file tree
Hide file tree
Showing 52 changed files with 1,190 additions and 388 deletions.
24 changes: 10 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,39 +49,35 @@ const transfer = await apiClient.transfer.create({

### Add items to a transfer

Once a transfer has been created you can then add items to it. If files are provided as items, they are not uploaded at this point, see next steps:
Once a transfer has been created you can then add items (files or links) to it. If you are adding files to the transfer, the files are not uploaded at this point, but in the next step.

```javascript
const transferItems = await apiClient.transfer.addItems(transfer.id, [{
content_identifier: 'file',
local_identifier: 'delightful-cat',
const files = await apiClient.transfer.addFiles(transfer, [{
filename: 'kittie.gif',
filesize: 1024
},
{
local_identifier: 'japan-wikipedia',
content_identifier: 'web_content',
}]);

const links = await apiClient.transfer.addLinks(transfer, [{
url: 'https://en.wikipedia.org/wiki/Japan',
meta: {
title: 'Japan'
}
}]);
```

It will return an object for each item you want to add to the transfer. For files, each one must be split into chunks, and uploaded to a pre-signed S3 URL, provided by the following method.
Each method will return an array of objects for each item that was added to the transfer. For files, this objects will be used to upload the correspondent file to the transfer, as explained in the next section.

### Upload a file

Once the item has been added to the transfer, next step is to upload the file or files. You must provide the content of the file to upload as a [Buffer](https://nodejs.org/api/buffer.html#buffer_class_buffer).
Once the file has been added to the transfer, next step is to upload the file or files. You must provide the content of the file to upload as a [Buffer](https://nodejs.org/api/buffer.html#buffer_class_buffer), we will NOT read the file for you. The content of the file will be splited and uploaded in chunks of 5MB to our S3 bucket.

```javascript
// Depending on your application, you will read the file using fs.readFile
// or it will be a file uploaded to your service.
// or it will be a file uploaded to your web server.
const fileContent = [/* Buffer */];
await Promise.all(
transferItems
.filter((item) => item.content_identifier === 'file')
.map((item) => apiClient.transfer.uploadFile(item, fileContent))
// files is the variable returned by apiClient.transfer.addFiles method
files.map((item) => apiClient.transfer.uploadFile(item, fileContent))
);
```

Expand Down
3 changes: 3 additions & 0 deletions __tests__/__snapshots__/index.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`createWTClient function should throw and error when no API KEY is provided 1`] = `[Error: No API Key provided]`;
3 changes: 3 additions & 0 deletions __tests__/authorize/__snapshots__/index.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Authorize method should throw an error if request fails 1`] = `[Error: The authorization call failed and no usable JWT could be found there. Please check your API Key.]`;
5 changes: 2 additions & 3 deletions __tests__/authorize/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ const axios = require('axios');

const authorize = require('../../src/authorize');
const request = require('../../src/request');
const WTError = require('../../src/error');

jest.mock('axios');

Expand Down Expand Up @@ -37,14 +36,14 @@ describe('Authorize method', () => {
});
});

it('should throw a WTError if request fails', async () => {
it('should throw an error if request fails', async () => {
try {
axios.mockImplementation(() =>
Promise.reject(new Error('Network error.'))
);
await authorize();
} catch (error) {
expect(error).toBeInstanceOf(WTError);
expect(error).toMatchSnapshot();
}
});
});
18 changes: 10 additions & 8 deletions __tests__/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,25 @@ describe('createWTClient function', () => {
});

it('should return a client if API KEY is provided', async () => {
try {
await createWTClient();
} catch ({ message }) {
expect(message).toEqual('No API Key provided');
}
});

it('should return an API client', async () => {
const apiClient = await createWTClient('super-secret-api-key');
expect(apiClient).toEqual({
authorize: expect.any(Function),
transfer: {
addFiles: expect.any(Function),
addItems: expect.any(Function),
addLinks: expect.any(Function),
completeFileUpload: expect.any(Function),
create: expect.any(Function),
uploadFile: expect.any(Function)
}
});
});

it('should throw and error when no API KEY is provided', async () => {
try {
await createWTClient();
} catch (error) {
expect(error).toMatchSnapshot();
}
});
});
22 changes: 22 additions & 0 deletions __tests__/items/actions/__snapshots__/add-files.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Add files action should create an add items request 1`] = `
Array [
RemoteFile {
"content_identifier": "file",
"id": "random-hash",
"local_identifier": "delightful-cat",
"meta": Object {
"multipart_parts": 3,
"multipart_upload_id": "some.random-id--",
},
"name": "kittie.gif",
"size": 195906,
"transfer": RemoteTransfer {
"items": Array [
[Circular],
],
},
},
]
`;
24 changes: 24 additions & 0 deletions __tests__/items/actions/__snapshots__/add-items.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Add items action should create an add items request 1`] = `
Array [
RemoteFile {
"content_identifier": "file",
"id": "random-hash",
"local_identifier": "delightful-cat",
"meta": Object {
"multipart_parts": 3,
"multipart_upload_id": "some.random-id--",
},
"name": "kittie.gif",
"size": 195906,
},
RemoteLink {
"content_identifier": "web_content",
"id": "random-hash",
"meta": Object {
"title": "WeTransfer",
},
},
]
`;
18 changes: 18 additions & 0 deletions __tests__/items/actions/__snapshots__/add-links.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Add links action should create an add items request 1`] = `
Array [
RemoteLink {
"content_identifier": "web_content",
"id": "random-hash",
"meta": Object {
"title": "WeTransfer",
},
"transfer": RemoteTransfer {
"items": Array [
[Circular],
],
},
},
]
`;
3 changes: 3 additions & 0 deletions __tests__/items/actions/__snapshots__/send-items.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Send items action should throw an error if items are not provided 1`] = `[Error: There was an error when adding items to the transfer.]`;
3 changes: 3 additions & 0 deletions __tests__/items/actions/__snapshots__/upload-file.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Upload file action should throw an error if request fails 1`] = `[Error: There was an error when uploading kittie.gif.]`;
46 changes: 46 additions & 0 deletions __tests__/items/actions/add-files.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
const addFilesAction = require('../../../src/items/actions/add-files');
const { futureFile, RemoteFile } = require('../../../src/items/models');
const { RemoteTransfer } = require('../../../src/transfer/models');

describe('Add files action', () => {
let addFiles = null;
let sendItems = null;
let transfer = null;
beforeEach(() => {
sendItems = jest.fn().mockReturnValue([
{
id: 'random-hash',
content_identifier: 'file',
local_identifier: 'delightful-cat',
meta: {
multipart_parts: 3,
multipart_upload_id: 'some.random-id--'
},
name: 'kittie.gif',
size: 195906,
upload_id: 'more.random-ids--',
upload_expires_at: 1520410633
}
]);

addFiles = addFilesAction({
sendItems,
futureFile,
RemoteFile
});

transfer = new RemoteTransfer();
});

it('should create an add items request', async () => {
const linkFiles = await addFiles(transfer, [
{
url: 'https://wetransfer.com',
meta: {
title: 'WeTransfer'
}
}
]);
expect(linkFiles).toMatchSnapshot();
});
});
55 changes: 55 additions & 0 deletions __tests__/items/actions/add-items.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
const addItemsAction = require('../../../src/items/actions/add-items');
const {
normalizeItem,
normalizeResponseItem
} = require('../../../src/items/models');

describe('Add items action', () => {
let addItems = null;
let sendItems = null;
beforeEach(() => {
sendItems = jest.fn().mockReturnValue([
{
id: 'random-hash',
content_identifier: 'file',
local_identifier: 'delightful-cat',
meta: {
multipart_parts: 3,
multipart_upload_id: 'some.random-id--'
},
name: 'kittie.gif',
size: 195906,
upload_id: 'more.random-ids--',
upload_expires_at: 1520410633
},
{
id: 'random-hash',
content_identifier: 'web_content',
meta: {
title: 'WeTransfer'
},
url: 'https://wetransfer.com'
}
]);

addItems = addItemsAction({
sendItems,
normalizeItem,
normalizeResponseItem
});
});

it('should create an add items request', async () => {
const items = await addItems('transfer-id', [
{
local_identifier: 'wetransfer.com',
content_identifier: 'web_content',
url: 'https://wetransfer.com',
meta: {
title: 'WeTransfer'
}
}
]);
expect(items).toMatchSnapshot();
});
});
41 changes: 41 additions & 0 deletions __tests__/items/actions/add-links.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
const addLinksAction = require('../../../src/items/actions/add-links');
const { futureLink, RemoteLink } = require('../../../src/items/models');
const { RemoteTransfer } = require('../../../src/transfer/models');

describe('Add links action', () => {
let addLinks = null;
let sendItems = null;
let transfer = null;
beforeEach(() => {
sendItems = jest.fn().mockReturnValue([
{
id: 'random-hash',
content_identifier: 'web_content',
meta: {
title: 'WeTransfer'
},
url: 'https://wetransfer.com'
}
]);

addLinks = addLinksAction({
sendItems,
futureLink,
RemoteLink
});

transfer = new RemoteTransfer();
});

it('should create an add items request', async () => {
const linkItems = await addLinks(transfer, [
{
url: 'https://wetransfer.com',
meta: {
title: 'WeTransfer'
}
}
]);
expect(linkItems).toMatchSnapshot();
});
});
26 changes: 26 additions & 0 deletions __tests__/items/actions/send-items.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const routes = require('../../../src/config/routes');
const sendItemsAction = require('../../../src/items/actions/send-items');

describe('Send items action', () => {
let sendItems = null;
const mocks = {};
beforeEach(() => {
mocks.request = { send: jest.fn() };
mocks.request.send.mockReturnValue(() =>
Promise.reject(new Error('Network error.'))
);

sendItems = sendItemsAction({
routes,
request: mocks.request
});
});

it('should throw an error if items are not provided', async () => {
try {
await sendItems();
} catch (error) {
expect(error).toMatchSnapshot();
}
});
});
Loading

0 comments on commit cde6562

Please sign in to comment.