mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-03-30 06:12:06 -07:00
Fix AniList token persistence and AVIF timing
- Defer AniList setup prompts until app-ready and reuse stored tokens - Add AVIF lead-in padding so motion stays aligned with sentence audio
This commit is contained in:
@@ -82,7 +82,42 @@ test('refresh handler prefers cached token when not forced', async () => {
|
||||
assert.equal(loadCalls, 0);
|
||||
});
|
||||
|
||||
test('refresh handler falls back to stored token then opens setup when missing', async () => {
|
||||
test('refresh handler falls back to stored token without opening setup', async () => {
|
||||
let cached: string | null = null;
|
||||
let opened = false;
|
||||
let openCalls = 0;
|
||||
const states: Array<{ status: string; source: string }> = [];
|
||||
const refresh = createRefreshAnilistClientSecretStateHandler({
|
||||
getResolvedConfig: () => ({ anilist: { accessToken: '' } }),
|
||||
isAnilistTrackingEnabled: () => true,
|
||||
getCachedAccessToken: () => cached,
|
||||
setCachedAccessToken: (token) => {
|
||||
cached = token;
|
||||
},
|
||||
saveStoredToken: () => {},
|
||||
loadStoredToken: () => ' stored-token ',
|
||||
setClientSecretState: (state) => {
|
||||
states.push({ status: state.status, source: state.source });
|
||||
},
|
||||
getAnilistSetupPageOpened: () => opened,
|
||||
setAnilistSetupPageOpened: (next) => {
|
||||
opened = next;
|
||||
},
|
||||
openAnilistSetupWindow: () => {
|
||||
openCalls += 1;
|
||||
},
|
||||
now: () => 400,
|
||||
});
|
||||
|
||||
const token = await refresh({ force: true });
|
||||
assert.equal(token, 'stored-token');
|
||||
assert.equal(cached, 'stored-token');
|
||||
assert.equal(opened, false);
|
||||
assert.equal(openCalls, 0);
|
||||
assert.deepEqual(states, [{ status: 'resolved', source: 'stored' }]);
|
||||
});
|
||||
|
||||
test('refresh handler opens setup when missing token and prompting allowed', async () => {
|
||||
let cached: string | null = null;
|
||||
let opened = false;
|
||||
let openCalls = 0;
|
||||
@@ -111,3 +146,44 @@ test('refresh handler falls back to stored token then opens setup when missing',
|
||||
assert.equal(cached, null);
|
||||
assert.equal(openCalls, 1);
|
||||
});
|
||||
|
||||
test('refresh handler skips setup open when missing token and prompting disabled', async () => {
|
||||
let cached: string | null = null;
|
||||
let opened = false;
|
||||
let openCalls = 0;
|
||||
const states: Array<{ status: string; source: string; message: string | null }> = [];
|
||||
const refresh = createRefreshAnilistClientSecretStateHandler({
|
||||
getResolvedConfig: () => ({ anilist: { accessToken: '' } }),
|
||||
isAnilistTrackingEnabled: () => true,
|
||||
getCachedAccessToken: () => cached,
|
||||
setCachedAccessToken: (token) => {
|
||||
cached = token;
|
||||
},
|
||||
saveStoredToken: () => {},
|
||||
loadStoredToken: () => '',
|
||||
setClientSecretState: (state) => {
|
||||
states.push({ status: state.status, source: state.source, message: state.message });
|
||||
},
|
||||
getAnilistSetupPageOpened: () => opened,
|
||||
setAnilistSetupPageOpened: (next) => {
|
||||
opened = next;
|
||||
},
|
||||
openAnilistSetupWindow: () => {
|
||||
openCalls += 1;
|
||||
},
|
||||
now: () => 500,
|
||||
});
|
||||
|
||||
const token = await refresh({ force: true, allowSetupPrompt: false });
|
||||
assert.equal(token, null);
|
||||
assert.equal(cached, null);
|
||||
assert.equal(opened, false);
|
||||
assert.equal(openCalls, 0);
|
||||
assert.deepEqual(states, [
|
||||
{
|
||||
status: 'error',
|
||||
source: 'none',
|
||||
message: 'cannot authenticate without anilist.accessToken',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -27,7 +27,10 @@ export function createRefreshAnilistClientSecretStateHandler<
|
||||
openAnilistSetupWindow: () => void;
|
||||
now: () => number;
|
||||
}) {
|
||||
return async (options?: { force?: boolean }): Promise<string | null> => {
|
||||
return async (options?: {
|
||||
force?: boolean;
|
||||
allowSetupPrompt?: boolean;
|
||||
}): Promise<string | null> => {
|
||||
const resolved = deps.getResolvedConfig();
|
||||
const now = deps.now();
|
||||
if (!deps.isAnilistTrackingEnabled(resolved)) {
|
||||
@@ -87,7 +90,11 @@ export function createRefreshAnilistClientSecretStateHandler<
|
||||
resolvedAt: null,
|
||||
errorAt: now,
|
||||
});
|
||||
if (deps.isAnilistTrackingEnabled(resolved) && !deps.getAnilistSetupPageOpened()) {
|
||||
if (
|
||||
options?.allowSetupPrompt !== false &&
|
||||
deps.isAnilistTrackingEnabled(resolved) &&
|
||||
!deps.getAnilistSetupPageOpened()
|
||||
) {
|
||||
deps.openAnilistSetupWindow();
|
||||
}
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user