import { PackageValidator } from '../../src/validator/package-validator'; import { CBFileSystem } from '../../src/node/file-system'; // Mock file system const mockFileSystem = { existsSync: jest.fn(), readdirSync: jest.fn(), mkdirSync: jest.fn(), unlinkSync: jest.fn(), rmdirSync: jest.fn(), statSync: jest.fn(), createWriteStream: jest.fn(), readFileSync: jest.fn(), writeFileSync: jest.fn(), copyFileSync: jest.fn(), lstatSync: jest.fn(), renameSync: jest.fn(), cpSync: jest.fn() } as jest.Mocked; describe('PackageValidator', () => { let packageValidator: PackageValidator; beforeEach(() => { jest.clearAllMocks(); packageValidator = new PackageValidator(mockFileSystem); }); describe('validateAppDirectoryExists', () => { it('should return true when directory exists', () => { mockFileSystem.existsSync.mockReturnValue(true); const result = packageValidator.validateAppDirectoryExists('/test-dir'); expect(result).toBe(true); expect(mockFileSystem.existsSync).toHaveBeenCalledWith('/test-dir'); }); it('should return false when directory does not exist', () => { mockFileSystem.existsSync.mockReturnValue(false); const result = packageValidator.validateAppDirectoryExists('/test-dir'); expect(result).toBe(false); expect(mockFileSystem.existsSync).toHaveBeenCalledWith('/test-dir'); }); it('should handle empty string path', () => { mockFileSystem.existsSync.mockReturnValue(false); const result = packageValidator.validateAppDirectoryExists(''); expect(result).toBe(false); expect(mockFileSystem.existsSync).toHaveBeenCalledWith(''); }); it('should handle null/undefined path', () => { mockFileSystem.existsSync.mockReturnValue(false); const result1 = packageValidator.validateAppDirectoryExists(null as any); const result2 = packageValidator.validateAppDirectoryExists(undefined as any); expect(result1).toBe(false); expect(result2).toBe(false); }); }); describe('validateManifestExists', () => { it('should return true when manifest.json exists', () => { mockFileSystem.existsSync.mockReturnValue(true); const result = packageValidator.validateManifestExists('/test-dir'); expect(result).toBe(true); expect(mockFileSystem.existsSync).toHaveBeenCalledWith('/test-dir/manifest.json'); }); it('should return false when manifest.json does not exist', () => { mockFileSystem.existsSync.mockReturnValue(false); const result = packageValidator.validateManifestExists('/test-dir'); expect(result).toBe(false); expect(mockFileSystem.existsSync).toHaveBeenCalledWith('/test-dir/manifest.json'); }); it('should handle different directory paths', () => { const paths = ['/app', '/home/user/project', './local-project']; paths.forEach(path => { mockFileSystem.existsSync.mockReturnValue(true); const result = packageValidator.validateManifestExists(path); expect(result).toBe(true); // path.join handles the path correctly expect(mockFileSystem.existsSync).toHaveBeenCalledWith(expect.stringContaining('manifest.json')); }); }); it('should handle empty directory path', () => { mockFileSystem.existsSync.mockReturnValue(false); const result = packageValidator.validateManifestExists(''); expect(result).toBe(false); expect(mockFileSystem.existsSync).toHaveBeenCalledWith('manifest.json'); }); }); describe('validateHandlerExists', () => { it('should return true when handler.js exists', () => { mockFileSystem.existsSync.mockReturnValue(true); const result = packageValidator.validateHandlerExists('/test-dir'); expect(result).toBe(true); expect(mockFileSystem.existsSync).toHaveBeenCalledWith('/test-dir/handler/handler.js'); }); it('should return false when handler.js does not exist', () => { mockFileSystem.existsSync.mockReturnValue(false); const result = packageValidator.validateHandlerExists('/test-dir'); expect(result).toBe(false); expect(mockFileSystem.existsSync).toHaveBeenCalledWith('/test-dir/handler/handler.js'); }); it('should handle different directory paths', () => { const paths = ['/app', '/home/user/project', './local-project']; paths.forEach(path => { mockFileSystem.existsSync.mockReturnValue(true); const result = packageValidator.validateHandlerExists(path); expect(result).toBe(true); // path.join handles the path correctly expect(mockFileSystem.existsSync).toHaveBeenCalledWith(expect.stringContaining('handler/handler.js')); }); }); it('should handle empty directory path', () => { mockFileSystem.existsSync.mockReturnValue(false); const result = packageValidator.validateHandlerExists(''); expect(result).toBe(false); expect(mockFileSystem.existsSync).toHaveBeenCalledWith('handler/handler.js'); }); }); describe('integration scenarios', () => { it('should validate complete app structure', () => { // Setup: all required components exist mockFileSystem.existsSync.mockImplementation((path: string) => { return path === '/complete-app' || path === '/complete-app/manifest.json' || path === '/complete-app/handler/handler.js'; }); const appExists = packageValidator.validateAppDirectoryExists('/complete-app'); const manifestExists = packageValidator.validateManifestExists('/complete-app'); const handlerExists = packageValidator.validateHandlerExists('/complete-app'); expect(appExists).toBe(true); expect(manifestExists).toBe(true); expect(handlerExists).toBe(true); }); it('should handle incomplete app structure', () => { // Setup: app exists but missing manifest and handler mockFileSystem.existsSync.mockImplementation((path: string) => { return path === '/incomplete-app'; }); const appExists = packageValidator.validateAppDirectoryExists('/incomplete-app'); const manifestExists = packageValidator.validateManifestExists('/incomplete-app'); const handlerExists = packageValidator.validateHandlerExists('/incomplete-app'); expect(appExists).toBe(true); expect(manifestExists).toBe(false); expect(handlerExists).toBe(false); }); it('should handle non-existent app', () => { mockFileSystem.existsSync.mockReturnValue(false); const appExists = packageValidator.validateAppDirectoryExists('/non-existent'); const manifestExists = packageValidator.validateManifestExists('/non-existent'); const handlerExists = packageValidator.validateHandlerExists('/non-existent'); expect(appExists).toBe(false); expect(manifestExists).toBe(false); expect(handlerExists).toBe(false); }); }); describe('error handling', () => { it('should handle file system errors gracefully', () => { mockFileSystem.existsSync.mockImplementation(() => { throw new Error('File system error'); }); expect(() => packageValidator.validateAppDirectoryExists('/test-dir')).toThrow('File system error'); expect(() => packageValidator.validateManifestExists('/test-dir')).toThrow('File system error'); expect(() => packageValidator.validateHandlerExists('/test-dir')).toThrow('File system error'); }); }); });