diff --git a/.gitignore b/.gitignore index 864ba321b8e..d612e44870b 100644 --- a/.gitignore +++ b/.gitignore @@ -198,3 +198,8 @@ src/main/resources/config/application-perso.* # Approvals testing src/test/resources/**/*.received.txt .approval_tests_temp/ + +###################### +# Personal Presets Definitions +###################### +src/main/resources/presets/personal/ diff --git a/src/main/java/tech/jhipster/lite/module/application/JHipsterModulesApplicationService.java b/src/main/java/tech/jhipster/lite/module/application/JHipsterModulesApplicationService.java index dc1023a2ba1..335b6a5c5d4 100644 --- a/src/main/java/tech/jhipster/lite/module/application/JHipsterModulesApplicationService.java +++ b/src/main/java/tech/jhipster/lite/module/application/JHipsterModulesApplicationService.java @@ -8,7 +8,7 @@ import tech.jhipster.lite.module.domain.javadependency.JavaDependenciesVersionsRepository; import tech.jhipster.lite.module.domain.javadependency.ProjectJavaDependenciesRepository; import tech.jhipster.lite.module.domain.landscape.JHipsterLandscape; -import tech.jhipster.lite.module.domain.preset.Preset; +import tech.jhipster.lite.module.domain.preset.Presets; import tech.jhipster.lite.module.domain.resource.JHipsterModulesResources; @Service @@ -56,7 +56,7 @@ public JHipsterLandscape landscape() { return modules.landscape(); } - public Collection getPresets() { + public Presets getPresets() { return preset.getPresets(); } } diff --git a/src/main/java/tech/jhipster/lite/module/domain/JHipsterPresetRepository.java b/src/main/java/tech/jhipster/lite/module/domain/JHipsterPresetRepository.java index c798eff6404..df4f82cfb99 100644 --- a/src/main/java/tech/jhipster/lite/module/domain/JHipsterPresetRepository.java +++ b/src/main/java/tech/jhipster/lite/module/domain/JHipsterPresetRepository.java @@ -1,8 +1,7 @@ package tech.jhipster.lite.module.domain; -import java.util.Collection; -import tech.jhipster.lite.module.domain.preset.Preset; +import tech.jhipster.lite.module.domain.preset.Presets; public interface JHipsterPresetRepository { - Collection getPresets(); + Presets getPresets(); } diff --git a/src/main/java/tech/jhipster/lite/module/domain/ProjectFiles.java b/src/main/java/tech/jhipster/lite/module/domain/ProjectFiles.java index 6a762bc54dc..145fe8e30ff 100644 --- a/src/main/java/tech/jhipster/lite/module/domain/ProjectFiles.java +++ b/src/main/java/tech/jhipster/lite/module/domain/ProjectFiles.java @@ -1,7 +1,11 @@ package tech.jhipster.lite.module.domain; +import java.util.Collection; + public interface ProjectFiles { String readString(String path); byte[] readBytes(String path); + + Collection findPaths(String path); } diff --git a/src/main/java/tech/jhipster/lite/module/domain/preset/Presets.java b/src/main/java/tech/jhipster/lite/module/domain/preset/Presets.java new file mode 100644 index 00000000000..d8ac5bafb05 --- /dev/null +++ b/src/main/java/tech/jhipster/lite/module/domain/preset/Presets.java @@ -0,0 +1,23 @@ +package tech.jhipster.lite.module.domain.preset; + +import java.util.Collection; +import java.util.Comparator; +import tech.jhipster.lite.shared.error.domain.Assert; + +public record Presets(Collection presets) { + public Presets { + Assert.notNull("presets", presets); + } + + public static Presets from(Collection presets) { + return new Presets(sortByAlphabeticalOrder(presets)); + } + + private static Collection sortByAlphabeticalOrder(Collection presets) { + return presets.stream().sorted(alphabeticalOrder()).toList(); + } + + private static Comparator alphabeticalOrder() { + return Comparator.comparing(preset -> preset.name().name()); + } +} diff --git a/src/main/java/tech/jhipster/lite/module/infrastructure/primary/ModulesResource.java b/src/main/java/tech/jhipster/lite/module/infrastructure/primary/ModulesResource.java index 24f96583ce4..85cd4873b42 100644 --- a/src/main/java/tech/jhipster/lite/module/infrastructure/primary/ModulesResource.java +++ b/src/main/java/tech/jhipster/lite/module/infrastructure/primary/ModulesResource.java @@ -68,6 +68,6 @@ public RestJHipsterModulePropertiesDefinition propertiesDefinition(@PathVariable @Operation(summary = "Get presets configuration") @GetMapping(path = "/presets", produces = MediaType.APPLICATION_JSON_VALUE) ResponseEntity getPresets() { - return ResponseEntity.ok(RestPresets.from(modules.getPresets())); + return ResponseEntity.ok(RestPresets.from(modules.getPresets().presets())); } } diff --git a/src/main/java/tech/jhipster/lite/module/infrastructure/secondary/FileSystemJHipsterPresetRepository.java b/src/main/java/tech/jhipster/lite/module/infrastructure/secondary/FileSystemJHipsterPresetRepository.java index cd7cd79078f..09be6f48ead 100644 --- a/src/main/java/tech/jhipster/lite/module/infrastructure/secondary/FileSystemJHipsterPresetRepository.java +++ b/src/main/java/tech/jhipster/lite/module/infrastructure/secondary/FileSystemJHipsterPresetRepository.java @@ -3,18 +3,21 @@ import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; import java.util.Collection; +import java.util.List; +import java.util.function.Function; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Repository; import tech.jhipster.lite.module.domain.JHipsterPresetRepository; import tech.jhipster.lite.module.domain.ProjectFiles; import tech.jhipster.lite.module.domain.preset.Preset; import tech.jhipster.lite.module.domain.preset.PresetName; +import tech.jhipster.lite.module.domain.preset.Presets; import tech.jhipster.lite.shared.error.domain.GeneratorException; @Repository class FileSystemJHipsterPresetRepository implements JHipsterPresetRepository { - private static final String PRESET_FOLDER = "/"; + private static final String ROOT_FOLDER = "/"; private final ObjectMapper json; private final ProjectFiles projectFiles; @@ -23,23 +26,39 @@ class FileSystemJHipsterPresetRepository implements JHipsterPresetRepository { public FileSystemJHipsterPresetRepository( ObjectMapper json, ProjectFiles projectFiles, - @Value("${jhlite.preset-file.name:preset.json}") String presetFileName + @Value("${jhlite.preset.folder:presets}") String presetFolderName ) { this.json = json; this.projectFiles = projectFiles; - this.presetName = PresetName.from(presetFileName); + this.presetName = PresetName.from(presetFolderName); } @Override - public Collection getPresets() { - try { - return json.readValue(projectFiles.readBytes(presetFilePath()), PersistedPresets.class).toDomain(); - } catch (IOException e) { - throw GeneratorException.technicalError("Can't read presets: " + e.getMessage(), e); - } + public Presets getPresets() { + return Presets.from(readAllPresets()); } - private String presetFilePath() { - return PRESET_FOLDER + presetName.name(); + private List readAllPresets() { + return projectFiles + .findPaths(presetFolderPath()) + .stream() + .map(readPresetFile()) + .map(PersistedPresets::toDomain) + .flatMap(Collection::stream) + .toList(); + } + + private Function readPresetFile() { + return path -> { + try { + return json.readValue(projectFiles.readBytes(path), PersistedPresets.class); + } catch (IOException e) { + throw GeneratorException.technicalError("Can't read preset file at " + path + ": " + e.getMessage(), e); + } + }; + } + + private String presetFolderPath() { + return ROOT_FOLDER + presetName.name(); } } diff --git a/src/main/java/tech/jhipster/lite/module/infrastructure/secondary/FileSystemProjectFiles.java b/src/main/java/tech/jhipster/lite/module/infrastructure/secondary/FileSystemProjectFiles.java index 98bc37eb552..d854972980e 100644 --- a/src/main/java/tech/jhipster/lite/module/infrastructure/secondary/FileSystemProjectFiles.java +++ b/src/main/java/tech/jhipster/lite/module/infrastructure/secondary/FileSystemProjectFiles.java @@ -2,7 +2,15 @@ import java.io.IOException; import java.io.InputStream; +import java.net.URISyntaxException; +import java.net.URL; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Collection; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Stream; import org.apache.commons.io.IOUtils; import org.springframework.stereotype.Service; import tech.jhipster.lite.module.domain.ProjectFiles; @@ -29,6 +37,16 @@ public String readString(String path) { } } + private InputStream getInputStream(String path) { + return FileSystemProjectFiles.class.getResourceAsStream(path.replace("\\", SLASH)); + } + + private void assertFileExist(String path, InputStream input) { + if (input == null) { + throw GeneratorException.technicalError("Can't find file: " + path); + } + } + @ExcludeFromGeneratedCodeCoverage(reason = "The error handling is an hard to test implementation detail") private static String toString(InputStream input) { try { @@ -52,22 +70,68 @@ public byte[] readBytes(String path) { } } - private void assertFileExist(String path, InputStream input) { - if (input == null) { - throw GeneratorException.technicalError("Can't find file: " + path); + @ExcludeFromGeneratedCodeCoverage(reason = "The error handling is an hard to test implementation detail") + private static byte[] toByteArray(InputStream input) { + try { + return IOUtils.toByteArray(input); + } catch (IOException e) { + throw GeneratorException.technicalError("Error reading file: " + e.getMessage(), e); } } - private InputStream getInputStream(String path) { - return FileSystemProjectFiles.class.getResourceAsStream(path.replace("\\", SLASH)); + @Override + public Collection findPaths(String rootFolder) { + Assert.notBlank("rootFolder", rootFolder); + + Path rootPath = rootPathFrom(rootFolder); + + assertFolder(rootPath); + + return buildRelativePath(rootFolder, rootPath); } @ExcludeFromGeneratedCodeCoverage(reason = "The error handling is an hard to test implementation detail") - private static byte[] toByteArray(InputStream input) { + private Path rootPathFrom(String resourcePath) { + URL folderUrl = getURL(resourcePath); + assertFolderExist(resourcePath, folderUrl); + try { - return IOUtils.toByteArray(input); + return Path.of(folderUrl.toURI()); + } catch (URISyntaxException e) { + throw GeneratorException.technicalError("Unable to read folder %s: %s".formatted(resourcePath, e.getMessage()), e); + } + } + + private void assertFolderExist(String path, URL url) { + if (url == null) { + throw GeneratorException.technicalError("Can't find folder: " + path); + } + } + + private void assertFolder(Path rootPath) { + if (!Files.isDirectory(rootPath)) { + throw GeneratorException.technicalError("Path %s is not a folder".formatted(rootPath)); + } + } + + @ExcludeFromGeneratedCodeCoverage(reason = "The error handling is an hard to test implementation detail") + private static List buildRelativePath(String rootFolder, Path rootPath) { + try (Stream walkStream = getWalkStream(rootPath)) { + return walkStream.filter(Files::isRegularFile).map(relativePathFrom(rootFolder, rootPath)).toList(); } catch (IOException e) { - throw GeneratorException.technicalError("Error reading file: " + e.getMessage(), e); + throw GeneratorException.technicalError("Error closing %s: %s".formatted(rootFolder, e.getMessage()), e); } } + + private static Stream getWalkStream(Path folder) throws IOException { + return Files.walk(folder); + } + + private static Function relativePathFrom(String rootFolder, Path rootPath) { + return path -> Path.of(rootFolder).resolve(rootPath.relativize(path)).toString().replace("\\", SLASH); + } + + private URL getURL(String path) { + return FileSystemProjectFiles.class.getResource(path.replace("\\", SLASH)); + } } diff --git a/src/main/resources/config/application.yml b/src/main/resources/config/application.yml index 61bdf5b058e..7c7767708f8 100644 --- a/src/main/resources/config/application.yml +++ b/src/main/resources/config/application.yml @@ -69,8 +69,8 @@ jhlite: hidden-resources: slugs: - svelte-core - preset-file: - name: preset.json + preset: + folder: presets server: port: 7471 diff --git a/src/main/resources/preset.json b/src/main/resources/presets/preset-maven.json similarity index 100% rename from src/main/resources/preset.json rename to src/main/resources/presets/preset-maven.json diff --git a/src/test/java/tech/jhipster/lite/module/infrastructure/secondary/FileSystemJHipsterPresetRepositoryTest.java b/src/test/java/tech/jhipster/lite/module/infrastructure/secondary/FileSystemJHipsterPresetRepositoryTest.java index f61fbc934e6..e15ebd1c734 100644 --- a/src/test/java/tech/jhipster/lite/module/infrastructure/secondary/FileSystemJHipsterPresetRepositoryTest.java +++ b/src/test/java/tech/jhipster/lite/module/infrastructure/secondary/FileSystemJHipsterPresetRepositoryTest.java @@ -6,7 +6,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; -import java.util.Collection; import java.util.List; import org.junit.jupiter.api.Test; import tech.jhipster.lite.JsonHelper; @@ -16,12 +15,44 @@ import tech.jhipster.lite.module.domain.ProjectFiles; import tech.jhipster.lite.module.domain.preset.Preset; import tech.jhipster.lite.module.domain.preset.PresetName; +import tech.jhipster.lite.module.domain.preset.Presets; import tech.jhipster.lite.shared.error.domain.GeneratorException; @UnitTest class FileSystemJHipsterPresetRepositoryTest { - private static final String DEFAULT_PRESET_FILE = "preset.json"; + private static final String DEFAULT_PRESET_FOLDER = "presets"; + + private static final String PRESET_JSON_TEMPLATE = + """ + { + "presets": [ + { + "name": "%s", + "modules": [ + %s + ] + } + ] + } + """; + private static final String PRESET_JSON_MULTIPLE_TEMPLATE = + """ + { + "presets": [ + %s + ] + } + """; + private static final String PRESET_ENTRY_TEMPLATE = + """ + { + "name": "%s", + "modules": [ + %s + ] + } + """; @Test void shouldHandleDeserializationErrors() throws IOException { @@ -30,85 +61,247 @@ void shouldHandleDeserializationErrors() throws IOException { FileSystemJHipsterPresetRepository fileSystemJHipsterPresetRepository = new FileSystemJHipsterPresetRepository( json, mockProjectFilesWithValidPresetJson(), - DEFAULT_PRESET_FILE + DEFAULT_PRESET_FOLDER ); assertThatThrownBy(fileSystemJHipsterPresetRepository::getPresets).isExactlyInstanceOf(GeneratorException.class); } @Test - void shouldNotReturnPresetFromUnknownFile() { + void shouldNotReturnPresetFromUnknownFolder() { ProjectFiles projectFiles = mock(ProjectFiles.class); - lenient().when(projectFiles.readBytes("/preset.json")).thenThrow(GeneratorException.class); + lenient().when(projectFiles.findPaths("/%s".formatted(DEFAULT_PRESET_FOLDER))).thenThrow(GeneratorException.class); FileSystemJHipsterPresetRepository fileSystemJHipsterPresetRepository = new FileSystemJHipsterPresetRepository( JsonHelper.jsonMapper(), projectFiles, - DEFAULT_PRESET_FILE + DEFAULT_PRESET_FOLDER ); assertThatThrownBy(fileSystemJHipsterPresetRepository::getPresets).isExactlyInstanceOf(GeneratorException.class); } @Test - void shouldGetExistingPreset() { + void shouldNotReturnPresetFromUnknownFile() { + ProjectFiles projectFiles = mockProjectFilesWithValidPresetJson(); + lenient().when(projectFiles.readBytes("/presets/preset-maven.json")).thenThrow(GeneratorException.class); + FileSystemJHipsterPresetRepository fileSystemJHipsterPresetRepository = new FileSystemJHipsterPresetRepository( + JsonHelper.jsonMapper(), + projectFiles, + DEFAULT_PRESET_FOLDER + ); + + assertThatThrownBy(fileSystemJHipsterPresetRepository::getPresets).isExactlyInstanceOf(GeneratorException.class); + } + + @Test + void shouldGetExistingPresetInAlphabeticalOrder() { FileSystemJHipsterPresetRepository fileSystemJHipsterPresetRepository = new FileSystemJHipsterPresetRepository( JsonHelper.jsonMapper(), mockProjectFilesWithValidPresetJson(), - DEFAULT_PRESET_FILE + DEFAULT_PRESET_FOLDER ); - Collection presets = fileSystemJHipsterPresetRepository.getPresets(); + Presets presets = fileSystemJHipsterPresetRepository.getPresets(); - assertThat(presets).containsExactly(expectedPreset()); + assertThat(presets.presets()).containsExactly( + expectedPresetAngularCore(), + expectedPresetJavaLibraryWithGradle(), + expectedPresetJavaLibraryWithMaven(), + expectedPresetVueCore(), + expectedPresetWebappVueSpringBoot() + ); } private static ProjectFiles mockProjectFilesWithValidPresetJson() { ProjectFiles projectFiles = mock(ProjectFiles.class); - String validPresetJson = + String mavenPreset = createPresetJson( + "Java Library with Maven", + """ + "init", + "application-service-hexagonal-architecture-documentation", + "maven-java", + "maven-wrapper", + "prettier", + "java-base", + "checkstyle", + "jacoco-with-min-coverage-check" + """ + ); + + String gradlePreset = createPresetJson( + "Java Library with Gradle", + """ + "init", + "application-service-hexagonal-architecture-documentation", + "gradle-java", + "gradle-wrapper", + "prettier", + "java-base", + "checkstyle", + "jacoco-with-min-coverage-check" + """ + ); + + String typescriptPreset = createPresetJson( + "Vue Core", """ - { - "presets": [ - { - "name": "angular + spring boot", - "modules": [ - "init", - "application-service-hexagonal-architecture-documentation", - "maven-java", - "prettier", - "angular-core", - "java-base", - "maven-wrapper", - "spring-boot", - "spring-boot-mvc-empty", - "logs-spy", - "spring-boot-tomcat" - ] - } - ] - } - """; - lenient().when(projectFiles.readBytes("/preset.json")).thenReturn(validPresetJson.getBytes(UTF_8)); + "init", + "application-service-hexagonal-architecture-documentation", + "prettier", + "typescript", + "vue-core" + """ + ); + + String personalPresets = createMultiplePresetsJson( + createPresetEntry( + "Webapp: Vue + Spring Boot", + """ + "init", + "application-service-hexagonal-architecture-documentation", + "maven-java", + "maven-wrapper", + "prettier", + "vue-core", + "java-base", + "checkstyle", + "jacoco-with-min-coverage-check", + "spring-boot", + "spring-boot-mvc-empty", + "logs-spy", + "spring-boot-tomcat", + "frontend-maven-plugin" + """ + ), + createPresetEntry( + "Angular Core", + """ + "init", + "application-service-hexagonal-architecture-documentation", + "prettier", + "typescript", + "angular-core" + """ + ) + ); + + lenient().when(projectFiles.readBytes("/presets/preset-maven.json")).thenReturn(mavenPreset.getBytes(UTF_8)); + lenient().when(projectFiles.readBytes("/presets/preset-gradle.json")).thenReturn(gradlePreset.getBytes(UTF_8)); + lenient().when(projectFiles.readBytes("/presets/preset-typescript.json")).thenReturn(typescriptPreset.getBytes(UTF_8)); + lenient().when(projectFiles.readBytes("/presets/personal/preset-personal.json")).thenReturn(personalPresets.getBytes(UTF_8)); + + lenient() + .when(projectFiles.findPaths("/presets")) + .thenReturn( + List.of( + "/presets/preset-maven.json", + "/presets/preset-gradle.json", + "/presets/preset-typescript.json", + "/presets/personal/preset-personal.json" + ) + ); return projectFiles; } - private static Preset expectedPreset() { + private static String createPresetJson(String name, String modules) { + return PRESET_JSON_TEMPLATE.formatted(name, modules); + } + + private static String createPresetEntry(String name, String modules) { + return PRESET_ENTRY_TEMPLATE.formatted(name, modules); + } + + private static String createMultiplePresetsJson(String... presetEntries) { + return PRESET_JSON_MULTIPLE_TEMPLATE.formatted(String.join(",\n", presetEntries)); + } + + private static Preset expectedPresetJavaLibraryWithMaven() { return new Preset( - new PresetName("angular + spring boot"), + new PresetName("Java Library with Maven"), new JHipsterModuleSlugs( List.of( new JHipsterModuleSlug("init"), new JHipsterModuleSlug("application-service-hexagonal-architecture-documentation"), new JHipsterModuleSlug("maven-java"), + new JHipsterModuleSlug("maven-wrapper"), + new JHipsterModuleSlug("prettier"), + new JHipsterModuleSlug("java-base"), + new JHipsterModuleSlug("checkstyle"), + new JHipsterModuleSlug("jacoco-with-min-coverage-check") + ) + ) + ); + } + + private static Preset expectedPresetJavaLibraryWithGradle() { + return new Preset( + new PresetName("Java Library with Gradle"), + new JHipsterModuleSlugs( + List.of( + new JHipsterModuleSlug("init"), + new JHipsterModuleSlug("application-service-hexagonal-architecture-documentation"), + new JHipsterModuleSlug("gradle-java"), + new JHipsterModuleSlug("gradle-wrapper"), new JHipsterModuleSlug("prettier"), - new JHipsterModuleSlug("angular-core"), new JHipsterModuleSlug("java-base"), + new JHipsterModuleSlug("checkstyle"), + new JHipsterModuleSlug("jacoco-with-min-coverage-check") + ) + ) + ); + } + + private static Preset expectedPresetVueCore() { + return new Preset( + new PresetName("Vue Core"), + new JHipsterModuleSlugs( + List.of( + new JHipsterModuleSlug("init"), + new JHipsterModuleSlug("application-service-hexagonal-architecture-documentation"), + new JHipsterModuleSlug("prettier"), + new JHipsterModuleSlug("typescript"), + new JHipsterModuleSlug("vue-core") + ) + ) + ); + } + + private static Preset expectedPresetWebappVueSpringBoot() { + return new Preset( + new PresetName("Webapp: Vue + Spring Boot"), + new JHipsterModuleSlugs( + List.of( + new JHipsterModuleSlug("init"), + new JHipsterModuleSlug("application-service-hexagonal-architecture-documentation"), + new JHipsterModuleSlug("maven-java"), new JHipsterModuleSlug("maven-wrapper"), + new JHipsterModuleSlug("prettier"), + new JHipsterModuleSlug("vue-core"), + new JHipsterModuleSlug("java-base"), + new JHipsterModuleSlug("checkstyle"), + new JHipsterModuleSlug("jacoco-with-min-coverage-check"), new JHipsterModuleSlug("spring-boot"), new JHipsterModuleSlug("spring-boot-mvc-empty"), new JHipsterModuleSlug("logs-spy"), - new JHipsterModuleSlug("spring-boot-tomcat") + new JHipsterModuleSlug("spring-boot-tomcat"), + new JHipsterModuleSlug("frontend-maven-plugin") + ) + ) + ); + } + + private static Preset expectedPresetAngularCore() { + return new Preset( + new PresetName("Angular Core"), + new JHipsterModuleSlugs( + List.of( + new JHipsterModuleSlug("init"), + new JHipsterModuleSlug("application-service-hexagonal-architecture-documentation"), + new JHipsterModuleSlug("prettier"), + new JHipsterModuleSlug("typescript"), + new JHipsterModuleSlug("angular-core") ) ) ); diff --git a/src/test/java/tech/jhipster/lite/module/infrastructure/secondary/FileSystemProjectFilesTest.java b/src/test/java/tech/jhipster/lite/module/infrastructure/secondary/FileSystemProjectFilesTest.java index e70d428046a..a7a47333f98 100644 --- a/src/test/java/tech/jhipster/lite/module/infrastructure/secondary/FileSystemProjectFilesTest.java +++ b/src/test/java/tech/jhipster/lite/module/infrastructure/secondary/FileSystemProjectFilesTest.java @@ -2,6 +2,7 @@ import static org.assertj.core.api.Assertions.*; +import java.util.Collection; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -43,4 +44,34 @@ void shouldReadFileContent() { assertThat(files.readBytes("/generator/dependencies/Dockerfile")).isNotEmpty(); } } + + @Nested + @DisplayName("Paths") + class FileSystemProjectFilesFindPathsTest { + + @Test + void shouldNotFindUnknownFolder() { + assertThatThrownBy(() -> files.findPaths("unknown")).isExactlyInstanceOf(GeneratorException.class); + } + + @Test + void shouldNotBeFile() { + assertThatThrownBy(() -> files.findPaths("/generator/dependencies/Dockerfile")).isExactlyInstanceOf(GeneratorException.class); + } + + @Test + void shouldFindFilesRelativePaths() { + Collection paths = files.findPaths("/generator/init"); + + assertThat(paths).contains( + "/generator/init/.editorconfig.mustache", + "/generator/init/.husky/pre-commit", + "/generator/init/.lintstagedrc.cjs", + "/generator/init/README.md.mustache", + "/generator/init/gitattributes", + "/generator/init/gitignore", + "/generator/init/package.json.mustache" + ); + } + } } diff --git a/src/test/java/tech/jhipster/lite/project/infrastructure/secondary/FakedFileSystemProjectFilesConfiguration.java b/src/test/java/tech/jhipster/lite/project/infrastructure/secondary/FakedFileSystemProjectFilesConfiguration.java index 442c36288ef..733fec04975 100644 --- a/src/test/java/tech/jhipster/lite/project/infrastructure/secondary/FakedFileSystemProjectFilesConfiguration.java +++ b/src/test/java/tech/jhipster/lite/project/infrastructure/secondary/FakedFileSystemProjectFilesConfiguration.java @@ -1,6 +1,9 @@ package tech.jhipster.lite.project.infrastructure.secondary; +import static org.mockito.Mockito.*; + import java.nio.charset.StandardCharsets; +import java.util.List; import org.mockito.Mockito; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; @@ -37,6 +40,9 @@ private static void mockPresetJson(FileSystemProjectFiles fileSystemProjectFiles } """; - Mockito.doReturn(presetJsonContent.getBytes(StandardCharsets.UTF_8)).when(fileSystemProjectFiles).readBytes("/preset.json"); + lenient().when(fileSystemProjectFiles.findPaths("/presets")).thenReturn(List.of("/presets/preset-maven.json")); + lenient() + .when(fileSystemProjectFiles.readBytes("/presets/preset-maven.json")) + .thenReturn(presetJsonContent.getBytes(StandardCharsets.UTF_8)); } } diff --git a/src/test/resources/config/application-test.yml b/src/test/resources/config/application-test.yml index fd89aa34bee..09b8afcc3b2 100644 --- a/src/test/resources/config/application-test.yml +++ b/src/test/resources/config/application-test.yml @@ -14,8 +14,8 @@ jhlite: hidden-resources: slugs: tags: - preset-file: - name: preset.json + preset: + folder: presets server: port: 0