fix(staging): align smoke admin creds and validate label limits

This commit is contained in:
vsxd 2026-03-23 13:55:55 +08:00 committed by Xudong Sun
parent ddf9e6e1d2
commit 91f547d883
5 changed files with 59 additions and 3 deletions

View file

@ -263,7 +263,8 @@ staging: ## 构建并启动 staging 环境,运行 smoke test混合模式
@echo "=== [4/5] Starting staging services ==="
$(STAGING_COMPOSE) up -d --wait server web
@echo "=== [5/5] Running smoke tests ==="
@if bash scripts/smoke-test.sh $(STAGING_API_URL); then \
@if BOOTSTRAP_ADMIN_USERNAME=admin BOOTSTRAP_ADMIN_PASSWORD='Admin@staging2026' \
bash scripts/smoke-test.sh $(STAGING_API_URL); then \
echo ""; \
echo "Staging passed. Environment is running:"; \
echo " Web UI: $(STAGING_WEB_URL)"; \

View file

@ -28,7 +28,7 @@ public class LabelDefinitionService {
this.labelDefinitionRepository = labelDefinitionRepository;
this.labelTranslationRepository = labelTranslationRepository;
this.labelPermissionChecker = labelPermissionChecker;
this.maxLabelDefinitions = maxLabelDefinitions;
this.maxLabelDefinitions = requirePositive(maxLabelDefinitions, "skillhub.label.max-definitions");
}
public List<LabelDefinition> listAll() {
@ -206,6 +206,13 @@ public class LabelDefinitionService {
return new DomainBadRequestException("label.slug.duplicate", slug);
}
private int requirePositive(int value, String propertyName) {
if (value <= 0) {
throw new IllegalArgumentException(propertyName + " must be greater than 0");
}
return value;
}
public record LabelSortOrderUpdate(Long labelId, int sortOrder) {
}
}

View file

@ -31,7 +31,7 @@ public class SkillLabelService {
this.labelDefinitionRepository = labelDefinitionRepository;
this.skillLabelRepository = skillLabelRepository;
this.labelPermissionChecker = labelPermissionChecker;
this.maxLabelsPerSkill = maxLabelsPerSkill;
this.maxLabelsPerSkill = requirePositive(maxLabelsPerSkill, "skillhub.label.max-per-skill");
}
public List<SkillLabel> listSkillLabels(Long skillId) {
@ -95,4 +95,11 @@ public class SkillLabelService {
throw new DomainForbiddenException("label.skill.no_permission");
}
}
private int requirePositive(int value, String propertyName) {
if (value <= 0) {
throw new IllegalArgumentException(propertyName + " must be greater than 0");
}
return value;
}
}

View file

@ -26,6 +26,18 @@ class LabelDefinitionServiceTest {
100
);
@Test
void constructorShouldRejectNonPositiveDefinitionLimit() {
IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> new LabelDefinitionService(
labelDefinitionRepository,
labelTranslationRepository,
labelPermissionChecker,
0
));
assertEquals("skillhub.label.max-definitions must be greater than 0", ex.getMessage());
}
@Test
void createShouldRejectDuplicateLocalesIgnoringCase() {
when(labelPermissionChecker.canManageDefinitions(Set.of("SUPER_ADMIN"))).thenReturn(true);

View file

@ -0,0 +1,29 @@
package com.iflytek.skillhub.domain.label;
import com.iflytek.skillhub.domain.skill.SkillRepository;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.mock;
class SkillLabelServiceTest {
private final SkillRepository skillRepository = mock(SkillRepository.class);
private final LabelDefinitionRepository labelDefinitionRepository = mock(LabelDefinitionRepository.class);
private final SkillLabelRepository skillLabelRepository = mock(SkillLabelRepository.class);
private final LabelPermissionChecker labelPermissionChecker = mock(LabelPermissionChecker.class);
@Test
void constructorShouldRejectNonPositivePerSkillLimit() {
IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> new SkillLabelService(
skillRepository,
labelDefinitionRepository,
skillLabelRepository,
labelPermissionChecker,
0
));
assertEquals("skillhub.label.max-per-skill must be greater than 0", ex.getMessage());
}
}