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

Feature/lef 388 upload assets function #187

Merged
merged 10 commits into from
Jun 28, 2023
63 changes: 63 additions & 0 deletions api-module-library/frontify/api.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const fetch = require('node-fetch');
const { get } = require('@friggframework/assertions');
const { OAuth2Requester } = require('@friggframework/module-plugin');
const querystring = require('querystring');
Expand Down Expand Up @@ -333,6 +334,68 @@ class Api extends OAuth2Requester {
assets: response.data.brand.search.edges,
};
}

async createAsset(asset) {
const ql = `mutation CreateAsset {
createAsset(input: {
fileId: "${asset.id}",
title: "${asset.title}",
projectId: "${asset.projectId}"
}) {
job {
assetId
}
}
}`;

const response = await this._post(this.buildRequestOptions(ql));
this.assertResponse(response);
return {
id: response.data.createAsset.job.assetId
};
}

async createFileId(input) {
const ql = `mutation UploadFile {
uploadFile(input: {
filename: "${input.filename}",
size: ${input.size},
chunkSize: ${input.chunkSize}
}) {
id
urls
}
}`;

const response = await this._post(this.buildRequestOptions(ql));
this.assertResponse(response);
return response.data.uploadFile;
}

// Total of addresses in urls should match the number of chunks in
// stream. The code invoking this method should take care of this
// using a correct "highWaterMark".
async uploadFile(stream, urls) {
const responses = [];

for await (const chunk of stream) {
// AWS url
const url = urls.shift();

// Using fetch to avoid sending Frontify auth headers to AWS
const resp = await fetch(url, {
method: 'PUT',
headers: {
'content-type': 'binary'
},
body: chunk
});

responses.push(resp);
}

return responses;
}
}

module.exports = { Api };
125 changes: 125 additions & 0 deletions api-module-library/frontify/api.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -969,5 +969,130 @@ describe(`${Config.label} API Tests`, () => {
});
});
});

describe('#createAsset', () => {
const ql = `mutation CreateAsset {
createAsset(input: {
fileId: "fileId",
title: "title",
projectId: "projectId"
}) {
job {
assetId
}
}
}`;

describe('Create a new asset', () => {
let scope;

beforeEach(() => {
scope = nock(baseUrl)
.post('', (body) => body.query.replace(/\s/g, '') === ql.replace(/\s/g, ''))
.reply(200, {
data: {
createAsset: {
job: {
assetId: 'assetId'
}
}
}
});
});

it('should hit the correct endpoint', async () => {
const asset = {
id: 'fileId',
title: 'title',
projectId: 'projectId'
};

const results = await api.createAsset(asset);
expect(results).toEqual({ id: 'assetId' });
expect(scope.isDone()).toBe(true);
});
});
});

describe('#createFileId', () => {
const ql = `mutation UploadFile {
uploadFile(input: {
filename: "filename",
size: size,
chunkSize: chunkSize
}) {
id
urls
}
}`;

describe('Create a file ID', () => {
let scope;

beforeEach(() => {
scope = nock(baseUrl)
.post('', (body) => body.query.replace(/\s/g, '') === ql.replace(/\s/g, ''))
.reply(200, {
data: {
uploadFile: {
uploadFile: 'uploadFile'
}
}
});
});

it('should hit the correct endpoint', async () => {
const input = {
filename: 'filename',
size: 'size',
chunkSize: 'chunkSize'
};

const results = await api.createFileId(input);
expect(results).toEqual({ uploadFile: 'uploadFile' });
expect(scope.isDone()).toBe(true);
});
});
});

describe('#uploadFile', () => {
describe('Create a file ID', () => {
let scopeOne, scopeTwo;

beforeEach(() => {
scopeOne = nock('https://foo')
.put('/bar', 'foo')
.reply(200, {
data: {
uploadFile: {
uploadFile: 'uploadFile'
}
}
});

scopeTwo = nock('https://bar')
.put('/foo', 'bar')
.reply(200, {
data: {
uploadFile: {
uploadFile: 'uploadFile'
}
}
});
});

it('should fetch files from correct endpoints', async () => {
const input = {
stream: ['foo', 'bar'],
urls: ['https://foo/bar', 'https://bar/foo'],
chunkSize: 'chunkSize'
};

await api.uploadFile(input.stream, input.urls);
expect(scopeOne.isDone()).toBe(true);
expect(scopeTwo.isDone()).toBe(true);
});
});
});
});
});