mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-09-16 01:33:09 +00:00
Парная фронтовая часть к эндпоинтам /cabinet/subscription/lava-recurrent (бот: 0dea2182). Блок — сиблинг Platega-блока с той же семантикой состояний (off/pending/active/past_due), поллинг раз в 8с пока привязка PENDING. Отличие от Platega в подписи: у Lava период задан продуктом в кабинете провайдера и приезжает числом дней, поэтому канонические значения (30/90/365 и т.д.) показываются словами, а произвольные — как «раз в N дн.». utils/lavaRecurring.ts: строгое распознавание 403 'Lava recurrent disabled' (другие 403-guard'ы прятать нельзя), деградация неизвестного статуса в off. Локали ru/en/zh/fa (+25 строк каждая, плейсхолдеры сверены). 7 тестов утилиты.
57 lines
2.3 KiB
TypeScript
57 lines
2.3 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
||
import { isLavaFeatureDisabledError, lavaPeriodLabelKey, lavaUiState } from './lavaRecurring';
|
||
|
||
describe('isLavaFeatureDisabledError', () => {
|
||
it('detects exactly the disabled-feature 403', () => {
|
||
expect(
|
||
isLavaFeatureDisabledError({
|
||
response: { status: 403, data: { detail: 'Lava recurrent disabled' } },
|
||
}),
|
||
).toBe(true);
|
||
});
|
||
|
||
it('ignores other 403s and malformed errors', () => {
|
||
// Другие guard'ы отдают тот же статус с иным detail — их прятать нельзя
|
||
expect(
|
||
isLavaFeatureDisabledError({ response: { status: 403, data: { detail: 'Blacklisted' } } }),
|
||
).toBe(false);
|
||
expect(
|
||
isLavaFeatureDisabledError({ response: { status: 403, data: { detail: { code: 'x' } } } }),
|
||
).toBe(false);
|
||
expect(isLavaFeatureDisabledError({ response: { status: 500, data: {} } })).toBe(false);
|
||
expect(isLavaFeatureDisabledError({ response: { status: 403 } })).toBe(false);
|
||
expect(isLavaFeatureDisabledError(null)).toBe(false);
|
||
expect(isLavaFeatureDisabledError('boom')).toBe(false);
|
||
});
|
||
});
|
||
|
||
describe('lavaUiState', () => {
|
||
it('hides the block when the feature is disabled', () => {
|
||
expect(lavaUiState({ status: 'ACTIVE' }, true)).toBe('hidden');
|
||
});
|
||
|
||
it('maps backend statuses to UI states', () => {
|
||
expect(lavaUiState({ status: 'PENDING' }, false)).toBe('pending');
|
||
expect(lavaUiState({ status: 'ACTIVE' }, false)).toBe('active');
|
||
expect(lavaUiState({ status: 'PAST_DUE' }, false)).toBe('past_due');
|
||
expect(lavaUiState({ status: 'none' }, false)).toBe('off');
|
||
});
|
||
|
||
it('degrades unknown or missing state to off instead of hanging', () => {
|
||
expect(lavaUiState({ status: 'SOMETHING_NEW' }, false)).toBe('off');
|
||
expect(lavaUiState(undefined, false)).toBe('off');
|
||
});
|
||
});
|
||
|
||
describe('lavaPeriodLabelKey', () => {
|
||
it('labels canonical periods', () => {
|
||
expect(lavaPeriodLabelKey(30)).toBe('subscription.lavaRecurring.period.month');
|
||
expect(lavaPeriodLabelKey(365)).toBe('subscription.lavaRecurring.period.year');
|
||
});
|
||
|
||
it('returns null for non-canonical periods so the caller falls back to "N days"', () => {
|
||
expect(lavaPeriodLabelKey(45)).toBeNull();
|
||
expect(lavaPeriodLabelKey(undefined)).toBeNull();
|
||
});
|
||
});
|