diff --git a/packages/core/src/InstanceSettings.ts b/packages/core/src/InstanceSettings.ts index 9332212edae9f..6802914c974ff 100644 --- a/packages/core/src/InstanceSettings.ts +++ b/packages/core/src/InstanceSettings.ts @@ -63,10 +63,11 @@ export class InstanceSettings { errorMessage: `Error parsing n8n-config file "${settingsFile}". It does not seem to be valid JSON.`, }); } else { + // Ensure that the `.n8n` folder exists + mkdirSync(this.n8nFolder, { recursive: true }); // If file doesn't exist, create new settings const encryptionKey = process.env.N8N_ENCRYPTION_KEY ?? randomBytes(24).toString('base64'); settings = { encryptionKey }; - mkdirSync(path.dirname(settingsFile)); this.save(settings); // console.info(`UserSettings were generated and saved to: ${settingsFile}`); } diff --git a/packages/core/test/InstanceSettings.test.ts b/packages/core/test/InstanceSettings.test.ts index 6d6e46ab9f883..05899e9c89490 100644 --- a/packages/core/test/InstanceSettings.test.ts +++ b/packages/core/test/InstanceSettings.test.ts @@ -4,13 +4,15 @@ import { InstanceSettings } from '@/InstanceSettings'; describe('InstanceSettings', () => { process.env.N8N_USER_FOLDER = '/test'; + const existSpy = jest.spyOn(fs, 'existsSync'); + beforeEach(() => jest.resetAllMocks()); + describe('If the settings file exists', () => { - beforeEach(() => { - jest.spyOn(fs, 'existsSync').mockReturnValue(true); - }); + const readSpy = jest.spyOn(fs, 'readFileSync'); + beforeEach(() => existSpy.mockReturnValue(true)); it('should load settings from the file', () => { - jest.spyOn(fs, 'readFileSync').mockReturnValue(JSON.stringify({ encryptionKey: 'test_key' })); + readSpy.mockReturnValue(JSON.stringify({ encryptionKey: 'test_key' })); const settings = new InstanceSettings(); expect(settings.encryptionKey).toEqual('test_key'); expect(settings.instanceId).toEqual( @@ -19,19 +21,24 @@ describe('InstanceSettings', () => { }); it('should throw error if settings file is not valid JSON', () => { - jest.spyOn(fs, 'readFileSync').mockReturnValue('{"encryptionKey":"test_key"'); + readSpy.mockReturnValue('{"encryptionKey":"test_key"'); expect(() => new InstanceSettings()).toThrowError(); }); }); describe('If the settings file does not exist', () => { + const mkdirSpy = jest.spyOn(fs, 'mkdirSync'); + const writeFileSpy = jest.spyOn(fs, 'writeFileSync'); + beforeEach(() => { + existSpy.mockReturnValue(false); + mkdirSpy.mockReturnValue(''); + writeFileSpy.mockReturnValue(); + }); + it('should create a new settings file', () => { - jest.spyOn(fs, 'existsSync').mockReturnValue(false); - const mkdirSpy = jest.spyOn(fs, 'mkdirSync').mockReturnValue(''); - const writeFileSpy = jest.spyOn(fs, 'writeFileSync').mockReturnValue(); const settings = new InstanceSettings(); expect(settings.encryptionKey).not.toEqual('test_key'); - expect(mkdirSpy).toHaveBeenCalledWith('/test/.n8n'); + expect(mkdirSpy).toHaveBeenCalledWith('/test/.n8n', { recursive: true }); expect(writeFileSpy).toHaveBeenCalledWith( '/test/.n8n/config', expect.stringContaining('"encryptionKey":'), @@ -41,16 +48,13 @@ describe('InstanceSettings', () => { it('should pick up the encryption key from env var N8N_ENCRYPTION_KEY', () => { process.env.N8N_ENCRYPTION_KEY = 'env_key'; - jest.spyOn(fs, 'existsSync').mockReturnValue(false); - const mkdirSpy = jest.spyOn(fs, 'mkdirSync').mockReturnValue(''); - const writeFileSpy = jest.spyOn(fs, 'writeFileSync').mockReturnValue(); const settings = new InstanceSettings(); expect(settings.encryptionKey).toEqual('env_key'); expect(settings.instanceId).toEqual( '2c70e12b7a0646f92279f427c7b38e7334d8e5389cff167a1dc30e73f826b683', ); expect(settings.encryptionKey).not.toEqual('test_key'); - expect(mkdirSpy).toHaveBeenCalledWith('/test/.n8n'); + expect(mkdirSpy).toHaveBeenCalledWith('/test/.n8n', { recursive: true }); expect(writeFileSpy).toHaveBeenCalledWith( '/test/.n8n/config', expect.stringContaining('"encryptionKey":'),