// (C) 2019 GoodData Corporation import { ExecuteAFM as AFM } from "@gooddata/typings"; import * as HttpStatusCodes from "http-status-codes"; import * as request from "supertest"; import { buildProject } from "../../../schema/builder"; import { schema } from "../../../schema/fixtures/dummySchema"; import { createEndpoint } from "../../../utils/tests"; import { executeVisualization, getAfmExecutionForVisualization, IVisualizationExecution, } from "../executeVisualization"; /* * Note: some of the vis objects in the dummy schema are garbage; they are not correctly defined in the dummy schema * which makes the builder to produce non-sensical visualization objects with measures referencing undefined metrics * and so on. The conversion of this to AFM is purely syntactical and thus, in garbage-in => garbage-out fashion, it produces * AFMs that reference non-existent measures or display forms resulting in AFM execution to bomb. */ describe("executeVisualization", () => { it("should return polling URI with default number of dimensions when resultSpec is not defined", async () => { const app = createEndpoint(executeVisualization, schema); const visualizationExecution: IVisualizationExecution = { visualizationExecution: { reference: "/gdc/md/mockproject/obj/my_sorted_table", }, }; const response = await request(app) .post("/gdc/app/projects/mockproject/executeVisualization") .send(visualizationExecution) .expect(HttpStatusCodes.CREATED); expect(response.body).toMatchSnapshot(); }); it("should return 400 for undefined visualization object", async () => { const app = createEndpoint(executeVisualization, schema); const visualizationExecution: IVisualizationExecution = { visualizationExecution: { reference: "/gdc/md/mockproject/obj/this does not exist", }, }; await request(app) .post("/gdc/app/projects/mockproject/executeVisualization") .send(visualizationExecution) .expect(HttpStatusCodes.BAD_REQUEST); }); }); describe("getAfmExecutionForVisualization", () => { const project = buildProject(schema); it("should return undefined if vis object does not exist", () => { const result = getAfmExecutionForVisualization(project, { visualizationExecution: { reference: "does not exist", }, }); expect(result).toBeUndefined(); }); it("should convert simple vis object to AFM", () => { const result = getAfmExecutionForVisualization(project, { visualizationExecution: { reference: "/gdc/md/mockproject/obj/my_sorted_table", }, }); expect(result).toEqual({ execution: { afm: { attributes: [ { displayForm: { uri: "/gdc/md/mockproject/obj/attr.employee.df", }, localIdentifier: "attr.employee", }, ], measures: [ { localIdentifier: "simple_metric", definition: { measure: { item: { uri: "/gdc/md/mockproject/obj/simple_metric", }, }, }, }, ], }, }, }); }); it("should not auto-fill resultSpec", () => { const result = getAfmExecutionForVisualization(project, { visualizationExecution: { reference: "/gdc/md/mockproject/obj/my_sorted_table", }, }); expect(result.execution.resultSpec).toBeUndefined(); }); it("should propagate resultSpec provided in request", () => { const resultSpec: AFM.IResultSpec = { sorts: [{ attributeSortItem: { attributeIdentifier: "attr.employee", direction: "asc" } }], }; const result = getAfmExecutionForVisualization(project, { visualizationExecution: { reference: "/gdc/md/mockproject/obj/my_sorted_table", resultSpec, }, }); expect(result.execution.resultSpec).toEqual(resultSpec); }); /* * NOTE: there are no extensive tests for filter merging here; that logic is unit-tested elsewhere */ it("should merge filters provided in request", () => { const filters: AFM.CompatibilityFilter[] = [ { positiveAttributeFilter: { displayForm: { identifier: "attr.employee.df" }, in: { values: ["One", "Two"] }, }, }, { measureValueFilter: { measure: { localIdentifier: "m2", }, condition: { comparison: { operator: "GREATER_THAN", value: 420, }, }, }, }, ]; const result = getAfmExecutionForVisualization(project, { visualizationExecution: { reference: "/gdc/md/mockproject/obj/my_sorted_table", filters, }, }); expect(result.execution.afm.filters).toEqual(filters); }); });