-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feature: 대기열 페이지에서 빠져나간 사용자와 대기한 사용자를 구분한다. (#152)
- Loading branch information
Showing
12 changed files
with
308 additions
and
10 deletions.
There are no files selected for viewing
14 changes: 14 additions & 0 deletions
14
src/main/java/com/thirdparty/ticketing/domain/waitingsystem/LastPollingEvent.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package com.thirdparty.ticketing.domain.waitingsystem; | ||
|
||
import com.thirdparty.ticketing.domain.common.Event; | ||
|
||
import lombok.Getter; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@Getter | ||
@RequiredArgsConstructor | ||
public class LastPollingEvent implements Event { | ||
|
||
private final String email; | ||
private final long performanceId; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -137,7 +137,7 @@ void setUp() throws JsonProcessingException { | |
void removeExpiredMemberInfoFromRunningRoom() { | ||
// given | ||
String anotherEmail = "[email protected]"; | ||
ZonedDateTime now = ZonedDateTime.now(); | ||
ZonedDateTime now = ZonedDateTime.now().plusSeconds(30); | ||
rawRunningRoom.add(getRunningRoomKey(performanceId), anotherEmail, now.toEpochSecond()); | ||
|
||
// when | ||
|
@@ -153,7 +153,7 @@ void removeExpiredMemberInfoFromRunningRoom() { | |
void removeExpiredMemberInfoFromWaitingRoom() throws JsonProcessingException { | ||
// given | ||
String anotherEmail = "[email protected]"; | ||
ZonedDateTime now = ZonedDateTime.now(); | ||
ZonedDateTime now = ZonedDateTime.now().plusSeconds(30); | ||
WaitingMember waitingMember = new WaitingMember(anotherEmail, performanceId, 2, now); | ||
rawRunningRoom.add(getRunningRoomKey(performanceId), anotherEmail, now.toEpochSecond()); | ||
rawWaitingRoom.put( | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,12 @@ | ||
package com.thirdparty.ticketing.global.waitingsystem; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.assertj.core.api.Assertions.within; | ||
|
||
import java.time.Instant; | ||
import java.time.ZoneId; | ||
import java.time.ZonedDateTime; | ||
import java.time.temporal.ChronoUnit; | ||
import java.util.Set; | ||
|
||
import org.junit.jupiter.api.BeforeEach; | ||
|
@@ -11,6 +16,7 @@ | |
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.data.redis.core.StringRedisTemplate; | ||
import org.springframework.data.redis.core.ZSetOperations; | ||
import org.springframework.data.redis.core.ZSetOperations.TypedTuple; | ||
|
||
import com.thirdparty.ticketing.domain.common.EventPublisher; | ||
import com.thirdparty.ticketing.domain.waitingsystem.WaitingSystem; | ||
|
@@ -32,6 +38,10 @@ void setUp() { | |
redisTemplate.getConnectionFactory().getConnection().commands().flushAll(); | ||
} | ||
|
||
private String getRunningRoomKey(long performanceId) { | ||
return "running_room:" + performanceId; | ||
} | ||
|
||
@Nested | ||
@DisplayName("폴링 이벤트 발행 시") | ||
class PublishPoolingEventTest { | ||
|
@@ -54,4 +64,80 @@ void moveUserToRunningRoom() { | |
assertThat(waitingSystem.isReadyToHandle(email, performanceId)).isTrue(); | ||
} | ||
} | ||
|
||
@Nested | ||
@DisplayName("마지막 폴링 이벤트 발행 시") | ||
class PublishLastPollingEventTest { | ||
|
||
@Test | ||
@DisplayName("작업 공간의 사용자 만료 시간을 업데이트한다.") | ||
void updateRunningMemberExpiredTime() { | ||
// given | ||
long performanceId = 1; | ||
String email = "[email protected]"; | ||
|
||
waitingSystem.enterWaitingRoom(email, performanceId); | ||
waitingSystem.moveUserToRunning(performanceId); | ||
|
||
// when | ||
waitingSystem.getRemainingCount(email, performanceId); | ||
|
||
// then | ||
Set<TypedTuple<String>> tuples = | ||
rawRunningRoom.rangeWithScores(getRunningRoomKey(performanceId), 0, -1); | ||
assertThat(tuples) | ||
.hasSize(1) | ||
.first() | ||
.satisfies( | ||
tuple -> { | ||
ZonedDateTime memberExpiredTime = | ||
ZonedDateTime.ofInstant( | ||
Instant.ofEpochSecond(tuple.getScore().longValue()), | ||
ZoneId.of("Asia/Seoul")); | ||
assertThat(memberExpiredTime) | ||
.isCloseTo( | ||
ZonedDateTime.now().plusMinutes(5), | ||
within(5, ChronoUnit.MINUTES)); | ||
}); | ||
} | ||
|
||
@Test | ||
@DisplayName("이메일에 해당하는 사용자만 업데이트한다.") | ||
void updateOnlyInputMember() { | ||
// given | ||
long performanceId = 1; | ||
String email = "[email protected]"; | ||
String anotherEmail = "[email protected]"; | ||
|
||
waitingSystem.enterWaitingRoom(email, performanceId); | ||
waitingSystem.enterWaitingRoom(anotherEmail, performanceId); | ||
waitingSystem.moveUserToRunning(performanceId); | ||
|
||
// when | ||
waitingSystem.getRemainingCount(email, performanceId); | ||
|
||
// then | ||
Set<TypedTuple<String>> tuples = | ||
rawRunningRoom.rangeWithScores(getRunningRoomKey(performanceId), 0, -1); | ||
TypedTuple<String> emailMember = | ||
tuples.stream() | ||
.filter(tuple -> tuple.getValue().equals(email)) | ||
.findFirst() | ||
.get(); | ||
TypedTuple<String> anotherEmailMember = | ||
tuples.stream() | ||
.filter(tuple -> tuple.getValue().equals(anotherEmail)) | ||
.findFirst() | ||
.get(); | ||
assertThat(getTime(emailMember.getScore())) | ||
.isCloseTo(ZonedDateTime.now().plusMinutes(5), within(1, ChronoUnit.MINUTES)); | ||
assertThat(getTime(anotherEmailMember.getScore())) | ||
.isCloseTo(ZonedDateTime.now().plusSeconds(30), within(5, ChronoUnit.SECONDS)); | ||
} | ||
|
||
private ZonedDateTime getTime(Double score) { | ||
return ZonedDateTime.ofInstant( | ||
Instant.ofEpochSecond(score.longValue()), ZoneId.of("Asia/Seoul")); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,11 @@ | ||
package com.thirdparty.ticketing.global.waitingsystem.memory.running; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.assertj.core.api.Assertions.catchException; | ||
import static org.assertj.core.api.Assertions.within; | ||
|
||
import java.time.ZonedDateTime; | ||
import java.time.temporal.ChronoUnit; | ||
import java.util.HashSet; | ||
import java.util.Set; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
|
@@ -216,4 +219,43 @@ void notRemoveMemberInfo() { | |
assertThat(room.get(performanceId).get(email)).isEqualTo(waitingMember); | ||
} | ||
} | ||
|
||
@Nested | ||
@DisplayName("사용자 만료 시간 업데이트 시") | ||
class UpdateRunningMemberExpiredTimeTest { | ||
|
||
@Test | ||
@DisplayName("사용자의 만료 시간을 5분으로 업데이트 한다.") | ||
void updateRunningMemberExpiredTime() { | ||
// given | ||
long performanceId = 1; | ||
String email = "[email protected]"; | ||
runningRoom.enter(performanceId, Set.of(new WaitingMember(email, performanceId))); | ||
|
||
// when | ||
runningRoom.updateRunningMemberExpiredTime(email, performanceId); | ||
|
||
// then | ||
WaitingMember waitingMember = room.get(performanceId).get(email); | ||
assertThat(waitingMember.getEnteredAt()) | ||
.isCloseTo(ZonedDateTime.now().plusMinutes(5), within(1, ChronoUnit.SECONDS)); | ||
} | ||
|
||
@Test | ||
@DisplayName("사용자가 작업 공간에 존재하지 않으면 무시한다.") | ||
void ignore_notExistsMember() { | ||
// given | ||
long performanceId = 1; | ||
String email = "[email protected]"; | ||
room.put(performanceId, new ConcurrentHashMap<>()); | ||
|
||
// when | ||
Exception exception = | ||
catchException( | ||
() -> runningRoom.updateRunningMemberExpiredTime(email, performanceId)); | ||
|
||
// then | ||
assertThat(exception).doesNotThrowAnyException(); | ||
} | ||
} | ||
} |
Oops, something went wrong.