|
@@ -16,6 +16,7 @@
|
|
|
|
|
|
|
|
import { Compute, Connector, Namespace } from 'config/types';
|
|
import { Compute, Connector, Namespace } from 'config/types';
|
|
|
import dataCatalog from './dataCatalog';
|
|
import dataCatalog from './dataCatalog';
|
|
|
|
|
+import { TableAnalysis } from './DataCatalogEntry';
|
|
|
|
|
|
|
|
const connectorOne: Connector = {
|
|
const connectorOne: Connector = {
|
|
|
buttonName: '',
|
|
buttonName: '',
|
|
@@ -35,7 +36,7 @@ const connectorTwo: Connector = {
|
|
|
type: ''
|
|
type: ''
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-const compute: Compute = { id: 'computeId', name: '', type: '' };
|
|
|
|
|
|
|
+const compute: Compute = { id: 'computeId', name: 'testCompute', type: '' };
|
|
|
|
|
|
|
|
const namespaceOne: Namespace = { computes: [compute], id: 'namespaceOne', name: '', status: '' };
|
|
const namespaceOne: Namespace = { computes: [compute], id: 'namespaceOne', name: '', status: '' };
|
|
|
const namespaceTwo: Namespace = { computes: [compute], id: 'namespaceTwo', name: '', status: '' };
|
|
const namespaceTwo: Namespace = { computes: [compute], id: 'namespaceTwo', name: '', status: '' };
|
|
@@ -53,8 +54,35 @@ const clearStorage = async (): Promise<void> => {
|
|
|
await dataCatalog.getCatalog(connectorTwo).clearStorageCascade();
|
|
await dataCatalog.getCatalog(connectorTwo).clearStorageCascade();
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+const createMockAnalysis = (comment: string): TableAnalysis => ({
|
|
|
|
|
+ cols: [],
|
|
|
|
|
+ comment,
|
|
|
|
|
+ details: { properties: {}, stats: {} },
|
|
|
|
|
+ hdfs_link: '',
|
|
|
|
|
+ is_view: false,
|
|
|
|
|
+ message: '',
|
|
|
|
|
+ name: '',
|
|
|
|
|
+ partition_keys: [],
|
|
|
|
|
+ path_location: '',
|
|
|
|
|
+ primary_keys: [],
|
|
|
|
|
+ properties: [],
|
|
|
|
|
+ stats: [],
|
|
|
|
|
+ hueTimestamp: Date.now()
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
describe('dataCatalog.ts', () => {
|
|
describe('dataCatalog.ts', () => {
|
|
|
- beforeEach(clearStorage);
|
|
|
|
|
|
|
+ beforeEach(() => {
|
|
|
|
|
+ // Enable caching for tests so that we can test the cache key generation
|
|
|
|
|
+ (window as unknown as { CACHEABLE_TTL: { default: number } }).CACHEABLE_TTL = {
|
|
|
|
|
+ default: 3600000
|
|
|
|
|
+ }; // 1 hour
|
|
|
|
|
+ return clearStorage();
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ afterEach(() => {
|
|
|
|
|
+ // Clean up global state to prevent test pollution
|
|
|
|
|
+ delete (window as unknown as { CACHEABLE_TTL?: { default: number } }).CACHEABLE_TTL;
|
|
|
|
|
+ });
|
|
|
|
|
|
|
|
afterAll(clearStorage);
|
|
afterAll(clearStorage);
|
|
|
|
|
|
|
@@ -107,4 +135,40 @@ describe('dataCatalog.ts', () => {
|
|
|
expect(caught).toBeTruthy();
|
|
expect(caught).toBeTruthy();
|
|
|
});
|
|
});
|
|
|
});
|
|
});
|
|
|
|
|
+
|
|
|
|
|
+ describe('cache key consistency', () => {
|
|
|
|
|
+ it('should generate consistent cache keys between save and load operations', async () => {
|
|
|
|
|
+ const testCases = [
|
|
|
|
|
+ { path: ['db1'], description: 'database level' },
|
|
|
|
|
+ { path: ['db1', 'table1'], description: 'table level' },
|
|
|
|
|
+ { path: ['db1', 'table1', 'col1'], description: 'column level' }
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ for (const testCase of testCases) {
|
|
|
|
|
+ const entry = await getEntry(testCase.path);
|
|
|
|
|
+
|
|
|
|
|
+ // Mock the store to capture the cache key used during save
|
|
|
|
|
+ let savedCacheKey: string | undefined;
|
|
|
|
|
+ const originalSetItem = entry.dataCatalog.store.setItem;
|
|
|
|
|
+ entry.dataCatalog.store.setItem = jest
|
|
|
|
|
+ .fn()
|
|
|
|
|
+ .mockImplementation((key: string, value: unknown) => {
|
|
|
|
|
+ savedCacheKey = key;
|
|
|
|
|
+ return originalSetItem.call(entry.dataCatalog.store, key, value);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // Save analysis data
|
|
|
|
|
+ entry.analysis = createMockAnalysis(`test comment for ${testCase.description}`);
|
|
|
|
|
+ await entry.save();
|
|
|
|
|
+
|
|
|
|
|
+ // Verify cache key format: namespace_computeName_path
|
|
|
|
|
+ const expectedKey = `${namespaceOne.id}_${compute.name}_${testCase.path.join('.')}`;
|
|
|
|
|
+ expect(savedCacheKey).toBe(expectedKey);
|
|
|
|
|
+ expect(savedCacheKey).not.toContain('undefined');
|
|
|
|
|
+
|
|
|
|
|
+ // Restore original method for next iteration
|
|
|
|
|
+ entry.dataCatalog.store.setItem = originalSetItem;
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
});
|
|
});
|