@autobe/agent 0.7.3 → 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 +249 -65
- package/lib/AutoBeAgent.js.map +1 -1
- package/lib/constants/AutoBeSystemPromptConstant.d.ts +5 -4
- 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 +1024 -663
- package/lib/index.mjs.map +1 -1
- package/lib/orchestrate/analyze/AutoBeAnalyzeAgent.js +7 -8
- package/lib/orchestrate/analyze/AutoBeAnalyzeAgent.js.map +1 -1
- package/lib/orchestrate/analyze/orchestrateAnalyze.js +2 -5
- package/lib/orchestrate/analyze/orchestrateAnalyze.js.map +1 -1
- package/lib/orchestrate/interface/orchestrateInterface.js +1 -1
- package/lib/orchestrate/interface/orchestrateInterface.js.map +1 -1
- package/lib/orchestrate/interface/orchestrateInterfaceComplement.js +6 -8
- package/lib/orchestrate/interface/orchestrateInterfaceComplement.js.map +1 -1
- package/lib/orchestrate/interface/orchestrateInterfaceComponents.js +9 -6
- package/lib/orchestrate/interface/orchestrateInterfaceComponents.js.map +1 -1
- package/lib/orchestrate/interface/orchestrateInterfaceEndpoints.js +3 -1
- package/lib/orchestrate/interface/orchestrateInterfaceEndpoints.js.map +1 -1
- package/lib/orchestrate/interface/orchestrateInterfaceOperations.js +5 -8
- package/lib/orchestrate/interface/orchestrateInterfaceOperations.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/orchestratePrismaComponent.js +5 -1
- package/lib/orchestrate/prisma/orchestratePrismaComponent.js.map +1 -1
- package/lib/orchestrate/prisma/orchestratePrismaCorrect.js +3 -6
- package/lib/orchestrate/prisma/orchestratePrismaCorrect.js.map +1 -1
- package/lib/orchestrate/prisma/orchestratePrismaSchema.js +11 -7
- package/lib/orchestrate/prisma/orchestratePrismaSchema.js.map +1 -1
- package/lib/orchestrate/prisma/transformPrismaCorrectHistories.js +1 -1
- package/lib/orchestrate/prisma/transformPrismaCorrectHistories.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 +90 -60
- package/lib/orchestrate/test/orchestrateTestCorrect.js.map +1 -1
- package/lib/orchestrate/test/orchestrateTestProgress.d.ts +3 -2
- package/lib/orchestrate/test/orchestrateTestProgress.js +75 -50
- package/lib/orchestrate/test/orchestrateTestProgress.js.map +1 -1
- package/lib/orchestrate/test/orchestrateTestScenario.d.ts +1 -1
- package/lib/orchestrate/test/orchestrateTestScenario.js +617 -208
- 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/enforceToolCall.d.ts +3 -0
- package/lib/utils/enforceToolCall.js +13 -0
- package/lib/utils/enforceToolCall.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 +5 -5
- package/src/AutoBeAgent.ts +252 -52
- package/src/constants/AutoBeSystemPromptConstant.ts +5 -4
- package/src/context/AutoBeContext.ts +7 -2
- package/src/factory/index.ts +0 -1
- package/src/orchestrate/analyze/AutoBeAnalyzeAgent.ts +5 -10
- package/src/orchestrate/analyze/orchestrateAnalyze.ts +2 -6
- package/src/orchestrate/interface/orchestrateInterface.ts +1 -1
- package/src/orchestrate/interface/orchestrateInterfaceComplement.ts +12 -11
- package/src/orchestrate/interface/orchestrateInterfaceComponents.ts +7 -6
- package/src/orchestrate/interface/orchestrateInterfaceEndpoints.ts +2 -1
- package/src/orchestrate/interface/orchestrateInterfaceOperations.ts +4 -9
- package/src/orchestrate/prisma/orchestratePrisma.ts +1 -0
- package/src/orchestrate/prisma/orchestratePrismaComponent.ts +4 -1
- package/src/orchestrate/prisma/orchestratePrismaCorrect.ts +6 -7
- package/src/orchestrate/prisma/orchestratePrismaSchema.ts +10 -7
- package/src/orchestrate/test/orchestrateTest.ts +6 -13
- package/src/orchestrate/test/orchestrateTestCorrect.ts +127 -78
- package/src/orchestrate/test/orchestrateTestProgress.ts +88 -47
- package/src/orchestrate/test/orchestrateTestScenario.ts +194 -105
- 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/enforceToolCall.ts +13 -0
- package/src/utils/types/BackoffOptions.ts +15 -0
|
@@ -49,105 +49,281 @@ 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
51
|
const typia_1 = __importDefault(require("typia"));
|
|
52
|
+
const uuid_1 = require("uuid");
|
|
52
53
|
const assertSchemaModel_1 = require("../../context/assertSchemaModel");
|
|
53
|
-
const
|
|
54
|
+
const divideArray_1 = require("../../utils/divideArray");
|
|
55
|
+
const enforceToolCall_1 = require("../../utils/enforceToolCall");
|
|
54
56
|
function orchestrateTestScenario(ctx) {
|
|
55
57
|
return __awaiter(this, void 0, void 0, function* () {
|
|
56
|
-
var _a, _b, _c, _d
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
responseBody: it.responseBody,
|
|
74
|
-
};
|
|
75
|
-
});
|
|
76
|
-
const start = new Date();
|
|
77
|
-
let completed = 0;
|
|
78
|
-
const scenarios = yield Promise.all(endpoints.map((endpoint, i, arr) => __awaiter(this, void 0, void 0, function* () {
|
|
79
|
-
var _a, _b;
|
|
80
|
-
const endponits = arr.filter((_el, j) => i !== j);
|
|
81
|
-
const rows = yield process(ctx, endpoint, endponits, files);
|
|
82
|
-
ctx.dispatch({
|
|
83
|
-
type: "testScenario",
|
|
84
|
-
scenarios: rows,
|
|
85
|
-
total: rows.flatMap((el) => el.scenarios).length,
|
|
86
|
-
step: (_b = (_a = ctx.state().test) === null || _a === void 0 ? void 0 : _a.step) !== null && _b !== void 0 ? _b : 0,
|
|
87
|
-
completed,
|
|
88
|
-
created_at: start.toISOString(),
|
|
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;
|
|
89
75
|
});
|
|
90
|
-
|
|
91
|
-
})));
|
|
76
|
+
} while (include.length > 0);
|
|
92
77
|
return {
|
|
93
78
|
type: "testScenario",
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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(),
|
|
99
91
|
};
|
|
100
92
|
});
|
|
101
93
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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
|
+
],
|
|
117
|
+
});
|
|
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.",
|
|
135
141
|
"",
|
|
136
142
|
"```json",
|
|
137
|
-
JSON.stringify(
|
|
143
|
+
JSON.stringify(operations.map((el) => ({
|
|
144
|
+
path: el.path,
|
|
145
|
+
method: el.method,
|
|
146
|
+
summary: el.summary,
|
|
147
|
+
}))),
|
|
138
148
|
"```",
|
|
139
|
-
].join("\n")
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
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
|
+
];
|
|
145
171
|
function createApplication(props) {
|
|
146
172
|
(0, assertSchemaModel_1.assertSchemaModel)(props.model);
|
|
147
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
|
+
};
|
|
148
324
|
return {
|
|
149
325
|
protocol: "class",
|
|
150
|
-
name: "Make
|
|
326
|
+
name: "Make test plans",
|
|
151
327
|
application,
|
|
152
328
|
execute: {
|
|
153
329
|
makeScenario: (next) => {
|
|
@@ -166,19 +342,19 @@ const claude = {
|
|
|
166
342
|
{
|
|
167
343
|
name: "makeScenario",
|
|
168
344
|
parameters: {
|
|
169
|
-
description: " Properties containing the endpoints and
|
|
345
|
+
description: " Properties containing the endpoints and test scenarios.\n\n------------------------------\n\nCurrent Type: {@link IAutoBeTestScenarioApplication.IProps}",
|
|
170
346
|
type: "object",
|
|
171
347
|
properties: {
|
|
172
|
-
|
|
173
|
-
title: "Array of
|
|
174
|
-
description: "Array of
|
|
348
|
+
scenarioGroups: {
|
|
349
|
+
title: "Array of test scenario groups",
|
|
350
|
+
description: "Array of test scenario groups.",
|
|
175
351
|
type: "array",
|
|
176
352
|
items: {
|
|
177
|
-
description: "Current Type: {@link
|
|
353
|
+
description: "Current Type: {@link IAutoBeTestScenarioApplication.IScenarioGroup}",
|
|
178
354
|
type: "object",
|
|
179
355
|
properties: {
|
|
180
356
|
endpoint: {
|
|
181
|
-
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.",
|
|
182
358
|
type: "object",
|
|
183
359
|
properties: {
|
|
184
360
|
path: {
|
|
@@ -214,26 +390,81 @@ const claude = {
|
|
|
214
390
|
]
|
|
215
391
|
},
|
|
216
392
|
scenarios: {
|
|
217
|
-
title: "
|
|
218
|
-
description: "
|
|
393
|
+
title: "Array of test scenarios",
|
|
394
|
+
description: "Array of test scenarios.",
|
|
219
395
|
type: "array",
|
|
220
396
|
items: {
|
|
221
|
-
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.",
|
|
222
398
|
type: "object",
|
|
223
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
|
+
},
|
|
224
404
|
functionName: {
|
|
225
405
|
title: "Descriptive function name derived from the user scenario",
|
|
226
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",
|
|
227
407
|
type: "string"
|
|
228
408
|
},
|
|
229
|
-
|
|
230
|
-
description: "
|
|
231
|
-
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
|
+
}
|
|
232
462
|
}
|
|
233
463
|
},
|
|
234
464
|
required: [
|
|
465
|
+
"draft",
|
|
235
466
|
"functionName",
|
|
236
|
-
"
|
|
467
|
+
"dependsOn"
|
|
237
468
|
]
|
|
238
469
|
}
|
|
239
470
|
}
|
|
@@ -246,28 +477,28 @@ const claude = {
|
|
|
246
477
|
}
|
|
247
478
|
},
|
|
248
479
|
required: [
|
|
249
|
-
"
|
|
480
|
+
"scenarioGroups"
|
|
250
481
|
],
|
|
251
482
|
additionalProperties: false,
|
|
252
483
|
$defs: {}
|
|
253
484
|
},
|
|
254
|
-
description: "Make
|
|
255
|
-
validate: (() => { const _io0 = input => Array.isArray(input.
|
|
256
|
-
path: _path + ".
|
|
257
|
-
expected: "Array<
|
|
258
|
-
value: input.
|
|
259
|
-
})) && input.
|
|
260
|
-
path: _path + ".
|
|
261
|
-
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",
|
|
262
493
|
value: elem
|
|
263
|
-
})) && _vo1(elem, _path + ".
|
|
264
|
-
path: _path + ".
|
|
265
|
-
expected: "
|
|
494
|
+
})) && _vo1(elem, _path + ".scenarioGroups[" + _index4 + "]", true && _exceptionable) || _report(_exceptionable, {
|
|
495
|
+
path: _path + ".scenarioGroups[" + _index4 + "]",
|
|
496
|
+
expected: "IAutoBeTestScenarioApplication.IScenarioGroup",
|
|
266
497
|
value: elem
|
|
267
498
|
})).every(flag => flag) || _report(_exceptionable, {
|
|
268
|
-
path: _path + ".
|
|
269
|
-
expected: "Array<
|
|
270
|
-
value: input.
|
|
499
|
+
path: _path + ".scenarioGroups",
|
|
500
|
+
expected: "Array<IAutoBeTestScenarioApplication.IScenarioGroup>",
|
|
501
|
+
value: input.scenarioGroups
|
|
271
502
|
})].every(flag => flag); const _vo1 = (input, _path, _exceptionable = true) => [("object" === typeof input.endpoint && null !== input.endpoint || _report(_exceptionable, {
|
|
272
503
|
path: _path + ".endpoint",
|
|
273
504
|
expected: "AutoBeOpenApi.IEndpoint",
|
|
@@ -278,19 +509,19 @@ const claude = {
|
|
|
278
509
|
value: input.endpoint
|
|
279
510
|
}), (Array.isArray(input.scenarios) || _report(_exceptionable, {
|
|
280
511
|
path: _path + ".scenarios",
|
|
281
|
-
expected: "Array<
|
|
512
|
+
expected: "Array<IAutoBeTestScenarioApplication.IScenario>",
|
|
282
513
|
value: input.scenarios
|
|
283
|
-
})) && input.scenarios.map((elem,
|
|
284
|
-
path: _path + ".scenarios[" +
|
|
285
|
-
expected: "
|
|
514
|
+
})) && input.scenarios.map((elem, _index5) => ("object" === typeof elem && null !== elem || _report(_exceptionable, {
|
|
515
|
+
path: _path + ".scenarios[" + _index5 + "]",
|
|
516
|
+
expected: "IAutoBeTestScenarioApplication.IScenario",
|
|
286
517
|
value: elem
|
|
287
|
-
})) && _vo3(elem, _path + ".scenarios[" +
|
|
288
|
-
path: _path + ".scenarios[" +
|
|
289
|
-
expected: "
|
|
518
|
+
})) && _vo3(elem, _path + ".scenarios[" + _index5 + "]", true && _exceptionable) || _report(_exceptionable, {
|
|
519
|
+
path: _path + ".scenarios[" + _index5 + "]",
|
|
520
|
+
expected: "IAutoBeTestScenarioApplication.IScenario",
|
|
290
521
|
value: elem
|
|
291
522
|
})).every(flag => flag) || _report(_exceptionable, {
|
|
292
523
|
path: _path + ".scenarios",
|
|
293
|
-
expected: "Array<
|
|
524
|
+
expected: "Array<IAutoBeTestScenarioApplication.IScenario>",
|
|
294
525
|
value: input.scenarios
|
|
295
526
|
})].every(flag => flag); const _vo2 = (input, _path, _exceptionable = true) => ["string" === typeof input.path || _report(_exceptionable, {
|
|
296
527
|
path: _path + ".path",
|
|
@@ -300,25 +531,53 @@ const claude = {
|
|
|
300
531
|
path: _path + ".method",
|
|
301
532
|
expected: "(\"delete\" | \"get\" | \"patch\" | \"post\" | \"put\")",
|
|
302
533
|
value: input.method
|
|
303
|
-
})].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, {
|
|
304
539
|
path: _path + ".functionName",
|
|
305
540
|
expected: "string",
|
|
306
541
|
value: input.functionName
|
|
307
|
-
}),
|
|
308
|
-
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",
|
|
309
568
|
expected: "string",
|
|
310
|
-
value: input.
|
|
569
|
+
value: input.purpose
|
|
311
570
|
})].every(flag => flag); const __is = input => "object" === typeof input && null !== input && _io0(input); let errors; let _report; return input => {
|
|
312
571
|
if (false === __is(input)) {
|
|
313
572
|
errors = [];
|
|
314
573
|
_report = __typia_transform__validateReport._validateReport(errors);
|
|
315
574
|
((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _report(true, {
|
|
316
575
|
path: _path + "",
|
|
317
|
-
expected: "
|
|
576
|
+
expected: "IAutoBeTestScenarioApplication.IProps",
|
|
318
577
|
value: input
|
|
319
578
|
})) && _vo0(input, _path + "", true) || _report(true, {
|
|
320
579
|
path: _path + "",
|
|
321
|
-
expected: "
|
|
580
|
+
expected: "IAutoBeTestScenarioApplication.IProps",
|
|
322
581
|
value: input
|
|
323
582
|
}))(input, "$input", true);
|
|
324
583
|
const success = 0 === errors.length;
|
|
@@ -351,19 +610,19 @@ const collection = {
|
|
|
351
610
|
{
|
|
352
611
|
name: "makeScenario",
|
|
353
612
|
parameters: {
|
|
354
|
-
description: " Properties containing the endpoints and
|
|
613
|
+
description: " Properties containing the endpoints and test scenarios.\n\n------------------------------\n\nCurrent Type: {@link IAutoBeTestScenarioApplication.IProps}",
|
|
355
614
|
type: "object",
|
|
356
615
|
properties: {
|
|
357
|
-
|
|
358
|
-
title: "Array of
|
|
359
|
-
description: "Array of
|
|
616
|
+
scenarioGroups: {
|
|
617
|
+
title: "Array of test scenario groups",
|
|
618
|
+
description: "Array of test scenario groups.",
|
|
360
619
|
type: "array",
|
|
361
620
|
items: {
|
|
362
|
-
description: "Current Type: {@link
|
|
621
|
+
description: "Current Type: {@link IAutoBeTestScenarioApplication.IScenarioGroup}",
|
|
363
622
|
type: "object",
|
|
364
623
|
properties: {
|
|
365
624
|
endpoint: {
|
|
366
|
-
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.",
|
|
367
626
|
type: "object",
|
|
368
627
|
properties: {
|
|
369
628
|
path: {
|
|
@@ -390,26 +649,72 @@ const collection = {
|
|
|
390
649
|
]
|
|
391
650
|
},
|
|
392
651
|
scenarios: {
|
|
393
|
-
title: "
|
|
394
|
-
description: "
|
|
652
|
+
title: "Array of test scenarios",
|
|
653
|
+
description: "Array of test scenarios.",
|
|
395
654
|
type: "array",
|
|
396
655
|
items: {
|
|
397
|
-
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.",
|
|
398
657
|
type: "object",
|
|
399
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
|
+
},
|
|
400
663
|
functionName: {
|
|
401
664
|
title: "Descriptive function name derived from the user scenario",
|
|
402
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",
|
|
403
666
|
type: "string"
|
|
404
667
|
},
|
|
405
|
-
|
|
406
|
-
description: "
|
|
407
|
-
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
|
+
}
|
|
408
712
|
}
|
|
409
713
|
},
|
|
410
714
|
required: [
|
|
715
|
+
"draft",
|
|
411
716
|
"functionName",
|
|
412
|
-
"
|
|
717
|
+
"dependsOn"
|
|
413
718
|
]
|
|
414
719
|
}
|
|
415
720
|
}
|
|
@@ -422,28 +727,28 @@ const collection = {
|
|
|
422
727
|
}
|
|
423
728
|
},
|
|
424
729
|
required: [
|
|
425
|
-
"
|
|
730
|
+
"scenarioGroups"
|
|
426
731
|
],
|
|
427
732
|
additionalProperties: false,
|
|
428
733
|
$defs: {}
|
|
429
734
|
},
|
|
430
|
-
description: "Make
|
|
431
|
-
validate: (() => { const _io0 = input => Array.isArray(input.
|
|
432
|
-
path: _path + ".
|
|
433
|
-
expected: "Array<
|
|
434
|
-
value: input.
|
|
435
|
-
})) && input.
|
|
436
|
-
path: _path + ".
|
|
437
|
-
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",
|
|
438
743
|
value: elem
|
|
439
|
-
})) && _vo1(elem, _path + ".
|
|
440
|
-
path: _path + ".
|
|
441
|
-
expected: "
|
|
744
|
+
})) && _vo1(elem, _path + ".scenarioGroups[" + _index4 + "]", true && _exceptionable) || _report(_exceptionable, {
|
|
745
|
+
path: _path + ".scenarioGroups[" + _index4 + "]",
|
|
746
|
+
expected: "IAutoBeTestScenarioApplication.IScenarioGroup",
|
|
442
747
|
value: elem
|
|
443
748
|
})).every(flag => flag) || _report(_exceptionable, {
|
|
444
|
-
path: _path + ".
|
|
445
|
-
expected: "Array<
|
|
446
|
-
value: input.
|
|
749
|
+
path: _path + ".scenarioGroups",
|
|
750
|
+
expected: "Array<IAutoBeTestScenarioApplication.IScenarioGroup>",
|
|
751
|
+
value: input.scenarioGroups
|
|
447
752
|
})].every(flag => flag); const _vo1 = (input, _path, _exceptionable = true) => [("object" === typeof input.endpoint && null !== input.endpoint || _report(_exceptionable, {
|
|
448
753
|
path: _path + ".endpoint",
|
|
449
754
|
expected: "AutoBeOpenApi.IEndpoint",
|
|
@@ -454,19 +759,19 @@ const collection = {
|
|
|
454
759
|
value: input.endpoint
|
|
455
760
|
}), (Array.isArray(input.scenarios) || _report(_exceptionable, {
|
|
456
761
|
path: _path + ".scenarios",
|
|
457
|
-
expected: "Array<
|
|
762
|
+
expected: "Array<IAutoBeTestScenarioApplication.IScenario>",
|
|
458
763
|
value: input.scenarios
|
|
459
|
-
})) && input.scenarios.map((elem,
|
|
460
|
-
path: _path + ".scenarios[" +
|
|
461
|
-
expected: "
|
|
764
|
+
})) && input.scenarios.map((elem, _index5) => ("object" === typeof elem && null !== elem || _report(_exceptionable, {
|
|
765
|
+
path: _path + ".scenarios[" + _index5 + "]",
|
|
766
|
+
expected: "IAutoBeTestScenarioApplication.IScenario",
|
|
462
767
|
value: elem
|
|
463
|
-
})) && _vo3(elem, _path + ".scenarios[" +
|
|
464
|
-
path: _path + ".scenarios[" +
|
|
465
|
-
expected: "
|
|
768
|
+
})) && _vo3(elem, _path + ".scenarios[" + _index5 + "]", true && _exceptionable) || _report(_exceptionable, {
|
|
769
|
+
path: _path + ".scenarios[" + _index5 + "]",
|
|
770
|
+
expected: "IAutoBeTestScenarioApplication.IScenario",
|
|
466
771
|
value: elem
|
|
467
772
|
})).every(flag => flag) || _report(_exceptionable, {
|
|
468
773
|
path: _path + ".scenarios",
|
|
469
|
-
expected: "Array<
|
|
774
|
+
expected: "Array<IAutoBeTestScenarioApplication.IScenario>",
|
|
470
775
|
value: input.scenarios
|
|
471
776
|
})].every(flag => flag); const _vo2 = (input, _path, _exceptionable = true) => ["string" === typeof input.path || _report(_exceptionable, {
|
|
472
777
|
path: _path + ".path",
|
|
@@ -476,25 +781,53 @@ const collection = {
|
|
|
476
781
|
path: _path + ".method",
|
|
477
782
|
expected: "(\"delete\" | \"get\" | \"patch\" | \"post\" | \"put\")",
|
|
478
783
|
value: input.method
|
|
479
|
-
})].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, {
|
|
480
789
|
path: _path + ".functionName",
|
|
481
790
|
expected: "string",
|
|
482
791
|
value: input.functionName
|
|
483
|
-
}),
|
|
484
|
-
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",
|
|
485
818
|
expected: "string",
|
|
486
|
-
value: input.
|
|
819
|
+
value: input.purpose
|
|
487
820
|
})].every(flag => flag); const __is = input => "object" === typeof input && null !== input && _io0(input); let errors; let _report; return input => {
|
|
488
821
|
if (false === __is(input)) {
|
|
489
822
|
errors = [];
|
|
490
823
|
_report = __typia_transform__validateReport._validateReport(errors);
|
|
491
824
|
((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _report(true, {
|
|
492
825
|
path: _path + "",
|
|
493
|
-
expected: "
|
|
826
|
+
expected: "IAutoBeTestScenarioApplication.IProps",
|
|
494
827
|
value: input
|
|
495
828
|
})) && _vo0(input, _path + "", true) || _report(true, {
|
|
496
829
|
path: _path + "",
|
|
497
|
-
expected: "
|
|
830
|
+
expected: "IAutoBeTestScenarioApplication.IProps",
|
|
498
831
|
value: input
|
|
499
832
|
}))(input, "$input", true);
|
|
500
833
|
const success = 0 === errors.length;
|
|
@@ -532,7 +865,7 @@ const collection = {
|
|
|
532
865
|
parameters: {
|
|
533
866
|
type: "object",
|
|
534
867
|
properties: {
|
|
535
|
-
|
|
868
|
+
scenarioGroups: {
|
|
536
869
|
type: "array",
|
|
537
870
|
items: {
|
|
538
871
|
type: "object",
|
|
@@ -562,7 +895,7 @@ const collection = {
|
|
|
562
895
|
"path",
|
|
563
896
|
"method"
|
|
564
897
|
],
|
|
565
|
-
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.",
|
|
566
899
|
additionalProperties: false
|
|
567
900
|
},
|
|
568
901
|
scenarios: {
|
|
@@ -570,61 +903,109 @@ const collection = {
|
|
|
570
903
|
items: {
|
|
571
904
|
type: "object",
|
|
572
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
|
+
},
|
|
573
910
|
functionName: {
|
|
574
911
|
type: "string",
|
|
575
912
|
title: "Descriptive function name derived from the user scenario",
|
|
576
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"
|
|
577
914
|
},
|
|
578
|
-
|
|
579
|
-
type: "
|
|
580
|
-
|
|
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."
|
|
581
961
|
}
|
|
582
962
|
},
|
|
583
963
|
required: [
|
|
964
|
+
"draft",
|
|
584
965
|
"functionName",
|
|
585
|
-
"
|
|
966
|
+
"dependsOn"
|
|
586
967
|
],
|
|
587
|
-
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.",
|
|
588
969
|
additionalProperties: false
|
|
589
970
|
},
|
|
590
|
-
title: "
|
|
591
|
-
description: "
|
|
971
|
+
title: "Array of test scenarios",
|
|
972
|
+
description: "Array of test scenarios."
|
|
592
973
|
}
|
|
593
974
|
},
|
|
594
975
|
required: [
|
|
595
976
|
"endpoint",
|
|
596
977
|
"scenarios"
|
|
597
978
|
],
|
|
598
|
-
description: "Current Type: {@link
|
|
979
|
+
description: "Current Type: {@link IAutoBeTestScenarioApplication.IScenarioGroup}",
|
|
599
980
|
additionalProperties: false
|
|
600
981
|
},
|
|
601
|
-
title: "Array of
|
|
602
|
-
description: "Array of
|
|
982
|
+
title: "Array of test scenario groups",
|
|
983
|
+
description: "Array of test scenario groups."
|
|
603
984
|
}
|
|
604
985
|
},
|
|
605
986
|
required: [
|
|
606
|
-
"
|
|
987
|
+
"scenarioGroups"
|
|
607
988
|
],
|
|
608
|
-
description: " Properties containing the endpoints and
|
|
989
|
+
description: " Properties containing the endpoints and test scenarios.\n\n------------------------------\n\nCurrent Type: {@link IAutoBeTestScenarioApplication.IProps}",
|
|
609
990
|
additionalProperties: false
|
|
610
991
|
},
|
|
611
|
-
description: "Make
|
|
612
|
-
validate: (() => { const _io0 = input => Array.isArray(input.
|
|
613
|
-
path: _path + ".
|
|
614
|
-
expected: "Array<
|
|
615
|
-
value: input.
|
|
616
|
-
})) && input.
|
|
617
|
-
path: _path + ".
|
|
618
|
-
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",
|
|
619
1000
|
value: elem
|
|
620
|
-
})) && _vo1(elem, _path + ".
|
|
621
|
-
path: _path + ".
|
|
622
|
-
expected: "
|
|
1001
|
+
})) && _vo1(elem, _path + ".scenarioGroups[" + _index4 + "]", true && _exceptionable) || _report(_exceptionable, {
|
|
1002
|
+
path: _path + ".scenarioGroups[" + _index4 + "]",
|
|
1003
|
+
expected: "IAutoBeTestScenarioApplication.IScenarioGroup",
|
|
623
1004
|
value: elem
|
|
624
1005
|
})).every(flag => flag) || _report(_exceptionable, {
|
|
625
|
-
path: _path + ".
|
|
626
|
-
expected: "Array<
|
|
627
|
-
value: input.
|
|
1006
|
+
path: _path + ".scenarioGroups",
|
|
1007
|
+
expected: "Array<IAutoBeTestScenarioApplication.IScenarioGroup>",
|
|
1008
|
+
value: input.scenarioGroups
|
|
628
1009
|
})].every(flag => flag); const _vo1 = (input, _path, _exceptionable = true) => [("object" === typeof input.endpoint && null !== input.endpoint || _report(_exceptionable, {
|
|
629
1010
|
path: _path + ".endpoint",
|
|
630
1011
|
expected: "AutoBeOpenApi.IEndpoint",
|
|
@@ -635,19 +1016,19 @@ const collection = {
|
|
|
635
1016
|
value: input.endpoint
|
|
636
1017
|
}), (Array.isArray(input.scenarios) || _report(_exceptionable, {
|
|
637
1018
|
path: _path + ".scenarios",
|
|
638
|
-
expected: "Array<
|
|
1019
|
+
expected: "Array<IAutoBeTestScenarioApplication.IScenario>",
|
|
639
1020
|
value: input.scenarios
|
|
640
|
-
})) && input.scenarios.map((elem,
|
|
641
|
-
path: _path + ".scenarios[" +
|
|
642
|
-
expected: "
|
|
1021
|
+
})) && input.scenarios.map((elem, _index5) => ("object" === typeof elem && null !== elem || _report(_exceptionable, {
|
|
1022
|
+
path: _path + ".scenarios[" + _index5 + "]",
|
|
1023
|
+
expected: "IAutoBeTestScenarioApplication.IScenario",
|
|
643
1024
|
value: elem
|
|
644
|
-
})) && _vo3(elem, _path + ".scenarios[" +
|
|
645
|
-
path: _path + ".scenarios[" +
|
|
646
|
-
expected: "
|
|
1025
|
+
})) && _vo3(elem, _path + ".scenarios[" + _index5 + "]", true && _exceptionable) || _report(_exceptionable, {
|
|
1026
|
+
path: _path + ".scenarios[" + _index5 + "]",
|
|
1027
|
+
expected: "IAutoBeTestScenarioApplication.IScenario",
|
|
647
1028
|
value: elem
|
|
648
1029
|
})).every(flag => flag) || _report(_exceptionable, {
|
|
649
1030
|
path: _path + ".scenarios",
|
|
650
|
-
expected: "Array<
|
|
1031
|
+
expected: "Array<IAutoBeTestScenarioApplication.IScenario>",
|
|
651
1032
|
value: input.scenarios
|
|
652
1033
|
})].every(flag => flag); const _vo2 = (input, _path, _exceptionable = true) => ["string" === typeof input.path || _report(_exceptionable, {
|
|
653
1034
|
path: _path + ".path",
|
|
@@ -657,25 +1038,53 @@ const collection = {
|
|
|
657
1038
|
path: _path + ".method",
|
|
658
1039
|
expected: "(\"delete\" | \"get\" | \"patch\" | \"post\" | \"put\")",
|
|
659
1040
|
value: input.method
|
|
660
|
-
})].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, {
|
|
661
1046
|
path: _path + ".functionName",
|
|
662
1047
|
expected: "string",
|
|
663
1048
|
value: input.functionName
|
|
664
|
-
}),
|
|
665
|
-
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",
|
|
666
1075
|
expected: "string",
|
|
667
|
-
value: input.
|
|
1076
|
+
value: input.purpose
|
|
668
1077
|
})].every(flag => flag); const __is = input => "object" === typeof input && null !== input && _io0(input); let errors; let _report; return input => {
|
|
669
1078
|
if (false === __is(input)) {
|
|
670
1079
|
errors = [];
|
|
671
1080
|
_report = __typia_transform__validateReport._validateReport(errors);
|
|
672
1081
|
((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _report(true, {
|
|
673
1082
|
path: _path + "",
|
|
674
|
-
expected: "
|
|
1083
|
+
expected: "IAutoBeTestScenarioApplication.IProps",
|
|
675
1084
|
value: input
|
|
676
1085
|
})) && _vo0(input, _path + "", true) || _report(true, {
|
|
677
1086
|
path: _path + "",
|
|
678
|
-
expected: "
|
|
1087
|
+
expected: "IAutoBeTestScenarioApplication.IProps",
|
|
679
1088
|
value: input
|
|
680
1089
|
}))(input, "$input", true);
|
|
681
1090
|
const success = 0 === errors.length;
|