Merge branch 'codex/feature-conversion-step1'

# Conflicts:
#	src/main/java/com/sztzjy/linkCommerce/controller/stu/StudentTrainingAnswerController.java
main
chenyuan 2 weeks ago
commit 31e47483f2

@ -398,6 +398,12 @@ public class StudentTrainingAnswerController {
private com.sztzjy.linkCommerce.service.ConsumerScenarioStepThreeService consumerScenarioStepThreeService;
@Autowired
private com.sztzjy.linkCommerce.service.ConsumerScenarioStepFourService consumerScenarioStepFourService;
@Autowired
private com.sztzjy.linkCommerce.service.FeatureConversionStepOneService featureConversionStepOneService;
@Autowired
private com.sztzjy.linkCommerce.service.FeatureConversionStepTwoService featureConversionStepTwoService;
@Autowired
private com.sztzjy.linkCommerce.service.FeatureConversionStepThreeService featureConversionStepThreeService;
@Autowired
private SupplierEvaluationStepTwoService supplierEvaluationStepTwoService;
@ -1188,6 +1194,15 @@ public class StudentTrainingAnswerController {
@ApiOperation("消费场景解构第四步校验")
public ResultEntity<com.sztzjy.linkCommerce.entity.dto.ConsumerScenarioStepFourValidationResult> validateConsumerScenarioStepFour(@RequestBody com.sztzjy.linkCommerce.entity.dto.ConsumerScenarioStepFourValidationRequest answer, HttpServletRequest request) { try { return new ResultEntity<>(HttpStatus.OK, "校验完成", consumerScenarioStepFourService.validate(answer, TokenProvider.getJWTUser(request))); } catch (ServiceException e) { return new ResultEntity<>(e.getCode(), e.getMessage()); } }
@PostMapping("/feature-conversion/step-1/validate")
@ApiOperation("需求转化为功能第一步校验")
public ResultEntity<com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepOneValidationResult> validateFeatureConversionStepOne(@RequestBody com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepOneValidationRequest answer, HttpServletRequest request) { try { return new ResultEntity<>(HttpStatus.OK, "校验完成", featureConversionStepOneService.validate(answer, TokenProvider.getJWTUser(request))); } catch (ServiceException e) { return new ResultEntity<>(e.getCode(), e.getMessage()); } }
@PostMapping("/feature-conversion/step-2/validate")
@ApiOperation("需求转化为功能第二步校验")
public ResultEntity<com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepTwoValidationResult> validateFeatureConversionStepTwo(@RequestBody com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepTwoValidationRequest answer, HttpServletRequest request) { try { return new ResultEntity<>(HttpStatus.OK, "校验完成", featureConversionStepTwoService.validate(answer, TokenProvider.getJWTUser(request))); } catch (ServiceException e) { return new ResultEntity<>(e.getCode(), e.getMessage()); } }
@PostMapping("/feature-conversion/step-3/validate")
@ApiOperation("需求转化为功能第三步校验")
public ResultEntity<com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepThreeValidationResult> validateFeatureConversionStepThree(@RequestBody com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepThreeValidationRequest answer, HttpServletRequest request) { try { return new ResultEntity<>(HttpStatus.OK, "校验完成", featureConversionStepThreeService.validate(answer, TokenProvider.getJWTUser(request))); } catch (ServiceException e) { return new ResultEntity<>(e.getCode(), e.getMessage()); } }
@DeleteMapping("/{taskKey}")
@ApiOperation("删除当前学生指定实训任务答案")
public ResultEntity delete(@PathVariable String taskKey,

@ -0,0 +1,34 @@
package com.sztzjy.linkCommerce.entity.dto;
import java.util.List;
public class FeatureConversionStepOneValidationRequest {
private List<ConversionRow> rows;
public List<ConversionRow> getRows() {
return rows;
}
public void setRows(List<ConversionRow> rows) {
this.rows = rows;
}
public static class ConversionRow {
private String voice;
private String insight;
private String definition;
private String description;
private String acceptance;
public String getVoice() { return voice; }
public void setVoice(String voice) { this.voice = voice; }
public String getInsight() { return insight; }
public void setInsight(String insight) { this.insight = insight; }
public String getDefinition() { return definition; }
public void setDefinition(String definition) { this.definition = definition; }
public String getDescription() { return description; }
public void setDescription(String description) { this.description = description; }
public String getAcceptance() { return acceptance; }
public void setAcceptance(String acceptance) { this.acceptance = acceptance; }
}
}

@ -0,0 +1,11 @@
package com.sztzjy.linkCommerce.entity.dto;
public class FeatureConversionStepOneValidationResult {
private boolean valid;
private String message;
public boolean isValid() { return valid; }
public void setValid(boolean valid) { this.valid = valid; }
public String getMessage() { return message; }
public void setMessage(String message) { this.message = message; }
}

@ -0,0 +1,37 @@
package com.sztzjy.linkCommerce.entity.dto;
import java.util.List;
public class FeatureConversionStepThreeValidationRequest {
private List<FeatureConversionStepTwoValidationRequest.RiceScoreRow> scoreRows;
private List<PriorityRow> rows;
public List<FeatureConversionStepTwoValidationRequest.RiceScoreRow> getScoreRows() {
return scoreRows;
}
public void setScoreRows(List<FeatureConversionStepTwoValidationRequest.RiceScoreRow> scoreRows) {
this.scoreRows = scoreRows;
}
public List<PriorityRow> getRows() {
return rows;
}
public void setRows(List<PriorityRow> rows) {
this.rows = rows;
}
public static class PriorityRow {
private String name;
private String priority;
private String reason;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getPriority() { return priority; }
public void setPriority(String priority) { this.priority = priority; }
public String getReason() { return reason; }
public void setReason(String reason) { this.reason = reason; }
}
}

@ -0,0 +1,11 @@
package com.sztzjy.linkCommerce.entity.dto;
public class FeatureConversionStepThreeValidationResult {
private boolean valid;
private String message;
public boolean isValid() { return valid; }
public void setValid(boolean valid) { this.valid = valid; }
public String getMessage() { return message; }
public void setMessage(String message) { this.message = message; }
}

@ -0,0 +1,52 @@
package com.sztzjy.linkCommerce.entity.dto;
import java.util.List;
public class FeatureConversionStepTwoValidationRequest {
private List<String> sourceDefinitions;
private List<RiceScoreRow> rows;
public List<String> getSourceDefinitions() {
return sourceDefinitions;
}
public void setSourceDefinitions(List<String> sourceDefinitions) {
this.sourceDefinitions = sourceDefinitions;
}
public List<RiceScoreRow> getRows() {
return rows;
}
public void setRows(List<RiceScoreRow> rows) {
this.rows = rows;
}
public static class RiceScoreRow {
private String requirementId;
private String name;
private String kano;
private Double reach;
private Double impact;
private Double confidence;
private Double effort;
private String riceScore;
public String getRequirementId() { return requirementId; }
public void setRequirementId(String requirementId) { this.requirementId = requirementId; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getKano() { return kano; }
public void setKano(String kano) { this.kano = kano; }
public Double getReach() { return reach; }
public void setReach(Double reach) { this.reach = reach; }
public Double getImpact() { return impact; }
public void setImpact(Double impact) { this.impact = impact; }
public Double getConfidence() { return confidence; }
public void setConfidence(Double confidence) { this.confidence = confidence; }
public Double getEffort() { return effort; }
public void setEffort(Double effort) { this.effort = effort; }
public String getRiceScore() { return riceScore; }
public void setRiceScore(String riceScore) { this.riceScore = riceScore; }
}
}

@ -0,0 +1,11 @@
package com.sztzjy.linkCommerce.entity.dto;
public class FeatureConversionStepTwoValidationResult {
private boolean valid;
private String message;
public boolean isValid() { return valid; }
public void setValid(boolean valid) { this.valid = valid; }
public String getMessage() { return message; }
public void setMessage(String message) { this.message = message; }
}

@ -0,0 +1,9 @@
package com.sztzjy.linkCommerce.service;
import com.sztzjy.linkCommerce.config.security.JwtUser;
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepOneValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepOneValidationResult;
public interface FeatureConversionStepOneService {
FeatureConversionStepOneValidationResult validate(FeatureConversionStepOneValidationRequest request, JwtUser user);
}

@ -0,0 +1,9 @@
package com.sztzjy.linkCommerce.service;
import com.sztzjy.linkCommerce.config.security.JwtUser;
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepThreeValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepThreeValidationResult;
public interface FeatureConversionStepThreeService {
FeatureConversionStepThreeValidationResult validate(FeatureConversionStepThreeValidationRequest request, JwtUser user);
}

@ -0,0 +1,9 @@
package com.sztzjy.linkCommerce.service;
import com.sztzjy.linkCommerce.config.security.JwtUser;
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepTwoValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepTwoValidationResult;
public interface FeatureConversionStepTwoService {
FeatureConversionStepTwoValidationResult validate(FeatureConversionStepTwoValidationRequest request, JwtUser user);
}

@ -0,0 +1,51 @@
package com.sztzjy.linkCommerce.service.impl;
import com.sztzjy.linkCommerce.config.exception.handler.ServiceException;
import com.sztzjy.linkCommerce.config.security.JwtUser;
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepOneValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepOneValidationResult;
import com.sztzjy.linkCommerce.service.FeatureConversionStepOneService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class FeatureConversionStepOneServiceImpl implements FeatureConversionStepOneService {
private static final int MIN_ROWS = 8;
private static final int MAX_ROWS = 12;
@Override
public FeatureConversionStepOneValidationResult validate(FeatureConversionStepOneValidationRequest request, JwtUser user) {
requireStudent(user);
List<FeatureConversionStepOneValidationRequest.ConversionRow> rows = request == null ? null : request.getRows();
if (rows == null || rows.size() < MIN_ROWS || rows.size() > MAX_ROWS || rows.stream().anyMatch(row -> row == null)) {
throw badRequest("请填写 8 至 12 行需求转化信息");
}
if (rows.stream().anyMatch(row -> StringUtils.isBlank(row.getVoice())
|| StringUtils.isBlank(row.getInsight())
|| StringUtils.isBlank(row.getDefinition())
|| StringUtils.isBlank(row.getDescription())
|| StringUtils.isBlank(row.getAcceptance()))) {
throw badRequest("请完整填写每行的用户原声、场景洞察、功能定义、功能描述和验收标准");
}
FeatureConversionStepOneValidationResult result = new FeatureConversionStepOneValidationResult();
result.setValid(true);
result.setMessage("需求转化表填写完整。");
return result;
}
private void requireStudent(JwtUser user) {
if (user == null || StringUtils.isBlank(user.getUserId())) {
throw new ServiceException(HttpStatus.UNAUTHORIZED, "请先登录后再提交");
}
if (user.getRoleId() != 4) {
throw new ServiceException(HttpStatus.FORBIDDEN, "仅学生可以提交实训答案");
}
}
private ServiceException badRequest(String message) {
return new ServiceException(HttpStatus.BAD_REQUEST, message);
}
}

@ -0,0 +1,58 @@
package com.sztzjy.linkCommerce.service.impl;
import com.sztzjy.linkCommerce.config.exception.handler.ServiceException;
import com.sztzjy.linkCommerce.config.security.JwtUser;
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepThreeValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepThreeValidationResult;
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepTwoValidationRequest;
import com.sztzjy.linkCommerce.service.FeatureConversionStepThreeService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
@Service
public class FeatureConversionStepThreeServiceImpl implements FeatureConversionStepThreeService {
private static final int MIN_ROWS = 8;
private static final int MAX_ROWS = 12;
private static final List<String> PRIORITIES = Arrays.asList("P0", "P1", "P2", "P3");
@Override
public FeatureConversionStepThreeValidationResult validate(FeatureConversionStepThreeValidationRequest request, JwtUser user) {
requireStudent(user);
List<FeatureConversionStepTwoValidationRequest.RiceScoreRow> scoreRows = request == null ? null : request.getScoreRows();
List<FeatureConversionStepThreeValidationRequest.PriorityRow> rows = request == null ? null : request.getRows();
if (scoreRows == null || rows == null || scoreRows.size() < MIN_ROWS || scoreRows.size() > MAX_ROWS || scoreRows.size() != rows.size()) {
throw badRequest("功能优先级表必须与第二步 RICE 评分表保持一致,且为 8 至 12 行");
}
for (int index = 0; index < rows.size(); index++) {
FeatureConversionStepTwoValidationRequest.RiceScoreRow scoreRow = scoreRows.get(index);
FeatureConversionStepThreeValidationRequest.PriorityRow row = rows.get(index);
if (scoreRow == null || row == null || StringUtils.isBlank(scoreRow.getName()) || !scoreRow.getName().equals(row.getName())) {
throw badRequest("功能名称和行数必须与第二步 RICE 评分表保持一致");
}
if (!PRIORITIES.contains(row.getPriority()) || StringUtils.isBlank(row.getReason())) {
throw badRequest("请为每项功能选择 P0-P3 优先级并填写划分理由");
}
}
FeatureConversionStepThreeValidationResult result = new FeatureConversionStepThreeValidationResult();
result.setValid(true);
result.setMessage("功能优先级清单填写完整。");
return result;
}
private void requireStudent(JwtUser user) {
if (user == null || StringUtils.isBlank(user.getUserId())) {
throw new ServiceException(HttpStatus.UNAUTHORIZED, "请先登录后再提交");
}
if (user.getRoleId() != 4) {
throw new ServiceException(HttpStatus.FORBIDDEN, "仅学生可以提交实训答案");
}
}
private ServiceException badRequest(String message) {
return new ServiceException(HttpStatus.BAD_REQUEST, message);
}
}

@ -0,0 +1,82 @@
package com.sztzjy.linkCommerce.service.impl;
import com.sztzjy.linkCommerce.config.exception.handler.ServiceException;
import com.sztzjy.linkCommerce.config.security.JwtUser;
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepTwoValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepTwoValidationResult;
import com.sztzjy.linkCommerce.service.FeatureConversionStepTwoService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.List;
@Service
public class FeatureConversionStepTwoServiceImpl implements FeatureConversionStepTwoService {
private static final int MIN_ROWS = 8;
private static final int MAX_ROWS = 12;
private static final List<String> KANO_TYPES = Arrays.asList("基本型", "期望型", "兴奋型", "无差异型", "反向型");
@Override
public FeatureConversionStepTwoValidationResult validate(FeatureConversionStepTwoValidationRequest request, JwtUser user) {
requireStudent(user);
List<String> sourceDefinitions = request == null ? null : request.getSourceDefinitions();
List<FeatureConversionStepTwoValidationRequest.RiceScoreRow> rows = request == null ? null : request.getRows();
if (sourceDefinitions == null || rows == null || rows.size() < MIN_ROWS || rows.size() > MAX_ROWS || sourceDefinitions.size() != rows.size()) {
throw badRequest("RICE 评分行数必须与第一步需求转化表一致,且为 8 至 12 行");
}
for (int index = 0; index < rows.size(); index++) {
String expectedId = String.format("F%02d", index + 1);
String expectedName = sourceDefinitions.get(index);
FeatureConversionStepTwoValidationRequest.RiceScoreRow row = rows.get(index);
if (row == null || StringUtils.isBlank(expectedName) || !expectedId.equals(row.getRequirementId()) || !expectedName.equals(row.getName())) {
throw badRequest("需求 ID 与功能名称必须与第一步的功能定义保持一致");
}
if (!KANO_TYPES.contains(row.getKano()) || !isScore(row.getReach()) || !isScore(row.getImpact())
|| !isConfidence(row.getConfidence()) || row.getEffort() == null || row.getEffort() <= 0 || !isRiceScoreValid(row)) {
throw badRequest("请完整填写 KANO、Reach、Impact、Confidence、Effort并确认 RICE 得分正确");
}
}
FeatureConversionStepTwoValidationResult result = new FeatureConversionStepTwoValidationResult();
result.setValid(true);
result.setMessage("RICE 评分填写完整。");
return result;
}
private boolean isScore(Double value) {
return value != null && value >= 1 && value <= 5 && value == Math.rint(value);
}
private boolean isConfidence(Double value) {
return value != null && value >= 1 && value <= 100 && value == Math.rint(value);
}
private boolean isRiceScoreValid(FeatureConversionStepTwoValidationRequest.RiceScoreRow row) {
if (StringUtils.isBlank(row.getRiceScore())) return false;
try {
BigDecimal expected = BigDecimal.valueOf(row.getReach())
.multiply(BigDecimal.valueOf(row.getImpact()))
.multiply(BigDecimal.valueOf(row.getConfidence()).movePointLeft(2))
.divide(BigDecimal.valueOf(row.getEffort()), 2, RoundingMode.HALF_UP);
return expected.compareTo(new BigDecimal(row.getRiceScore())) == 0;
} catch (NumberFormatException error) {
return false;
}
}
private void requireStudent(JwtUser user) {
if (user == null || StringUtils.isBlank(user.getUserId())) {
throw new ServiceException(HttpStatus.UNAUTHORIZED, "请先登录后再提交");
}
if (user.getRoleId() != 4) {
throw new ServiceException(HttpStatus.FORBIDDEN, "仅学生可以提交实训答案");
}
}
private ServiceException badRequest(String message) {
return new ServiceException(HttpStatus.BAD_REQUEST, message);
}
}

@ -0,0 +1,60 @@
package com.sztzjy.linkCommerce.service.impl;
import com.sztzjy.linkCommerce.config.exception.handler.ServiceException;
import com.sztzjy.linkCommerce.config.security.JwtUser;
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepOneValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepOneValidationResult;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
class FeatureConversionStepOneServiceImplTest {
private final FeatureConversionStepOneServiceImpl service = new FeatureConversionStepOneServiceImpl();
@Test
void acceptsEightCompleteRows() {
FeatureConversionStepOneValidationResult result = service.validate(request(8), student());
assertTrue(result.isValid());
}
@Test
void rejectsTooFewRows() {
assertThrows(ServiceException.class, () -> service.validate(request(7), student()));
}
@Test
void rejectsIncompleteRow() {
FeatureConversionStepOneValidationRequest request = request(8);
request.getRows().get(0).setAcceptance(" ");
assertThrows(ServiceException.class, () -> service.validate(request, student()));
}
private FeatureConversionStepOneValidationRequest request(int count) {
FeatureConversionStepOneValidationRequest request = new FeatureConversionStepOneValidationRequest();
List<FeatureConversionStepOneValidationRequest.ConversionRow> rows = new ArrayList<>();
for (int index = 0; index < count; index++) {
FeatureConversionStepOneValidationRequest.ConversionRow row = new FeatureConversionStepOneValidationRequest.ConversionRow();
row.setVoice("用户原声");
row.setInsight("场景洞察");
row.setDefinition("功能定义");
row.setDescription("功能描述");
row.setAcceptance("验收标准");
rows.add(row);
}
request.setRows(rows);
return request;
}
private JwtUser student() {
JwtUser user = new JwtUser();
user.setUserId("stu-1");
user.setRoleId(4);
return user;
}
}

@ -0,0 +1,69 @@
package com.sztzjy.linkCommerce.service.impl;
import com.sztzjy.linkCommerce.config.exception.handler.ServiceException;
import com.sztzjy.linkCommerce.config.security.JwtUser;
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepThreeValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepThreeValidationResult;
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepTwoValidationRequest;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
class FeatureConversionStepThreeServiceImplTest {
private final FeatureConversionStepThreeServiceImpl service = new FeatureConversionStepThreeServiceImpl();
@Test
void acceptsPriorityRowsSynchronizedWithRiceRows() {
FeatureConversionStepThreeValidationResult result = service.validate(request(), student());
assertTrue(result.isValid());
}
@Test
void rejectsPriorityNameNotSynchronizedWithRiceRows() {
FeatureConversionStepThreeValidationRequest request = request();
request.getRows().get(0).setName("被篡改的功能名称");
assertThrows(ServiceException.class, () -> service.validate(request, student()));
}
@Test
void rejectsBlankPriorityReason() {
FeatureConversionStepThreeValidationRequest request = request();
request.getRows().get(0).setReason(" ");
assertThrows(ServiceException.class, () -> service.validate(request, student()));
}
private FeatureConversionStepThreeValidationRequest request() {
FeatureConversionStepThreeValidationRequest request = new FeatureConversionStepThreeValidationRequest();
List<FeatureConversionStepTwoValidationRequest.RiceScoreRow> scoreRows = new ArrayList<>();
List<FeatureConversionStepThreeValidationRequest.PriorityRow> rows = new ArrayList<>();
for (int index = 0; index < 8; index++) {
String name = "功能定义" + (index + 1);
FeatureConversionStepTwoValidationRequest.RiceScoreRow scoreRow = new FeatureConversionStepTwoValidationRequest.RiceScoreRow();
scoreRow.setName(name);
scoreRows.add(scoreRow);
FeatureConversionStepThreeValidationRequest.PriorityRow row = new FeatureConversionStepThreeValidationRequest.PriorityRow();
row.setName(name);
row.setPriority(index == 0 ? "P0" : "P1");
row.setReason("结合 RICE 评分确定开发优先级");
rows.add(row);
}
request.setScoreRows(scoreRows);
request.setRows(rows);
return request;
}
private JwtUser student() {
JwtUser user = new JwtUser();
user.setUserId("student-id");
user.setRoleId(4);
return user;
}
}

@ -0,0 +1,70 @@
package com.sztzjy.linkCommerce.service.impl;
import com.sztzjy.linkCommerce.config.exception.handler.ServiceException;
import com.sztzjy.linkCommerce.config.security.JwtUser;
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepTwoValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepTwoValidationResult;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
class FeatureConversionStepTwoServiceImplTest {
private final FeatureConversionStepTwoServiceImpl service = new FeatureConversionStepTwoServiceImpl();
@Test
void acceptsSynchronizedRiceRows() {
FeatureConversionStepTwoValidationResult result = service.validate(request(), student());
assertTrue(result.isValid());
}
@Test
void rejectsNameNotSynchronizedWithStepOne() {
FeatureConversionStepTwoValidationRequest request = request();
request.getRows().get(0).setName("手动修改的功能");
assertThrows(ServiceException.class, () -> service.validate(request, student()));
}
@Test
void rejectsInvalidRiceScore() {
FeatureConversionStepTwoValidationRequest request = request();
request.getRows().get(0).setRiceScore("15.99");
assertThrows(ServiceException.class, () -> service.validate(request, student()));
}
private FeatureConversionStepTwoValidationRequest request() {
FeatureConversionStepTwoValidationRequest request = new FeatureConversionStepTwoValidationRequest();
List<String> definitions = new ArrayList<>();
List<FeatureConversionStepTwoValidationRequest.RiceScoreRow> rows = new ArrayList<>();
for (int index = 0; index < 8; index++) {
String definition = "功能定义" + (index + 1);
definitions.add(definition);
FeatureConversionStepTwoValidationRequest.RiceScoreRow row = new FeatureConversionStepTwoValidationRequest.RiceScoreRow();
row.setRequirementId(String.format("F%02d", index + 1));
row.setName(definition);
row.setKano("基本型");
row.setReach(5D);
row.setImpact(4D);
row.setConfidence(80D);
row.setEffort(1D);
row.setRiceScore("16.00");
rows.add(row);
}
request.setSourceDefinitions(definitions);
request.setRows(rows);
return request;
}
private JwtUser student() {
JwtUser user = new JwtUser();
user.setUserId("stu-1");
user.setRoleId(4);
return user;
}
}
Loading…
Cancel
Save