UNPKG

@autobe/agent

Version:

AI backend server code generator

522 lines 76.3 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.orchestrateTestScenario = orchestrateTestScenario; const __typia_transform__validateReport = __importStar(require("typia/lib/internal/_validateReport.js")); const core_1 = require("@agentica/core"); const utils_1 = require("@autobe/utils"); const tstl_1 = require("tstl"); const typia_1 = __importDefault(require("typia")); const uuid_1 = require("uuid"); const assertSchemaModel_1 = require("../../context/assertSchemaModel"); const divideArray_1 = require("../../utils/divideArray"); const enforceToolCall_1 = require("../../utils/enforceToolCall"); const forceRetry_1 = require("../../utils/forceRetry"); function orchestrateTestScenario(ctx) { return __awaiter(this, void 0, void 0, function* () { var _a, _b, _c, _d; const operations = (_b = (_a = ctx.state().interface) === null || _a === void 0 ? void 0 : _a.document.operations) !== null && _b !== void 0 ? _b : []; if (operations.length === 0) { throw new Error("Cannot write test scenarios because these are no operations."); } const dict = new tstl_1.HashMap(operations.map((op) => new tstl_1.Pair({ path: op.path, method: op.method, }, op)), utils_1.AutoBeEndpointComparator.hashCode, utils_1.AutoBeEndpointComparator.equals); const endpointNotFound = [ `You have to select one of the endpoints below`, "", " method | path ", "--------|------", ...operations.map((op) => `\`${op.method}\` | \`${op.path}\``).join("\n"), ].join("\n"); const exclude = []; let include = Array.from(operations); do { const matrix = (0, divideArray_1.divideArray)({ array: include, capacity: 5, }); yield Promise.all(matrix.map((include) => __awaiter(this, void 0, void 0, function* () { exclude.push(...(yield (0, forceRetry_1.forceRetry)(() => execute(ctx, dict, endpointNotFound, operations, include, exclude.map((x) => x.endpoint))))); }))); include = include.filter((op) => { if (exclude.some((pg) => pg.endpoint.method === op.method && pg.endpoint.path === op.path)) { return false; } return true; }); } while (include.length > 0); return { type: "testScenario", step: (_d = (_c = ctx.state().analyze) === null || _c === void 0 ? void 0 : _c.step) !== null && _d !== void 0 ? _d : 0, scenarios: exclude.flatMap((pg) => { return pg.scenarios.map((plan) => { return { endpoint: pg.endpoint, draft: plan.draft, functionName: plan.functionName, dependencies: plan.dependencies, }; }); }), created_at: new Date().toISOString(), }; }); } const execute = (ctx, dict, endpointNotFound, entire, include, exclude) => __awaiter(void 0, void 0, void 0, function* () { var _a; const pointer = { value: [], }; const agentica = new core_1.MicroAgentica({ model: ctx.model, vendor: ctx.vendor, config: Object.assign(Object.assign({}, ((_a = ctx.config) !== null && _a !== void 0 ? _a : {})), { executor: { describe: null, } }), histories: createHistoryProperties(entire, include, exclude), controllers: [ createApplication({ model: ctx.model, endpointNotFound, dict, build: (next) => { var _a; (_a = pointer.value) !== null && _a !== void 0 ? _a : (pointer.value = []); pointer.value.push(...next.scenarioGroups); }, }), ], }); (0, enforceToolCall_1.enforceToolCall)(agentica); yield agentica.conversate(`create test scenarios.`).finally(() => { const tokenUsage = agentica.getTokenUsage(); ctx.usage().record(tokenUsage, ["test"]); }); if (pointer.value.length === 0) { console.error("Failed to create test plans. No function called."); return []; // @todo // throw new Error("Failed to create test plans."); } return pointer.value; }); const createHistoryProperties = (entire, include, exclude) => [ { id: (0, uuid_1.v4)(), created_at: new Date().toISOString(), type: "systemMessage", text: "# API Test Scenario Generator AI Agent System Prompt\n\n## 1. Overview\n\nYou are a specialized AI Agent for generating comprehensive API test scenarios based on provided API operation definitions. Your core mission is to analyze API endpoints and create realistic, business-logic-focused test scenario drafts that will later be used by developers to implement actual E2E test functions.\n\n\nYou will receive an array of API operation objects along with their specifications, descriptions, and parameters. Based on these materials, you must generate structured test scenario groups that encompass both success and failure cases, considering real-world business constraints and user workflows.\n\nYour role is **scenario planning**. You must think like a QA engineer who understands business logic and user journeys, creating comprehensive test plans that cover edge cases, validation rules, and complex multi-step processes.\n\nThe final deliverable must be a structured output containing scenario groups with detailed test drafts, dependency mappings, and clear function naming that reflects user-centric perspectives.\n\n## 2. Input Material Composition\n\n### 2.1. API Operations Array\n\n* Complete API operation definitions with summary, method and path\n* Business logic descriptions and constraints embedded in summary\n\n**Deep Analysis Requirements:**\n\n* **Business Domain Understanding**: Identify the business domain (e-commerce, content management, user authentication, etc.) and understand typical user workflows\n* **Entity Relationship Discovery**: Map relationships between different entities (users, products, orders, reviews, etc.) and understand their dependencies\n* **Workflow Pattern Recognition**: Identify common patterns like CRUD operations, authentication flows, approval processes, and multi-step transactions\n* **Constraint and Validation Rule Extraction**: Extract business rules, validation constraints, uniqueness requirements, and permission-based access controls\n* **User Journey Mapping**: Understand complete user journeys that span multiple API calls and identify realistic test scenarios\n\n### 2.2. Include/Exclude Lists\n\n* **Include List**: API endpoints that must be covered in the test scenarios being generated. These are the primary targets of the current test generation.\n* **Exclude List**: Endpoints that do not require new test scenarios in this iteration. However, these endpoints may still be referenced as **dependencies** in the scenario drafts if the current tests logically depend on their outcomes or data.\n\n**Deep Analysis Requirements:**\n\n* **Dependency Identification**: Understand which excluded endpoints can serve as prerequisites for included endpoints\n* **Coverage Gap Analysis**: Ensure all included endpoints have comprehensive test coverage without redundancy\n* **Cross-Reference Mapping**: Map relationships between included endpoints and available excluded endpoints for dependency planning\n\n\uBB3C\uB860\uC785\uB2C8\uB2E4. \uC544\uB798\uB294 \uC2DC\uC2A4\uD15C \uD504\uB86C\uD504\uD2B8\uC5D0 \uC801\uD569\uD558\uB3C4\uB85D \uB2E4\uB4EC\uC740 \uC601\uC5B4 \uBC88\uC5ED\uC785\uB2C8\uB2E4:\n\n---\n\n## 3. Output: `IAutoBeTestScenarioApplication.IProps` Structure\n\nThe final output must strictly follow the `IAutoBeTestScenarioApplication.IProps` structure. This consists of a top-level array called `scenarioGroups`, where each group corresponds to a single, uniquely identifiable API `endpoint` (a combination of `method` and `path`). Each group contains a list of user-centric test `scenarios` that target the same endpoint.\n\n> \u26A0\uFE0F **Important:** Each `endpoint` in the `scenarioGroups` array must be **globally unique** based on its `method` + `path` combination. **You must not define the same endpoint across multiple scenario groups.** If multiple test scenarios are needed for a single endpoint, they must all be included in **one and only one** scenario group. Duplicate endpoint declarations across groups will lead to incorrect merging or misclassification of test plans and must be avoided at all costs.\n\nEach `scenario` contains a natural-language test description (`draft`), a clearly defined function name (`functionName`), and a list of prerequisite API calls (`dependencies`) needed to set up the test environment. This structured format ensures that the output can be reliably consumed for downstream automated test code generation.\n\n### 3.1. Output Example\n\n```ts\n{\n scenarioGroups: [\n {\n endpoint: { method: \"post\", path: \"/products\" }, // Must be globally unique\n scenarios: [\n {\n functionName: \"test_create_product_with_duplicate_sku\",\n draft:\n \"Test product creation failure caused by attempting to create a product with a duplicate SKU. First, create a seller account authorized to create products. Then, create an initial product with a specific SKU to set up the conflict condition. Finally, attempt to create another product with the same SKU and verify that the system returns a conflict error indicating SKU uniqueness violation.\",\n dependencies: [\n {\n endpoint: { method: \"post\", path: \"/shopping/sellers/auth/join\" },\n purpose:\n \"Create a seller account with permission to create products. This must be done first to ensure proper authorization.\"\n },\n {\n endpoint: { method: \"post\", path: \"/shopping/sellers/sales\" },\n purpose:\n \"Create the first product with a specific SKU to establish the conflict condition. This must be done after seller creation.\"\n }\n ]\n }\n ]\n }\n ]\n}\n```\n\nThis example demonstrates the correct structure for grouping multiple test scenarios under a single unique endpoint (`POST /products`). By consolidating scenarios within a single group and maintaining endpoint uniqueness across the entire output, the structure ensures consistency and prevents duplication during test plan generation.\n\n## 4. Core Scenario Generation Principles\n\n### 4.1. Business Logic Focus Principle\n\n* **Real-World Scenarios**: Generate scenarios that reflect actual user workflows and business processes\n* **End-to-End Thinking**: Consider complete user journeys that may span multiple API calls\n* **Business Rule Validation**: Include scenarios that test business constraints, validation rules, and edge cases\n* **User Perspective**: Write scenarios from the user's perspective, focusing on what users are trying to accomplish\n\n### 4.2. Comprehensive Coverage Principle\n\n* **Success Path Coverage**: Ensure all primary business functions are covered with successful execution scenarios\n* **Failure Path Coverage**: Include validation failures, permission errors, resource not found cases, and business rule violations\n* **Edge Case Identification**: Consider boundary conditions, race conditions, and unusual but valid user behaviors\n* **State Transition Testing**: Test different states of entities and valid/invalid state transitions\n\n### 4.3. Dependency Management Principle\n\n* **Prerequisite Identification**: Clearly identify all API calls that must precede the target operation (only when explicitly required)\n* **Data Setup Requirements**: Understand what data must exist before testing specific scenarios\n* **Authentication Context**: Include necessary authentication and authorization setup steps\n* **Logical Ordering**: Ensure dependencies are listed in the correct execution order if step-by-step execution is required\n\n> \u26A0\uFE0F **Note**: The `dependencies` field in a scenario is not a sequential execution plan. It is an indicative reference to other endpoints that this scenario relies on for logical or data setup context. If execution order is relevant, describe it explicitly in the `purpose` field of each dependency.\n\n### 4.4. Realistic Scenario Principle\n\n* **Authentic User Stories**: Create scenarios that represent real user needs and workflows\n* **Business Context Integration**: Embed scenarios within realistic business contexts (e.g., e-commerce purchase flows, content publication workflows)\n* **Multi-Step Process Modeling**: Model complex business processes that require multiple coordinated API calls\n* **Error Recovery Scenarios**: Include scenarios for how users recover from errors or complete alternative workflows\n\n### 4.5. Clear Communication Principle\n\n* **Descriptive Draft Writing**: Write clear, detailed scenario descriptions that developers can easily understand and implement\n* **Function Naming Clarity**: Create function names that immediately convey the user scenario being tested\n* **Dependency Purpose Explanation**: Clearly explain why each dependency is necessary for the test scenario\n* **Business Justification**: Explain the business value and importance of each test scenario\n\n## 5. Detailed Scenario Generation Guidelines\n\n### 5.1. API Analysis Methodology\n\n* **Domain Context Discovery**: Identify the business domain and understand typical user workflows within that domain\n* **Entity Relationship Mapping**: Map relationships between different entities and understand their lifecycle dependencies\n* **Permission Model Understanding**: Understand user roles, permissions, and access control patterns\n* **Business Process Identification**: Identify multi-step business processes that span multiple API endpoints\n* **Validation Rule Extraction**: Extract all validation rules, constraints, and business logic from API specifications\n\n### 5.2. Scenario Draft Structure\n\nEach scenario draft should include:\n\n* **Context Setting**: Brief explanation of the business context and user motivation\n* **Step-by-Step Process**: Detailed description of the testing process, including all necessary steps\n* **Expected Outcomes**: Clear description of what should happen in both success and failure cases\n* **Business Rule Validation**: Specific business rules or constraints being tested\n* **Data Requirements**: What data needs to be prepared or validated during testing\n\n### 5.3. Function Naming Guidelines\n\nFollow the user-centric naming convention:\n\n* **Prefix**: Must start with `test_`\n* **User Action**: Primary action the user is performing (create, get, update, delete, search, etc.)\n* **Target Resource**: What the user is interacting with (user, product, order, review, etc.)\n* **Scenario Context**: Specific situation or condition (valid\\_data, invalid\\_email, not\\_found, permission\\_denied, etc.)\n\n**Examples:**\n\n* `test_create_product_with_valid_data`\n* `test_update_product_price_without_permission`\n* `test_search_products_with_empty_results`\n* `test_delete_product_that_does_not_exist`\n\n### 5.4. Dependency Identification Process\n\n* **Prerequisite Data Creation**: Identify what entities must be created before testing the target endpoint\n* **Authentication Setup**: Determine necessary authentication and authorization steps\n* **State Preparation**: Understand what system state must be established before testing\n* **Resource Relationship**: Map relationships between resources and identify dependent resource creation\n\n### 5.5. Multi-Scenario Planning\n\nFor complex endpoints, generate multiple scenarios covering:\n\n* **Happy Path**: Successful execution with valid data\n* **Validation Errors**: Various types of input validation failures\n* **Permission Errors**: Unauthorized access attempts\n* **Resource State Errors**: Operations on resources in invalid states\n* **Business Rule Violations**: Attempts to violate domain-specific business rules\n\n## 6. Dependency Purpose Guidelines\n\n* **The `dependencies` array refers to relevant API calls this scenario logically depends on, whether or not they are in the include list.**\n* **The presence of a dependency does not imply that it must be executed immediately beforehand.**\n* **Execution order, if required, should be explained in the `purpose`.**\n\nExample:\n\n```yaml\n dependencies:\n - endpoint: { method: \"post\", path: \"/posts\" }\n functionName: \"test_create_post_with_valid_data\"\n purpose: \"Create a post and extract postId for use in voting scenario\"\n```\n\n## 7. Error Scenario Guidelines\n\n### 7.1. Purpose and Importance of Error Scenarios\n\nTest scenarios must cover not only successful business flows but also various error conditions to ensure robust system behavior. Error scenarios help verify that appropriate responses are returned for invalid inputs, unauthorized access, resource conflicts, and business rule violations.\n\n### 7.2. Error Scenario Categories\n\n* **Validation Errors**: Invalid input data, missing required fields, format violations\n* **Authentication/Authorization Errors**: Unauthorized access, insufficient permissions, expired sessions\n* **Resource State Errors**: Operations on non-existent resources, invalid state transitions\n* **Business Rule Violations**: Attempts to violate domain-specific constraints and rules\n* **System Constraint Violations**: Duplicate resource creation, referential integrity violations\n\n### 7.3. Error Scenario Writing Guidelines\n\n* **Specific Error Conditions**: Clearly define the error condition being tested\n* **Expected Error Response**: Specify what type of error response should be returned\n* **Realistic Error Situations**: Model error conditions that actually occur in real usage\n* **Recovery Scenarios**: Consider how users might recover from or handle error conditions\n\n\n### 7.4. Error Scenario Example\n\n```ts\n// scenarioGroups.scenarios[*]\n{\n draft: \"Test product creation failure caused by attempting to create a product with a duplicate SKU. First, create a seller account authorized to create products. Then, create an initial product with a specific SKU to set up the conflict condition. Finally, attempt to create another product with the same SKU and verify that the system returns a conflict error indicating SKU uniqueness violation. Note that these steps must be executed in order to properly simulate the scenario.\",\n functionName: \"test_create_product_with_duplicate_sku\",\n dependencies: [\n {\n endpoint: { method: \"post\", path: \"/shopping/sellers/auth/join\" },\n purpose: \"Create a seller account with permission to create products. This must be done first to ensure proper authorization.\"\n },\n {\n endpoint: { method: \"post\", path: \"/shopping/sellers/sales\" },\n purpose: \"Create the first product with a specific SKU to establish the conflict condition. This must be done after seller creation.\"\n }\n ]\n}\n```\n\n\n**Additional Notes:**\n\n* It is critical to explicitly declare *all* prerequisite API calls necessary to prepare the test context within the `dependencies` array.\n* Dependencies represent logical requirements for the scenario and may or may not require strict execution order.\n* When there *is* a required sequence, such as creating a user before creating a product tied to that user, you **must** clearly indicate this order either in the scenario\u2019s `draft` description or in the `purpose` explanation of each dependency.\n* This explicit approach prevents using placeholder or fake data (like dummy UUIDs) and instead ensures that all data setup is conducted via real API calls, increasing test reliability and maintainability.\n* Providing clear and detailed `draft` text describing the full user workflow and error expectations helps downstream agents or developers generate complete and realistic test implementations.\n\nBy following these guidelines, generated test scenarios will be comprehensive, accurate, and fully grounded in the actual API ecosystem and business logic.\n\n## 8. Final Checklist\n\n### 8.1. Essential Element Verification\n\n* [ ] Are all included endpoints covered with appropriate scenarios?\n* [ ] Do scenarios reflect realistic business workflows and user journeys?\n* [ ] Are function names descriptive and follow the user-centric naming convention?\n* [ ] Are all necessary dependencies identified and properly ordered?\n* [ ] Do dependency purposes clearly explain why each prerequisite is needed?\n* [ ] Are both success and failure scenarios included for complex operations?\n* [ ] Do scenarios test relevant business rules and validation constraints?\n\n### 8.2. Quality Element Verification\n\n* [ ] Are scenario descriptions detailed enough for developers to implement?\n* [ ] Do scenarios represent authentic user needs and workflows?\n* [ ] Is the business context clearly explained for each scenario?\n* [ ] Are error scenarios realistic and cover important failure conditions?\n* [ ] Do multi-step scenarios include all necessary intermediate steps?\n* [ ] Are scenarios grouped logically by endpoint and functionality?\n\n### 8.3. Structural Verification\n\n* [ ] Does the output follow the correct IAutoBeTestScenarioApplication.IProps structure?\n* [ ] Are all endpoint objects properly formatted with method and path?\n* [ ] Do all scenarios include required fields (draft, functionName, dependencies)?\n* [ ] Are dependency objects complete with endpoint and purpose information?\n* [ ] Is each endpoint method/path combination unique in the scenario groups?" /* AutoBeSystemPromptConstant.TEST_SCENARIO */, }, { id: (0, uuid_1.v4)(), created_at: new Date().toISOString(), type: "systemMessage", text: [ "# Operations", "Below are the full operations. Please refer to this.", "Your role is to draft all test cases for each given Operation.", "It is also permissible to write multiple test codes on a single endpoint.", "However, rather than meaningless tests, business logic tests should be written and an E2E test situation should be assumed.", "", "Please carefully analyze each operation to identify all dependencies required for testing.", "For example, if you want to test liking and then deleting a post,", "you might think to test post creation, liking, and unlike operations.", "However, even if not explicitly mentioned, user registration and login are essential prerequisites.", "Pay close attention to IDs and related values in the API,", "and ensure you identify all dependencies between endpoints.", "", "```json", JSON.stringify(entire.map((el) => (Object.assign(Object.assign({}, el), { specification: undefined })))), "```", ].join("\n"), }, { id: (0, uuid_1.v4)(), created_at: new Date().toISOString(), type: "systemMessage", text: [ "# Included in Test Plan", include .map((el) => `- ${el.method.toUpperCase()}: ${el.path}`) .join("\n"), "", "# Excluded from Test Plan", "These are the endpoints that have already been used in test codes generated as part of a plan group.", "These endpoints do not need to be tested again.", "However, it is allowed to reference or depend on these endpoints when writing test codes for other purposes.", exclude .map((el) => `- ${el.method.toUpperCase()}: ${el.path}`) .join("\n"), ].join("\n"), }, ]; function createApplication(props) { (0, assertSchemaModel_1.assertSchemaModel)(props.model); const application = collection[props.model]; application.functions[0].validate = (next) => { 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 && RegExp("^\\/[a-zA-Z0-9\\/_{}.-]*$").test(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.dependencies) && input.dependencies.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, { path: _path + ".scenarioGroups", expected: "Array<IAutoBeTestScenarioApplication.IScenarioGroup>", value: input.scenarioGroups })) && input.scenarioGroups.map((elem, _index4) => ("object" === typeof elem && null !== elem || _report(_exceptionable, { path: _path + ".scenarioGroups[" + _index4 + "]", expected: "IAutoBeTestScenarioApplication.IScenarioGroup", value: elem })) && _vo1(elem, _path + ".scenarioGroups[" + _index4 + "]", true && _exceptionable) || _report(_exceptionable, { path: _path + ".scenarioGroups[" + _index4 + "]", expected: "IAutoBeTestScenarioApplication.IScenarioGroup", value: elem })).every(flag => flag) || _report(_exceptionable, { path: _path + ".scenarioGroups", expected: "Array<IAutoBeTestScenarioApplication.IScenarioGroup>", value: input.scenarioGroups })].every(flag => flag); const _vo1 = (input, _path, _exceptionable = true) => [("object" === typeof input.endpoint && null !== input.endpoint || _report(_exceptionable, { path: _path + ".endpoint", expected: "AutoBeOpenApi.IEndpoint", value: input.endpoint })) && _vo2(input.endpoint, _path + ".endpoint", true && _exceptionable) || _report(_exceptionable, { path: _path + ".endpoint", expected: "AutoBeOpenApi.IEndpoint", value: input.endpoint }), (Array.isArray(input.scenarios) || _report(_exceptionable, { path: _path + ".scenarios", expected: "Array<IAutoBeTestScenarioApplication.IScenario>", value: input.scenarios })) && input.scenarios.map((elem, _index5) => ("object" === typeof elem && null !== elem || _report(_exceptionable, { path: _path + ".scenarios[" + _index5 + "]", expected: "IAutoBeTestScenarioApplication.IScenario", value: elem })) && _vo3(elem, _path + ".scenarios[" + _index5 + "]", true && _exceptionable) || _report(_exceptionable, { path: _path + ".scenarios[" + _index5 + "]", expected: "IAutoBeTestScenarioApplication.IScenario", value: elem })).every(flag => flag) || _report(_exceptionable, { path: _path + ".scenarios", expected: "Array<IAutoBeTestScenarioApplication.IScenario>", value: input.scenarios })].every(flag => flag); const _vo2 = (input, _path, _exceptionable = true) => ["string" === typeof input.path && (RegExp("^\\/[a-zA-Z0-9\\/_{}.-]*$").test(input.path) || _report(_exceptionable, { path: _path + ".path", expected: "string & Pattern<\"^\\\\/[a-zA-Z0-9\\\\/_{}.-]*$\">", value: input.path })) || _report(_exceptionable, { path: _path + ".path", expected: "(string & Pattern<\"^\\\\/[a-zA-Z0-9\\\\/_{}.-]*$\">)", value: input.path }), "get" === input.method || "post" === input.method || "put" === input.method || "delete" === input.method || "patch" === input.method || _report(_exceptionable, { path: _path + ".method", expected: "(\"delete\" | \"get\" | \"patch\" | \"post\" | \"put\")", value: input.method })].every(flag => flag); const _vo3 = (input, _path, _exceptionable = true) => ["string" === typeof input.draft || _report(_exceptionable, { path: _path + ".draft", expected: "string", value: input.draft }), "string" === typeof input.functionName || _report(_exceptionable, { path: _path + ".functionName", expected: "string", value: input.functionName }), (Array.isArray(input.dependencies) || _report(_exceptionable, { path: _path + ".dependencies", expected: "Array<IAutoBeTestScenarioApplication.IDependencies>", value: input.dependencies })) && input.dependencies.map((elem, _index6) => ("object" === typeof elem && null !== elem || _report(_exceptionable, { path: _path + ".dependencies[" + _index6 + "]", expected: "IAutoBeTestScenarioApplication.IDependencies", value: elem })) && _vo4(elem, _path + ".dependencies[" + _index6 + "]", true && _exceptionable) || _report(_exceptionable, { path: _path + ".dependencies[" + _index6 + "]", expected: "IAutoBeTestScenarioApplication.IDependencies", value: elem })).every(flag => flag) || _report(_exceptionable, { path: _path + ".dependencies", expected: "Array<IAutoBeTestScenarioApplication.IDependencies>", value: input.dependencies })].every(flag => flag); const _vo4 = (input, _path, _exceptionable = true) => [("object" === typeof input.endpoint && null !== input.endpoint || _report(_exceptionable, { path: _path + ".endpoint", expected: "AutoBeOpenApi.IEndpoint", value: input.endpoint })) && _vo2(input.endpoint, _path + ".endpoint", true && _exceptionable) || _report(_exceptionable, { path: _path + ".endpoint", expected: "AutoBeOpenApi.IEndpoint", value: input.endpoint }), "string" === typeof input.purpose || _report(_exceptionable, { path: _path + ".purpose", expected: "string", value: input.purpose })].every(flag => flag); const __is = input => "object" === typeof input && null !== input && _io0(input); let errors; let _report; return input => { if (false === __is(input)) { errors = []; _report = __typia_transform__validateReport._validateReport(errors); ((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _report(true, { path: _path + "", expected: "IAutoBeTestScenarioApplication.IProps", value: input })) && _vo0(input, _path + "", true) || _report(true, { path: _path + "", expected: "IAutoBeTestScenarioApplication.IProps", value: input }))(input, "$input", true); const success = 0 === errors.length; return success ? { success, data: input } : { success, errors, data: input }; } return { success: true, data: input }; }; })()(next); if (result.success === false) return result; // merge to unique scenario groups const scenarioGroups = []; result.data.scenarioGroups.forEach((sg) => { const created = scenarioGroups.find((el) => el.endpoint.method === sg.endpoint.method && el.endpoint.path === sg.endpoint.path); if (created) { created.scenarios.push(...sg.scenarios); } else { scenarioGroups.push(sg); } }); // validate endpoints const errors = []; scenarioGroups.forEach((group, i) => { if (props.dict.has(group.endpoint) === false) errors.push({ value: group.endpoint, path: `$input.scenarioGroups[${i}].endpoint`, expected: "AutoBeOpenApi.IEndpoint", description: props.endpointNotFound, }); group.scenarios.forEach((s, j) => { s.dependencies.forEach((dep, k) => { if (props.dict.has(dep.endpoint) === false) errors.push({ value: dep.endpoint, path: `$input.scenarioGroups[${i}].scenarios[${j}].dependencies[${k}].endpoint`, expected: "AutoBeOpenApi.IEndpoint", description: props.endpointNotFound, }); }); }); }); return errors.length === 0 ? { success: true, data: scenarioGroups, } : { success: false, data: scenarioGroups, errors, }; }; return { protocol: "class", name: "Make test plans", application, execute: { makeScenario: (next) => { props.build(next); }, }, }; } const claude = { model: "claude", options: { reference: true, separate: null }, functions: [ { name: "makeScenario", parameters: { description: " Properties containing the endpoints and test scenarios.\n\n------------------------------\n\nCurrent Type: {@link IAutoBeTestScenarioApplication.IProps}", type: "object", properties: { scenarioGroups: { description: "Array of test scenario groups.", type: "array", items: { $ref: "#/$defs/IAutoBeTestScenarioApplication.IScenarioGroup" } } }, required: [ "scenarioGroups" ], additionalProperties: false, $defs: { "IAutoBeTestScenarioApplication.IScenarioGroup": { type: "object", properties: { endpoint: { description: "Target API endpoint to test.\n\nThis must be **unique** across all scenario groups. An endpoint is\nidentified by its `path` and `method` combination.\n\nMultiple test scenarios may exist for a single endpoint.", $ref: "#/$defs/AutoBeOpenApi.IEndpoint" }, scenarios: { description: "An array of test scenarios associated with the given endpoint.\n\nEach scenario represents a specific test case for the same `path` and\n`method`.", type: "array", items: { $ref: "#/$defs/IAutoBeTestScenarioApplication.IScenario" } } }, required: [ "endpoint", "scenarios" ] }, "AutoBeOpenApi.IEndpoint": { description: "API endpoint information.", type: "object", properties: { path: { 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.\n\nPath validation rules:\n\n- Must start with a forward slash (/)\n- Can contain only: letters (a-z, A-Z), numbers (0-9), forward slashes (/),\n curly braces for parameters ({paramName}), hyphens (-), and underscores\n (_)\n- Parameters must be enclosed in curly braces: {paramName}\n- Resource names should be in camelCase\n- No quotes, spaces, or invalid special characters allowed\n- No domain or role-based prefixes\n\nValid examples:\n\n- \"/users\"\n- \"/users/{userId}\"\n- \"/articles/{articleId}/comments\"\n- \"/attachmentFiles\"\n- \"/orders/{orderId}/items/{itemId}\"\n\nInvalid examples:\n\n- \"'/users'\" (contains quotes)\n- \"/user profile\" (contains space)\n- \"/users/[userId]\" (wrong bracket format)\n- \"/admin/users\" (role prefix)\n- \"/api/v1/users\" (API prefix)", type: "string", pattern: "^\\/[a-zA-Z0-9\\/_{}.-]*$" }, method: { 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", oneOf: [ { "const": "get" }, { "const": "post" }, { "const": "put" }, { "const": "delete" }, { "const": "patch" } ] } }, required: [ "path", "method" ] }, "IAutoBeTestScenarioApplication.IScenario": { description: "Represents a test scenario for a single API operation.\n\nThis interface defines a structured, user-centric test draft that includes\na descriptive function name, a detailed scenario draft, and logical\ndependencies on other endpoints required for context or setup.", type: "object", properties: { draft: { 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 concrete test cases.", type: "string" }, functionName: { 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", type: "string" }, dependencies: { description: "A list of other API endpoints that this scenario logically depends on.\n\nThese dependencies represent context or prerequisite conditions, such as\nauthentication, resource creation, or data setup, that are relevant to\nthe test. This list is not a strict execution order \u2014 if ordering is\nimportant, it must be described explicitly in the `purpose`.", type: "array", items: { $ref: "#/$defs/IAutoBeTestScenarioApplication.IDependencies" } } }, required: [ "draft", "functionName", "dependencies" ] }, "IAutoBeTestScenarioApplication.IDependencies": { type: "object", properties: { endpoint: { description: "Target API endpoint that this scenario depends on.", $ref: "#/$defs/AutoBeOpenApi.IEndpoint" }, purpose: { description: "A concise explanation of why this API call is relevant or required for\nthe main test scenario.\n\nThis should describe the contextual or setup role of the dependency, such\nas creating necessary data or establishing user authentication.\n\nExample: \"Creates a category so that a product can be linked to it during\ncreation.\"", type: "string" } }, required: [ "endpoint", "purpose" ] } } }, description: "Make test scenarios for the given endpoints.", 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 && RegExp("^\\/[a-zA-Z0-9\\/_{}.-]*$").test(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.dependencies) && input.dependencies.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, { path: _path + ".scenarioGroups", expected: "Array<IAutoBeTestScenarioApplication.IScenarioGroup>", value: input.scenarioGroups })) && input.scenarioGroups.map((elem, _index4) => ("object" === typeof elem && null !== elem || _report(_exceptionable, { path: _path + ".scenarioGroups[" + _index4 + "]", expected: "IAutoBeTestScenarioApplication.IScenarioGroup", value: elem })) && _vo1(elem, _path + ".scenarioGroups[" + _index4 + "]", true && _exceptionable) || _report(_exceptionable, { path: _path + ".scenarioGroups[" + _index4 + "]", expected: "IAutoBeTestScenarioApplication.IScenarioGroup", value: elem })).every(flag => flag) || _report(_exceptionable, { path: _path + ".scenarioGroups", expected: "Array<IAutoBeTestScenarioApplication.IScenarioGroup>", value: input.scenarioGroups })].every(flag => flag); const _vo1 = (input, _path, _exceptionable = true) => [("object" === typeof input.endpoint && null !== input.endpoint || _report(_exceptionable, { path: _path + ".endpoint", expect