Merge pull request #1317 from cptran777/ui-health-typings

Ui health typings and api handler
This commit is contained in:
Charlie Tran 2018-08-13 13:13:30 -07:00 committed by GitHub
commit 479f575383
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 125 additions and 7 deletions

View File

@ -3,8 +3,9 @@ import { get, computed, setProperties, getProperties } from '@ember/object';
import { task } from 'ember-concurrency';
import ComputedProperty from '@ember/object/computed';
import { IChartDatum } from 'wherehows-web/typings/app/visualization/charts';
import { IHealthScore } from 'wherehows-web/typings/api/datasets/health';
import { IHealthScore, IDatasetHealth } from 'wherehows-web/typings/api/datasets/health';
import { healthCategories, healthSeverity, healthDetail } from 'wherehows-web/constants/data/temp-mock/health';
import { readDatasetHealthByUrn } from 'wherehows-web/utils/api/datasets/health';
/**
* Used for the dataset health tab, represents the fieldnames for the health score table
@ -124,7 +125,8 @@ export default class DatasetHealthContainer extends Component {
* An async parent task to group all data tasks for this container component
* @type {Task<TaskInstance<Promise<any>>, (a?: any) => TaskInstance<TaskInstance<Promise<any>>>>}
*/
getContainerDataTask = task(function*(this: DatasetHealthContainer): IterableIterator<void> {
getContainerDataTask = task(function*(this: DatasetHealthContainer): IterableIterator<Promise<IDatasetHealth>> {
const { health } = yield readDatasetHealthByUrn(get(this, 'urn'));
// Pretend like we're getting data from somehwere
const healthData = {
categories: healthCategories,
@ -137,6 +139,8 @@ export default class DatasetHealthContainer extends Component {
severityMetrics: healthData.severity,
tableData: healthData.detail
});
return health; // Do something with health information
});
/**

View File

@ -1,3 +1,32 @@
/**
* This object is a raw response object for a health score detail from the api layer that will
* be used mainly in our metadata health score table
*/
export interface IHealthScoreObject {
tier: string | null;
// score will be a float between 0 and 1 representing a percentage
score: number;
description: string;
weight: number;
validator: string;
}
/**
* This is the abstracted response from the api request to datasets/:urn/health
*/
export interface IDatasetHealth {
// score will be a float between 0 and 1 representing a percetnage
score: number;
validations: Array<IHealthScoreObject>;
}
/**
* This is the raw response from the api layer for a request to datasets/:urn/health
*/
export interface IHealthScoreResponse {
health: IDatasetHealth;
}
/**
* Primarily used in the dataset health tab, represents an individual health score entry for the table
*/

View File

@ -22,7 +22,7 @@ export interface IMirageServer {
loadFixtures: (...files: Array<string>) => void;
loadFactories: (factoryMap: object) => void;
create: (type: string, options?: object) => object;
createList: <T>(type: string, amount: number, traitsAndOverrides?: object) => Array<T>;
createList: <T>(type: string, amount: number, traitsAndOverrides?: object | string) => Array<T>;
shutdown: (this: IMirageServer) => void;
}

View File

@ -0,0 +1,22 @@
import { datasetUrlByUrn } from 'wherehows-web/utils/api/datasets/shared';
import { getJSON } from 'wherehows-web/utils/api/fetcher';
import { IHealthScoreResponse, IDatasetHealth } from 'wherehows-web/typings/api/datasets/health';
/**
* Returns the url for dataset metadata health by urn
* @param urn
* @return {string}
*/
const datasetHealthUrlByUrn = (urn: string): string => `${datasetUrlByUrn(urn)}/health`;
export const readDatasetHealthByUrn = async (urn: string): Promise<IDatasetHealth> => {
const defaultResponse = { score: 0, validations: [] };
try {
const { health } = await getJSON<IHealthScoreResponse>({ url: datasetHealthUrlByUrn(urn) });
return health;
} catch {
return defaultResponse;
}
};

View File

@ -25,6 +25,7 @@ import { aclAuth } from 'wherehows-web/mirage/helpers/aclauth';
import { getDatasetUpstreams } from 'wherehows-web/mirage/helpers/dataset-upstreams';
import { getDatasetRetention } from 'wherehows-web/mirage/helpers/dataset-retentions';
import { getDatasetFabrics } from 'wherehows-web/mirage/helpers/dataset-fabrics';
import { getDatasetHealth } from 'wherehows-web/mirage/helpers/dataset-health';
export default function(this: IMirageServer) {
this.get('/config', getConfig);
@ -41,7 +42,7 @@ export default function(this: IMirageServer) {
this.get('/datasets/:dataset_id/schema', getDatasetSchema);
this.get('/datasets/:dataset_id/compliance/suggestions', getDatasetComplianceSuggestion);
this.get('/datasets/:dataset_id/compliance/suggestion', getDatasetComplianceSuggestion);
this.get('/datasets/:dataset_id/owners', getDatasetOwners);
@ -57,6 +58,8 @@ export default function(this: IMirageServer) {
this.get('/datasets/:dataset_id/fabrics', getDatasetFabrics);
this.get('/datasets/:dataset_id/health', getDatasetHealth);
this.namespace = '/api/v1';
this.get('/datasets/:dataset_id', getDataset);

View File

@ -0,0 +1,48 @@
import { Factory, faker, trait } from 'ember-cli-mirage';
import { IHealthScoreObject } from 'wherehows-web/typings/api/datasets/health';
const tierOptions = ['CRITICAL', 'WARNING', 'MINOR'];
export default Factory.extend({
id(id: number) {
return id;
},
score: faker.random.number({ min: 0, max: 100 }),
validations() {
const numValidations = faker.random.number({ min: 1, max: 6 });
const validations: Array<IHealthScoreObject> = [];
for (let i = 0; i < numValidations; i++) {
const validation: IHealthScoreObject = {
tier: tierOptions[i % 3],
score: faker.random.number({ min: 0, max: 100 }) / 100,
description: faker.lorem.sentences(),
weight: faker.random.number({ min: 0, max: 100 }) / 100,
validator: 'fake'
};
validations.push(validation);
}
return validations;
},
forTesting: trait({
score: 83,
validations() {
const validations: Array<IHealthScoreObject> = [];
for (let i = 0; i < 3; i++) {
const validation: IHealthScoreObject = {
tier: tierOptions[i],
score: 1 - (3 - i) * 0.25,
description: faker.lorem.sentences(2),
weight: faker.random.number({ min: 0, max: 100 }) / 100,
validator: 'fake'
};
validations.push(validation);
}
}
})
});

View File

@ -0,0 +1,7 @@
import { IFunctionRouteHandler } from 'wherehows-web/typings/ember-cli-mirage';
export const getDatasetHealth = function(this: IFunctionRouteHandler, { db: healths }: any) {
return {
health: this.serialize(healths[0])
};
};

View File

@ -27,4 +27,5 @@ export default function(server: IMirageServer) {
server.createList('suggestion', 2);
server.createList('platform', 2);
server.createList('version', 2);
server.createList('health', 1);
}

View File

@ -1,13 +1,17 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import { urn } from 'wherehows-web/mirage/fixtures/urn';
import { render, find } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
module('Integration | Component | datasets/containers/dataset-health', function(hooks) {
setupRenderingTest(hooks);
// TODO: More meaningful tests as we continue with development
test('it renders', async function(assert) {
await render(hbs`{{datasets/containers/dataset-health}}`);
this.set('urn', urn);
await render(hbs`{{datasets/containers/dataset-health urn=urn}}`);
assert.ok(this.element, 'Renders without errors');
assert.ok(find('.dataset-health__score-table'), 'renders the health table component');
});
});