UNPKG

6.46 kBPlain TextView Raw
1/*
2 * Copyright © 2019 Atomist, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17import {
18 guid,
19 HandlerContext,
20 Maker,
21 MessageClient,
22 Project,
23 ProjectOperationCredentials,
24 RepoId,
25} from "@atomist/automation-client";
26import { successOn } from "@atomist/automation-client/lib/action/ActionResult";
27import { HandleCommand } from "@atomist/automation-client/lib/HandleCommand";
28import { HandleEvent } from "@atomist/automation-client/lib/HandleEvent";
29import { BuildableAutomationServer } from "@atomist/automation-client/lib/server/BuildableAutomationServer";
30import {
31 AbstractSoftwareDeliveryMachine,
32 GeneratorRegistration,
33 generatorRegistrationToCommand,
34 SoftwareDeliveryMachineConfiguration,
35} from "@atomist/sdm";
36import * as assert from "assert";
37import * as flatten from "flat";
38import * as _ from "lodash";
39import { defaultSoftwareDeliveryMachineConfiguration } from "../../../machine/defaultSoftwareDeliveryMachineConfiguration";
40import { toArray } from "../../../util/misc/array";
41import { invokeCommand } from "../../job/invokeCommand";
42import { universalGenerator } from "../generator";
43import { UniversalTransform } from "../generatorSupport";
44
45export interface AssertGeneratorResult {
46 id: RepoId;
47 project: Project;
48 parameters: Record<string, any>;
49}
50
51export async function assertUniversalGenerator(generatorUnderTest: GeneratorRegistration<any>,
52 transformsUnderTest: UniversalTransform<any> | Array<UniversalTransform<any>>,
53 initialParams: Record<string, any>,
54 promptForParams: Record<string, any> = {}): Promise<AssertGeneratorResult> {
55 try {
56 // Prepare the result of generator run
57 let project: Project;
58 let id: RepoId;
59 let params: Record<string, any>;
60
61 // Set up configuration and overwrite the projectPersister to capture the result of the generator
62 const configuration: SoftwareDeliveryMachineConfiguration = _.merge({},
63 {
64 ...defaultSoftwareDeliveryMachineConfiguration({}),
65 name: "test",
66 },
67 {
68 sdm: {
69 projectPersister: async (p: Project,
70 credentials: ProjectOperationCredentials,
71 targetId: RepoId,
72 parameters?: object) => {
73 project = p;
74 id = targetId;
75 params = parameters;
76 return successOn<Project>(p);
77 },
78 },
79 });
80
81 const automationServer = new BuildableAutomationServer({});
82 const sdm = new TestSoftwareDeliveryMachine("test", configuration);
83
84 (global as any).__runningAutomationClient = {
85 configuration,
86 automationServer,
87 };
88
89 // Create the generator instance and register it with the underlying automation client
90 const generator = universalGenerator(sdm, generatorUnderTest, toArray(transformsUnderTest));
91 automationServer.registerCommandHandler(generatorRegistrationToCommand(sdm, generator));
92
93 let parameterSpecs: any[] = [];
94 const messageClient: MessageClient = {
95 respond: async msg => {
96 if (!!msg.parameter_specs) {
97 parameterSpecs = msg.parameter_specs;
98 }
99 },
100 send: async () => {
101 },
102 delete: async () => {
103 },
104 };
105
106 // Invoke the generator with the initial set of parameters
107 let result = await invokeCommand(generatorUnderTest, initialParams, mockHandlerContext(messageClient, initialParams));
108 assert.deepStrictEqual(result.code, 0, `Generator failed during initial execution: ${result.message}`);
109 assert.deepStrictEqual(parameterSpecs.map(p => p.name).sort(), _.keys(promptForParams).sort());
110
111 if (!!project) {
112 return {
113 id,
114 project,
115 parameters: params,
116 };
117 }
118
119 // Now invoke generator with additional parameters needed by the matched transformsAndParameters
120 const allParameters = { ...initialParams, ...promptForParams };
121 result = await invokeCommand(
122 generatorUnderTest,
123 allParameters,
124 mockHandlerContext(messageClient, allParameters));
125 assert.deepStrictEqual(result.code, 0, `Generator failed during parameter prompt execution: ${result.message}`);
126 assert(!!project, "Generated project is undefined");
127
128 return {
129 id,
130 project,
131 parameters: params,
132 };
133 } finally {
134 delete (global as any).__runningAutomationClient;
135 }
136}
137
138function mockHandlerContext(messageClient: MessageClient, params: any): HandlerContext {
139 return {
140 messageClient,
141 trigger: {
142 parameters: flattenParameters(params),
143 },
144 invocationId: guid(),
145 correlationId: guid(),
146 graphClient: undefined,
147 workspaceId: `A${guid().slice(0, 7).toUpperCase()}`,
148 } as any;
149}
150
151function flattenParameters(params: any): any {
152 const parameters: any[] = [];
153 _.forEach(flatten(params), (v, k) => {
154 parameters.push({ name: k, value: v });
155 });
156 return parameters;
157}
158
159class TestSoftwareDeliveryMachine extends AbstractSoftwareDeliveryMachine {
160
161 public readonly commandHandlers: Array<Maker<HandleCommand>> = [];
162 public readonly eventHandlers: Array<Maker<HandleEvent<any>>> = [];
163 public readonly ingesters: string[] = [];
164
165 constructor(name: string, configuration: SoftwareDeliveryMachineConfiguration) {
166 super(name, configuration, []);
167 }
168}