mirror of
https://github.com/imgfloat/server.git
synced 2026-05-08 10:19:35 +00:00
Add tests for VersionService, GithubReleaseService, AuditLogService, AuthorizationService, MarketplaceScriptSeedLoader; fix duplicate import in ChannelDirectoryService
This commit is contained in:
@@ -8,7 +8,6 @@ import dev.kruhlmann.imgfloat.model.api.request.AssetOrderRequest;
|
||||
import dev.kruhlmann.imgfloat.model.api.request.CanvasSettingsRequest;
|
||||
import dev.kruhlmann.imgfloat.model.api.request.ChannelScriptSettingsRequest;
|
||||
import dev.kruhlmann.imgfloat.model.api.request.CodeAssetRequest;
|
||||
import dev.kruhlmann.imgfloat.model.api.request.AssetOrderRequest;
|
||||
import dev.kruhlmann.imgfloat.model.api.request.PlaybackRequest;
|
||||
import dev.kruhlmann.imgfloat.model.api.request.TransformRequest;
|
||||
import dev.kruhlmann.imgfloat.model.api.request.VisibilityRequest;
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
package dev.kruhlmann.imgfloat.service;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import dev.kruhlmann.imgfloat.model.db.audit.AuditLogEntry;
|
||||
import dev.kruhlmann.imgfloat.repository.audit.AuditLogRepository;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class AuditLogServiceTest {
|
||||
|
||||
private AuditLogRepository repository;
|
||||
private AuditLogService service;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
repository = mock(AuditLogRepository.class);
|
||||
service = new AuditLogService(repository);
|
||||
}
|
||||
|
||||
@Test
|
||||
void recordEntryPersistesNormalizedEntry() {
|
||||
service.recordEntry("BroadCaster", "Actor", "ACTION", "some details");
|
||||
|
||||
ArgumentCaptor<AuditLogEntry> captor = ArgumentCaptor.forClass(AuditLogEntry.class);
|
||||
verify(repository).save(captor.capture());
|
||||
AuditLogEntry entry = captor.getValue();
|
||||
assertThat(entry.getBroadcaster()).isEqualTo("broadcaster");
|
||||
assertThat(entry.getActor()).isEqualTo("actor");
|
||||
assertThat(entry.getAction()).isEqualTo("ACTION");
|
||||
assertThat(entry.getDetails()).isEqualTo("some details");
|
||||
}
|
||||
|
||||
@Test
|
||||
void recordEntrySkipsBlankBroadcaster() {
|
||||
service.recordEntry(" ", "actor", "ACTION", "details");
|
||||
verify(repository, never()).save(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void recordEntrySkipsNullBroadcaster() {
|
||||
service.recordEntry(null, "actor", "ACTION", "details");
|
||||
verify(repository, never()).save(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void recordEntryUsesDefaultActorWhenNull() {
|
||||
service.recordEntry("broadcaster", null, "ACTION", "details");
|
||||
|
||||
ArgumentCaptor<AuditLogEntry> captor = ArgumentCaptor.forClass(AuditLogEntry.class);
|
||||
verify(repository).save(captor.capture());
|
||||
assertThat(captor.getValue().getActor()).isEqualTo("system");
|
||||
}
|
||||
|
||||
@Test
|
||||
void recordEntryUsesDefaultActorWhenBlank() {
|
||||
service.recordEntry("broadcaster", " ", "ACTION", "details");
|
||||
|
||||
ArgumentCaptor<AuditLogEntry> captor = ArgumentCaptor.forClass(AuditLogEntry.class);
|
||||
verify(repository).save(captor.capture());
|
||||
assertThat(captor.getValue().getActor()).isEqualTo("system");
|
||||
}
|
||||
|
||||
@Test
|
||||
void recordEntryDoesNotThrowWhenRepositoryFails() {
|
||||
doThrow(new DataAccessResourceFailureException("db down")).when(repository).save(any());
|
||||
// Must not propagate
|
||||
service.recordEntry("broadcaster", "actor", "ACTION", "details");
|
||||
}
|
||||
|
||||
@Test
|
||||
void listEntriesReturnsEmptyPageForBlankBroadcaster() {
|
||||
Page<AuditLogEntry> result = service.listEntries(" ", null, null, null, 0, 20);
|
||||
assertThat(result.isEmpty()).isTrue();
|
||||
verify(repository, never()).searchEntries(any(), any(), any(), any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void listEntriesClampsSizeAndDelegatesToRepository() {
|
||||
when(repository.searchEntries(any(), any(), any(), any(), any()))
|
||||
.thenReturn(new PageImpl<>(List.of()));
|
||||
|
||||
service.listEntries("broadcaster", null, null, null, 0, 999);
|
||||
|
||||
ArgumentCaptor<Pageable> pageableCaptor = ArgumentCaptor.forClass(Pageable.class);
|
||||
verify(repository).searchEntries(any(), any(), any(), any(), pageableCaptor.capture());
|
||||
assertThat(pageableCaptor.getValue().getPageSize()).isEqualTo(200);
|
||||
}
|
||||
|
||||
@Test
|
||||
void deleteEntriesForBroadcasterDelegatesToRepository() {
|
||||
service.deleteEntriesForBroadcaster("Broadcaster");
|
||||
verify(repository).deleteByBroadcaster("broadcaster");
|
||||
}
|
||||
|
||||
@Test
|
||||
void deleteEntriesSkipsBlankBroadcaster() {
|
||||
service.deleteEntriesForBroadcaster(" ");
|
||||
verify(repository, never()).deleteByBroadcaster(any());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
package dev.kruhlmann.imgfloat.service;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
|
||||
class AuthorizationServiceTest {
|
||||
|
||||
private ChannelDirectoryService channelDirectoryService;
|
||||
private SystemAdministratorService sysadminService;
|
||||
private AuthorizationService authorizationService;
|
||||
private AuthorizationService authorizationServiceSysadminDisabled;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
channelDirectoryService = mock(ChannelDirectoryService.class);
|
||||
sysadminService = mock(SystemAdministratorService.class);
|
||||
authorizationService = new AuthorizationService(channelDirectoryService, sysadminService, true);
|
||||
authorizationServiceSysadminDisabled = new AuthorizationService(channelDirectoryService, sysadminService, false);
|
||||
}
|
||||
|
||||
// --- userMatchesSessionUsernameOrThrowHttpError ---
|
||||
|
||||
@Test
|
||||
void matchesSessionUsernamePassesWhenEqual() {
|
||||
// must not throw
|
||||
authorizationService.userMatchesSessionUsernameOrThrowHttpError("alice", "alice");
|
||||
}
|
||||
|
||||
@Test
|
||||
void matchesSessionUsernameThrowsWhenSessionNull() {
|
||||
assertThatThrownBy(() -> authorizationService.userMatchesSessionUsernameOrThrowHttpError("alice", null))
|
||||
.isInstanceOf(ResponseStatusException.class)
|
||||
.hasMessageContaining("logged in");
|
||||
}
|
||||
|
||||
@Test
|
||||
void matchesSessionUsernameThrowsWhenSubmittedNull() {
|
||||
assertThatThrownBy(() -> authorizationService.userMatchesSessionUsernameOrThrowHttpError(null, "alice"))
|
||||
.isInstanceOf(ResponseStatusException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void matchesSessionUsernameThrowsWhenDifferent() {
|
||||
assertThatThrownBy(() -> authorizationService.userMatchesSessionUsernameOrThrowHttpError("alice", "bob"))
|
||||
.isInstanceOf(ResponseStatusException.class)
|
||||
.hasMessageContaining("not this user");
|
||||
}
|
||||
|
||||
// --- userIsBroadcaster ---
|
||||
|
||||
@Test
|
||||
void userIsBroadcasterReturnsTrueWhenEqual() {
|
||||
assertThat(authorizationService.userIsBroadcaster("alice", "alice")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void userIsBroadcasterReturnsFalseWhenDifferent() {
|
||||
assertThat(authorizationService.userIsBroadcaster("alice", "bob")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void userIsBroadcasterReturnsFalseWhenEitherNull() {
|
||||
assertThat(authorizationService.userIsBroadcaster(null, "alice")).isFalse();
|
||||
assertThat(authorizationService.userIsBroadcaster("alice", null)).isFalse();
|
||||
}
|
||||
|
||||
// --- userIsChannelAdminForBroadcaster ---
|
||||
|
||||
@Test
|
||||
void channelAdminCheckDelegatesToChannelDirectoryService() {
|
||||
when(channelDirectoryService.isAdmin("broadcaster", "alice")).thenReturn(true);
|
||||
assertThat(authorizationService.userIsChannelAdminForBroadcaster("broadcaster", "alice")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void channelAdminCheckReturnsFalseWhenNull() {
|
||||
assertThat(authorizationService.userIsChannelAdminForBroadcaster(null, "alice")).isFalse();
|
||||
assertThat(authorizationService.userIsChannelAdminForBroadcaster("broadcaster", null)).isFalse();
|
||||
}
|
||||
|
||||
// --- userIsSystemAdministrator ---
|
||||
|
||||
@Test
|
||||
void sysadminCheckDelegatesToSysadminService() {
|
||||
when(sysadminService.isSysadmin("admin")).thenReturn(true);
|
||||
assertThat(authorizationService.userIsSystemAdministrator("admin")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void sysadminCheckReturnsFalseWhenNull() {
|
||||
assertThat(authorizationService.userIsSystemAdministrator(null)).isFalse();
|
||||
}
|
||||
|
||||
// --- userIsBroadcasterOrChannelAdmin ---
|
||||
|
||||
@Test
|
||||
void allowsWhenBroadcasterMatchesSelf() {
|
||||
assertThat(authorizationService.userIsBroadcasterOrChannelAdminForBroadcaster("alice", "alice")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void allowsChannelAdmin() {
|
||||
when(channelDirectoryService.isAdmin("broadcaster", "admin")).thenReturn(true);
|
||||
assertThat(authorizationService.userIsBroadcasterOrChannelAdminForBroadcaster("broadcaster", "admin")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void allowsSysadminWhenAccessEnabled() {
|
||||
when(sysadminService.isSysadmin("sysadmin")).thenReturn(true);
|
||||
assertThat(authorizationService.userIsBroadcasterOrChannelAdminForBroadcaster("broadcaster", "sysadmin")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void deniedSysadminWhenAccessDisabled() {
|
||||
when(sysadminService.isSysadmin("sysadmin")).thenReturn(true);
|
||||
when(channelDirectoryService.isAdmin("broadcaster", "sysadmin")).thenReturn(false);
|
||||
assertThat(authorizationServiceSysadminDisabled.userIsBroadcasterOrChannelAdminForBroadcaster("broadcaster", "sysadmin")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void deniesRandomUser() {
|
||||
when(channelDirectoryService.isAdmin("broadcaster", "random")).thenReturn(false);
|
||||
when(sysadminService.isSysadmin("random")).thenReturn(false);
|
||||
assertThat(authorizationService.userIsBroadcasterOrChannelAdminForBroadcaster("broadcaster", "random")).isFalse();
|
||||
}
|
||||
|
||||
// --- throw-based wrappers ---
|
||||
|
||||
@Test
|
||||
void throwsWhenNotBroadcasterOrAdmin() {
|
||||
when(channelDirectoryService.isAdmin("broadcaster", "random")).thenReturn(false);
|
||||
when(sysadminService.isSysadmin("random")).thenReturn(false);
|
||||
assertThatThrownBy(
|
||||
() -> authorizationService.userIsBroadcasterOrChannelAdminForBroadcasterOrThrowHttpError("broadcaster", "random")
|
||||
).isInstanceOf(ResponseStatusException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void throwsWhenNotSysadmin() {
|
||||
when(sysadminService.isSysadmin("user")).thenReturn(false);
|
||||
assertThatThrownBy(() -> authorizationService.userIsSystemAdministratorOrThrowHttpError("user"))
|
||||
.isInstanceOf(ResponseStatusException.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package dev.kruhlmann.imgfloat.service;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class GithubReleaseServiceTest {
|
||||
|
||||
@Test
|
||||
void returnsDownloadBaseUrlWhenConfigured() {
|
||||
GithubReleaseService service = new GithubReleaseService("imgfloat", "client", "1.2.3");
|
||||
String url = service.getDownloadBaseUrl();
|
||||
assertThat(url).startsWith("https://github.com/imgfloat/client/releases/download/v1.2.3/");
|
||||
}
|
||||
|
||||
@Test
|
||||
void stripsLeadingVFromVersion() {
|
||||
GithubReleaseService service = new GithubReleaseService("imgfloat", "client", "v1.2.3");
|
||||
assertThat(service.getDownloadBaseUrl()).contains("/v1.2.3/");
|
||||
assertThat(service.getClientReleaseVersion()).isEqualTo("1.2.3");
|
||||
}
|
||||
|
||||
@Test
|
||||
void stripsSnapshotSuffix() {
|
||||
GithubReleaseService service = new GithubReleaseService("imgfloat", "client", "1.2.3-SNAPSHOT");
|
||||
assertThat(service.getClientReleaseVersion()).isEqualTo("1.2.3");
|
||||
assertThat(service.getDownloadBaseUrl()).contains("/v1.2.3/");
|
||||
}
|
||||
|
||||
@Test
|
||||
void throwsWhenOwnerMissing() {
|
||||
GithubReleaseService service = new GithubReleaseService(null, "client", "1.0.0");
|
||||
assertThatThrownBy(service::getDownloadBaseUrl)
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessageContaining("GitHub client configuration");
|
||||
}
|
||||
|
||||
@Test
|
||||
void throwsWhenRepoMissing() {
|
||||
GithubReleaseService service = new GithubReleaseService("imgfloat", null, "1.0.0");
|
||||
assertThatThrownBy(service::getDownloadBaseUrl).isInstanceOf(IllegalStateException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void throwsWhenVersionMissing() {
|
||||
GithubReleaseService service = new GithubReleaseService("imgfloat", "client", null);
|
||||
assertThatThrownBy(service::getDownloadBaseUrl).isInstanceOf(IllegalStateException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void throwsWhenVersionBlank() {
|
||||
GithubReleaseService service = new GithubReleaseService("imgfloat", "client", " ");
|
||||
assertThatThrownBy(service::getDownloadBaseUrl).isInstanceOf(IllegalStateException.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
package dev.kruhlmann.imgfloat.service;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import dev.kruhlmann.imgfloat.model.api.response.ScriptMarketplaceEntry;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
class MarketplaceScriptSeedLoaderTest {
|
||||
|
||||
@TempDir
|
||||
Path tempDir;
|
||||
|
||||
private void writeScript(Path dir, String name, String description, String source) throws IOException {
|
||||
Files.createDirectories(dir);
|
||||
String metaJson = description != null
|
||||
? "{\"name\":\"" + name + "\",\"description\":\"" + description + "\"}"
|
||||
: "{\"name\":\"" + name + "\"}";
|
||||
Files.writeString(dir.resolve("metadata.json"), metaJson);
|
||||
Files.writeString(dir.resolve("source.js"), source);
|
||||
}
|
||||
|
||||
@Test
|
||||
void returnsEmptyListWhenRootPathIsNonExistentDirectory() throws IOException {
|
||||
// Pass a path that does not exist and is not the fallback doc/marketplace-scripts
|
||||
Path nonExistent = tempDir.resolve("does-not-exist");
|
||||
MarketplaceScriptSeedLoader loader = new MarketplaceScriptSeedLoader(nonExistent.toString());
|
||||
assertThat(loader.listEntriesForQuery(null)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadsScriptFromDirectory() throws IOException {
|
||||
Path scriptDir = tempDir.resolve("my-script");
|
||||
writeScript(scriptDir, "My Script", "A test script", "console.log('hi');");
|
||||
|
||||
MarketplaceScriptSeedLoader loader = new MarketplaceScriptSeedLoader(tempDir.toString());
|
||||
List<ScriptMarketplaceEntry> entries = loader.listEntriesForQuery(null);
|
||||
|
||||
assertThat(entries).hasSize(1);
|
||||
assertThat(entries.get(0).id()).isEqualTo("my-script");
|
||||
assertThat(entries.get(0).name()).isEqualTo("My Script");
|
||||
assertThat(entries.get(0).description()).isEqualTo("A test script");
|
||||
}
|
||||
|
||||
@Test
|
||||
void skipsDirectoryWithMissingMetadata() throws IOException {
|
||||
Path scriptDir = tempDir.resolve("no-meta");
|
||||
Files.createDirectories(scriptDir);
|
||||
Files.writeString(scriptDir.resolve("source.js"), "/* source */");
|
||||
|
||||
MarketplaceScriptSeedLoader loader = new MarketplaceScriptSeedLoader(tempDir.toString());
|
||||
assertThat(loader.listEntriesForQuery(null)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void skipsDirectoryWithMissingSourceJs() throws IOException {
|
||||
Path scriptDir = tempDir.resolve("no-source");
|
||||
Files.createDirectories(scriptDir);
|
||||
Files.writeString(scriptDir.resolve("metadata.json"), "{\"name\":\"Test\"}");
|
||||
|
||||
MarketplaceScriptSeedLoader loader = new MarketplaceScriptSeedLoader(tempDir.toString());
|
||||
assertThat(loader.listEntriesForQuery(null)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void skipsDirectoryWithBlankName() throws IOException {
|
||||
Path scriptDir = tempDir.resolve("blank-name");
|
||||
Files.createDirectories(scriptDir);
|
||||
Files.writeString(scriptDir.resolve("metadata.json"), "{\"name\":\" \"}");
|
||||
Files.writeString(scriptDir.resolve("source.js"), "/* source */");
|
||||
|
||||
MarketplaceScriptSeedLoader loader = new MarketplaceScriptSeedLoader(tempDir.toString());
|
||||
assertThat(loader.listEntriesForQuery(null)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void filtersByQueryOnNameAndDescription() throws IOException {
|
||||
Path dir1 = tempDir.resolve("alpha-script");
|
||||
writeScript(dir1, "Alpha Script", "does alpha things", "/* */");
|
||||
Path dir2 = tempDir.resolve("beta-script");
|
||||
writeScript(dir2, "Beta Script", "does beta things", "/* */");
|
||||
|
||||
MarketplaceScriptSeedLoader loader = new MarketplaceScriptSeedLoader(tempDir.toString());
|
||||
assertThat(loader.listEntriesForQuery("alpha")).hasSize(1);
|
||||
assertThat(loader.listEntriesForQuery("beta")).hasSize(1);
|
||||
assertThat(loader.listEntriesForQuery("script")).hasSize(2);
|
||||
assertThat(loader.listEntriesForQuery("zzznotfound")).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void findByIdReturnsCorrectScript() throws IOException {
|
||||
Path scriptDir = tempDir.resolve("find-me");
|
||||
writeScript(scriptDir, "Find Me", null, "/* */");
|
||||
|
||||
MarketplaceScriptSeedLoader loader = new MarketplaceScriptSeedLoader(tempDir.toString());
|
||||
Optional<MarketplaceScriptSeedLoader.SeedScript> found = loader.findById("find-me");
|
||||
assertThat(found).isPresent();
|
||||
assertThat(found.get().name()).isEqualTo("Find Me");
|
||||
}
|
||||
|
||||
@Test
|
||||
void findByIdReturnsEmptyForUnknownId() throws IOException {
|
||||
MarketplaceScriptSeedLoader loader = new MarketplaceScriptSeedLoader(tempDir.toString());
|
||||
assertThat(loader.findById("does-not-exist")).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadsLogoWhenPresent() throws IOException {
|
||||
Path scriptDir = tempDir.resolve("with-logo");
|
||||
writeScript(scriptDir, "With Logo", null, "/* */");
|
||||
// write a minimal PNG (1x1 white pixel)
|
||||
byte[] minimalPng = new byte[]{
|
||||
(byte)0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, // PNG signature
|
||||
0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, // IHDR chunk
|
||||
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
|
||||
0x08, 0x02, 0x00, 0x00, 0x00, (byte)0x90, 0x77, 0x53,
|
||||
(byte)0xde, 0x00, 0x00, 0x00, 0x0c, 0x49, 0x44, 0x41, // IDAT chunk
|
||||
0x54, 0x08, (byte)0xd7, 0x63, (byte)0xf8, (byte)0xcf, (byte)0xc0, 0x00,
|
||||
0x00, 0x00, 0x02, 0x00, 0x01, (byte)0xe2, 0x21, (byte)0xbc,
|
||||
0x33, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, // IEND chunk
|
||||
0x44, (byte)0xae, 0x42, 0x60, (byte)0x82
|
||||
};
|
||||
Files.write(scriptDir.resolve("logo.png"), minimalPng);
|
||||
|
||||
MarketplaceScriptSeedLoader loader = new MarketplaceScriptSeedLoader(tempDir.toString());
|
||||
Optional<MarketplaceScriptSeedLoader.SeedScript> found = loader.findById("with-logo");
|
||||
assertThat(found).isPresent();
|
||||
assertThat(found.get().loadLogo()).isPresent();
|
||||
assertThat(found.get().entry().logoUrl()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void normalizesAllowedDomains() throws IOException {
|
||||
Path scriptDir = tempDir.resolve("domains-script");
|
||||
Files.createDirectories(scriptDir);
|
||||
Files.writeString(scriptDir.resolve("metadata.json"),
|
||||
"{\"name\":\"Domains\",\"allowedDomains\":[\"EXAMPLE.COM\",\"api.foo.bar:8080\",\"duplicate.com\",\"duplicate.com\"]}");
|
||||
Files.writeString(scriptDir.resolve("source.js"), "/* */");
|
||||
|
||||
MarketplaceScriptSeedLoader loader = new MarketplaceScriptSeedLoader(tempDir.toString());
|
||||
Optional<MarketplaceScriptSeedLoader.SeedScript> found = loader.findById("domains-script");
|
||||
assertThat(found).isPresent();
|
||||
List<String> domains = found.get().allowedDomains();
|
||||
assertThat(domains).contains("example.com", "api.foo.bar:8080");
|
||||
assertThat(domains).doesNotHaveDuplicates();
|
||||
assertThat(domains).hasSize(3); // EXAMPLE.COM + api.foo.bar:8080 + duplicate.com (deduped)
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadsSourceContent() throws IOException {
|
||||
Path scriptDir = tempDir.resolve("source-test");
|
||||
writeScript(scriptDir, "Source Test", null, "console.log('loaded');");
|
||||
|
||||
MarketplaceScriptSeedLoader loader = new MarketplaceScriptSeedLoader(tempDir.toString());
|
||||
Optional<MarketplaceScriptSeedLoader.SeedScript> found = loader.findById("source-test");
|
||||
assertThat(found).isPresent();
|
||||
assertThat(found.get().loadSource()).isPresent();
|
||||
assertThat(new String(found.get().loadSource().get().bytes())).contains("loaded");
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadsAttachments() throws IOException {
|
||||
Path scriptDir = tempDir.resolve("with-attachments");
|
||||
writeScript(scriptDir, "With Attachments", null, "/* */");
|
||||
Path attachmentsDir = scriptDir.resolve("attachments");
|
||||
Files.createDirectories(attachmentsDir);
|
||||
Files.writeString(attachmentsDir.resolve("data.json"), "{\"key\":\"value\"}");
|
||||
|
||||
MarketplaceScriptSeedLoader loader = new MarketplaceScriptSeedLoader(tempDir.toString());
|
||||
Optional<MarketplaceScriptSeedLoader.SeedScript> found = loader.findById("with-attachments");
|
||||
assertThat(found).isPresent();
|
||||
assertThat(found.get().attachments()).hasSize(1);
|
||||
assertThat(found.get().attachments().get(0).name()).isEqualTo("data.json");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package dev.kruhlmann.imgfloat.service;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class VersionServiceTest {
|
||||
|
||||
@Test
|
||||
void returnsVersionWhenPomXmlPresent() {
|
||||
// VersionService reads pom.xml from the filesystem during development;
|
||||
// in the test classpath pom.xml is available at the project root.
|
||||
VersionService service = new VersionService();
|
||||
String version = service.getVersion();
|
||||
assertThat(version).isNotBlank();
|
||||
// Should look like a semver string, not "unknown" or empty
|
||||
assertThat(version).matches("[0-9]+\\.[0-9]+.*");
|
||||
}
|
||||
|
||||
@Test
|
||||
void versionIsConsistentAcrossCalls() {
|
||||
VersionService service = new VersionService();
|
||||
assertThat(service.getVersion()).isEqualTo(service.getVersion());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user