Skip to content

Commit 0a32007

Browse files
missing test and int4egration test done
1 parent b8d93de commit 0a32007

19 files changed

Lines changed: 2026 additions & 7 deletions

pubspec.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,7 +1350,7 @@ packages:
13501350
source: hosted
13511351
version: "2.2.1"
13521352
path_provider_platform_interface:
1353-
dependency: transitive
1353+
dependency: "direct dev"
13541354
description:
13551355
name: path_provider_platform_interface
13561356
sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
@@ -1382,7 +1382,7 @@ packages:
13821382
source: hosted
13831383
version: "3.1.6"
13841384
plugin_platform_interface:
1385-
dependency: transitive
1385+
dependency: "direct dev"
13861386
description:
13871387
name: plugin_platform_interface
13881388
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"

pubspec.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,11 @@ dev_dependencies:
119119
# Mocktail: null-safety-native mock library, no codegen, no
120120
# mockito @GenerateMocks boilerplate. Companion to bloc_test.
121121
mocktail: ^1.0.4
122+
# Direct deps for test/_helpers/fake_path_provider.dart (platform-interface
123+
# fakes). Both already resolve transitively via path_provider; declaring
124+
# them keeps depend_on_referenced_packages honest.
125+
path_provider_platform_interface: ^2.1.0
126+
plugin_platform_interface: ^2.1.0
122127

123128
flutter_lints: ^2.0.0
124129
build_runner: ^2.13.0

test/TESTING.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,12 @@ below, or add one if the shape is missing.
103103
| Helper file | Exposes | Use for |
104104
|---|---|---|
105105
| `isar_test_harness.dart` | `openTestIsar()`, `groupSeed`, `privateGroupSeed`, `followedUserSeed`, `followedNoteSeed` | Opening an isolated on-disk Isar in `setUp` + one-liner seed rows for those specific collections. |
106-
| `isar_seeds.dart` | builders `noteRow`, `unreadRow`, `relationEdge`, `reportRow`, `deletedNoteRow`, `eventQueueRow`, `profileRow`, `mediaAttachmentRow` + committers `seedNoteRow`, `seedUnreadRow`, `seedRelationEdge`, `seedReport`, `seedDeletedNote`, `seedProfile` | Isar model rows for `Note`, `UnreadNote`, `NoteRelation`, `Report`, `DeletedNote`, `EventQueue`, `NostrProfile`. Builders return the model (batch them in one `writeTxn`); committers wrap their own `writeTxn`. |
106+
| `isar_seeds.dart` | builders `noteRow`, `unreadRow`, `relationEdge`, `reportRow`, `deletedNoteRow`, `eventQueueRow`, `profileRow`, `dmConversationRow`, `relayRow`, `savedNoteRow`, `shivConversationRow`, `shivMessageRow`, `mediaAttachmentRow` + committers `seedNoteRow`, `seedUnreadRow`, `seedRelationEdge`, `seedReport`, `seedDeletedNote`, `seedProfile`, `seedDmConversation`, `seedRelay` | Isar model rows for `Note`, `UnreadNote`, `NoteRelation`, `Report`, `DeletedNote`, `EventQueue`, `NostrProfile`, `DmConversation`, `Relay`, `SavedNote`, `ShivConversation`, `ShivMessage`. Builders return the model (batch them in one `writeTxn`); committers wrap their own `writeTxn`. |
107107
| `recording_event_queue.dart` | `RecordingEventQueue`, `EnqueueCall` | Any repo that publishes through `EventQueueRepository.enqueueSignedEvent`. Configure `leftOnEnqueue` / `throwOnEnqueue` to simulate failure. Inspect `.calls` to assert wire shape. |
108108
| `fake_note_relations.dart` | `FakeNoteRelations` | Any repo that reads from `NoteRelationRepository`. Seed `.children[parentId]` / `.parents[childId]` before the test runs. |
109109
| `stub_user_repository.dart` | `StubUserRepository` | Any repo that calls `UserRepository.getActiveKeysHex()` or `getActiveUser()` (both derive from `.keys`). Set `.keys = null` to simulate a logged-out identity. |
110110
| `stub_followed_users.dart` | `StubFollowedUsers` | Any repo that reads the follow list via `FollowedUserRepository.getAllPubkeys()`. Seed `.pubkeys`; set `.leftOnGetAllPubkeys` to simulate failure. |
111+
| `fake_path_provider.dart` | `FakePathProviderPlatform` | Code that calls `getApplicationDocumentsDirectory()` / `getApplicationSupportDirectory()`. Install via `PathProviderPlatform.instance = FakePathProviderPlatform(docs: ..., support: ...)` pointing at temp dirs. |
111112

112113
### Constants in `fixtures.dart`
113114

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import 'package:path_provider_platform_interface/path_provider_platform_interface.dart';
2+
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
3+
4+
/// Deterministic [PathProviderPlatform] test double.
5+
///
6+
/// Points `getApplicationDocumentsDirectory()` / `getApplicationSupportDirectory()`
7+
/// at caller-chosen temp dirs. Install in `setUp` via
8+
/// `PathProviderPlatform.instance = FakePathProviderPlatform(docs: ..., support: ...)`.
9+
class FakePathProviderPlatform extends PathProviderPlatform
10+
with MockPlatformInterfaceMixin {
11+
FakePathProviderPlatform({required this.docs, required this.support});
12+
13+
final String docs;
14+
final String support;
15+
16+
@override
17+
Future<String?> getApplicationDocumentsPath() async => docs;
18+
19+
@override
20+
Future<String?> getApplicationSupportPath() async => support;
21+
22+
@override
23+
Future<String?> getTemporaryPath() async => support;
24+
}

test/_helpers/fixtures.dart

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@ import 'package:uniun/core/enum/note_type.dart';
1212
import 'package:uniun/core/enum/relay_status.dart';
1313
import 'package:uniun/core/notes/note_kinds.dart';
1414
import 'package:uniun/domain/entities/dm/dm_conversation_entity.dart';
15+
import 'package:uniun/domain/entities/graph_edge/graph_edge_entity.dart';
16+
import 'package:uniun/domain/entities/graph_node/graph_node_entity.dart';
1517
import 'package:uniun/domain/entities/manas/manas_entity.dart';
1618
import 'package:uniun/domain/entities/media/media_blob_entity.dart';
1719
import 'package:uniun/domain/entities/media/media_dim.dart';
20+
import 'package:uniun/domain/entities/memory_node/memory_node_entity.dart';
1821
import 'package:uniun/domain/entities/note/note_entity.dart';
1922
import 'package:uniun/domain/entities/profile/profile_entity.dart';
2023
import 'package:uniun/domain/entities/relay/relay_entity.dart';
@@ -395,6 +398,60 @@ List<ManasEntity> manyManas(int n) => [
395398
for (var i = 0; i < n; i++) aManas(manasId: 'm-$i', name: 'Manas $i'),
396399
];
397400

401+
// ── Graph entities ───────────────────────────────────────────────────────────
402+
403+
GraphNodeEntity aGraphNode({
404+
String key = 'node-1',
405+
String name = 'Node One',
406+
String type = 'topic',
407+
DateTime? createdAt,
408+
DateTime? updatedAt,
409+
}) {
410+
return GraphNodeEntity(
411+
key: key,
412+
name: name,
413+
type: type,
414+
createdAt: createdAt ?? tT0,
415+
updatedAt: updatedAt ?? tNow,
416+
);
417+
}
418+
419+
GraphEdgeEntity aGraphEdge({
420+
String sourceKey = 'node-1',
421+
String targetKey = 'node-2',
422+
String relationType = 'mentions',
423+
String sourceNoteId = 'note-1',
424+
DateTime? createdAt,
425+
}) {
426+
return GraphEdgeEntity(
427+
sourceKey: sourceKey,
428+
targetKey: targetKey,
429+
relationType: relationType,
430+
sourceNoteId: sourceNoteId,
431+
createdAt: createdAt ?? tNow,
432+
);
433+
}
434+
435+
// ── MemoryNodeEntity ─────────────────────────────────────────────────────────
436+
437+
MemoryNodeEntity aMemoryNode({
438+
String noteId = 'note-1',
439+
String summary = 'a wiki-style summary',
440+
List<String> keyPoints = const ['point'],
441+
List<String> concepts = const ['concept'],
442+
List<String> linkedNoteIds = const [],
443+
DateTime? updatedAt,
444+
}) {
445+
return MemoryNodeEntity(
446+
noteId: noteId,
447+
summary: summary,
448+
keyPoints: keyPoints,
449+
concepts: concepts,
450+
linkedNoteIds: linkedNoteIds,
451+
updatedAt: updatedAt ?? tNow,
452+
);
453+
}
454+
398455
// ── UserKeyEntity ────────────────────────────────────────────────────────────
399456

400457
UserKeyEntity aUserKey({

test/_helpers/isar_seeds.dart

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@ import 'package:uniun/data/models/dm/dm_conversation_model.dart';
77
import 'package:uniun/data/models/event_queue_model.dart';
88
import 'package:uniun/data/models/note_relation_model.dart';
99
import 'package:uniun/data/models/profile_model.dart';
10+
import 'package:uniun/core/enum/message_role.dart';
1011
import 'package:uniun/data/models/relay_model.dart';
12+
import 'package:uniun/data/models/saved_note_model.dart';
13+
import 'package:uniun/data/models/shiv_conversation_model.dart';
14+
import 'package:uniun/data/models/shiv_message_model.dart';
1115
import 'package:uniun/data/models/notes/media_attachment.dart';
1216
import 'package:uniun/data/models/notes/note_model.dart';
1317
import 'package:uniun/data/models/notes/unread_note_model.dart';
@@ -222,6 +226,75 @@ RelayModel relayRow(
222226
..lastConnectedAt = lastConnectedAt
223227
..isSystem = isSystem;
224228

229+
/// Build a [SavedNoteModel] row without committing it.
230+
SavedNoteModel savedNoteRow(
231+
String eventId, {
232+
String content = 'x',
233+
String authorPubkey = kAlicePub,
234+
String sig = 'sig',
235+
NoteType type = NoteType.text,
236+
List<String> eTagRefs = const [],
237+
List<String> pTagRefs = const [],
238+
List<String> tTags = const [],
239+
String? rootEventId,
240+
String? replyToEventId,
241+
String? sourceGroupId,
242+
String? sourcePrivateGroupId,
243+
String? embeddedNoteJson,
244+
List<MediaAttachment> attachments = const [],
245+
DateTime? created,
246+
DateTime? savedAt,
247+
}) =>
248+
SavedNoteModel()
249+
..eventId = eventId
250+
..sig = sig
251+
..authorPubkey = authorPubkey
252+
..content = content
253+
..type = type
254+
..eTagRefs = List<String>.from(eTagRefs)
255+
..pTagRefs = List<String>.from(pTagRefs)
256+
..tTags = List<String>.from(tTags)
257+
..rootEventId = rootEventId
258+
..replyToEventId = replyToEventId
259+
..sourceGroupId = sourceGroupId
260+
..sourcePrivateGroupId = sourcePrivateGroupId
261+
..embeddedNoteJson = embeddedNoteJson
262+
..attachments = attachments
263+
..created = created ?? tNow
264+
..savedAt = savedAt ?? tNow;
265+
266+
/// Build a [ShivConversationModel] row without committing it.
267+
ShivConversationModel shivConversationRow(
268+
String conversationId, {
269+
String title = 'chat',
270+
String? activeLeafMessageId,
271+
DateTime? createdAt,
272+
DateTime? updatedAt,
273+
}) =>
274+
ShivConversationModel()
275+
..conversationId = conversationId
276+
..title = title
277+
..activeLeafMessageId = activeLeafMessageId
278+
..createdAt = createdAt ?? tNow
279+
..updatedAt = updatedAt ?? tNow;
280+
281+
/// Build a [ShivMessageModel] row without committing it.
282+
ShivMessageModel shivMessageRow(
283+
String messageId, {
284+
String conversationId = 'conv-1',
285+
String? parentId,
286+
MessageRole role = MessageRole.user,
287+
String content = 'x',
288+
DateTime? createdAt,
289+
}) =>
290+
ShivMessageModel()
291+
..messageId = messageId
292+
..conversationId = conversationId
293+
..parentId = parentId
294+
..role = role
295+
..content = content
296+
..createdAt = createdAt ?? tNow;
297+
225298
/// Build a [MediaAttachment] embedded row without committing it. Convenient
226299
/// when a test needs a note carrying media via [noteRow]`.attachments`.
227300
MediaAttachment mediaAttachmentRow({

test/_helpers/recording_event_queue.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class RecordingEventQueue implements EventQueueRepository {
5757
hTag: hTag,
5858
embeddedNoteJson: embeddedNoteJson,
5959
reportType: reportType,
60+
serverTags: serverTags,
6061
imeta: imeta,
6162
));
6263
return const Right(1);
@@ -80,6 +81,7 @@ class EnqueueCall {
8081
this.hTag,
8182
this.embeddedNoteJson,
8283
this.reportType,
84+
this.serverTags = const [],
8385
this.imeta = const [],
8486
});
8587

@@ -96,5 +98,6 @@ class EnqueueCall {
9698
final String? hTag;
9799
final String? embeddedNoteJson;
98100
final String? reportType;
101+
final List<String> serverTags;
99102
final List<MediaBlobEntity> imeta;
100103
}

test/_helpers/stub_user_repository.dart

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,22 @@ class StubUserRepository implements UserRepository {
1717
pubkeyHex: kTestPubHex,
1818
);
1919

20+
/// When set, [getActiveUser] returns exactly this entity. Use for code
21+
/// paths that decode `user.nsec` (needs a real bech32 nsec, which the
22+
/// default [aUserKey] placeholder is not).
23+
UserKeyEntity? activeUser;
24+
2025
@override
2126
Future<({String privkeyHex, String pubkeyHex})?> getActiveKeysHex() async =>
2227
keys;
2328

2429
@override
25-
Future<Either<Failure, UserKeyEntity>> getActiveUser() async =>
26-
keys == null
27-
? const Left(Failure.notFoundFailure('no active user'))
28-
: Right(aUserKey(pubkeyHex: keys!.pubkeyHex));
30+
Future<Either<Failure, UserKeyEntity>> getActiveUser() async {
31+
if (activeUser != null) return Right(activeUser!);
32+
return keys == null
33+
? const Left(Failure.notFoundFailure('no active user'))
34+
: Right(aUserKey(pubkeyHex: keys!.pubkeyHex));
35+
}
2936

3037
@override
3138
Future<Either<Failure, UserKeyEntity>> generateKey() =>

0 commit comments

Comments
 (0)