feat: add runtime feature overrides
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
import { randomUUID } from 'node:crypto';
|
||||
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
import { afterEach, describe, expect, it } from 'vitest';
|
||||
import { clearFeatureOverridesCache, refreshFeatureOverridesCache } from '../src/lib/runtime-features.js';
|
||||
import { buildLikesFeatures, buildSearchFeatures } from '../src/lib/twitter-client-features.js';
|
||||
|
||||
describe('runtime-features', () => {
|
||||
afterEach(() => {
|
||||
delete process.env.BIRD_FEATURES_JSON;
|
||||
delete process.env.BIRD_FEATURES_CACHE;
|
||||
delete process.env.BIRD_FEATURES_PATH;
|
||||
clearFeatureOverridesCache();
|
||||
});
|
||||
|
||||
it('applies global and set overrides from env json', () => {
|
||||
process.env.BIRD_FEATURES_JSON = JSON.stringify({
|
||||
global: {
|
||||
global_flag: true,
|
||||
ignored: 'nope',
|
||||
},
|
||||
sets: {
|
||||
search: {
|
||||
global_flag: false,
|
||||
search_only: true,
|
||||
bad: 1,
|
||||
},
|
||||
likes: {
|
||||
likes_only: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
clearFeatureOverridesCache();
|
||||
const search = buildSearchFeatures();
|
||||
expect(search.global_flag).toBe(false);
|
||||
expect(search.search_only).toBe(true);
|
||||
expect(search.bad).toBeUndefined();
|
||||
|
||||
const likes = buildLikesFeatures();
|
||||
expect(likes.global_flag).toBe(true);
|
||||
expect(likes.likes_only).toBe(true);
|
||||
});
|
||||
|
||||
it('refresh merges defaults with existing cache', async () => {
|
||||
const cacheDir = path.join(os.tmpdir(), `bird-test-${randomUUID()}`);
|
||||
await mkdir(cacheDir, { recursive: true });
|
||||
const cachePath = path.join(cacheDir, 'features.json');
|
||||
|
||||
await writeFile(
|
||||
cachePath,
|
||||
JSON.stringify(
|
||||
{
|
||||
global: {
|
||||
existing_flag: true,
|
||||
},
|
||||
sets: {
|
||||
search: {
|
||||
existing_search: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
null,
|
||||
2,
|
||||
),
|
||||
);
|
||||
|
||||
process.env.BIRD_FEATURES_PATH = cachePath;
|
||||
await refreshFeatureOverridesCache();
|
||||
|
||||
const raw = await readFile(cachePath, 'utf8');
|
||||
const parsed = JSON.parse(raw) as {
|
||||
global?: Record<string, boolean>;
|
||||
sets?: Record<string, Record<string, boolean>>;
|
||||
};
|
||||
|
||||
expect(parsed.global?.existing_flag).toBe(true);
|
||||
expect(parsed.global?.responsive_web_grok_annotations_enabled).toBe(false);
|
||||
expect(parsed.sets?.search?.existing_search).toBe(false);
|
||||
});
|
||||
|
||||
it('applies overrides from cache file', async () => {
|
||||
const cacheDir = path.join(os.tmpdir(), `bird-test-${randomUUID()}`);
|
||||
await mkdir(cacheDir, { recursive: true });
|
||||
const cachePath = path.join(cacheDir, 'features.json');
|
||||
|
||||
await writeFile(
|
||||
cachePath,
|
||||
JSON.stringify(
|
||||
{
|
||||
global: {
|
||||
file_flag: true,
|
||||
},
|
||||
sets: {
|
||||
search: {
|
||||
file_search: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
null,
|
||||
2,
|
||||
),
|
||||
);
|
||||
|
||||
process.env.BIRD_FEATURES_PATH = cachePath;
|
||||
clearFeatureOverridesCache();
|
||||
|
||||
const search = buildSearchFeatures();
|
||||
expect(search.file_flag).toBe(true);
|
||||
expect(search.file_search).toBe(true);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user