Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 155 additions & 0 deletions api/src/main/resources/custom_templates/api_test.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
package {{package}};

import {{invokerPackage}}.ApiException;
import {{modelPackage}}.*;
import com.okta.sdk.helper.PresetHelper;
import com.okta.sdk.helper.TerraformHelper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.DisplayName;

{{#imports}}
import {{import}};
{{/imports}}

import java.io.File;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

java.io.File is imported but never used anywhere in the template. This will produce an unused import warning in every generated class.

import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;

/**
* Auto-generated unit tests for {{classname}} operations
*
* NOTE: This test class requires Terraform-generated prerequisite data to run.
* Tests will fail if the TF_OUTPUTS environment variable is not set with the
* required test prerequisite data.
*/
public class {{classname}}Test {

private {{classname}} apiClient;
private PresetHelper presetHelper;
private TerraformHelper terraformHelper;

@BeforeEach
public void setUp() {
presetHelper = new PresetHelper();
terraformHelper = new TerraformHelper();
apiClient = new {{classname}}(presetHelper.getApiClient());
}

{{#operations}}
{{#operation}}
/**
* Test case for {{operationId}} operation.
*
* This test executes the actual API method with parameters extracted from
* prerequisite data created by Terraform. It validates HTTP response codes.
*
* Method name: test_{{operationId}}
*/
@Test
@DisplayName("Test {{operationId}} operation")
@SuppressWarnings("unchecked")
public void test_{{operationId}}() throws Exception {
// Load prerequisite data from Terraform
Map<String, Object> prerequisiteData = terraformHelper.getPrerequisiteDataForTest("test_{{operationId}}");

// Fail if no prerequisite data found - tests require Terraform data
if (prerequisiteData.isEmpty()) {
throw new AssertionError("No prerequisite data found in Terraform output for test: test_{{operationId}}");
}

// Extract parameters from prerequisite data
Map<String, Object> payload = (Map<String, Object>) prerequisiteData.getOrDefault("payload", new HashMap<>());
Map<String, Object> prerequisiteObject = (Map<String, Object>) prerequisiteData.getOrDefault("prerequisite_object", new HashMap<>());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prerequisiteObject is extracted but never referenced anywhere in the test body.


// Handle file uploads if present
byte[] fileContent = null;
if (payload.containsKey("file_path")) {
String filePath = payload.get("file_path").toString();
fileContent = Files.readAllBytes(Paths.get(filePath));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fileContent is declared, conditionally populated by reading from disk, but never passed to any API method call.

}

// Execute the API method with parameters extracted from prerequisiteData
try {
{{#returnType}}
{{{returnType}}} response = apiClient.{{operationId}}(
{{#allParams}}
{{#isBodyParam}}extractParameterWithType(prerequisiteData, "{{paramName}}", null, "{{datatype}}", "{{paramName}}"){{/isBodyParam}}{{^isBodyParam}}extractParameter(prerequisiteData, "{{paramName}}", null){{/isBodyParam}}{{^-last}}, {{/-last}}
{{/allParams}}
);

// Verify response is not null
if (response == null) {
throw new AssertionError("Response should not be null for {{operationId}}");
}
{{/returnType}}
{{^returnType}}
apiClient.{{operationId}}(
{{#allParams}}
{{#isBodyParam}}extractParameterWithType(prerequisiteData, "{{paramName}}", null, "{{datatype}}", "{{paramName}}"){{/isBodyParam}}{{^isBodyParam}}extractParameter(prerequisiteData, "{{paramName}}", null){{/isBodyParam}}{{^-last}}, {{/-last}}
{{/allParams}}
);
{{/returnType}}
} catch (ApiException e) {
// Verify the HTTP response status code is valid (200, 201, 202, 204)
int code = e.getCode();
if (!(code == 200 || code == 201 || code == 202 || code == 204)) {
throw new AssertionError("API returned unexpected status code: " + code);
}
}
}

{{/operation}}
{{/operations}}

/**
* Helper method to extract a parameter from prerequisite data.
* Delegates to TerraformHelper.extractParameter for smart field name resolution.
*
* @param prerequisiteData Map containing Terraform prerequisite data
* @param paramName Name of the parameter to extract
* @param defaultValue Default value if parameter is not found
* @return The extracted parameter value or default value
*/
@SuppressWarnings("unchecked")
private <T> T extractParameter(Map<String, Object> prerequisiteData, String paramName, T defaultValue) {
Object value = TerraformHelper.extractParameter(prerequisiteData, paramName, defaultValue);
return (T) value;
}

/**
* Helper method to extract a parameter with a specific target class for deserialization.
* This is useful when a parameter can be multiple model types (e.g., Group vs AddGroupRequest).
*
* @param prerequisiteData Map containing Terraform prerequisite data
* @param paramName Name of the parameter to extract
* @param defaultValue Default value if parameter is not found
* @param targetClassName Fully qualified class name for deserialization
* @param typeHint Parameter name hint for intelligent type inference
* @return The extracted parameter value deserialized to the target class, or default value
*/
@SuppressWarnings("unchecked")
private <T> T extractParameterWithType(Map<String, Object> prerequisiteData, String paramName, T defaultValue, String targetClassName, String typeHint) {
Object value = TerraformHelper.extractParameter(prerequisiteData, paramName, defaultValue, targetClassName, typeHint);
return (T) value;
}

/**
* Convert camelCase to snake_case
*/
private String toSnakeCase(String camelCase) {
if (camelCase == null || camelCase.isEmpty()) return camelCase;
StringBuilder result = new StringBuilder();
for (int i = 0; i < camelCase.length(); i++) {
char c = camelCase.charAt(i);
if (Character.isUpperCase(c)) {
if (i > 0) result.append("_");
result.append(Character.toLowerCase(c));
} else {
result.append(c);
}
}
return result.toString();
}
}