@orfeas126/box-ui-elements
Version:
Box UI Elements
1,094 lines (1,022 loc) • 147 kB
JavaScript
// @flow
import Cache from '../../utils/Cache';
import * as ErrorUtil from '../../utils/error';
import Metadata from '../Metadata';
import {
ERROR_CODE_CREATE_METADATA,
ERROR_CODE_DELETE_METADATA,
ERROR_CODE_FETCH_METADATA_SUGGESTIONS,
ERROR_CODE_FETCH_METADATA_TEMPLATES,
ERROR_CODE_FETCH_METADATA,
ERROR_CODE_FETCH_SKILLS,
ERROR_CODE_UPDATE_METADATA,
ERROR_CODE_UPDATE_SKILLS,
METADATA_SCOPE_GLOBAL,
METADATA_SUGGESTIONS_CONFIDENCE_EXPERIMENTAL,
METADATA_TEMPLATE_CLASSIFICATION,
METADATA_TEMPLATE_PROPERTIES,
TYPE_FILE,
ERROR_CODE_EMPTY_METADATA_SUGGESTIONS,
ERROR_CODE_FETCH_METADATA_OPTIONS,
ERROR_CODE_FETCH_METADATA_TAXONOMY,
ERROR_CODE_FETCH_METADATA_TAXONOMY_NODE,
} from '../../constants';
import { handleOnAbort } from '../utils';
let metadata: Metadata;
jest.mock('../utils', () => ({
...jest.requireActual('../utils'),
handleOnAbort: jest.fn(),
}));
describe('api/Metadata', () => {
beforeEach(() => {
metadata = new Metadata({});
jest.resetAllMocks();
});
describe('getCacheKey()', () => {
test('should return correct key', () => {
expect(metadata.getCacheKey('foo')).toBe('file_foo');
});
});
describe('getMetadataCacheKey()', () => {
test('should return correct key', () => {
expect(metadata.getMetadataCacheKey('foo')).toBe('metadata_foo');
});
});
describe('getSkillsCacheKey()', () => {
test('should return correct key', () => {
expect(metadata.getSkillsCacheKey('foo')).toBe('metadata_foo_skills');
});
});
describe('getClassificationCacheKey()', () => {
test('should return correct key', () => {
expect(metadata.getClassificationCacheKey('foo')).toBe('metadata_foo_classification');
});
});
describe('getMetadataUrl()', () => {
test('should return base api url when no template or scope', () => {
expect(metadata.getMetadataUrl('foo')).toBe('https://api.box.com/2.0/files/foo/metadata');
expect(metadata.getMetadataUrl('foo', '', 'template')).toBe('https://api.box.com/2.0/files/foo/metadata');
expect(metadata.getMetadataUrl('foo', 'scope')).toBe('https://api.box.com/2.0/files/foo/metadata');
});
test('should return correct api url with scope and template', () => {
expect(metadata.getMetadataUrl('foo', 'scope', 'template')).toBe(
'https://api.box.com/2.0/files/foo/metadata/scope/template',
);
});
});
describe('getMetadataTemplateUrl()', () => {
test('should return correct base api url', () => {
expect(metadata.getMetadataTemplateUrl('scope')).toBe('https://api.box.com/2.0/metadata_templates');
});
});
describe('getMetadataTemplateUrlForInstance()', () => {
test('should return template url for an instance', () => {
expect(metadata.getMetadataTemplateUrlForInstance('id')).toBe(
'https://api.box.com/2.0/metadata_templates?metadata_instance_id=id',
);
});
});
describe('getMetadataTemplateSchemaUrl()', () => {
test('should return url for to get metadata schema using template key', () => {
const templateKey = 'templateKey_123';
expect(metadata.getMetadataTemplateSchemaUrl(templateKey)).toBe(
`https://api.box.com/2.0/metadata_templates/enterprise/${templateKey}/schema`,
);
});
});
describe('getMetadataTemplateUrlForScope()', () => {
test('should return correct template url for scope', () => {
expect(metadata.getMetadataTemplateUrlForScope('scope')).toBe(
'https://api.box.com/2.0/metadata_templates/scope',
);
});
});
describe('getCustomPropertiesTemplate()', () => {
test('should return correct properties template', () => {
expect(metadata.getCustomPropertiesTemplate()).toEqual({
id: expect.stringContaining('metadata_template_'),
scope: METADATA_SCOPE_GLOBAL,
templateKey: METADATA_TEMPLATE_PROPERTIES,
hidden: false,
fields: [],
});
});
});
describe('createEditor()', () => {
test('should return an uneditable editor', () => {
expect(
metadata.createEditor(
{
$id: 'id',
$foo: 'bar',
foo: 'bar',
$canEdit: true,
},
{ id: 'foo' },
false,
),
).toEqual({
template: {
id: 'foo',
},
instance: {
id: 'id',
canEdit: false,
data: {
foo: 'bar',
},
},
});
});
test('should return an editable editor', () => {
expect(
metadata.createEditor(
{
$id: 'id',
$foo: 'bar',
foo: 'bar',
$canEdit: true,
},
{ id: 'foo' },
true,
),
).toEqual({
template: {
id: 'foo',
},
instance: {
id: 'id',
canEdit: true,
data: {
foo: 'bar',
},
},
});
});
});
describe('createTemplateInstance()', () => {
test('should return Metadata Template Instance', () => {
expect(
metadata.createTemplateInstance(
{
$id: '321',
$template: '',
$canEdit: true,
testStringField: 'This is string',
testFloatField: '2.1',
},
{
displayName: 'Test template',
fields: [
{
description: 'Test description',
displayName: 'Test string field',
id: '123',
key: 'testStringField',
type: 'string',
},
{
description: 'Test description',
displayName: 'Test float field',
id: '456',
key: 'testFloatField',
type: 'float',
},
],
id: '123456',
templateKey: 'instance_from_template',
scope: 'enterprise',
},
true,
),
).toEqual({
canEdit: true,
displayName: 'Test template',
hidden: undefined,
id: '123456',
fields: [
{
description: 'Test description',
displayName: 'Test string field',
id: '123',
key: 'testStringField',
type: 'string',
value: 'This is string',
},
{
description: 'Test description',
displayName: 'Test float field',
id: '456',
key: 'testFloatField',
type: 'float',
value: '2.1',
},
],
scope: 'enterprise',
templateKey: 'instance_from_template',
});
});
test('should return Metadata Template Instance for Custom Metadata', () => {
expect(
metadata.createTemplateInstance(
{
$canEdit: true,
$id: '321',
$template: '',
testCustomField: 'This is string',
},
{
displayName: 'Test template',
fields: [],
id: '123456',
templateKey: 'properties',
},
false,
),
).toEqual({
canEdit: false,
displayName: 'Test template',
hidden: undefined,
id: '123456',
fields: [
{
key: 'testCustomField',
type: 'string',
value: 'This is string',
},
],
templateKey: 'properties',
});
});
});
describe('getTemplates()', () => {
test('should return templates with enterprise scope', async () => {
const templatesFromServer = [
{ id: 1, hidden: false },
{ id: 2, hidden: true },
{ id: 3, hidden: false },
{ id: 4, hidden: false },
{
id: 5,
hidden: true,
templateKey: METADATA_TEMPLATE_CLASSIFICATION,
},
{
id: 6,
hidden: false,
templateKey: METADATA_TEMPLATE_CLASSIFICATION,
},
];
metadata.getMetadataTemplateUrlForScope = jest.fn().mockReturnValueOnce('template_url');
metadata.xhr.get = jest.fn().mockReturnValueOnce({
data: {
entries: templatesFromServer,
},
});
const templates = await metadata.getTemplates('id', 'enterprise');
expect(metadata.errorCode).toBe(ERROR_CODE_FETCH_METADATA_TEMPLATES);
expect(templates).toEqual(templates);
expect(metadata.getMetadataTemplateUrlForScope).toHaveBeenCalledWith('enterprise');
expect(metadata.xhr.get).toHaveBeenCalledWith({
url: 'template_url',
id: 'file_id',
params: {
limit: 1000,
},
});
});
test('should return templates scoped to instance id', async () => {
const templatesFromServer = [{ id: 1, hidden: false }];
metadata.getMetadataTemplateUrlForInstance = jest.fn().mockReturnValueOnce('template_url');
metadata.xhr.get = jest.fn().mockReturnValueOnce({
data: {
entries: templatesFromServer,
},
});
const templates = await metadata.getTemplates('id', 'scope', 'id');
expect(metadata.errorCode).toBe(ERROR_CODE_FETCH_METADATA_TEMPLATES);
expect(templates).toEqual(templates);
expect(metadata.getMetadataTemplateUrlForInstance).toHaveBeenCalledWith('id');
expect(metadata.xhr.get).toHaveBeenCalledWith({
url: 'template_url',
id: 'file_id',
params: {
limit: 1000,
},
});
});
test('should return empty array of templates when error is 400', async () => {
const error = new Error();
error.status = 400;
metadata.getMetadataTemplateUrlForScope = jest.fn().mockReturnValueOnce('template_url');
metadata.xhr.get = jest.fn().mockReturnValueOnce(Promise.reject(error));
let templates;
try {
templates = await metadata.getTemplates('id', 'scope');
} catch (e) {
expect(e.status).toEqual(400);
}
expect(metadata.errorCode).toBe(ERROR_CODE_FETCH_METADATA_TEMPLATES);
expect(templates).toEqual([]);
expect(metadata.getMetadataTemplateUrlForScope).toHaveBeenCalledWith('scope');
expect(metadata.xhr.get).toHaveBeenCalledWith({
url: 'template_url',
id: 'file_id',
params: {
limit: 1000,
},
});
});
test('should throw error when error is not 400', async () => {
const error = new Error();
error.status = 401;
metadata.getMetadataTemplateUrlForScope = jest.fn().mockReturnValueOnce('template_url');
metadata.xhr.get = jest.fn().mockReturnValueOnce(Promise.reject(error));
let templates;
try {
templates = await metadata.getTemplates('id', 'scope');
} catch (e) {
expect(e.status).toEqual(401);
}
expect(metadata.errorCode).toBe(ERROR_CODE_FETCH_METADATA_TEMPLATES);
expect(templates).toBeUndefined();
expect(metadata.getMetadataTemplateUrlForScope).toHaveBeenCalledWith('scope');
expect(metadata.xhr.get).toHaveBeenCalledWith({
url: 'template_url',
id: 'file_id',
params: {
limit: 1000,
},
});
});
});
describe('getSchemaByTemplateKey()', () => {
test('should return metadata template for provided template key', async () => {
const metadataTemplate = 'metadataTemplate';
const templateKey = 'templateKey_123';
const url = `https://api.box.com/2.0/metadata_templates/enterprise/${templateKey}/schema`;
metadata.xhr.get = jest.fn().mockReturnValueOnce(Promise.resolve(metadataTemplate));
const response = await metadata.getSchemaByTemplateKey(templateKey);
expect(metadata.xhr.get).toHaveBeenCalledWith({ url });
expect(response).toBe(metadataTemplate);
});
});
describe('getInstances()', () => {
test('should return templates with enterprise scope', async () => {
const instancesFromServer = [
{ id: 1, hidden: false },
{ id: 2, hidden: true },
{ id: 3, hidden: false },
{ id: 4, hidden: false },
];
metadata.getMetadataUrl = jest.fn().mockReturnValueOnce('metadata_url');
metadata.xhr.get = jest.fn().mockReturnValueOnce({
data: {
entries: instancesFromServer,
},
});
const instances = await metadata.getInstances('id');
expect(metadata.errorCode).toBe(ERROR_CODE_FETCH_METADATA);
expect(instances).toEqual(instances);
expect(metadata.getMetadataUrl).toHaveBeenCalledWith('id');
expect(metadata.xhr.get).toHaveBeenCalledWith({
url: 'metadata_url',
id: 'file_id',
});
});
test('should return empty array of templates when error is 400', async () => {
const error = new Error();
error.status = 400;
metadata.getMetadataUrl = jest.fn().mockReturnValueOnce('metadata_url');
metadata.xhr.get = jest.fn().mockReturnValueOnce(Promise.reject(error));
let instances;
try {
instances = await metadata.getInstances('id');
} catch (e) {
expect(e.status).toEqual(400);
}
expect(metadata.errorCode).toBe(ERROR_CODE_FETCH_METADATA);
expect(instances).toEqual([]);
expect(metadata.getMetadataUrl).toHaveBeenCalledWith('id');
expect(metadata.xhr.get).toHaveBeenCalledWith({
url: 'metadata_url',
id: 'file_id',
});
});
test('should throw error when error is not 400', async () => {
const error = new Error();
error.status = 401;
metadata.getMetadataUrl = jest.fn().mockReturnValueOnce('metadata_url');
metadata.xhr.get = jest.fn().mockReturnValueOnce(Promise.reject(error));
let instances;
try {
instances = await metadata.getInstances('id');
} catch (e) {
expect(e.status).toEqual(401);
}
expect(metadata.errorCode).toBe(ERROR_CODE_FETCH_METADATA);
expect(instances).toBeUndefined();
expect(metadata.getMetadataUrl).toHaveBeenCalledWith('id');
expect(metadata.xhr.get).toHaveBeenCalledWith({
url: 'metadata_url',
id: 'file_id',
});
});
test('should apply hydrated query string param for isMetadataRedesign', async () => {
metadata.getMetadataUrl = jest.fn().mockReturnValueOnce('metadata_url');
metadata.xhr.get = jest.fn().mockReturnValueOnce({
data: {
entries: [],
},
});
await metadata.getInstances('id', true);
expect(metadata.xhr.get).toHaveBeenCalledWith({
url: 'metadata_url?view=hydrated',
id: 'file_id',
});
});
});
describe('getUserAddableTemplates()', () => {
test('should return empty array when metadata feature is off', async () => {
const custom = 'custom';
const ent = [{ templateKey: 'e1' }, { templateKey: 'e2' }];
const templates = [...ent, { templateKey: 'securityClassification-6VMVochwUWo' }];
expect(metadata.getUserAddableTemplates(custom, templates, false)).toEqual([]);
});
test('should return only custom props tempalte when file is externally owned', async () => {
const custom = 'custom';
const ent = [{ templateKey: 'e1' }, { templateKey: 'e2' }];
const templates = [...ent, { templateKey: 'securityClassification-6VMVochwUWo' }];
expect(metadata.getUserAddableTemplates(custom, templates, true, true)).toEqual(['custom']);
});
test('should return all templates for file owner minus classification', async () => {
const custom = 'custom';
const ent = [{ templateKey: 'e1' }, { templateKey: 'e2' }];
const templates = [...ent, { templateKey: 'securityClassification-6VMVochwUWo' }];
expect(metadata.getUserAddableTemplates(custom, templates, true)).toEqual(['custom', ...ent]);
});
test('should return all templates for file owner minus hidden ones', async () => {
const custom = 'custom';
const ent = [{ templateKey: 'e1', hidden: true }, { templateKey: 'e2' }];
const templates = [...ent, { templateKey: 'securityClassification-6VMVochwUWo' }];
expect(metadata.getUserAddableTemplates(custom, templates, true)).toEqual([
'custom',
{ templateKey: 'e2' },
]);
});
});
describe('extractClassification()', () => {
test('should extract and cache classification and return filtered instances', async () => {
const cache = new Cache();
metadata.getCache = jest.fn().mockReturnValueOnce(cache);
metadata.getClassificationCacheKey = jest.fn().mockReturnValueOnce('cache_id_classification');
expect(
metadata.extractClassification('id', [
{ $template: 'foo' },
{ $template: 'bad' },
{ $template: 'securityClassification-6VMVochwUWo' },
]),
).toEqual([{ $template: 'foo' }, { $template: 'bad' }]);
expect(metadata.getClassificationCacheKey).toHaveBeenCalledWith('id');
expect(cache.get('cache_id_classification')).toEqual({ $template: 'securityClassification-6VMVochwUWo' });
});
test('should return instances if no classification found', async () => {
const cache = new Cache();
metadata.getCache = jest.fn().mockReturnValueOnce(cache);
metadata.getClassificationCacheKey = jest.fn().mockReturnValueOnce('cache_id_classification');
expect(metadata.extractClassification('id', [{ $template: 'foo' }, { $template: 'bad' }])).toEqual([
{ $template: 'foo' },
{ $template: 'bad' },
]);
expect(metadata.getClassificationCacheKey).not.toHaveBeenCalled();
expect(cache.get('cache_id_classification')).toBeUndefined();
});
});
describe('getTemplateForInstance()', () => {
const templatesFromServer = [
{ id: 1, scope: 'global', templateKey: 'global1' },
{ id: 2, scope: 'enterprise', templateKey: 'enterprise2' },
{ id: 3, scope: 'enterprise', templateKey: 'enterprise3' },
{ id: 4, scope: 'enterprise', templateKey: 'enterprise4' },
{ id: 5, scope: 'global', templateKey: 'global5' },
{ id: 6, scope: 'global', templateKey: 'global6' },
];
test('should return undefined when no global template found', async () => {
const template = await metadata.getTemplateForInstance(
'id',
{
$id: 'instanceId',
$scope: 'global',
$template: 'foo',
},
templatesFromServer,
);
expect(template).toBeUndefined();
});
test('should return found enterprise template', async () => {
const template = await metadata.getTemplateForInstance(
'id',
{
$id: 'instanceId',
$scope: 'enterprise',
$template: 'enterprise2',
},
templatesFromServer,
);
expect(template).toBe(templatesFromServer[1]);
});
test('should return templates scoped to instance id', async () => {
metadata.getTemplates = jest.fn().mockResolvedValueOnce(['collabed_template']);
const template = await metadata.getTemplateForInstance(
'id',
{
$id: 'instanceId',
$scope: 'enterprise',
$template: 'foobar',
},
templatesFromServer,
);
expect(template).toBe('collabed_template');
expect(metadata.getTemplates).toBeCalledWith('id', 'enterprise', 'instanceId');
});
});
describe('getEditors()', () => {
test('should build and return editors with valid templates', async () => {
const instances = [
{
$id: '1',
$scope: 'global',
$template: 'global1',
},
{
$id: '2',
$scope: 'enterprise',
$template: 'enterprise2',
},
{
$id: '3',
$scope: 'enterprise',
$template: 'enterprise3',
},
{
$id: '4',
$scope: 'global',
$template: 'custom',
},
{
$id: '5',
$scope: 'global',
$template: 'bogus',
},
];
metadata.createEditor = jest
.fn()
.mockReturnValueOnce('editor1')
.mockReturnValueOnce('editor2')
.mockReturnValueOnce('editor3')
.mockReturnValueOnce('editor4');
metadata.getTemplateForInstance = jest
.fn()
.mockResolvedValueOnce('template1')
.mockResolvedValueOnce('template2')
.mockResolvedValueOnce('template3')
.mockResolvedValueOnce('template4')
.mockResolvedValueOnce();
const editors = await metadata.getEditors('id', instances, {}, [], [], true);
expect(editors).toEqual(['editor1', 'editor2', 'editor3', 'editor4']);
expect(metadata.createEditor).toBeCalledTimes(4);
expect(metadata.createEditor.mock.calls[0][0]).toBe(instances[0]);
expect(metadata.createEditor.mock.calls[0][1]).toBe('template1');
expect(metadata.createEditor.mock.calls[0][2]).toBe(true);
expect(metadata.createEditor.mock.calls[1][0]).toBe(instances[1]);
expect(metadata.createEditor.mock.calls[1][1]).toBe('template2');
expect(metadata.createEditor.mock.calls[1][2]).toBe(true);
expect(metadata.createEditor.mock.calls[2][0]).toBe(instances[2]);
expect(metadata.createEditor.mock.calls[2][1]).toBe('template3');
expect(metadata.createEditor.mock.calls[2][2]).toBe(true);
expect(metadata.createEditor.mock.calls[3][0]).toBe(instances[3]);
expect(metadata.createEditor.mock.calls[3][1]).toBe('template4');
expect(metadata.createEditor.mock.calls[3][2]).toBe(true);
expect(metadata.getTemplateForInstance).toBeCalledTimes(5);
expect(metadata.getTemplateForInstance.mock.calls[0][0]).toBe('id');
expect(metadata.getTemplateForInstance.mock.calls[0][1]).toBe(instances[0]);
expect(metadata.getTemplateForInstance.mock.calls[0][2]).toEqual([{}]);
expect(metadata.getTemplateForInstance.mock.calls[1][0]).toBe('id');
expect(metadata.getTemplateForInstance.mock.calls[1][1]).toBe(instances[1]);
expect(metadata.getTemplateForInstance.mock.calls[1][2]).toEqual([{}]);
expect(metadata.getTemplateForInstance.mock.calls[2][0]).toBe('id');
expect(metadata.getTemplateForInstance.mock.calls[2][1]).toBe(instances[2]);
expect(metadata.getTemplateForInstance.mock.calls[2][2]).toEqual([{}]);
expect(metadata.getTemplateForInstance.mock.calls[3][0]).toBe('id');
expect(metadata.getTemplateForInstance.mock.calls[3][1]).toBe(instances[3]);
expect(metadata.getTemplateForInstance.mock.calls[3][2]).toEqual([{}]);
expect(metadata.getTemplateForInstance.mock.calls[4][0]).toBe('id');
expect(metadata.getTemplateForInstance.mock.calls[4][1]).toBe(instances[4]);
expect(metadata.getTemplateForInstance.mock.calls[4][2]).toEqual([{}]);
});
});
describe('getTemplateInstances()', () => {
test('should build and return Metadata Template Instances with valid data', async () => {
const instances = [
{
$id: '1',
$scope: 'global',
$template: 'global1',
},
{
$id: '2',
$scope: 'enterprise',
$template: 'enterprise2',
},
{
$id: '3',
$scope: 'enterprise',
$template: 'enterprise3',
},
{
$id: '4',
$scope: 'global',
$template: 'custom',
},
{
$id: '5',
$scope: 'global',
$template: 'bogus',
},
];
metadata.createTemplateInstance = jest
.fn()
.mockReturnValueOnce('templateInstance1')
.mockReturnValueOnce('templateInstance2')
.mockReturnValueOnce('templateInstance3')
.mockReturnValueOnce('templateInstance4');
metadata.getTemplateForInstance = jest
.fn()
.mockResolvedValueOnce('template1')
.mockResolvedValueOnce('template2')
.mockResolvedValueOnce('template3')
.mockResolvedValueOnce('template4')
.mockResolvedValueOnce();
const templateInstances = await metadata.getTemplateInstances('id', instances, {}, [], [], true);
expect(templateInstances).toEqual([
'templateInstance1',
'templateInstance2',
'templateInstance3',
'templateInstance4',
]);
expect(metadata.createTemplateInstance).toBeCalledTimes(4);
expect(metadata.createTemplateInstance.mock.calls[0][0]).toBe(instances[0]);
expect(metadata.createTemplateInstance.mock.calls[0][1]).toBe('template1');
expect(metadata.createTemplateInstance.mock.calls[1][0]).toBe(instances[1]);
expect(metadata.createTemplateInstance.mock.calls[1][1]).toBe('template2');
expect(metadata.createTemplateInstance.mock.calls[2][0]).toBe(instances[2]);
expect(metadata.createTemplateInstance.mock.calls[2][1]).toBe('template3');
expect(metadata.createTemplateInstance.mock.calls[3][0]).toBe(instances[3]);
expect(metadata.createTemplateInstance.mock.calls[3][1]).toBe('template4');
expect(metadata.getTemplateForInstance).toBeCalledTimes(5);
expect(metadata.getTemplateForInstance.mock.calls[0][0]).toBe('id');
expect(metadata.getTemplateForInstance.mock.calls[0][1]).toBe(instances[0]);
expect(metadata.getTemplateForInstance.mock.calls[0][2]).toEqual([{}]);
expect(metadata.getTemplateForInstance.mock.calls[1][0]).toBe('id');
expect(metadata.getTemplateForInstance.mock.calls[1][1]).toBe(instances[1]);
expect(metadata.getTemplateForInstance.mock.calls[1][2]).toEqual([{}]);
expect(metadata.getTemplateForInstance.mock.calls[2][0]).toBe('id');
expect(metadata.getTemplateForInstance.mock.calls[2][1]).toBe(instances[2]);
expect(metadata.getTemplateForInstance.mock.calls[2][2]).toEqual([{}]);
expect(metadata.getTemplateForInstance.mock.calls[3][0]).toBe('id');
expect(metadata.getTemplateForInstance.mock.calls[3][1]).toBe(instances[3]);
expect(metadata.getTemplateForInstance.mock.calls[3][2]).toEqual([{}]);
expect(metadata.getTemplateForInstance.mock.calls[4][0]).toBe('id');
expect(metadata.getTemplateForInstance.mock.calls[4][1]).toBe(instances[4]);
expect(metadata.getTemplateForInstance.mock.calls[4][2]).toEqual([{}]);
});
});
describe('getMetadata()', () => {
test('should call error callback with a bad item error when no id', () => {
jest.spyOn(ErrorUtil, 'getBadItemError').mockReturnValueOnce('error');
metadata.errorHandler = jest.fn();
metadata.successHandler = jest.fn();
metadata.getMetadata({}, jest.fn(), jest.fn(), true);
expect(metadata.errorCode).toBe(ERROR_CODE_FETCH_METADATA);
expect(metadata.errorHandler).toBeCalledWith('error');
expect(metadata.successHandler).not.toBeCalled();
expect(ErrorUtil.getBadItemError).toBeCalled();
});
test('should call error callback with a bad item error when no permissions object', () => {
jest.spyOn(ErrorUtil, 'getBadItemError').mockReturnValueOnce('error');
metadata.errorHandler = jest.fn();
metadata.successHandler = jest.fn();
metadata.getMetadata({ id: 'id' }, jest.fn(), jest.fn(), true);
expect(metadata.errorCode).toBe(ERROR_CODE_FETCH_METADATA);
expect(metadata.errorHandler).toBeCalledWith('error');
expect(metadata.successHandler).not.toBeCalled();
expect(ErrorUtil.getBadItemError).toBeCalled();
});
test('should not make request and and return cached data', async () => {
const file = {
id: 'id',
is_externally_owned: true,
permissions: {
can_upload: true,
},
};
const cache = new Cache();
cache.set('cache_id_metadata', 'cached_metadata');
metadata.errorHandler = jest.fn();
metadata.successHandler = jest.fn();
metadata.isDestroyed = jest.fn().mockReturnValueOnce(false);
metadata.getCache = jest.fn().mockReturnValueOnce(cache);
metadata.getMetadataCacheKey = jest.fn().mockReturnValueOnce('cache_id_metadata');
metadata.getInstances = jest.fn().mockResolvedValueOnce('instances');
metadata.getEditors = jest.fn().mockResolvedValueOnce('editors');
metadata.getTemplateInstances = jest.fn().mockResolvedValueOnce('templateInstances');
metadata.getCustomPropertiesTemplate = jest.fn().mockReturnValueOnce('custom');
metadata.getUserAddableTemplates = jest.fn().mockReturnValueOnce('templates');
metadata.getTemplates = jest.fn().mockResolvedValueOnce('global').mockResolvedValueOnce('enterprise');
await metadata.getMetadata(file, jest.fn(), jest.fn(), true, { refreshCache: false });
expect(metadata.isDestroyed).not.toHaveBeenCalled();
expect(metadata.getCache).toHaveBeenCalled();
expect(metadata.getMetadataCacheKey).toHaveBeenCalledWith(file.id);
expect(metadata.getInstances).not.toHaveBeenCalledWith();
expect(metadata.getTemplates).not.toHaveBeenCalledWith();
expect(metadata.getTemplates).not.toHaveBeenCalledWith();
expect(metadata.getEditors).not.toHaveBeenCalledWith();
expect(metadata.getTemplateInstances).not.toHaveBeenCalledWith();
expect(metadata.getUserAddableTemplates).not.toHaveBeenCalledWith();
expect(metadata.successHandler).toHaveBeenCalledWith('cached_metadata');
expect(metadata.successHandler).toHaveBeenCalledTimes(1);
expect(metadata.errorHandler).not.toHaveBeenCalled();
expect(cache.get('cache_id_metadata')).toEqual('cached_metadata');
});
test('should make request and update cache and call success handler', async () => {
const file = {
id: 'id',
is_externally_owned: true,
permissions: {
can_upload: true,
},
};
const cache = new Cache();
metadata.errorHandler = jest.fn();
metadata.successHandler = jest.fn();
metadata.isDestroyed = jest.fn().mockReturnValueOnce(false);
metadata.getCache = jest.fn().mockReturnValueOnce(cache);
metadata.getMetadataCacheKey = jest.fn().mockReturnValueOnce('cache_id_metadata');
metadata.getInstances = jest.fn().mockResolvedValueOnce('instances');
metadata.getEditors = jest.fn().mockResolvedValueOnce('editors');
metadata.getTemplateInstances = jest.fn().mockResolvedValueOnce('templateInstances');
metadata.getCustomPropertiesTemplate = jest.fn().mockReturnValueOnce('custom');
metadata.getUserAddableTemplates = jest.fn().mockReturnValueOnce('templates');
metadata.getTemplates = jest.fn().mockResolvedValueOnce('global').mockResolvedValueOnce('enterprise');
metadata.extractClassification = jest.fn().mockReturnValueOnce('filteredInstances');
await metadata.getMetadata(file, jest.fn(), jest.fn(), true);
expect(metadata.isDestroyed).toHaveBeenCalled();
expect(metadata.getCache).toHaveBeenCalled();
expect(metadata.getMetadataCacheKey).toHaveBeenCalledWith(file.id);
expect(metadata.getInstances).toHaveBeenCalledWith(file.id, false);
expect(metadata.getTemplates).toHaveBeenCalledWith(file.id, 'global');
expect(metadata.getTemplates).toHaveBeenCalledWith(file.id, 'enterprise');
expect(metadata.extractClassification).toBeCalledWith('id', 'instances');
expect(metadata.getEditors).toHaveBeenCalledWith(
file.id,
'filteredInstances',
'custom',
'enterprise',
'global',
true,
);
expect(metadata.getTemplateInstances).not.toHaveBeenCalled();
expect(metadata.getUserAddableTemplates).toHaveBeenCalledWith('custom', 'enterprise', true, true);
expect(metadata.successHandler).toHaveBeenCalledWith({
editors: 'editors',
templateInstances: [],
templates: 'templates',
});
expect(metadata.errorHandler).not.toHaveBeenCalled();
expect(cache.get('cache_id_metadata')).toEqual({
editors: 'editors',
templateInstances: [],
templates: 'templates',
});
});
test('should make request and update cache and call success handler for Metadata Redesign', async () => {
const file = {
id: 'id',
is_externally_owned: true,
permissions: {
can_upload: true,
},
};
const cache = new Cache();
metadata.errorHandler = jest.fn();
metadata.successHandler = jest.fn();
metadata.isDestroyed = jest.fn().mockReturnValueOnce(false);
metadata.getCache = jest.fn().mockReturnValueOnce(cache);
metadata.getMetadataCacheKey = jest.fn().mockReturnValueOnce('cache_id_metadata');
metadata.getInstances = jest.fn().mockResolvedValueOnce('instances');
metadata.getEditors = jest.fn().mockResolvedValueOnce('editors');
metadata.getTemplateInstances = jest.fn().mockResolvedValueOnce('templateInstances');
metadata.getCustomPropertiesTemplate = jest.fn().mockReturnValueOnce('custom');
metadata.getUserAddableTemplates = jest.fn().mockReturnValueOnce('templates');
metadata.getTemplates = jest.fn().mockResolvedValueOnce('global').mockResolvedValueOnce('enterprise');
metadata.extractClassification = jest.fn().mockReturnValueOnce('filteredInstances');
await metadata.getMetadata(file, jest.fn(), jest.fn(), true, {}, true);
expect(metadata.isDestroyed).toHaveBeenCalled();
expect(metadata.getCache).toHaveBeenCalled();
expect(metadata.getMetadataCacheKey).toHaveBeenCalledWith(file.id);
expect(metadata.getInstances).toHaveBeenCalledWith(file.id, true);
expect(metadata.getTemplates).toHaveBeenCalledWith(file.id, 'global');
expect(metadata.getTemplates).toHaveBeenCalledWith(file.id, 'enterprise');
expect(metadata.extractClassification).toBeCalledWith('id', 'instances');
expect(metadata.getEditors).not.toHaveBeenCalled();
expect(metadata.getTemplateInstances).toHaveBeenCalledWith(
file.id,
'filteredInstances',
'custom',
'enterprise',
'global',
true,
);
expect(metadata.getUserAddableTemplates).toHaveBeenCalledWith('custom', 'enterprise', true, true);
expect(metadata.successHandler).toHaveBeenCalledWith({
editors: [],
templateInstances: 'templateInstances',
templates: 'templates',
});
expect(metadata.errorHandler).not.toHaveBeenCalled();
expect(cache.get('cache_id_metadata')).toEqual({
editors: [],
templateInstances: 'templateInstances',
templates: 'templates',
});
});
test('should make request and update cache and call success handler after returning cached value when refreshCache is true', async () => {
const file = {
id: 'id',
is_externally_owned: true,
permissions: {
can_upload: true,
},
};
const cache = new Cache();
cache.set('cache_id_metadata', 'cached_metadata');
metadata.errorHandler = jest.fn();
metadata.successHandler = jest.fn();
metadata.isDestroyed = jest.fn().mockReturnValueOnce(false);
metadata.getCache = jest.fn().mockReturnValueOnce(cache);
metadata.getMetadataCacheKey = jest.fn().mockReturnValueOnce('cache_id_metadata');
metadata.getInstances = jest.fn().mockResolvedValueOnce('instances');
metadata.getEditors = jest.fn().mockResolvedValueOnce('editors');
metadata.getTemplateInstances = jest.fn().mockResolvedValueOnce('templateInstances');
metadata.getCustomPropertiesTemplate = jest.fn().mockReturnValueOnce('custom');
metadata.getUserAddableTemplates = jest.fn().mockReturnValueOnce('templates');
metadata.getTemplates = jest.fn().mockResolvedValueOnce('global').mockResolvedValueOnce('enterprise');
metadata.extractClassification = jest.fn().mockReturnValueOnce('filteredInstances');
await metadata.getMetadata(file, jest.fn(), jest.fn(), true, { refreshCache: true });
expect(metadata.isDestroyed).toHaveBeenCalled();
expect(metadata.getCache).toHaveBeenCalled();
expect(metadata.getMetadataCacheKey).toHaveBeenCalledWith(file.id);
expect(metadata.getInstances).toHaveBeenCalledWith(file.id, false);
expect(metadata.getTemplates).toHaveBeenCalledWith(file.id, 'global');
expect(metadata.getTemplates).toHaveBeenCalledWith(file.id, 'enterprise');
expect(metadata.extractClassification).toBeCalledWith('id', 'instances');
expect(metadata.getEditors).toHaveBeenCalledWith(
file.id,
'filteredInstances',
'custom',
'enterprise',
'global',
true,
);
expect(metadata.getTemplateInstances).not.toHaveBeenCalled();
expect(metadata.getUserAddableTemplates).toHaveBeenCalledWith('custom', 'enterprise', true, true);
expect(metadata.successHandler).toHaveBeenCalledTimes(2);
expect(metadata.successHandler).toHaveBeenCalledWith('cached_metadata');
expect(metadata.successHandler).toHaveBeenCalledWith({
editors: 'editors',
templateInstances: [],
templates: 'templates',
});
expect(metadata.errorHandler).not.toHaveBeenCalled();
expect(cache.get('cache_id_metadata')).toEqual({
editors: 'editors',
templateInstances: [],
templates: 'templates',
});
});
test('should ignore cache and make request and update cache and call success handler when forceFetch is true', async () => {
const file = {
id: 'id',
is_externally_owned: true,
permissions: {
can_upload: true,
},
};
const cache = new Cache();
cache.set('cache_id_metadata', 'cached_metadata');
metadata.errorHandler = jest.fn();
metadata.successHandler = jest.fn();
metadata.isDestroyed = jest.fn().mockReturnValueOnce(false);
metadata.getCache = jest.fn().mockReturnValueOnce(cache);
metadata.getMetadataCacheKey = jest.fn().mockReturnValueOnce('cache_id_metadata');
metadata.getInstances = jest.fn().mockResolvedValueOnce('instances');
metadata.getEditors = jest.fn().mockResolvedValueOnce('editors');
metadata.getTemplateInstances = jest.fn().mockResolvedValueOnce('templateInstances');
metadata.getCustomPropertiesTemplate = jest.fn().mockReturnValueOnce('custom');
metadata.getUserAddableTemplates = jest.fn().mockReturnValueOnce('templates');
metadata.getTemplates = jest.fn().mockResolvedValueOnce('global').mockResolvedValueOnce('enterprise');
metadata.extractClassification = jest.fn().mockReturnValueOnce('filteredInstances');
await metadata.getMetadata(file, jest.fn(), jest.fn(), true, { forceFetch: true });
expect(metadata.isDestroyed).toHaveBeenCalled();
expect(metadata.getCache).toHaveBeenCalled();
expect(metadata.getMetadataCacheKey).toHaveBeenCalledWith(file.id);
expect(metadata.getInstances).toHaveBeenCalledWith(file.id, false);
expect(metadata.getTemplates).toHaveBeenCalledWith(file.id, 'global');
expect(metadata.getTemplates).toHaveBeenCalledWith(file.id, 'enterprise');
expect(metadata.extractClassification).toBeCalledWith('id', 'instances');
expect(metadata.getEditors).toHaveBeenCalledWith(
file.id,
'filteredInstances',
'custom',
'enterprise',
'global',
true,
);
expect(metadata.getTemplateInstances).not.toHaveBeenCalled();
expect(metadata.getUserAddableTemplates).toHaveBeenCalledWith('custom', 'enterprise', true, true);
expect(metadata.successHandler).toHaveBeenCalledTimes(1);
expect(metadata.successHandler).not.toHaveBeenCalledWith('cached_metadata');
expect(metadata.successHandler).toHaveBeenCalledWith({
editors: 'editors',
templateInstances: [],
templates: 'templates',
});
expect(metadata.errorHandler).not.toHaveBeenCalled();
expect(cache.get('cache_id_metadata')).toEqual({
editors: 'editors',
templateInstances: [],
templates: 'templates',
});
});
test('should make request and update cache and call success handler with metadata feature off', async () => {
const file = {
id: 'id',
is_externally_owned: true,
permissions: {
can_upload: true,
},
};
const cache = new Cache();
metadata.errorHandler = jest.fn();
metadata.successHandler = jest.fn();
metadata.isDestroyed = jest.fn().mockReturnValueOnce(false);
metadata.getCache = jest.fn().mockReturnValueOnce(cache);
metadata.getMetadataCacheKey = jest.fn().mockReturnValueOnce('cache_id_metadata');
metadata.getInstances = jest.fn().mockResolvedValueOnce('instances');
metadata.getEditors = jest.fn().mockResolvedValueOnce('editors');
metadata.getTemplateInstances = jest.fn().mockResolvedValueOnce('templateInstances');
metadata.getCustomPropertiesTemplate = jest.fn().mockReturnValueOnce('custom');
metadata.getUserAddableTemplates = jest.fn().mockReturnValueOnce('templates');
metadata.getTemplates = jest.fn().mockResolvedValueOnce('global').mockResolvedValueOnce('enterprise');
metadata.extractClassification = jest.fn().mockReturnValueOnce('filteredInstances');
await metadata.getMetadata(file, jest.fn(), jest.fn(), false);
expect(metadata.isDestroyed).toHaveBeenCalled();
expect(metadata.getCache).toHaveBeenCalled();
expect(metadata.getMetadataCacheKey).toHaveBeenCalledWith(file.id);
expect(metadata.getInstances).toHaveBeenCalledWith(file.id, false);
expect(metadata.getTemplates).toHaveBeenCalledWith(file.id, 'global');
expect(metadata.getTemplates).not.toHaveBeenCalledWith(file.id, 'enterprise');
expect(metadata.extractClassification).toBeCalledWith('id', 'instances');
expect(metadata.getEditors).toHaveBeenCalledWith(
file.id,
'filteredInstances',
'custom',
[],
'global',
true,
);
expect(metadata.getTemplateInstances).not.toHaveBeenCalled();
expect(metadata.getUserAddableTemplates).toHaveBeenCalledWith('custom', [], false, true);
expect(metadata.successHandler).toHaveBeenCalledTimes(1);
expect(metadata.successHandler).toHaveBeenCalledWith({
editors: 'editors',
templateInstances: [],
templates: 'templates',
});
expect(metadata.errorHandler).not.toHaveBeenCalled();
expect(cache.get('cache_id_metadata')).toEqual({
editors: 'editors',
templateInstances: [],
templates: 'templates',
});
});
test('should call error handler on an error', async () => {
const file = {
id: 'id',
is_externally_owned: true,
permissions: {
can_upload: true,
},
};
const cache = new Cache();
metadata.e