chore: scaffold the Serverpod 4 build

Deviations from a stock `serverpod create`:
- Dropped Flutter web support, for two reasons:
  - Appflowy editor had issues in the past, potentially related to the
    Flutter-Web IME bridge. Upstream has also open bugs in relation to
that:
    - AppFlowy-IO/appflowy-editor#1029 [Bug][Web] Unwanted space on click
       and overall space bugs (open)
    - AppFlowy-IO/appflowy-editor#782 [Bug] Editor auto-scrolling when
       pressing space too quickly if placed inside a scrollable (open)
  - Offline-first is a required feature. serverpod_offline_sync's SQLite
    support in browsers, maybe via sqlite3.wasm + OPFS, is not
documented.
- SDK constraints raised to ^3.13.0, instead of ^3.12.2, so enjoy the
  newest language features.
- Pinned to Flutter 3.47.4 via FVM.

Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-09-16 19:24:59 +02:00
commit e17d99fa51
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64
2 changed files with 17563 additions and 0 deletions

View file

@ -0,0 +1,24 @@
import 'package:test/test.dart';
// Import the generated test helper file, it contains everything you need.
import 'test_tools/serverpod_test_tools.dart';
void main() {
// This is an example test that uses the `withServerpod` test helper.
// `withServerpod` enables you to call your endpoints directly from the test like regular functions.
// Note that after adding or modifying an endpoint, you will need to run
// `serverpod generate` to update the test tools code.
// Refer to the docs for more information on how to use the test helper.
withServerpod('Given Greeting endpoint', (sessionBuilder, endpoints) {
test(
'when calling `hello` with name then returned greeting includes name',
() async {
// Call the endpoint method by using the `endpoints` parameter and
// pass `sessionBuilder` as a first argument. Refer to the docs on
// how to use the `sessionBuilder` to set up different test scenarios.
final greeting = await endpoints.greeting.hello(sessionBuilder, 'Bob');
expect(greeting.message, 'Hello Bob');
},
);
});
}

View file

@ -0,0 +1,537 @@
/* AUTOMATICALLY GENERATED CODE DO NOT MODIFY */
/* To generate run: "serverpod generate" */
// ignore_for_file: implementation_imports
// ignore_for_file: library_private_types_in_public_api
// ignore_for_file: non_constant_identifier_names
// ignore_for_file: public_member_api_docs
// ignore_for_file: type_literal_in_constant_pattern
// ignore_for_file: use_super_parameters
// ignore_for_file: invalid_use_of_internal_member
// ignore_for_file: no_leading_underscores_for_local_identifiers
// ignore_for_file: no_leading_underscores_for_library_prefixes
import 'dart:async' as _ida;
import 'dart:io' as _idi;
import 'package:halkyon_learn_server/src/generated/greetings/greeting.dart'
as _if4yg514;
import 'package:serverpod/serverpod.dart' as _is;
import 'package:serverpod_auth_core_server/serverpod_auth_core_server.dart'
as _iacs;
import 'package:serverpod_test/serverpod_test.dart' as _ist;
import 'package:halkyon_learn_server/src/generated/protocol.dart';
import 'package:halkyon_learn_server/src/generated/endpoints.dart';
export 'package:serverpod_test/serverpod_test_public_exports.dart';
/// Creates a new test group that takes a callback that can be used to write tests.
/// The callback has two parameters: `sessionBuilder` and `endpoints`.
/// `sessionBuilder` is used to build a `Session` object that represents the server state during an endpoint call and is used to set up scenarios.
/// `endpoints` contains all your Serverpod endpoints and lets you call them:
/// ```dart
/// withServerpod('Given Example endpoint', (sessionBuilder, endpoints) {
/// test('when calling `hello` then should return greeting', () async {
/// final greeting = await endpoints.example.hello(sessionBuilder, 'Michael');
/// expect(greeting, 'Hello Michael');
/// });
/// });
/// ```
///
/// **Configuration options**
///
/// [applyMigrations] Whether pending migrations should be applied when starting Serverpod. Defaults to `true`
///
/// [enableSessionLogging] Whether session logging should be enabled. Defaults to `false`
///
/// [rollbackDatabase] Options for when to rollback the database during the test lifecycle.
/// By default `withServerpod` does all database operations inside a transaction that is rolled back after each `test` case.
/// Just like the following enum describes, the behavior of the automatic rollbacks can be configured:
/// ```dart
/// /// Options for when to rollback the database during the test lifecycle.
/// enum RollbackDatabase {
/// /// After each test. This is the default.
/// afterEach,
///
/// /// After all tests.
/// afterAll,
///
/// /// Disable rolling back the database.
/// disabled,
/// }
/// ```
///
/// [runMode] The run mode that Serverpod should be running in. Defaults to `test`.
///
/// [serverpodLoggingMode] The logging mode used when creating Serverpod. Defaults to `ServerpodLoggingMode.normal`
///
/// [serverpodStartTimeout] The timeout to use when starting Serverpod, which connects to the database among other things. Defaults to `Duration(seconds: 120)`.
///
/// [testServerOutputMode] Options for controlling test server output during test execution. Defaults to `TestServerOutputMode.normal`.
/// ```dart
/// /// Options for controlling test server output during test execution.
/// enum TestServerOutputMode {
/// /// Default mode - only stderr is printed (stdout suppressed).
/// /// This hides normal startup/shutdown logs while preserving error messages.
/// normal,
///
/// /// All logging - both stdout and stderr are printed.
/// /// Useful for debugging when you need to see all server output.
/// verbose,
///
/// /// No logging - both stdout and stderr are suppressed.
/// /// Completely silent mode, useful when you don't want any server output.
/// silent,
/// }
/// ```
///
/// [configOverride] A function to override the server configuration. This function is called with
/// the default server configuration after it is loaded from the config/ directory
/// and before it is used to start the server. Use this to override particular
/// settings in the server configuration.
///
/// [databaseInterceptor] Optional interceptor that replaces the default database for each session.
/// See [Serverpod.databaseInterceptor] for more information.
///
/// [testGroupTagsOverride] By default Serverpod test tools tags the `withServerpod` test group with `"integration"`.
/// This is to provide a simple way to only run unit or integration tests.
/// This property allows this tag to be overridden to something else. Defaults to `['integration']`.
///
/// [experimentalFeatures] Optionally specify experimental features. See [Serverpod] for more information.
///
/// [serverDirectory] The server package directory `config/<runMode>.yaml`, `config/passwords.yaml`,
/// and `migrations/<module>/...` are resolved against. Defaults to
/// [Directory.current] at the time the test boots. Pass this when the test
/// isolate's cwd is not the server package root (e.g. running tests from a
/// workspace parent directory) so config and migrations are still loaded
/// from the right place.
@_ist.isTestGroup
void withServerpod(
String testGroupName,
_ist.TestClosure<TestEndpoints> testClosure, {
bool? applyMigrations,
_is.ServerpodConfig Function(_is.ServerpodConfig)? configOverride,
_is.DatabaseInterceptor? databaseInterceptor,
bool? enableSessionLogging,
_is.ExperimentalFeatures? experimentalFeatures,
_ist.RollbackDatabase? rollbackDatabase,
String? runMode,
_is.RuntimeParametersListBuilder? runtimeParametersBuilder,
_idi.Directory? serverDirectory,
_is.ServerpodLoggingMode? serverpodLoggingMode,
Duration? serverpodStartTimeout,
List<String>? testGroupTagsOverride,
_ist.TestServerOutputMode? testServerOutputMode,
}) {
_ist.buildWithServerpod<_InternalTestEndpoints>(
testGroupName,
_ist.TestServerpod(
testEndpoints: _InternalTestEndpoints(),
endpoints: Endpoints(),
serializationManager: Protocol(),
runMode: runMode,
applyMigrations: applyMigrations,
isDatabaseEnabled: true,
serverpodLoggingMode: serverpodLoggingMode,
testServerOutputMode: testServerOutputMode,
serverDirectory: serverDirectory,
experimentalFeatures: experimentalFeatures,
configOverride: configOverride,
runtimeParametersBuilder: runtimeParametersBuilder,
databaseInterceptor: databaseInterceptor,
),
maybeRollbackDatabase: rollbackDatabase,
maybeEnableSessionLogging: enableSessionLogging,
maybeTestGroupTagsOverride: testGroupTagsOverride,
maybeServerpodStartTimeout: serverpodStartTimeout,
maybeTestServerOutputMode: testServerOutputMode,
)(testClosure);
}
class TestEndpoints {
late final _EmailIdpEndpoint emailIdp;
late final _JwtRefreshEndpoint jwtRefresh;
late final _GreetingEndpoint greeting;
}
class _InternalTestEndpoints extends TestEndpoints
implements _ist.InternalTestEndpoints {
@override
void initialize(
_is.SerializationManager serializationManager,
_is.EndpointDispatch endpoints,
) {
emailIdp = _EmailIdpEndpoint(
endpoints,
serializationManager,
);
jwtRefresh = _JwtRefreshEndpoint(
endpoints,
serializationManager,
);
greeting = _GreetingEndpoint(
endpoints,
serializationManager,
);
}
}
class _EmailIdpEndpoint {
_EmailIdpEndpoint(
this._endpointDispatch,
this._serializationManager,
);
final _is.EndpointDispatch _endpointDispatch;
final _is.SerializationManager _serializationManager;
_ida.Future<_iacs.AuthSuccess> login(
_ist.TestSessionBuilder sessionBuilder, {
required String email,
required String password,
}) async {
return _ist.callAwaitableFunctionAndHandleExceptions(() async {
var _localUniqueSession =
(sessionBuilder as _ist.InternalTestSessionBuilder).internalBuild(
endpoint: 'emailIdp',
method: 'login',
);
try {
var _localCallContext = await _endpointDispatch.getMethodCallContext(
createSessionCallback: (_) => _localUniqueSession,
endpointPath: 'emailIdp',
methodName: 'login',
parameters: _ist.testObjectToJson({
'email': email,
'password': password,
}),
serializationManager: _serializationManager,
);
var _localReturnValue =
await (_localCallContext.method.call(
_localUniqueSession,
_localCallContext.arguments,
)
as _ida.Future<_iacs.AuthSuccess>);
return _localReturnValue;
} finally {
await _localUniqueSession.close();
}
});
}
_ida.Future<_is.UuidValue> startRegistration(
_ist.TestSessionBuilder sessionBuilder, {
required String email,
}) async {
return _ist.callAwaitableFunctionAndHandleExceptions(() async {
var _localUniqueSession =
(sessionBuilder as _ist.InternalTestSessionBuilder).internalBuild(
endpoint: 'emailIdp',
method: 'startRegistration',
);
try {
var _localCallContext = await _endpointDispatch.getMethodCallContext(
createSessionCallback: (_) => _localUniqueSession,
endpointPath: 'emailIdp',
methodName: 'startRegistration',
parameters: _ist.testObjectToJson({'email': email}),
serializationManager: _serializationManager,
);
var _localReturnValue =
await (_localCallContext.method.call(
_localUniqueSession,
_localCallContext.arguments,
)
as _ida.Future<_is.UuidValue>);
return _localReturnValue;
} finally {
await _localUniqueSession.close();
}
});
}
_ida.Future<String> verifyRegistrationCode(
_ist.TestSessionBuilder sessionBuilder, {
required _is.UuidValue accountRequestId,
required String verificationCode,
}) async {
return _ist.callAwaitableFunctionAndHandleExceptions(() async {
var _localUniqueSession =
(sessionBuilder as _ist.InternalTestSessionBuilder).internalBuild(
endpoint: 'emailIdp',
method: 'verifyRegistrationCode',
);
try {
var _localCallContext = await _endpointDispatch.getMethodCallContext(
createSessionCallback: (_) => _localUniqueSession,
endpointPath: 'emailIdp',
methodName: 'verifyRegistrationCode',
parameters: _ist.testObjectToJson({
'accountRequestId': accountRequestId,
'verificationCode': verificationCode,
}),
serializationManager: _serializationManager,
);
var _localReturnValue =
await (_localCallContext.method.call(
_localUniqueSession,
_localCallContext.arguments,
)
as _ida.Future<String>);
return _localReturnValue;
} finally {
await _localUniqueSession.close();
}
});
}
_ida.Future<_iacs.AuthSuccess> finishRegistration(
_ist.TestSessionBuilder sessionBuilder, {
required String registrationToken,
required String password,
}) async {
return _ist.callAwaitableFunctionAndHandleExceptions(() async {
var _localUniqueSession =
(sessionBuilder as _ist.InternalTestSessionBuilder).internalBuild(
endpoint: 'emailIdp',
method: 'finishRegistration',
);
try {
var _localCallContext = await _endpointDispatch.getMethodCallContext(
createSessionCallback: (_) => _localUniqueSession,
endpointPath: 'emailIdp',
methodName: 'finishRegistration',
parameters: _ist.testObjectToJson({
'registrationToken': registrationToken,
'password': password,
}),
serializationManager: _serializationManager,
);
var _localReturnValue =
await (_localCallContext.method.call(
_localUniqueSession,
_localCallContext.arguments,
)
as _ida.Future<_iacs.AuthSuccess>);
return _localReturnValue;
} finally {
await _localUniqueSession.close();
}
});
}
_ida.Future<_is.UuidValue> startPasswordReset(
_ist.TestSessionBuilder sessionBuilder, {
required String email,
}) async {
return _ist.callAwaitableFunctionAndHandleExceptions(() async {
var _localUniqueSession =
(sessionBuilder as _ist.InternalTestSessionBuilder).internalBuild(
endpoint: 'emailIdp',
method: 'startPasswordReset',
);
try {
var _localCallContext = await _endpointDispatch.getMethodCallContext(
createSessionCallback: (_) => _localUniqueSession,
endpointPath: 'emailIdp',
methodName: 'startPasswordReset',
parameters: _ist.testObjectToJson({'email': email}),
serializationManager: _serializationManager,
);
var _localReturnValue =
await (_localCallContext.method.call(
_localUniqueSession,
_localCallContext.arguments,
)
as _ida.Future<_is.UuidValue>);
return _localReturnValue;
} finally {
await _localUniqueSession.close();
}
});
}
_ida.Future<String> verifyPasswordResetCode(
_ist.TestSessionBuilder sessionBuilder, {
required _is.UuidValue passwordResetRequestId,
required String verificationCode,
}) async {
return _ist.callAwaitableFunctionAndHandleExceptions(() async {
var _localUniqueSession =
(sessionBuilder as _ist.InternalTestSessionBuilder).internalBuild(
endpoint: 'emailIdp',
method: 'verifyPasswordResetCode',
);
try {
var _localCallContext = await _endpointDispatch.getMethodCallContext(
createSessionCallback: (_) => _localUniqueSession,
endpointPath: 'emailIdp',
methodName: 'verifyPasswordResetCode',
parameters: _ist.testObjectToJson({
'passwordResetRequestId': passwordResetRequestId,
'verificationCode': verificationCode,
}),
serializationManager: _serializationManager,
);
var _localReturnValue =
await (_localCallContext.method.call(
_localUniqueSession,
_localCallContext.arguments,
)
as _ida.Future<String>);
return _localReturnValue;
} finally {
await _localUniqueSession.close();
}
});
}
_ida.Future<void> finishPasswordReset(
_ist.TestSessionBuilder sessionBuilder, {
required String finishPasswordResetToken,
required String newPassword,
}) async {
return _ist.callAwaitableFunctionAndHandleExceptions(() async {
var _localUniqueSession =
(sessionBuilder as _ist.InternalTestSessionBuilder).internalBuild(
endpoint: 'emailIdp',
method: 'finishPasswordReset',
);
try {
var _localCallContext = await _endpointDispatch.getMethodCallContext(
createSessionCallback: (_) => _localUniqueSession,
endpointPath: 'emailIdp',
methodName: 'finishPasswordReset',
parameters: _ist.testObjectToJson({
'finishPasswordResetToken': finishPasswordResetToken,
'newPassword': newPassword,
}),
serializationManager: _serializationManager,
);
var _localReturnValue =
await (_localCallContext.method.call(
_localUniqueSession,
_localCallContext.arguments,
)
as _ida.Future<void>);
return _localReturnValue;
} finally {
await _localUniqueSession.close();
}
});
}
_ida.Future<bool> hasAccount(_ist.TestSessionBuilder sessionBuilder) async {
return _ist.callAwaitableFunctionAndHandleExceptions(() async {
var _localUniqueSession =
(sessionBuilder as _ist.InternalTestSessionBuilder).internalBuild(
endpoint: 'emailIdp',
method: 'hasAccount',
);
try {
var _localCallContext = await _endpointDispatch.getMethodCallContext(
createSessionCallback: (_) => _localUniqueSession,
endpointPath: 'emailIdp',
methodName: 'hasAccount',
parameters: _ist.testObjectToJson({}),
serializationManager: _serializationManager,
);
var _localReturnValue =
await (_localCallContext.method.call(
_localUniqueSession,
_localCallContext.arguments,
)
as _ida.Future<bool>);
return _localReturnValue;
} finally {
await _localUniqueSession.close();
}
});
}
}
class _JwtRefreshEndpoint {
_JwtRefreshEndpoint(
this._endpointDispatch,
this._serializationManager,
);
final _is.EndpointDispatch _endpointDispatch;
final _is.SerializationManager _serializationManager;
_ida.Future<_iacs.AuthSuccess> refreshAccessToken(
_ist.TestSessionBuilder sessionBuilder, {
String? refreshToken,
}) async {
return _ist.callAwaitableFunctionAndHandleExceptions(() async {
var _localUniqueSession =
(sessionBuilder as _ist.InternalTestSessionBuilder).internalBuild(
endpoint: 'jwtRefresh',
method: 'refreshAccessToken',
);
try {
var _localCallContext = await _endpointDispatch.getMethodCallContext(
createSessionCallback: (_) => _localUniqueSession,
endpointPath: 'jwtRefresh',
methodName: 'refreshAccessToken',
parameters: _ist.testObjectToJson({'refreshToken': refreshToken}),
serializationManager: _serializationManager,
);
var _localReturnValue =
await (_localCallContext.method.call(
_localUniqueSession,
_localCallContext.arguments,
)
as _ida.Future<_iacs.AuthSuccess>);
return _localReturnValue;
} finally {
await _localUniqueSession.close();
}
});
}
}
class _GreetingEndpoint {
_GreetingEndpoint(
this._endpointDispatch,
this._serializationManager,
);
final _is.EndpointDispatch _endpointDispatch;
final _is.SerializationManager _serializationManager;
_ida.Future<_if4yg514.Greeting> hello(
_ist.TestSessionBuilder sessionBuilder,
String name,
) async {
return _ist.callAwaitableFunctionAndHandleExceptions(() async {
var _localUniqueSession =
(sessionBuilder as _ist.InternalTestSessionBuilder).internalBuild(
endpoint: 'greeting',
method: 'hello',
);
try {
var _localCallContext = await _endpointDispatch.getMethodCallContext(
createSessionCallback: (_) => _localUniqueSession,
endpointPath: 'greeting',
methodName: 'hello',
parameters: _ist.testObjectToJson({'name': name}),
serializationManager: _serializationManager,
);
var _localReturnValue =
await (_localCallContext.method.call(
_localUniqueSession,
_localCallContext.arguments,
)
as _ida.Future<_if4yg514.Greeting>);
return _localReturnValue;
} finally {
await _localUniqueSession.close();
}
});
}
}