mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-03-01 06:22:44 -08:00
feat(core): add Discord presence service and extract Jellyfin runtime composition
Introduce Discord presence runtime support and continue composition-root decomposition by moving Jellyfin wiring into dedicated composer modules. This keeps main runtime orchestration thinner while preserving behavior and test coverage across config, runtime, and docs updates.
This commit is contained in:
@@ -17,7 +17,7 @@ test('jellyfin directPlayContainers are normalized', () => {
|
||||
|
||||
test('jellyfin legacy auth keys are ignored by resolver', () => {
|
||||
const { context } = createResolveContext({
|
||||
jellyfin: ({ accessToken: 'legacy-token', userId: 'legacy-user' } as unknown) as never,
|
||||
jellyfin: { accessToken: 'legacy-token', userId: 'legacy-user' } as unknown as never,
|
||||
});
|
||||
|
||||
applyIntegrationConfig(context);
|
||||
@@ -25,3 +25,61 @@ test('jellyfin legacy auth keys are ignored by resolver', () => {
|
||||
assert.equal('accessToken' in (context.resolved.jellyfin as Record<string, unknown>), false);
|
||||
assert.equal('userId' in (context.resolved.jellyfin as Record<string, unknown>), false);
|
||||
});
|
||||
|
||||
test('discordPresence fields are parsed and clamped', () => {
|
||||
const { context } = createResolveContext({
|
||||
discordPresence: {
|
||||
enabled: true,
|
||||
clientId: '123456789',
|
||||
detailsTemplate: 'Watching {title}',
|
||||
stateTemplate: 'Paused',
|
||||
largeImageKey: 'subminer-logo',
|
||||
largeImageText: 'SubMiner Runtime',
|
||||
smallImageKey: 'pause',
|
||||
smallImageText: 'Paused',
|
||||
buttonLabel: 'Open Repo',
|
||||
buttonUrl: 'https://github.com/sudacode/SubMiner',
|
||||
updateIntervalMs: 500,
|
||||
debounceMs: -100,
|
||||
},
|
||||
});
|
||||
|
||||
applyIntegrationConfig(context);
|
||||
|
||||
assert.equal(context.resolved.discordPresence.enabled, true);
|
||||
assert.equal(context.resolved.discordPresence.clientId, '123456789');
|
||||
assert.equal(context.resolved.discordPresence.detailsTemplate, 'Watching {title}');
|
||||
assert.equal(context.resolved.discordPresence.stateTemplate, 'Paused');
|
||||
assert.equal(context.resolved.discordPresence.largeImageKey, 'subminer-logo');
|
||||
assert.equal(context.resolved.discordPresence.largeImageText, 'SubMiner Runtime');
|
||||
assert.equal(context.resolved.discordPresence.smallImageKey, 'pause');
|
||||
assert.equal(context.resolved.discordPresence.smallImageText, 'Paused');
|
||||
assert.equal(context.resolved.discordPresence.buttonLabel, 'Open Repo');
|
||||
assert.equal(context.resolved.discordPresence.buttonUrl, 'https://github.com/sudacode/SubMiner');
|
||||
assert.equal(context.resolved.discordPresence.updateIntervalMs, 1000);
|
||||
assert.equal(context.resolved.discordPresence.debounceMs, 0);
|
||||
});
|
||||
|
||||
test('discordPresence invalid values warn and keep defaults', () => {
|
||||
const { context, warnings } = createResolveContext({
|
||||
discordPresence: {
|
||||
enabled: 'true' as never,
|
||||
clientId: 123 as never,
|
||||
updateIntervalMs: 'fast' as never,
|
||||
debounceMs: null as never,
|
||||
},
|
||||
});
|
||||
|
||||
applyIntegrationConfig(context);
|
||||
|
||||
assert.equal(context.resolved.discordPresence.enabled, false);
|
||||
assert.equal(context.resolved.discordPresence.clientId, '');
|
||||
assert.equal(context.resolved.discordPresence.updateIntervalMs, 15_000);
|
||||
assert.equal(context.resolved.discordPresence.debounceMs, 750);
|
||||
|
||||
const warnedPaths = warnings.map((warning) => warning.path);
|
||||
assert.ok(warnedPaths.includes('discordPresence.enabled'));
|
||||
assert.ok(warnedPaths.includes('discordPresence.clientId'));
|
||||
assert.ok(warnedPaths.includes('discordPresence.updateIntervalMs'));
|
||||
assert.ok(warnedPaths.includes('discordPresence.debounceMs'));
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user