100 lines
3.3 KiB
Dart
100 lines
3.3 KiB
Dart
|
|
@Tags(['integration'])
|
||
|
|
library;
|
||
|
|
|
||
|
|
import 'dart:convert';
|
||
|
|
|
||
|
|
import 'package:bip340/bip340.dart' as bip340;
|
||
|
|
import 'package:swarm/swarm.dart';
|
||
|
|
import 'package:test/test.dart';
|
||
|
|
|
||
|
|
const _privKey =
|
||
|
|
'0000000000000000000000000000000000000000000000000000000000000001';
|
||
|
|
|
||
|
|
const _relayUrl = 'wss://relay.otherwhere.app/';
|
||
|
|
|
||
|
|
void main() {
|
||
|
|
late NostrFetchActor fetcher;
|
||
|
|
late String pubkey;
|
||
|
|
|
||
|
|
setUp(() {
|
||
|
|
fetcher = NostrFetchActor(relayUrls: [_relayUrl]);
|
||
|
|
pubkey = bip340.getPublicKey(_privKey);
|
||
|
|
});
|
||
|
|
|
||
|
|
String filter(Map<String, dynamic> f) => jsonEncode(f);
|
||
|
|
|
||
|
|
group('relay.otherwhere.app fetch', () {
|
||
|
|
test('fetches kind 0 (metadata) by author', () async {
|
||
|
|
final result = await fetcher.handle(FetchEvents(
|
||
|
|
filter({'kinds': [0], 'authors': [pubkey], 'limit': 1}),
|
||
|
|
));
|
||
|
|
final events = (result as EventsFetched).events;
|
||
|
|
expect(events, isNotEmpty);
|
||
|
|
final event = jsonDecode(events.first) as Map<String, dynamic>;
|
||
|
|
expect(event['kind'], equals(0));
|
||
|
|
expect(event['pubkey'], equals(pubkey));
|
||
|
|
}, timeout: const Timeout(Duration(seconds: 15)));
|
||
|
|
|
||
|
|
test('fetches kind 37515 (place) by d tag', () async {
|
||
|
|
final result = await fetcher.handle(FetchEvents(
|
||
|
|
filter({
|
||
|
|
'kinds': [37515],
|
||
|
|
'#d': ['place:swarmtest0'],
|
||
|
|
'authors': [pubkey],
|
||
|
|
'limit': 1,
|
||
|
|
}),
|
||
|
|
));
|
||
|
|
final events = (result as EventsFetched).events;
|
||
|
|
expect(events, isNotEmpty);
|
||
|
|
final event = jsonDecode(events.first) as Map<String, dynamic>;
|
||
|
|
expect(event['kind'], equals(37515));
|
||
|
|
final tags = event['tags'] as List;
|
||
|
|
final dTag = tags.firstWhere((t) => (t as List).first == 'd') as List;
|
||
|
|
expect(dTag[1], equals('place:swarmtest0'));
|
||
|
|
}, timeout: const Timeout(Duration(seconds: 15)));
|
||
|
|
|
||
|
|
test('fetches kind 37518 (check-in) by d tag', () async {
|
||
|
|
final result = await fetcher.handle(FetchEvents(
|
||
|
|
filter({
|
||
|
|
'kinds': [37518],
|
||
|
|
'#d': ['checkin:swarmtest0'],
|
||
|
|
'authors': [pubkey],
|
||
|
|
'limit': 1,
|
||
|
|
}),
|
||
|
|
));
|
||
|
|
final events = (result as EventsFetched).events;
|
||
|
|
expect(events, isNotEmpty);
|
||
|
|
final event = jsonDecode(events.first) as Map<String, dynamic>;
|
||
|
|
expect(event['kind'], equals(37518));
|
||
|
|
}, timeout: const Timeout(Duration(seconds: 15)));
|
||
|
|
|
||
|
|
test('fetched events have valid BIP-340 signatures', () async {
|
||
|
|
final result = await fetcher.handle(FetchEvents(
|
||
|
|
filter({'authors': [pubkey], 'limit': 10}),
|
||
|
|
));
|
||
|
|
final events = (result as EventsFetched).events;
|
||
|
|
expect(events, isNotEmpty);
|
||
|
|
for (final raw in events) {
|
||
|
|
final e = jsonDecode(raw) as Map<String, dynamic>;
|
||
|
|
expect(
|
||
|
|
bip340.verify(
|
||
|
|
e['pubkey'] as String,
|
||
|
|
e['id'] as String,
|
||
|
|
e['sig'] as String,
|
||
|
|
),
|
||
|
|
isTrue,
|
||
|
|
reason: 'event ${e['id']} has invalid signature',
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}, timeout: const Timeout(Duration(seconds: 15)));
|
||
|
|
|
||
|
|
test('returns empty list for unknown author', () async {
|
||
|
|
const unknown = 'deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef';
|
||
|
|
final result = await fetcher.handle(FetchEvents(
|
||
|
|
filter({'authors': [unknown], 'limit': 5}),
|
||
|
|
));
|
||
|
|
expect((result as EventsFetched).events, isEmpty);
|
||
|
|
}, timeout: const Timeout(Duration(seconds: 15)));
|
||
|
|
});
|
||
|
|
}
|