box-ui-elements-mlh
Version:
426 lines (363 loc) • 14.2 kB
JavaScript
import browser from '../Browser';
import {
toISOStringNoMS,
getFileLastModifiedAsISONoMSIfPossible,
tryParseJson,
isDataTransferItemAFolder,
isDataTransferItemAPackage,
isMultiputSupported,
getFileFromDataTransferItem,
getPackageFileFromDataTransferItem,
doesFileContainAPIOptions,
doesDataTransferItemContainAPIOptions,
getFile,
getDataTransferItem,
getFileAPIOptions,
getDataTransferItemAPIOptions,
DEFAULT_API_OPTIONS,
getFileId,
getDataTransferItemId,
} from '../uploads';
const mockFile = { name: 'hi' };
const entry = {
name: 'hi',
file: fn => {
fn(mockFile);
},
};
const mockItem = { kind: 'file', webkitGetAsEntry: () => entry };
const options = { options: true };
describe('util/uploads', () => {
describe('toISOStringNoMS()', () => {
test('should format the time string properly', () => {
const d = new Date(1273912371111);
expect(toISOStringNoMS(d)).toBe('2010-05-15T08:32:51Z');
});
});
describe('getFileLastModifiedAsISONoMSIfPossible()', () => {
// Test cases in order
// file with valid last modified
// file with non-numeric last modified (string)
// I don't know of a browser that has lastModified as a Date object, but I just added
// these two test cases to confirm that our code does something reasonable (i.e. return
// a string or null, but not crash).
// file with non-numeric lastModified (valid date)
// file with non-numeric lastModified (invalid Date)
// file no lastModified
test.each`
file | expectedResult
${{ lastModified: 1483326245678 }} | ${'2017-01-02T03:04:05Z'}
${{ lastModified: 'not a number' }} | ${null}
${{ lastModified: new Date('2017-01-02T03:04:05.678Z') }} | ${'2017-01-02T03:04:05Z'}
${{ lastModified: new Date('not valid') }} | ${null}
${{}} | ${null}
${{ lastModifiedDate: 1483326245678 }} | ${'2017-01-02T03:04:05Z'}
${{ lastModifiedDate: 'not a number' }} | ${null}
${{ lastModifiedDate: new Date('2017-01-02T03:04:05.678Z') }} | ${'2017-01-02T03:04:05Z'}
${{ lastModifiedDate: new Date('not valid') }} | ${null}
${{}} | ${null}
`(
'should return the properly formatted date when possible and return null otherwise',
({ file, expectedResult }) => {
expect(getFileLastModifiedAsISONoMSIfPossible(file)).toBe(expectedResult);
},
);
});
describe('tryParseJson()', () => {
test.each`
str | expectedResult
${''} | ${null}
${'a'} | ${null}
${'{'} | ${null}
${'1'} | ${1}
${'"a"'} | ${'a'}
${'{}'} | ${{}}
${'[1,2,3]'} | ${[1, 2, 3]}
${'{"a": 1}'} | ${{ a: 1 }}
`('should return correct results', ({ str, expectedResult }) => {
expect(tryParseJson(str)).toEqual(expectedResult);
});
});
describe('doesFileContainAPIOptions()', () => {
test('should return true when argument is UploadFileWithAPIOptions type', () => {
expect(
doesFileContainAPIOptions({
file: mockFile,
options,
}),
).toBeTruthy();
});
test('should return false when argument is UploadFile type', () => {
expect(doesFileContainAPIOptions(mockFile)).toBeFalsy();
});
});
describe('doesDataTransferItemContainAPIOptions()', () => {
test('should return true when argument is UploadDataTransferItemWithAPIOptions type', () => {
expect(
doesDataTransferItemContainAPIOptions({
item: mockItem,
options,
}),
).toBeTruthy();
});
test('should return false when argument is DataTransferItem type', () => {
expect(doesDataTransferItemContainAPIOptions(mockItem)).toBeFalsy();
});
});
describe('getFile()', () => {
test('should return file when argument is UploadFileWithAPIOptions type', () => {
expect(
getFile({
file: mockFile,
options,
}),
).toEqual(mockFile);
});
test('should return file when argument is UploadFile type', () => {
expect(getFile(mockFile)).toEqual(mockFile);
});
});
describe('getDataTransferItem()', () => {
test('should return item when argument is UploadDataTransferItemWithAPIOptions type', () => {
expect(
getDataTransferItem({
item: mockItem,
options,
}),
).toEqual(mockItem);
});
test('should return item when argument is DataTransferItem type', () => {
expect(getDataTransferItem(mockItem)).toEqual(mockItem);
});
});
describe('getFileAPIOptions()', () => {
test('should return options when argument is UploadFileWithAPIOptions type', () => {
expect(
getFileAPIOptions({
file: mockFile,
options,
}),
).toEqual(options);
});
test('should return DEFAULT_API_OPTIONS when argument is UploadFile type', () => {
expect(getFileAPIOptions(mockFile)).toEqual(DEFAULT_API_OPTIONS);
});
});
describe('getDataTransferItemAPIOptions()', () => {
test('should return options when argument is UploadDataTransferItemWithAPIOptions type', () => {
expect(
getDataTransferItemAPIOptions({
item: mockItem,
options,
}),
).toEqual(options);
});
test('should return DEFAULT_API_OPTIONS when argument is DataTransferItem type', () => {
expect(getDataTransferItemAPIOptions(mockItem)).toEqual(DEFAULT_API_OPTIONS);
});
});
describe('getFileFromDataTransferItem()', () => {
test('should return file of UploadFileWithAPIOptions type when itemData is UploadDataTransferItemWithAPIOptions type', async () => {
const itemData = {
item: mockItem,
options,
};
expect(await getFileFromDataTransferItem(itemData)).toEqual({
file: mockFile,
options,
});
});
});
describe('getPackageFileFromDataTransferItem()', () => {
test('should return file of UploadFileWithAPIOptions type when itemData is UploadDataTransferItemWithAPIOptions type', async () => {
const mockPackageItem = {
getAsFile: jest.fn(() => mockFile),
webkitGetAsEntry: () => entry,
};
const itemData = {
item: mockPackageItem,
options,
};
expect(await getPackageFileFromDataTransferItem(itemData)).toEqual({
file: mockFile,
options,
});
});
});
describe('isDataTransferItemAPackage()', () => {
test('should be false if data transfer item thinks it is a folder', () => {
const folderEntry = {
isDirectory: true,
};
const folderItem = {
kind: '',
webkitGetAsEntry: () => folderEntry,
};
const itemData = {
item: folderItem,
options,
};
expect(isDataTransferItemAPackage(itemData)).toBeFalsy();
});
test('should be false if data transfer item thinks it is a file', () => {
const fileEntry = {
isDirectory: false,
isFile: true,
};
const folderItem = {
kind: 'file',
webkitGetAsEntry: () => fileEntry,
};
const itemData = {
item: folderItem,
options,
};
expect(isDataTransferItemAPackage(itemData)).toBeFalsy();
});
test('should be true if data transfer item has both identifies a directory but has kind = file and type = application/zip', () => {
const packageEntry = {
isDirectory: true,
isFile: false,
};
const folderItem = {
kind: 'file',
type: 'application/zip',
webkitGetAsEntry: () => packageEntry,
};
const itemData = {
item: folderItem,
options,
};
expect(isDataTransferItemAPackage(itemData)).toBeTruthy();
});
test('should be false if data transfer item has both identifies a directory but only has kind = file', () => {
const packageEntry = {
isDirectory: true,
isFile: false,
};
const folderItem = {
kind: 'file',
webkitGetAsEntry: () => packageEntry,
};
const itemData = {
item: folderItem,
options,
};
expect(isDataTransferItemAPackage(itemData)).toBeFalsy();
});
});
describe('isDataTransferItemAFolder()', () => {
test('should return true if item is a folder', () => {
const folderEntry = {
isDirectory: true,
};
const folderItem = {
kind: '',
webkitGetAsEntry: () => folderEntry,
};
const itemData = {
item: folderItem,
options,
};
expect(isDataTransferItemAFolder(itemData)).toBeTruthy();
});
test('should return false if item is not a folder', () => {
const fileEntry = {
isDirectory: false,
};
const fileItem = { kind: '', webkitGetAsEntry: () => fileEntry };
const itemData = {
item: fileItem,
options,
};
expect(isDataTransferItemAFolder(itemData)).toBeFalsy();
});
test('should return false if item does not have an entry', () => {
const fileItem = { kind: '', webkitGetAsEntry: () => undefined };
expect(isDataTransferItemAFolder(fileItem)).toBeFalsy();
});
});
describe('getFileId()', () => {
test('should return file id correctly when file does not contain API options', () => {
const file = {
name: 'hi',
};
expect(getFileId(file)).toBe('hi');
});
test('should return file id correctly when file does contain API options', () => {
const file = {
file: {
name: 'hi',
},
options: {
folderId: '0',
uploadInitTimestamp: 123123,
},
};
expect(getFileId(file)).toBe('hi_0_123123');
});
});
describe('getFileId()', () => {
test('should return file id correctly when file does not contain API options', () => {
const file = {
name: 'hi',
};
expect(getFileId(file)).toBe('hi');
});
test('should return file id correctly when file does contain API options', () => {
const file = {
file: {
name: 'hi',
},
options: {
folderId: '0',
uploadInitTimestamp: 123123,
},
};
expect(getFileId(file)).toBe('hi_0_123123');
});
});
describe('getDataTransferItemId()', () => {
const rootFolderId = 0;
const now = Date.now();
Date.now = jest.fn(() => now);
test('should return item id correctly when item does not contain API options', () => {
expect(getDataTransferItemId(mockItem, rootFolderId)).toBe('hi');
});
test('should return item id correctly when item does contain API options', () => {
const item = {
item: mockItem,
options: {
folderId: '0',
uploadInitTimestamp: 123123,
},
};
expect(getDataTransferItemId(item, rootFolderId)).toBe('hi_0_123123');
});
});
describe('isMultiputSupported()', () => {
let windowSpy;
beforeEach(() => {
windowSpy = jest.spyOn(window, 'window', 'get');
});
afterEach(() => {
windowSpy.mockRestore();
});
test.each([
['mobile safari', true, false, false],
['mobile chrome on ios', false, true, false],
['mobile other browsers', false, false, true],
])(
'should return whether multiput is supported on device: %o',
(test, mobileSafari, mobileChromeOniOS, expected) => {
windowSpy.mockImplementation(() => ({
crypto: { subtle: true },
location: { protocol: 'https:' },
}));
browser.isMobileSafari = jest.fn().mockReturnValueOnce(mobileSafari);
browser.isMobileChromeOniOS = jest.fn().mockReturnValueOnce(mobileChromeOniOS);
expect(isMultiputSupported()).toEqual(expected);
},
);
});
});