serverpod-offline-sync/test/triggers/trigger_generation_test.dart

173 lines
4.8 KiB
Dart
Raw Normal View History

import 'package:drift_offline_first/src/migrator.dart';
import 'package:drift_offline_first/src/triggers.dart';
import 'package:test/test.dart';
import '../utils/database.dart';
void main() {
group('Given a SQLite3 database with a table', () {
late OfflineSyncMigrator migrator;
setUp(() async {
migrator = database.createMigrator();
});
group('when generating trigger statements', () {
late List<String> triggers;
setUp(() async {
final generator = Sqlite3OfflineSyncTriggers(migrator);
triggers = generator.generateCreateTriggerStatements(database.todosTable);
});
test('then one trigger is created for each operation.', () {
expect(triggers, hasLength(3));
expect(triggers, anyElement(contains('AFTER INSERT ON "todos"')));
expect(triggers, anyElement(contains('AFTER UPDATE ON "todos"')));
expect(triggers, anyElement(contains('AFTER DELETE ON "todos"')));
});
test('then the insert trigger statement is correct.', () {
final insertStatement = triggers
.firstWhere((trigger) => trigger.contains('AFTER INSERT ON "todos"'));
expect(
insertStatement,
'''\
CREATE TRIGGER IF NOT EXISTS __crdt__todos__insert
AFTER INSERT ON "todos"
BEGIN
INSERT OR REPLACE INTO __crdt_data (
"user_id", "table_name", "column_name", "row_id", "hlc_timestamp", "raw_value"
)
SELECT
'${migrator.userId}' AS "user_id",
'todos' AS "table_name",
column_name,
NEW."id" AS "row_id",
"hlc_timestamp",
raw_value
FROM (
SELECT $nextHlcFunction('${migrator.userId}', '${migrator.nodeId}') AS "hlc_timestamp"
), (
SELECT
'id' AS "column_name",
NEW."id" AS "raw_value"
UNION ALL
SELECT
'title' AS "column_name",
NEW."title" AS "raw_value"
UNION ALL
SELECT
'content' AS "column_name",
NEW."content" AS "raw_value"
UNION ALL
SELECT
'target_date' AS "column_name",
NEW."target_date" AS "raw_value"
UNION ALL
SELECT
'category' AS "column_name",
NEW."category" AS "raw_value"
UNION ALL
SELECT
'status' AS "column_name",
NEW."status" AS "raw_value"
);
END;''',
);
});
test('then the update trigger statement is correct.', () {
final updateStatement = triggers
.firstWhere((trigger) => trigger.contains('AFTER UPDATE ON "todos"'));
expect(
updateStatement,
'''\
CREATE TRIGGER IF NOT EXISTS __crdt__todos__update
AFTER UPDATE ON "todos"
BEGIN
INSERT OR REPLACE INTO __crdt_data (
"user_id", "table_name", "column_name", "row_id", "hlc_timestamp", "raw_value"
)
SELECT
'${migrator.userId}' AS "user_id",
'todos' AS "table_name",
column_name,
OLD."id" AS "row_id",
"hlc_timestamp",
raw_value
FROM (
SELECT $nextHlcFunction('${migrator.userId}', '${migrator.nodeId}') AS "hlc_timestamp"
), (
SELECT
'id' AS "column_name",
NEW."id" AS "raw_value",
NEW."id" IS NOT OLD."id" AS "value_changed"
UNION ALL
SELECT
'title' AS "column_name",
NEW."title" AS "raw_value",
NEW."title" IS NOT OLD."title" AS "value_changed"
UNION ALL
SELECT
'content' AS "column_name",
NEW."content" AS "raw_value",
NEW."content" IS NOT OLD."content" AS "value_changed"
UNION ALL
SELECT
'target_date' AS "column_name",
NEW."target_date" AS "raw_value",
NEW."target_date" IS NOT OLD."target_date" AS "value_changed"
UNION ALL
SELECT
'category' AS "column_name",
NEW."category" AS "raw_value",
NEW."category" IS NOT OLD."category" AS "value_changed"
UNION ALL
SELECT
'status' AS "column_name",
NEW."status" AS "raw_value",
NEW."status" IS NOT OLD."status" AS "value_changed"
)
WHERE (value_changed = TRUE);
END;''',
);
});
test('then the delete trigger statement is correct.', () {
final deleteStatement = triggers
.firstWhere((trigger) => trigger.contains('AFTER DELETE ON "todos"'));
expect(
deleteStatement,
'''\
CREATE TRIGGER IF NOT EXISTS __crdt__todos__delete
AFTER DELETE ON "todos"
BEGIN
INSERT OR REPLACE INTO __crdt_data (
"user_id", "table_name", "column_name", "row_id", "hlc_timestamp", "raw_value"
)
SELECT
'${migrator.userId}' AS "user_id",
'todos' AS "table_name",
column_name,
OLD."id" AS "row_id",
"hlc_timestamp",
raw_value
FROM (
SELECT $nextHlcFunction('${migrator.userId}', '${migrator.nodeId}') AS "hlc_timestamp"
), (
SELECT
'__crdt_is_deleted' AS "column_name",
TRUE AS "raw_value"
);
END;''',
);
});
});
});
// TODO: Add a test for the case where a table has multiple primary key columns.
}