Support non-JSON content types and fix multi-placeholder replacement #12
@@ -135,11 +135,21 @@ public class MockRequestInterceptor implements HandlerInterceptor {
|
||||
// Replace placeholders in the mock response body with path/global values
|
||||
Object body = mockService.replacePlaceholders(selected.body(), pathVars);
|
||||
|
||||
// Write the mock response: headers, status, and JSON body
|
||||
// Write the mock response: headers, status, and body
|
||||
selected.headers().forEach(response::setHeader);
|
||||
response.setStatus(selected.status());
|
||||
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
||||
|
||||
// Respect Content-Type from YAML headers; default to application/json
|
||||
String contentType = selected.headers().getOrDefault("Content-Type",
|
||||
MediaType.APPLICATION_JSON_VALUE);
|
||||
response.setContentType(contentType);
|
||||
|
||||
// For non-JSON content types with a string body, write the raw string directly
|
||||
if (!contentType.contains("json") && body instanceof String rawBody) {
|
||||
response.getWriter().write(rawBody);
|
||||
} else {
|
||||
response.getWriter().write(mockService.toJson(body));
|
||||
}
|
||||
|
||||
return false; // Request has been fully handled
|
||||
}
|
||||
|
||||
@@ -215,28 +215,24 @@ public class MockService {
|
||||
String result = input;
|
||||
|
||||
// Process datetime with offset (e.g., {datetime+2d4h30m} or {datetime+2d4h30m:rfc3339})
|
||||
Matcher dateTimeOffsetMatcher = DATETIME_OFFSET_PATTERN.matcher(result);
|
||||
if (dateTimeOffsetMatcher.find()) {
|
||||
String sign = dateTimeOffsetMatcher.group("sign");
|
||||
String daysStr = dateTimeOffsetMatcher.group("days");
|
||||
String hoursStr = dateTimeOffsetMatcher.group("hours");
|
||||
String minutesStr = dateTimeOffsetMatcher.group("minutes");
|
||||
String format = dateTimeOffsetMatcher.group("format");
|
||||
result = replaceAllMatches(result, DATETIME_OFFSET_PATTERN, matcher -> {
|
||||
String sign = matcher.group("sign");
|
||||
String daysStr = matcher.group("days");
|
||||
String hoursStr = matcher.group("hours");
|
||||
String minutesStr = matcher.group("minutes");
|
||||
String format = matcher.group("format");
|
||||
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
LocalDateTime target = calculateDateTimeWithOffset(now, sign, daysStr, hoursStr, minutesStr);
|
||||
|
||||
String replacement = formatDateTime(target, format);
|
||||
result = dateTimeOffsetMatcher.replaceFirst(replacement);
|
||||
}
|
||||
return formatDateTime(target, format);
|
||||
});
|
||||
|
||||
// Process datetime with days at specific time (e.g., {datetime+2d@13:00} or {datetime+2d@13:00:rfc3339})
|
||||
Matcher dateTimeAtTimeMatcher = DATETIME_AT_TIME_PATTERN.matcher(result);
|
||||
if (dateTimeAtTimeMatcher.find()) {
|
||||
String sign = dateTimeAtTimeMatcher.group("sign");
|
||||
int days = Integer.parseInt(dateTimeAtTimeMatcher.group("days"));
|
||||
String timeStr = dateTimeAtTimeMatcher.group("time");
|
||||
String format = dateTimeAtTimeMatcher.group("format");
|
||||
result = replaceAllMatches(result, DATETIME_AT_TIME_PATTERN, matcher -> {
|
||||
String sign = matcher.group("sign");
|
||||
int days = Integer.parseInt(matcher.group("days"));
|
||||
String timeStr = matcher.group("time");
|
||||
String format = matcher.group("format");
|
||||
|
||||
LocalDate targetDate = LocalDate.now();
|
||||
if ("+".equals(sign)) {
|
||||
@@ -247,17 +243,14 @@ public class MockService {
|
||||
|
||||
LocalTime time = LocalTime.parse(timeStr);
|
||||
LocalDateTime target = LocalDateTime.of(targetDate, time);
|
||||
|
||||
String replacement = formatDateTime(target, format);
|
||||
result = dateTimeAtTimeMatcher.replaceFirst(replacement);
|
||||
}
|
||||
return formatDateTime(target, format);
|
||||
});
|
||||
|
||||
// Process date with offset (e.g., {date-4d} or {date-4d:MMM dd, yyyy})
|
||||
Matcher dateOffsetMatcher = DATE_OFFSET_PATTERN.matcher(result);
|
||||
if (dateOffsetMatcher.find()) {
|
||||
String sign = dateOffsetMatcher.group("sign");
|
||||
int days = Integer.parseInt(dateOffsetMatcher.group("days"));
|
||||
String format = dateOffsetMatcher.group("format");
|
||||
result = replaceAllMatches(result, DATE_OFFSET_PATTERN, matcher -> {
|
||||
String sign = matcher.group("sign");
|
||||
int days = Integer.parseInt(matcher.group("days"));
|
||||
String format = matcher.group("format");
|
||||
|
||||
LocalDate target = LocalDate.now();
|
||||
if ("+".equals(sign)) {
|
||||
@@ -265,14 +258,29 @@ public class MockService {
|
||||
} else {
|
||||
target = target.minusDays(days);
|
||||
}
|
||||
|
||||
String replacement = formatDate(target, format);
|
||||
result = dateOffsetMatcher.replaceFirst(replacement);
|
||||
}
|
||||
return formatDate(target, format);
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces all matches of a pattern in the input string, using a function
|
||||
* to compute the replacement for each match.
|
||||
*/
|
||||
private String replaceAllMatches(String input, Pattern pattern,
|
||||
java.util.function.Function<Matcher, String> replacer)
|
||||
{
|
||||
Matcher matcher = pattern.matcher(input);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while (matcher.find()) {
|
||||
String replacement = replacer.apply(matcher);
|
||||
matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement));
|
||||
}
|
||||
matcher.appendTail(sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates a LocalDateTime with the given offset components.
|
||||
* @param base the base datetime to start from
|
||||
|
||||
Reference in New Issue
Block a user