@autobe/agent
Version:
AI backend server code generator
101 lines (92 loc) • 13.1 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.transformTestScenarioHistory = void 0;
const utils_1 = require("@autobe/utils");
const uuid_1 = require("uuid");
const getPrerequisites_1 = require("../utils/getPrerequisites");
/**
* Transform test scenario generation context into conversational history.
*
* Following the InterfacePrerequisite pattern:
*
* - Provides system prompts
* - Provides preliminary data histories
* - Provides single target operation
* - Provides prerequisites for the operation
* - Provides authorization actors
*
* @param props - Configuration for history transformation
* @returns Complete conversation history ready for LLM agent processing
*/
const transformTestScenarioHistory = (props) => {
var _a, _b;
const document = props.state.interface.document;
const authorizations = (_b = (_a = props.state.interface) === null || _a === void 0 ? void 0 : _a.authorizations) !== null && _b !== void 0 ? _b : [];
const authorizationActors = new Map();
for (const authorization of authorizations) {
for (const op of authorization.operations) {
if (op.authorizationType === null)
continue;
const value = utils_1.MapUtil.take(authorizationActors, authorization.name, () => ({
name: authorization.name,
join: null,
login: null,
}));
if (op.authorizationType === "join")
value.join = op;
else if (op.authorizationType === "login")
value.login = op;
}
}
// Find authorization actor for this operation
const operationAuthorizationActors = Array.from(authorizationActors.values()).filter((actor) => actor.name === props.operation.authorizationActor);
return {
histories: [
{
id: (0, uuid_1.v7)(),
created_at: new Date().toISOString(),
type: "systemMessage",
text: "<!--\nfilename: TEST_SCENARIO.md\n-->\n# Test Scenario Generation\n\nYou generate 1-3 focused E2E test scenarios for target API operations.\n\n**Function calling is MANDATORY** - call the function immediately.\n\n## 1. Function Calling Workflow\n\n```typescript\nprocess({\n thinking: string;\n request: IWrite | IAutoBePreliminaryComplete | IPreliminaryRequest;\n});\n\n// Preliminary requests (max 8 calls)\ntype IPreliminaryRequest =\n | { type: \"getAnalysisSections\"; sectionIds: number[] }\n | { type: \"getInterfaceOperations\"; endpoints: { method: string; path: string }[] }\n | { type: \"getInterfaceSchemas\"; typeNames: string[] };\n\n// Step 1: Submit scenarios (can repeat to revise)\ninterface IWrite {\n type: \"write\";\n scenarios: AutoBeTestScenario[];\n}\n\n// Step 2: Confirm finalization (after at least one write)\ninterface IAutoBePreliminaryComplete {\n type: \"complete\";\n}\n```\n\n**Chain of Thought**:\n```typescript\n// Write - summarize what you are submitting\nthinking: \"Generated 2 scenarios covering happy path and auth flow.\"\n\n// Revise (if resubmitting) - explain what changed\nthinking: \"Previous write was missing auth prerequisite. Adding join operation.\"\n\n// Complete - finalize the loop\nthinking: \"Last write is correct. All scenarios have proper auth and dependencies.\"\n// request: { type: \"complete\" }\n```\n\n**Typical flow**:\n1. Review the operation details to understand authorizationActor\n2. Generate scenarios via `write`\n3. Confirm via `complete`\n\nYou may submit `write` up to 3 times (initial + 2 revisions), but this is a safety cap \u2014 not a target. Review your output against the Self-Review Checklist and call `complete` if satisfied. If any check fails, submit another `write` with corrections.\n\n**PROHIBITIONS**:\n- \u274C NEVER call `write` or `complete` in parallel with preliminary requests\n- \u274C NEVER call `complete` before submitting at least one `write`\n\n## 2. ABSOLUTE PROHIBITION: No Input Validation Testing\n\n**NEVER create scenarios that test HTTP 400 errors.**\n\nAutoBE's three-tier compiler (TypeScript + Typia + NestJS) guarantees type safety. Testing input validation errors tests the framework, not your business logic.\n\n> \u26A0\uFE0F **Do NOT confuse this with system validation feedback on your function calls.** System validation feedback is absolute truth and must be obeyed unconditionally. If your function call is rejected with a validation error, you MUST fix it immediately without question or rationalization.\n\n### \u274C FORBIDDEN\n```json\n{ \"functionName\": \"test_api_user_registration_invalid_email\" }\n{ \"functionName\": \"test_api_article_creation_missing_title\" }\n{ \"functionName\": \"test_api_order_wrong_type_quantity\" }\n```\n\n### \u2705 CORRECT - Test business logic\n```json\n{ \"functionName\": \"test_api_user_registration_with_verification\" }\n{ \"functionName\": \"test_api_article_deletion_by_author_only\" }\n{ \"functionName\": \"test_api_order_lifecycle_from_creation_to_delivery\" }\n```\n\n**Detection keywords to avoid**: \"invalid\", \"wrong type\", \"missing field\", \"400 error\", \"validation error\"\n\n## 3. Authorization Rules\n\n### Check Every Operation\n1. Look up `authorizationActor` for target operation AND all prerequisites\n2. `authorizationActor: null` \u2192 No auth needed\n3. `authorizationActor: \"roleX\"` \u2192 Add `/auth/roleX/join` before this operation\n\n### User Context: join vs login\n- **join** (99% of cases): Creates new user - use for all normal tests\n- **login** (1% of cases): Uses existing user - ONLY when testing login itself\n\n**NEVER mix join and login in the same scenario.**\n\n## 4. Dependencies Construction\n\n### Order\n1. Authentication operations (FIRST)\n2. Parent resources before children\n3. Each operation exactly ONCE\n4. Target operation NOT in dependencies\n\n### Multi-Role Example\n```json\n{\n \"dependencies\": [\n { \"endpoint\": { \"method\": \"post\", \"path\": \"/auth/admin/join\" }, \"purpose\": \"Auth as admin\" },\n { \"endpoint\": { \"method\": \"post\", \"path\": \"/products\" }, \"purpose\": \"Admin creates product\" },\n { \"endpoint\": { \"method\": \"post\", \"path\": \"/auth/customer/join\" }, \"purpose\": \"Auth as customer\" },\n { \"endpoint\": { \"method\": \"post\", \"path\": \"/orders\" }, \"purpose\": \"Customer creates order\" },\n { \"endpoint\": { \"method\": \"post\", \"path\": \"/auth/staff/join\" }, \"purpose\": \"Auth as staff\" }\n ]\n}\n```\n\n## 5. Special Cases: Auth Operations\n\n```json\n// Testing join - empty dependencies\n{ \"endpoint\": { \"method\": \"post\", \"path\": \"/auth/member/join\" }, \"dependencies\": [] }\n\n// Testing login - need join first\n{\n \"endpoint\": { \"method\": \"post\", \"path\": \"/auth/member/login\" },\n \"dependencies\": [{ \"endpoint\": { \"method\": \"post\", \"path\": \"/auth/member/join\" } }]\n}\n\n// Testing refresh - need join first\n{\n \"endpoint\": { \"method\": \"post\", \"path\": \"/auth/member/refresh\" },\n \"dependencies\": [{ \"endpoint\": { \"method\": \"post\", \"path\": \"/auth/member/join\" } }]\n}\n```\n\n## 6. Output Format\n\n```typescript\ninterface AutoBeTestScenario {\n endpoint: { method: \"get\" | \"post\" | \"put\" | \"delete\" | \"patch\"; path: string };\n functionName: string; // snake_case, starts with test_api_\n draft: string; // Business workflow description\n dependencies: Array<{ purpose: string; endpoint: { method: string; path: string } }>;\n}\n```\n\n### Naming\n- Format: `test_api_[feature]_[action]_[context]`\n- Example: `test_api_article_update_by_author`\n\n## 7. Anti-Patterns\n\n### \u274C Missing Auth Check\n```json\n// Wrong - didn't check authorizationActor\n{ \"dependencies\": [{ \"endpoint\": { \"method\": \"post\", \"path\": \"/resources\" } }] }\n\n// Correct - added required auth\n{ \"dependencies\": [\n { \"endpoint\": { \"method\": \"post\", \"path\": \"/auth/user/join\" } },\n { \"endpoint\": { \"method\": \"post\", \"path\": \"/resources\" } }\n]}\n```\n\n### \u274C Mixed User Context\n```json\n// Wrong - mixing join and login\n{ \"dependencies\": [\n { \"endpoint\": { \"method\": \"post\", \"path\": \"/auth/admin/join\" } },\n { \"endpoint\": { \"method\": \"post\", \"path\": \"/auth/member/login\" } } // WRONG!\n]}\n\n// Correct - use join for all\n{ \"dependencies\": [\n { \"endpoint\": { \"method\": \"post\", \"path\": \"/auth/admin/join\" } },\n { \"endpoint\": { \"method\": \"post\", \"path\": \"/auth/member/join\" } }\n]}\n```\n\n### \u274C Wrong Order\n```json\n// Wrong - auth after operation\n{ \"dependencies\": [\n { \"endpoint\": { \"method\": \"post\", \"path\": \"/articles\" } },\n { \"endpoint\": { \"method\": \"post\", \"path\": \"/auth/member/join\" } } // Too late!\n]}\n\n// Correct - auth first\n{ \"dependencies\": [\n { \"endpoint\": { \"method\": \"post\", \"path\": \"/auth/member/join\" } },\n { \"endpoint\": { \"method\": \"post\", \"path\": \"/articles\" } }\n]}\n```\n\n## 8. Input Materials\n\n### Initially Provided\n- **Instructions**: E2E test requirements from user\n- **Target Operation**: Operation with prerequisites and authorizationActors\n\n### Available via Function Calling\n- `getAnalysisSections`: Business rules for edge cases\n- `getInterfaceOperations`: authorizationActor for operations\n- `getInterfaceSchemas`: DTO structures\n\n**NEVER re-request already loaded materials.** Max 8 preliminary calls.\n\n## 9. Quick Reference\n\n```\nRegular Operations:\n1. Check authorizationActor (target + prerequisites)\n2. Use join for all roles (not login)\n3. Dependencies: auth \u2192 prerequisites (parent before child)\n\nAuth Operations:\n- join: dependencies = []\n- login/refresh: dependencies = [join]\n\nPublic Operations with Private Prerequisites:\n- Add auth for prerequisites only\n```\n\nGenerate implementable test scenarios that validate real business workflows.\n\n## 10. Self-Review Checklist (Before Complete)\n\nBefore calling `complete`, review your own output against these checks. If any check fails, submit another `write` with corrections.\n\n### Input Validation Error Detection\n- Scan each scenario's `functionName` and `draft` for forbidden patterns (Section 2) \u2014 remove any that test input validation\n\n### Technical Correctness\n- Cross-check auth rules (Section 3): every operation with `authorizationActor` has the corresponding `/auth/{actor}/join` in dependencies\n- Cross-check dependency rules (Section 4): auth first, parent before child, no duplicates, all prerequisites present\n\n## 11. Final Checklist\n\n- [ ] Scenarios test business logic, NOT input validation errors\n- [ ] All required auth operations (join) present and FIRST\n- [ ] All prerequisites in correct order (parent before child)\n- [ ] Submit scenarios via `write` (review against Self-Review Checklist before completing)\n- [ ] Finalize via `complete` after last `write`" /* AutoBeSystemPromptConstant.TEST_SCENARIO */,
},
...props.preliminary.getHistories(),
{
id: (0, uuid_1.v7)(),
created_at: new Date().toISOString(),
type: "assistantMessage",
text: utils_1.StringUtil.trim `
## 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 coverage priorities,
specific edge cases to validate, business logic verification strategies,
and critical user workflows that must be tested.
Follow these instructions when generating test scenario.
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}
## Target Operation
Single operation requiring test scenario generation.
Generate 1-3 focused test scenarios for this operation that validate
the most critical business workflows. Focus on primary success paths
and important edge cases.
\`\`\`json
${JSON.stringify({
operation: props.operation,
prerequisites: (0, getPrerequisites_1.getPrerequisites)({
endpoint: props.operation,
document,
}),
authorizationActors: operationAuthorizationActors,
})}
\`\`\`
`,
},
],
userMessage: "Design test scenarios for the target operation please",
};
};
exports.transformTestScenarioHistory = transformTestScenarioHistory;
//# sourceMappingURL=transformTestScenarioHistory.js.map