160 lines
4.7 KiB
TypeScript
160 lines
4.7 KiB
TypeScript
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
import { stripSystemdSupervisorEnv } from '@electron/gateway/config-sync-env';
|
|
|
|
const {
|
|
mockEnsureCloudSyncPluginInstalled,
|
|
mockReadOpenClawConfig,
|
|
mockWriteOpenClawConfig,
|
|
mockLoggerWarn,
|
|
} = vi.hoisted(() => ({
|
|
mockEnsureCloudSyncPluginInstalled: vi.fn(),
|
|
mockReadOpenClawConfig: vi.fn(),
|
|
mockWriteOpenClawConfig: vi.fn(),
|
|
mockLoggerWarn: vi.fn(),
|
|
}));
|
|
|
|
vi.mock('@electron/utils/plugin-install', () => ({
|
|
copyPluginFromNodeModules: vi.fn(),
|
|
cpSyncSafe: vi.fn(),
|
|
ensureCloudSyncPluginInstalled: mockEnsureCloudSyncPluginInstalled,
|
|
fixupPluginManifest: vi.fn(),
|
|
}));
|
|
|
|
vi.mock('@electron/utils/channel-config', () => ({
|
|
cleanupDanglingWeChatPluginState: vi.fn(),
|
|
listConfiguredChannelsFromConfig: vi.fn(() => []),
|
|
readOpenClawConfig: mockReadOpenClawConfig,
|
|
writeOpenClawConfig: mockWriteOpenClawConfig,
|
|
}));
|
|
|
|
vi.mock('@electron/utils/logger', () => ({
|
|
logger: {
|
|
info: vi.fn(),
|
|
warn: mockLoggerWarn,
|
|
error: vi.fn(),
|
|
debug: vi.fn(),
|
|
},
|
|
}));
|
|
|
|
describe('stripSystemdSupervisorEnv', () => {
|
|
it('removes systemd supervisor marker env vars', () => {
|
|
const env = {
|
|
PATH: '/usr/bin:/bin',
|
|
OPENCLAW_SYSTEMD_UNIT: 'openclaw-gateway.service',
|
|
INVOCATION_ID: 'abc123',
|
|
SYSTEMD_EXEC_PID: '777',
|
|
JOURNAL_STREAM: '8:12345',
|
|
OTHER: 'keep-me',
|
|
};
|
|
|
|
const result = stripSystemdSupervisorEnv(env);
|
|
|
|
expect(result).toEqual({
|
|
PATH: '/usr/bin:/bin',
|
|
OTHER: 'keep-me',
|
|
});
|
|
});
|
|
|
|
it('keeps unrelated variables unchanged', () => {
|
|
const env = {
|
|
NODE_ENV: 'production',
|
|
OPENCLAW_GATEWAY_TOKEN: 'token',
|
|
CLAWDBOT_SKIP_CHANNELS: '0',
|
|
};
|
|
|
|
expect(stripSystemdSupervisorEnv(env)).toEqual(env);
|
|
});
|
|
|
|
it('does not mutate source env object', () => {
|
|
const env = {
|
|
OPENCLAW_SYSTEMD_UNIT: 'openclaw-gateway.service',
|
|
VALUE: '1',
|
|
};
|
|
const before = { ...env };
|
|
|
|
const result = stripSystemdSupervisorEnv(env);
|
|
|
|
expect(env).toEqual(before);
|
|
expect(result).toEqual({ VALUE: '1' });
|
|
});
|
|
});
|
|
|
|
describe('Cloud Sync launch config', () => {
|
|
const originalEnv = process.env;
|
|
|
|
beforeEach(() => {
|
|
vi.resetModules();
|
|
vi.clearAllMocks();
|
|
process.env = { ...originalEnv };
|
|
delete process.env.YINIAN_CLOUD_SYNC_ENABLED;
|
|
delete process.env.YINIAN_CLOUD_SYNC_SERVER_URL;
|
|
delete process.env.CLOUDCLAW_SERVER_URL;
|
|
delete process.env.YINIAN_API_BASE_URL;
|
|
mockEnsureCloudSyncPluginInstalled.mockReturnValue({ installed: true });
|
|
mockReadOpenClawConfig.mockResolvedValue({});
|
|
mockWriteOpenClawConfig.mockResolvedValue(undefined);
|
|
});
|
|
|
|
afterEach(() => {
|
|
process.env = originalEnv;
|
|
});
|
|
|
|
it('derives the Cloud Sync server URL from explicit and API base env vars', async () => {
|
|
const { deriveCloudSyncServerUrl } = await import('@electron/gateway/config-sync');
|
|
|
|
expect(deriveCloudSyncServerUrl()).toBe('https://onefeel.brother7.cn');
|
|
|
|
process.env.YINIAN_API_BASE_URL = 'https://onefeel.brother7.cn/ingress/';
|
|
expect(deriveCloudSyncServerUrl()).toBe('https://onefeel.brother7.cn');
|
|
|
|
process.env.YINIAN_CLOUD_SYNC_SERVER_URL = ' https://cloud.example.com/// ';
|
|
expect(deriveCloudSyncServerUrl()).toBe('https://cloud.example.com');
|
|
});
|
|
|
|
it('writes the Cloud Sync plugin entry before Gateway launch', async () => {
|
|
process.env.YINIAN_API_BASE_URL = 'https://onefeel.brother7.cn/ingress';
|
|
mockReadOpenClawConfig.mockResolvedValue({
|
|
plugins: {
|
|
allow: ['existing-plugin'],
|
|
entries: {
|
|
'cloud-sync': {
|
|
enabled: false,
|
|
config: { keep: 'value' },
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
const { ensureCloudSyncPluginConfigured } = await import('@electron/gateway/config-sync');
|
|
await ensureCloudSyncPluginConfigured();
|
|
|
|
expect(mockEnsureCloudSyncPluginInstalled).toHaveBeenCalled();
|
|
expect(mockWriteOpenClawConfig).toHaveBeenCalledWith({
|
|
plugins: {
|
|
enabled: true,
|
|
allow: ['existing-plugin', 'cloud-sync'],
|
|
entries: {
|
|
'cloud-sync': {
|
|
enabled: true,
|
|
config: {
|
|
keep: 'value',
|
|
serverUrl: 'https://onefeel.brother7.cn',
|
|
},
|
|
},
|
|
},
|
|
},
|
|
});
|
|
});
|
|
|
|
it('does not touch plugin config when Cloud Sync is disabled', async () => {
|
|
process.env.YINIAN_CLOUD_SYNC_ENABLED = '0';
|
|
|
|
const { ensureCloudSyncPluginConfigured } = await import('@electron/gateway/config-sync');
|
|
await ensureCloudSyncPluginConfigured();
|
|
|
|
expect(mockEnsureCloudSyncPluginInstalled).not.toHaveBeenCalled();
|
|
expect(mockReadOpenClawConfig).not.toHaveBeenCalled();
|
|
expect(mockWriteOpenClawConfig).not.toHaveBeenCalled();
|
|
});
|
|
});
|