Skip to content

Commit 01de05c

Browse files
authored
Merge pull request #143 from basictech01/publish/view
pyblish read core tests added
2 parents 165ded9 + 0a32007 commit 01de05c

29 files changed

Lines changed: 4087 additions & 27 deletions

pubspec.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1414,7 +1414,7 @@ packages:
14141414
source: hosted
14151415
version: "2.2.1"
14161416
path_provider_platform_interface:
1417-
dependency: transitive
1417+
dependency: "direct dev"
14181418
description:
14191419
name: path_provider_platform_interface
14201420
sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
@@ -1446,7 +1446,7 @@ packages:
14461446
source: hosted
14471447
version: "3.1.6"
14481448
plugin_platform_interface:
1449-
dependency: transitive
1449+
dependency: "direct dev"
14501450
description:
14511451
name: plugin_platform_interface
14521452
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"

pubspec.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,11 @@ dev_dependencies:
126126
# Mocktail: null-safety-native mock library, no codegen, no
127127
# mockito @GenerateMocks boilerplate. Companion to bloc_test.
128128
mocktail: ^1.0.4
129+
# Direct deps for test/_helpers/fake_path_provider.dart (platform-interface
130+
# fakes). Both already resolve transitively via path_provider; declaring
131+
# them keeps depend_on_referenced_packages honest.
132+
path_provider_platform_interface: ^2.1.0
133+
plugin_platform_interface: ^2.1.0
129134

130135
flutter_lints: ^2.0.0
131136
build_runner: ^2.13.0

test/TESTING.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,19 +103,26 @@ 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` | `seedNoteRow`, `seedUnreadRow`, `seedRelationEdge`, `seedReport` | Direct writes into `Note`, `UnreadNote`, `NoteRelation`, `Report` collections. Each helper wraps its own `writeTxn`, safe to call ad-hoc from any test using `openTestIsar()`. |
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. |
109-
| `stub_user_repository.dart` | `StubUserRepository` | Any repo that calls `UserRepository.getActiveKeysHex()`. Set `.keys = null` to simulate a logged-out identity. |
109+
| `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. |
110+
| `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. |
110112

111113
### Constants in `fixtures.dart`
112114

113115
```dart
114116
kTestPrivHex, kTestPubHex, kSigningKeys, aSigningKeys(...) // signing keys
115117
kSampleEventIdHex // 64-char hex event id (for NIP-56 / nostr code paths)
116118
kSampleTargetPubkeyHex // 64-char hex pubkey (same, for target-user args)
119+
tOwnProfileSentinel // DateTime(3000,6,1) own-profile eviction sentinel
117120
```
118121

122+
Isar round-trips `DateTime` as **local time** and SharedPreferences-backed
123+
stores truncate to millis — compare instants (`isAtSameMomentAs`) or epoch
124+
millis, never `==` against a UTC fixture.
125+
119126
Use `kSampleEventIdHex` / `kSampleTargetPubkeyHex` when the code under
120127
test validates hex shape (schnorr sig, NIP-56 tag verify, etc). Use the
121128
short `kAlicePub` / `kBobPub` when the value is just an opaque identifier.
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: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,18 @@
99
// - Times default to [tT0] / [tNow] so tests are deterministic.
1010

1111
import 'package:uniun/core/enum/note_type.dart';
12+
import 'package:uniun/core/enum/relay_status.dart';
1213
import 'package:uniun/core/notes/note_kinds.dart';
14+
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';
1317
import 'package:uniun/domain/entities/manas/manas_entity.dart';
1418
import 'package:uniun/domain/entities/media/media_blob_entity.dart';
1519
import 'package:uniun/domain/entities/media/media_dim.dart';
20+
import 'package:uniun/domain/entities/memory_node/memory_node_entity.dart';
1621
import 'package:uniun/domain/entities/note/note_entity.dart';
1722
import 'package:uniun/domain/entities/profile/profile_entity.dart';
23+
import 'package:uniun/domain/entities/relay/relay_entity.dart';
1824
import 'package:uniun/domain/entities/saved_note/saved_note_entity.dart';
1925
import 'package:uniun/domain/entities/user_key/user_key_entity.dart';
2026
import 'package:uniun/domain/usecases/user_usecases.dart';
@@ -24,6 +30,10 @@ import 'package:uniun/domain/usecases/user_usecases.dart';
2430
final DateTime tT0 = DateTime.utc(2026, 1, 1);
2531
final DateTime tNow = DateTime.utc(2026, 6, 30, 12, 0, 0);
2632

33+
/// Own-profile eviction sentinel — mirrors the production value the
34+
/// CleanupManager never reaches (`ProfileModel.lastSeenAt` docs).
35+
final DateTime tOwnProfileSentinel = DateTime(3000, 6, 1);
36+
2737
// ── Predefined pubkeys ───────────────────────────────────────────────────────
2838

2939
const String kSelfPub = 'self-pub';
@@ -286,6 +296,40 @@ ProfileEntity aProfile({
286296
ProfileEntity anAnonymousProfile({String pubkey = kAlicePub}) =>
287297
aProfile(pubkey: pubkey, name: null, username: null);
288298

299+
// ── DmConversationEntity ─────────────────────────────────────────────────────
300+
301+
DmConversationEntity aDmConversation({
302+
int id = 0,
303+
String otherPubkey = kSampleTargetPubkeyHex,
304+
List<String> relays = const [],
305+
}) {
306+
return DmConversationEntity(
307+
id: id,
308+
otherPubkey: otherPubkey,
309+
relays: relays,
310+
);
311+
}
312+
313+
// ── RelayEntity ──────────────────────────────────────────────────────────────
314+
315+
RelayEntity aRelay({
316+
String url = 'wss://relay.example',
317+
bool read = true,
318+
bool write = true,
319+
RelayStatus status = RelayStatus.disconnected,
320+
DateTime? lastConnectedAt,
321+
bool isSystem = false,
322+
}) {
323+
return RelayEntity(
324+
url: url,
325+
read: read,
326+
write: write,
327+
status: status,
328+
lastConnectedAt: lastConnectedAt,
329+
isSystem: isSystem,
330+
);
331+
}
332+
289333
// ── SavedNoteEntity ──────────────────────────────────────────────────────────
290334

291335
SavedNoteEntity aSavedNote({
@@ -354,6 +398,60 @@ List<ManasEntity> manyManas(int n) => [
354398
for (var i = 0; i < n; i++) aManas(manasId: 'm-$i', name: 'Manas $i'),
355399
];
356400

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+
357455
// ── UserKeyEntity ────────────────────────────────────────────────────────────
358456

359457
UserKeyEntity aUserKey({

0 commit comments

Comments
 (0)