Skip to content
Merged
Show file tree
Hide file tree
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
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import com.kntro.reqsai.shared.domain.exception.DomainException;
import com.kntro.reqsai.shared.domain.exception.EntityNotFoundException;

import java.util.Locale;

/**
* Factory for Requirement Discovery domain exceptions — the context-specific counterpart of the shared
* {@code Exceptions} and a mirror of {@code WorkspaceExceptions}.
Expand All @@ -15,8 +17,11 @@ private DiscoveryExceptions() {
}

public static DomainException duplicateUserStory(double similarity) {
// Format with Locale.ROOT so the decimal separator is always a dot: the client parses this
// similarity out of the ProblemDetail `detail` expecting "0.87", and a comma-decimal JVM locale
// would otherwise make it read the score as 0 (0%) on the duplicate-story surface.
return new DomainException(DiscoveryError.DUPLICATE_USER_STORY,
"A near-duplicate user story already exists (similarity %.2f)".formatted(similarity));
String.format(Locale.ROOT, "A near-duplicate user story already exists (similarity %.2f)", similarity));
}

public static EntityNotFoundException sessionNotFound(java.util.UUID id) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.kntro.reqsai.discovery.domain.exception;

import com.kntro.reqsai.shared.domain.exception.DomainException;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.util.Locale;

import static org.assertj.core.api.Assertions.assertThat;

@DisplayName("Discovery: duplicate-story exception")
class DiscoveryExceptionsTest {

private final Locale original = Locale.getDefault();

@AfterEach
void restoreLocale() {
Locale.setDefault(original);
}

@Test
@DisplayName("similarity is dot-formatted even under a comma-decimal default locale")
void similarity_dot_formatted_regardless_of_locale() {
// A comma-decimal locale (es-PE/Germany) would otherwise render "0,87", which the client parses
// as 0 (0%) off the ProblemDetail detail. Locale.ROOT keeps the machine-parsed value a dot.
Locale.setDefault(Locale.GERMANY);

DomainException ex = DiscoveryExceptions.duplicateUserStory(0.87);

assertThat(ex.getMessage()).contains("similarity 0.87");
assertThat(ex.getMessage()).doesNotContain("0,87");
}
}
Loading