/
Chebarik
/
PackageManagement
Обзор
Документация
Войти
/
Chebarik
/
PackageManagement
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/test/java/com/packagemanagement/application/service/PackageApplicationServiceTest.java
517 строк
20 KB
Николай Мехоношин
Implemented non functional requirements
14 апр 2026, 18:37
14 апр 2026, 18:37
2e86838
Код
Авторство
О чём код?
package com.packagemanagement.application.service; import com.packagemanagement.application.dto.PackageDto; import com.packagemanagement.application.dto.PackageMapper; import com.packagemanagement.application.dto.VersionDto; import com.packagemanagement.application.port.AuditService; import com.packagemanagement.application.port.CacheService; import com.packagemanagement.application.port.StorageService; import com.packagemanagement.domain.exception.InvalidPackageFormatException; import com.packagemanagement.domain.exception.PackageAlreadyExistsException; import com.packagemanagement.domain.exception.PackageNotFoundException; import com.packagemanagement.domain.exception.VersionNotFoundException; import com.packagemanagement.domain.model.Package; import com.packagemanagement.domain.model.PackageFormat; import com.packagemanagement.domain.model.PackageId; import com.packagemanagement.domain.model.PackageVersion; import com.packagemanagement.domain.repository.PackageRepository; import com.packagemanagement.domain.service.PackageDomainService; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.mapstruct.factory.Mappers; import java.util.List; import java.util.Optional; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) @DisplayName("PackageApplicationService") class PackageApplicationServiceTest { @Mock private PackageRepository packageRepository; @Mock private CacheService cacheService; @Mock private StorageService storageService; @Mock private AuditService auditService; @Mock private PackageDomainService packageDomainService; private PackageMapper packageMapper; private PackageApplicationService service; @BeforeEach void setUp() { packageMapper = Mappers.getMapper(PackageMapper.class); service = new PackageApplicationService( packageRepository, packageDomainService, cacheService, storageService, auditService, packageMapper ); } @Nested @DisplayName("createPackage") class CreatePackage { @Test @DisplayName("should create package successfully") void shouldCreatePackageSuccessfully() { when(packageRepository.existsByName("my-package")).thenReturn(false); when(packageRepository.save(any(Package.class))).thenAnswer(inv -> inv.getArgument(0)); PackageDto result = service.createPackage("my-package", "Description", PackageFormat.NUGET); assertNotNull(result); assertEquals("my-package", result.name()); assertEquals("Description", result.description()); assertEquals("NUGET", result.format()); verify(packageRepository).save(any(Package.class)); verify(auditService).logPackageCreated(anyString(), eq("my-package"), anyString()); verify(cacheService).put(anyString(), any(), any()); } @Test @DisplayName("should throw exception when package name already exists") void shouldThrowExceptionWhenNameExists() { when(packageRepository.existsByName("existing-package")).thenReturn(true); assertThrows(PackageAlreadyExistsException.class, () -> service.createPackage("existing-package", "Description", PackageFormat.NUGET) ); verify(packageRepository, never()).save(any()); } @Test @DisplayName("should create Maven package") void shouldCreateMavenPackage() { when(packageRepository.existsByName("java-lib")).thenReturn(false); when(packageRepository.save(any(Package.class))).thenAnswer(inv -> inv.getArgument(0)); PackageDto result = service.createPackage("java-lib", "Java library", PackageFormat.MAVEN); assertEquals("MAVEN", result.format()); } } @Nested @DisplayName("uploadVersion") class UploadVersion { private Package nugetPackage; private Package mavenPackage; @BeforeEach void setUp() { nugetPackage = Package.create("test-package", "Test", PackageFormat.NUGET); mavenPackage = Package.create("maven-package", "Test Maven", PackageFormat.MAVEN); } @Test @DisplayName("should upload NuGet version successfully") void shouldUploadNugetVersionSuccessfully() { String packageId = nugetPackage.getId().getValue(); byte[] content = "package content".getBytes(); when(packageRepository.findById(any(PackageId.class))).thenReturn(Optional.of(nugetPackage)); when(packageDomainService.isValidVersionNumber("1.0.0")).thenReturn(true); when(packageDomainService.validateFormat(content, PackageFormat.NUGET)).thenReturn(true); when(packageDomainService.calculateHash(content)).thenReturn("hash123"); when(packageRepository.save(any(Package.class))).thenAnswer(inv -> inv.getArgument(0)); VersionDto result = service.uploadVersion(packageId, "1.0.0", content, "package.nupkg"); assertNotNull(result); assertEquals("1.0.0", result.versionNumber()); assertEquals(content.length, result.size()); verify(storageService).store(packageId, "1.0.0", content); verify(auditService).logVersionUploaded(packageId, "1.0.0", "system"); verify(cacheService).evict(anyString()); } @Test @DisplayName("should upload Maven JAR version successfully") void shouldUploadMavenJarVersionSuccessfully() { String packageId = mavenPackage.getId().getValue(); byte[] content = "jar content".getBytes(); when(packageRepository.findById(any(PackageId.class))).thenReturn(Optional.of(mavenPackage)); when(packageDomainService.isValidVersionNumber("1.0.0")).thenReturn(true); when(packageDomainService.validateFormat(content, PackageFormat.MAVEN)).thenReturn(true); when(packageDomainService.calculateHash(content)).thenReturn("hash123"); when(packageRepository.save(any(Package.class))).thenAnswer(inv -> inv.getArgument(0)); VersionDto result = service.uploadVersion(packageId, "1.0.0", content, "library.jar"); assertNotNull(result); assertEquals("1.0.0", result.versionNumber()); } @Test @DisplayName("should upload Maven WAR version successfully") void shouldUploadMavenWarVersionSuccessfully() { String packageId = mavenPackage.getId().getValue(); byte[] content = "war content".getBytes(); when(packageRepository.findById(any(PackageId.class))).thenReturn(Optional.of(mavenPackage)); when(packageDomainService.isValidVersionNumber("1.0.0")).thenReturn(true); when(packageDomainService.validateFormat(content, PackageFormat.MAVEN)).thenReturn(true); when(packageDomainService.calculateHash(content)).thenReturn("hash123"); when(packageRepository.save(any(Package.class))).thenAnswer(inv -> inv.getArgument(0)); VersionDto result = service.uploadVersion(packageId, "1.0.0", content, "app.war"); assertNotNull(result); } @Test @DisplayName("should throw exception for invalid file extension") void shouldThrowExceptionForInvalidFileExtension() { String packageId = nugetPackage.getId().getValue(); when(packageRepository.findById(any(PackageId.class))).thenReturn(Optional.of(nugetPackage)); when(packageDomainService.isValidVersionNumber("1.0.0")).thenReturn(true); assertThrows(InvalidPackageFormatException.class, () -> service.uploadVersion(packageId, "1.0.0", new byte[10], "package.jar") ); } @Test @DisplayName("should throw exception when uploading nupkg to Maven package") void shouldThrowExceptionForNupkgToMaven() { String packageId = mavenPackage.getId().getValue(); when(packageRepository.findById(any(PackageId.class))).thenReturn(Optional.of(mavenPackage)); when(packageDomainService.isValidVersionNumber("1.0.0")).thenReturn(true); assertThrows(InvalidPackageFormatException.class, () -> service.uploadVersion(packageId, "1.0.0", new byte[10], "package.nupkg") ); } @Test @DisplayName("should throw exception for invalid version number") void shouldThrowExceptionForInvalidVersionNumber() { assertThrows(IllegalArgumentException.class, () -> service.uploadVersion("pkg-id", "invalid-version!", new byte[0], "file.nupkg") ); } @Test @DisplayName("should throw exception when package not found") void shouldThrowExceptionWhenPackageNotFound() { when(packageDomainService.isValidVersionNumber("1.0.0")).thenReturn(true); when(packageRepository.findById(any(PackageId.class))).thenReturn(Optional.empty()); assertThrows(PackageNotFoundException.class, () -> service.uploadVersion("non-existent", "1.0.0", new byte[0], "file.nupkg") ); } @Test @DisplayName("should throw exception for duplicate version") void shouldThrowExceptionForDuplicateVersion() { String packageId = nugetPackage.getId().getValue(); nugetPackage.addVersion(PackageVersion.create("1.0.0", 100L, "hash")); when(packageRepository.findById(any(PackageId.class))).thenReturn(Optional.of(nugetPackage)); when(packageDomainService.isValidVersionNumber("1.0.0")).thenReturn(true); when(packageDomainService.validateFormat(any(), any())).thenReturn(true); when(packageDomainService.checkVersionConflict(nugetPackage, "1.0.0")).thenReturn(true); assertThrows(IllegalArgumentException.class, () -> service.uploadVersion(packageId, "1.0.0", new byte[0], "file.nupkg") ); } @Test @DisplayName("should throw exception when filename is null") void shouldThrowExceptionWhenFilenameIsNull() { String packageId = nugetPackage.getId().getValue(); when(packageRepository.findById(any(PackageId.class))).thenReturn(Optional.of(nugetPackage)); when(packageDomainService.isValidVersionNumber("1.0.0")).thenReturn(true); assertThrows(InvalidPackageFormatException.class, () -> service.uploadVersion(packageId, "1.0.0", new byte[10], null) ); } @Test @DisplayName("should throw exception for invalid package content format") void shouldThrowExceptionForInvalidPackageContentFormat() { String packageId = nugetPackage.getId().getValue(); byte[] content = "invalid content".getBytes(); when(packageRepository.findById(any(PackageId.class))).thenReturn(Optional.of(nugetPackage)); when(packageDomainService.isValidVersionNumber("1.0.0")).thenReturn(true); when(packageDomainService.validateFormat(content, PackageFormat.NUGET)).thenReturn(false); assertThrows(InvalidPackageFormatException.class, () -> service.uploadVersion(packageId, "1.0.0", content, "package.nupkg") ); verify(storageService, never()).store(anyString(), anyString(), any()); } } @Nested @DisplayName("deletePackage") class DeletePackage { @Test @DisplayName("should delete package successfully") void shouldDeletePackageSuccessfully() { Package pkg = Package.create("to-delete", "Test", PackageFormat.NUGET); String packageId = pkg.getId().getValue(); when(packageRepository.findById(any(PackageId.class))).thenReturn(Optional.of(pkg)); service.deletePackage(packageId); verify(storageService).deleteAll(packageId); verify(packageRepository).delete(any(PackageId.class)); verify(auditService).logPackageDeleted(packageId, "to-delete", "system"); verify(cacheService).evict(contains(packageId)); verify(cacheService).evictByPattern(anyString()); } @Test @DisplayName("should throw exception when package not found") void shouldThrowExceptionWhenPackageNotFound() { when(packageRepository.findById(any(PackageId.class))).thenReturn(Optional.empty()); assertThrows(PackageNotFoundException.class, () -> service.deletePackage("non-existent") ); verify(storageService, never()).deleteAll(anyString()); } } @Nested @DisplayName("deleteVersion") class DeleteVersion { @Test @DisplayName("should delete draft version successfully") void shouldDeleteDraftVersionSuccessfully() { Package pkg = Package.create("test-package", "Test", PackageFormat.NUGET); PackageVersion version = PackageVersion.create("1.0.0", 1024L, "hash"); pkg.addVersion(version); String packageId = pkg.getId().getValue(); when(packageRepository.findById(any(PackageId.class))).thenReturn(Optional.of(pkg)); when(packageRepository.save(any(Package.class))).thenAnswer(inv -> inv.getArgument(0)); service.deleteVersion(packageId, "1.0.0"); verify(storageService).delete(packageId, "1.0.0"); verify(auditService).logVersionDeleted(packageId, "1.0.0", "system"); } @Test @DisplayName("should throw exception when version not found") void shouldThrowExceptionWhenVersionNotFound() { Package pkg = Package.create("test-package", "Test", PackageFormat.NUGET); when(packageRepository.findById(any(PackageId.class))).thenReturn(Optional.of(pkg)); assertThrows(IllegalArgumentException.class, () -> service.deleteVersion(pkg.getId().getValue(), "1.0.0") ); } } @Nested @DisplayName("getPackage") class GetPackage { @Test @DisplayName("should return cached package if available") void shouldReturnCachedPackage() { PackageDto cachedDto = new PackageDto("id", "cached", "desc", "NUGET", List.of(), "1.0.0", "2024-01-01T00:00:00Z", "2024-01-01T00:00:00Z"); when(cacheService.get(anyString(), eq(PackageDto.class))) .thenReturn(Optional.of(cachedDto)); PackageDto result = service.getPackage("id"); assertEquals("cached", result.name()); verify(packageRepository, never()).findById(any()); } @Test @DisplayName("should fetch from repository when not cached") void shouldFetchFromRepositoryWhenNotCached() { Package pkg = Package.create("test-package", "Test", PackageFormat.NUGET); String packageId = pkg.getId().getValue(); when(cacheService.get(anyString(), eq(PackageDto.class))).thenReturn(Optional.empty()); when(packageRepository.findById(any(PackageId.class))).thenReturn(Optional.of(pkg)); PackageDto result = service.getPackage(packageId); assertEquals("test-package", result.name()); verify(cacheService).put(anyString(), any(), any()); } @Test @DisplayName("should throw exception when package not found") void shouldThrowExceptionWhenPackageNotFound() { when(cacheService.get(anyString(), eq(PackageDto.class))).thenReturn(Optional.empty()); when(packageRepository.findById(any(PackageId.class))).thenReturn(Optional.empty()); assertThrows(PackageNotFoundException.class, () -> service.getPackage("non-existent") ); } } @Nested @DisplayName("getAllPackages") class GetAllPackages { @Test @DisplayName("should return all packages") void shouldReturnAllPackages() { Package pkg1 = Package.create("package-1", "Desc 1", PackageFormat.NUGET); Package pkg2 = Package.create("package-2", "Desc 2", PackageFormat.MAVEN); when(packageRepository.findAll()).thenReturn(List.of(pkg1, pkg2)); List<PackageDto> result = service.getAllPackages(); assertEquals(2, result.size()); } @Test @DisplayName("should return empty list when no packages") void shouldReturnEmptyListWhenNoPackages() { when(packageRepository.findAll()).thenReturn(List.of()); List<PackageDto> result = service.getAllPackages(); assertTrue(result.isEmpty()); } @Test @DisplayName("should return paginated packages") void shouldReturnPaginatedPackages() { Package pkg1 = Package.create("package-1", "Desc", PackageFormat.NUGET); when(packageRepository.findAll(0, 10)).thenReturn(List.of(pkg1)); List<PackageDto> result = service.getAllPackages(0, 10); assertEquals(1, result.size()); verify(packageRepository).findAll(0, 10); } } @Nested @DisplayName("searchPackages") class SearchPackages { @Test @DisplayName("should return matching packages") void shouldReturnMatchingPackages() { Package pkg = Package.create("search-test", "Desc", PackageFormat.NUGET); when(packageRepository.searchByName("search")).thenReturn(List.of(pkg)); List<PackageDto> result = service.searchPackages("search"); assertEquals(1, result.size()); assertEquals("search-test", result.get(0).name()); } } @Nested @DisplayName("downloadVersion") class DownloadVersion { @Test @DisplayName("should download published version") void shouldDownloadPublishedVersion() { Package pkg = Package.create("test-package", "Test", PackageFormat.NUGET); PackageVersion version = PackageVersion.create("1.0.0", 1024L, "hash"); version.publish(); pkg.addVersion(version); String packageId = pkg.getId().getValue(); byte[] content = "file content".getBytes(); when(packageRepository.findById(any(PackageId.class))).thenReturn(Optional.of(pkg)); when(storageService.retrieve(packageId, "1.0.0")).thenReturn(content); byte[] result = service.downloadVersion(packageId, "1.0.0"); assertArrayEquals(content, result); verify(auditService).logVersionDownloaded(packageId, "1.0.0", "system"); } @Test @DisplayName("should throw exception for draft version download") void shouldThrowExceptionForDraftVersionDownload() { Package pkg = Package.create("test-package", "Test", PackageFormat.NUGET); PackageVersion version = PackageVersion.create("1.0.0", 1024L, "hash"); pkg.addVersion(version); when(packageRepository.findById(any(PackageId.class))).thenReturn(Optional.of(pkg)); assertThrows(IllegalStateException.class, () -> service.downloadVersion(pkg.getId().getValue(), "1.0.0") ); } @Test @DisplayName("should throw exception when version not found") void shouldThrowExceptionWhenVersionNotFound() { Package pkg = Package.create("test-package", "Test", PackageFormat.NUGET); when(packageRepository.findById(any(PackageId.class))).thenReturn(Optional.of(pkg)); assertThrows(VersionNotFoundException.class, () -> service.downloadVersion(pkg.getId().getValue(), "1.0.0") ); } } @Nested @DisplayName("getPackageCount") class GetPackageCount { @Test @DisplayName("should return correct count") void shouldReturnCorrectCount() { when(packageRepository.count()).thenReturn(42L); long count = service.getPackageCount(); assertEquals(42L, count); } } }