Add tests for fetchTechDocsMetadata

Signed-off-by: vitorgrenzel <vitorgrenzel@gmail.com>
This commit is contained in:
vitorgrenzel
2021-02-18 02:31:21 -03:00
parent ac4a098551
commit b27aa7c7ac
3 changed files with 107 additions and 13 deletions
@@ -17,6 +17,7 @@ import type {
BlobUploadCommonResponse,
ContainerGetPropertiesResponse,
} from '@azure/storage-blob';
import { EventEmitter } from 'events';
import fs from 'fs-extra';
import os from 'os';
import path from 'path';
@@ -62,6 +63,24 @@ export class BlockBlobClient {
exists() {
return checkFileExists(this.blobName);
}
download() {
const emitter = new EventEmitter();
process.nextTick(() => {
if (fs.existsSync(this.blobName)) {
emitter.emit('data', Buffer.from(fs.readFileSync(this.blobName)));
} else {
emitter.emit(
'error',
new Error(`The file ${this.blobName} doest not exist!`),
);
}
emitter.emit('end');
});
return Promise.resolve({
readableStreamBody: emitter,
});
}
}
class BlockBlobClientFailUpload extends BlockBlobClient {
@@ -20,8 +20,9 @@ import mockFs from 'mock-fs';
import os from 'os';
import path from 'path';
import { AzureBlobStoragePublish } from './azureBlobStorage';
import { PublisherBase } from './types';
import { PublisherBase, TechDocsMetadata } from './types';
import type { Entity, EntityName } from '@backstage/catalog-model';
import type { Logger } from 'winston';
// NOTE: /packages/techdocs-common/__mocks__ is being used to mock Azure client library
const createMockEntity = (annotations = {}) => {
@@ -38,6 +39,12 @@ const createMockEntity = (annotations = {}) => {
};
};
const createMockEntityName = (): EntityName => ({
kind: 'TestKind',
name: 'test-component-name',
namespace: 'test-namespace',
});
const rootDir = os.platform() === 'win32' ? 'C:\\rootDir' : '/rootDir';
const getEntityRootDir = (entity: Entity) => {
const {
@@ -255,4 +262,60 @@ describe('error reporting', () => {
mockFs.restore();
});
describe('fetchTechDocsMetadata', () => {
it('should return tech docs metadata', async () => {
const entityNameMock = createMockEntityName();
const entity = createMockEntity();
const entityRootDir = getEntityRootDir(entity);
mockFs({
[entityRootDir]: {
'techdocs_metadata.json':
'{"site_name": "backstage", "site_description": "site_content"}',
},
});
const expectedMetadata: TechDocsMetadata = {
site_name: 'backstage',
site_description: 'site_content',
};
expect(
await publisher.fetchTechDocsMetadata(entityNameMock),
).toStrictEqual(expectedMetadata);
mockFs.restore();
});
it('should return tech docs metadata when json encoded with single quotes', async () => {
const entityNameMock = createMockEntityName();
const entity = createMockEntity();
const entityRootDir = getEntityRootDir(entity);
mockFs({
[entityRootDir]: {
'techdocs_metadata.json': `{'site_name': 'backstage', 'site_description': 'site_content'}`,
},
});
const expectedMetadata: TechDocsMetadata = {
site_name: 'backstage',
site_description: 'site_content',
};
expect(
await publisher.fetchTechDocsMetadata(entityNameMock),
).toStrictEqual(expectedMetadata);
mockFs.restore();
});
it('should return an error if the techdocs_metadata.json file is not present', async () => {
const entityNameMock = createMockEntityName();
await publisher
.fetchTechDocsMetadata(entityNameMock)
.catch(error =>
expect(error.message).toEqual(
expect.stringContaining('TechDocs metadata fetch'),
),
);
});
});
});
@@ -201,13 +201,13 @@ export class AzureBlobStoragePublish implements PublisherBase {
return;
}
body
.on('data', chunk => {
fileStreamChunks.push(chunk);
})
.on('error', e => {
this.logger.error(e.message);
reject(e.message);
})
.on('data', chunk => {
fileStreamChunks.push(chunk);
})
.on('end', () => {
resolve(Buffer.concat(fileStreamChunks));
});
@@ -220,16 +220,28 @@ export class AzureBlobStoragePublish implements PublisherBase {
): Promise<TechDocsMetadata> {
const entityRootDir = `${entityName.namespace}/${entityName.kind}/${entityName.name}`;
try {
return await new Promise<TechDocsMetadata>(resolve => {
const download = this.download(
this.containerName,
`${entityRootDir}/techdocs_metadata.json`,
);
resolve(JSON5.parse(download.toString()));
return await new Promise<TechDocsMetadata>(async (resolve, reject) => {
try {
const techdocsMetadataJson = await this.download(
this.containerName,
`${entityRootDir}/techdocs_metadata.json`,
);
if (!techdocsMetadataJson) {
throw new Error(
`Unable to parse the techdocs metadata file ${entityRootDir}/techdocs_metadata.json.`,
);
}
const techdocsMetadata = JSON5.parse(
techdocsMetadataJson.toString('utf-8'),
);
resolve(techdocsMetadata);
} catch (err) {
this.logger.error(err.message);
reject(new Error(err.message));
}
});
} catch (e) {
this.logger.error(e.message);
throw e;
throw new Error(`TechDocs metadata fetch failed, ${e.message}`);
}
}