Files
plezy/test/profiles/profile_test.dart
T
2026-05-01 01:20:36 +02:00

128 lines
4.1 KiB
Dart

import 'package:flutter_test/flutter_test.dart';
import 'package:plezy/profiles/profile.dart';
void main() {
group('Profile', () {
test('local profile defaults', () {
final p = Profile(id: 'local-1', kind: ProfileKind.local, displayName: 'Owner', createdAt: DateTime(2026, 1, 1));
expect(p.isLocal, isTrue);
expect(p.isPlexHome, isFalse);
expect(p.isPinProtected, isFalse);
expect(p.parentConnectionId, isNull);
});
test('local profile with PIN is pin-protected', () {
final p = Profile(
id: 'local-1',
kind: ProfileKind.local,
displayName: 'Kids',
pinHash: computePinHash('1234'),
createdAt: DateTime(2026, 1, 1),
);
expect(p.isPinProtected, isTrue);
});
test('plex_home profile pin protection follows the protected flag', () {
final p = Profile(
id: 'plex-home-acct1-uuid1',
kind: ProfileKind.plexHome,
displayName: 'Sarah',
parentConnectionId: 'acct1',
plexProtected: true,
createdAt: DateTime(2026, 1, 1),
);
expect(p.isLocal, isFalse);
expect(p.isPinProtected, isTrue);
});
test('local PIN hash is round-tripped via configJson', () {
final p = Profile(
id: 'local-1',
kind: ProfileKind.local,
displayName: 'Kids',
pinHash: computePinHash('1234'),
createdAt: DateTime(2026, 1, 1),
);
final json = p.toConfigJson();
final restored = Profile.fromRow(
id: p.id,
kind: 'local',
displayName: p.displayName,
avatarThumbUrl: null,
json: json,
sortOrder: 0,
createdAt: p.createdAt,
lastUsedAt: null,
);
expect(restored.pinHash, p.pinHash);
expect(restored.isPinProtected, isTrue);
});
test('plex_home configJson round-trips with all flags', () {
final p = Profile(
id: 'plex-home-acct1-uuid1',
kind: ProfileKind.plexHome,
displayName: 'Admin',
parentConnectionId: 'acct1',
plexAdmin: true,
plexRestricted: false,
plexProtected: true,
createdAt: DateTime(2026, 1, 1),
);
final json = p.toConfigJson();
final restored = Profile.fromRow(
id: p.id,
kind: 'plex_home',
displayName: p.displayName,
avatarThumbUrl: null,
json: json,
sortOrder: 0,
createdAt: p.createdAt,
lastUsedAt: null,
);
expect(restored.plexAdmin, isTrue);
expect(restored.plexRestricted, isFalse);
expect(restored.plexProtected, isTrue);
expect(restored.parentConnectionId, 'acct1');
});
test('plexHomeProfileId is deterministic', () {
expect(plexHomeProfileId(accountConnectionId: 'plex.dev1', homeUserUuid: 'uuid-1'), 'plex-home-plex.dev1-uuid-1');
});
test('parsePlexHomeProfileId round-trips a real hyphenated UUID', () {
// Real Plex Home UUIDs are 36-char standard UUIDs (4 internal hyphens),
// and accountConnectionId can carry hyphens too (e.g. plex.client-id).
const acct = 'plex.client-id-123';
const uuid = 'a1b2c3d4-e5f6-7890-abcd-ef0123456789';
final id = plexHomeProfileId(accountConnectionId: acct, homeUserUuid: uuid);
final parsed = parsePlexHomeProfileId(id);
expect(parsed, isNotNull);
expect(parsed!.accountConnectionId, acct);
expect(parsed.homeUserUuid, uuid);
});
test('parsePlexHomeProfileId rejects non-Plex-Home ids', () {
expect(parsePlexHomeProfileId('local-1'), isNull);
expect(parsePlexHomeProfileId('plex-home-only'), isNull);
expect(parsePlexHomeProfileId('plex-home-acct-not-a-uuid'), isNull);
});
});
group('PIN hashing', () {
test('computePinHash is deterministic for the same input', () {
expect(computePinHash('1234'), computePinHash('1234'));
});
test('computePinHash differs for different inputs', () {
expect(computePinHash('1234'), isNot(computePinHash('5678')));
});
test('verifyPin matches its hash', () {
final h = computePinHash('4242');
expect(verifyPin('4242', h), isTrue);
expect(verifyPin('1111', h), isFalse);
});
});
}