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
14 changes: 14 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,12 @@
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.github.librepdf</groupId>
<artifactId>openpdf</artifactId>
Expand Down Expand Up @@ -160,6 +166,14 @@
</annotationProcessorPaths>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>-javaagent:${settings.localRepository}/net/bytebuddy/byte-buddy-agent/1.17.8/byte-buddy-agent-1.17.8.jar</argLine>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);

return http.build();
}
}

@Bean
public AuthenticationProvider authenticationProvider() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public ResponseEntity<?> logout(@AuthenticationPrincipal User user) {

@GetMapping("/me")
public ResponseEntity<?> getCurrentUser(@AuthenticationPrincipal User user) {
if (user == null) {
if (user == null || user.getUserId() == null) {
return ResponseEntity.status(401).body(Map.of("message", "Not authenticated"));
}

Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
spring.config.import=optional:file:.env.properties

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Is this line necessary @arosha-w . The env file is not named as .env.properties


spring.application.name=CrimeLinkAnalyzer

# Server Configuration
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
package com.crimeLink.analyzer.controller;

import com.crimeLink.analyzer.dto.AuditLogDTO;
import com.crimeLink.analyzer.entity.BackupMetadata;
import com.crimeLink.analyzer.entity.LoginAudit;
import com.crimeLink.analyzer.entity.User;
import com.crimeLink.analyzer.repository.LoginAuditRepository;
import com.crimeLink.analyzer.repository.UserRepository;
import com.crimeLink.analyzer.service.BackupService;
import com.crimeLink.analyzer.service.SystemSettingsService;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.data.domain.*;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.PasswordEncoder;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)
class AdminControllerTest {

@Mock private UserRepository userRepo;
@Mock private LoginAuditRepository auditRepo;
@Mock private PasswordEncoder passwordEncoder;
@Mock private BackupService backupService;
@Mock private SystemSettingsService settingsService;
@Mock private Authentication authentication;

@InjectMocks
private AdminController controller;

@Test
void getUsers_shouldReturnAll_whenNoFilters() {
when(userRepo.findAll()).thenReturn(List.of(new User(), new User()));

ResponseEntity<List<User>> response = controller.getUsers(null, null);

assertEquals(200, response.getStatusCode().value());
assertEquals(2, response.getBody().size());
}

@Test
void getUsers_shouldReturnByRoleAndStatus() {
when(userRepo.findByRoleAndStatus("Admin", "Active")).thenReturn(List.of(new User()));

ResponseEntity<List<User>> response = controller.getUsers("Admin", "Active");

assertEquals(200, response.getStatusCode().value());
assertEquals(1, response.getBody().size());
}

@Test
void createUser_shouldReturn400_whenEmailExists() {
User user = new User();
user.setEmail("a@test.com");

when(userRepo.existsByEmail("a@test.com")).thenReturn(true);

ResponseEntity<?> response = controller.createUser(user);

assertEquals(400, response.getStatusCode().value());
}

@Test
void createUser_shouldEncodePasswordAndSave() {
User user = new User();
user.setEmail("a@test.com");
user.setPasswordHash("plain");

when(userRepo.existsByEmail("a@test.com")).thenReturn(false);
when(passwordEncoder.encode("plain")).thenReturn("hashed");
when(userRepo.save(any(User.class))).thenAnswer(inv -> inv.getArgument(0));

ResponseEntity<?> response = controller.createUser(user);

assertEquals(200, response.getStatusCode().value());
User saved = (User) response.getBody();
assertEquals("hashed", saved.getPasswordHash());
}

@Test
void updateUser_shouldReturn404_whenMissing() {
when(userRepo.findById(1)).thenReturn(Optional.empty());

ResponseEntity<?> response = controller.updateUser(1, new User());

assertEquals(404, response.getStatusCode().value());
}

@Test
void updateUser_shouldUpdateAndEncodePassword() {
User existing = new User();
existing.setUserId(1);

User updated = new User();
updated.setName("New");
updated.setEmail("new@test.com");
updated.setPasswordHash("pw");

when(userRepo.findById(1)).thenReturn(Optional.of(existing));
when(passwordEncoder.encode("pw")).thenReturn("hashed");
when(userRepo.save(any(User.class))).thenAnswer(inv -> inv.getArgument(0));

ResponseEntity<?> response = controller.updateUser(1, updated);

assertEquals(200, response.getStatusCode().value());
User body = (User) response.getBody();
assertEquals("New", body.getName());
assertEquals("hashed", body.getPasswordHash());
}

@Test
void deactivateUser_shouldReturn404_whenMissing() {
when(userRepo.findById(1)).thenReturn(Optional.empty());

ResponseEntity<?> response = controller.deactivateUser(1);

assertEquals(404, response.getStatusCode().value());
}

@Test
void deactivateUser_shouldSetInactive() {
User user = new User();
user.setUserId(1);
user.setStatus("Active");

when(userRepo.findById(1)).thenReturn(Optional.of(user));

ResponseEntity<?> response = controller.deactivateUser(1);

assertEquals(200, response.getStatusCode().value());
assertEquals("Inactive", user.getStatus());
verify(userRepo).save(user);
}

@Test
void getAuditLogs_shouldMapDtos() {
LoginAudit log = new LoginAudit();
log.setAuditId(10L);
log.setUserId(1);
log.setEmail("u@test.com");
log.setIpAddress("127.0.0.1");
log.setLoginTime(LocalDateTime.now());
log.setSuccess(false);
log.setFailureReason("Invalid password");

User user = new User();
user.setUserId(1);
user.setName("Officer A");

Page<LoginAudit> page = new PageImpl<>(List.of(log));
when(auditRepo.findAll(any(PageRequest.class))).thenReturn(page);
when(userRepo.findById(1)).thenReturn(Optional.of(user));

ResponseEntity<List<AuditLogDTO>> response = controller.getAuditLogs(100, 0);

assertEquals(200, response.getStatusCode().value());
assertEquals(1, response.getBody().size());
assertEquals("Officer A", response.getBody().get(0).getUserName());
}

@Test
void triggerBackup_shouldReturn200() {
BackupMetadata metadata = new BackupMetadata();
metadata.setFilename("backup.zip");
metadata.setSizeBytes(100L);
metadata.setCreatedAt(LocalDateTime.now());

when(authentication.getName()).thenReturn("admin@test.com");
when(backupService.createBackup("admin@test.com")).thenReturn(metadata);

ResponseEntity<?> response = controller.triggerBackup(authentication);

assertEquals(200, response.getStatusCode().value());
}

@Test
void restoreBackup_shouldReturn400_whenFilenameMissing() {
ResponseEntity<?> response = controller.restoreBackup(Map.of(), authentication);

assertEquals(400, response.getStatusCode().value());
}

@Test
void restoreBackup_shouldReturn200_whenValid() {
when(authentication.getName()).thenReturn("admin@test.com");

ResponseEntity<?> response = controller.restoreBackup(
Map.of("filename", "backup.zip"), authentication);

assertEquals(200, response.getStatusCode().value());
verify(backupService).restoreBackup("backup.zip", "admin@test.com");
}

@Test
void listBackups_shouldReturnList() {
when(backupService.listBackups()).thenReturn(List.of(new BackupMetadata()));

ResponseEntity<List<BackupMetadata>> response = controller.listBackups();

assertEquals(200, response.getStatusCode().value());
assertEquals(1, response.getBody().size());
}

@Test
void getSettings_shouldReturnMap() {
when(settingsService.getAllSettings()).thenReturn(Map.of("theme", "dark"));

ResponseEntity<Map<String, String>> response = controller.getSettings();

assertEquals(200, response.getStatusCode().value());
assertEquals("dark", response.getBody().get("theme"));
}

@Test
void updateSettings_shouldReturn200() {
when(settingsService.updateSettings(anyMap())).thenReturn(Map.of("theme", "dark"));

ResponseEntity<?> response = controller.updateSettings(Map.of("theme", "dark"));

assertEquals(200, response.getStatusCode().value());
}

@Test
void getSystemHealth_shouldReturnUp() {
ResponseEntity<?> response = controller.getSystemHealth();
assertEquals(200, response.getStatusCode().value());
}
}
Loading