@autobe/agent 0.8.0 → 0.9.0
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.
- package/lib/AutoBeAgent.d.ts +183 -12
- package/lib/AutoBeAgent.js +245 -65
- package/lib/AutoBeAgent.js.map +1 -1
- package/lib/constants/AutoBeSystemPromptConstant.d.ts +4 -3
- package/lib/constants/AutoBeSystemPromptConstant.js.map +1 -1
- package/lib/context/AutoBeContext.d.ts +2 -2
- package/lib/factory/index.d.ts +0 -1
- package/lib/factory/index.js +0 -1
- package/lib/factory/index.js.map +1 -1
- package/lib/index.mjs +976 -633
- package/lib/index.mjs.map +1 -1
- package/lib/orchestrate/analyze/AutoBeAnalyzeAgent.js +1 -1
- package/lib/orchestrate/analyze/AutoBeAnalyzeAgent.js.map +1 -1
- package/lib/orchestrate/interface/orchestrateInterface.js +1 -1
- package/lib/orchestrate/interface/orchestrateInterface.js.map +1 -1
- package/lib/orchestrate/prisma/orchestratePrisma.js +1 -1
- package/lib/orchestrate/prisma/orchestratePrisma.js.map +1 -1
- package/lib/orchestrate/prisma/orchestratePrismaCorrect.js +1 -1
- package/lib/orchestrate/prisma/orchestratePrismaCorrect.js.map +1 -1
- package/lib/orchestrate/test/orchestrateTest.js +4 -8
- package/lib/orchestrate/test/orchestrateTest.js.map +1 -1
- package/lib/orchestrate/test/orchestrateTestCorrect.d.ts +2 -2
- package/lib/orchestrate/test/orchestrateTestCorrect.js +89 -57
- package/lib/orchestrate/test/orchestrateTestCorrect.js.map +1 -1
- package/lib/orchestrate/test/orchestrateTestProgress.d.ts +3 -2
- package/lib/orchestrate/test/orchestrateTestProgress.js +73 -46
- package/lib/orchestrate/test/orchestrateTestProgress.js.map +1 -1
- package/lib/orchestrate/test/orchestrateTestScenario.d.ts +2 -2
- package/lib/orchestrate/test/orchestrateTestScenario.js +616 -237
- package/lib/orchestrate/test/orchestrateTestScenario.js.map +1 -1
- package/lib/orchestrate/test/structures/IAutoBeTestScenarioApplication.d.ts +123 -0
- package/lib/orchestrate/test/structures/IAutoBeTestScenarioApplication.js +3 -0
- package/lib/orchestrate/test/structures/IAutoBeTestScenarioApplication.js.map +1 -0
- package/lib/orchestrate/test/transformTestCorrectHistories.d.ts +2 -1
- package/lib/orchestrate/test/transformTestCorrectHistories.js +14 -10
- package/lib/orchestrate/test/transformTestCorrectHistories.js.map +1 -1
- package/lib/orchestrate/test/transformTestProgressHistories.d.ts +7 -1
- package/lib/orchestrate/test/transformTestProgressHistories.js +20 -20
- package/lib/orchestrate/test/transformTestProgressHistories.js.map +1 -1
- package/lib/orchestrate/test/transformTestScenarioHistories.d.ts +1 -2
- package/lib/orchestrate/test/transformTestScenarioHistories.js +1 -77
- package/lib/orchestrate/test/transformTestScenarioHistories.js.map +1 -1
- package/lib/structures/IAutoBeConfig.d.ts +48 -10
- package/lib/structures/IAutoBeProps.d.ts +87 -0
- package/lib/structures/IAutoBeVendor.d.ts +64 -22
- package/lib/utils/backoffRetry.d.ts +7 -0
- package/lib/utils/backoffRetry.js +73 -0
- package/lib/utils/backoffRetry.js.map +1 -0
- package/lib/utils/types/BackoffOptions.d.ts +12 -0
- package/lib/utils/types/BackoffOptions.js +3 -0
- package/lib/utils/types/BackoffOptions.js.map +1 -0
- package/package.json +4 -4
- package/src/AutoBeAgent.ts +248 -52
- package/src/constants/AutoBeSystemPromptConstant.ts +4 -3
- package/src/context/AutoBeContext.ts +7 -2
- package/src/factory/index.ts +0 -1
- package/src/orchestrate/analyze/AutoBeAnalyzeAgent.ts +1 -1
- package/src/orchestrate/interface/orchestrateInterface.ts +1 -1
- package/src/orchestrate/prisma/orchestratePrisma.ts +1 -0
- package/src/orchestrate/prisma/orchestratePrismaCorrect.ts +4 -2
- package/src/orchestrate/test/orchestrateTest.ts +6 -13
- package/src/orchestrate/test/orchestrateTestCorrect.ts +125 -72
- package/src/orchestrate/test/orchestrateTestProgress.ts +86 -42
- package/src/orchestrate/test/orchestrateTestScenario.ts +192 -151
- package/src/orchestrate/test/structures/IAutoBeTestScenarioApplication.ts +132 -0
- package/src/orchestrate/test/transformTestCorrectHistories.ts +14 -10
- package/src/orchestrate/test/transformTestProgressHistories.ts +25 -22
- package/src/orchestrate/test/transformTestScenarioHistories.ts +0 -79
- package/src/structures/IAutoBeConfig.ts +48 -10
- package/src/structures/IAutoBeProps.ts +91 -0
- package/src/structures/IAutoBeVendor.ts +64 -22
- package/src/utils/backoffRetry.ts +84 -0
- package/src/utils/types/BackoffOptions.ts +15 -0
|
@@ -48,136 +48,282 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
48
48
|
exports.orchestrateTestScenario = orchestrateTestScenario;
|
|
49
49
|
const __typia_transform__validateReport = __importStar(require("typia/lib/internal/_validateReport.js"));
|
|
50
50
|
const core_1 = require("@agentica/core");
|
|
51
|
-
const tstl_1 = require("tstl");
|
|
52
51
|
const typia_1 = __importDefault(require("typia"));
|
|
52
|
+
const uuid_1 = require("uuid");
|
|
53
53
|
const assertSchemaModel_1 = require("../../context/assertSchemaModel");
|
|
54
54
|
const divideArray_1 = require("../../utils/divideArray");
|
|
55
55
|
const enforceToolCall_1 = require("../../utils/enforceToolCall");
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
method
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
parameters: it.parameters,
|
|
76
|
-
requestBody: it.requestBody,
|
|
77
|
-
responseBody: it.responseBody,
|
|
78
|
-
};
|
|
79
|
-
});
|
|
80
|
-
const matrix = (0, divideArray_1.divideArray)({
|
|
81
|
-
array: endpoints,
|
|
82
|
-
capacity,
|
|
83
|
-
});
|
|
84
|
-
const start = new Date();
|
|
85
|
-
let completed = 0;
|
|
86
|
-
const scenarios = yield Promise.all(matrix.map((e) => __awaiter(this, void 0, void 0, function* () {
|
|
87
|
-
var _a, _b;
|
|
88
|
-
const rows = yield divideAndConquer(ctx, e, endpoints, files, 3, (count) => {
|
|
89
|
-
completed += count;
|
|
90
|
-
});
|
|
91
|
-
ctx.dispatch({
|
|
92
|
-
type: "testScenario",
|
|
93
|
-
scenarios: rows,
|
|
94
|
-
total: rows.flatMap((el) => el.scenarios).length,
|
|
95
|
-
step: (_b = (_a = ctx.state().test) === null || _a === void 0 ? void 0 : _a.step) !== null && _b !== void 0 ? _b : 0,
|
|
96
|
-
completed,
|
|
97
|
-
created_at: start.toISOString(),
|
|
56
|
+
function orchestrateTestScenario(ctx) {
|
|
57
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
58
|
+
var _a, _b, _c, _d;
|
|
59
|
+
const operations = (_b = (_a = ctx.state().interface) === null || _a === void 0 ? void 0 : _a.document.operations) !== null && _b !== void 0 ? _b : [];
|
|
60
|
+
if (operations.length === 0) {
|
|
61
|
+
throw new Error("Cannot write test scenarios because these are no operations.");
|
|
62
|
+
}
|
|
63
|
+
const exclude = [];
|
|
64
|
+
let include = Array.from(operations);
|
|
65
|
+
do {
|
|
66
|
+
const matrix = (0, divideArray_1.divideArray)({ array: include, capacity: 30 });
|
|
67
|
+
yield Promise.all(matrix.map((_include) => __awaiter(this, void 0, void 0, function* () {
|
|
68
|
+
exclude.push(...(yield execute(ctx, operations, _include, exclude.map((x) => x.endpoint))));
|
|
69
|
+
})));
|
|
70
|
+
include = include.filter((op) => {
|
|
71
|
+
if (exclude.some((pg) => pg.endpoint.method === op.method && pg.endpoint.path === op.path)) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
return true;
|
|
98
75
|
});
|
|
99
|
-
|
|
100
|
-
})));
|
|
76
|
+
} while (include.length > 0);
|
|
101
77
|
return {
|
|
102
78
|
type: "testScenario",
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
79
|
+
step: (_d = (_c = ctx.state().analyze) === null || _c === void 0 ? void 0 : _c.step) !== null && _d !== void 0 ? _d : 0,
|
|
80
|
+
scenarios: exclude.flatMap((pg) => {
|
|
81
|
+
return pg.scenarios.map((plan) => {
|
|
82
|
+
return {
|
|
83
|
+
endpoint: pg.endpoint,
|
|
84
|
+
draft: plan.draft,
|
|
85
|
+
functionName: plan.functionName,
|
|
86
|
+
dependencies: plan.dependsOn,
|
|
87
|
+
};
|
|
88
|
+
});
|
|
89
|
+
}),
|
|
90
|
+
created_at: new Date().toISOString(),
|
|
108
91
|
};
|
|
109
92
|
});
|
|
110
93
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
94
|
+
const execute = (ctx, ops, include, exclude) => __awaiter(void 0, void 0, void 0, function* () {
|
|
95
|
+
var _a;
|
|
96
|
+
const pointer = {
|
|
97
|
+
value: [],
|
|
98
|
+
};
|
|
99
|
+
const agentica = new core_1.MicroAgentica({
|
|
100
|
+
model: ctx.model,
|
|
101
|
+
vendor: ctx.vendor,
|
|
102
|
+
config: Object.assign(Object.assign({}, ((_a = ctx.config) !== null && _a !== void 0 ? _a : {})), { executor: {
|
|
103
|
+
describe: null,
|
|
104
|
+
} }),
|
|
105
|
+
tokenUsage: ctx.usage(),
|
|
106
|
+
histories: createHistoryProperties(ops, include, exclude),
|
|
107
|
+
controllers: [
|
|
108
|
+
createApplication({
|
|
109
|
+
model: ctx.model,
|
|
110
|
+
build: (next) => {
|
|
111
|
+
var _a;
|
|
112
|
+
(_a = pointer.value) !== null && _a !== void 0 ? _a : (pointer.value = []);
|
|
113
|
+
pointer.value.push(...next.scenarioGroups);
|
|
114
|
+
},
|
|
115
|
+
}),
|
|
116
|
+
],
|
|
131
117
|
});
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
var _a;
|
|
156
|
-
(_a = pointer.value) !== null && _a !== void 0 ? _a : (pointer.value = []);
|
|
157
|
-
pointer.value.push(...next.scenarios);
|
|
158
|
-
},
|
|
159
|
-
}),
|
|
160
|
-
],
|
|
161
|
-
});
|
|
162
|
-
(0, enforceToolCall_1.enforceToolCall)(agentica);
|
|
163
|
-
yield agentica.conversate([
|
|
164
|
-
"Make User Scenarios for below endpoints:",
|
|
118
|
+
(0, enforceToolCall_1.enforceToolCall)(agentica);
|
|
119
|
+
yield agentica.conversate(`create test scenarios.`);
|
|
120
|
+
if (pointer.value.length === 0) {
|
|
121
|
+
throw new Error("Failed to create test plans.");
|
|
122
|
+
}
|
|
123
|
+
return pointer.value;
|
|
124
|
+
});
|
|
125
|
+
const createHistoryProperties = (operations, include, exclude) => [
|
|
126
|
+
{
|
|
127
|
+
id: (0, uuid_1.v4)(),
|
|
128
|
+
created_at: new Date().toISOString(),
|
|
129
|
+
type: "systemMessage",
|
|
130
|
+
text: "You are the AutoAPI Test Scenario Generator.\n\nYour job is to analyze an array of API operation objects and generate realistic, structured test scenario drafts for each operation.\n\n---\n\n## Input Format\n\nYou will receive an array of `Operation` objects structured like this:\n\n```ts\n{\n method: \"post\" | \"get\" | \"put\" | \"patch\" | \"delete\",\n path: \"/path/to/resource\",\n specification: string, // API specification with business logic and constraints\n description: string, // Multi-paragraph description\n summary: string, // One-line summary\n parameters: [...], // List of path/query/body parameters\n requestBody?: {\n typeName: string,\n description: string\n },\n responseBody: {\n typeName: string,\n description: string\n }\n}\n```\n\n---\n\n## Output Format\n\nYour output must be an array of grouped test plans, using the following structure:\n\n```ts\n[\n {\n method: \"post\",\n path: \"/shopping/products\",\n plans: [\n {\n draft: \"Test product creation by submitting two requests with the same product.pid. Confirm that the second request returns a uniqueness constraint error.\",\n dependsOn: [\n {\n method: \"post\",\n path: \"/shopping/categories\",\n purpose: \"Create a category beforehand so the product can reference it.\"\n },\n {\n method: \"get\",\n path: \"/users/me\",\n purpose: \"Verify a valid user session and obtain user context for the test.\"\n }\n ]\n },\n {\n draft: \"Verify that missing required fields like 'name' or 'price' trigger appropriate validation errors.\",\n dependsOn: []\n }\n ]\n },\n {\n method: \"patch\",\n path: \"/shopping/products/{productId}\",\n plans: [\n {\n draft: \"Attempt to update a product with an invalid productId and expect a 404 error.\",\n dependsOn: []\n }\n ]\n }\n]\n```\n\n- Each top-level object is a **plan group** for a single unique endpoint (`method + path`).\n- The `plans` array contains **one or more test drafts** for that endpoint.\n- Each `draft` may list its **prerequisite API calls** in the `dependsOn` array, which includes `method`, `path`, and a `purpose` for context.\n\n---\n\n### \u2705 **Uniqueness Rule**\n\n> \u26A0\uFE0F **Each `{method} + {path}` combination must appear only once** in the output array.\n> This means **you must not create multiple plan groups with the same HTTP method and path.**\n\n* Treat each `{method} + {path}` pair as a **unique test identifier**.\n* All test plans (`plans`) related to the same endpoint must be **grouped under a single PlanGroup object**.\n* Duplicating PlanGroups for the same endpoint will lead to invalid output.\n\n**\u2705 Good:**\n\n```ts\n[\n {\n method: \"patch\",\n path: \"/blog/posts/{postId}\",\n plans: [\n { draft: \"...\", dependsOn: [...] },\n { draft: \"...\", dependsOn: [...] }\n ]\n }\n]\n```\n\n**\u274C Bad:**\n\n```ts\n[\n {\n method: \"patch\",\n path: \"/blog/posts/{postId}\",\n plans: [ ... ]\n },\n {\n method: \"patch\",\n path: \"/blog/posts/{postId}\", // Duplicate! Not allowed.\n plans: [ ... ]\n }\n]\n```\n\n---\n\n## Writing Guidelines\n\n1. **draft**:\n - Write a clear and realistic test plan for the operation.\n - Include both success and failure cases where applicable.\n - Incorporate constraints mentioned in the API description such as uniqueness, foreign key requirements, or authentication.\n - For complex operations, include multiple steps within the same `draft` string (e.g., create \u2192 verify \u2192 delete).\n\n2. **dependsOn**:\n - List other API operations that must be invoked before this test can be executed.\n - Each item must include `method`, `path`, and `purpose`.\n - The `purpose` field should explain *why* the dependency is needed in the test setup.\n\n3. Treat each `{method} + {path}` combination as a unique test identifier.\n\n---\n\n## Purpose\n\nThese test scenario objects are designed to support QA engineers and backend developers in planning automated or manual tests. Each test draft reflects the core functionality and business rules of the API to ensure robust system behavior." /* AutoBeSystemPromptConstant.TEST_SCENARIO */,
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
id: (0, uuid_1.v4)(),
|
|
134
|
+
created_at: new Date().toISOString(),
|
|
135
|
+
type: "systemMessage",
|
|
136
|
+
text: [
|
|
137
|
+
"Below are the full operations. Please refer to this.",
|
|
138
|
+
"Your role is to draft all test cases for each given Operation.",
|
|
139
|
+
"It is also permissible to write multiple test codes on a single endpoint.",
|
|
140
|
+
"However, rather than meaningless tests, business logic tests should be written and an E2E test situation should be assumed.",
|
|
165
141
|
"",
|
|
166
142
|
"```json",
|
|
167
|
-
JSON.stringify(
|
|
143
|
+
JSON.stringify(operations.map((el) => ({
|
|
144
|
+
path: el.path,
|
|
145
|
+
method: el.method,
|
|
146
|
+
summary: el.summary,
|
|
147
|
+
}))),
|
|
168
148
|
"```",
|
|
169
|
-
].join("\n")
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
149
|
+
].join("\n"),
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
id: (0, uuid_1.v4)(),
|
|
153
|
+
created_at: new Date().toISOString(),
|
|
154
|
+
type: "systemMessage",
|
|
155
|
+
text: [
|
|
156
|
+
"# Included in Test Plan",
|
|
157
|
+
include
|
|
158
|
+
.map((el) => `- ${el.method.toUpperCase()}: ${el.path}`)
|
|
159
|
+
.join("\n"),
|
|
160
|
+
"",
|
|
161
|
+
"# Excluded from Test Plan",
|
|
162
|
+
"These are the endpoints that have already been used in test codes generated as part of a plan group.",
|
|
163
|
+
"These endpoints do not need to be tested again.",
|
|
164
|
+
"However, it is allowed to reference or depend on these endpoints when writing test codes for other purposes.",
|
|
165
|
+
exclude
|
|
166
|
+
.map((el) => `- ${el.method.toUpperCase()}: ${el.path}`)
|
|
167
|
+
.join("\n"),
|
|
168
|
+
].join("\n"),
|
|
169
|
+
},
|
|
170
|
+
];
|
|
175
171
|
function createApplication(props) {
|
|
176
172
|
(0, assertSchemaModel_1.assertSchemaModel)(props.model);
|
|
177
173
|
const application = collection[props.model];
|
|
174
|
+
application.functions[0].validate = (next) => {
|
|
175
|
+
const result = (() => { const _io0 = input => Array.isArray(input.scenarioGroups) && input.scenarioGroups.every(elem => "object" === typeof elem && null !== elem && _io1(elem)); const _io1 = input => "object" === typeof input.endpoint && null !== input.endpoint && _io2(input.endpoint) && (Array.isArray(input.scenarios) && input.scenarios.every(elem => "object" === typeof elem && null !== elem && _io3(elem))); const _io2 = input => "string" === typeof input.path && ("get" === input.method || "post" === input.method || "put" === input.method || "delete" === input.method || "patch" === input.method); const _io3 = input => "string" === typeof input.draft && "string" === typeof input.functionName && (Array.isArray(input.dependsOn) && input.dependsOn.every(elem => "object" === typeof elem && null !== elem && _io4(elem))); const _io4 = input => "object" === typeof input.endpoint && null !== input.endpoint && _io2(input.endpoint) && "string" === typeof input.purpose; const _vo0 = (input, _path, _exceptionable = true) => [(Array.isArray(input.scenarioGroups) || _report(_exceptionable, {
|
|
176
|
+
path: _path + ".scenarioGroups",
|
|
177
|
+
expected: "Array<IAutoBeTestScenarioApplication.IScenarioGroup>",
|
|
178
|
+
value: input.scenarioGroups
|
|
179
|
+
})) && input.scenarioGroups.map((elem, _index4) => ("object" === typeof elem && null !== elem || _report(_exceptionable, {
|
|
180
|
+
path: _path + ".scenarioGroups[" + _index4 + "]",
|
|
181
|
+
expected: "IAutoBeTestScenarioApplication.IScenarioGroup",
|
|
182
|
+
value: elem
|
|
183
|
+
})) && _vo1(elem, _path + ".scenarioGroups[" + _index4 + "]", true && _exceptionable) || _report(_exceptionable, {
|
|
184
|
+
path: _path + ".scenarioGroups[" + _index4 + "]",
|
|
185
|
+
expected: "IAutoBeTestScenarioApplication.IScenarioGroup",
|
|
186
|
+
value: elem
|
|
187
|
+
})).every(flag => flag) || _report(_exceptionable, {
|
|
188
|
+
path: _path + ".scenarioGroups",
|
|
189
|
+
expected: "Array<IAutoBeTestScenarioApplication.IScenarioGroup>",
|
|
190
|
+
value: input.scenarioGroups
|
|
191
|
+
})].every(flag => flag); const _vo1 = (input, _path, _exceptionable = true) => [("object" === typeof input.endpoint && null !== input.endpoint || _report(_exceptionable, {
|
|
192
|
+
path: _path + ".endpoint",
|
|
193
|
+
expected: "AutoBeOpenApi.IEndpoint",
|
|
194
|
+
value: input.endpoint
|
|
195
|
+
})) && _vo2(input.endpoint, _path + ".endpoint", true && _exceptionable) || _report(_exceptionable, {
|
|
196
|
+
path: _path + ".endpoint",
|
|
197
|
+
expected: "AutoBeOpenApi.IEndpoint",
|
|
198
|
+
value: input.endpoint
|
|
199
|
+
}), (Array.isArray(input.scenarios) || _report(_exceptionable, {
|
|
200
|
+
path: _path + ".scenarios",
|
|
201
|
+
expected: "Array<IAutoBeTestScenarioApplication.IScenario>",
|
|
202
|
+
value: input.scenarios
|
|
203
|
+
})) && input.scenarios.map((elem, _index5) => ("object" === typeof elem && null !== elem || _report(_exceptionable, {
|
|
204
|
+
path: _path + ".scenarios[" + _index5 + "]",
|
|
205
|
+
expected: "IAutoBeTestScenarioApplication.IScenario",
|
|
206
|
+
value: elem
|
|
207
|
+
})) && _vo3(elem, _path + ".scenarios[" + _index5 + "]", true && _exceptionable) || _report(_exceptionable, {
|
|
208
|
+
path: _path + ".scenarios[" + _index5 + "]",
|
|
209
|
+
expected: "IAutoBeTestScenarioApplication.IScenario",
|
|
210
|
+
value: elem
|
|
211
|
+
})).every(flag => flag) || _report(_exceptionable, {
|
|
212
|
+
path: _path + ".scenarios",
|
|
213
|
+
expected: "Array<IAutoBeTestScenarioApplication.IScenario>",
|
|
214
|
+
value: input.scenarios
|
|
215
|
+
})].every(flag => flag); const _vo2 = (input, _path, _exceptionable = true) => ["string" === typeof input.path || _report(_exceptionable, {
|
|
216
|
+
path: _path + ".path",
|
|
217
|
+
expected: "string",
|
|
218
|
+
value: input.path
|
|
219
|
+
}), "get" === input.method || "post" === input.method || "put" === input.method || "delete" === input.method || "patch" === input.method || _report(_exceptionable, {
|
|
220
|
+
path: _path + ".method",
|
|
221
|
+
expected: "(\"delete\" | \"get\" | \"patch\" | \"post\" | \"put\")",
|
|
222
|
+
value: input.method
|
|
223
|
+
})].every(flag => flag); const _vo3 = (input, _path, _exceptionable = true) => ["string" === typeof input.draft || _report(_exceptionable, {
|
|
224
|
+
path: _path + ".draft",
|
|
225
|
+
expected: "string",
|
|
226
|
+
value: input.draft
|
|
227
|
+
}), "string" === typeof input.functionName || _report(_exceptionable, {
|
|
228
|
+
path: _path + ".functionName",
|
|
229
|
+
expected: "string",
|
|
230
|
+
value: input.functionName
|
|
231
|
+
}), (Array.isArray(input.dependsOn) || _report(_exceptionable, {
|
|
232
|
+
path: _path + ".dependsOn",
|
|
233
|
+
expected: "Array<IAutoBeTestScenarioApplication.IDependsOn>",
|
|
234
|
+
value: input.dependsOn
|
|
235
|
+
})) && input.dependsOn.map((elem, _index6) => ("object" === typeof elem && null !== elem || _report(_exceptionable, {
|
|
236
|
+
path: _path + ".dependsOn[" + _index6 + "]",
|
|
237
|
+
expected: "IAutoBeTestScenarioApplication.IDependsOn",
|
|
238
|
+
value: elem
|
|
239
|
+
})) && _vo4(elem, _path + ".dependsOn[" + _index6 + "]", true && _exceptionable) || _report(_exceptionable, {
|
|
240
|
+
path: _path + ".dependsOn[" + _index6 + "]",
|
|
241
|
+
expected: "IAutoBeTestScenarioApplication.IDependsOn",
|
|
242
|
+
value: elem
|
|
243
|
+
})).every(flag => flag) || _report(_exceptionable, {
|
|
244
|
+
path: _path + ".dependsOn",
|
|
245
|
+
expected: "Array<IAutoBeTestScenarioApplication.IDependsOn>",
|
|
246
|
+
value: input.dependsOn
|
|
247
|
+
})].every(flag => flag); const _vo4 = (input, _path, _exceptionable = true) => [("object" === typeof input.endpoint && null !== input.endpoint || _report(_exceptionable, {
|
|
248
|
+
path: _path + ".endpoint",
|
|
249
|
+
expected: "AutoBeOpenApi.IEndpoint",
|
|
250
|
+
value: input.endpoint
|
|
251
|
+
})) && _vo2(input.endpoint, _path + ".endpoint", true && _exceptionable) || _report(_exceptionable, {
|
|
252
|
+
path: _path + ".endpoint",
|
|
253
|
+
expected: "AutoBeOpenApi.IEndpoint",
|
|
254
|
+
value: input.endpoint
|
|
255
|
+
}), "string" === typeof input.purpose || _report(_exceptionable, {
|
|
256
|
+
path: _path + ".purpose",
|
|
257
|
+
expected: "string",
|
|
258
|
+
value: input.purpose
|
|
259
|
+
})].every(flag => flag); const __is = input => "object" === typeof input && null !== input && _io0(input); let errors; let _report; return input => {
|
|
260
|
+
if (false === __is(input)) {
|
|
261
|
+
errors = [];
|
|
262
|
+
_report = __typia_transform__validateReport._validateReport(errors);
|
|
263
|
+
((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _report(true, {
|
|
264
|
+
path: _path + "",
|
|
265
|
+
expected: "IAutoBeTestScenarioApplication.IProps",
|
|
266
|
+
value: input
|
|
267
|
+
})) && _vo0(input, _path + "", true) || _report(true, {
|
|
268
|
+
path: _path + "",
|
|
269
|
+
expected: "IAutoBeTestScenarioApplication.IProps",
|
|
270
|
+
value: input
|
|
271
|
+
}))(input, "$input", true);
|
|
272
|
+
const success = 0 === errors.length;
|
|
273
|
+
return success ? {
|
|
274
|
+
success,
|
|
275
|
+
data: input
|
|
276
|
+
} : {
|
|
277
|
+
success,
|
|
278
|
+
errors,
|
|
279
|
+
data: input
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
return {
|
|
283
|
+
success: true,
|
|
284
|
+
data: input
|
|
285
|
+
};
|
|
286
|
+
}; })()(next);
|
|
287
|
+
if (result.success === false)
|
|
288
|
+
return result;
|
|
289
|
+
const errors = [];
|
|
290
|
+
result.data.scenarioGroups.forEach((pg, i, arr) => {
|
|
291
|
+
arr.forEach((target, j) => {
|
|
292
|
+
if (i !== j &&
|
|
293
|
+
target.endpoint.method === pg.endpoint.method &&
|
|
294
|
+
target.endpoint.path === pg.endpoint.path) {
|
|
295
|
+
if (!errors.some((el) => el.path !== `planGroups[${j}].path` &&
|
|
296
|
+
el.value !== target.endpoint.path)) {
|
|
297
|
+
errors.push({
|
|
298
|
+
path: `planGroups[${j}].path`,
|
|
299
|
+
expected: `planGroup's {method + path} cannot duplicated.`,
|
|
300
|
+
value: target.endpoint.path,
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
if (!errors.some((el) => el.path !== `planGroups[${j}].method` &&
|
|
304
|
+
el.value !== target.endpoint.method)) {
|
|
305
|
+
errors.push({
|
|
306
|
+
path: `planGroups[${j}].method`,
|
|
307
|
+
expected: `planGroup's {method + path} cannot duplicated.`,
|
|
308
|
+
value: target.endpoint.method,
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
});
|
|
314
|
+
if (errors.length !== 0) {
|
|
315
|
+
console.log(JSON.stringify(errors, null, 2), "errors");
|
|
316
|
+
return {
|
|
317
|
+
success: false,
|
|
318
|
+
errors,
|
|
319
|
+
data: next,
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
return result;
|
|
323
|
+
};
|
|
178
324
|
return {
|
|
179
325
|
protocol: "class",
|
|
180
|
-
name: "Make
|
|
326
|
+
name: "Make test plans",
|
|
181
327
|
application,
|
|
182
328
|
execute: {
|
|
183
329
|
makeScenario: (next) => {
|
|
@@ -196,19 +342,19 @@ const claude = {
|
|
|
196
342
|
{
|
|
197
343
|
name: "makeScenario",
|
|
198
344
|
parameters: {
|
|
199
|
-
description: " Properties containing the endpoints and
|
|
345
|
+
description: " Properties containing the endpoints and test scenarios.\n\n------------------------------\n\nCurrent Type: {@link IAutoBeTestScenarioApplication.IProps}",
|
|
200
346
|
type: "object",
|
|
201
347
|
properties: {
|
|
202
|
-
|
|
203
|
-
title: "Array of
|
|
204
|
-
description: "Array of
|
|
348
|
+
scenarioGroups: {
|
|
349
|
+
title: "Array of test scenario groups",
|
|
350
|
+
description: "Array of test scenario groups.",
|
|
205
351
|
type: "array",
|
|
206
352
|
items: {
|
|
207
|
-
description: "Current Type: {@link
|
|
353
|
+
description: "Current Type: {@link IAutoBeTestScenarioApplication.IScenarioGroup}",
|
|
208
354
|
type: "object",
|
|
209
355
|
properties: {
|
|
210
356
|
endpoint: {
|
|
211
|
-
description: "Target API endpoint
|
|
357
|
+
description: "Target API endpoint to test.\n\n------------------------------\n\nDescription of the current {@link AutoBeOpenApi.IEndpoint} type:\n\n> API endpoint information.",
|
|
212
358
|
type: "object",
|
|
213
359
|
properties: {
|
|
214
360
|
path: {
|
|
@@ -244,26 +390,81 @@ const claude = {
|
|
|
244
390
|
]
|
|
245
391
|
},
|
|
246
392
|
scenarios: {
|
|
247
|
-
title: "
|
|
248
|
-
description: "
|
|
393
|
+
title: "Array of test scenarios",
|
|
394
|
+
description: "Array of test scenarios.",
|
|
249
395
|
type: "array",
|
|
250
396
|
items: {
|
|
251
|
-
description: "
|
|
397
|
+
description: "Description of the current {@link IAutoBeTestScenarioApplication.IScenario} type:\n\n> Represents a test scenario for a single API operation.\n> \n> This interface extends `AutoBeOpenApi.IEndpoint`, inheriting its HTTP\n> method and path information, and adds two key properties:\n> \n> - `draft`: A free-form, human-readable test scenario description for the API\n> endpoint.\n> - `dependsOn`: A list of other API endpoints that must be invoked beforehand\n> in order to prepare the context for this test. Each dependency includes\n> the purpose of the dependency.\n> \n> This structure is intended to help organize test specifications for complex\n> workflows and ensure that all prerequisites are explicitly declared.",
|
|
252
398
|
type: "object",
|
|
253
399
|
properties: {
|
|
400
|
+
draft: {
|
|
401
|
+
description: "A detailed natural language description of how this API endpoint should\nbe tested. This should include both successful and failure scenarios,\nbusiness rule validations, edge cases, and any sequence of steps\nnecessary to perform the test. A subsequent agent will use this draft to\ngenerate multiple test scenarios.",
|
|
402
|
+
type: "string"
|
|
403
|
+
},
|
|
254
404
|
functionName: {
|
|
255
405
|
title: "Descriptive function name derived from the user scenario",
|
|
256
406
|
description: "Descriptive function name derived from the user scenario.\n\nThe function name serves as a concise, technical identifier that clearly\nrepresents the specific user scenario being described. It should be\nimmediately understandable and directly correspond to the user situation\nwithout requiring additional context.\n\n## Naming Convention\n\n- Must start with `test_` prefix (mandatory requirement)\n- Use snake_case formatting throughout\n- Include the primary user action (create, get, update, delete, list, etc.)\n- Specify the target resource (user, product, order, profile, etc.)\n- Add scenario-specific context (valid_data, invalid_email, not_found,\n etc.)\n\n## Content Structure\n\nFunction names should follow this pattern:\n`test_[user_action]_[resource]_[scenario_context]`\n\nWhere:\n\n- `user_action`: What the user is trying to do\n- `resource`: What the user is interacting with\n- `scenario_context`: The specific situation or condition\n\n## User-Focused Examples\n\n- `test_create_user_profile_with_complete_information` - User providing all\n available profile data\n- `test_retrieve_user_profile_when_profile_exists` - User accessing their\n existing profile\n- `test_update_user_email_with_valid_new_address` - User changing their\n email to a valid new one\n- `test_delete_user_account_when_user_lacks_permission` - User attempting\n account deletion without authorization\n- `test_search_user_profiles_with_pagination_preferences` - User browsing\n profiles with specific pagination\n\n## Clarity Guidelines\n\n- Prioritize clarity over brevity\n- Avoid technical jargon or implementation terms\n- Use terminology that reflects user perspective\n- Ensure the name alone conveys the user's intent\n- Make it understandable to non-technical stakeholders\n- Keep consistent with user scenario description\n\n## Single Endpoint Alignment\n\nFunction names must reflect scenarios that:\n\n- Accomplish user goals through this single endpoint only\n- Don't imply dependency on other API operations\n- Represent complete user interactions",
|
|
257
407
|
type: "string"
|
|
258
408
|
},
|
|
259
|
-
|
|
260
|
-
description: "
|
|
261
|
-
type: "
|
|
409
|
+
dependsOn: {
|
|
410
|
+
description: "A list of other API endpoints that must be executed before this test\nscenario. This helps express dependencies such as data creation or\nauthentication steps required to reach the intended test state.",
|
|
411
|
+
type: "array",
|
|
412
|
+
items: {
|
|
413
|
+
description: "Current Type: {@link IAutoBeTestScenarioApplication.IDependsOn}",
|
|
414
|
+
type: "object",
|
|
415
|
+
properties: {
|
|
416
|
+
endpoint: {
|
|
417
|
+
description: "Target API endpoint that must be executed before the main operation.\n\n------------------------------\n\nDescription of the current {@link AutoBeOpenApi.IEndpoint} type:\n\n> API endpoint information.",
|
|
418
|
+
type: "object",
|
|
419
|
+
properties: {
|
|
420
|
+
path: {
|
|
421
|
+
title: "HTTP path of the API operation",
|
|
422
|
+
description: "HTTP path of the API operation.\n\nThe URL path for accessing this API operation, using path parameters\nenclosed in curly braces (e.g., `/shoppings/customers/sales/{saleId}`).\n\nIt must be corresponded to the {@link parameters path parameters}.\n\nThe path structure should clearly indicate which database entity this\noperation is manipulating, helping to ensure all entities have\nappropriate API coverage.",
|
|
423
|
+
type: "string"
|
|
424
|
+
},
|
|
425
|
+
method: {
|
|
426
|
+
title: "HTTP method of the API operation",
|
|
427
|
+
description: "HTTP method of the API operation.\n\nNote that, if the API operation has {@link requestBody}, method must not\nbe `get`.\n\nAlso, even though the API operation has been designed to only get\ninformation, but it needs complicated request information, it must be\ndefined as `patch` method with {@link requestBody} data specification.\n\n- `get`: get information\n- `patch`: get information with complicated request data\n ({@link requestBody})\n- `post`: create new record\n- `put`: update existing record\n- `delete`: remove record",
|
|
428
|
+
oneOf: [
|
|
429
|
+
{
|
|
430
|
+
"const": "get"
|
|
431
|
+
},
|
|
432
|
+
{
|
|
433
|
+
"const": "post"
|
|
434
|
+
},
|
|
435
|
+
{
|
|
436
|
+
"const": "put"
|
|
437
|
+
},
|
|
438
|
+
{
|
|
439
|
+
"const": "delete"
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
"const": "patch"
|
|
443
|
+
}
|
|
444
|
+
]
|
|
445
|
+
}
|
|
446
|
+
},
|
|
447
|
+
required: [
|
|
448
|
+
"path",
|
|
449
|
+
"method"
|
|
450
|
+
]
|
|
451
|
+
},
|
|
452
|
+
purpose: {
|
|
453
|
+
description: "A concise exscenarioation of why this API call is required before\nexecuting the test for the main operation.\n\nExample: \"Creates a category so that a product can be linked to it during\ncreation.\"",
|
|
454
|
+
type: "string"
|
|
455
|
+
}
|
|
456
|
+
},
|
|
457
|
+
required: [
|
|
458
|
+
"endpoint",
|
|
459
|
+
"purpose"
|
|
460
|
+
]
|
|
461
|
+
}
|
|
262
462
|
}
|
|
263
463
|
},
|
|
264
464
|
required: [
|
|
465
|
+
"draft",
|
|
265
466
|
"functionName",
|
|
266
|
-
"
|
|
467
|
+
"dependsOn"
|
|
267
468
|
]
|
|
268
469
|
}
|
|
269
470
|
}
|
|
@@ -276,28 +477,28 @@ const claude = {
|
|
|
276
477
|
}
|
|
277
478
|
},
|
|
278
479
|
required: [
|
|
279
|
-
"
|
|
480
|
+
"scenarioGroups"
|
|
280
481
|
],
|
|
281
482
|
additionalProperties: false,
|
|
282
483
|
$defs: {}
|
|
283
484
|
},
|
|
284
|
-
description: "Make
|
|
285
|
-
validate: (() => { const _io0 = input => Array.isArray(input.
|
|
286
|
-
path: _path + ".
|
|
287
|
-
expected: "Array<
|
|
288
|
-
value: input.
|
|
289
|
-
})) && input.
|
|
290
|
-
path: _path + ".
|
|
291
|
-
expected: "
|
|
485
|
+
description: "Make test scenarios for the given endpoints.",
|
|
486
|
+
validate: (() => { const _io0 = input => Array.isArray(input.scenarioGroups) && input.scenarioGroups.every(elem => "object" === typeof elem && null !== elem && _io1(elem)); const _io1 = input => "object" === typeof input.endpoint && null !== input.endpoint && _io2(input.endpoint) && (Array.isArray(input.scenarios) && input.scenarios.every(elem => "object" === typeof elem && null !== elem && _io3(elem))); const _io2 = input => "string" === typeof input.path && ("get" === input.method || "post" === input.method || "put" === input.method || "delete" === input.method || "patch" === input.method); const _io3 = input => "string" === typeof input.draft && "string" === typeof input.functionName && (Array.isArray(input.dependsOn) && input.dependsOn.every(elem => "object" === typeof elem && null !== elem && _io4(elem))); const _io4 = input => "object" === typeof input.endpoint && null !== input.endpoint && _io2(input.endpoint) && "string" === typeof input.purpose; const _vo0 = (input, _path, _exceptionable = true) => [(Array.isArray(input.scenarioGroups) || _report(_exceptionable, {
|
|
487
|
+
path: _path + ".scenarioGroups",
|
|
488
|
+
expected: "Array<IAutoBeTestScenarioApplication.IScenarioGroup>",
|
|
489
|
+
value: input.scenarioGroups
|
|
490
|
+
})) && input.scenarioGroups.map((elem, _index4) => ("object" === typeof elem && null !== elem || _report(_exceptionable, {
|
|
491
|
+
path: _path + ".scenarioGroups[" + _index4 + "]",
|
|
492
|
+
expected: "IAutoBeTestScenarioApplication.IScenarioGroup",
|
|
292
493
|
value: elem
|
|
293
|
-
})) && _vo1(elem, _path + ".
|
|
294
|
-
path: _path + ".
|
|
295
|
-
expected: "
|
|
494
|
+
})) && _vo1(elem, _path + ".scenarioGroups[" + _index4 + "]", true && _exceptionable) || _report(_exceptionable, {
|
|
495
|
+
path: _path + ".scenarioGroups[" + _index4 + "]",
|
|
496
|
+
expected: "IAutoBeTestScenarioApplication.IScenarioGroup",
|
|
296
497
|
value: elem
|
|
297
498
|
})).every(flag => flag) || _report(_exceptionable, {
|
|
298
|
-
path: _path + ".
|
|
299
|
-
expected: "Array<
|
|
300
|
-
value: input.
|
|
499
|
+
path: _path + ".scenarioGroups",
|
|
500
|
+
expected: "Array<IAutoBeTestScenarioApplication.IScenarioGroup>",
|
|
501
|
+
value: input.scenarioGroups
|
|
301
502
|
})].every(flag => flag); const _vo1 = (input, _path, _exceptionable = true) => [("object" === typeof input.endpoint && null !== input.endpoint || _report(_exceptionable, {
|
|
302
503
|
path: _path + ".endpoint",
|
|
303
504
|
expected: "AutoBeOpenApi.IEndpoint",
|
|
@@ -308,19 +509,19 @@ const claude = {
|
|
|
308
509
|
value: input.endpoint
|
|
309
510
|
}), (Array.isArray(input.scenarios) || _report(_exceptionable, {
|
|
310
511
|
path: _path + ".scenarios",
|
|
311
|
-
expected: "Array<
|
|
512
|
+
expected: "Array<IAutoBeTestScenarioApplication.IScenario>",
|
|
312
513
|
value: input.scenarios
|
|
313
|
-
})) && input.scenarios.map((elem,
|
|
314
|
-
path: _path + ".scenarios[" +
|
|
315
|
-
expected: "
|
|
514
|
+
})) && input.scenarios.map((elem, _index5) => ("object" === typeof elem && null !== elem || _report(_exceptionable, {
|
|
515
|
+
path: _path + ".scenarios[" + _index5 + "]",
|
|
516
|
+
expected: "IAutoBeTestScenarioApplication.IScenario",
|
|
316
517
|
value: elem
|
|
317
|
-
})) && _vo3(elem, _path + ".scenarios[" +
|
|
318
|
-
path: _path + ".scenarios[" +
|
|
319
|
-
expected: "
|
|
518
|
+
})) && _vo3(elem, _path + ".scenarios[" + _index5 + "]", true && _exceptionable) || _report(_exceptionable, {
|
|
519
|
+
path: _path + ".scenarios[" + _index5 + "]",
|
|
520
|
+
expected: "IAutoBeTestScenarioApplication.IScenario",
|
|
320
521
|
value: elem
|
|
321
522
|
})).every(flag => flag) || _report(_exceptionable, {
|
|
322
523
|
path: _path + ".scenarios",
|
|
323
|
-
expected: "Array<
|
|
524
|
+
expected: "Array<IAutoBeTestScenarioApplication.IScenario>",
|
|
324
525
|
value: input.scenarios
|
|
325
526
|
})].every(flag => flag); const _vo2 = (input, _path, _exceptionable = true) => ["string" === typeof input.path || _report(_exceptionable, {
|
|
326
527
|
path: _path + ".path",
|
|
@@ -330,25 +531,53 @@ const claude = {
|
|
|
330
531
|
path: _path + ".method",
|
|
331
532
|
expected: "(\"delete\" | \"get\" | \"patch\" | \"post\" | \"put\")",
|
|
332
533
|
value: input.method
|
|
333
|
-
})].every(flag => flag); const _vo3 = (input, _path, _exceptionable = true) => ["string" === typeof input.
|
|
534
|
+
})].every(flag => flag); const _vo3 = (input, _path, _exceptionable = true) => ["string" === typeof input.draft || _report(_exceptionable, {
|
|
535
|
+
path: _path + ".draft",
|
|
536
|
+
expected: "string",
|
|
537
|
+
value: input.draft
|
|
538
|
+
}), "string" === typeof input.functionName || _report(_exceptionable, {
|
|
334
539
|
path: _path + ".functionName",
|
|
335
540
|
expected: "string",
|
|
336
541
|
value: input.functionName
|
|
337
|
-
}),
|
|
338
|
-
path: _path + ".
|
|
542
|
+
}), (Array.isArray(input.dependsOn) || _report(_exceptionable, {
|
|
543
|
+
path: _path + ".dependsOn",
|
|
544
|
+
expected: "Array<IAutoBeTestScenarioApplication.IDependsOn>",
|
|
545
|
+
value: input.dependsOn
|
|
546
|
+
})) && input.dependsOn.map((elem, _index6) => ("object" === typeof elem && null !== elem || _report(_exceptionable, {
|
|
547
|
+
path: _path + ".dependsOn[" + _index6 + "]",
|
|
548
|
+
expected: "IAutoBeTestScenarioApplication.IDependsOn",
|
|
549
|
+
value: elem
|
|
550
|
+
})) && _vo4(elem, _path + ".dependsOn[" + _index6 + "]", true && _exceptionable) || _report(_exceptionable, {
|
|
551
|
+
path: _path + ".dependsOn[" + _index6 + "]",
|
|
552
|
+
expected: "IAutoBeTestScenarioApplication.IDependsOn",
|
|
553
|
+
value: elem
|
|
554
|
+
})).every(flag => flag) || _report(_exceptionable, {
|
|
555
|
+
path: _path + ".dependsOn",
|
|
556
|
+
expected: "Array<IAutoBeTestScenarioApplication.IDependsOn>",
|
|
557
|
+
value: input.dependsOn
|
|
558
|
+
})].every(flag => flag); const _vo4 = (input, _path, _exceptionable = true) => [("object" === typeof input.endpoint && null !== input.endpoint || _report(_exceptionable, {
|
|
559
|
+
path: _path + ".endpoint",
|
|
560
|
+
expected: "AutoBeOpenApi.IEndpoint",
|
|
561
|
+
value: input.endpoint
|
|
562
|
+
})) && _vo2(input.endpoint, _path + ".endpoint", true && _exceptionable) || _report(_exceptionable, {
|
|
563
|
+
path: _path + ".endpoint",
|
|
564
|
+
expected: "AutoBeOpenApi.IEndpoint",
|
|
565
|
+
value: input.endpoint
|
|
566
|
+
}), "string" === typeof input.purpose || _report(_exceptionable, {
|
|
567
|
+
path: _path + ".purpose",
|
|
339
568
|
expected: "string",
|
|
340
|
-
value: input.
|
|
569
|
+
value: input.purpose
|
|
341
570
|
})].every(flag => flag); const __is = input => "object" === typeof input && null !== input && _io0(input); let errors; let _report; return input => {
|
|
342
571
|
if (false === __is(input)) {
|
|
343
572
|
errors = [];
|
|
344
573
|
_report = __typia_transform__validateReport._validateReport(errors);
|
|
345
574
|
((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _report(true, {
|
|
346
575
|
path: _path + "",
|
|
347
|
-
expected: "
|
|
576
|
+
expected: "IAutoBeTestScenarioApplication.IProps",
|
|
348
577
|
value: input
|
|
349
578
|
})) && _vo0(input, _path + "", true) || _report(true, {
|
|
350
579
|
path: _path + "",
|
|
351
|
-
expected: "
|
|
580
|
+
expected: "IAutoBeTestScenarioApplication.IProps",
|
|
352
581
|
value: input
|
|
353
582
|
}))(input, "$input", true);
|
|
354
583
|
const success = 0 === errors.length;
|
|
@@ -381,19 +610,19 @@ const collection = {
|
|
|
381
610
|
{
|
|
382
611
|
name: "makeScenario",
|
|
383
612
|
parameters: {
|
|
384
|
-
description: " Properties containing the endpoints and
|
|
613
|
+
description: " Properties containing the endpoints and test scenarios.\n\n------------------------------\n\nCurrent Type: {@link IAutoBeTestScenarioApplication.IProps}",
|
|
385
614
|
type: "object",
|
|
386
615
|
properties: {
|
|
387
|
-
|
|
388
|
-
title: "Array of
|
|
389
|
-
description: "Array of
|
|
616
|
+
scenarioGroups: {
|
|
617
|
+
title: "Array of test scenario groups",
|
|
618
|
+
description: "Array of test scenario groups.",
|
|
390
619
|
type: "array",
|
|
391
620
|
items: {
|
|
392
|
-
description: "Current Type: {@link
|
|
621
|
+
description: "Current Type: {@link IAutoBeTestScenarioApplication.IScenarioGroup}",
|
|
393
622
|
type: "object",
|
|
394
623
|
properties: {
|
|
395
624
|
endpoint: {
|
|
396
|
-
description: "Target API endpoint
|
|
625
|
+
description: "Target API endpoint to test.\n\n------------------------------\n\nDescription of the current {@link AutoBeOpenApi.IEndpoint} type:\n\n> API endpoint information.",
|
|
397
626
|
type: "object",
|
|
398
627
|
properties: {
|
|
399
628
|
path: {
|
|
@@ -420,26 +649,72 @@ const collection = {
|
|
|
420
649
|
]
|
|
421
650
|
},
|
|
422
651
|
scenarios: {
|
|
423
|
-
title: "
|
|
424
|
-
description: "
|
|
652
|
+
title: "Array of test scenarios",
|
|
653
|
+
description: "Array of test scenarios.",
|
|
425
654
|
type: "array",
|
|
426
655
|
items: {
|
|
427
|
-
description: "
|
|
656
|
+
description: "Description of the current {@link IAutoBeTestScenarioApplication.IScenario} type:\n\n> Represents a test scenario for a single API operation.\n> \n> This interface extends `AutoBeOpenApi.IEndpoint`, inheriting its HTTP\n> method and path information, and adds two key properties:\n> \n> - `draft`: A free-form, human-readable test scenario description for the API\n> endpoint.\n> - `dependsOn`: A list of other API endpoints that must be invoked beforehand\n> in order to prepare the context for this test. Each dependency includes\n> the purpose of the dependency.\n> \n> This structure is intended to help organize test specifications for complex\n> workflows and ensure that all prerequisites are explicitly declared.",
|
|
428
657
|
type: "object",
|
|
429
658
|
properties: {
|
|
659
|
+
draft: {
|
|
660
|
+
description: "A detailed natural language description of how this API endpoint should\nbe tested. This should include both successful and failure scenarios,\nbusiness rule validations, edge cases, and any sequence of steps\nnecessary to perform the test. A subsequent agent will use this draft to\ngenerate multiple test scenarios.",
|
|
661
|
+
type: "string"
|
|
662
|
+
},
|
|
430
663
|
functionName: {
|
|
431
664
|
title: "Descriptive function name derived from the user scenario",
|
|
432
665
|
description: "Descriptive function name derived from the user scenario.\n\nThe function name serves as a concise, technical identifier that clearly\nrepresents the specific user scenario being described. It should be\nimmediately understandable and directly correspond to the user situation\nwithout requiring additional context.\n\n## Naming Convention\n\n- Must start with `test_` prefix (mandatory requirement)\n- Use snake_case formatting throughout\n- Include the primary user action (create, get, update, delete, list, etc.)\n- Specify the target resource (user, product, order, profile, etc.)\n- Add scenario-specific context (valid_data, invalid_email, not_found,\n etc.)\n\n## Content Structure\n\nFunction names should follow this pattern:\n`test_[user_action]_[resource]_[scenario_context]`\n\nWhere:\n\n- `user_action`: What the user is trying to do\n- `resource`: What the user is interacting with\n- `scenario_context`: The specific situation or condition\n\n## User-Focused Examples\n\n- `test_create_user_profile_with_complete_information` - User providing all\n available profile data\n- `test_retrieve_user_profile_when_profile_exists` - User accessing their\n existing profile\n- `test_update_user_email_with_valid_new_address` - User changing their\n email to a valid new one\n- `test_delete_user_account_when_user_lacks_permission` - User attempting\n account deletion without authorization\n- `test_search_user_profiles_with_pagination_preferences` - User browsing\n profiles with specific pagination\n\n## Clarity Guidelines\n\n- Prioritize clarity over brevity\n- Avoid technical jargon or implementation terms\n- Use terminology that reflects user perspective\n- Ensure the name alone conveys the user's intent\n- Make it understandable to non-technical stakeholders\n- Keep consistent with user scenario description\n\n## Single Endpoint Alignment\n\nFunction names must reflect scenarios that:\n\n- Accomplish user goals through this single endpoint only\n- Don't imply dependency on other API operations\n- Represent complete user interactions",
|
|
433
666
|
type: "string"
|
|
434
667
|
},
|
|
435
|
-
|
|
436
|
-
description: "
|
|
437
|
-
type: "
|
|
668
|
+
dependsOn: {
|
|
669
|
+
description: "A list of other API endpoints that must be executed before this test\nscenario. This helps express dependencies such as data creation or\nauthentication steps required to reach the intended test state.",
|
|
670
|
+
type: "array",
|
|
671
|
+
items: {
|
|
672
|
+
description: "Current Type: {@link IAutoBeTestScenarioApplication.IDependsOn}",
|
|
673
|
+
type: "object",
|
|
674
|
+
properties: {
|
|
675
|
+
endpoint: {
|
|
676
|
+
description: "Target API endpoint that must be executed before the main operation.\n\n------------------------------\n\nDescription of the current {@link AutoBeOpenApi.IEndpoint} type:\n\n> API endpoint information.",
|
|
677
|
+
type: "object",
|
|
678
|
+
properties: {
|
|
679
|
+
path: {
|
|
680
|
+
title: "HTTP path of the API operation",
|
|
681
|
+
description: "HTTP path of the API operation.\n\nThe URL path for accessing this API operation, using path parameters\nenclosed in curly braces (e.g., `/shoppings/customers/sales/{saleId}`).\n\nIt must be corresponded to the {@link parameters path parameters}.\n\nThe path structure should clearly indicate which database entity this\noperation is manipulating, helping to ensure all entities have\nappropriate API coverage.",
|
|
682
|
+
type: "string"
|
|
683
|
+
},
|
|
684
|
+
method: {
|
|
685
|
+
title: "HTTP method of the API operation",
|
|
686
|
+
description: "HTTP method of the API operation.\n\nNote that, if the API operation has {@link requestBody}, method must not\nbe `get`.\n\nAlso, even though the API operation has been designed to only get\ninformation, but it needs complicated request information, it must be\ndefined as `patch` method with {@link requestBody} data specification.\n\n- `get`: get information\n- `patch`: get information with complicated request data\n ({@link requestBody})\n- `post`: create new record\n- `put`: update existing record\n- `delete`: remove record",
|
|
687
|
+
type: "string",
|
|
688
|
+
"enum": [
|
|
689
|
+
"get",
|
|
690
|
+
"post",
|
|
691
|
+
"put",
|
|
692
|
+
"delete",
|
|
693
|
+
"patch"
|
|
694
|
+
]
|
|
695
|
+
}
|
|
696
|
+
},
|
|
697
|
+
required: [
|
|
698
|
+
"path",
|
|
699
|
+
"method"
|
|
700
|
+
]
|
|
701
|
+
},
|
|
702
|
+
purpose: {
|
|
703
|
+
description: "A concise exscenarioation of why this API call is required before\nexecuting the test for the main operation.\n\nExample: \"Creates a category so that a product can be linked to it during\ncreation.\"",
|
|
704
|
+
type: "string"
|
|
705
|
+
}
|
|
706
|
+
},
|
|
707
|
+
required: [
|
|
708
|
+
"endpoint",
|
|
709
|
+
"purpose"
|
|
710
|
+
]
|
|
711
|
+
}
|
|
438
712
|
}
|
|
439
713
|
},
|
|
440
714
|
required: [
|
|
715
|
+
"draft",
|
|
441
716
|
"functionName",
|
|
442
|
-
"
|
|
717
|
+
"dependsOn"
|
|
443
718
|
]
|
|
444
719
|
}
|
|
445
720
|
}
|
|
@@ -452,28 +727,28 @@ const collection = {
|
|
|
452
727
|
}
|
|
453
728
|
},
|
|
454
729
|
required: [
|
|
455
|
-
"
|
|
730
|
+
"scenarioGroups"
|
|
456
731
|
],
|
|
457
732
|
additionalProperties: false,
|
|
458
733
|
$defs: {}
|
|
459
734
|
},
|
|
460
|
-
description: "Make
|
|
461
|
-
validate: (() => { const _io0 = input => Array.isArray(input.
|
|
462
|
-
path: _path + ".
|
|
463
|
-
expected: "Array<
|
|
464
|
-
value: input.
|
|
465
|
-
})) && input.
|
|
466
|
-
path: _path + ".
|
|
467
|
-
expected: "
|
|
735
|
+
description: "Make test scenarios for the given endpoints.",
|
|
736
|
+
validate: (() => { const _io0 = input => Array.isArray(input.scenarioGroups) && input.scenarioGroups.every(elem => "object" === typeof elem && null !== elem && _io1(elem)); const _io1 = input => "object" === typeof input.endpoint && null !== input.endpoint && _io2(input.endpoint) && (Array.isArray(input.scenarios) && input.scenarios.every(elem => "object" === typeof elem && null !== elem && _io3(elem))); const _io2 = input => "string" === typeof input.path && ("get" === input.method || "post" === input.method || "put" === input.method || "delete" === input.method || "patch" === input.method); const _io3 = input => "string" === typeof input.draft && "string" === typeof input.functionName && (Array.isArray(input.dependsOn) && input.dependsOn.every(elem => "object" === typeof elem && null !== elem && _io4(elem))); const _io4 = input => "object" === typeof input.endpoint && null !== input.endpoint && _io2(input.endpoint) && "string" === typeof input.purpose; const _vo0 = (input, _path, _exceptionable = true) => [(Array.isArray(input.scenarioGroups) || _report(_exceptionable, {
|
|
737
|
+
path: _path + ".scenarioGroups",
|
|
738
|
+
expected: "Array<IAutoBeTestScenarioApplication.IScenarioGroup>",
|
|
739
|
+
value: input.scenarioGroups
|
|
740
|
+
})) && input.scenarioGroups.map((elem, _index4) => ("object" === typeof elem && null !== elem || _report(_exceptionable, {
|
|
741
|
+
path: _path + ".scenarioGroups[" + _index4 + "]",
|
|
742
|
+
expected: "IAutoBeTestScenarioApplication.IScenarioGroup",
|
|
468
743
|
value: elem
|
|
469
|
-
})) && _vo1(elem, _path + ".
|
|
470
|
-
path: _path + ".
|
|
471
|
-
expected: "
|
|
744
|
+
})) && _vo1(elem, _path + ".scenarioGroups[" + _index4 + "]", true && _exceptionable) || _report(_exceptionable, {
|
|
745
|
+
path: _path + ".scenarioGroups[" + _index4 + "]",
|
|
746
|
+
expected: "IAutoBeTestScenarioApplication.IScenarioGroup",
|
|
472
747
|
value: elem
|
|
473
748
|
})).every(flag => flag) || _report(_exceptionable, {
|
|
474
|
-
path: _path + ".
|
|
475
|
-
expected: "Array<
|
|
476
|
-
value: input.
|
|
749
|
+
path: _path + ".scenarioGroups",
|
|
750
|
+
expected: "Array<IAutoBeTestScenarioApplication.IScenarioGroup>",
|
|
751
|
+
value: input.scenarioGroups
|
|
477
752
|
})].every(flag => flag); const _vo1 = (input, _path, _exceptionable = true) => [("object" === typeof input.endpoint && null !== input.endpoint || _report(_exceptionable, {
|
|
478
753
|
path: _path + ".endpoint",
|
|
479
754
|
expected: "AutoBeOpenApi.IEndpoint",
|
|
@@ -484,19 +759,19 @@ const collection = {
|
|
|
484
759
|
value: input.endpoint
|
|
485
760
|
}), (Array.isArray(input.scenarios) || _report(_exceptionable, {
|
|
486
761
|
path: _path + ".scenarios",
|
|
487
|
-
expected: "Array<
|
|
762
|
+
expected: "Array<IAutoBeTestScenarioApplication.IScenario>",
|
|
488
763
|
value: input.scenarios
|
|
489
|
-
})) && input.scenarios.map((elem,
|
|
490
|
-
path: _path + ".scenarios[" +
|
|
491
|
-
expected: "
|
|
764
|
+
})) && input.scenarios.map((elem, _index5) => ("object" === typeof elem && null !== elem || _report(_exceptionable, {
|
|
765
|
+
path: _path + ".scenarios[" + _index5 + "]",
|
|
766
|
+
expected: "IAutoBeTestScenarioApplication.IScenario",
|
|
492
767
|
value: elem
|
|
493
|
-
})) && _vo3(elem, _path + ".scenarios[" +
|
|
494
|
-
path: _path + ".scenarios[" +
|
|
495
|
-
expected: "
|
|
768
|
+
})) && _vo3(elem, _path + ".scenarios[" + _index5 + "]", true && _exceptionable) || _report(_exceptionable, {
|
|
769
|
+
path: _path + ".scenarios[" + _index5 + "]",
|
|
770
|
+
expected: "IAutoBeTestScenarioApplication.IScenario",
|
|
496
771
|
value: elem
|
|
497
772
|
})).every(flag => flag) || _report(_exceptionable, {
|
|
498
773
|
path: _path + ".scenarios",
|
|
499
|
-
expected: "Array<
|
|
774
|
+
expected: "Array<IAutoBeTestScenarioApplication.IScenario>",
|
|
500
775
|
value: input.scenarios
|
|
501
776
|
})].every(flag => flag); const _vo2 = (input, _path, _exceptionable = true) => ["string" === typeof input.path || _report(_exceptionable, {
|
|
502
777
|
path: _path + ".path",
|
|
@@ -506,25 +781,53 @@ const collection = {
|
|
|
506
781
|
path: _path + ".method",
|
|
507
782
|
expected: "(\"delete\" | \"get\" | \"patch\" | \"post\" | \"put\")",
|
|
508
783
|
value: input.method
|
|
509
|
-
})].every(flag => flag); const _vo3 = (input, _path, _exceptionable = true) => ["string" === typeof input.
|
|
784
|
+
})].every(flag => flag); const _vo3 = (input, _path, _exceptionable = true) => ["string" === typeof input.draft || _report(_exceptionable, {
|
|
785
|
+
path: _path + ".draft",
|
|
786
|
+
expected: "string",
|
|
787
|
+
value: input.draft
|
|
788
|
+
}), "string" === typeof input.functionName || _report(_exceptionable, {
|
|
510
789
|
path: _path + ".functionName",
|
|
511
790
|
expected: "string",
|
|
512
791
|
value: input.functionName
|
|
513
|
-
}),
|
|
514
|
-
path: _path + ".
|
|
792
|
+
}), (Array.isArray(input.dependsOn) || _report(_exceptionable, {
|
|
793
|
+
path: _path + ".dependsOn",
|
|
794
|
+
expected: "Array<IAutoBeTestScenarioApplication.IDependsOn>",
|
|
795
|
+
value: input.dependsOn
|
|
796
|
+
})) && input.dependsOn.map((elem, _index6) => ("object" === typeof elem && null !== elem || _report(_exceptionable, {
|
|
797
|
+
path: _path + ".dependsOn[" + _index6 + "]",
|
|
798
|
+
expected: "IAutoBeTestScenarioApplication.IDependsOn",
|
|
799
|
+
value: elem
|
|
800
|
+
})) && _vo4(elem, _path + ".dependsOn[" + _index6 + "]", true && _exceptionable) || _report(_exceptionable, {
|
|
801
|
+
path: _path + ".dependsOn[" + _index6 + "]",
|
|
802
|
+
expected: "IAutoBeTestScenarioApplication.IDependsOn",
|
|
803
|
+
value: elem
|
|
804
|
+
})).every(flag => flag) || _report(_exceptionable, {
|
|
805
|
+
path: _path + ".dependsOn",
|
|
806
|
+
expected: "Array<IAutoBeTestScenarioApplication.IDependsOn>",
|
|
807
|
+
value: input.dependsOn
|
|
808
|
+
})].every(flag => flag); const _vo4 = (input, _path, _exceptionable = true) => [("object" === typeof input.endpoint && null !== input.endpoint || _report(_exceptionable, {
|
|
809
|
+
path: _path + ".endpoint",
|
|
810
|
+
expected: "AutoBeOpenApi.IEndpoint",
|
|
811
|
+
value: input.endpoint
|
|
812
|
+
})) && _vo2(input.endpoint, _path + ".endpoint", true && _exceptionable) || _report(_exceptionable, {
|
|
813
|
+
path: _path + ".endpoint",
|
|
814
|
+
expected: "AutoBeOpenApi.IEndpoint",
|
|
815
|
+
value: input.endpoint
|
|
816
|
+
}), "string" === typeof input.purpose || _report(_exceptionable, {
|
|
817
|
+
path: _path + ".purpose",
|
|
515
818
|
expected: "string",
|
|
516
|
-
value: input.
|
|
819
|
+
value: input.purpose
|
|
517
820
|
})].every(flag => flag); const __is = input => "object" === typeof input && null !== input && _io0(input); let errors; let _report; return input => {
|
|
518
821
|
if (false === __is(input)) {
|
|
519
822
|
errors = [];
|
|
520
823
|
_report = __typia_transform__validateReport._validateReport(errors);
|
|
521
824
|
((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _report(true, {
|
|
522
825
|
path: _path + "",
|
|
523
|
-
expected: "
|
|
826
|
+
expected: "IAutoBeTestScenarioApplication.IProps",
|
|
524
827
|
value: input
|
|
525
828
|
})) && _vo0(input, _path + "", true) || _report(true, {
|
|
526
829
|
path: _path + "",
|
|
527
|
-
expected: "
|
|
830
|
+
expected: "IAutoBeTestScenarioApplication.IProps",
|
|
528
831
|
value: input
|
|
529
832
|
}))(input, "$input", true);
|
|
530
833
|
const success = 0 === errors.length;
|
|
@@ -562,7 +865,7 @@ const collection = {
|
|
|
562
865
|
parameters: {
|
|
563
866
|
type: "object",
|
|
564
867
|
properties: {
|
|
565
|
-
|
|
868
|
+
scenarioGroups: {
|
|
566
869
|
type: "array",
|
|
567
870
|
items: {
|
|
568
871
|
type: "object",
|
|
@@ -592,7 +895,7 @@ const collection = {
|
|
|
592
895
|
"path",
|
|
593
896
|
"method"
|
|
594
897
|
],
|
|
595
|
-
description: "Target API endpoint
|
|
898
|
+
description: "Target API endpoint to test.\n\n------------------------------\n\nDescription of the current {@link AutoBeOpenApi.IEndpoint} type:\n\n> API endpoint information.",
|
|
596
899
|
additionalProperties: false
|
|
597
900
|
},
|
|
598
901
|
scenarios: {
|
|
@@ -600,61 +903,109 @@ const collection = {
|
|
|
600
903
|
items: {
|
|
601
904
|
type: "object",
|
|
602
905
|
properties: {
|
|
906
|
+
draft: {
|
|
907
|
+
type: "string",
|
|
908
|
+
description: "A detailed natural language description of how this API endpoint should\nbe tested. This should include both successful and failure scenarios,\nbusiness rule validations, edge cases, and any sequence of steps\nnecessary to perform the test. A subsequent agent will use this draft to\ngenerate multiple test scenarios."
|
|
909
|
+
},
|
|
603
910
|
functionName: {
|
|
604
911
|
type: "string",
|
|
605
912
|
title: "Descriptive function name derived from the user scenario",
|
|
606
913
|
description: "Descriptive function name derived from the user scenario.\n\nThe function name serves as a concise, technical identifier that clearly\nrepresents the specific user scenario being described. It should be\nimmediately understandable and directly correspond to the user situation\nwithout requiring additional context.\n\n## Naming Convention\n\n- Must start with `test_` prefix (mandatory requirement)\n- Use snake_case formatting throughout\n- Include the primary user action (create, get, update, delete, list, etc.)\n- Specify the target resource (user, product, order, profile, etc.)\n- Add scenario-specific context (valid_data, invalid_email, not_found,\n etc.)\n\n## Content Structure\n\nFunction names should follow this pattern:\n`test_[user_action]_[resource]_[scenario_context]`\n\nWhere:\n\n- `user_action`: What the user is trying to do\n- `resource`: What the user is interacting with\n- `scenario_context`: The specific situation or condition\n\n## User-Focused Examples\n\n- `test_create_user_profile_with_complete_information` - User providing all\n available profile data\n- `test_retrieve_user_profile_when_profile_exists` - User accessing their\n existing profile\n- `test_update_user_email_with_valid_new_address` - User changing their\n email to a valid new one\n- `test_delete_user_account_when_user_lacks_permission` - User attempting\n account deletion without authorization\n- `test_search_user_profiles_with_pagination_preferences` - User browsing\n profiles with specific pagination\n\n## Clarity Guidelines\n\n- Prioritize clarity over brevity\n- Avoid technical jargon or implementation terms\n- Use terminology that reflects user perspective\n- Ensure the name alone conveys the user's intent\n- Make it understandable to non-technical stakeholders\n- Keep consistent with user scenario description\n\n## Single Endpoint Alignment\n\nFunction names must reflect scenarios that:\n\n- Accomplish user goals through this single endpoint only\n- Don't imply dependency on other API operations\n- Represent complete user interactions"
|
|
607
914
|
},
|
|
608
|
-
|
|
609
|
-
type: "
|
|
610
|
-
|
|
915
|
+
dependsOn: {
|
|
916
|
+
type: "array",
|
|
917
|
+
items: {
|
|
918
|
+
type: "object",
|
|
919
|
+
properties: {
|
|
920
|
+
endpoint: {
|
|
921
|
+
type: "object",
|
|
922
|
+
properties: {
|
|
923
|
+
path: {
|
|
924
|
+
type: "string",
|
|
925
|
+
title: "HTTP path of the API operation",
|
|
926
|
+
description: "HTTP path of the API operation.\n\nThe URL path for accessing this API operation, using path parameters\nenclosed in curly braces (e.g., `/shoppings/customers/sales/{saleId}`).\n\nIt must be corresponded to the {@link parameters path parameters}.\n\nThe path structure should clearly indicate which database entity this\noperation is manipulating, helping to ensure all entities have\nappropriate API coverage."
|
|
927
|
+
},
|
|
928
|
+
method: {
|
|
929
|
+
type: "string",
|
|
930
|
+
"enum": [
|
|
931
|
+
"get",
|
|
932
|
+
"post",
|
|
933
|
+
"put",
|
|
934
|
+
"delete",
|
|
935
|
+
"patch"
|
|
936
|
+
],
|
|
937
|
+
title: "HTTP method of the API operation",
|
|
938
|
+
description: "HTTP method of the API operation.\n\nNote that, if the API operation has {@link requestBody}, method must not\nbe `get`.\n\nAlso, even though the API operation has been designed to only get\ninformation, but it needs complicated request information, it must be\ndefined as `patch` method with {@link requestBody} data specification.\n\n- `get`: get information\n- `patch`: get information with complicated request data\n ({@link requestBody})\n- `post`: create new record\n- `put`: update existing record\n- `delete`: remove record"
|
|
939
|
+
}
|
|
940
|
+
},
|
|
941
|
+
required: [
|
|
942
|
+
"path",
|
|
943
|
+
"method"
|
|
944
|
+
],
|
|
945
|
+
description: "Target API endpoint that must be executed before the main operation.\n\n------------------------------\n\nDescription of the current {@link AutoBeOpenApi.IEndpoint} type:\n\n> API endpoint information.",
|
|
946
|
+
additionalProperties: false
|
|
947
|
+
},
|
|
948
|
+
purpose: {
|
|
949
|
+
type: "string",
|
|
950
|
+
description: "A concise exscenarioation of why this API call is required before\nexecuting the test for the main operation.\n\nExample: \"Creates a category so that a product can be linked to it during\ncreation.\""
|
|
951
|
+
}
|
|
952
|
+
},
|
|
953
|
+
required: [
|
|
954
|
+
"endpoint",
|
|
955
|
+
"purpose"
|
|
956
|
+
],
|
|
957
|
+
description: "Current Type: {@link IAutoBeTestScenarioApplication.IDependsOn}",
|
|
958
|
+
additionalProperties: false
|
|
959
|
+
},
|
|
960
|
+
description: "A list of other API endpoints that must be executed before this test\nscenario. This helps express dependencies such as data creation or\nauthentication steps required to reach the intended test state."
|
|
611
961
|
}
|
|
612
962
|
},
|
|
613
963
|
required: [
|
|
964
|
+
"draft",
|
|
614
965
|
"functionName",
|
|
615
|
-
"
|
|
966
|
+
"dependsOn"
|
|
616
967
|
],
|
|
617
|
-
description: "
|
|
968
|
+
description: "Description of the current {@link IAutoBeTestScenarioApplication.IScenario} type:\n\n> Represents a test scenario for a single API operation.\n> \n> This interface extends `AutoBeOpenApi.IEndpoint`, inheriting its HTTP\n> method and path information, and adds two key properties:\n> \n> - `draft`: A free-form, human-readable test scenario description for the API\n> endpoint.\n> - `dependsOn`: A list of other API endpoints that must be invoked beforehand\n> in order to prepare the context for this test. Each dependency includes\n> the purpose of the dependency.\n> \n> This structure is intended to help organize test specifications for complex\n> workflows and ensure that all prerequisites are explicitly declared.",
|
|
618
969
|
additionalProperties: false
|
|
619
970
|
},
|
|
620
|
-
title: "
|
|
621
|
-
description: "
|
|
971
|
+
title: "Array of test scenarios",
|
|
972
|
+
description: "Array of test scenarios."
|
|
622
973
|
}
|
|
623
974
|
},
|
|
624
975
|
required: [
|
|
625
976
|
"endpoint",
|
|
626
977
|
"scenarios"
|
|
627
978
|
],
|
|
628
|
-
description: "Current Type: {@link
|
|
979
|
+
description: "Current Type: {@link IAutoBeTestScenarioApplication.IScenarioGroup}",
|
|
629
980
|
additionalProperties: false
|
|
630
981
|
},
|
|
631
|
-
title: "Array of
|
|
632
|
-
description: "Array of
|
|
982
|
+
title: "Array of test scenario groups",
|
|
983
|
+
description: "Array of test scenario groups."
|
|
633
984
|
}
|
|
634
985
|
},
|
|
635
986
|
required: [
|
|
636
|
-
"
|
|
987
|
+
"scenarioGroups"
|
|
637
988
|
],
|
|
638
|
-
description: " Properties containing the endpoints and
|
|
989
|
+
description: " Properties containing the endpoints and test scenarios.\n\n------------------------------\n\nCurrent Type: {@link IAutoBeTestScenarioApplication.IProps}",
|
|
639
990
|
additionalProperties: false
|
|
640
991
|
},
|
|
641
|
-
description: "Make
|
|
642
|
-
validate: (() => { const _io0 = input => Array.isArray(input.
|
|
643
|
-
path: _path + ".
|
|
644
|
-
expected: "Array<
|
|
645
|
-
value: input.
|
|
646
|
-
})) && input.
|
|
647
|
-
path: _path + ".
|
|
648
|
-
expected: "
|
|
992
|
+
description: "Make test scenarios for the given endpoints.",
|
|
993
|
+
validate: (() => { const _io0 = input => Array.isArray(input.scenarioGroups) && input.scenarioGroups.every(elem => "object" === typeof elem && null !== elem && _io1(elem)); const _io1 = input => "object" === typeof input.endpoint && null !== input.endpoint && _io2(input.endpoint) && (Array.isArray(input.scenarios) && input.scenarios.every(elem => "object" === typeof elem && null !== elem && _io3(elem))); const _io2 = input => "string" === typeof input.path && ("get" === input.method || "post" === input.method || "put" === input.method || "delete" === input.method || "patch" === input.method); const _io3 = input => "string" === typeof input.draft && "string" === typeof input.functionName && (Array.isArray(input.dependsOn) && input.dependsOn.every(elem => "object" === typeof elem && null !== elem && _io4(elem))); const _io4 = input => "object" === typeof input.endpoint && null !== input.endpoint && _io2(input.endpoint) && "string" === typeof input.purpose; const _vo0 = (input, _path, _exceptionable = true) => [(Array.isArray(input.scenarioGroups) || _report(_exceptionable, {
|
|
994
|
+
path: _path + ".scenarioGroups",
|
|
995
|
+
expected: "Array<IAutoBeTestScenarioApplication.IScenarioGroup>",
|
|
996
|
+
value: input.scenarioGroups
|
|
997
|
+
})) && input.scenarioGroups.map((elem, _index4) => ("object" === typeof elem && null !== elem || _report(_exceptionable, {
|
|
998
|
+
path: _path + ".scenarioGroups[" + _index4 + "]",
|
|
999
|
+
expected: "IAutoBeTestScenarioApplication.IScenarioGroup",
|
|
649
1000
|
value: elem
|
|
650
|
-
})) && _vo1(elem, _path + ".
|
|
651
|
-
path: _path + ".
|
|
652
|
-
expected: "
|
|
1001
|
+
})) && _vo1(elem, _path + ".scenarioGroups[" + _index4 + "]", true && _exceptionable) || _report(_exceptionable, {
|
|
1002
|
+
path: _path + ".scenarioGroups[" + _index4 + "]",
|
|
1003
|
+
expected: "IAutoBeTestScenarioApplication.IScenarioGroup",
|
|
653
1004
|
value: elem
|
|
654
1005
|
})).every(flag => flag) || _report(_exceptionable, {
|
|
655
|
-
path: _path + ".
|
|
656
|
-
expected: "Array<
|
|
657
|
-
value: input.
|
|
1006
|
+
path: _path + ".scenarioGroups",
|
|
1007
|
+
expected: "Array<IAutoBeTestScenarioApplication.IScenarioGroup>",
|
|
1008
|
+
value: input.scenarioGroups
|
|
658
1009
|
})].every(flag => flag); const _vo1 = (input, _path, _exceptionable = true) => [("object" === typeof input.endpoint && null !== input.endpoint || _report(_exceptionable, {
|
|
659
1010
|
path: _path + ".endpoint",
|
|
660
1011
|
expected: "AutoBeOpenApi.IEndpoint",
|
|
@@ -665,19 +1016,19 @@ const collection = {
|
|
|
665
1016
|
value: input.endpoint
|
|
666
1017
|
}), (Array.isArray(input.scenarios) || _report(_exceptionable, {
|
|
667
1018
|
path: _path + ".scenarios",
|
|
668
|
-
expected: "Array<
|
|
1019
|
+
expected: "Array<IAutoBeTestScenarioApplication.IScenario>",
|
|
669
1020
|
value: input.scenarios
|
|
670
|
-
})) && input.scenarios.map((elem,
|
|
671
|
-
path: _path + ".scenarios[" +
|
|
672
|
-
expected: "
|
|
1021
|
+
})) && input.scenarios.map((elem, _index5) => ("object" === typeof elem && null !== elem || _report(_exceptionable, {
|
|
1022
|
+
path: _path + ".scenarios[" + _index5 + "]",
|
|
1023
|
+
expected: "IAutoBeTestScenarioApplication.IScenario",
|
|
673
1024
|
value: elem
|
|
674
|
-
})) && _vo3(elem, _path + ".scenarios[" +
|
|
675
|
-
path: _path + ".scenarios[" +
|
|
676
|
-
expected: "
|
|
1025
|
+
})) && _vo3(elem, _path + ".scenarios[" + _index5 + "]", true && _exceptionable) || _report(_exceptionable, {
|
|
1026
|
+
path: _path + ".scenarios[" + _index5 + "]",
|
|
1027
|
+
expected: "IAutoBeTestScenarioApplication.IScenario",
|
|
677
1028
|
value: elem
|
|
678
1029
|
})).every(flag => flag) || _report(_exceptionable, {
|
|
679
1030
|
path: _path + ".scenarios",
|
|
680
|
-
expected: "Array<
|
|
1031
|
+
expected: "Array<IAutoBeTestScenarioApplication.IScenario>",
|
|
681
1032
|
value: input.scenarios
|
|
682
1033
|
})].every(flag => flag); const _vo2 = (input, _path, _exceptionable = true) => ["string" === typeof input.path || _report(_exceptionable, {
|
|
683
1034
|
path: _path + ".path",
|
|
@@ -687,25 +1038,53 @@ const collection = {
|
|
|
687
1038
|
path: _path + ".method",
|
|
688
1039
|
expected: "(\"delete\" | \"get\" | \"patch\" | \"post\" | \"put\")",
|
|
689
1040
|
value: input.method
|
|
690
|
-
})].every(flag => flag); const _vo3 = (input, _path, _exceptionable = true) => ["string" === typeof input.
|
|
1041
|
+
})].every(flag => flag); const _vo3 = (input, _path, _exceptionable = true) => ["string" === typeof input.draft || _report(_exceptionable, {
|
|
1042
|
+
path: _path + ".draft",
|
|
1043
|
+
expected: "string",
|
|
1044
|
+
value: input.draft
|
|
1045
|
+
}), "string" === typeof input.functionName || _report(_exceptionable, {
|
|
691
1046
|
path: _path + ".functionName",
|
|
692
1047
|
expected: "string",
|
|
693
1048
|
value: input.functionName
|
|
694
|
-
}),
|
|
695
|
-
path: _path + ".
|
|
1049
|
+
}), (Array.isArray(input.dependsOn) || _report(_exceptionable, {
|
|
1050
|
+
path: _path + ".dependsOn",
|
|
1051
|
+
expected: "Array<IAutoBeTestScenarioApplication.IDependsOn>",
|
|
1052
|
+
value: input.dependsOn
|
|
1053
|
+
})) && input.dependsOn.map((elem, _index6) => ("object" === typeof elem && null !== elem || _report(_exceptionable, {
|
|
1054
|
+
path: _path + ".dependsOn[" + _index6 + "]",
|
|
1055
|
+
expected: "IAutoBeTestScenarioApplication.IDependsOn",
|
|
1056
|
+
value: elem
|
|
1057
|
+
})) && _vo4(elem, _path + ".dependsOn[" + _index6 + "]", true && _exceptionable) || _report(_exceptionable, {
|
|
1058
|
+
path: _path + ".dependsOn[" + _index6 + "]",
|
|
1059
|
+
expected: "IAutoBeTestScenarioApplication.IDependsOn",
|
|
1060
|
+
value: elem
|
|
1061
|
+
})).every(flag => flag) || _report(_exceptionable, {
|
|
1062
|
+
path: _path + ".dependsOn",
|
|
1063
|
+
expected: "Array<IAutoBeTestScenarioApplication.IDependsOn>",
|
|
1064
|
+
value: input.dependsOn
|
|
1065
|
+
})].every(flag => flag); const _vo4 = (input, _path, _exceptionable = true) => [("object" === typeof input.endpoint && null !== input.endpoint || _report(_exceptionable, {
|
|
1066
|
+
path: _path + ".endpoint",
|
|
1067
|
+
expected: "AutoBeOpenApi.IEndpoint",
|
|
1068
|
+
value: input.endpoint
|
|
1069
|
+
})) && _vo2(input.endpoint, _path + ".endpoint", true && _exceptionable) || _report(_exceptionable, {
|
|
1070
|
+
path: _path + ".endpoint",
|
|
1071
|
+
expected: "AutoBeOpenApi.IEndpoint",
|
|
1072
|
+
value: input.endpoint
|
|
1073
|
+
}), "string" === typeof input.purpose || _report(_exceptionable, {
|
|
1074
|
+
path: _path + ".purpose",
|
|
696
1075
|
expected: "string",
|
|
697
|
-
value: input.
|
|
1076
|
+
value: input.purpose
|
|
698
1077
|
})].every(flag => flag); const __is = input => "object" === typeof input && null !== input && _io0(input); let errors; let _report; return input => {
|
|
699
1078
|
if (false === __is(input)) {
|
|
700
1079
|
errors = [];
|
|
701
1080
|
_report = __typia_transform__validateReport._validateReport(errors);
|
|
702
1081
|
((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _report(true, {
|
|
703
1082
|
path: _path + "",
|
|
704
|
-
expected: "
|
|
1083
|
+
expected: "IAutoBeTestScenarioApplication.IProps",
|
|
705
1084
|
value: input
|
|
706
1085
|
})) && _vo0(input, _path + "", true) || _report(true, {
|
|
707
1086
|
path: _path + "",
|
|
708
|
-
expected: "
|
|
1087
|
+
expected: "IAutoBeTestScenarioApplication.IProps",
|
|
709
1088
|
value: input
|
|
710
1089
|
}))(input, "$input", true);
|
|
711
1090
|
const success = 0 === errors.length;
|