Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 3 additions & 9 deletions src/elements/content-explorer/MetadataQueryAPIHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,17 +172,11 @@ export default class MetadataQueryAPIHelper {
};

getTemplateSchemaInfo = (data: MetadataQueryResponseData): Promise<MetadataTemplateSchemaResponse | void> => {
const { entries } = data;
this.metadataQueryResponseData = data;
if (!entries || entries.length === 0) {
// Don't make metadata API call to get template info
return Promise.resolve();
}

const metadata = getProp(entries, '[0].metadata');
this.templateScope = Object.keys(metadata)[0];
const instance = metadata[this.templateScope];
this.templateKey = Object.keys(instance)[0];
const [scope, key] = this.metadataQuery.from.split('.');
this.templateScope = scope;
this.templateKey = key;

return this.api.getMetadataAPI(true).getSchemaByTemplateKey(this.templateKey);
};
Expand Down
40 changes: 14 additions & 26 deletions src/elements/content-explorer/MetadataQueryBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { BoxItemSelection } from '@box/box-item-type-selector';
import isNil from 'lodash/isNil';
import { mapFileTypes } from './utils';
import { getFileExtensions } from './utils';

type QueryResult = {
queryParams: { [key: string]: number | Date | string };
Expand Down Expand Up @@ -134,42 +133,31 @@ export const getMimeTypeFilter = (filterValue: string[], fieldKey: string, argIn
};
}

// Use mapFileTypes to get the correct extensions and handle special cases
const mappedExtensions = mapFileTypes(filterValue as BoxItemSelection);
if (mappedExtensions.length === 0) {
return {
queryParams: {},
queries: [],
keysGenerated: 0,
};
}

let currentArgIndex = argIndexStart;
const queryParams: { [key: string]: number | Date | string } = {};
const queries: string[] = [];

// Handle specific extensions and folder type
const extensions: string[] = [];
const extensions: string[][] = [];
let hasFolder = false;

for (const extension of mappedExtensions) {
if (extension === 'folder') {
if (!hasFolder) {
currentArgIndex += 1;
const folderArgKey = generateArgKey('mime_folderType', currentArgIndex);
queryParams[folderArgKey] = 'folder';
queries.push(`(item.type = :${folderArgKey})`);
hasFolder = true;
}
for (const extension of filterValue) {
if (extension === 'folderType' && !hasFolder) {
currentArgIndex += 1;
const folderArgKey = generateArgKey('mime_folderType', currentArgIndex);
queryParams[folderArgKey] = 'folder';
queries.push(`(item.type = :${folderArgKey})`);
hasFolder = true;
} else {
extensions.push(extension);
extensions.push(getFileExtensions(extension));
}
}

// flat the array of arrays
const flattenExtensions = extensions.flat();
// Handle extensions in batch if any exist
if (extensions.length > 0) {
if (flattenExtensions.length > 0) {
const extensionQueryParams = Object.fromEntries(
extensions.map(extension => {
flattenExtensions.map(extension => {
currentArgIndex += 1;
return [generateArgKey(fieldKey, currentArgIndex), extension];
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,14 +189,14 @@ describe('elements/content-explorer/MetadataQueryAPIHelper', () => {
};
const mdQuery = {
ancestor_folder_id: '672838458',
from: 'enterprise_1234.templateKey',
from: `${templateScope}.${templateKey}`,
query: 'query',
query_params: {},
fields: [
FIELD_ITEM_NAME,
'metadata.enterprise_1234.templateKey.type',
'metadata.enterprise_1234.templateKey.year',
'metadata.enterprise_1234.templateKey.approved',
`metadata.${templateScope}.${templateKey}.type`,
`metadata.${templateScope}.${templateKey}.year`,
`metadata.${templateScope}.${templateKey}.approved`,
],
};

Expand All @@ -206,6 +206,10 @@ describe('elements/content-explorer/MetadataQueryAPIHelper', () => {
metadataQueryAPIHelper.templateScope = templateScope;
metadataQueryAPIHelper.metadataTemplate = template;
metadataQueryAPIHelper.metadataQuery = mdQuery;

// Reset mocks before each test
getSchemaByTemplateKeyFunc.mockClear();
getSchemaByTemplateKeyFunc.mockResolvedValue(templateSchemaResponse);
});

describe('flattenMetadata()', () => {
Expand Down Expand Up @@ -267,7 +271,7 @@ describe('elements/content-explorer/MetadataQueryAPIHelper', () => {
});

describe('getTemplateSchemaInfo()', () => {
test('should set instance properties and make xhr call to get template info when response has valid entries', async () => {
test('should set instance properties and make xhr call to get template info', async () => {
const result = await metadataQueryAPIHelper.getTemplateSchemaInfo(metadataQueryResponse);
expect(getSchemaByTemplateKeyFunc).toHaveBeenCalledWith(templateKey);
expect(result).toEqual(templateSchemaResponse);
Expand All @@ -276,26 +280,49 @@ describe('elements/content-explorer/MetadataQueryAPIHelper', () => {
expect(metadataQueryAPIHelper.templateKey).toEqual(templateKey);
});

test('should not make xhr call to get metadata template info when response has zero/invalid entries', async () => {
test('should make xhr call to get metadata template info even when response has zero entries', async () => {
const emptyEntriesResponse = { entries: [], next_marker: nextMarker };
const result = await metadataQueryAPIHelper.getTemplateSchemaInfo(emptyEntriesResponse);
expect(getSchemaByTemplateKeyFunc).not.toHaveBeenCalled();
expect(result).toBe(undefined);
expect(getSchemaByTemplateKeyFunc).toHaveBeenCalledWith(templateKey);
expect(result).toEqual(templateSchemaResponse);
expect(metadataQueryAPIHelper.metadataQueryResponseData).toEqual(emptyEntriesResponse);
expect(metadataQueryAPIHelper.templateScope).toEqual(templateScope);
expect(metadataQueryAPIHelper.templateKey).toEqual(templateKey);
});

test('should handle response with null entries', async () => {
test('should make xhr call to get metadata template info even when response has null entries', async () => {
const nullEntriesResponse = { entries: null, next_marker: nextMarker };
const result = await metadataQueryAPIHelper.getTemplateSchemaInfo(nullEntriesResponse);
expect(getSchemaByTemplateKeyFunc).not.toHaveBeenCalled();
expect(result).toBe(undefined);
expect(getSchemaByTemplateKeyFunc).toHaveBeenCalledWith(templateKey);
expect(result).toEqual(templateSchemaResponse);
expect(metadataQueryAPIHelper.metadataQueryResponseData).toEqual(nullEntriesResponse);
expect(metadataQueryAPIHelper.templateScope).toEqual(templateScope);
expect(metadataQueryAPIHelper.templateKey).toEqual(templateKey);
});

test('should handle response with undefined entries', async () => {
test('should make xhr call to get metadata template info even when response has undefined entries', async () => {
const undefinedEntriesResponse = { next_marker: nextMarker };
const result = await metadataQueryAPIHelper.getTemplateSchemaInfo(undefinedEntriesResponse);
expect(getSchemaByTemplateKeyFunc).not.toHaveBeenCalled();
expect(result).toBe(undefined);
expect(getSchemaByTemplateKeyFunc).toHaveBeenCalledWith(templateKey);
expect(result).toEqual(templateSchemaResponse);
expect(metadataQueryAPIHelper.metadataQueryResponseData).toEqual(undefinedEntriesResponse);
expect(metadataQueryAPIHelper.templateScope).toEqual(templateScope);
expect(metadataQueryAPIHelper.templateKey).toEqual(templateKey);
});

test('should extract template scope and key from metadata query from field', async () => {
// Test with different scope and key in the query
const differentScope = 'enterprise_99999';
const differentKey = 'differentTemplate';
metadataQueryAPIHelper.metadataQuery = {
...mdQuery,
from: `${differentScope}.${differentKey}`,
};

await metadataQueryAPIHelper.getTemplateSchemaInfo(metadataQueryResponse);
expect(getSchemaByTemplateKeyFunc).toHaveBeenCalledWith(differentKey);
expect(metadataQueryAPIHelper.templateScope).toEqual(differentScope);
expect(metadataQueryAPIHelper.templateKey).toEqual(differentKey);
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
getSelectFilter,
getMimeTypeFilter,
} from '../MetadataQueryBuilder';
import { getFileExtensions } from '../utils';

describe('elements/content-explorer/MetadataQueryBuilder', () => {
describe('mergeQueryParams', () => {
Expand Down Expand Up @@ -532,4 +533,16 @@ describe('elements/content-explorer/MetadataQueryBuilder', () => {
});
});
});

describe('getFileExtensions', () => {
test('should return actual file extensions for single file type', () => {
const result = getFileExtensions('documentType');
expect(result).toEqual(['doc', 'docx', 'gdoc', 'rtf', 'txt']);
});

test('should handle empty array input', () => {
const result = getFileExtensions('');
expect(result).toEqual([]);
});
});
});
2 changes: 0 additions & 2 deletions src/elements/content-explorer/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,4 @@ export const NON_FOLDER_FILE_TYPES_MAP = new Map([
['threedType', ['obj', 'fbx', 'stl', 'amf', 'iges']],
]);

export const FILE_FOLDER_TYPES_MAP = new Map(NON_FOLDER_FILE_TYPES_MAP).set('folderType', ['folder']);

export const NON_FOLDER_FILE_TYPES = Array.from(NON_FOLDER_FILE_TYPES_MAP.keys());
19 changes: 5 additions & 14 deletions src/elements/content-explorer/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,10 @@ import {
} from '@box/metadata-editor';
import type { MetadataFieldType } from '@box/metadata-view';
import type { Selection } from 'react-aria-components';
import { BoxItemSelection } from '@box/box-item-type-selector';
import type { BoxItem, Collection } from '../../common/types/core';

import messages from '../common/messages';
import { FILE_FOLDER_TYPES_MAP, NON_FOLDER_FILE_TYPES } from './constants';
import { NON_FOLDER_FILE_TYPES_MAP } from './constants';

// Specific type for metadata field value in the item
// Note: Item doesn't have field value in metadata object if that field is not set, so the value will be undefined in this case
Expand Down Expand Up @@ -196,17 +195,9 @@ export function useTemplateInstance(metadataTemplate: MetadataTemplate, selected
};
}

export const mapFileTypes = (selectedFileTypes: BoxItemSelection) => {
const selectedFileTypesSet = new Set(selectedFileTypes);

const areAllNonFolderFileTypesSelected = NON_FOLDER_FILE_TYPES.every(key => selectedFileTypesSet.has(key));

if (areAllNonFolderFileTypesSelected) {
if (selectedFileTypes.includes('folderType')) {
return [];
}
return ['file'];
export const getFileExtensions = (selectedFileType: string) => {
if (NON_FOLDER_FILE_TYPES_MAP.has(selectedFileType)) {
return NON_FOLDER_FILE_TYPES_MAP.get(selectedFileType).flat();
}

return selectedFileTypes.map(fileType => FILE_FOLDER_TYPES_MAP.get(fileType as string) || []).flat();
return [];
};