worldhopper/test/services/server_software/kavita_server_software_test.dart
Felipe M. 58a562abe8
feat: refactor server software abstraction with Kavita REST API integration
Rename all OPDS-prefixed models to generic names (Server, Feed, Entry,
Link, StreamLink), expand the ServerSoftware interface to cover all
server interactions, and implement a full Kavita REST API client that
replaces the OPDS delegation.

- Rename OPDS* models to generic names across ~60 files
- Add database migrations 13 (opds_id → entry_id) and 14 (unify credentials)
- Create OPDSServerSoftware wrapping existing OPDS services
- Create KavitaApiClient for direct Kavita REST API calls
- Create KavitaFeedMapper to convert Kavita JSON to Feed/Entry models
- Rewrite KavitaServerSoftware to use native API (no OPDS delegation)
- Unify server credentials (remove softwareUsername/softwarePassword)
- Simplify add/edit server UI to single auth section
- Add test connection button to server add/edit screens
- Add progress indicator to PublicationCard using local and server data
- Eliminate softwareType branching in reader screens
- Add EntryProgress and fetchEntryProgress to ServerSoftware interface
- Fix Entry.acquisitionLink crash on empty links
- Add 59 new tests covering models, services, and providers
2026-04-06 17:46:48 +02:00

61 lines
1.8 KiB
Dart

import 'package:flutter_test/flutter_test.dart';
import 'package:worldhopper/models/server.dart';
// Kavita URL pattern extracted from KavitaServerSoftware for isolated testing
// without needing to construct the full OPDSServerSoftware dependency tree.
final _urlPattern = RegExp(
r'/api/opds/[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}',
);
bool _detectFromUrl(Server server) => _urlPattern.hasMatch(server.url);
Server _server(String url) => Server(
id: 's1',
name: 'Test',
url: url,
createdAt: DateTime(2024),
);
void main() {
group('Kavita detectFromUrl', () {
test('detects standard Kavita OPDS URL', () {
final server = _server(
'https://kavita.example.com/api/opds/12345678-1234-1234-1234-123456789abc',
);
expect(_detectFromUrl(server), isTrue);
});
test('detects Kavita URL with trailing path', () {
final server = _server(
'https://kavita.example.com/api/opds/12345678-1234-1234-1234-123456789abc/series/1',
);
expect(_detectFromUrl(server), isTrue);
});
test('rejects plain OPDS URL', () {
final server = _server('https://example.com/opds');
expect(_detectFromUrl(server), isFalse);
});
test('rejects URL with invalid UUID', () {
final server = _server(
'https://kavita.example.com/api/opds/not-a-uuid',
);
expect(_detectFromUrl(server), isFalse);
});
test('rejects URL with /api/ but no opds path', () {
final server = _server(
'https://kavita.example.com/api/library',
);
expect(_detectFromUrl(server), isFalse);
});
test('detects uppercase hex UUID', () {
final server = _server(
'https://kavita.example.com/api/opds/ABCDEF12-1234-5678-9ABC-DEF012345678',
);
expect(_detectFromUrl(server), isTrue);
});
});
}