aboutsummaryrefslogtreecommitdiffstats
path: root/packages/main/src/controllers
diff options
context:
space:
mode:
Diffstat (limited to 'packages/main/src/controllers')
-rw-r--r--packages/main/src/controllers/__tests__/initConfig.spec.ts41
-rw-r--r--packages/main/src/controllers/initConfig.ts23
2 files changed, 52 insertions, 12 deletions
diff --git a/packages/main/src/controllers/__tests__/initConfig.spec.ts b/packages/main/src/controllers/__tests__/initConfig.spec.ts
index 11e7690..241ab2d 100644
--- a/packages/main/src/controllers/__tests__/initConfig.spec.ts
+++ b/packages/main/src/controllers/__tests__/initConfig.spec.ts
@@ -20,6 +20,7 @@
20 20
21import { jest } from '@jest/globals'; 21import { jest } from '@jest/globals';
22import { mocked } from 'jest-mock'; 22import { mocked } from 'jest-mock';
23import { getSnapshot } from 'mobx-state-tree';
23import ms from 'ms'; 24import ms from 'ms';
24 25
25import type ConfigPersistenceService from '../../services/ConfigPersistenceService'; 26import type ConfigPersistenceService from '../../services/ConfigPersistenceService';
@@ -74,6 +75,8 @@ describe('when initializing', () => {
74 mocked(persistenceService.readConfig).mockResolvedValueOnce({ 75 mocked(persistenceService.readConfig).mockResolvedValueOnce({
75 found: true, 76 found: true,
76 data: { 77 data: {
78 // Use a default empty config file to not trigger config rewrite.
79 ...getSnapshot(config),
77 themeSource: 'dark', 80 themeSource: 'dark',
78 }, 81 },
79 }); 82 });
@@ -95,7 +98,21 @@ describe('when initializing', () => {
95 }); 98 });
96 }); 99 });
97 100
98 it('should not apply an invalid config file', async () => { 101 it('should update the config file if new details are added during read', async () => {
102 mocked(persistenceService.readConfig).mockResolvedValueOnce({
103 found: true,
104 data: {
105 themeSource: 'light',
106 profile: {
107 name: 'Test profile',
108 },
109 },
110 });
111 await initConfig(config, persistenceService);
112 expect(persistenceService.writeConfig).toHaveBeenCalledTimes(1);
113 });
114
115 it('should not apply an invalid config file but should not overwrite it', async () => {
99 mocked(persistenceService.readConfig).mockResolvedValueOnce({ 116 mocked(persistenceService.readConfig).mockResolvedValueOnce({
100 found: true, 117 found: true,
101 data: { 118 data: {
@@ -104,6 +121,7 @@ describe('when initializing', () => {
104 }); 121 });
105 await initConfig(config, persistenceService); 122 await initConfig(config, persistenceService);
106 expect(config.themeSource).not.toBe(-1); 123 expect(config.themeSource).not.toBe(-1);
124 expect(persistenceService.writeConfig).not.toHaveBeenCalled();
107 }); 125 });
108 126
109 it('should bail if it cannot determine whether there is a config file', async () => { 127 it('should bail if it cannot determine whether there is a config file', async () => {
@@ -122,7 +140,7 @@ describe('when it has loaded the config', () => {
122 beforeEach(async () => { 140 beforeEach(async () => {
123 mocked(persistenceService.readConfig).mockResolvedValueOnce({ 141 mocked(persistenceService.readConfig).mockResolvedValueOnce({
124 found: true, 142 found: true,
125 data: {}, 143 data: getSnapshot(config),
126 }); 144 });
127 mocked(persistenceService.watchConfig).mockReturnValueOnce(watcherDisposer); 145 mocked(persistenceService.watchConfig).mockReturnValueOnce(watcherDisposer);
128 sutDisposer = await initConfig(config, persistenceService, throttleMs); 146 sutDisposer = await initConfig(config, persistenceService, throttleMs);
@@ -152,6 +170,8 @@ describe('when it has loaded the config', () => {
152 mocked(persistenceService.readConfig).mockResolvedValueOnce({ 170 mocked(persistenceService.readConfig).mockResolvedValueOnce({
153 found: true, 171 found: true,
154 data: { 172 data: {
173 // Use a default empty config file to not trigger config rewrite.
174 ...getSnapshot(config),
155 themeSource: 'dark', 175 themeSource: 'dark',
156 }, 176 },
157 }); 177 });
@@ -161,7 +181,21 @@ describe('when it has loaded the config', () => {
161 expect(config.themeSource).toBe('dark'); 181 expect(config.themeSource).toBe('dark');
162 }); 182 });
163 183
164 it('should not apply an invalid config file when it has changed', async () => { 184 it('should update the config file if new details are added', async () => {
185 mocked(persistenceService.readConfig).mockResolvedValueOnce({
186 found: true,
187 data: {
188 themeSource: 'light',
189 profile: {
190 name: 'Test profile',
191 },
192 },
193 });
194 await configChangedCallback();
195 expect(persistenceService.writeConfig).toHaveBeenCalledTimes(1);
196 });
197
198 it('should not apply an invalid config file when it has changed but should not overwrite it', async () => {
165 mocked(persistenceService.readConfig).mockResolvedValueOnce({ 199 mocked(persistenceService.readConfig).mockResolvedValueOnce({
166 found: true, 200 found: true,
167 data: { 201 data: {
@@ -170,6 +204,7 @@ describe('when it has loaded the config', () => {
170 }); 204 });
171 await configChangedCallback(); 205 await configChangedCallback();
172 expect(config.themeSource).not.toBe(-1); 206 expect(config.themeSource).not.toBe(-1);
207 expect(persistenceService.writeConfig).not.toHaveBeenCalled();
173 }); 208 });
174 209
175 it('should handle config reading errors gracefully', async () => { 210 it('should handle config reading errors gracefully', async () => {
diff --git a/packages/main/src/controllers/initConfig.ts b/packages/main/src/controllers/initConfig.ts
index 93be978..2dcabaf 100644
--- a/packages/main/src/controllers/initConfig.ts
+++ b/packages/main/src/controllers/initConfig.ts
@@ -18,12 +18,13 @@
18 * SPDX-License-Identifier: AGPL-3.0-only 18 * SPDX-License-Identifier: AGPL-3.0-only
19 */ 19 */
20 20
21import deepEqual from 'deep-equal';
21import { debounce } from 'lodash-es'; 22import { debounce } from 'lodash-es';
22import { getSnapshot, onSnapshot } from 'mobx-state-tree'; 23import { getSnapshot, onSnapshot } from 'mobx-state-tree';
23import ms from 'ms'; 24import ms from 'ms';
24 25
25import type ConfigPersistenceService from '../services/ConfigPersistenceService.js'; 26import type ConfigPersistenceService from '../services/ConfigPersistenceService';
26import { Config, ConfigFileIn, ConfigSnapshotOut } from '../stores/Config.js'; 27import { Config, ConfigFileIn, ConfigSnapshotOut } from '../stores/Config';
27import type Disposer from '../utils/Disposer'; 28import type Disposer from '../utils/Disposer';
28import { getLogger } from '../utils/log'; 29import { getLogger } from '../utils/log';
29 30
@@ -40,6 +41,12 @@ export default async function initConfig(
40 41
41 let lastSnapshotOnDisk: ConfigSnapshotOut | undefined; 42 let lastSnapshotOnDisk: ConfigSnapshotOut | undefined;
42 43
44 async function writeConfig(): Promise<void> {
45 const snapshot = getSnapshot(config);
46 await persistenceService.writeConfig(snapshot);
47 lastSnapshotOnDisk = snapshot;
48 }
49
43 async function readConfig(): Promise<boolean> { 50 async function readConfig(): Promise<boolean> {
44 const result = await persistenceService.readConfig(); 51 const result = await persistenceService.readConfig();
45 if (result.found) { 52 if (result.found) {
@@ -49,18 +56,16 @@ export default async function initConfig(
49 config.loadFromConfigFile(result.data as ConfigFileIn); 56 config.loadFromConfigFile(result.data as ConfigFileIn);
50 } catch (error) { 57 } catch (error) {
51 log.error('Failed to apply config snapshot', result.data, error); 58 log.error('Failed to apply config snapshot', result.data, error);
59 return true;
60 }
61 lastSnapshotOnDisk = getSnapshot(config);
62 if (!deepEqual(result.data, lastSnapshotOnDisk, { strict: true })) {
63 await writeConfig();
52 } 64 }
53 } 65 }
54 lastSnapshotOnDisk = getSnapshot(config);
55 return result.found; 66 return result.found;
56 } 67 }
57 68
58 async function writeConfig(): Promise<void> {
59 const snapshot = getSnapshot(config);
60 await persistenceService.writeConfig(snapshot);
61 lastSnapshotOnDisk = snapshot;
62 }
63
64 if (!(await readConfig())) { 69 if (!(await readConfig())) {
65 log.info('Config file was not found'); 70 log.info('Config file was not found');
66 await writeConfig(); 71 await writeConfig();