Skip to content
Open
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 @@ -2,8 +2,7 @@

import io.mosip.authentication.authfilter.exception.IdAuthenticationFilterException;
import io.mosip.authentication.childauthfilter.impl.ChildAuthFilterImpl;
import io.mosip.authentication.core.indauth.dto.AuthRequestDTO;
import io.mosip.authentication.core.indauth.dto.IdentityInfoDTO;
import io.mosip.authentication.core.indauth.dto.*;

import org.junit.Before;
import org.junit.Test;
Expand Down Expand Up @@ -89,7 +88,63 @@ public void testAdultNoError() throws Exception {

filter.validate(new AuthRequestDTO(), data, new HashMap<>());
}
private AuthRequestDTO buildOtpRequest() {
AuthRequestDTO authRequest = new AuthRequestDTO();
RequestDTO request = new RequestDTO();
request.setOtp("123456");
authRequest.setRequest(request);
return authRequest;
}

private AuthRequestDTO buildDemoRequest() {
AuthRequestDTO authRequest = new AuthRequestDTO();
RequestDTO request = new RequestDTO();

IdentityDTO identity = new IdentityDTO();
identity.setDob("2019-01-01"); // any demo attribute

request.setDemographics(identity);
authRequest.setRequest(request);
return authRequest;
}

private AuthRequestDTO buildEmptyAuthRequest() {
AuthRequestDTO authRequest = new AuthRequestDTO();
authRequest.setRequest(new RequestDTO());
return authRequest;
}
Comment on lines +91 to +115

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Avoid hard‑coded demo DOB to prevent age‑source mismatches.
If ChildAuthFilterImpl ever derives age from request demographics, the fixed "2019-01-01" can make the test non‑representative or time‑sensitive. Prefer passing the same DOB used in the identity map (or omit DOB and use another demo field).

🔧 Suggested tweak
-    private AuthRequestDTO buildDemoRequest() {
+    private AuthRequestDTO buildDemoRequest(String demoDob) {
         AuthRequestDTO authRequest = new AuthRequestDTO();
         RequestDTO request = new RequestDTO();

         IdentityDTO identity = new IdentityDTO();
-        identity.setDob("2019-01-01"); // any demo attribute
+        identity.setDob(demoDob);

         request.setDemographics(identity);
         authRequest.setRequest(request);
         return authRequest;
     }
-        filter.validate(buildDemoRequest(), data, new HashMap<>());
+        filter.validate(buildDemoRequest(dob), data, new HashMap<>());
🤖 Prompt for AI Agents
In
`@authentication/authentication-common/src/test/java/childauthFilter/ChildAuthFilterImplTest.java`
around lines 91 - 115, The buildDemoRequest method in ChildAuthFilterImplTest
currently hardcodes IdentityDTO.dob to "2019-01-01", which can cause age/source
mismatches against the identity map used by ChildAuthFilterImpl; update
buildDemoRequest to either omit setting dob or set it to the same test DOB
constant used by the identity map (e.g., reference a shared
TEST_DOB/TestIdentity constant), or accept a DOB parameter so tests can pass the
canonical value; change call sites in the test to use the shared DOB to keep
demographics consistent with ChildAuthFilterImpl's age derivation.


@Test(expected = IdAuthenticationFilterException.class)
public void testChildOtpDenied() throws Exception {
String dob = LocalDate.now().minusYears(3).toString(); // child

Map<String, List<IdentityInfoDTO>> data = new HashMap<>();
data.put("dob", List.of(createDob(dob)));

filter.validate(buildOtpRequest(), data, new HashMap<>());
}

@Test(expected = IdAuthenticationFilterException.class)
public void testChildDemoDeniedWhenConfigured() throws Exception {
TestUtils.setField(filter, "factorsDeniedForChild", new String[]{"otp", "bio", "demo"});

String dob = LocalDate.now().minusYears(4).toString();

Map<String, List<IdentityInfoDTO>> data = new HashMap<>();
data.put("dob", List.of(createDob(dob)));

filter.validate(buildDemoRequest(), data, new HashMap<>());
}

@Test
public void testChildWithNoAuthFactorsAllowed() throws Exception {
String dob = LocalDate.now().minusYears(3).toString();

Map<String, List<IdentityInfoDTO>> data = new HashMap<>();
data.put("dob", List.of(createDob(dob)));

filter.validate(buildEmptyAuthRequest(), data, new HashMap<>());
}
}


Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package io.mosip.authentication.common.service.config;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.test.context.junit4.SpringRunner;

import static org.junit.Assert.*;

@RunWith(SpringRunner.class)
public class CacheConfigTest {

@Test
public void testCacheManagerBeanCreation() {
// Load only this configuration
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(CacheConfig.class);

ConcurrentMapCacheManager cacheManager =
context.getBean(ConcurrentMapCacheManager.class);

assertNotNull(cacheManager);

context.close();
Comment on lines +14 to +25

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

rg -n "AnnotationConfigApplicationContext" -C 3

Repository: mosip/id-authentication

Length of output: 190


🌐 Web query:

AnnotationConfigApplicationContext AutoCloseable Spring Framework

💡 Result:

AnnotationConfigApplicationContext is AutoCloseable because it implements Closeable, AutoCloseable (inherited through Spring’s ConfigurableApplicationContext/GenericApplicationContext hierarchy). (docs.spring.io)

That means you can safely use it with try-with-resources (or call close() manually) to shut down the Spring container and release resources / run bean destruction callbacks:

try (var ctx = new AnnotationConfigApplicationContext(AppConfig.class)) {
    MyService s = ctx.getBean(MyService.class);
}
// ctx.close() called automatically

AnnotationConfigApplicationContext is the standalone container variant that accepts @Configuration / @Component / JSR-330 annotated classes (or package scanning). (docs.spring.io)

Citations:


Close AnnotationConfigApplicationContext via try-with-resources.

The context must be closed to release Spring container resources and trigger bean destruction callbacks. Using try-with-resources guarantees cleanup even if an assertion fails, whereas manual close() won't execute if an exception is thrown before reaching it.

Suggested change
-        AnnotationConfigApplicationContext context =
-                new AnnotationConfigApplicationContext(CacheConfig.class);
-
-        ConcurrentMapCacheManager cacheManager =
-                context.getBean(ConcurrentMapCacheManager.class);
-
-        assertNotNull(cacheManager);
-
-        context.close();
+        try (AnnotationConfigApplicationContext context =
+                     new AnnotationConfigApplicationContext(CacheConfig.class)) {
+            ConcurrentMapCacheManager cacheManager =
+                    context.getBean(ConcurrentMapCacheManager.class);
+            assertNotNull(cacheManager);
+        }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@Test
public void testCacheManagerBeanCreation() {
// Load only this configuration
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(CacheConfig.class);
ConcurrentMapCacheManager cacheManager =
context.getBean(ConcurrentMapCacheManager.class);
assertNotNull(cacheManager);
context.close();
`@Test`
public void testCacheManagerBeanCreation() {
// Load only this configuration
try (AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(CacheConfig.class)) {
ConcurrentMapCacheManager cacheManager =
context.getBean(ConcurrentMapCacheManager.class);
assertNotNull(cacheManager);
}
}
🤖 Prompt for AI Agents
In
`@authentication/authentication-common/src/test/java/io/mosip/authentication/common/service/config/CacheConfigTest.java`
around lines 14 - 25, The test method testCacheManagerBeanCreation currently
creates an AnnotationConfigApplicationContext named context and calls
context.close() manually; change it to use try-with-resources by instantiating
the AnnotationConfigApplicationContext in a try(...) block so the context is
automatically closed even if assertions fail, then obtain the
ConcurrentMapCacheManager bean inside that block and remove the explicit
context.close() call.

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package io.mosip.authentication.common.service.config;

import static org.junit.Assert.*;

import java.lang.reflect.Field;

import org.junit.Before;
import org.junit.Test;

public class DemoAuthConfigTest {

private DemoAuthConfig config;

@Before
public void setup() {
config = new DemoAuthConfig();
}

private void setField(String name, String value) throws Exception {
Field f = DemoAuthConfig.class.getDeclaredField(name);
f.setAccessible(true);
f.set(config, value);
}

/* ---------------- DemoApi ---------------- */

@Test
public void testGetDemoApiSDKInstanceClassNotFound() throws Exception {
setField("demosdkClassName", "invalid.demo.Api.Class");

try {
config.getDemoApiSDKInstance();
fail("Expected ClassNotFoundException");
} catch (ClassNotFoundException e) {
assertTrue(e.getMessage().contains("invalid.demo.Api.Class"));
}
}

@Test
public void testGetDemoApiSDKInstanceNoDefaultConstructor() throws Exception {
// java.lang.Integer exists but has NO no-arg constructor
setField("demosdkClassName", Integer.class.getName());

// ReflectionUtils.findConstructor() returns empty
assertNull(config.getDemoApiSDKInstance());
}

/* ---------------- Normalizer ---------------- */

@Test
public void testGetNormalizerSDKInstanceClassNotFound() throws Exception {
setField("normalizerClassName", "invalid.normalizer.Class");

try {
config.getNormalizerSDKInstance();
fail("Expected ClassNotFoundException");
} catch (ClassNotFoundException e) {
assertTrue(e.getMessage().contains("invalid.normalizer.Class"));
}
}

@Test(expected = ClassCastException.class)
public void testGetNormalizerSDKInstanceInvalidType() throws Exception {
setField("normalizerClassName", String.class.getName());
config.getNormalizerSDKInstance();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package io.mosip.authentication.common.service.config;

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockedStatic;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.web.servlet.LocaleResolver;

import io.mosip.authentication.common.service.util.EnvUtil;
@RunWith(MockitoJUnitRunner.class)
public class IdAuthConfigTest {

private IdAuthConfig config;

@Mock
private EnvUtil environment;

@Before
public void setup() throws Exception {
// anonymous subclass (allowed)
config = new IdAuthConfig() {
@Override protected boolean isFingerAuthEnabled() { return true; }
@Override protected boolean isFaceAuthEnabled() { return true; }
@Override protected boolean isIrisAuthEnabled() { return true; }
};

// 🔑 inject @Autowired field manually
java.lang.reflect.Field field =
IdAuthConfig.class.getDeclaredField("environment");
field.setAccessible(true);
field.set(config, environment);
}

@Test
public void testMessageSource() {
assertNotNull(config.messageSource());
}

@Test
public void testThreadPoolTaskScheduler() {
assertNotNull(config.threadPoolTaskScheduler());
}

@Test
public void testAfterburnerModule() {
assertNotNull(config.afterburnerModule());
}

@Test
public void testRestRequestBuilder() {
assertNotNull(config.getRestRequestBuilder());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package io.mosip.authentication.common.service.config;

import static org.junit.Assert.*;

import java.lang.reflect.Field;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.core.ProducerFactory;

@RunWith(MockitoJUnitRunner.class)
public class KafkaProducerConfigTest {

private KafkaProducerConfig config;

@Before
public void setup() throws Exception {
config = new KafkaProducerConfig();

// 🔑 Inject @Value field using reflection
Field field = KafkaProducerConfig.class
.getDeclaredField("bootstrapAddress");
field.setAccessible(true);
field.set(config, "localhost:9092");
}

/* ---------------- producerFactory ---------------- */

@Test
public void testProducerFactory() {
ProducerFactory<String, Object> factory = config.producerFactory();

assertNotNull(factory);
}

/* ---------------- kafkaTemplate ---------------- */

@Test
public void testKafkaTemplate() {
KafkaTemplate<String, Object> template = config.kafkaTemplate();

assertNotNull(template);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package io.mosip.authentication.common.service.config;

import static org.junit.Assert.*;

import java.lang.reflect.Method;
import java.util.List;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.util.ReflectionUtils;

import io.mosip.authentication.core.util.LanguageComparator;

@RunWith(MockitoJUnitRunner.class)
public class LangComparatorConfigTest {

private LangComparatorConfig config;

@Before
public void setup() {
config = new LangComparatorConfig() {
@Override
public List<String> getSystemSupportedLanguageCodes() {
// provide fixed list for testing
return List.of("en", "fr", "hi");
}
};
}

/* ---------------- getSystemSupportedLanguageCodes ---------------- */
@Test
public void testGetSystemSupportedLanguageCodes() {
Method method = ReflectionUtils.findMethod(LangComparatorConfig.class, "getSystemSupportedLanguageCodes");
ReflectionUtils.makeAccessible(method);

@SuppressWarnings("unchecked")
List<String> result = (List<String>) ReflectionUtils.invokeMethod(method, config);

assertNotNull(result);
assertEquals(3, result.size());
assertTrue(result.contains("en"));
assertTrue(result.contains("fr"));
assertTrue(result.contains("hi"));
}

/* ---------------- getLanguageComparator ---------------- */
@Test
public void testGetLanguageComparator() {
Method method = ReflectionUtils.findMethod(LangComparatorConfig.class, "getLanguageComparator");
ReflectionUtils.makeAccessible(method);

LanguageComparator comparator = (LanguageComparator) ReflectionUtils.invokeMethod(method, config);

// just check object creation (we don't need getLanguageCodes)
assertNotNull(comparator);
}

@Test
public void testGetSystemSupportedLanguageCodesActualLogic() throws Exception {
// use ReflectionUtils to invoke the method
Method method = ReflectionUtils.findMethod(LangComparatorConfig.class, "getSystemSupportedLanguageCodes");
ReflectionUtils.makeAccessible(method);

@SuppressWarnings("unchecked")
List<String> result = (List<String>) ReflectionUtils.invokeMethod(method, config);

assertNotNull(result);
assertEquals(3, result.size());
assertTrue(result.contains("en"));
assertTrue(result.contains("fr"));
assertTrue(result.contains("hi"));
}
Comment on lines +60 to +74

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Duplicate test – does not test actual production logic.

testGetSystemSupportedLanguageCodesActualLogic is identical to testGetSystemSupportedLanguageCodes and uses the same overridden config instance. Despite its name, it does not exercise the real implementation.

Either remove this duplicate or, if the intent is to test production logic, create a separate instance without the override and provide necessary dependencies (e.g., mock the configuration source).

♻️ Proposed fix – remove duplicate
-    `@Test`
-    public void testGetSystemSupportedLanguageCodesActualLogic() throws Exception {
-        // use ReflectionUtils to invoke the method
-        Method method = ReflectionUtils.findMethod(LangComparatorConfig.class, "getSystemSupportedLanguageCodes");
-        ReflectionUtils.makeAccessible(method);
-
-        `@SuppressWarnings`("unchecked")
-        List<String> result = (List<String>) ReflectionUtils.invokeMethod(method, config);
-
-        assertNotNull(result);
-        assertEquals(3, result.size());
-        assertTrue(result.contains("en"));
-        assertTrue(result.contains("fr"));
-        assertTrue(result.contains("hi"));
-    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@Test
public void testGetSystemSupportedLanguageCodesActualLogic() throws Exception {
// use ReflectionUtils to invoke the method
Method method = ReflectionUtils.findMethod(LangComparatorConfig.class, "getSystemSupportedLanguageCodes");
ReflectionUtils.makeAccessible(method);
@SuppressWarnings("unchecked")
List<String> result = (List<String>) ReflectionUtils.invokeMethod(method, config);
assertNotNull(result);
assertEquals(3, result.size());
assertTrue(result.contains("en"));
assertTrue(result.contains("fr"));
assertTrue(result.contains("hi"));
}
🤖 Prompt for AI Agents
In
`@authentication/authentication-common/src/test/java/io/mosip/authentication/common/service/config/LangComparatorConfigTest.java`
around lines 60 - 74, The test method
testGetSystemSupportedLanguageCodesActualLogic is a duplicate of
testGetSystemSupportedLanguageCodes and currently invokes
getSystemSupportedLanguageCodes on the overridden test fixture config instead of
the real implementation; either delete the duplicate test method or change it to
instantiate a real LangComparatorConfig (instead of reusing the test's
overridden config variable) and supply/mocking the real configuration source so
that invoking getSystemSupportedLanguageCodes exercises production logic and
asserts the expected language list.

}
Loading