Skip to content

Commit

Permalink
fix: Clean up and refactor test tools (serverpod#2816)
Browse files Browse the repository at this point in the history
  • Loading branch information
hampuslavin authored Oct 4, 2024
1 parent 830108f commit 4ad06e9
Show file tree
Hide file tree
Showing 12 changed files with 741 additions and 498 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ export 'serverpod_test.dart'
show
AuthenticationOverride,
ConnectionClosedException,
flushMicrotasks,
flushEventQueue,
InvalidConfigurationException,
ResetTestSessions,
RollbackDatabase,
ServerpodInsufficientAccessException,
ServerpodUnauthenticatedException,
Expand Down
14 changes: 5 additions & 9 deletions packages/serverpod_test/lib/src/test_session.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ abstract class TestSession implements DatabaseAccessor {
/// AuthenticationInfo for the session.
Future<AuthenticationInfo?> get authenticationInfo;

/// Access to the message central
MessageCentralAccess get messages;
/// Gets the unerlying Serverpod session
Session get serverpodSession;

/// Creates a new unique session with the provided properties.
/// This is useful for setting up different session states in the tests
Expand All @@ -57,6 +57,7 @@ class InternalTestSession extends TestSession {
final bool _enableLogging;

/// The underlying Serverpod session
@override
InternalServerpodSession serverpodSession;

@override
Expand All @@ -67,9 +68,6 @@ class InternalTestSession extends TestSession {
return serverpodSession.authenticated;
}

@override
MessageCentralAccess get messages => serverpodSession.messages;

@override
Transaction? get transaction =>
serverpodSession.transactionManager.currentTransaction;
Expand Down Expand Up @@ -121,11 +119,9 @@ class InternalTestSession extends TestSession {
}
}

/// Resets the internal state of the test session
/// and recreates the underlying Serverpod session.
Future<void> resetState() async {
/// Recreates the underlying Serverpod session.
Future<void> recreateServerpodSession() async {
await serverpodSession.close();
_authenticationOverride = null;
serverpodSession = _testServerpod.createSession(
enableLogging: _enableLogging,
rollbackDatabase: serverpodSession.rollbackDatabase,
Expand Down
8 changes: 4 additions & 4 deletions packages/serverpod_test/lib/src/util.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/// Test helper to flush all pending microtasks.
/// Test helper to flush the event queue.
/// Useful for waiting for async events to complete before continuing the test.
///
/// For example, if depending on a generator function to execute up to its `yield`, then the
Expand All @@ -9,8 +9,8 @@
/// await flushEventQueue();
/// ```
///
/// Implemenation note: `Future.delayed` will be put on the event loop since it's a timer.
/// Items on the event loop are not processed until all pending microtasks are completed.
Future<void> flushMicrotasks() {
/// Implemenation note: `Future.delayed` will be put last in the event queue since it's a timer.
/// This will ensure that all other events are processed before the `Future.delayed` event.
Future<void> flushEventQueue() {
return Future.delayed(Duration.zero);
}
18 changes: 2 additions & 16 deletions packages/serverpod_test/lib/src/with_serverpod.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,6 @@ class InvalidConfigurationException implements Exception {
}
}

/// Options for when to reset the test session and recreate
/// the underlying Serverpod session during the test lifecycle.
enum ResetTestSessions {
/// After each test. This is the default.
afterEach,

/// After all tests.
afterAll,
}

/// Options for when to rollback the database during the test lifecycle.
enum RollbackDatabase {
/// After each test. This is the default.
Expand All @@ -70,11 +60,9 @@ void Function(TestClosure<T>)
buildWithServerpod<T extends InternalTestEndpoints>(
String testGroupName,
TestServerpod<T> testServerpod, {
ResetTestSessions? maybeResetTestSessions,
RollbackDatabase? maybeRollbackDatabase,
bool? maybeEnableSessionLogging,
}) {
var resetTestSessions = maybeResetTestSessions ?? ResetTestSessions.afterEach;
var rollbackDatabase = maybeRollbackDatabase ?? RollbackDatabase.afterEach;
List<InternalTestSession> allTestSessions = [];

Expand Down Expand Up @@ -112,10 +100,8 @@ void Function(TestClosure<T>)
await transactionManager.addSavePoint();
}

if (resetTestSessions == ResetTestSessions.afterEach) {
for (var testSession in allTestSessions) {
await testSession.resetState();
}
for (var testSession in allTestSessions) {
await testSession.recreateServerpodSession();
}

await GlobalStreamManager.closeAllStreams();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ void main() {

var stream = endpoints.methodStreaming.getBroadcastStream(session);
// Wait for the stream to be created, otherwise cancel is called before creation
await flushMicrotasks();
await flushEventQueue();

var subscription = stream.listen((event) {});
await subscription.cancel();
Expand All @@ -45,7 +45,7 @@ void main() {

var stream = endpoints.methodStreaming.getBroadcastStream(session);
// Wait for the stream to be created, otherwise cancel is called before creation
await flushMicrotasks();
await flushEventQueue();

var subscription = stream.listen((event) {});
await subscription.cancel();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ void main() {
'and the authenticated user is revoked then stream is closed with ConnectionClosedException.',
() async {
await expectLater(
session.messages.authenticationRevoked(
session.serverpodSession.messages.authenticationRevoked(
authenticatedUserId,
RevokedAuthenticationUser(),
),
Expand All @@ -153,7 +153,7 @@ void main() {
'and the required scope for an endpoint is revoked then stream is closed with ConnectionClosedException.',
() async {
await expectLater(
session.messages.authenticationRevoked(
session.serverpodSession.messages.authenticationRevoked(
authenticatedUserId,
RevokedAuthenticationScope(scopes: ['user']),
),
Expand Down Expand Up @@ -235,7 +235,7 @@ void main() {
'and the authenticated user is revoked then streams are closed with ConnectionClosedException.',
() async {
await expectLater(
session.messages.authenticationRevoked(
session.serverpodSession.messages.authenticationRevoked(
authenticatedUserId,
RevokedAuthenticationUser(),
),
Expand All @@ -261,7 +261,7 @@ void main() {
'and the required scope for an endpoint is revoked then streams are closed with ConnectionClosedException.',
() async {
await expectLater(
session.messages.authenticationRevoked(
session.serverpodSession.messages.authenticationRevoked(
authenticatedUserId,
RevokedAuthenticationScope(scopes: ['user']),
),
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ void main() {

var stream =
endpoints.testTools.listenForNumbersOnSharedStream(userSession1);
await flushMicrotasks();
await flushEventQueue();

await endpoints.testTools.postNumberToSharedStream(userSession2, 111);
await endpoints.testTools.postNumberToSharedStream(userSession2, 222);
Expand Down
Loading

0 comments on commit 4ad06e9

Please sign in to comment.