139 lines
7.0 KiB
Java

package p.packer.services;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import p.packer.messages.AssetReference;
import p.packer.messages.GetAssetDetailsRequest;
import p.packer.messages.PackerOperationStatus;
import p.packer.messages.PackerProjectContext;
import p.packer.messages.assets.OutputCodecCatalog;
import p.packer.messages.assets.PackerAssetState;
import p.packer.messages.assets.PackerBuildParticipation;
import p.packer.testing.PackerFixtureLocator;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.*;
final class PackerAssetDetailsServiceTest {
@TempDir
Path tempDir;
@Test
void returnsRegisteredDetailsForRegisteredAssetReferenceById() throws Exception {
final Path projectRoot = copyFixture("workspaces/managed-basic", tempDir.resolve("managed"));
final PackerAssetDetailsService service = service();
final var result = service.getAssetDetails(new GetAssetDetailsRequest(project(projectRoot), AssetReference.forAssetId(1)));
assertEquals(PackerOperationStatus.SUCCESS, result.status());
assertEquals(PackerAssetState.REGISTERED, result.details().summary().state());
assertEquals(PackerBuildParticipation.INCLUDED, result.details().summary().buildParticipation());
assertEquals("fixture-uuid-1", result.details().summary().identity().assetUuid());
assertEquals("ui_atlas", result.details().summary().identity().assetName());
assertEquals("TILES/indexed_v1", result.details().outputFormat().displayName());
assertEquals(List.of(OutputCodecCatalog.NONE), result.details().availableOutputCodecs());
assertEquals(List.of(), result.details().codecConfigurationFieldsByCodec().get(OutputCodecCatalog.NONE));
assertTrue(result.diagnostics().isEmpty());
}
@Test
void returnsUnregisteredDetailsForValidUnregisteredRootReference() throws Exception {
final Path projectRoot = copyFixture("workspaces/orphan-valid", tempDir.resolve("orphan"));
final PackerAssetDetailsService service = service();
final var result = service.getAssetDetails(new GetAssetDetailsRequest(project(projectRoot), AssetReference.forRelativeAssetRoot("orphans/ui_sounds")));
assertEquals(PackerOperationStatus.SUCCESS, result.status());
assertEquals(PackerAssetState.UNREGISTERED, result.details().summary().state());
assertEquals(PackerBuildParticipation.EXCLUDED, result.details().summary().buildParticipation());
assertEquals("orphan-uuid-1", result.details().summary().identity().assetUuid());
assertEquals("ui_sounds", result.details().summary().identity().assetName());
assertEquals(List.of(OutputCodecCatalog.NONE), result.details().availableOutputCodecs());
assertEquals(List.of(), result.details().codecConfigurationFieldsByCodec().get(OutputCodecCatalog.NONE));
}
@Test
void exposesMetadataFieldsFromOutputMetadataContract() throws Exception {
final Path projectRoot = copyFixture("workspaces/managed-basic", tempDir.resolve("managed-with-metadata"));
final Path manifestPath = projectRoot.resolve("assets/ui/atlas/asset.json");
final ObjectMapper mapper = new ObjectMapper();
final var manifest = mapper.readTree(manifestPath.toFile());
final ObjectNode output = (ObjectNode) manifest.path("output");
final ObjectNode metadata = output.putObject("metadata");
metadata.put("tile_size", "16");
metadata.put("channels", "1");
mapper.writerWithDefaultPrettyPrinter().writeValue(manifestPath.toFile(), manifest);
final PackerAssetDetailsService service = service();
final var result = service.getAssetDetails(new GetAssetDetailsRequest(project(projectRoot), AssetReference.forAssetId(1)));
assertEquals(PackerOperationStatus.SUCCESS, result.status());
assertEquals(
Map.of("tile_size", "16", "channels", "1"),
result.details().metadataFields().stream().collect(java.util.stream.Collectors.toMap(
field -> field.key(),
field -> field.value())));
}
@Test
void returnsInvalidDetailsForInvalidDeclaration() throws Exception {
final Path projectRoot = copyFixture("workspaces/invalid-missing-fields", tempDir.resolve("invalid"));
final PackerAssetDetailsService service = service();
final var result = service.getAssetDetails(new GetAssetDetailsRequest(project(projectRoot), AssetReference.forRelativeAssetRoot("bad")));
assertEquals(PackerOperationStatus.FAILED, result.status());
assertEquals(PackerAssetState.UNREGISTERED, result.details().summary().state());
assertEquals(PackerBuildParticipation.EXCLUDED, result.details().summary().buildParticipation());
assertFalse(result.diagnostics().isEmpty());
}
@Test
void returnsFailureWhenReferenceCannotBeResolved() {
final PackerAssetDetailsService service = service();
final var result = service.getAssetDetails(new GetAssetDetailsRequest(project(tempDir.resolve("empty")), AssetReference.forRelativeAssetRoot("missing/root")));
assertEquals(PackerOperationStatus.FAILED, result.status());
assertEquals(PackerAssetState.UNREGISTERED, result.details().summary().state());
assertEquals(PackerBuildParticipation.EXCLUDED, result.details().summary().buildParticipation());
assertTrue(result.diagnostics().stream().anyMatch(diagnostic -> diagnostic.message().contains("could not be resolved")));
}
private PackerProjectContext project(Path root) {
return new PackerProjectContext("main", root);
}
private PackerAssetDetailsService service() {
final var foundation = new p.packer.services.PackerWorkspaceFoundation();
final var parser = new PackerAssetDeclarationParser(new ObjectMapper());
final var runtimeRegistry = new PackerRuntimeRegistry(new PackerRuntimeLoader(foundation, parser));
final var resolver = new PackerAssetReferenceResolver(foundation.lookup());
return new PackerAssetDetailsService(runtimeRegistry, resolver);
}
private Path copyFixture(String relativePath, Path targetRoot) throws Exception {
final Path sourceRoot = PackerFixtureLocator.fixtureRoot(relativePath);
try (var stream = Files.walk(sourceRoot)) {
for (Path source : stream.sorted(Comparator.naturalOrder()).toList()) {
final Path target = targetRoot.resolve(sourceRoot.relativize(source).toString());
if (Files.isDirectory(source)) {
Files.createDirectories(target);
} else {
Files.createDirectories(target.getParent());
Files.copy(source, target);
}
}
}
return targetRoot;
}
}