test: update all tests for Ed25519 license minting and tier rename
- LicenseServiceTest: mock SigningKeyService, assert signed token format - VendorTenantServiceTest: add SigningKeyService mock, update mintLicense stubs - All tests: LOW→STARTER, MID→TEAM, HIGH→BUSINESS, BUSINESS→ENTERPRISE - Remove all features-related test assertions - 80/80 tests passing Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -35,7 +35,7 @@ class LicenseControllerTest {
|
||||
|
||||
private String createTenantAndGetId() throws Exception {
|
||||
String slug = "license-tenant-" + System.nanoTime();
|
||||
var request = new CreateTenantRequest("License Test Org", slug, "MID", null, null);
|
||||
var request = new CreateTenantRequest("License Test Org", slug, "TEAM", null, null);
|
||||
|
||||
var result = mockMvc.perform(post("/api/tenants")
|
||||
.with(jwt().jwt(j -> j
|
||||
@@ -60,8 +60,7 @@ class LicenseControllerTest {
|
||||
new SimpleGrantedAuthority("SCOPE_platform:admin"))))
|
||||
.andExpect(status().isCreated())
|
||||
.andExpect(jsonPath("$.token").isNotEmpty())
|
||||
.andExpect(jsonPath("$.tier").value("MID"))
|
||||
.andExpect(jsonPath("$.features.correlation").value(true));
|
||||
.andExpect(jsonPath("$.tier").value("TEAM"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -78,7 +77,7 @@ class LicenseControllerTest {
|
||||
.with(jwt().jwt(j -> j.claim("sub", "test-user"))
|
||||
.authorities(new SimpleGrantedAuthority("SCOPE_platform:admin"))))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.tier").value("MID"));
|
||||
.andExpect(jsonPath("$.tier").value("TEAM"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -12,8 +12,10 @@ import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.time.Duration;
|
||||
import java.util.Optional;
|
||||
import java.util.Base64;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -30,11 +32,26 @@ class LicenseServiceTest {
|
||||
@Mock
|
||||
private AuditService auditService;
|
||||
|
||||
@Mock
|
||||
private SigningKeyService signingKeyService;
|
||||
|
||||
private LicenseService licenseService;
|
||||
|
||||
private KeyPair testKeyPair;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
licenseService = new LicenseService(licenseRepository, auditService);
|
||||
void setUp() throws Exception {
|
||||
licenseService = new LicenseService(licenseRepository, auditService, signingKeyService);
|
||||
testKeyPair = KeyPairGenerator.getInstance("Ed25519").generateKeyPair();
|
||||
}
|
||||
|
||||
private void stubPrivateKey() {
|
||||
when(signingKeyService.getPrivateKey()).thenReturn(testKeyPair.getPrivate());
|
||||
}
|
||||
|
||||
private void stubPublicKey() {
|
||||
when(signingKeyService.getPublicKeyBase64()).thenReturn(
|
||||
Base64.getEncoder().encodeToString(testKeyPair.getPublic().getEncoded()));
|
||||
}
|
||||
|
||||
private TenantEntity createTenant(Tier tier) {
|
||||
@@ -65,69 +82,71 @@ class LicenseServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void generateLicense_producesUuidToken() {
|
||||
var tenant = createTenant(Tier.MID);
|
||||
void generateLicense_producesSignedToken() {
|
||||
var tenant = createTenant(Tier.TEAM);
|
||||
stubPrivateKey();
|
||||
when(licenseRepository.save(any(LicenseEntity.class))).thenAnswer(inv -> withGeneratedId(inv.getArgument(0)));
|
||||
|
||||
var license = licenseService.generateLicense(tenant, Duration.ofDays(365), UUID.randomUUID());
|
||||
|
||||
assertThat(license.getToken()).isNotBlank();
|
||||
// Token must be a valid UUID string
|
||||
assertThat(UUID.fromString(license.getToken())).isNotNull();
|
||||
assertThat(license.getTier()).isEqualTo("MID");
|
||||
}
|
||||
|
||||
@Test
|
||||
void generateLicense_setsCorrectFeaturesForTier() {
|
||||
var tenant = createTenant(Tier.HIGH);
|
||||
when(licenseRepository.save(any(LicenseEntity.class))).thenAnswer(inv -> withGeneratedId(inv.getArgument(0)));
|
||||
|
||||
var license = licenseService.generateLicense(tenant, Duration.ofDays(30), UUID.randomUUID());
|
||||
|
||||
assertThat(license.getFeatures()).containsEntry("debugger", true);
|
||||
assertThat(license.getFeatures()).containsEntry("replay", true);
|
||||
// Ed25519 signed token contains a '.' separator between payload and signature
|
||||
assertThat(license.getToken()).contains(".");
|
||||
assertThat(license.getTier()).isEqualTo("TEAM");
|
||||
}
|
||||
|
||||
@Test
|
||||
void generateLicense_setsCorrectLimitsForTier() {
|
||||
var tenant = createTenant(Tier.LOW);
|
||||
var tenant = createTenant(Tier.STARTER);
|
||||
stubPrivateKey();
|
||||
when(licenseRepository.save(any(LicenseEntity.class))).thenAnswer(inv -> withGeneratedId(inv.getArgument(0)));
|
||||
|
||||
var license = licenseService.generateLicense(tenant, Duration.ofDays(30), UUID.randomUUID());
|
||||
|
||||
assertThat(license.getLimits()).containsEntry("max_agents", 3);
|
||||
assertThat(license.getLimits()).containsEntry("retention_days", 7);
|
||||
assertThat(license.getLimits()).containsEntry("max_agents", 20);
|
||||
assertThat(license.getLimits()).containsEntry("max_environments", 2);
|
||||
assertThat(license.getLimits()).containsEntry("max_execution_retention_days", 7);
|
||||
}
|
||||
|
||||
@Test
|
||||
void verifyLicenseToken_validTokenReturnsPayload() {
|
||||
var tenant = createTenant(Tier.MID);
|
||||
void generateLicense_setsGracePeriodAndLabel() {
|
||||
var tenant = createTenant(Tier.BUSINESS);
|
||||
stubPrivateKey();
|
||||
when(licenseRepository.save(any(LicenseEntity.class))).thenAnswer(inv -> withGeneratedId(inv.getArgument(0)));
|
||||
|
||||
var license = licenseService.generateLicense(tenant, Duration.ofDays(365), UUID.randomUUID());
|
||||
|
||||
assertThat(license.getGracePeriodDays()).isEqualTo(LicenseDefaults.DEFAULT_GRACE_PERIOD_DAYS);
|
||||
assertThat(license.getLabel()).contains("Test Tenant");
|
||||
}
|
||||
|
||||
@Test
|
||||
void verifyToken_validTokenReturnsLicenseInfo() {
|
||||
var tenant = createTenant(Tier.TEAM);
|
||||
stubPrivateKey();
|
||||
stubPublicKey();
|
||||
when(licenseRepository.save(any(LicenseEntity.class))).thenAnswer(inv -> withGeneratedId(inv.getArgument(0)));
|
||||
|
||||
var license = licenseService.generateLicense(tenant, Duration.ofDays(30), UUID.randomUUID());
|
||||
|
||||
when(licenseRepository.findByToken(license.getToken())).thenReturn(Optional.of(license));
|
||||
var result = licenseService.verifyToken(license.getToken(), "test");
|
||||
|
||||
var payload = licenseService.verifyLicenseToken(license.getToken());
|
||||
|
||||
assertThat(payload).isPresent();
|
||||
assertThat(payload.get().get("tier")).isEqualTo("MID");
|
||||
assertThat(payload.get().get("tenant_id")).isEqualTo(tenant.getId().toString());
|
||||
assertThat(result).isPresent();
|
||||
assertThat(result.get().tenantId()).isEqualTo("test");
|
||||
}
|
||||
|
||||
@Test
|
||||
void verifyLicenseToken_unknownTokenReturnsEmpty() {
|
||||
when(licenseRepository.findByToken(any())).thenReturn(Optional.empty());
|
||||
|
||||
var payload = licenseService.verifyLicenseToken("unknown-token");
|
||||
|
||||
assertThat(payload).isEmpty();
|
||||
void verifyToken_invalidTokenReturnsEmpty() {
|
||||
stubPublicKey();
|
||||
var result = licenseService.verifyToken("invalid-token", "test");
|
||||
assertThat(result).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void generateLicense_logsAuditEvent() {
|
||||
var tenant = createTenant(Tier.LOW);
|
||||
var tenant = createTenant(Tier.STARTER);
|
||||
var actorId = UUID.randomUUID();
|
||||
stubPrivateKey();
|
||||
when(licenseRepository.save(any(LicenseEntity.class))).thenAnswer(inv -> withGeneratedId(inv.getArgument(0)));
|
||||
|
||||
licenseService.generateLicense(tenant, Duration.ofDays(30), actorId);
|
||||
|
||||
@@ -52,7 +52,7 @@ class TenantPortalControllerTest {
|
||||
var tenant = new TenantEntity();
|
||||
tenant.setName(name);
|
||||
tenant.setSlug(slug);
|
||||
tenant.setTier(Tier.LOW);
|
||||
tenant.setTier(Tier.STARTER);
|
||||
tenant.setStatus(TenantStatus.ACTIVE);
|
||||
tenant.setLogtoOrgId(orgId);
|
||||
return tenantRepository.save(tenant);
|
||||
|
||||
@@ -85,8 +85,8 @@ class TenantPortalServiceTest {
|
||||
license.setToken("test-token-" + UUID.randomUUID());
|
||||
license.setIssuedAt(Instant.now());
|
||||
license.setExpiresAt(expiresAt);
|
||||
license.setFeatures(Map.of("feature1", true));
|
||||
license.setLimits(Map.of("maxApps", 10));
|
||||
license.setLimits(Map.of("max_apps", 10));
|
||||
license.setGracePeriodDays(14);
|
||||
var f = LicenseEntity.class.getDeclaredField("id");
|
||||
f.setAccessible(true);
|
||||
f.set(license, UUID.randomUUID());
|
||||
@@ -97,10 +97,10 @@ class TenantPortalServiceTest {
|
||||
|
||||
@Test
|
||||
void getDashboard_returnsDashboardData() throws Exception {
|
||||
var tenant = tenantWithId("Acme Corp", "acme-corp", Tier.LOW, TenantStatus.ACTIVE);
|
||||
var tenant = tenantWithId("Acme Corp", "acme-corp", Tier.STARTER, TenantStatus.ACTIVE);
|
||||
tenant.setServerEndpoint("http://server:8080");
|
||||
var expiresAt = Instant.now().plus(Duration.ofDays(30));
|
||||
var license = licenseWithId(tenantId, "LOW", expiresAt);
|
||||
var license = licenseWithId(tenantId, "STARTER", expiresAt);
|
||||
|
||||
when(tenantService.getById(tenantId)).thenReturn(Optional.of(tenant));
|
||||
when(serverApiClient.getHealth("http://server:8080")).thenReturn(new ServerHealthResponse(true, "UP"));
|
||||
@@ -112,22 +112,21 @@ class TenantPortalServiceTest {
|
||||
|
||||
assertThat(result.name()).isEqualTo("Acme Corp");
|
||||
assertThat(result.slug()).isEqualTo("acme-corp");
|
||||
assertThat(result.tier()).isEqualTo("LOW");
|
||||
assertThat(result.tier()).isEqualTo("STARTER");
|
||||
assertThat(result.status()).isEqualTo("ACTIVE");
|
||||
assertThat(result.serverHealthy()).isTrue();
|
||||
assertThat(result.serverStatus()).isEqualTo("UP");
|
||||
assertThat(result.serverEndpoint()).isEqualTo("http://server:8080");
|
||||
assertThat(result.licenseTier()).isEqualTo("LOW");
|
||||
assertThat(result.licenseTier()).isEqualTo("STARTER");
|
||||
assertThat(result.licenseDaysRemaining()).isGreaterThanOrEqualTo(29);
|
||||
assertThat(result.limits()).isNotEmpty();
|
||||
assertThat(result.features()).isNotEmpty();
|
||||
assertThat(result.agentCount()).isEqualTo(3);
|
||||
assertThat(result.environmentCount()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getDashboard_handlesNoServer() throws Exception {
|
||||
var tenant = tenantWithId("Acme Corp", "acme-corp", Tier.LOW, TenantStatus.PROVISIONING);
|
||||
var tenant = tenantWithId("Acme Corp", "acme-corp", Tier.STARTER, TenantStatus.PROVISIONING);
|
||||
// serverEndpoint is null by default
|
||||
|
||||
when(tenantService.getById(tenantId)).thenReturn(Optional.of(tenant));
|
||||
@@ -148,9 +147,9 @@ class TenantPortalServiceTest {
|
||||
|
||||
@Test
|
||||
void getLicense_returnsLicenseData() throws Exception {
|
||||
var tenant = tenantWithId("Acme Corp", "acme-corp", Tier.LOW, TenantStatus.ACTIVE);
|
||||
var tenant = tenantWithId("Acme Corp", "acme-corp", Tier.STARTER, TenantStatus.ACTIVE);
|
||||
var expiresAt = Instant.now().plus(Duration.ofDays(60));
|
||||
var license = licenseWithId(tenantId, "LOW", expiresAt);
|
||||
var license = licenseWithId(tenantId, "STARTER", expiresAt);
|
||||
|
||||
when(tenantService.getById(tenantId)).thenReturn(Optional.of(tenant));
|
||||
when(licenseService.getActiveLicense(tenantId)).thenReturn(Optional.of(license));
|
||||
@@ -159,18 +158,18 @@ class TenantPortalServiceTest {
|
||||
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.id()).isEqualTo(license.getId());
|
||||
assertThat(result.tier()).isEqualTo("LOW");
|
||||
assertThat(result.tier()).isEqualTo("STARTER");
|
||||
assertThat(result.token()).isEqualTo(license.getToken());
|
||||
assertThat(result.issuedAt()).isEqualTo(license.getIssuedAt());
|
||||
assertThat(result.expiresAt()).isEqualTo(expiresAt);
|
||||
assertThat(result.daysRemaining()).isGreaterThanOrEqualTo(59);
|
||||
assertThat(result.features()).isEqualTo(Map.of("feature1", true));
|
||||
assertThat(result.limits()).isEqualTo(Map.of("maxApps", 10));
|
||||
assertThat(result.limits()).isEqualTo(Map.of("max_apps", 10));
|
||||
assertThat(result.gracePeriodDays()).isEqualTo(14);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getLicense_returnsNullWhenNoLicense() throws Exception {
|
||||
var tenant = tenantWithId("Acme Corp", "acme-corp", Tier.LOW, TenantStatus.ACTIVE);
|
||||
var tenant = tenantWithId("Acme Corp", "acme-corp", Tier.STARTER, TenantStatus.ACTIVE);
|
||||
|
||||
when(tenantService.getById(tenantId)).thenReturn(Optional.of(tenant));
|
||||
when(licenseService.getActiveLicense(tenantId)).thenReturn(Optional.empty());
|
||||
@@ -184,7 +183,7 @@ class TenantPortalServiceTest {
|
||||
|
||||
@Test
|
||||
void getSettings_returnsSettingsData() throws Exception {
|
||||
var tenant = tenantWithId("Acme Corp", "acme-corp", Tier.MID, TenantStatus.ACTIVE);
|
||||
var tenant = tenantWithId("Acme Corp", "acme-corp", Tier.TEAM, TenantStatus.ACTIVE);
|
||||
tenant.setServerEndpoint("http://server:8080");
|
||||
|
||||
when(tenantService.getById(tenantId)).thenReturn(Optional.of(tenant));
|
||||
@@ -193,7 +192,7 @@ class TenantPortalServiceTest {
|
||||
|
||||
assertThat(result.name()).isEqualTo("Acme Corp");
|
||||
assertThat(result.slug()).isEqualTo("acme-corp");
|
||||
assertThat(result.tier()).isEqualTo("MID");
|
||||
assertThat(result.tier()).isEqualTo("TEAM");
|
||||
assertThat(result.status()).isEqualTo("ACTIVE");
|
||||
assertThat(result.serverEndpoint()).isEqualTo("https://test.example.com/t/acme-corp/");
|
||||
assertThat(result.createdAt()).isNull(); // no @PrePersist called in test, createdAt is null
|
||||
|
||||
@@ -35,7 +35,7 @@ class TenantControllerTest {
|
||||
|
||||
@Test
|
||||
void createTenant_returns201() throws Exception {
|
||||
var request = new CreateTenantRequest("Test Org", "test-org-" + System.nanoTime(), "LOW", null, null);
|
||||
var request = new CreateTenantRequest("Test Org", "test-org-" + System.nanoTime(), "STARTER", null, null);
|
||||
|
||||
mockMvc.perform(post("/api/tenants")
|
||||
.with(jwt().jwt(j -> j
|
||||
@@ -47,7 +47,7 @@ class TenantControllerTest {
|
||||
.content(objectMapper.writeValueAsString(request)))
|
||||
.andExpect(status().isCreated())
|
||||
.andExpect(jsonPath("$.name").value("Test Org"))
|
||||
.andExpect(jsonPath("$.tier").value("LOW"))
|
||||
.andExpect(jsonPath("$.tier").value("STARTER"))
|
||||
.andExpect(jsonPath("$.status").value("PROVISIONING"));
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ class TenantServiceTest {
|
||||
|
||||
@Test
|
||||
void create_savesNewTenantWithCorrectFields() {
|
||||
var request = new CreateTenantRequest("Acme Corp", "acme-corp", "MID", null, null);
|
||||
var request = new CreateTenantRequest("Acme Corp", "acme-corp", "TEAM", null, null);
|
||||
var actorId = UUID.randomUUID();
|
||||
|
||||
when(tenantRepository.existsBySlugAndStatusNot("acme-corp", TenantStatus.DELETED)).thenReturn(false);
|
||||
@@ -51,7 +51,7 @@ class TenantServiceTest {
|
||||
|
||||
assertThat(result.getName()).isEqualTo("Acme Corp");
|
||||
assertThat(result.getSlug()).isEqualTo("acme-corp");
|
||||
assertThat(result.getTier()).isEqualTo(Tier.MID);
|
||||
assertThat(result.getTier()).isEqualTo(Tier.TEAM);
|
||||
assertThat(result.getStatus()).isEqualTo(TenantStatus.PROVISIONING);
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ class TenantServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void create_defaultsToLowTier() {
|
||||
void create_defaultsToStarterTier() {
|
||||
var request = new CreateTenantRequest("Acme Corp", "acme-corp", null, null, null);
|
||||
|
||||
when(tenantRepository.existsBySlugAndStatusNot("acme-corp", TenantStatus.DELETED)).thenReturn(false);
|
||||
@@ -90,7 +90,7 @@ class TenantServiceTest {
|
||||
|
||||
var result = tenantService.create(request, UUID.randomUUID());
|
||||
|
||||
assertThat(result.getTier()).isEqualTo(Tier.LOW);
|
||||
assertThat(result.getTier()).isEqualTo(Tier.STARTER);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -51,7 +51,7 @@ class VendorTenantControllerTest {
|
||||
@Test
|
||||
void listTenants_returnsAllTenants() throws Exception {
|
||||
String slug = "list-test-" + System.nanoTime();
|
||||
createTenant("List Test Org", slug, "LOW");
|
||||
createTenant("List Test Org", slug, "STARTER");
|
||||
|
||||
mockMvc.perform(get("/api/vendor/tenants")
|
||||
.with(jwt().jwt(j -> j
|
||||
@@ -65,7 +65,7 @@ class VendorTenantControllerTest {
|
||||
@Test
|
||||
void createTenant_returns201() throws Exception {
|
||||
String slug = "create-test-" + System.nanoTime();
|
||||
var request = new CreateTenantRequest("Create Test Org", slug, "MID", null, null);
|
||||
var request = new CreateTenantRequest("Create Test Org", slug, "TEAM", null, null);
|
||||
|
||||
mockMvc.perform(post("/api/vendor/tenants")
|
||||
.with(jwt().jwt(j -> j
|
||||
@@ -78,16 +78,16 @@ class VendorTenantControllerTest {
|
||||
.andExpect(status().isCreated())
|
||||
.andExpect(jsonPath("$.name").value("Create Test Org"))
|
||||
.andExpect(jsonPath("$.slug").value(slug))
|
||||
.andExpect(jsonPath("$.tier").value("MID"))
|
||||
.andExpect(jsonPath("$.tier").value("TEAM"))
|
||||
.andExpect(jsonPath("$.id").isNotEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void createTenant_returns409ForDuplicateSlug() throws Exception {
|
||||
String slug = "duplicate-vendor-" + System.nanoTime();
|
||||
createTenant("First Org", slug, "LOW");
|
||||
createTenant("First Org", slug, "STARTER");
|
||||
|
||||
var request = new CreateTenantRequest("Second Org", slug, "LOW", null, null);
|
||||
var request = new CreateTenantRequest("Second Org", slug, "STARTER", null, null);
|
||||
mockMvc.perform(post("/api/vendor/tenants")
|
||||
.with(jwt().jwt(j -> j
|
||||
.claim("sub", "test-user")
|
||||
@@ -102,7 +102,7 @@ class VendorTenantControllerTest {
|
||||
@Test
|
||||
void getTenantDetail_returnsDetailWithServerStatus() throws Exception {
|
||||
String slug = "detail-test-" + System.nanoTime();
|
||||
String id = createTenant("Detail Test Org", slug, "LOW");
|
||||
String id = createTenant("Detail Test Org", slug, "STARTER");
|
||||
|
||||
mockMvc.perform(get("/api/vendor/tenants/" + id)
|
||||
.with(jwt().jwt(j -> j
|
||||
@@ -118,7 +118,7 @@ class VendorTenantControllerTest {
|
||||
@Test
|
||||
void suspendTenant_returnsUpdatedStatus() throws Exception {
|
||||
String slug = "suspend-test-" + System.nanoTime();
|
||||
String id = createTenant("Suspend Test Org", slug, "LOW");
|
||||
String id = createTenant("Suspend Test Org", slug, "STARTER");
|
||||
|
||||
mockMvc.perform(post("/api/vendor/tenants/" + id + "/suspend")
|
||||
.with(jwt().jwt(j -> j
|
||||
@@ -132,7 +132,7 @@ class VendorTenantControllerTest {
|
||||
@Test
|
||||
void deleteTenant_returns204() throws Exception {
|
||||
String slug = "delete-test-" + System.nanoTime();
|
||||
String id = createTenant("Delete Test Org", slug, "LOW");
|
||||
String id = createTenant("Delete Test Org", slug, "STARTER");
|
||||
|
||||
mockMvc.perform(delete("/api/vendor/tenants/" + id)
|
||||
.with(jwt().jwt(j -> j
|
||||
@@ -144,7 +144,7 @@ class VendorTenantControllerTest {
|
||||
|
||||
@Test
|
||||
void createTenant_returns401WithoutAuth() throws Exception {
|
||||
var request = new CreateTenantRequest("No Auth Org", "no-auth-vendor-" + System.nanoTime(), "LOW", null, null);
|
||||
var request = new CreateTenantRequest("No Auth Org", "no-auth-vendor-" + System.nanoTime(), "STARTER", null, null);
|
||||
|
||||
mockMvc.perform(post("/api/vendor/tenants")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.siegeln.cameleer.saas.provisioning.TenantDataCleanupService;
|
||||
import net.siegeln.cameleer.saas.provisioning.TenantDatabaseService;
|
||||
import net.siegeln.cameleer.saas.license.LicenseEntity;
|
||||
import net.siegeln.cameleer.saas.license.LicenseService;
|
||||
import net.siegeln.cameleer.saas.license.SigningKeyService;
|
||||
import net.siegeln.cameleer.saas.provisioning.ProvisionResult;
|
||||
import net.siegeln.cameleer.saas.provisioning.TenantProvisioner;
|
||||
import net.siegeln.cameleer.saas.tenant.TenantEntity;
|
||||
@@ -52,6 +53,9 @@ class VendorTenantServiceTest {
|
||||
@Mock
|
||||
private LicenseService licenseService;
|
||||
|
||||
@Mock
|
||||
private SigningKeyService signingKeyService;
|
||||
|
||||
@Mock
|
||||
private TenantProvisioner tenantProvisioner;
|
||||
|
||||
@@ -85,11 +89,11 @@ class VendorTenantServiceTest {
|
||||
// Pass null for self-proxy initially, then re-create with the instance itself
|
||||
// (in production, Spring's @Lazy proxy handles this circular ref)
|
||||
vendorTenantService = new VendorTenantService(
|
||||
tenantService, tenantRepository, licenseService,
|
||||
tenantService, tenantRepository, licenseService, signingKeyService,
|
||||
tenantProvisioner, serverApiClient, logtoClient, logtoConfig,
|
||||
auditService, provisioningProps, dataCleanupService, tenantDatabaseService, null);
|
||||
vendorTenantService = new VendorTenantService(
|
||||
tenantService, tenantRepository, licenseService,
|
||||
tenantService, tenantRepository, licenseService, signingKeyService,
|
||||
tenantProvisioner, serverApiClient, logtoClient, logtoConfig,
|
||||
auditService, provisioningProps, dataCleanupService, tenantDatabaseService, vendorTenantService);
|
||||
|
||||
@@ -133,7 +137,7 @@ class VendorTenantServiceTest {
|
||||
private LicenseEntity licenseWithId(UUID tenantId) throws Exception {
|
||||
var license = new LicenseEntity();
|
||||
license.setTenantId(tenantId);
|
||||
license.setTier("LOW");
|
||||
license.setTier("STARTER");
|
||||
license.setToken("test-token-" + UUID.randomUUID());
|
||||
license.setIssuedAt(Instant.now());
|
||||
license.setExpiresAt(Instant.now().plus(Duration.ofDays(365)));
|
||||
@@ -147,9 +151,9 @@ class VendorTenantServiceTest {
|
||||
|
||||
@Test
|
||||
void createAndProvision_createsTenantAndLicense() throws Exception {
|
||||
var request = new CreateTenantRequest("Acme Corp", "acme-corp", "LOW", null, null);
|
||||
var request = new CreateTenantRequest("Acme Corp", "acme-corp", "STARTER", null, null);
|
||||
var actorId = UUID.randomUUID();
|
||||
var tenant = tenantWithId("Acme Corp", "acme-corp", Tier.LOW);
|
||||
var tenant = tenantWithId("Acme Corp", "acme-corp", Tier.STARTER);
|
||||
var license = licenseWithId(tenant.getId());
|
||||
|
||||
when(tenantService.create(request, actorId)).thenReturn(tenant);
|
||||
@@ -167,9 +171,9 @@ class VendorTenantServiceTest {
|
||||
|
||||
@Test
|
||||
void createAndProvision_setsActiveWhenProvisionerSucceeds() throws Exception {
|
||||
var request = new CreateTenantRequest("Acme Corp", "acme-corp", "LOW", null, null);
|
||||
var request = new CreateTenantRequest("Acme Corp", "acme-corp", "STARTER", null, null);
|
||||
var actorId = UUID.randomUUID();
|
||||
var tenant = tenantWithId("Acme Corp", "acme-corp", Tier.LOW);
|
||||
var tenant = tenantWithId("Acme Corp", "acme-corp", Tier.STARTER);
|
||||
var license = licenseWithId(tenant.getId());
|
||||
|
||||
when(tenantService.create(request, actorId)).thenReturn(tenant);
|
||||
@@ -191,9 +195,9 @@ class VendorTenantServiceTest {
|
||||
|
||||
@Test
|
||||
void createAndProvision_setsProvisionErrorOnFailure() throws Exception {
|
||||
var request = new CreateTenantRequest("Acme Corp", "acme-corp", "LOW", null, null);
|
||||
var request = new CreateTenantRequest("Acme Corp", "acme-corp", "STARTER", null, null);
|
||||
var actorId = UUID.randomUUID();
|
||||
var tenant = tenantWithId("Acme Corp", "acme-corp", Tier.LOW);
|
||||
var tenant = tenantWithId("Acme Corp", "acme-corp", Tier.STARTER);
|
||||
var license = licenseWithId(tenant.getId());
|
||||
|
||||
when(tenantService.create(request, actorId)).thenReturn(tenant);
|
||||
@@ -214,9 +218,9 @@ class VendorTenantServiceTest {
|
||||
|
||||
@Test
|
||||
void createAndProvision_worksWithoutProvisioner() throws Exception {
|
||||
var request = new CreateTenantRequest("Acme Corp", "acme-corp", "LOW", null, null);
|
||||
var request = new CreateTenantRequest("Acme Corp", "acme-corp", "STARTER", null, null);
|
||||
var actorId = UUID.randomUUID();
|
||||
var tenant = tenantWithId("Acme Corp", "acme-corp", Tier.LOW);
|
||||
var tenant = tenantWithId("Acme Corp", "acme-corp", Tier.STARTER);
|
||||
var license = licenseWithId(tenant.getId());
|
||||
|
||||
when(tenantService.create(request, actorId)).thenReturn(tenant);
|
||||
@@ -236,8 +240,8 @@ class VendorTenantServiceTest {
|
||||
void suspend_stopsContainersAndSetsStatus() throws Exception {
|
||||
var tenantId = UUID.randomUUID();
|
||||
var actorId = UUID.randomUUID();
|
||||
var tenant = tenantWithId("Acme Corp", "acme-corp", Tier.LOW);
|
||||
var suspended = tenantWithId("Acme Corp", "acme-corp", Tier.LOW);
|
||||
var tenant = tenantWithId("Acme Corp", "acme-corp", Tier.STARTER);
|
||||
var suspended = tenantWithId("Acme Corp", "acme-corp", Tier.STARTER);
|
||||
suspended.setStatus(TenantStatus.SUSPENDED);
|
||||
|
||||
when(tenantService.getById(tenantId)).thenReturn(Optional.of(tenant));
|
||||
@@ -255,8 +259,8 @@ class VendorTenantServiceTest {
|
||||
void suspend_skipsStopWhenProvisionerUnavailable() throws Exception {
|
||||
var tenantId = UUID.randomUUID();
|
||||
var actorId = UUID.randomUUID();
|
||||
var tenant = tenantWithId("Acme Corp", "acme-corp", Tier.LOW);
|
||||
var suspended = tenantWithId("Acme Corp", "acme-corp", Tier.LOW);
|
||||
var tenant = tenantWithId("Acme Corp", "acme-corp", Tier.STARTER);
|
||||
var suspended = tenantWithId("Acme Corp", "acme-corp", Tier.STARTER);
|
||||
suspended.setStatus(TenantStatus.SUSPENDED);
|
||||
|
||||
when(tenantService.getById(tenantId)).thenReturn(Optional.of(tenant));
|
||||
@@ -273,7 +277,7 @@ class VendorTenantServiceTest {
|
||||
void delete_removesContainersRevokesLicenseDeletesOrg() throws Exception {
|
||||
var tenantId = UUID.randomUUID();
|
||||
var actorId = UUID.randomUUID();
|
||||
var tenant = tenantWithId("Acme Corp", "acme-corp", Tier.LOW);
|
||||
var tenant = tenantWithId("Acme Corp", "acme-corp", Tier.STARTER);
|
||||
tenant.setLogtoOrgId("org-123");
|
||||
|
||||
when(tenantService.getById(tenantId)).thenReturn(Optional.of(tenant));
|
||||
@@ -294,17 +298,20 @@ class VendorTenantServiceTest {
|
||||
void renewLicense_revokesOldAndGeneratesNew() throws Exception {
|
||||
var tenantId = UUID.randomUUID();
|
||||
var actorId = UUID.randomUUID();
|
||||
var tenant = tenantWithId("Acme Corp", "acme-corp", Tier.LOW);
|
||||
var tenant = tenantWithId("Acme Corp", "acme-corp", Tier.STARTER);
|
||||
tenant.setServerEndpoint("http://server:8080");
|
||||
var newLicense = licenseWithId(tenantId);
|
||||
|
||||
when(tenantService.getById(tenantId)).thenReturn(Optional.of(tenant));
|
||||
when(licenseService.generateLicense(eq(tenant), any(Duration.class), eq(actorId))).thenReturn(newLicense);
|
||||
// mintLicense() calls the full generateLicense overload (limits, expiresAt, grace, label, actor)
|
||||
when(licenseService.generateLicense(eq(tenant), any(java.util.Map.class), any(Instant.class),
|
||||
any(Integer.class), any(String.class), eq(actorId))).thenReturn(newLicense);
|
||||
|
||||
var result = vendorTenantService.renewLicense(tenantId, actorId);
|
||||
|
||||
verify(licenseService).revokeLicense(tenantId, actorId);
|
||||
verify(licenseService).generateLicense(eq(tenant), any(Duration.class), eq(actorId));
|
||||
verify(licenseService).generateLicense(eq(tenant), any(java.util.Map.class), any(Instant.class),
|
||||
any(Integer.class), any(String.class), eq(actorId));
|
||||
verify(serverApiClient).pushLicense("http://server:8080", newLicense.getToken());
|
||||
assertThat(result).isSameAs(newLicense);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user