Analog zu BakaAuth, aber ohne Passwort: holt/speichert einen geräte-gebundenen Gast-Token vom neuen /api/guest-token-Endpunkt (siehe docs/superpowers/specs/2026-08-26-youtube-guest-quota-design.md). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_$(uuidgen | cut -d- -f1)
121 lines
3.4 KiB
Dart
121 lines
3.4 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:http/http.dart' as http;
|
|
import 'package:http/testing.dart';
|
|
import 'package:melo/services/baka_auth.dart';
|
|
import 'package:melo/services/gast_zugang.dart';
|
|
|
|
class _MemorySpeicher implements TokenSpeicher {
|
|
final Map<String, String> werte = {};
|
|
@override
|
|
Future<String?> lesen(String key) async => werte[key];
|
|
@override
|
|
Future<void> schreiben(String key, String wert) async => werte[key] = wert;
|
|
@override
|
|
Future<void> loeschen(String key) async => werte.remove(key);
|
|
}
|
|
|
|
void main() {
|
|
test('Ohne Token ist gastHeader leer', () {
|
|
final gast = GastZugang(
|
|
client: MockClient((_) async => http.Response('', 500)),
|
|
speicher: _MemorySpeicher(),
|
|
);
|
|
|
|
expect(gast.hatToken, isFalse);
|
|
expect(gast.gastHeader, isEmpty);
|
|
});
|
|
|
|
test('holeToken() speichert den Token bei Erfolg', () async {
|
|
final speicher = _MemorySpeicher();
|
|
final gast = GastZugang(
|
|
client: MockClient(
|
|
(_) async => http.Response(jsonEncode({'guest_token': 'g-1'}), 200)),
|
|
speicher: speicher,
|
|
);
|
|
|
|
final fehler = await gast.holeToken();
|
|
|
|
expect(fehler, isNull);
|
|
expect(gast.hatToken, isTrue);
|
|
expect(gast.gastHeader, {'X-Guest-Token': 'g-1'});
|
|
expect(speicher.werte['guest_token'], 'g-1');
|
|
});
|
|
|
|
test('holeToken() meldet einen Fehler bei einer toten Verbindung',
|
|
() async {
|
|
final gast = GastZugang(
|
|
client: MockClient((_) async => throw Exception('down')),
|
|
speicher: _MemorySpeicher(),
|
|
);
|
|
|
|
final fehler = await gast.holeToken();
|
|
|
|
expect(fehler, 'Proxy nicht erreichbar');
|
|
expect(gast.hatToken, isFalse);
|
|
});
|
|
|
|
test('holeToken() meldet einen Fehler bei einem Server-Fehlerstatus',
|
|
() async {
|
|
final gast = GastZugang(
|
|
client: MockClient((_) async => http.Response('', 500)),
|
|
speicher: _MemorySpeicher(),
|
|
);
|
|
|
|
final fehler = await gast.holeToken();
|
|
|
|
expect(fehler, 'Gast-Zugang fehlgeschlagen (500)');
|
|
expect(gast.hatToken, isFalse);
|
|
});
|
|
|
|
test('holeToken() meldet einen Fehler bei unlesbarer Antwort', () async {
|
|
final gast = GastZugang(
|
|
client: MockClient((_) async => http.Response('nicht json', 200)),
|
|
speicher: _MemorySpeicher(),
|
|
);
|
|
|
|
final fehler = await gast.holeToken();
|
|
|
|
expect(fehler, 'Proxy antwortet unverständlich (200)');
|
|
expect(gast.hatToken, isFalse);
|
|
});
|
|
|
|
test('holeToken() meldet einen Fehler ohne guest_token-Feld', () async {
|
|
final gast = GastZugang(
|
|
client: MockClient((_) async => http.Response(jsonEncode({}), 200)),
|
|
speicher: _MemorySpeicher(),
|
|
);
|
|
|
|
final fehler = await gast.holeToken();
|
|
|
|
expect(fehler, 'Proxy hat keinen Gast-Token geliefert');
|
|
expect(gast.hatToken, isFalse);
|
|
});
|
|
|
|
test('laden() stellt einen gespeicherten Gast-Token wieder her', () async {
|
|
final speicher = _MemorySpeicher();
|
|
speicher.werte['guest_token'] = 'g-alt';
|
|
final gast = GastZugang(
|
|
client: MockClient((_) async => http.Response('', 500)),
|
|
speicher: speicher,
|
|
);
|
|
|
|
await gast.laden();
|
|
|
|
expect(gast.hatToken, isTrue);
|
|
expect(gast.gastHeader, {'X-Guest-Token': 'g-alt'});
|
|
});
|
|
|
|
test('merkeVerbleibend übernimmt den zuletzt gemeldeten Stand', () {
|
|
final gast = GastZugang(
|
|
client: MockClient((_) async => http.Response('', 500)),
|
|
speicher: _MemorySpeicher(),
|
|
);
|
|
|
|
gast.merkeVerbleibend(3);
|
|
|
|
expect(gast.verbleibend, 3);
|
|
});
|
|
}
|