You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
303 lines
8.6 KiB
303 lines
8.6 KiB
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:app_boilerplate/data/nostr/nostr_service.dart';
|
|
import 'package:app_boilerplate/data/nostr/models/nostr_keypair.dart';
|
|
import 'package:app_boilerplate/data/nostr/models/nostr_event.dart';
|
|
|
|
void main() {
|
|
group('NostrService - Keypair Generation', () {
|
|
/// Tests that keypair generation creates valid keypairs.
|
|
test('generateKeyPair - success', () {
|
|
// Arrange
|
|
final service = NostrService();
|
|
|
|
// Act
|
|
final keypair = service.generateKeyPair();
|
|
|
|
// Assert
|
|
expect(keypair.privateKey, isNotEmpty);
|
|
expect(keypair.publicKey, isNotEmpty);
|
|
expect(keypair.privateKey.length, equals(64)); // 32 bytes = 64 hex chars
|
|
expect(keypair.publicKey.length, equals(64)); // 32 bytes = 64 hex chars
|
|
});
|
|
|
|
/// Tests that each generated keypair is unique.
|
|
test('generateKeyPair - generates unique keypairs', () {
|
|
// Arrange
|
|
final service = NostrService();
|
|
|
|
// Act
|
|
final keypair1 = service.generateKeyPair();
|
|
final keypair2 = service.generateKeyPair();
|
|
|
|
// Assert
|
|
expect(keypair1.privateKey, isNot(equals(keypair2.privateKey)));
|
|
expect(keypair1.publicKey, isNot(equals(keypair2.publicKey)));
|
|
});
|
|
|
|
/// Tests keypair JSON serialization.
|
|
test('NostrKeyPair - JSON serialization', () {
|
|
// Arrange
|
|
final keypair = NostrKeyPair.generate();
|
|
|
|
// Act
|
|
final json = keypair.toJson();
|
|
final restored = NostrKeyPair.fromJson(json);
|
|
|
|
// Assert
|
|
expect(restored.privateKey, equals(keypair.privateKey));
|
|
expect(restored.publicKey, equals(keypair.publicKey));
|
|
});
|
|
});
|
|
|
|
group('NostrService - Relay Management', () {
|
|
/// Tests adding a relay.
|
|
test('addRelay - success', () {
|
|
// Arrange
|
|
final service = NostrService();
|
|
|
|
// Act
|
|
service.addRelay('wss://relay.example.com');
|
|
|
|
// Assert
|
|
final relays = service.getRelays();
|
|
expect(relays.length, equals(1));
|
|
expect(relays[0].url, equals('wss://relay.example.com'));
|
|
});
|
|
|
|
/// Tests adding multiple relays.
|
|
test('addRelay - multiple relays', () {
|
|
// Arrange
|
|
final service = NostrService();
|
|
|
|
// Act
|
|
service.addRelay('wss://relay1.example.com');
|
|
service.addRelay('wss://relay2.example.com');
|
|
service.addRelay('wss://relay3.example.com');
|
|
|
|
// Assert
|
|
final relays = service.getRelays();
|
|
expect(relays.length, equals(3));
|
|
});
|
|
|
|
/// Tests that duplicate relays are not added.
|
|
test('addRelay - prevents duplicates', () {
|
|
// Arrange
|
|
final service = NostrService();
|
|
|
|
// Act
|
|
service.addRelay('wss://relay.example.com');
|
|
service.addRelay('wss://relay.example.com');
|
|
|
|
// Assert
|
|
final relays = service.getRelays();
|
|
expect(relays.length, equals(1));
|
|
});
|
|
|
|
/// Tests removing a relay.
|
|
test('removeRelay - success', () {
|
|
// Arrange
|
|
final service = NostrService();
|
|
service.addRelay('wss://relay.example.com');
|
|
|
|
// Act
|
|
service.removeRelay('wss://relay.example.com');
|
|
|
|
// Assert
|
|
final relays = service.getRelays();
|
|
expect(relays.length, equals(0));
|
|
});
|
|
});
|
|
|
|
group('NostrService - Event Creation', () {
|
|
/// Tests creating a Nostr event.
|
|
test('NostrEvent.create - success', () {
|
|
// Arrange
|
|
final keypair = NostrKeyPair.generate();
|
|
final content = 'Test event content';
|
|
|
|
// Act
|
|
final event = NostrEvent.create(
|
|
content: content,
|
|
privateKey: keypair.privateKey,
|
|
);
|
|
|
|
// Assert
|
|
expect(event.content, equals(content));
|
|
expect(event.pubkey, isNotEmpty);
|
|
expect(event.id, isNotEmpty);
|
|
expect(event.sig, isNotEmpty);
|
|
expect(event.kind, equals(1)); // Default kind
|
|
expect(event.createdAt, greaterThan(0));
|
|
});
|
|
|
|
/// Tests creating event with custom kind.
|
|
test('NostrEvent.create - custom kind', () {
|
|
// Arrange
|
|
final keypair = NostrKeyPair.generate();
|
|
|
|
// Act
|
|
final event = NostrEvent.create(
|
|
content: 'Metadata',
|
|
kind: 0,
|
|
privateKey: keypair.privateKey,
|
|
);
|
|
|
|
// Assert
|
|
expect(event.kind, equals(0));
|
|
});
|
|
|
|
/// Tests creating event with tags.
|
|
test('NostrEvent.create - with tags', () {
|
|
// Arrange
|
|
final keypair = NostrKeyPair.generate();
|
|
final tags = [
|
|
['t', 'tag1'],
|
|
['p', 'pubkey123'],
|
|
];
|
|
|
|
// Act
|
|
final event = NostrEvent.create(
|
|
content: 'Tagged content',
|
|
privateKey: keypair.privateKey,
|
|
tags: tags,
|
|
);
|
|
|
|
// Assert
|
|
expect(event.tags.length, equals(2));
|
|
expect(event.tags[0], equals(['t', 'tag1']));
|
|
});
|
|
|
|
/// Tests event JSON serialization.
|
|
test('NostrEvent - JSON serialization', () {
|
|
// Arrange
|
|
final keypair = NostrKeyPair.generate();
|
|
final event = NostrEvent.create(
|
|
content: 'Test',
|
|
privateKey: keypair.privateKey,
|
|
);
|
|
|
|
// Act
|
|
final json = event.toJson();
|
|
final restored = NostrEvent.fromJson(json);
|
|
|
|
// Assert
|
|
expect(restored.id, equals(event.id));
|
|
expect(restored.content, equals(event.content));
|
|
expect(restored.kind, equals(event.kind));
|
|
});
|
|
});
|
|
|
|
group('NostrService - Metadata Sync', () {
|
|
/// Tests syncing metadata to relays.
|
|
test('syncMetadata - success', () async {
|
|
// Arrange
|
|
final service = NostrService();
|
|
final keypair = NostrKeyPair.generate();
|
|
final metadata = {
|
|
'name': 'Test User',
|
|
'about': 'Test description',
|
|
};
|
|
|
|
// Mock relay connection (without actual WebSocket)
|
|
// Note: In a real test, you'd mock the WebSocket channel
|
|
// For now, we test that the event is created correctly
|
|
|
|
// Act
|
|
try {
|
|
final event = await service.syncMetadata(
|
|
metadata: metadata,
|
|
privateKey: keypair.privateKey,
|
|
);
|
|
|
|
// Assert - event should be created
|
|
expect(event, isNotNull);
|
|
expect(event.content, contains('Test User'));
|
|
expect(event.kind, equals(0)); // Metadata kind
|
|
} catch (e) {
|
|
// Expected to fail without real relay connection
|
|
expect(e, isA<NostrException>());
|
|
}
|
|
});
|
|
|
|
/// Tests syncing metadata with custom kind.
|
|
test('syncMetadata - custom kind', () async {
|
|
// Arrange
|
|
final service = NostrService();
|
|
final keypair = NostrKeyPair.generate();
|
|
final metadata = {'key': 'value'};
|
|
|
|
// Act
|
|
try {
|
|
final event = await service.syncMetadata(
|
|
metadata: metadata,
|
|
privateKey: keypair.privateKey,
|
|
kind: 30000, // Custom kind
|
|
);
|
|
|
|
// Assert
|
|
expect(event.kind, equals(30000));
|
|
} catch (e) {
|
|
// Expected to fail without real relay connection
|
|
expect(e, isA<NostrException>());
|
|
}
|
|
});
|
|
});
|
|
|
|
group('NostrService - Error Handling', () {
|
|
/// Tests error handling when publishing without relay connection.
|
|
test('publishEvent - fails when not connected', () async {
|
|
// Arrange
|
|
final service = NostrService();
|
|
final keypair = NostrKeyPair.generate();
|
|
final event = NostrEvent.create(
|
|
content: 'Test',
|
|
privateKey: keypair.privateKey,
|
|
);
|
|
|
|
// Act & Assert
|
|
expect(
|
|
() => service.publishEvent(event, 'wss://relay.example.com'),
|
|
throwsA(isA<NostrException>()),
|
|
);
|
|
});
|
|
|
|
/// Tests error handling when publishing to all relays without connections.
|
|
test('publishEventToAllRelays - handles disconnected relays', () async {
|
|
// Arrange
|
|
final service = NostrService();
|
|
service.addRelay('wss://relay1.example.com');
|
|
service.addRelay('wss://relay2.example.com');
|
|
final keypair = NostrKeyPair.generate();
|
|
final event = NostrEvent.create(
|
|
content: 'Test',
|
|
privateKey: keypair.privateKey,
|
|
);
|
|
|
|
// Act
|
|
final results = await service.publishEventToAllRelays(event);
|
|
|
|
// Assert - all should fail since not connected
|
|
expect(results.length, equals(2));
|
|
expect(results['wss://relay1.example.com'], isFalse);
|
|
expect(results['wss://relay2.example.com'], isFalse);
|
|
});
|
|
});
|
|
|
|
group('NostrService - Cleanup', () {
|
|
/// Tests that dispose cleans up resources.
|
|
test('dispose - cleans up resources', () {
|
|
// Arrange
|
|
final service = NostrService();
|
|
service.addRelay('wss://relay1.example.com');
|
|
service.addRelay('wss://relay2.example.com');
|
|
|
|
// Act
|
|
service.dispose();
|
|
|
|
// Assert
|
|
final relays = service.getRelays();
|
|
expect(relays.length, equals(0));
|
|
});
|
|
});
|
|
}
|