/ tests / unit / workspace / migration.test.ts
migration.test.ts
  1  /**
  2   * Tests for workspace migration utilities
  3   */
  4  
  5  import { describe, it, expect } from 'vitest';
  6  import {
  7    CURRENT_VERSION,
  8    needsMigration,
  9    getConfigVersion,
 10    migrateConfig,
 11    validateMigratedConfig,
 12  } from '../../../src/lib/workspace/migration';
 13  import { createDefaultConfig } from '../../../src/lib/types';
 14  
 15  describe('getConfigVersion', () => {
 16    it('returns 0 for null/undefined', () => {
 17      expect(getConfigVersion(null)).toBe(0);
 18      expect(getConfigVersion(undefined)).toBe(0);
 19    });
 20  
 21    it('returns 0 for non-object', () => {
 22      expect(getConfigVersion('string')).toBe(0);
 23      expect(getConfigVersion(123)).toBe(0);
 24    });
 25  
 26    it('returns 0 for object without version', () => {
 27      expect(getConfigVersion({})).toBe(0);
 28      expect(getConfigVersion({ foo: 'bar' })).toBe(0);
 29    });
 30  
 31    it('returns version from object', () => {
 32      expect(getConfigVersion({ version: 1 })).toBe(1);
 33      expect(getConfigVersion({ version: 5 })).toBe(5);
 34    });
 35  });
 36  
 37  describe('needsMigration', () => {
 38    it('returns true for null/undefined', () => {
 39      expect(needsMigration(null)).toBe(true);
 40      expect(needsMigration(undefined)).toBe(true);
 41    });
 42  
 43    it('returns true for old version', () => {
 44      expect(needsMigration({ version: 0 })).toBe(true);
 45      expect(needsMigration({ version: CURRENT_VERSION - 1 })).toBe(true);
 46    });
 47  
 48    it('returns false for current version', () => {
 49      expect(needsMigration({ version: CURRENT_VERSION })).toBe(false);
 50    });
 51  
 52    it('returns false for future version', () => {
 53      expect(needsMigration({ version: CURRENT_VERSION + 1 })).toBe(false);
 54    });
 55  });
 56  
 57  describe('migrateConfig', () => {
 58    it('updates version to current', () => {
 59      const oldConfig = { version: 0 };
 60      const migrated = migrateConfig(oldConfig);
 61      expect(migrated.version).toBe(CURRENT_VERSION);
 62    });
 63  
 64    it('preserves existing properties', () => {
 65      const oldConfig = {
 66        version: 0,
 67        customField: 'preserved',
 68      };
 69      const migrated = migrateConfig(oldConfig);
 70      expect((migrated as Record<string, unknown>).customField).toBe('preserved');
 71    });
 72  });
 73  
 74  describe('validateMigratedConfig', () => {
 75    it('returns no errors for valid config', () => {
 76      const config = createDefaultConfig();
 77      const errors = validateMigratedConfig(config);
 78      expect(errors).toHaveLength(0);
 79    });
 80  
 81    it('detects version mismatch', () => {
 82      const config = createDefaultConfig();
 83      config.version = 999;
 84      const errors = validateMigratedConfig(config);
 85      expect(errors.some((e) => e.includes('Version mismatch'))).toBe(true);
 86    });
 87  
 88    it('detects missing workspaces', () => {
 89      const config = createDefaultConfig();
 90      (config as Record<string, unknown>).workspaces = undefined;
 91      const errors = validateMigratedConfig(config);
 92      expect(errors.some((e) => e.includes('workspaces'))).toBe(true);
 93    });
 94  
 95    it('detects missing context', () => {
 96      const config = createDefaultConfig();
 97      (config as Record<string, unknown>).context = undefined;
 98      const errors = validateMigratedConfig(config);
 99      expect(errors.some((e) => e.includes('context'))).toBe(true);
100    });
101  
102    it('detects missing settings', () => {
103      const config = createDefaultConfig();
104      (config as Record<string, unknown>).settings = undefined;
105      const errors = validateMigratedConfig(config);
106      expect(errors.some((e) => e.includes('settings'))).toBe(true);
107    });
108  
109    it('detects missing metadata', () => {
110      const config = createDefaultConfig();
111      (config as Record<string, unknown>).metadata = undefined;
112      const errors = validateMigratedConfig(config);
113      expect(errors.some((e) => e.includes('metadata'))).toBe(true);
114    });
115  });