From 77e13d312c2b9b47427eeeb055209e4a3337deb8 Mon Sep 17 00:00:00 2001 From: bymyself Date: Mon, 19 Jan 2026 19:26:11 -0800 Subject: [PATCH] feat: add survey registry for feature survey configurations Amp-Thread-ID: https://ampcode.com/threads/T-019c7db5-bd68-713b-bf60-4b1022483308 --- src/platform/surveys/surveyRegistry.test.ts | 75 ++++++++++++++++++++ src/platform/surveys/surveyRegistry.ts | 19 +++++ src/platform/surveys/useSurveyEligibility.ts | 2 +- 3 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 src/platform/surveys/surveyRegistry.test.ts create mode 100644 src/platform/surveys/surveyRegistry.ts diff --git a/src/platform/surveys/surveyRegistry.test.ts b/src/platform/surveys/surveyRegistry.test.ts new file mode 100644 index 000000000..c79098536 --- /dev/null +++ b/src/platform/surveys/surveyRegistry.test.ts @@ -0,0 +1,75 @@ +import { afterEach, beforeEach, describe, expect, it } from 'vitest' + +import type { FeatureSurveyConfig } from './useSurveyEligibility' + +import { + FEATURE_SURVEYS, + getEnabledSurveys, + getSurveyConfig +} from './surveyRegistry' + +const TEST_FEATURE_ID = '__test-feature__' +const TEST_CONFIG: FeatureSurveyConfig = { + featureId: TEST_FEATURE_ID, + typeformId: 'test-form-123', + triggerThreshold: 5, + delayMs: 3000, + enabled: true +} + +describe('surveyRegistry', () => { + let originalEntries: Record + + beforeEach(() => { + originalEntries = { ...FEATURE_SURVEYS } + FEATURE_SURVEYS[TEST_FEATURE_ID] = TEST_CONFIG + }) + + afterEach(() => { + for (const key of Object.keys(FEATURE_SURVEYS)) { + delete FEATURE_SURVEYS[key] + } + Object.assign(FEATURE_SURVEYS, originalEntries) + }) + + describe('getSurveyConfig', () => { + it('returns undefined for unknown feature', () => { + expect(getSurveyConfig('nonexistent-feature')).toBeUndefined() + }) + + it('returns config for registered feature', () => { + const config = getSurveyConfig(TEST_FEATURE_ID) + expect(config).toEqual(TEST_CONFIG) + }) + }) + + describe('getEnabledSurveys', () => { + it('includes surveys with enabled: true', () => { + const enabled = getEnabledSurveys() + expect(enabled).toContainEqual(TEST_CONFIG) + }) + + it('includes surveys where enabled is undefined', () => { + const implicitlyEnabled: FeatureSurveyConfig = { + featureId: '__implicit__', + typeformId: 'form-456' + } + FEATURE_SURVEYS['__implicit__'] = implicitlyEnabled + + const enabled = getEnabledSurveys() + expect(enabled).toContainEqual(implicitlyEnabled) + }) + + it('excludes surveys with enabled: false', () => { + const disabledConfig: FeatureSurveyConfig = { + featureId: '__disabled__', + typeformId: 'form-789', + enabled: false + } + FEATURE_SURVEYS['__disabled__'] = disabledConfig + + const enabled = getEnabledSurveys() + expect(enabled).not.toContainEqual(disabledConfig) + }) + }) +}) diff --git a/src/platform/surveys/surveyRegistry.ts b/src/platform/surveys/surveyRegistry.ts new file mode 100644 index 000000000..e93f58181 --- /dev/null +++ b/src/platform/surveys/surveyRegistry.ts @@ -0,0 +1,19 @@ +import type { FeatureSurveyConfig } from './useSurveyEligibility' + +/** + * Registry of all feature surveys. + * Add new surveys here when targeting specific features for feedback. + */ +export const FEATURE_SURVEYS: Record = {} + +export function getSurveyConfig( + featureId: string +): FeatureSurveyConfig | undefined { + return FEATURE_SURVEYS[featureId] +} + +export function getEnabledSurveys(): FeatureSurveyConfig[] { + return Object.values(FEATURE_SURVEYS).filter( + (config) => config.enabled !== false + ) +} diff --git a/src/platform/surveys/useSurveyEligibility.ts b/src/platform/surveys/useSurveyEligibility.ts index 37929e25c..e8e86f230 100644 --- a/src/platform/surveys/useSurveyEligibility.ts +++ b/src/platform/surveys/useSurveyEligibility.ts @@ -6,7 +6,7 @@ import { isCloud, isDesktop, isNightly } from '@/platform/distribution/types' import { useFeatureUsageTracker } from './useFeatureUsageTracker' -interface FeatureSurveyConfig { +export interface FeatureSurveyConfig { /** Feature identifier. Must remain static after initialization. */ featureId: string typeformId: string