Skip to content

Commit

Permalink
Merge pull request #395 from mailgun/filename-for-string-attachments
Browse files Browse the repository at this point in the history
fix: Filename is not respected for attachments with type string
  • Loading branch information
olexandr-mazepa authored Jan 4, 2024
2 parents 61a6b50 + 72ecbaa commit 6248cc0
Show file tree
Hide file tree
Showing 7 changed files with 24,376 additions and 18 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/on-pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ jobs:
name: test
strategy:
matrix:
os: [ ubuntu-latest ]
runs-on: ${{ matrix.os }}
node-version: [14.x, 16.x, 18.x, 20.x]
runs-on: 'ubuntu-latest'
steps:
- name: Checkout
uses: actions/checkout@v3

- uses: actions/setup-node@v3
with:
node-version: lts/hydrogen
node-version: ${{ matrix.node-version }}

- name: Print node version
run: node -v
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ build

./test.js
.coverage/
.nvmrc
14,484 changes: 14,481 additions & 3 deletions dist/mailgun.node.js

Large diffs are not rendered by default.

9,806 changes: 9,803 additions & 3 deletions dist/mailgun.web.js

Large diffs are not rendered by default.

12 changes: 7 additions & 5 deletions lib/Classes/common/FormDataBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,19 +112,21 @@ class FormDataBuilder {
const objData = isStreamData ? obj : obj.data;
// getAttachmentOptions should be called with obj parameter to prevent loosing filename
const options = this.getAttachmentOptions(obj);
if (typeof objData === 'string') {
formData.append(key, objData as string);
return;
}

if (this.isFormDataPackage(formData)) {
const fd = formData as NodeFormData;
fd.append(key, objData, options);
const data = typeof objData === 'string' ? Buffer.from(objData) : objData;
fd.append(key, data, options);
return;
}

if (typeof Blob !== undefined) { // either node > 18 or browser
const browserFormData = formDataInstance as FormData; // Browser compliant FormData
if (typeof objData === 'string') {
const blobInstance = new Blob([objData]);
browserFormData.append(key, blobInstance, options.filename);
return;
}
if (objData instanceof Blob) {
browserFormData.append(key, objData, options.filename);
return;
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"build:prepublish": "node ./SetupPackage.js",
"start": "webpack --watch --config ./webpack/webpack.dev.config.js --progress --color",
"test": "multi='dot=- xunit=./results.xml' nyc --reporter=text-summary --reporter=lcov --report-dir=.coverage mocha -t 10000 -R mocha-multi -r ts-node/register test/*.test.ts",
"test:debug": "multi='dot=- xunit=./results.xml' nyc --reporter=text-summary --reporter=lcov --report-dir=.coverage mocha --inspect-brk -t 10000 -R mocha-multi -r ts-node/register test/*.test.ts",
"test:watch": "mocha -r ts-node/register -w -R dot test/*.test.ts",
"docs": "typedoc --tsconfig ./tsconfig.json --plugin typedoc-plugin-markdown",
"lint": "eslint . --ext .ts",
Expand Down
84 changes: 80 additions & 4 deletions test/formDataBuilder.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { expect } from 'chai';
import NodeFormData from 'form-data';
import { Blob } from 'buffer';
import FormDataBuilder from '../lib/Classes/common/FormDataBuilder';
import { InputFormData } from '../lib';

describe('FormDataBuilder', function () {
let builder: FormDataBuilder;
before(function () {
builder = new FormDataBuilder(NodeFormData);
});
describe('createFormData (form-data package)', async () => {
before(function () {
builder = new FormDataBuilder(NodeFormData);
});

describe('createFormData', async () => {
it('checks that input object exists', async () => {
try {
// @ts-expect-error check case when SDK is being used without type checking
Expand All @@ -32,5 +34,79 @@ describe('FormDataBuilder', function () {
expect(data).include('Content-Disposition: form-data; name="attachment"; filename="file"');
expect(data).include('Content-Type: application/octet-stream');
});

it('Respects filename', async () => {
const result = builder.createFormData({ attachment: { filename: 'test', data: Buffer.from('test message') } }) as NodeFormData;
const data = result.getBuffer().toString();
expect(data).include('Content-Disposition: form-data; name="attachment"; filename="test"');
expect(data).include('Content-Type: application/octet-stream');
});

it('Respects filename when string provided', async () => {
const result = builder.createFormData({ attachment: { filename: 'test', data: 'test message' } }) as NodeFormData;
const data = result.getBuffer().toString();
expect(data).include('Content-Disposition: form-data; name="attachment"; filename="test"');
expect(data).include('Content-Type: application/octet-stream');
});
});

if (Blob && global.FormData) {
describe('createFormData (Browser FormData + Blob)', async () => {
before(function () {
builder = new FormDataBuilder(global.FormData as InputFormData);
});

it('Adds blob correctly', async () => {
const result = builder.createFormData({ attachment: { data: new Blob(['FormData test message']) } }) as FormData;
const file = result.get('attachment') as File;
expect(file).to.exist;
expect(file.size).to.be.equal(21);
expect(file.name).to.be.equal('file');
});

it('Respects filename', async () => {
const result = builder.createFormData({ attachment: { filename: 'test', data: new Blob(['FormData test message']) } }) as FormData;
const file = result.get('attachment') as File;
expect(file).to.exist;
expect(file.size).to.be.equal(21);
expect(file.name).to.be.equal('test');
});

it('Respects filename when string provided', async () => {
const result = builder.createFormData({ attachment: { filename: 'test', data: 'FormData test message' } }) as FormData;
const file = result.get('attachment') as File;
expect(file.name).to.be.equal('test');
expect(file.size).to.be.equal(21);
});
});
} else {
// eslint-disable-next-line no-console
console.warn('Blob or global.FormData does not exist. Skipping the FormData + Blob test');
}
if (global.FormData) {
describe('createFormData (Browser FormData + Buffer)', async () => {
before(function () {
builder = new FormDataBuilder(global.FormData as InputFormData);
});

it('Adds blob correctly', async () => {
const result = builder.createFormData({ attachment: { data: Buffer.from('FormData test message') } }) as FormData;
const file = result.get('attachment') as File;
expect(file).to.exist;
expect(file.size).to.be.equal(21);
expect(file.name).to.be.equal('file');
});

it('Respects filename', async () => {
const result = builder.createFormData({ attachment: { filename: 'test', data: Buffer.from('FormData test message') } }) as FormData;
const file = result.get('attachment') as File;
expect(file).to.exist;
expect(file.size).to.be.equal(21);
expect(file.name).to.be.equal('test');
});
});
} else {
// eslint-disable-next-line no-console
console.warn('global.FormData does not exist. Skipping the FormData + Buffer test');
}
});

0 comments on commit 6248cc0

Please sign in to comment.