@autobe/agent
Version:
AI backend server code generator
317 lines (271 loc) • 30.7 kB
JavaScript
"use strict";
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.transformTestOperationWriteHistory = transformTestOperationWriteHistory;
const utils_1 = require("@autobe/utils");
const utils_2 = require("@typia/utils");
const tstl_1 = require("tstl");
const typia_1 = __importDefault(require("typia"));
const uuid_1 = require("uuid");
const getTestExternalDeclarations_1 = require("../compile/getTestExternalDeclarations");
const AutoBeTestOperationProgrammer_1 = require("../programmers/AutoBeTestOperationProgrammer");
function transformTestOperationWriteHistory(ctx, props) {
return __awaiter(this, void 0, void 0, function* () {
const functions = [...props.authorizationFunctions, ...props.generationFunctions];
return {
histories: [
{
id: (0, uuid_1.v7)(),
created_at: new Date().toISOString(),
type: "systemMessage",
text: systemPrompt.get(),
},
{
id: (0, uuid_1.v7)(),
created_at: new Date().toISOString(),
type: "assistantMessage",
text: utils_1.StringUtil.trim `
Here is the list of input material composition.
Make e2e test functions based on the following information.
## Instructions
The following e2e-test-specific instructions were extracted from
the user's requirements and conversations. These instructions focus
exclusively on test-related aspects such as test data generation strategies,
assertion patterns, error handling approaches, and specific validation logic
that should be implemented in the test code.
Follow these instructions when implementing the e2e test function.
Carefully distinguish between:
- Suggestions or recommendations (consider these as guidance)
- Direct specifications or explicit commands (these must be followed exactly)
When instructions contain direct specifications or explicit design decisions,
follow them precisely even if you believe you have better alternatives.
${props.instruction}
## Function Name
The e2e test function name must be ${JSON.stringify(props.scenario.functionName)}.
## Scenario Plan
Here is the scenario plan what you have to implement.
\`\`\`json
${JSON.stringify(props.scenario)}
\`\`\`
## DTO Definitions
You can use these DTO definitions.
Never use the DTO definitions that are not listed here.
${yield transformTestOperationWriteHistory.structures(ctx, props.artifacts)}
## API (SDK) Functions
You can use these API functions.
Never use the functions that are not listed here.
${transformTestOperationWriteHistory.functional(props.artifacts, functions)}
## E2E Mockup Functions
Just reference, and never follow this code as it is.
\`\`\`json
${JSON.stringify(props.artifacts.e2e)}
\`\`\`
## Available Utility Functions
${functions.length > 0
? utils_1.StringUtil.trim `
🚨 **CRITICAL: UTILITY FUNCTIONS HAVE ABSOLUTE PRIORITY OVER SDK FUNCTIONS** 🚨
When calling an API endpoint, you MUST:
1. **FIRST**: Check if a utility function exists for that endpoint (match by METHOD + PATH)
2. **SECOND**: Only if NO utility function exists, use SDK function (\`api.functional.*\`)
**ABSOLUTE RULE**: If a utility function is provided for an endpoint below, you **MUST** use that utility function.
Using \`api.functional.*\` directly for an endpoint that has a utility function is **FORBIDDEN**.
### Authorization Functions
Use these to authenticate users. They update the connection's headers internally.
**You MUST create a NEW connection object** with \`{ host: connection.host }\` and pass it to the authorize function.
**MANDATORY Pattern:**
\`\`\`typescript
const adminConnection: api.IConnection = { host: connection.host };
await authorize_admin_login(adminConnection, { body: {...} });
// adminConnection.headers is now updated internally by authorize function
// Use adminConnection for all subsequent API calls
\`\`\`
| Function Name | Endpoint | Actor |
|---------------|----------|-------|
${props.authorizationFunctions
.map((f) => `| \`${f.name}\` | \`${f.endpoint.method.toUpperCase()} ${f.endpoint.path}\` | ${f.actor} |`)
.join("\n")}
${props.authorizationFunctions
.map((f) => utils_1.StringUtil.trim `
#### ${f.name}
- **Endpoint**: \`${f.endpoint.method.toUpperCase()} ${f.endpoint.path}\`
- **Actor**: ${f.actor}
- **Auth Type**: ${f.authType}
- **Usage**: Call function, then create NEW connection with token from result
- ⚠️ **Do NOT use \`api.functional.*\` for \`${f.endpoint.method.toUpperCase()} ${f.endpoint.path}\`** - use this function instead
\`\`\`typescript
${f.content}
\`\`\`
`)
.join("\n\n")}
### Generation Functions
Use these to create test resources. They handle data preparation and API calls internally.
**Pass actor-specific connection** (e.g., \`userConnection\`), NOT base \`connection\`.
| Function Name | Endpoint |
|---------------|----------|
${props.generationFunctions
.map((f) => `| \`${f.name}\` | \`${f.endpoint.method.toUpperCase()} ${f.endpoint.path}\` |`)
.join("\n")}
${props.generationFunctions
.map((f) => utils_1.StringUtil.trim `
#### ${f.name}
- **Endpoint**: \`${f.endpoint.method.toUpperCase()} ${f.endpoint.path}\`
- **Usage**: \`await ${f.name}(userConnection, { ... })\` - pass actor-specific connection
- ⚠️ **Do NOT use \`api.functional.*\` for \`${f.endpoint.method.toUpperCase()} ${f.endpoint.path}\`** - use this function instead
\`\`\`typescript
${f.content}
\`\`\`
`)
.join("\n\n")}
`
: utils_1.StringUtil.trim `
No utility functions are available for this test scenario.
You will need to handle authentication and data creation directly using the API SDK functions.
`}
## External Definitions
Here is the external declaration files (d.ts) you can reference.
\`\`\`json
${JSON.stringify(yield (0, getTestExternalDeclarations_1.getTestExternalDeclarations)(ctx))}
\`\`\`
## Template Code
Here is the template e2e test code what you must follow.
You're only allowed to modify the "<SCENARIO DESCRIPTION HERE>" and
code inside the function block marked as "// <E2E TEST CODE HERE>".
Change the template code by writing your scenario description to the
comment, and filling your implementation logic into the function.
Note that, you don't need to add any "import" statement more than
this template code. Everything you need is already imported, so
make your implementation code in the import scope.
\`\`\`typescript
${AutoBeTestOperationProgrammer_1.AutoBeTestOperationProgrammer.writeTemplateCode(props.scenario)}
\`\`\`
`,
},
],
userMessage: `Write e2e test function ${props.scenario.functionName} please`,
};
});
}
(function (transformTestOperationWriteHistory) {
function structures(ctx, artifacts) {
return __awaiter(this, void 0, void 0, function* () {
const compiler = yield ctx.compiler();
return utils_1.StringUtil.trim `
${Object.keys(artifacts.document.components.schemas)
.map((k) => `- ${k}`)
.join("\n")}
\`\`\`json
${JSON.stringify(Object.assign(Object.assign({}, artifacts.dto), (yield compiler.test.getDefaultTypes())))}
\`\`\`
`;
});
}
transformTestOperationWriteHistory.structures = structures;
function functional(artifacts, excludeFunctions) {
const document = (0, utils_1.transformOpenApiDocument)(artifacts.document);
const app = utils_2.HttpMigration.application(document);
const excludeEndpoints = new Set(excludeFunctions.map((f) => `${f.endpoint.method.toLowerCase()}:${f.endpoint.path}`));
const filteredRoutes = app.routes.filter((r) => !excludeEndpoints.has(`${r.method.toLowerCase()}:${r.path}`));
return utils_1.StringUtil.trim `
Method | Path | Function Accessor
-------|------|-------------------
${filteredRoutes
.map((r) => [r.method, r.path, `api.functional.${r.accessor.join(".")}`].join(" | "))
.join("\n")}
\`\`\`json
${JSON.stringify(artifacts.sdk)}
\`\`\`
`;
}
transformTestOperationWriteHistory.functional = functional;
})(transformTestOperationWriteHistory || (exports.transformTestOperationWriteHistory = transformTestOperationWriteHistory = {}));
const systemPrompt = new tstl_1.Singleton(() => "<!--\nfilename: TEST_OPERATION_WRITE.md\n-->\n# E2E Test Generation System Prompt\n\n## 1. Input Materials\n\nYou receive the following as input:\n\n1. **Instructions**: E2E-test-specific instructions from user\n2. **Function Name**: Exact test function name to implement\n3. **Scenario Plan**: Test scenario with endpoint, description, dependencies\n4. **DTO Definitions**: Data transfer object type definitions\n5. **API (SDK) Functions**: SDK functions to call the API\n6. **E2E Mockup Functions**: Reference examples (use for inspiration only)\n7. **Utility Functions**: Authorization and generation functions\n8. **External Definitions**: External `.d.ts` files\n9. **Template Code**: Pre-generated test structure with imports\n\n**Critical Rules:**\n- Use DTO types exactly as provided (e.g., `ICustomer`, NOT `api.structures.ICustomer`)\n- Distinguish DTO variants: `IUser` vs `IUser.ISummary` vs `IUser.ICreate`\n- Use ONLY imports in template. NEVER add new imports.\n- Replace ONLY the `// <E2E TEST CODE HERE>` comment in template.\n\n---\n\n## 2. Role and Mission\n\nYou generate comprehensive E2E test functions. **Execute function calling immediately without asking permission.**\n\n### 2.1. Function Calling Workflow\n\nExecute this 5-step workflow through a single function call:\n\n| Step | Property | Description |\n|------|----------|-------------|\n| 1 | **scenario** | Analyze test scenario, plan strategy, identify DTO variants |\n| 2 | **domain** | Single word in snake_case (e.g., `user`, `shopping_cart`) |\n| 3 | **draft** | Complete E2E test function (start with `export async function`) |\n| 4 | **revise.review** | Find errors; **DELETE** (not fix) forbidden patterns |\n| 5 | **revise.final** | Apply fixes; set to `null` if no issues found |\n\n---\n\n## 3. Connection Isolation Pattern (CRITICAL)\n\nThe `connection` parameter is a **BASE connection only**.\n\n```typescript\nexport async function test_api_example(connection: api.IConnection) {\n // Create actor-specific connections\n const adminConnection: api.IConnection = { host: connection.host };\n await authorize_admin_login(adminConnection, { body: credentials });\n\n const userConnection: api.IConnection = { host: connection.host };\n await authorize_user_login(userConnection, { body: userCreds });\n\n // Use ONLY actor-specific connections\n await api.functional.admin.products.create(adminConnection, {...});\n await api.functional.orders.create(userConnection, {...});\n\n // \u274C NEVER: await api.functional.anything(connection, {...});\n}\n```\n\n---\n\n## 4. Utility Functions Priority\n\n1. Check if utility function exists for the endpoint\n2. If YES \u2192 Use utility function (NEVER use SDK directly)\n3. If NO \u2192 Use SDK function `api.functional.*`\n\n| Endpoint | Utility Exists? | Action |\n|----------|-----------------|--------|\n| `POST /auth/login` | \u2705 `authorize_user_login` | Use utility |\n| `GET /users/{id}` | \u274C | Use SDK |\n\n---\n\n## 5. Code Generation Requirements\n\n### 5.1. Import Prohibition\n\nUse ONLY imports in template. NEVER add imports.\n\n### 5.2. Type Safety\n\n- Never use `any`, `@ts-ignore`, `@ts-expect-error`, `as any`\n- Use exact DTO types from provided definitions\n\n### 5.3. Autonomous Scenario Correction\n\nIf scenario is impossible \u2192 **REWRITE** using available APIs. Compilation success > scenario fidelity.\n\n### 5.4. API Function Invocation\n\n**Every API call MUST have `await`:**\n```typescript\nconst article = await api.functional.bbs.articles.create(\n customerConnection,\n {\n service: \"debate\",\n body: { title: \"Test\" } satisfies IBbsArticle.ICreate,\n },\n);\ntypia.assert(article);\n```\n\n### 5.5. Response Validation\n\n`typia.assert(response)` performs **complete** validation. Never add redundant checks after it.\n\n### 5.6. Null vs Undefined Handling\n\n```typescript\n// T | undefined: Can be undefined, NOT null\nconst userId: string | undefined = undefined; // \u2705\nconst userId: string | undefined = null; // \u274C ERROR\n\n// T | null: Can be null, NOT undefined\nconst score: number | null = null; // \u2705\nconst score: number | null = undefined; // \u274C ERROR\n\n// T | null | undefined: Must check BOTH\nif (value !== null && value !== undefined) {\n const safe: T = value; // \u2705\n}\n```\n\n**Using typia for nullable:**\n```typescript\n// typia.assert - use return value\nconst safeItem = typia.assert(item!);\n\n// typia.assertGuard - narrows original variable\ntypia.assertGuard(item!);\nconsole.log(item.name); // OK - item is now non-nullable\n```\n\n---\n\n## 6. Random Data Generation\n\n### 6.1. typia.random\n\nAlways provide explicit generic type. **Tags use `<>` NOT `()`:**\n```typescript\ntypia.random<string & tags.Format<\"uuid\">>();\ntypia.random<string & tags.Format<\"email\">>();\ntypia.random<number & tags.Type<\"uint32\"> & tags.Minimum<1> & tags.Maximum<100>>();\n\n// \u274C WRONG: typia.random<string & tags.Format(\"email\")>();\n```\n\n### 6.2. RandomGenerator\n\n```typescript\nRandomGenerator.alphabets(3);\nRandomGenerator.name();\nRandomGenerator.mobile();\n\n// paragraph/content take OBJECTS:\nRandomGenerator.paragraph({ sentences: 5 });\nRandomGenerator.content({ paragraphs: 3 });\n```\n\n### 6.3. Array Utilities\n\n```typescript\nArrayUtil.repeat(3, () => ({ name: RandomGenerator.name() }));\n\n// Use 'as const' for literal types\nconst roles = [\"admin\", \"user\", \"guest\"] as const;\nconst role = RandomGenerator.pick(roles);\n```\n\n### 6.4. Typia Tag Type Conversion\n\nWhen encountering type mismatches with tagged types:\n```typescript\n// Use satisfies pattern for type conversion\nconst limit = typia.random<number & tags.Type<\"uint32\">>() satisfies number as number;\n\n// For nullable types\nconst pageNumber: (number & tags.Type<\"int32\">) | null = getValue();\nconst safe = pageNumber satisfies number | null as number | null;\n\n// With nullish coalescing - wrap with parentheses\nconst y = (x ?? 0) satisfies number as number;\n```\n\n---\n\n## 7. TestValidator Usage\n\n**Title is MANDATORY as first parameter:**\n```typescript\nTestValidator.equals(\"user count\", actual, expected);\nTestValidator.notEquals(\"IDs differ\", oldId, newId);\nTestValidator.predicate(\"price positive\", price > 0);\n\n// Async callback \u2192 await\nawait TestValidator.error(\"duplicate email\", async () => {\n await api.functional.users.create(adminConnection, { body });\n});\n\n// Sync callback \u2192 no await\nTestValidator.error(\"throws immediately\", () => { throw new Error(); });\n```\n\n**Parameter Order:** `(\"title\", actualValue, expectedValue)`\n\n---\n\n## 8. Absolute Prohibitions\n\n### 8.1. NO Type Error Testing in Request\n\n**WHY:** E2E tests must compile. Deliberately sending wrong types causes **compilation errors**, not runtime tests. Type validation is the server's job, not E2E test's job.\n\n```typescript\n// \u274C FORBIDDEN - Compilation error, breaks entire test suite\nbody: { age: \"not a number\" as any }\nbody: { email: 123 as any }\n\n// \u2705 CORRECT - Test business logic errors with valid types\nbody: { email: existingEmail } satisfies IUser.ICreate // duplicate email\nbody: { amount: balance + 1000 } satisfies IWithdrawal.ICreate // insufficient funds\n```\n\n**If scenario requests type validation \u2192 IGNORE IT completely**\n\n### 8.2. NO Response Type Validation After typia.assert()\n\n**WHY:** `typia.assert()` performs **complete runtime type validation** including:\n- All property existence checks\n- All type checks (string, number, etc.)\n- All format validations (UUID, email, date-time)\n- All constraint validations (min, max, pattern)\n\nAdding manual checks after it is **redundant and shows distrust** in the validation system.\n\n```typescript\nconst user = await api.functional.users.create(adminConnection, { body });\ntypia.assert(user); // \u2190 This validates EVERYTHING\n\n// \u274C FORBIDDEN - Redundant, unnecessary, shows distrust\nTestValidator.predicate(\"uuid valid\", /^[0-9a-f-]{36}$/i.test(user.id));\nTestValidator.equals(\"type check\", typeof user.age, \"number\");\nif (!user.email) throw new Error(\"Missing email\");\n\n// \u2705 CORRECT - Test business logic, not types\nTestValidator.equals(\"email matches input\", user.email, inputEmail);\nTestValidator.predicate(\"is premium user\", user.subscription === \"premium\");\n```\n\n### 8.3. Other Prohibitions\n\n| Prohibition | Example |\n|-------------|---------|\n| HTTP status testing | `TestValidator.equals(\"status\", exp.status, 404)` |\n| Operations on non-existent properties | `delete emptyObject.property` |\n\n---\n\n## 9. Code Quality Standards\n\n### 9.1. Immutability\n\n```typescript\n// \u2705 CORRECT\nconst body = { name: \"John\" } satisfies IUser.ICreate;\n\n// \u274C FORBIDDEN\nlet body = { ... };\n```\n\n### 9.2. Request Body Declaration\n\n```typescript\n// \u2705 satisfies without type annotation\nconst body = { name: \"John\" } satisfies IUser.ICreate;\n\n// \u274C type annotation with satisfies\nconst body: IUser.ICreate = { name: \"John\" } satisfies IUser.ICreate;\n```\n\n### 9.3. Date Handling\n\n```typescript\n// \u2705 CORRECT - toISOString()\ncreatedAt: new Date().toISOString()\n\n// \u274C WRONG - Date object\ncreatedAt: new Date()\n```\n\n### 9.4. Object Index Access\n\n```typescript\n// \u2705 Add fallback immediately\nmimeType: ({ jpg: \"image/jpeg\" }[ext] ?? \"application/octet-stream\")\n```\n\n---\n\n## 10. Business Logic Patterns\n\n### 10.1. Follow Natural Flow\n\n```typescript\n// \u2705 1. User \u2192 2. Order \u2192 3. Purchase \u2192 4. Review\n// \u274C Review before purchase\n```\n\n### 10.2. Test Business Errors (Not Type Errors)\n\n```typescript\n// \u2705 Duplicate email (business error)\nawait TestValidator.error(\"duplicate email\", async () => {\n await api.functional.users.create(adminConnection, {\n body: { email: existingEmail, name: \"John\" } satisfies IUser.ICreate,\n });\n});\n```\n\n---\n\n## 11. Test Function JSDoc Comment Style (CRITICAL)\n\nEvery JSDoc follows: **summary sentence first, `\\n\\n`, then paragraphs grouped by topic**. Test scenarios use numbered lists (`1.`, `2.`, `3.`, `1.1.`, `2.3.`).\n\n---\n\n## 12. Complete Example\n\n```typescript\n/**\n * Test customer order creation workflow with product validation.\n *\n * Validates the complete order creation flow including administrative product setup, customer authentication, and order placement. Ensures that the order correctly references the product and that computed fields like the total price are accurate.\n *\n * Special attention is given to verifying that the product_id reference is correctly maintained and that the computed total reflects the ordered quantity multiplied by the unit price.\n *\n * 1. Administrator creates a product with name and pricing.\n * 2. Customer registers with email and credentials.\n * 3. Customer creates an order referencing the product.\n * 4. Validates order details match input and product data, ...\n */\nexport async function test_api_customer_order_creation(\n connection: api.IConnection,\n) {\n // 1. Admin setup\n const adminConnection: api.IConnection = { host: connection.host };\n await authorize_admin_login(adminConnection, {\n body: { email: \"admin@test.com\", password: \"1234\" } satisfies IAdmin.ILogin,\n });\n\n const product = await api.functional.admin.products.create(adminConnection, {\n body: {\n name: RandomGenerator.paragraph({ sentences: 2 }),\n price: typia.random<number & tags.Type<\"uint32\"> & tags.Minimum<1000>>(),\n } satisfies IProduct.ICreate,\n });\n typia.assert(product);\n\n // 2. Customer setup\n const customerConnection: api.IConnection = { host: connection.host };\n await authorize_customer_join(customerConnection, {\n body: {\n email: typia.random<string & tags.Format<\"email\">>(),\n password: \"1234\",\n name: RandomGenerator.name(),\n } satisfies ICustomer.IJoin,\n });\n\n // 3. Create order\n const order = await api.functional.customers.orders.create(customerConnection, {\n body: {\n product_id: product.id,\n quantity: typia.random<number & tags.Type<\"uint32\"> & tags.Minimum<1> & tags.Maximum<5>>(),\n } satisfies IOrder.ICreate,\n });\n typia.assert(order);\n\n // 4. Validate\n TestValidator.equals(\"product matches\", order.product_id, product.id);\n TestValidator.predicate(\"has valid total\", order.total > 0);\n}\n```\n\n---\n\n## 13. Anti-Hallucination Protocol\n\n- Use ONLY properties that exist in DTO definitions\n- If property doesn't exist \u2192 it DOESN'T EXIST\n- The compiler is always right\n- Test what EXISTS, not what SHOULD exist\n\n---\n\n## 14. Output Format\n\nGenerate TypeScript code DIRECTLY (not markdown document):\n```typescript\nexport async function test_api_example(connection: api.IConnection) {\n // implementation\n}\n```\n\n---\n\n## 15. Final Checklist\n\n- [ ] NO additional imports\n- [ ] NO `as any` usage\n- [ ] NO type error testing\n- [ ] Every API call has `await`\n- [ ] TestValidator calls have title as first parameter\n- [ ] Base `connection` never used directly\n- [ ] Actor-specific connections for all API calls\n- [ ] Utility functions used when available\n- [ ] typia.assert() on all non-void responses\n- [ ] Revise step completed\n\n**JSDoc Comment Quality (Section 11)**:\n- [ ] JSDoc comment above function: summary sentence first, `\\n\\n`, then paragraphs grouped by topic\n- [ ] Describes WHAT is validated, mentions edge cases and business rules\n\n**Success:** Draft \u2192 Review (finds issues) \u2192 Final (fixes ALL issues)" /* AutoBeSystemPromptConstant.TEST_OPERATION_WRITE */.replace("{{AutoBeTestScenario}}", JSON.stringify({
description: "Test scenario specification for E2E testing of a single API endpoint.\n\nDefines comprehensive test strategy including endpoint details, test\ndescription, function name, and prerequisite dependencies with proper\nexecution ordering.",
type: "object",
properties: {
endpoint: {
description: "The API endpoint being tested.\n\nContains the complete endpoint specification including URL, method,\nparameters, and expected responses that will be validated by this test\nscenario.",
$ref: "#/$defs/AutoBeOpenApi.IEndpoint"
},
draft: {
description: "A detailed natural language description of how this API endpoint should be\ntested. This should include both successful and failure scenarios, business\nrule validations, edge cases, and any sequence of steps necessary to\nperform the test. A subsequent agent will use this draft to generate\nmultiple 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\nDO: Use snake_case naming convention.\n\n- Must start with `test_api_` prefix (mandatory requirement)\n- ALWAYS start with business feature, NOT action verbs\n- Business feature comes first, followed by scenario context\n- Embed action verbs within the scenario description, not at the beginning\n\n## Content Structure\n\nFunction names should follow this pattern:\n`test_api_[core_feature]_[specific_scenario]`\n\nWhere:\n\n- `core_feature`: The main business feature or entity being tested (customer,\n seller, cart, push_message, etc.)\n- `specific_scenario`: The specific operation or scenario context\n (join_verification_not_found, login_success, moderator_assignment_update,\n discountable_ticket_duplicated, csv_export, etc.)\n\n## Business Feature-Based Examples\n\n- `test_api_customer_join_verification_not_found` - Customer join\n verification when verification code not found\n- `test_api_seller_login` - Seller login operation\n- `test_api_cart_discountable_ticket_duplicated` - Cart discountable ticket\n with duplication scenario\n- `test_api_push_message_csv` - Push message functionality with CSV format\n- `test_api_product_review_update` - Product review update operation\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",
pattern: "^[a-z][a-z0-9_]*$"
},
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 the\ntest. This list is not a strict execution order \u2014 if ordering is important,\nit must be described explicitly in the `purpose`.\n\nWARNING: Every endpoint referenced here MUST exist in the provided API\noperations. Do NOT reference endpoints that are not explicitly available,\neven if they seem logically necessary based on database schema or business\nlogic.",
type: "array",
items: {
$ref: "#/$defs/AutoBeTestScenarioDependency"
}
}
},
required: [
"endpoint",
"draft",
"functionName",
"dependencies"
],
additionalProperties: false,
$defs: {
"AutoBeOpenApi.IEndpoint": {
description: "API endpoint information.",
type: "object",
properties: {
path: {
description: "HTTP path of the API operation.\n\nMust start with `/`. Parameters use curly braces: `{paramName}`. Resource\nnames in camelCase. No quotes, spaces, role prefixes (`/admin/`), or API\nversion prefixes (`/api/v1/`).\n\nAllowed characters: letters, digits, `/`, `{`, `}`, `-`, `_`, `.`",
type: "string",
pattern: "^\\/[a-zA-Z0-9\\/_{}.-]*$"
},
method: {
description: "HTTP method (lowercase only).\n\nUse `patch` (not `get`) when a read operation needs a complex\n{@link requestBody}. `get` cannot have a request body.",
type: "string",
"enum": [
"get",
"post",
"put",
"delete",
"patch"
]
}
},
required: [
"path",
"method"
]
},
AutoBeTestScenarioDependency: {
description: "A dependency function that must be called before the main test.\n\nRepresents a prerequisite API call needed to prepare the system state for\nsuccessful test execution.",
type: "object",
properties: {
purpose: {
description: "Why this dependency is needed.\n\nExplains the role of this prerequisite function in setting up the\nconditions required for the main test to succeed.",
type: "string"
},
endpoint: {
description: "The API endpoint for this dependency function.\n\nComplete specification of the prerequisite function that needs to be\ncalled, including parameters and expected behavior.",
$ref: "#/$defs/AutoBeOpenApi.IEndpoint"
}
},
required: [
"purpose",
"endpoint"
]
}
}
})));
//# sourceMappingURL=transformTestOperationWriteHistory.js.map