@ondc/automation-mock-runner 1.3.41 → 1.3.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -81,5 +81,6 @@ export declare class MockRunner {
81
81
  static runGetSave(payload: any, expression: string): Promise<ExecutionResult>;
82
82
  static encodeBase64(input: string): string;
83
83
  static decodeBase64(encoded: string): string;
84
+ private static resolveBaseActionId;
84
85
  private static getIdFromSession;
85
86
  }
@@ -59,16 +59,17 @@ class MockRunner {
59
59
  const executionId = this.logger.createExecutionContext(actionId);
60
60
  const startTime = Date.now();
61
61
  try {
62
+ const baseActionId = MockRunner.resolveBaseActionId(actionId);
62
63
  this.logger.logExecution(executionId, "Starting payload generation", {
63
64
  actionId,
64
65
  inputKeys: Object.keys(inputs),
65
66
  });
66
- const step = this.config.steps.find((s) => s.action_id === actionId);
67
+ const step = this.config.steps.find((s) => s.action_id === baseActionId);
67
68
  if (!step) {
68
69
  const availableActions = this.config.steps.map((s) => s.action_id);
69
70
  throw new errors_1.ActionNotFoundError(actionId, availableActions);
70
71
  }
71
- const index = this.config.steps.findIndex((s) => s.action_id === actionId);
72
+ const index = this.config.steps.findIndex((s) => s.action_id === baseActionId);
72
73
  // Deep clone to avoid mutations
73
74
  const defaultPayload = JSON.parse(JSON.stringify(step.mock.defaultPayload));
74
75
  const sessionData = await this.getSessionDataUpToStep(index);
@@ -132,16 +133,17 @@ class MockRunner {
132
133
  const executionId = this.logger.createExecutionContext(actionId);
133
134
  const startTime = Date.now();
134
135
  try {
136
+ const baseActionId = MockRunner.resolveBaseActionId(actionId);
135
137
  this.logger.logExecution(executionId, "Starting payload generation with session data", {
136
138
  actionId,
137
139
  sessionKeys: Object.keys(sessionData),
138
140
  });
139
- const step = this.config.steps.find((s) => s.action_id === actionId);
141
+ const step = this.config.steps.find((s) => s.action_id === baseActionId);
140
142
  if (!step) {
141
143
  const availableActions = this.config.steps.map((s) => s.action_id);
142
144
  throw new errors_1.ActionNotFoundError(actionId, availableActions);
143
145
  }
144
- const index = this.config.steps.findIndex((s) => s.action_id === actionId);
146
+ const index = this.config.steps.findIndex((s) => s.action_id === baseActionId);
145
147
  // Deep clone to avoid mutations
146
148
  const defaultPayload = JSON.parse(JSON.stringify(step.mock.defaultPayload));
147
149
  const context = this.generateContext(step.action_id, step.api, sessionData);
@@ -191,11 +193,12 @@ class MockRunner {
191
193
  }
192
194
  async runValidatePayload(actionId, targetPayload) {
193
195
  try {
194
- const step = this.config.steps.find((s) => s.action_id === actionId);
196
+ const baseActionId = MockRunner.resolveBaseActionId(actionId);
197
+ const step = this.config.steps.find((s) => s.action_id === baseActionId);
195
198
  if (!step) {
196
199
  throw new Error(`Action step with ID ${actionId} not found.`);
197
200
  }
198
- const index = this.config.steps.findIndex((s) => s.action_id === actionId);
201
+ const index = this.config.steps.findIndex((s) => s.action_id === baseActionId);
199
202
  const schema = (0, function_registry_1.getFunctionSchema)("validate");
200
203
  const sessionData = await this.getSessionDataUpToStep(index);
201
204
  const result = await this.getRunnerInstance().execute(MockRunner.decodeBase64(step.mock.validate), schema, [targetPayload, sessionData]);
@@ -217,7 +220,8 @@ class MockRunner {
217
220
  }
218
221
  async runValidatePayloadWithSession(actionId, targetPayload, sessionData) {
219
222
  try {
220
- const step = this.config.steps.find((s) => s.action_id === actionId);
223
+ const baseActionId = MockRunner.resolveBaseActionId(actionId);
224
+ const step = this.config.steps.find((s) => s.action_id === baseActionId);
221
225
  if (!step) {
222
226
  throw new Error(`Action step with ID ${actionId} not found.`);
223
227
  }
@@ -241,11 +245,12 @@ class MockRunner {
241
245
  }
242
246
  async runMeetRequirements(actionId) {
243
247
  try {
244
- const step = this.config.steps.find((s) => s.action_id === actionId);
248
+ const baseActionId = MockRunner.resolveBaseActionId(actionId);
249
+ const step = this.config.steps.find((s) => s.action_id === baseActionId);
245
250
  if (!step) {
246
251
  throw new Error(`Action step with ID ${actionId} not found.`);
247
252
  }
248
- const index = this.config.steps.findIndex((s) => s.action_id === actionId);
253
+ const index = this.config.steps.findIndex((s) => s.action_id === baseActionId);
249
254
  const schema = (0, function_registry_1.getFunctionSchema)("meetsRequirements");
250
255
  const sessionData = await this.getSessionDataUpToStep(index);
251
256
  const result = await this.getRunnerInstance().execute(MockRunner.decodeBase64(step.mock.requirements), schema, [sessionData]);
@@ -267,7 +272,8 @@ class MockRunner {
267
272
  }
268
273
  async runMeetRequirementsWithSession(actionId, sessionData) {
269
274
  try {
270
- const step = this.config.steps.find((s) => s.action_id === actionId);
275
+ const baseActionId = MockRunner.resolveBaseActionId(actionId);
276
+ const step = this.config.steps.find((s) => s.action_id === baseActionId);
271
277
  if (!step) {
272
278
  throw new Error(`Action step with ID ${actionId} not found.`);
273
279
  }
@@ -290,6 +296,7 @@ class MockRunner {
290
296
  }
291
297
  }
292
298
  getDefaultStep(api, actionId, formType) {
299
+ const baseActionId = MockRunner.resolveBaseActionId(actionId);
293
300
  if (formType === "dynamic_form" || formType === "html_form") {
294
301
  return {
295
302
  api: api,
@@ -386,7 +393,10 @@ class MockRunner {
386
393
  }
387
394
  generateContext(actionId, action, sessionData) {
388
395
  // Find the step configuration for this action
389
- const step = this.config.steps.find((s) => s.action_id === actionId);
396
+ // GENERATED#1#on_search_full_page_gcr
397
+ // get the last by splitting on # and taking the last part
398
+ const baseActionId = MockRunner.resolveBaseActionId(actionId);
399
+ const step = this.config.steps.find((s) => s.action_id === baseActionId);
390
400
  // Determine the message_id based on responseFor logic
391
401
  let messageId = (0, uuid_1.v4)();
392
402
  if (step?.responseFor) {
@@ -587,6 +597,9 @@ class MockRunner {
587
597
  const bytes = new Uint8Array([...binaryString].map((char) => char.charCodeAt(0)));
588
598
  return new TextDecoder().decode(bytes);
589
599
  }
600
+ static resolveBaseActionId(actionId) {
601
+ return actionId.split("#").slice(-1)[0];
602
+ }
590
603
  static getIdFromSession(sessionData, key) {
591
604
  if (sessionData === undefined) {
592
605
  return undefined;
@@ -101,7 +101,13 @@ function convertToFlowConfig(config) {
101
101
  const pair = config.steps.find((s) => s.responseFor === step.action_id)?.action_id ||
102
102
  null;
103
103
  let flowStep = {};
104
- const isFormStep = ["HTML_FORM", "DYNAMIC_FORM", "HTML_FORM_MULTI"];
104
+ const isFormStep = [
105
+ "HTML_FORM",
106
+ "DYNAMIC_FORM",
107
+ "HTML_FORM_MULTI",
108
+ "dynamic_form",
109
+ "html_form",
110
+ ];
105
111
  // Check if previous step was a form step
106
112
  const previousStep = index > 0 ? config.steps[index - 1] : null;
107
113
  const isPreviousStepForm = previousStep !== null && isFormStep.includes(previousStep.api);
@@ -130,7 +136,7 @@ function convertToFlowConfig(config) {
130
136
  ],
131
137
  };
132
138
  }
133
- else if (step.api === "HTML_FORM") {
139
+ else if (step.api === "HTML_FORM" || step.api === "html_form") {
134
140
  flowStep = {
135
141
  key: step.action_id,
136
142
  type: "HTML_FORM",
@@ -655,4 +655,68 @@ describe("MockRunner", () => {
655
655
  expect(result.result.message.discountPercent).toBe(20);
656
656
  });
657
657
  });
658
+ describe("baseActionId extraction (GENERATED# prefix support)", () => {
659
+ let prefixedRunner;
660
+ beforeEach(async () => {
661
+ const baseConfig = {
662
+ meta: {
663
+ domain: "ONDC:TRV14",
664
+ version: "2.0.0",
665
+ flowId: "prefix-test",
666
+ },
667
+ transaction_data: {
668
+ transaction_id: "prefix-test-txn-id",
669
+ latest_timestamp: "1970-01-01T00:00:00.000Z",
670
+ },
671
+ steps: [],
672
+ transaction_history: [],
673
+ validationLib: "",
674
+ helperLib: "",
675
+ };
676
+ const base = new MockRunner_1.MockRunner(baseConfig, true);
677
+ base.getConfig().steps.push(base.getDefaultStep("search", "search_0"));
678
+ prefixedRunner = new MockRunner_1.MockRunner(await (0, configHelper_1.createOptimizedMockConfig)(base.getConfig()), true);
679
+ });
680
+ it("runGeneratePayload: GENERATED#1#search_0 resolves to search_0", async () => {
681
+ const result = await prefixedRunner.runGeneratePayload("GENERATED#1#search_0", {});
682
+ expect(result.success).toBe(true);
683
+ });
684
+ it("runGeneratePayload: plain search_0 still works", async () => {
685
+ const result = await prefixedRunner.runGeneratePayload("search_0", {});
686
+ expect(result.success).toBe(true);
687
+ });
688
+ it("runGeneratePayloadWithSession: GENERATED#1#search_0 resolves to search_0", async () => {
689
+ const result = await prefixedRunner.runGeneratePayloadWithSession("GENERATED#1#search_0", { transaction_id: "some-txn" });
690
+ expect(result.success).toBe(true);
691
+ });
692
+ it("runValidatePayload: GENERATED#1#search_0 resolves to search_0", async () => {
693
+ const payload = {
694
+ context: { domain: "ONDC:TRV14", action: "search" },
695
+ message: {},
696
+ };
697
+ const result = await prefixedRunner.runValidatePayload("GENERATED#1#search_0", payload);
698
+ expect(result.success).toBe(true);
699
+ });
700
+ it("runValidatePayloadWithSession: GENERATED#1#search_0 resolves to search_0", async () => {
701
+ const result = await prefixedRunner.runValidatePayloadWithSession("GENERATED#1#search_0", { context: {}, message: {} }, {});
702
+ expect(result.success).toBe(true);
703
+ });
704
+ it("runMeetRequirements: GENERATED#1#search_0 resolves to search_0", async () => {
705
+ const result = await prefixedRunner.runMeetRequirements("GENERATED#1#search_0");
706
+ expect(result.success).toBe(true);
707
+ });
708
+ it("runMeetRequirementsWithSession: GENERATED#1#search_0 resolves to search_0", async () => {
709
+ const result = await prefixedRunner.runMeetRequirementsWithSession("GENERATED#1#search_0", {});
710
+ expect(result.success).toBe(true);
711
+ });
712
+ it("unknown prefixed action ID returns failure", async () => {
713
+ const result = await prefixedRunner.runGeneratePayload("GENERATED#1#unknown_action", {});
714
+ expect(result.success).toBe(false);
715
+ expect(result.error?.message).toContain("unknown_action");
716
+ });
717
+ it("deeply prefixed ID (multiple #) uses only the last segment", async () => {
718
+ const result = await prefixedRunner.runGeneratePayload("PREFIX#ANOTHER#search_0", {});
719
+ expect(result.success).toBe(true);
720
+ });
721
+ });
658
722
  });