| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688 |
- import {
- CurrencyCode,
- LanguageCode,
- mergeConfig,
- Permission,
- SettingsStoreEntry,
- SettingsStoreService,
- TransactionalConnection,
- } from '@vendure/core';
- import { createTestEnvironment, E2E_DEFAULT_CHANNEL_TOKEN } from '@vendure/testing';
- import path from 'path';
- import { afterAll, beforeAll, describe, expect, it } from 'vitest';
- import { initialData } from '../../../e2e-common/e2e-initial-data';
- import { TEST_SETUP_TIMEOUT_MS, testConfig } from '../../../e2e-common/test-config';
- import { SettingsStoreTestPlugin } from './fixtures/test-plugins/settings-store-test-plugin';
- import {
- createAdministratorDocument,
- createChannelDocument,
- createRoleDocument,
- getSettingsStoreValueDocument,
- getSettingsStoreValuesDocument,
- setSettingsStoreValueDocument,
- setSettingsStoreValuesDocument,
- } from './graphql/shared-definitions';
- describe('SettingsStore system', () => {
- const { server, adminClient } = createTestEnvironment(
- mergeConfig(testConfig(), {
- plugins: [SettingsStoreTestPlugin],
- }),
- );
- beforeAll(async () => {
- await server.init({
- initialData,
- productsCsvPath: path.join(__dirname, 'fixtures/e2e-products-minimal.csv'),
- customerCount: 1,
- });
- await adminClient.asSuperAdmin();
- }, TEST_SETUP_TIMEOUT_MS);
- afterAll(async () => {
- await server.destroy();
- });
- describe('Global scoped fields', () => {
- it('should set and get a global value', async () => {
- const { setSettingsStoreValue } = await adminClient.query(setSettingsStoreValueDocument, {
- input: { key: 'test.globalSetting', value: 'global-value' },
- });
- expect(setSettingsStoreValue.result).toBe(true);
- expect(setSettingsStoreValue.key).toBe('test.globalSetting');
- expect(setSettingsStoreValue.error).toBeNull();
- const { getSettingsStoreValue } = await adminClient.query(getSettingsStoreValueDocument, {
- key: 'test.globalSetting',
- });
- expect(getSettingsStoreValue).toBe('global-value');
- });
- it('should return same global value from different contexts', async () => {
- // Create another user
- await adminClient.query(createAdministratorDocument, {
- input: {
- firstName: 'Test',
- lastName: 'Admin',
- emailAddress: 'test@test.com',
- password: 'password',
- roleIds: ['1'], // SuperAdmin role
- },
- });
- // Login as the new user and check global value
- await adminClient.asUserWithCredentials('test@test.com', 'password');
- const { getSettingsStoreValue } = await adminClient.query(getSettingsStoreValueDocument, {
- key: 'test.globalSetting',
- });
- expect(getSettingsStoreValue).toBe('global-value');
- });
- });
- describe('User scoped fields', () => {
- beforeAll(async () => {
- await adminClient.asSuperAdmin();
- });
- it('should store separate values per user', async () => {
- // Set value as superadmin
- await adminClient.query(setSettingsStoreValueDocument, {
- input: { key: 'test.userSetting', value: 'superadmin-value' },
- });
- // Create and switch to another user
- await adminClient.query(createAdministratorDocument, {
- input: {
- firstName: 'Test2',
- lastName: 'Admin2',
- emailAddress: 'test2@test.com',
- password: 'password',
- roleIds: ['1'],
- },
- });
- await adminClient.asUserWithCredentials('test2@test.com', 'password');
- // Should not see superadmin's value
- const { getSettingsStoreValue: emptyValue } = await adminClient.query(
- getSettingsStoreValueDocument,
- {
- key: 'test.userSetting',
- },
- );
- expect(emptyValue).toBeNull();
- // Set different value for this user
- await adminClient.query(setSettingsStoreValueDocument, {
- input: { key: 'test.userSetting', value: 'test2-value' },
- });
- const { getSettingsStoreValue: userValue } = await adminClient.query(
- getSettingsStoreValueDocument,
- {
- key: 'test.userSetting',
- },
- );
- expect(userValue).toBe('test2-value');
- // Switch back to superadmin and verify original value
- await adminClient.asSuperAdmin();
- const { getSettingsStoreValue: superadminValue } = await adminClient.query(
- getSettingsStoreValueDocument,
- {
- key: 'test.userSetting',
- },
- );
- expect(superadminValue).toBe('superadmin-value');
- });
- });
- describe('Channel scoped fields', () => {
- const testChannelToken = 'test-channel-token';
- it('should store separate values per channel', async () => {
- await adminClient.asSuperAdmin();
- // Set value in default channel
- await adminClient.query(setSettingsStoreValueDocument, {
- input: { key: 'test.channelSetting', value: 'default-channel-value' },
- });
- const defaultZoneId = 'T_1';
- // Create a new channel
- await adminClient.query(createChannelDocument, {
- input: {
- code: 'test-channel',
- token: testChannelToken,
- defaultLanguageCode: LanguageCode.en,
- currencyCode: CurrencyCode.USD,
- pricesIncludeTax: false,
- defaultShippingZoneId: defaultZoneId,
- defaultTaxZoneId: defaultZoneId,
- },
- });
- // Switch to new channel
- adminClient.setChannelToken(testChannelToken);
- // Should not see default channel's value
- const { getSettingsStoreValue: emptyValue } = await adminClient.query(
- getSettingsStoreValueDocument,
- {
- key: 'test.channelSetting',
- },
- );
- expect(emptyValue).toBeNull();
- // Set different value for this channel
- await adminClient.query(setSettingsStoreValueDocument, {
- input: { key: 'test.channelSetting', value: 'test-channel-value' },
- });
- const { getSettingsStoreValue: channelValue } = await adminClient.query(
- getSettingsStoreValueDocument,
- {
- key: 'test.channelSetting',
- },
- );
- expect(channelValue).toBe('test-channel-value');
- // Switch back to default channel and verify original value
- adminClient.setChannelToken(E2E_DEFAULT_CHANNEL_TOKEN);
- const { getSettingsStoreValue: defaultValue } = await adminClient.query(
- getSettingsStoreValueDocument,
- {
- key: 'test.channelSetting',
- },
- );
- expect(defaultValue).toBe('default-channel-value');
- });
- });
- describe('User and channel scoped fields', () => {
- const testChannelToken = 'test-channel-token';
- it('should store separate values per user per channel', async () => {
- await adminClient.asSuperAdmin();
- // Set value as superadmin in default channel
- await adminClient.query(setSettingsStoreValueDocument, {
- input: { key: 'test.userAndChannelSetting', value: 'superadmin-default' },
- });
- // Switch to test channel
- adminClient.setChannelToken(testChannelToken);
- // Should not see default channel value
- const { getSettingsStoreValue: emptyValue } = await adminClient.query(
- getSettingsStoreValueDocument,
- {
- key: 'test.userAndChannelSetting',
- },
- );
- expect(emptyValue).toBeNull();
- // Set different value for superadmin in test channel
- await adminClient.query(setSettingsStoreValueDocument, {
- input: { key: 'test.userAndChannelSetting', value: 'superadmin-test' },
- });
- // Switch to test2 user in test channel
- await adminClient.asUserWithCredentials('test2@test.com', 'password');
- adminClient.setChannelToken(testChannelToken);
- // Should not see superadmin's value
- const { getSettingsStoreValue: emptyUserValue } = await adminClient.query(
- getSettingsStoreValueDocument,
- {
- key: 'test.userAndChannelSetting',
- },
- );
- expect(emptyUserValue).toBeNull();
- // Set value for test2 user in test channel
- await adminClient.query(setSettingsStoreValueDocument, {
- input: { key: 'test.userAndChannelSetting', value: 'test2-test' },
- });
- // Verify all combinations maintain separate values
- const { getSettingsStoreValue: test2TestValue } = await adminClient.query(
- getSettingsStoreValueDocument,
- {
- key: 'test.userAndChannelSetting',
- },
- );
- expect(test2TestValue).toBe('test2-test');
- // Switch back to superadmin in test channel
- await adminClient.asSuperAdmin();
- adminClient.setChannelToken(testChannelToken);
- const { getSettingsStoreValue: superadminTestValue } = await adminClient.query(
- getSettingsStoreValueDocument,
- {
- key: 'test.userAndChannelSetting',
- },
- );
- expect(superadminTestValue).toBe('superadmin-test');
- // Switch to default channel
- adminClient.setChannelToken(E2E_DEFAULT_CHANNEL_TOKEN);
- const { getSettingsStoreValue: superadminDefaultValue } = await adminClient.query(
- getSettingsStoreValueDocument,
- {
- key: 'test.userAndChannelSetting',
- },
- );
- expect(superadminDefaultValue).toBe('superadmin-default');
- });
- });
- describe('Bulk operations', () => {
- it('should get multiple values', async () => {
- await adminClient.asSuperAdmin();
- adminClient.setChannelToken(E2E_DEFAULT_CHANNEL_TOKEN);
- const result = await adminClient.query(getSettingsStoreValuesDocument, {
- keys: ['test.globalSetting', 'test.userSetting'],
- });
- expect(result.getSettingsStoreValues).toEqual({
- 'test.globalSetting': 'global-value',
- 'test.userSetting': 'superadmin-value',
- });
- });
- it('should set multiple values', async () => {
- await adminClient.asSuperAdmin();
- const { setSettingsStoreValues } = await adminClient.query(setSettingsStoreValuesDocument, {
- inputs: [
- { key: 'test.bulk1', value: 'bulk-value-1' },
- { key: 'test.bulk2', value: 'bulk-value-2' },
- ],
- });
- expect(setSettingsStoreValues).toHaveLength(2);
- expect(setSettingsStoreValues[0].result).toBe(true);
- expect(setSettingsStoreValues[0].key).toBe('test.bulk1');
- expect(setSettingsStoreValues[1].result).toBe(true);
- expect(setSettingsStoreValues[1].key).toBe('test.bulk2');
- const result = await adminClient.query(getSettingsStoreValuesDocument, {
- keys: ['test.bulk1', 'test.bulk2'],
- });
- expect(result.getSettingsStoreValues).toEqual({
- 'test.bulk1': 'bulk-value-1',
- 'test.bulk2': 'bulk-value-2',
- });
- });
- });
- describe('Complex data types', () => {
- it('should handle JSON objects', async () => {
- await adminClient.asSuperAdmin();
- const complexData = {
- nested: {
- array: [1, 2, 3],
- boolean: true,
- null: null,
- },
- string: 'test',
- };
- await adminClient.query(setSettingsStoreValueDocument, {
- input: { key: 'test.complexData', value: complexData },
- });
- const { getSettingsStoreValue } = await adminClient.query(getSettingsStoreValueDocument, {
- key: 'test.complexData',
- });
- expect(getSettingsStoreValue).toEqual(complexData);
- });
- });
- describe('Validation', () => {
- it('should validate values according to field config', async () => {
- await adminClient.asSuperAdmin();
- // Try to set invalid theme value - should return structured error result
- const invalidResult = await adminClient.query(setSettingsStoreValueDocument, {
- input: { key: 'test.validatedField', value: 'invalid-value' },
- });
- expect(invalidResult.setSettingsStoreValue.result).toBe(false);
- expect(invalidResult.setSettingsStoreValue.key).toBe('test.validatedField');
- expect(invalidResult.setSettingsStoreValue.error).toContain('Validation failed');
- // Set valid value should work
- const { setSettingsStoreValue } = await adminClient.query(setSettingsStoreValueDocument, {
- input: { key: 'test.validatedField', value: 'valid-option' },
- });
- expect(setSettingsStoreValue.result).toBe(true);
- expect(setSettingsStoreValue.error).toBeNull();
- });
- });
- describe('Readonly fields', () => {
- it('should prevent modification of readonly fields', async () => {
- await adminClient.asSuperAdmin();
- const { setSettingsStoreValue } = await adminClient.query(setSettingsStoreValueDocument, {
- input: { key: 'test.readonlyField', value: 'attempt-change' },
- });
- expect(setSettingsStoreValue.result).toBe(false);
- expect(setSettingsStoreValue.key).toBe('test.readonlyField');
- expect(setSettingsStoreValue.error).toContain('readonly');
- });
- });
- describe('Permission handling', () => {
- it('should reject users without required permissions', async () => {
- await adminClient.asSuperAdmin();
- // Create a role with limited permissions (no CreateAdministrator permission)
- const { createRole } = await adminClient.query(createRoleDocument, {
- input: {
- code: 'limited-role',
- description: 'Limited permissions role',
- permissions: [Permission.Authenticated, Permission.ReadAdministrator], // No CreateAdministrator
- },
- });
- // Create a user with limited permissions
- await adminClient.query(createAdministratorDocument, {
- input: {
- firstName: 'Limited',
- lastName: 'User',
- emailAddress: 'limited@test.com',
- password: 'password',
- roleIds: [createRole.id],
- },
- });
- // Switch to limited user
- await adminClient.asUserWithCredentials('limited@test.com', 'password');
- // Try to access admin-only field - should get null (no access)
- const { getSettingsStoreValue: deniedValue } = await adminClient.query(
- getSettingsStoreValueDocument,
- {
- key: 'test.adminOnlyField',
- },
- );
- expect(deniedValue).toBeNull();
- // Try to set admin-only field - should return structured error result
- const { setSettingsStoreValue } = await adminClient.query(setSettingsStoreValueDocument, {
- input: { key: 'test.adminOnlyField', value: 'denied-value' },
- });
- expect(setSettingsStoreValue.result).toBe(false);
- expect(setSettingsStoreValue.key).toBe('test.adminOnlyField');
- expect(setSettingsStoreValue.error).toContain('Insufficient permissions');
- });
- it('should allow users with required permissions', async () => {
- await adminClient.asSuperAdmin();
- // SuperAdmin should have all permissions
- const { setSettingsStoreValue } = await adminClient.query(setSettingsStoreValueDocument, {
- input: { key: 'test.adminOnlyField', value: 'admin-value' },
- });
- expect(setSettingsStoreValue.result).toBe(true);
- expect(setSettingsStoreValue.key).toBe('test.adminOnlyField');
- expect(setSettingsStoreValue.error).toBeNull();
- const { getSettingsStoreValue } = await adminClient.query(getSettingsStoreValueDocument, {
- key: 'test.adminOnlyField',
- });
- expect(getSettingsStoreValue).toBe('admin-value');
- });
- });
- describe('Invalid key handling', () => {
- it('should gracefully handle getting invalid keys', async () => {
- await adminClient.asSuperAdmin();
- try {
- await adminClient.query(getSettingsStoreValueDocument, {
- key: 'invalid.nonExistentKey',
- });
- expect.fail('Should have thrown an error for invalid key');
- } catch (error) {
- expect((error as Error).message).toContain('not registered');
- }
- });
- it('should gracefully handle setting invalid keys', async () => {
- await adminClient.asSuperAdmin();
- const { setSettingsStoreValue } = await adminClient.query(setSettingsStoreValueDocument, {
- input: { key: 'invalid.nonExistentKey', value: 'some-value' },
- });
- expect(setSettingsStoreValue.result).toBe(false);
- expect(setSettingsStoreValue.key).toBe('invalid.nonExistentKey');
- expect(setSettingsStoreValue.error).toContain('not registered');
- });
- });
- describe('Bulk operations with mixed keys', () => {
- it('should handle bulk get with one valid, one invalid key', async () => {
- await adminClient.asSuperAdmin();
- try {
- await adminClient.query(getSettingsStoreValuesDocument, {
- keys: ['test.globalSetting', 'invalid.nonExistentKey'],
- });
- expect.fail('Should have thrown an error for invalid key in bulk operation');
- } catch (error) {
- expect((error as Error).message).toContain('not registered');
- }
- });
- it('should handle bulk set with one valid, one invalid key', async () => {
- await adminClient.asSuperAdmin();
- const { setSettingsStoreValues } = await adminClient.query(setSettingsStoreValuesDocument, {
- inputs: [
- { key: 'test.bulk1', value: 'valid-value' },
- { key: 'invalid.nonExistentKey', value: 'invalid-value' },
- ],
- });
- expect(setSettingsStoreValues).toHaveLength(2);
- expect(setSettingsStoreValues[0].result).toBe(true);
- expect(setSettingsStoreValues[0].key).toBe('test.bulk1');
- expect(setSettingsStoreValues[0].error).toBeNull();
- expect(setSettingsStoreValues[1].result).toBe(false);
- expect(setSettingsStoreValues[1].key).toBe('invalid.nonExistentKey');
- expect(setSettingsStoreValues[1].error).toContain('not registered');
- });
- it('should handle bulk operations with permission-restricted keys', async () => {
- await adminClient.asSuperAdmin();
- // First set a value as admin
- await adminClient.query(setSettingsStoreValueDocument, {
- input: { key: 'test.adminOnlyField', value: 'admin-bulk-value' },
- });
- // Switch to limited user
- await adminClient.asUserWithCredentials('limited@test.com', 'password');
- // Try bulk get with mix of accessible and restricted keys
- const { getSettingsStoreValues } = await adminClient.query(getSettingsStoreValuesDocument, {
- keys: ['test.globalSetting', 'test.adminOnlyField'],
- });
- // Should only return values for accessible keys
- expect(getSettingsStoreValues).toEqual({
- 'test.globalSetting': 'global-value',
- // adminOnlyField should be omitted due to permissions
- });
- // Try bulk set with mix of accessible and restricted keys
- const { setSettingsStoreValues } = await adminClient.query(setSettingsStoreValuesDocument, {
- inputs: [
- { key: 'test.globalSetting', value: 'new-global-value' },
- { key: 'test.adminOnlyField', value: 'denied-value' },
- ],
- });
- expect(setSettingsStoreValues).toHaveLength(2);
- expect(setSettingsStoreValues[0].result).toBe(true);
- expect(setSettingsStoreValues[0].key).toBe('test.globalSetting');
- expect(setSettingsStoreValues[0].error).toBeNull();
- expect(setSettingsStoreValues[1].result).toBe(false);
- expect(setSettingsStoreValues[1].key).toBe('test.adminOnlyField');
- expect(setSettingsStoreValues[1].error).toContain('Insufficient permissions');
- });
- });
- describe('Orphaned entries cleanup', () => {
- let settingsStoreService: SettingsStoreService;
- beforeAll(async () => {
- await adminClient.asSuperAdmin();
- // Get the SettingsStoreService directly from the application
- try {
- settingsStoreService = server.app.get(SettingsStoreService);
- } catch (error) {
- // eslint-disable-next-line no-console
- console.error('Failed to get SettingsStoreService:', error);
- // Try getting it from the service module
- settingsStoreService = server.app.get('SettingsStoreService');
- }
- });
- it('should identify orphaned entries', async () => {
- // Insert some orphaned entries directly into the database
- const connection = server.app.get(TransactionalConnection);
- const repo = connection.rawConnection.getRepository(SettingsStoreEntry);
- // Create entries with keys that don't have field definitions
- await repo.save([
- {
- key: 'orphaned.oldSetting1',
- value: 'old-value-1',
- scope: '',
- updatedAt: new Date(Date.now() - 8 * 24 * 60 * 60 * 1000), // 8 days ago
- },
- {
- key: 'orphaned.oldSetting2',
- value: { complex: 'object', array: [1, 2, 3] },
- scope: 'user:123',
- updatedAt: new Date(Date.now() - 10 * 24 * 60 * 60 * 1000), // 10 days ago
- },
- {
- key: 'orphaned.recentSetting',
- value: 'recent-value',
- scope: '',
- updatedAt: new Date(Date.now() - 1 * 24 * 60 * 60 * 1000), // 1 day ago
- },
- ]);
- // Test finding orphaned entries older than 7 days
- const orphanedEntries = await settingsStoreService.findOrphanedEntries({
- olderThan: '7d',
- maxDeleteCount: 100,
- });
- expect(orphanedEntries.length).toBe(2); // Should find the 8-day and 10-day old entries
- expect(orphanedEntries.map(e => e.key)).toEqual(
- expect.arrayContaining(['orphaned.oldSetting1', 'orphaned.oldSetting2']),
- );
- expect(orphanedEntries.find(e => e.key === 'orphaned.oldSetting1')?.scope).toBe('');
- expect(orphanedEntries.find(e => e.key === 'orphaned.oldSetting2')?.scope).toBe('user:123');
- expect(orphanedEntries.find(e => e.key === 'orphaned.oldSetting2')?.valuePreview).toContain(
- 'complex',
- );
- });
- it('should perform dry-run cleanup', async () => {
- const result = await settingsStoreService.cleanupOrphanedEntries({
- olderThan: '7d',
- dryRun: true,
- maxDeleteCount: 100,
- });
- expect(result.dryRun).toBe(true);
- expect(result.deletedCount).toBe(2); // Should find 2 entries to delete
- expect(result.deletedEntries.length).toBeLessThanOrEqual(10); // Sample entries
- // Verify entries are still in database (dry run shouldn't delete)
- const connection = server.app.get(TransactionalConnection);
- const repo = connection.rawConnection.getRepository(SettingsStoreEntry);
- const remainingEntries = await repo.find({
- where: [{ key: 'orphaned.oldSetting1' }, { key: 'orphaned.oldSetting2' }],
- });
- expect(remainingEntries.length).toBe(2);
- });
- it('should actually cleanup orphaned entries', async () => {
- const result = await settingsStoreService.cleanupOrphanedEntries({
- olderThan: '7d',
- dryRun: false,
- maxDeleteCount: 100,
- batchSize: 50,
- });
- expect(result.dryRun).toBe(false);
- expect(result.deletedCount).toBe(2);
- expect(result.deletedEntries.length).toBeLessThanOrEqual(10);
- // Verify entries are actually deleted from database
- const connection = server.app.get(TransactionalConnection);
- const repo = connection.rawConnection.getRepository(SettingsStoreEntry);
- const remainingEntries = await repo.find({
- where: [{ key: 'orphaned.oldSetting1' }, { key: 'orphaned.oldSetting2' }],
- });
- expect(remainingEntries.length).toBe(0);
- // Recent entry should still exist (not old enough)
- const recentEntry = await repo.findOne({ where: { key: 'orphaned.recentSetting' } });
- expect(recentEntry).not.toBeNull();
- });
- it('should respect age thresholds with ms package formats', async () => {
- // Create entries of different ages
- const connection = server.app.get(TransactionalConnection);
- const repo = connection.rawConnection.getRepository(SettingsStoreEntry);
- await repo.save([
- {
- key: 'orphaned.veryOld',
- value: 'very-old',
- scope: '',
- updatedAt: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000), // 30 days ago
- },
- {
- key: 'orphaned.somewhartOld',
- value: 'somewhat-old',
- scope: '',
- updatedAt: new Date(Date.now() - 5 * 24 * 60 * 60 * 1000), // 5 days ago
- },
- ]);
- // Test different ms package formats
- const old10d = await settingsStoreService.findOrphanedEntries({ olderThan: '10d' });
- expect(old10d.map(e => e.key)).toContain('orphaned.veryOld');
- expect(old10d.map(e => e.key)).not.toContain('orphaned.somewhartOld');
- const old3d = await settingsStoreService.findOrphanedEntries({ olderThan: '3 days' });
- expect(old3d.map(e => e.key)).toContain('orphaned.veryOld');
- expect(old3d.map(e => e.key)).toContain('orphaned.somewhartOld');
- const old1w = await settingsStoreService.findOrphanedEntries({ olderThan: '1w' });
- expect(old1w.map(e => e.key)).toContain('orphaned.veryOld');
- expect(old1w.map(e => e.key)).not.toContain('orphaned.somewhartOld');
- // Cleanup
- await settingsStoreService.cleanupOrphanedEntries({ olderThan: '1d' });
- });
- });
- });
|