From 1e60780a3d04e87557947864172e1d542c0455ed Mon Sep 17 00:00:00 2001 From: siddu015 <116783967+siddu015@users.noreply.github.com> Date: Sun, 23 Feb 2025 01:41:05 +0530 Subject: [PATCH] Feat: Added Generate Test Cases and moved short prompting examples to another function --- lib/services/ollama_service.dart | 154 ++++++++++++++++++++++++++++--- lib/widgets/chatbot_widget.dart | 16 ++++ 2 files changed, 157 insertions(+), 13 deletions(-) diff --git a/lib/services/ollama_service.dart b/lib/services/ollama_service.dart index 8179b211..9feae827 100644 --- a/lib/services/ollama_service.dart +++ b/lib/services/ollama_service.dart @@ -20,23 +20,52 @@ class OllamaService { // Explain latest API request & response Future explainLatestApi({required dynamic requestModel, required dynamic responseModel}) async { if (requestModel == null || responseModel == null) { - return "There are no recent API Requests."; + return "No recent API requests found"; } - final requestJson = jsonEncode(requestModel.toJson()); - final responseJson = jsonEncode(responseModel.toJson()); + // Extract request details + final method = requestModel.httpRequestModel?.method + .toString() + .split('.') + .last + .toUpperCase() + ?? "GET"; + final endpoint = requestModel.httpRequestModel?.url ?? "Unknown endpoint"; + final headers = requestModel.httpRequestModel?.enabledHeadersMap ?? {}; + final parameters = requestModel.httpRequestModel?.enabledParamsMap ?? {}; + final body = requestModel.httpRequestModel?.body; + + // Process response + final rawResponse = responseModel.body; + final responseBody = rawResponse is String; + final statusCode = responseModel.statusCode ?? 0; final prompt = ''' - Explain the API request and response in a simple way: - - **Request Details:** - $requestJson - - **Response Details:** - $responseJson - - Please provide a brief and clear explanation with key insights. - '''; +Analyze this API interaction following these examples: + +Current API Request: +- Endpoint: $endpoint +- Method: $method +- Headers: ${headers.isNotEmpty ? jsonEncode(headers) : "None"} +- Parameters: ${parameters.isNotEmpty ? jsonEncode(parameters) : "None"} +- Body: ${body ?? "None"} + +Current Response: +- Status Code: $statusCode +- Response Body: ${jsonEncode(responseBody)} + +Required Analysis Format: +1. Start with overall status assessment +2. List validation/security issues +3. Highlight request/response mismatches +4. Suggest concrete improvements +5. Use plain text formatting with clear section headers + +Response Structure: +API Request: [request details] +Response: [response details] +Analysis: [structured analysis]'''; + return generateResponse(prompt); } @@ -70,4 +99,103 @@ class OllamaService { return generateResponse(prompt); } + + Future generateTestCases({required dynamic requestModel, required dynamic responseModel}) async { + + final method = requestModel.httpRequestModel?.method + .toString() + .split('.') + .last + .toUpperCase() + ?? "GET"; + final endpoint = requestModel.httpRequestModel?.url ?? "Unknown endpoint"; + final headers = requestModel.httpRequestModel?.enabledHeadersMap ?? {}; + final parameters = requestModel.httpRequestModel?.enabledParamsMap ?? {}; + final body = requestModel.httpRequestModel?.body; + final exampleParams = await generateExampleParams( + requestModel: requestModel, + responseModel: responseModel, + ); + final prompt = ''' +Generate test cases for the following API: + +**API Request:** +- **Endpoint:** `$endpoint` +- **Method:** `$method` +- **Headers:** ${headers.isNotEmpty ? jsonEncode(headers) : "None"} +- **Parameters:** ${parameters.isNotEmpty ? jsonEncode(parameters) : "None"} + +**Test Case Requirements:** +1. Normal case (valid input, expected success) +2. Edge case (unexpected or boundary values) +3. Missing required parameters +4. Invalid authentication (if applicable) +5. Error handling for different status codes + +**Example Test Case Format:** +@Test +void testValidRequest() { + final response = sendRequest("$endpoint", method: "$method", params: $exampleParams); + assert(response.status == 200); +} +\`\`\` + +Generate test cases covering all scenarios. +'''; + + return generateResponse(prompt); + } + + /// Generate example parameter values based on parameter names + Future> generateExampleParams({required dynamic requestModel, required dynamic responseModel,}) async { + final ollamaService = OllamaService(); + + final method = requestModel.httpRequestModel?.method + .toString() + .split('.') + .last + .toUpperCase() + ?? "GET"; + final endpoint = requestModel.httpRequestModel?.url ?? "Unknown endpoint"; + final headers = requestModel.httpRequestModel?.enabledHeadersMap ?? {}; + final parameters = requestModel.httpRequestModel?.enabledParamsMap ?? {}; + final body = requestModel.httpRequestModel?.body; + + + final dynamic rawResponse = responseModel?.body; + final Map? apiResponse = + (rawResponse is String) ? jsonDecode(rawResponse) : rawResponse is Map ? rawResponse : null; + + // Construct LLM prompt to analyze and extract meaningful test cases + final String prompt = ''' +Analyze the following API request and generate structured example parameters. + +**API Request:** +- **Endpoint:** `$endpoint` +- **Method:** `$method` +- **Headers:** ${headers.isNotEmpty ? jsonEncode(headers) : "None"} +- **Parameters:** ${parameters.isNotEmpty ? jsonEncode(parameters) : "None"} +- **Body:** ${body ?? "None"} + +**Response:** +- **Status Code:** ${responseModel?.statusCode ?? "Unknown"} +- **Response Body:** ${apiResponse != null ? jsonEncode(apiResponse) : rawResponse} + +### **Required Output Format** +1. **Standard Example Values**: Assign the most appropriate example values for each parameter. +2. **Edge Cases**: Provide at least 2 edge cases per parameter. +3. **Invalid Cases**: Generate invalid inputs for error handling. +4. **Output must be in valid JSON format.** +'''; + + // Force LLM to return structured JSON output + final String response = await ollamaService.generateResponse(prompt); + + try { + return jsonDecode(response) as Map; + } catch (e) { + return {"error": "Failed to parse response from LLM."}; + } + + } } diff --git a/lib/widgets/chatbot_widget.dart b/lib/widgets/chatbot_widget.dart index 44f8278c..687f7e5e 100644 --- a/lib/widgets/chatbot_widget.dart +++ b/lib/widgets/chatbot_widget.dart @@ -38,6 +38,11 @@ class _ChatbotWidgetState extends ConsumerState { requestModel: requestModel, responseModel: responseModel, ); + } else if (message == "Generate Test Case") { + response = await ollamaService.generateTestCases( + requestModel: requestModel, + responseModel: responseModel + ); } else { response = await ollamaService.generateResponse(message); } @@ -91,6 +96,17 @@ class _ChatbotWidgetState extends ConsumerState { ), ], const Spacer(), + const SizedBox(width: 8), + ElevatedButton.icon( + onPressed: () => _sendMessage("Generate Test Case"), + icon: const Icon(Icons.developer_mode), + label: const Text("Test Case"), + style: ElevatedButton.styleFrom( + backgroundColor: Colors.blueAccent, + ), + ), + + const Spacer(), ], ), Expanded(