test: 49 tests for economy services (EconomyService, BlackjackService, SlotService, JobService)
This commit is contained in:
parent
0787e98921
commit
4a3bc33356
4 changed files with 696 additions and 0 deletions
|
|
@ -0,0 +1,128 @@
|
||||||
|
package creator.loki.feature.economy.service;
|
||||||
|
|
||||||
|
import creator.loki.feature.economy.domain.EconomyAccount;
|
||||||
|
import creator.loki.feature.economy.repository.EconomyRepository;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Nested;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.Captor;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
class BlackjackServiceTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private EconomyRepository repository;
|
||||||
|
|
||||||
|
@Captor
|
||||||
|
private ArgumentCaptor<EconomyAccount> accountCaptor;
|
||||||
|
|
||||||
|
private BlackjackService service;
|
||||||
|
|
||||||
|
private final EconomyAccount account = new EconomyAccount.Builder()
|
||||||
|
.userId("user1").cash(1000).build();
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
service = new BlackjackService(repository);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
class StartGame {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsNullWhenBetIsZeroOrNegative() {
|
||||||
|
assertNull(service.startGame("user1", 0));
|
||||||
|
assertNull(service.startGame("user1", -50));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsNullWhenInsufficientCash() {
|
||||||
|
when(repository.getAccount("user1")).thenReturn(account);
|
||||||
|
|
||||||
|
assertNull(service.startGame("user1", 9999));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void deductsBetFromCash() {
|
||||||
|
when(repository.getAccount("user1")).thenReturn(account);
|
||||||
|
|
||||||
|
service.startGame("user1", 200);
|
||||||
|
|
||||||
|
verify(repository).save(accountCaptor.capture());
|
||||||
|
assertEquals(800, accountCaptor.getValue().getCash());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
class Hit {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsNullWhenNoActiveGame() {
|
||||||
|
assertNull(service.hit("user1"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
class Stand {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsNullWhenNoActiveGame() {
|
||||||
|
assertNull(service.stand("user1"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
class GameFlow {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void startGameThenStandCompletesGame() {
|
||||||
|
when(repository.getAccount("user1")).thenReturn(account);
|
||||||
|
|
||||||
|
BlackjackService.BlackjackState state = service.startGame("user1", 100);
|
||||||
|
assertNotNull(state);
|
||||||
|
|
||||||
|
state = service.stand("user1");
|
||||||
|
assertNotNull(state);
|
||||||
|
assertTrue(state.isOver());
|
||||||
|
assertTrue(state.payout() >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void playerHitsUntilBust() {
|
||||||
|
when(repository.getAccount("user1")).thenReturn(account);
|
||||||
|
|
||||||
|
BlackjackService.BlackjackState state = service.startGame("user1", 100);
|
||||||
|
assertNotNull(state);
|
||||||
|
|
||||||
|
int maxHits = 20;
|
||||||
|
while (!state.isOver() && maxHits-- > 0) {
|
||||||
|
state = service.hit("user1");
|
||||||
|
if (state == null) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
assertNotNull(state);
|
||||||
|
assertTrue(state.isOver());
|
||||||
|
if (state.playerSum() > 21) {
|
||||||
|
assertEquals(0, state.payout());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void startGameThenStandSavesPayout() {
|
||||||
|
when(repository.getAccount("user1")).thenReturn(account);
|
||||||
|
|
||||||
|
service.startGame("user1", 100);
|
||||||
|
service.stand("user1");
|
||||||
|
|
||||||
|
verify(repository, atLeast(2)).save(any());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,252 @@
|
||||||
|
package creator.loki.feature.economy.service;
|
||||||
|
|
||||||
|
import creator.loki.core.security.CooldownManager;
|
||||||
|
import creator.loki.feature.economy.domain.EconomyAccount;
|
||||||
|
import creator.loki.feature.economy.repository.EconomyRepository;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Nested;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.Captor;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
class EconomyServiceTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private EconomyRepository repository;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private CooldownManager cooldownManager;
|
||||||
|
|
||||||
|
@Captor
|
||||||
|
private ArgumentCaptor<EconomyAccount> accountCaptor;
|
||||||
|
|
||||||
|
private EconomyService service;
|
||||||
|
|
||||||
|
private final EconomyAccount baseAccount = new EconomyAccount.Builder()
|
||||||
|
.userId("user1").cash(1000).bank(500).totalEarned(200).totalSpent(100)
|
||||||
|
.lastDaily(LocalDate.now().minusDays(2).toString())
|
||||||
|
.dailyStreak(0).efficiency(0).fishingLuck(0)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
private final EconomyAccount targetAccount = new EconomyAccount.Builder()
|
||||||
|
.userId("user2").cash(500).bank(0).build();
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
service = new EconomyService(repository, cooldownManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
class Transfer {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsFalseWhenAmountIsZeroOrNegative() {
|
||||||
|
assertFalse(service.transfer("user1", "user2", 0));
|
||||||
|
assertFalse(service.transfer("user1", "user2", -1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsFalseWhenSenderHasInsufficientCash() {
|
||||||
|
when(repository.getAccount("user1")).thenReturn(baseAccount);
|
||||||
|
|
||||||
|
assertFalse(service.transfer("user1", "user2", 9999));
|
||||||
|
verify(repository, never()).save(any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsTrueAndTransfersCashCorrectly() {
|
||||||
|
when(repository.getAccount("user1")).thenReturn(baseAccount);
|
||||||
|
when(repository.getAccount("user2")).thenReturn(targetAccount);
|
||||||
|
|
||||||
|
assertTrue(service.transfer("user1", "user2", 200));
|
||||||
|
|
||||||
|
verify(repository, times(2)).save(accountCaptor.capture());
|
||||||
|
assertEquals(800, accountCaptor.getAllValues().get(0).getCash());
|
||||||
|
assertEquals(700, accountCaptor.getAllValues().get(1).getCash());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void callsRepositorySaveTwice() {
|
||||||
|
when(repository.getAccount("user1")).thenReturn(baseAccount);
|
||||||
|
when(repository.getAccount("user2")).thenReturn(targetAccount);
|
||||||
|
|
||||||
|
service.transfer("user1", "user2", 100);
|
||||||
|
|
||||||
|
verify(repository, times(2)).save(any());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
class Deposit {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsFalseWhenAmountIsZeroOrNegative() {
|
||||||
|
assertFalse(service.deposit("user1", 0));
|
||||||
|
assertFalse(service.deposit("user1", -5));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsFalseWhenInsufficientCash() {
|
||||||
|
when(repository.getAccount("user1")).thenReturn(baseAccount);
|
||||||
|
|
||||||
|
assertFalse(service.deposit("user1", 9999));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsTrueAndMovesCashToBank() {
|
||||||
|
when(repository.getAccount("user1")).thenReturn(baseAccount);
|
||||||
|
|
||||||
|
assertTrue(service.deposit("user1", 300));
|
||||||
|
|
||||||
|
verify(repository).save(accountCaptor.capture());
|
||||||
|
EconomyAccount saved = accountCaptor.getValue();
|
||||||
|
assertEquals(700, saved.getCash());
|
||||||
|
assertEquals(800, saved.getBank());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
class Withdraw {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsFalseWhenAmountIsZeroOrNegative() {
|
||||||
|
assertFalse(service.withdraw("user1", 0));
|
||||||
|
assertFalse(service.withdraw("user1", -10));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsFalseWhenInsufficientBank() {
|
||||||
|
when(repository.getAccount("user1")).thenReturn(baseAccount);
|
||||||
|
|
||||||
|
assertFalse(service.withdraw("user1", 9999));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsTrueAndMovesBankToCash() {
|
||||||
|
when(repository.getAccount("user1")).thenReturn(baseAccount);
|
||||||
|
|
||||||
|
assertTrue(service.withdraw("user1", 200));
|
||||||
|
|
||||||
|
verify(repository).save(accountCaptor.capture());
|
||||||
|
EconomyAccount saved = accountCaptor.getValue();
|
||||||
|
assertEquals(1200, saved.getCash());
|
||||||
|
assertEquals(300, saved.getBank());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
class EarnCash {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void addsToCashAndTotalEarned() {
|
||||||
|
when(repository.getAccount("user1")).thenReturn(baseAccount);
|
||||||
|
|
||||||
|
long newCash = service.earnCash("user1", 150);
|
||||||
|
|
||||||
|
assertEquals(1150, newCash);
|
||||||
|
verify(repository).save(accountCaptor.capture());
|
||||||
|
EconomyAccount saved = accountCaptor.getValue();
|
||||||
|
assertEquals(1150, saved.getCash());
|
||||||
|
assertEquals(350, saved.getTotalEarned());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
class SpendCash {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsFalseWhenAmountIsZeroOrNegative() {
|
||||||
|
assertFalse(service.spendCash("user1", 0));
|
||||||
|
assertFalse(service.spendCash("user1", -50));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsFalseWhenInsufficientCash() {
|
||||||
|
when(repository.getAccount("user1")).thenReturn(baseAccount);
|
||||||
|
|
||||||
|
assertFalse(service.spendCash("user1", 9999));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsTrueAndSubtractsCashAndAddsToTotalSpent() {
|
||||||
|
when(repository.getAccount("user1")).thenReturn(baseAccount);
|
||||||
|
|
||||||
|
assertTrue(service.spendCash("user1", 400));
|
||||||
|
|
||||||
|
verify(repository).save(accountCaptor.capture());
|
||||||
|
EconomyAccount saved = accountCaptor.getValue();
|
||||||
|
assertEquals(600, saved.getCash());
|
||||||
|
assertEquals(500, saved.getTotalSpent());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
class ClaimDaily {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsNullWhenAlreadyClaimedToday() {
|
||||||
|
EconomyAccount todayClaimed = new EconomyAccount.Builder(baseAccount)
|
||||||
|
.lastDaily(LocalDate.now().toString())
|
||||||
|
.build();
|
||||||
|
when(repository.getAccount("user1")).thenReturn(todayClaimed);
|
||||||
|
|
||||||
|
assertNull(service.claimDaily("user1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsDailyResultWithStreakOneForNewUser() {
|
||||||
|
EconomyAccount newUser = new EconomyAccount.Builder()
|
||||||
|
.userId("user1").cash(100).lastDaily(null).dailyStreak(0).build();
|
||||||
|
when(repository.getAccount("user1")).thenReturn(newUser);
|
||||||
|
|
||||||
|
EconomyService.DailyResult result = service.claimDaily("user1");
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals(1, result.streak());
|
||||||
|
assertEquals(50, result.amount());
|
||||||
|
assertEquals(150, result.newCash());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsDailyResultWithStreakTwoForConsecutiveDays() {
|
||||||
|
EconomyAccount returning = new EconomyAccount.Builder(baseAccount)
|
||||||
|
.cash(200).totalEarned(50)
|
||||||
|
.lastDaily(LocalDate.now().minusDays(1).toString())
|
||||||
|
.dailyStreak(1).build();
|
||||||
|
when(repository.getAccount("user1")).thenReturn(returning);
|
||||||
|
|
||||||
|
EconomyService.DailyResult result = service.claimDaily("user1");
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals(2, result.streak());
|
||||||
|
assertEquals(50, result.amount());
|
||||||
|
assertEquals(250, result.newCash());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsDailyResultWithAmountSeventyFiveForStreakAtLeastSeven() {
|
||||||
|
EconomyAccount veteran = new EconomyAccount.Builder(baseAccount)
|
||||||
|
.cash(500).totalEarned(300)
|
||||||
|
.lastDaily(LocalDate.now().minusDays(1).toString())
|
||||||
|
.dailyStreak(6).build();
|
||||||
|
when(repository.getAccount("user1")).thenReturn(veteran);
|
||||||
|
|
||||||
|
EconomyService.DailyResult result = service.claimDaily("user1");
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals(7, result.streak());
|
||||||
|
assertEquals(75, result.amount());
|
||||||
|
assertEquals(575, result.newCash());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,184 @@
|
||||||
|
package creator.loki.feature.economy.service;
|
||||||
|
|
||||||
|
import creator.loki.feature.economy.domain.EconomyAccount;
|
||||||
|
import creator.loki.feature.economy.domain.Job;
|
||||||
|
import creator.loki.feature.economy.repository.EconomyRepository;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Nested;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.Captor;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
class JobServiceTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private EconomyRepository repository;
|
||||||
|
|
||||||
|
@Captor
|
||||||
|
private ArgumentCaptor<EconomyAccount> accountCaptor;
|
||||||
|
|
||||||
|
private JobService service;
|
||||||
|
|
||||||
|
private final EconomyAccount account = new EconomyAccount.Builder()
|
||||||
|
.userId("user1").cash(100).totalEarned(0).efficiency(0)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
service = new JobService(repository);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
class ListJobs {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsSixJobs() {
|
||||||
|
List<JobService.JobInfo> jobs = service.listJobs();
|
||||||
|
|
||||||
|
assertEquals(6, jobs.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void containsWoodcutter() {
|
||||||
|
List<JobService.JobInfo> jobs = service.listJobs();
|
||||||
|
|
||||||
|
JobService.JobInfo woodcutter = jobs.stream()
|
||||||
|
.filter(j -> j.name().equals("WOODCUTTER"))
|
||||||
|
.findFirst().orElseThrow();
|
||||||
|
assertEquals("Лесоруб", woodcutter.displayName());
|
||||||
|
assertEquals(0, woodcutter.requiredLevel());
|
||||||
|
assertEquals(15, woodcutter.minPayout());
|
||||||
|
assertEquals(30, woodcutter.maxPayout());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
class SetJob {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void savesJobNameToAccount() {
|
||||||
|
when(repository.getAccount("user1")).thenReturn(account);
|
||||||
|
|
||||||
|
service.setJob("user1", "WOODCUTTER");
|
||||||
|
|
||||||
|
verify(repository).save(accountCaptor.capture());
|
||||||
|
assertEquals("WOODCUTTER", accountCaptor.getValue().getJob());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void doesNothingForInvalidJobName() {
|
||||||
|
service.setJob("user1", "INVALID");
|
||||||
|
|
||||||
|
verify(repository, never()).save(any());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
class GetCurrentJob {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsDisplayNameWhenJobIsSet() {
|
||||||
|
EconomyAccount withJob = new EconomyAccount.Builder(account)
|
||||||
|
.job("MINER").build();
|
||||||
|
when(repository.getAccount("user1")).thenReturn(withJob);
|
||||||
|
|
||||||
|
String display = service.getCurrentJob("user1");
|
||||||
|
|
||||||
|
assertEquals("Шахтёр", display);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsNullWhenNoJob() {
|
||||||
|
when(repository.getAccount("user1")).thenReturn(account);
|
||||||
|
|
||||||
|
assertNull(service.getCurrentJob("user1"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
class Work {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsNullWhenNoJobSet() {
|
||||||
|
when(repository.getAccount("user1")).thenReturn(account);
|
||||||
|
|
||||||
|
assertNull(service.work("user1", 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsNullWhenOnCooldown() {
|
||||||
|
EconomyAccount withJob = new EconomyAccount.Builder(account)
|
||||||
|
.job("WOODCUTTER").lastWork(String.valueOf(System.currentTimeMillis()))
|
||||||
|
.build();
|
||||||
|
when(repository.getAccount("user1")).thenReturn(withJob);
|
||||||
|
|
||||||
|
assertNull(service.work("user1", 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsWorkResultWithPayoutInRange() {
|
||||||
|
EconomyAccount withJob = new EconomyAccount.Builder(account)
|
||||||
|
.job("WOODCUTTER").lastWork("0")
|
||||||
|
.build();
|
||||||
|
when(repository.getAccount("user1")).thenReturn(withJob);
|
||||||
|
|
||||||
|
JobService.WorkResult result = service.work("user1", 0);
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
assertTrue(result.amount() >= 15);
|
||||||
|
assertTrue(result.amount() <= 30);
|
||||||
|
assertTrue(result.newCash() >= 115);
|
||||||
|
assertTrue(result.newCash() <= 130);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void multipliesPayoutByEfficiency() {
|
||||||
|
EconomyAccount efficient = new EconomyAccount.Builder(account)
|
||||||
|
.job("WOODCUTTER").lastWork("0").efficiency(100)
|
||||||
|
.build();
|
||||||
|
when(repository.getAccount("user1")).thenReturn(efficient);
|
||||||
|
|
||||||
|
JobService.WorkResult result = service.work("user1", 0);
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
assertTrue(result.amount() >= 30);
|
||||||
|
assertTrue(result.amount() <= 60);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsNullWhenLevelTooLow() {
|
||||||
|
EconomyAccount withJob = new EconomyAccount.Builder(account)
|
||||||
|
.job("PROGRAMMER").lastWork("0")
|
||||||
|
.build();
|
||||||
|
when(repository.getAccount("user1")).thenReturn(withJob);
|
||||||
|
|
||||||
|
assertNull(service.work("user1", 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void savesUpdatedAccount() {
|
||||||
|
EconomyAccount withJob = new EconomyAccount.Builder(account)
|
||||||
|
.job("WOODCUTTER").lastWork("0")
|
||||||
|
.build();
|
||||||
|
when(repository.getAccount("user1")).thenReturn(withJob);
|
||||||
|
|
||||||
|
service.work("user1", 0);
|
||||||
|
|
||||||
|
verify(repository).save(accountCaptor.capture());
|
||||||
|
EconomyAccount saved = accountCaptor.getValue();
|
||||||
|
assertNotNull(saved.getLastWork());
|
||||||
|
assertTrue(saved.getCash() >= 115);
|
||||||
|
assertTrue(saved.getTotalEarned() >= 15);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,132 @@
|
||||||
|
package creator.loki.feature.economy.service;
|
||||||
|
|
||||||
|
import creator.loki.feature.economy.domain.EconomyAccount;
|
||||||
|
import creator.loki.feature.economy.domain.SlotCombination;
|
||||||
|
import creator.loki.feature.economy.repository.EconomyRepository;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Nested;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.Captor;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
class SlotServiceTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private EconomyRepository repository;
|
||||||
|
|
||||||
|
@Captor
|
||||||
|
private ArgumentCaptor<EconomyAccount> accountCaptor;
|
||||||
|
|
||||||
|
private SlotService service;
|
||||||
|
|
||||||
|
private final EconomyAccount account = new EconomyAccount.Builder()
|
||||||
|
.userId("user1").cash(500).build();
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
service = new SlotService(repository);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
class Spin {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsNullWhenBetIsZeroOrNegative() {
|
||||||
|
assertNull(service.spin("user1", 0));
|
||||||
|
assertNull(service.spin("user1", -10));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsNullWhenInsufficientCash() {
|
||||||
|
when(repository.getAccount("user1")).thenReturn(account);
|
||||||
|
|
||||||
|
assertNull(service.spin("user1", 9999));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void deductsBetFromCash() {
|
||||||
|
when(repository.getAccount("user1")).thenReturn(account);
|
||||||
|
|
||||||
|
service.spin("user1", 100);
|
||||||
|
|
||||||
|
verify(repository, atLeastOnce()).save(accountCaptor.capture());
|
||||||
|
assertEquals(400, accountCaptor.getAllValues().get(0).getCash());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsNonNullResultWithValidEmojis() {
|
||||||
|
when(repository.getAccount("user1")).thenReturn(account);
|
||||||
|
|
||||||
|
SlotService.SlotResult result = service.spin("user1", 100);
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
assertNotNull(result.emoji1());
|
||||||
|
assertNotNull(result.emoji2());
|
||||||
|
assertNotNull(result.emoji3());
|
||||||
|
assertTrue(result.cashAfter() >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void winAmountIsZeroAndComboNameIsNullWhenNoMatch() {
|
||||||
|
when(repository.getAccount("user1")).thenReturn(account);
|
||||||
|
|
||||||
|
SlotService.SlotResult result = service.spin("user1", 100);
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals(result.cashAfter(), account.getCash() - 100 + result.winAmount());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
class SlotCombinationMatch {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsNullForNonMatchingEmojis() {
|
||||||
|
assertNull(SlotCombination.match("\uD83C\uDF52", "\uD83D\uDD14", "\uD83D\uDC8E"));
|
||||||
|
assertNull(SlotCombination.match("\uD83C\uDF52", "\uD83C\uDF52", "\uD83D\uDD14"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsCherryForThreeCherries() {
|
||||||
|
SlotCombination result = SlotCombination.match("\uD83C\uDF52", "\uD83C\uDF52", "\uD83C\uDF52");
|
||||||
|
assertEquals(SlotCombination.CHERRY, result);
|
||||||
|
assertEquals(3, result.getMultiplier());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsBellForThreeBells() {
|
||||||
|
SlotCombination result = SlotCombination.match("\uD83D\uDD14", "\uD83D\uDD14", "\uD83D\uDD14");
|
||||||
|
assertEquals(SlotCombination.BELL, result);
|
||||||
|
assertEquals(5, result.getMultiplier());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsDiamondForThreeDiamonds() {
|
||||||
|
SlotCombination result = SlotCombination.match("\uD83D\uDC8E", "\uD83D\uDC8E", "\uD83D\uDC8E");
|
||||||
|
assertEquals(SlotCombination.DIAMOND, result);
|
||||||
|
assertEquals(10, result.getMultiplier());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsCrownForThreeCrowns() {
|
||||||
|
SlotCombination result = SlotCombination.match("\uD83D\uDC51", "\uD83D\uDC51", "\uD83D\uDC51");
|
||||||
|
assertEquals(SlotCombination.CROWN, result);
|
||||||
|
assertEquals(15, result.getMultiplier());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsJackpotForThreeLightningBolts() {
|
||||||
|
SlotCombination result = SlotCombination.match("\u26A1", "\u26A1", "\u26A1");
|
||||||
|
assertEquals(SlotCombination.JACKPOT, result);
|
||||||
|
assertEquals(50, result.getMultiplier());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue