|
|
|
|
@ -1,337 +0,0 @@
|
|
|
|
|
package com.yau.digitalrmb.training.application;
|
|
|
|
|
|
|
|
|
|
import com.yau.digitalrmb.progress.application.ModuleCompletionService;
|
|
|
|
|
import com.yau.digitalrmb.shared.api.ErrorCode;
|
|
|
|
|
import com.yau.digitalrmb.shared.exception.BusinessException;
|
|
|
|
|
import org.junit.jupiter.api.Test;
|
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
import org.springframework.boot.test.context.SpringBootTest;
|
|
|
|
|
import org.springframework.jdbc.core.JdbcTemplate;
|
|
|
|
|
import org.springframework.test.context.ActiveProfiles;
|
|
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
|
|
import static org.assertj.core.api.Assertions.assertThat;
|
|
|
|
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
|
|
|
|
|
|
|
|
|
@SpringBootTest
|
|
|
|
|
@ActiveProfiles("test")
|
|
|
|
|
@Transactional
|
|
|
|
|
class TrainingTaskProgressServiceTest {
|
|
|
|
|
private static final String USER = "progress-user-1";
|
|
|
|
|
private static final String OTHER = "progress-user-2";
|
|
|
|
|
private static final String PAYMENT = "CURRENCY_PAYMENT";
|
|
|
|
|
|
|
|
|
|
@Autowired private TrainingTaskProgressService service;
|
|
|
|
|
@Autowired private ModuleCompletionService moduleCompletion;
|
|
|
|
|
@Autowired private JdbcTemplate jdbc;
|
|
|
|
|
|
|
|
|
|
/** 每步一个字母:D=已完成 C=当前可操作 S=已保存草稿 L=锁定 N=未开始。 */
|
|
|
|
|
private String statuses(TrainingTaskProgressService.TrainingTaskView view) {
|
|
|
|
|
return view.getSteps().stream().map(TrainingTaskProgressService.TrainingStepView::getStatus)
|
|
|
|
|
.map(s -> {
|
|
|
|
|
switch (s) {
|
|
|
|
|
case "COMPLETED": return "D";
|
|
|
|
|
case "CURRENT": return "C";
|
|
|
|
|
case "SAVED": return "S";
|
|
|
|
|
case "LOCKED": return "L";
|
|
|
|
|
case "NOT_STARTED": return "N";
|
|
|
|
|
default: return "?";
|
|
|
|
|
}
|
|
|
|
|
}).collect(Collectors.joining());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void untouchedModuleStartsAtTheFirstStep() {
|
|
|
|
|
TrainingTaskProgressService.TrainingTaskView view = service.one(USER, PAYMENT);
|
|
|
|
|
|
|
|
|
|
assertThat(view.getStatus()).isEqualTo("NOT_STARTED");
|
|
|
|
|
assertThat(view.getCompletedSteps()).isZero();
|
|
|
|
|
assertThat(view.getSavedSteps()).isZero();
|
|
|
|
|
assertThat(view.getCurrentStepCode()).isEqualTo("01");
|
|
|
|
|
assertThat(statuses(view)).isEqualTo("CLLLLL");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void savingADraftMarksTheStepSavedAndTheModuleInProgressWithoutCompletingIt() {
|
|
|
|
|
TrainingTaskProgressService.TrainingTaskView view =
|
|
|
|
|
service.saveStep(USER, PAYMENT, "01", "{\"payer\":\"A\",\"amount\":12.5}");
|
|
|
|
|
|
|
|
|
|
assertThat(view.getStatus()).isEqualTo("IN_PROGRESS");
|
|
|
|
|
assertThat(view.getCompletedSteps()).isZero();
|
|
|
|
|
assertThat(view.getSavedSteps()).isEqualTo(1);
|
|
|
|
|
assertThat(view.getCurrentStepCode()).isEqualTo("01");
|
|
|
|
|
assertThat(view.getSteps().get(0).getStatus()).isEqualTo("SAVED");
|
|
|
|
|
assertThat(view.getSteps().get(0).isActionAvailable()).isTrue();
|
|
|
|
|
assertThat(view.getSteps().get(0).isHasData()).isTrue();
|
|
|
|
|
assertThat(view.getSteps().get(0).getSavedAt()).isNotNull();
|
|
|
|
|
assertThat(view.getSteps().get(1).getStatus()).isEqualTo("LOCKED");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void draftDataRoundTripsAndEachSaveReplacesThePreviousOne() {
|
|
|
|
|
service.saveStep(USER, PAYMENT, "02", "{\"v\":1}");
|
|
|
|
|
service.saveStep(USER, PAYMENT, "02", "{\"v\":2,\"note\":\"房租\"}");
|
|
|
|
|
|
|
|
|
|
TrainingTaskProgressService.TrainingStepDetailView detail = service.stepDetail(USER, PAYMENT, "02");
|
|
|
|
|
|
|
|
|
|
assertThat(detail.getStepData()).isEqualTo("{\"v\":2,\"note\":\"房租\"}");
|
|
|
|
|
assertThat(detail.isHasData()).isTrue();
|
|
|
|
|
assertThat(detail.getStepName()).isEqualTo("签名支付请求");
|
|
|
|
|
assertThat(jdbc.queryForObject("SELECT COUNT(*) FROM training_task_step_progress WHERE user_id=?",
|
|
|
|
|
Integer.class, USER)).isEqualTo(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void stepWithoutADraftReturnsNoData() {
|
|
|
|
|
TrainingTaskProgressService.TrainingStepDetailView detail = service.stepDetail(USER, PAYMENT, "01");
|
|
|
|
|
|
|
|
|
|
assertThat(detail.getStepData()).isNull();
|
|
|
|
|
assertThat(detail.isHasData()).isFalse();
|
|
|
|
|
assertThat(detail.getStatus()).isEqualTo("CURRENT");
|
|
|
|
|
assertThat(detail.getSavedAt()).isNull();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void draftsCanBeSavedBeyondTheFrontierWithoutUnlockingAnything() {
|
|
|
|
|
TrainingTaskProgressService.TrainingTaskView view =
|
|
|
|
|
service.saveStep(USER, PAYMENT, "03", "{\"x\":1}");
|
|
|
|
|
|
|
|
|
|
assertThat(statuses(view)).isEqualTo("CLSLLL");
|
|
|
|
|
assertThat(view.getCurrentStepCode()).isEqualTo("01");
|
|
|
|
|
assertThat(view.getSteps().get(2).isActionAvailable()).isFalse();
|
|
|
|
|
assertThat(view.getCompletedSteps()).isZero();
|
|
|
|
|
assertThat(view.getStatus()).isEqualTo("IN_PROGRESS");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void completingAStepKeepsItsDraftDataAndCountsItExactlyOnce() {
|
|
|
|
|
service.saveStep(USER, PAYMENT, "01", "{\"keep\":true}");
|
|
|
|
|
|
|
|
|
|
service.completeThrough(USER, PAYMENT, "01");
|
|
|
|
|
service.completeThrough(USER, PAYMENT, "01");
|
|
|
|
|
TrainingTaskProgressService.TrainingTaskView view = service.one(USER, PAYMENT);
|
|
|
|
|
|
|
|
|
|
assertThat(view.getCompletedSteps()).isEqualTo(1);
|
|
|
|
|
assertThat(view.getSavedSteps()).isZero();
|
|
|
|
|
assertThat(view.getCurrentStepCode()).isEqualTo("02");
|
|
|
|
|
assertThat(view.getSteps().get(0).getStatus()).isEqualTo("COMPLETED");
|
|
|
|
|
assertThat(service.stepDetail(USER, PAYMENT, "01").getStepData()).isEqualTo("{\"keep\":true}");
|
|
|
|
|
assertThat(jdbc.queryForObject("SELECT COUNT(*) FROM training_task_step_progress WHERE user_id=?",
|
|
|
|
|
Integer.class, USER)).isEqualTo(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void completingALaterStepAlsoCompletesTheEarlierOnesThatOnlyHadDrafts() {
|
|
|
|
|
service.saveStep(USER, PAYMENT, "01", "{\"a\":1}");
|
|
|
|
|
service.saveStep(USER, PAYMENT, "02", "{\"b\":2}");
|
|
|
|
|
|
|
|
|
|
service.completeThrough(USER, PAYMENT, "02");
|
|
|
|
|
TrainingTaskProgressService.TrainingTaskView view = service.one(USER, PAYMENT);
|
|
|
|
|
|
|
|
|
|
// 前两步已完成,第 3 步是下一个可操作步骤,其余锁定
|
|
|
|
|
assertThat(statuses(view)).isEqualTo("DDCLLL");
|
|
|
|
|
assertThat(view.getCompletedSteps()).isEqualTo(2);
|
|
|
|
|
assertThat(view.getCurrentStepCode()).isEqualTo("03");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void completedStepAcceptsOnlyOneFinalizingSaveThenLocksTheOriginalAnswer() {
|
|
|
|
|
service.saveStep(USER, PAYMENT, "01", "{\"v\":1}");
|
|
|
|
|
service.completeThrough(USER, PAYMENT, "01");
|
|
|
|
|
|
|
|
|
|
// 完成之后紧接着的那一次保存(页面做完最后一个动作会自动存一次)被接受
|
|
|
|
|
TrainingTaskProgressService.TrainingTaskView view = service.saveStep(USER, PAYMENT, "01", "{\"v\":2}");
|
|
|
|
|
assertThat(view.getSteps().get(0).getStatus()).isEqualTo("COMPLETED");
|
|
|
|
|
assertThat(view.getSteps().get(0).isLocked()).isTrue();
|
|
|
|
|
assertThat(view.getCompletedSteps()).isEqualTo(1);
|
|
|
|
|
|
|
|
|
|
// 之后任何不同的内容都被拒绝,原答案保持不变
|
|
|
|
|
assertThatThrownBy(() -> service.saveStep(USER, PAYMENT, "01", "{\"v\":3,\"cheat\":true}"))
|
|
|
|
|
.isInstanceOf(BusinessException.class)
|
|
|
|
|
.satisfies(e -> assertThat(((BusinessException) e).getErrorCode()).isEqualTo(ErrorCode.CONFLICT));
|
|
|
|
|
TrainingTaskProgressService.TrainingStepDetailView detail = service.stepDetail(USER, PAYMENT, "01");
|
|
|
|
|
assertThat(detail.getStepData()).isEqualTo("{\"v\":2}");
|
|
|
|
|
assertThat(detail.isLocked()).isTrue();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void savingTheSameAnswerAgainAfterLockingIsAHarmlessNoOp() {
|
|
|
|
|
service.completeThrough(USER, PAYMENT, "01");
|
|
|
|
|
service.saveStep(USER, PAYMENT, "01", "{\"a\":1}");
|
|
|
|
|
|
|
|
|
|
TrainingTaskProgressService.TrainingTaskView view = service.saveStep(USER, PAYMENT, "01", "{\"a\":1}");
|
|
|
|
|
|
|
|
|
|
assertThat(view.getSteps().get(0).isLocked()).isTrue();
|
|
|
|
|
assertThat(service.stepDetail(USER, PAYMENT, "01").getStepData()).isEqualTo("{\"a\":1}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void lockedAnswerComparisonIgnoresWhitespaceAndKeyOrderButNotContent() {
|
|
|
|
|
service.completeThrough(USER, PAYMENT, "01");
|
|
|
|
|
service.saveStep(USER, PAYMENT, "01", "{\"a\":1,\"b\":[1,2],\"c\":{\"x\":\"房租\"}}");
|
|
|
|
|
|
|
|
|
|
// 只是排版、键顺序不同:同一份答案,视为幂等成功
|
|
|
|
|
service.saveStep(USER, PAYMENT, "01", "{ \"c\": {\"x\": \"房租\"}, \"b\": [1, 2], \"a\": 1 }");
|
|
|
|
|
|
|
|
|
|
// 内容有任何不同(值、数组顺序、多一个字段)都必须拒绝
|
|
|
|
|
for (String changed : new String[]{
|
|
|
|
|
"{\"a\":2,\"b\":[1,2],\"c\":{\"x\":\"房租\"}}",
|
|
|
|
|
"{\"a\":1,\"b\":[2,1],\"c\":{\"x\":\"房租\"}}",
|
|
|
|
|
"{\"a\":1,\"b\":[1,2],\"c\":{\"x\":\"房租\"},\"d\":0}"}) {
|
|
|
|
|
assertThatThrownBy(() -> service.saveStep(USER, PAYMENT, "01", changed))
|
|
|
|
|
.as(changed).isInstanceOf(BusinessException.class);
|
|
|
|
|
}
|
|
|
|
|
assertThat(service.stepDetail(USER, PAYMENT, "01").getStepData())
|
|
|
|
|
.isEqualTo("{\"a\":1,\"b\":[1,2],\"c\":{\"x\":\"房租\"}}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void draftsStayEditableUntilTheStepIsCompleted() {
|
|
|
|
|
service.saveStep(USER, PAYMENT, "02", "{\"v\":1}");
|
|
|
|
|
service.saveStep(USER, PAYMENT, "02", "{\"v\":2}");
|
|
|
|
|
service.saveStep(USER, PAYMENT, "02", "{\"v\":3}");
|
|
|
|
|
|
|
|
|
|
TrainingTaskProgressService.TrainingStepDetailView detail = service.stepDetail(USER, PAYMENT, "02");
|
|
|
|
|
assertThat(detail.getStepData()).isEqualTo("{\"v\":3}");
|
|
|
|
|
assertThat(detail.isLocked()).isFalse();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void completingALaterStepGivesEarlierDraftStepsTheirOneFinalizingSave() {
|
|
|
|
|
service.saveStep(USER, PAYMENT, "01", "{\"s\":1}");
|
|
|
|
|
service.completeThrough(USER, PAYMENT, "02");
|
|
|
|
|
|
|
|
|
|
service.saveStep(USER, PAYMENT, "01", "{\"s\":2}");
|
|
|
|
|
assertThatThrownBy(() -> service.saveStep(USER, PAYMENT, "01", "{\"s\":3}"))
|
|
|
|
|
.isInstanceOf(BusinessException.class);
|
|
|
|
|
assertThat(service.stepDetail(USER, PAYMENT, "01").getStepData()).isEqualTo("{\"s\":2}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void completedStepWithoutAnyAnswerCanStillBeSavedOnceAndLocksAfterwards() {
|
|
|
|
|
service.completeThrough(USER, PAYMENT, "01");
|
|
|
|
|
assertThat(service.stepDetail(USER, PAYMENT, "01").isLocked()).isFalse();
|
|
|
|
|
|
|
|
|
|
service.saveStep(USER, PAYMENT, "01", "{\"first\":1}");
|
|
|
|
|
|
|
|
|
|
assertThatThrownBy(() -> service.saveStep(USER, PAYMENT, "01", "{\"second\":2}"))
|
|
|
|
|
.isInstanceOf(BusinessException.class);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void lockingIsPerUserAndResetUnlocksTheModule() {
|
|
|
|
|
service.completeThrough(USER, PAYMENT, "01");
|
|
|
|
|
service.saveStep(USER, PAYMENT, "01", "{\"u\":1}");
|
|
|
|
|
|
|
|
|
|
service.saveStep(OTHER, PAYMENT, "01", "{\"o\":1}");
|
|
|
|
|
service.saveStep(OTHER, PAYMENT, "01", "{\"o\":2}");
|
|
|
|
|
assertThat(service.stepDetail(OTHER, PAYMENT, "01").getStepData()).isEqualTo("{\"o\":2}");
|
|
|
|
|
|
|
|
|
|
service.resetModule(USER, PAYMENT);
|
|
|
|
|
service.saveStep(USER, PAYMENT, "01", "{\"again\":1}");
|
|
|
|
|
assertThat(service.stepDetail(USER, PAYMENT, "01").getStepData()).isEqualTo("{\"again\":1}");
|
|
|
|
|
assertThat(service.stepDetail(USER, PAYMENT, "01").isLocked()).isFalse();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void draftsAreNeverCountedAsCompletedByTheModuleCompletionProgress() {
|
|
|
|
|
service.saveStep(USER, PAYMENT, "01", "{\"a\":1}");
|
|
|
|
|
service.saveStep(USER, PAYMENT, "02", "{\"b\":2}");
|
|
|
|
|
|
|
|
|
|
assertThat(moduleCompletion.getModuleCompletion(USER, "5").getSchedule()).isZero();
|
|
|
|
|
|
|
|
|
|
service.completeThrough(USER, PAYMENT, "01");
|
|
|
|
|
|
|
|
|
|
assertThat(moduleCompletion.getModuleCompletion(USER, "5").getSchedule())
|
|
|
|
|
.isEqualTo(16.67);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void usersNeverSeeEachOthersDrafts() {
|
|
|
|
|
service.saveStep(USER, PAYMENT, "01", "{\"secret\":1}");
|
|
|
|
|
|
|
|
|
|
assertThat(service.one(OTHER, PAYMENT).getSavedSteps()).isZero();
|
|
|
|
|
assertThat(service.stepDetail(OTHER, PAYMENT, "01").getStepData()).isNull();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void resetRemovesDraftsTogetherWithCompletedSteps() {
|
|
|
|
|
service.saveStep(USER, PAYMENT, "01", "{\"a\":1}");
|
|
|
|
|
service.completeThrough(USER, PAYMENT, "01");
|
|
|
|
|
service.saveStep(USER, PAYMENT, "02", "{\"b\":2}");
|
|
|
|
|
|
|
|
|
|
service.reset(USER, PAYMENT);
|
|
|
|
|
|
|
|
|
|
TrainingTaskProgressService.TrainingTaskView view = service.one(USER, PAYMENT);
|
|
|
|
|
assertThat(view.getStatus()).isEqualTo("NOT_STARTED");
|
|
|
|
|
assertThat(service.stepDetail(USER, PAYMENT, "02").getStepData()).isNull();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void resetModuleOnlyClearsTheRequestedModuleOfTheRequestedUser() {
|
|
|
|
|
service.saveStep(USER, PAYMENT, "01", "{\"a\":1}");
|
|
|
|
|
service.saveStep(USER, "CURRENCY_EXCHANGE", "01", "{\"b\":1}");
|
|
|
|
|
service.saveStep(OTHER, PAYMENT, "01", "{\"c\":1}");
|
|
|
|
|
|
|
|
|
|
service.resetModule(USER, PAYMENT);
|
|
|
|
|
|
|
|
|
|
assertThat(service.one(USER, PAYMENT).getSavedSteps()).isZero();
|
|
|
|
|
assertThat(service.one(USER, "CURRENCY_EXCHANGE").getSavedSteps()).isEqualTo(1);
|
|
|
|
|
assertThat(service.one(OTHER, PAYMENT).getSavedSteps()).isEqualTo(1);
|
|
|
|
|
// 没有数据时重复重置同样成功
|
|
|
|
|
service.resetModule(USER, PAYMENT);
|
|
|
|
|
assertThatThrownBy(() -> service.resetModule(USER, "NOPE")).isInstanceOf(BusinessException.class);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void everyModuleFromOneToFiveSupportsDrafts() {
|
|
|
|
|
String[] modules = {"PBOC_CURRENCY_GENERATION", "PBOC_CURRENCY_ISSUANCE", "WALLET_OPENING",
|
|
|
|
|
"CURRENCY_EXCHANGE", "CURRENCY_PAYMENT"};
|
|
|
|
|
int[] steps = {9, 7, 5, 5, 6};
|
|
|
|
|
for (int i = 0; i < modules.length; i++) {
|
|
|
|
|
TrainingTaskProgressService.TrainingTaskView view =
|
|
|
|
|
service.saveStep(USER, modules[i], "01", "{\"m\":" + i + "}");
|
|
|
|
|
|
|
|
|
|
assertThat(view.getTotalSteps()).as(modules[i]).isEqualTo(steps[i]);
|
|
|
|
|
assertThat(view.isActionUnavailable()).as(modules[i]).isFalse();
|
|
|
|
|
assertThat(view.getSteps().get(0).getStatus()).as(modules[i]).isEqualTo("SAVED");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void rejectsDataThatIsNotAJsonObjectOrArray() {
|
|
|
|
|
for (String bad : new String[]{"", " ", "not json", "{\"a\":", "{\"a\":1} x", "123", "\"text\"", "null"}) {
|
|
|
|
|
assertThatThrownBy(() -> service.saveStep(USER, PAYMENT, "01", bad))
|
|
|
|
|
.as("input=[" + bad + "]")
|
|
|
|
|
.isInstanceOf(BusinessException.class);
|
|
|
|
|
}
|
|
|
|
|
assertThatThrownBy(() -> service.saveStep(USER, PAYMENT, "01", null))
|
|
|
|
|
.isInstanceOf(BusinessException.class);
|
|
|
|
|
assertThat(service.one(USER, PAYMENT).getSavedSteps()).isZero();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void acceptsJsonArraysAndRejectsOversizedPayloads() {
|
|
|
|
|
assertThat(service.saveStep(USER, PAYMENT, "01", "[1,2,3]").getSavedSteps()).isEqualTo(1);
|
|
|
|
|
|
|
|
|
|
StringBuilder huge = new StringBuilder("{\"d\":\"");
|
|
|
|
|
for (int i = 0; i < TrainingTaskProgressService.MAX_STEP_DATA_LENGTH; i++) huge.append('x');
|
|
|
|
|
huge.append("\"}");
|
|
|
|
|
assertThatThrownBy(() -> service.saveStep(USER, PAYMENT, "02", huge.toString()))
|
|
|
|
|
.isInstanceOf(BusinessException.class);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void rejectsUnknownModulesAndStepsInsteadOfFailingWithAServerError() {
|
|
|
|
|
assertThatThrownBy(() -> service.saveStep(USER, "NOPE", "01", "{}"))
|
|
|
|
|
.isInstanceOf(BusinessException.class);
|
|
|
|
|
assertThatThrownBy(() -> service.saveStep(USER, PAYMENT, "99", "{}"))
|
|
|
|
|
.isInstanceOf(BusinessException.class);
|
|
|
|
|
assertThatThrownBy(() -> service.stepDetail(USER, PAYMENT, "99"))
|
|
|
|
|
.isInstanceOf(BusinessException.class);
|
|
|
|
|
assertThatThrownBy(() -> service.one(USER, "NOPE"))
|
|
|
|
|
.isInstanceOf(BusinessException.class);
|
|
|
|
|
}
|
|
|
|
|
}
|