aboutsummaryrefslogtreecommitdiffstats
path: root/packages/main/src/stores
diff options
context:
space:
mode:
Diffstat (limited to 'packages/main/src/stores')
-rw-r--r--packages/main/src/stores/Config.ts58
-rw-r--r--packages/main/src/stores/GlobalSettings.ts38
-rw-r--r--packages/main/src/stores/MainStore.ts39
-rw-r--r--packages/main/src/stores/Profile.ts45
-rw-r--r--packages/main/src/stores/RuntimeService.ts74
-rw-r--r--packages/main/src/stores/Service.ts109
-rw-r--r--packages/main/src/stores/ServiceSettings.ts37
-rw-r--r--packages/main/src/stores/SharedStore.ts112
-rw-r--r--packages/main/src/stores/__tests__/SharedStore.spec.ts (renamed from packages/main/src/stores/__tests__/Config.spec.ts)52
9 files changed, 322 insertions, 242 deletions
diff --git a/packages/main/src/stores/Config.ts b/packages/main/src/stores/Config.ts
deleted file mode 100644
index e7fc360..0000000
--- a/packages/main/src/stores/Config.ts
+++ /dev/null
@@ -1,58 +0,0 @@
1/*
2 * Copyright (C) 2021-2022 Kristóf Marussy <kristof@marussy.com>
3 *
4 * This file is part of Sophie.
5 *
6 * Sophie is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as
8 * published by the Free Software Foundation, version 3.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 *
18 * SPDX-License-Identifier: AGPL-3.0-only
19 */
20
21import { config as originalConfig, ThemeSource } from '@sophie/shared';
22import { applySnapshot, Instance, SnapshotIn } from 'mobx-state-tree';
23
24import { addMissingProfileIds, PartialProfileSnapshotIn } from './Profile';
25import {
26 addMissingServiceIdsAndProfiles,
27 PartialServiceSnapshotIn,
28} from './Service';
29
30export const config = originalConfig.actions((self) => ({
31 loadFromConfigFile(snapshot: ConfigFileIn): void {
32 const profiles = addMissingProfileIds(snapshot.profiles);
33 const services = addMissingServiceIdsAndProfiles(
34 snapshot.services,
35 profiles,
36 );
37 applySnapshot(self, {
38 ...snapshot,
39 profiles,
40 services,
41 });
42 },
43 setThemeSource(mode: ThemeSource): void {
44 self.themeSource = mode;
45 },
46}));
47
48export interface Config extends Instance<typeof config> {}
49
50export interface ConfigSnapshotIn extends SnapshotIn<typeof config> {}
51
52export interface ConfigFileIn
53 extends Omit<ConfigSnapshotIn, 'profiles' | 'services'> {
54 profiles?: PartialProfileSnapshotIn[] | undefined;
55 services?: PartialServiceSnapshotIn[] | undefined;
56}
57
58export type { ConfigSnapshotOut } from '@sophie/shared';
diff --git a/packages/main/src/stores/GlobalSettings.ts b/packages/main/src/stores/GlobalSettings.ts
new file mode 100644
index 0000000..1eb13b3
--- /dev/null
+++ b/packages/main/src/stores/GlobalSettings.ts
@@ -0,0 +1,38 @@
1/*
2 * Copyright (C) 2022 Kristóf Marussy <kristof@marussy.com>
3 *
4 * This file is part of Sophie.
5 *
6 * Sophie is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as
8 * published by the Free Software Foundation, version 3.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 *
18 * SPDX-License-Identifier: AGPL-3.0-only
19 */
20
21import {
22 globalSettings as originalGlobalSettings,
23 ThemeSource,
24} from '@sophie/shared';
25import { Instance } from 'mobx-state-tree';
26
27export const globalSettings = originalGlobalSettings.actions((self) => ({
28 setThemeSource(mode: ThemeSource): void {
29 self.themeSource = mode;
30 },
31}));
32
33export interface GlobalSettings extends Instance<typeof globalSettings> {}
34
35export type {
36 GlobalSettingsSnapshotIn,
37 GlobalSettingsSnapshotOut,
38} from '@sophie/shared';
diff --git a/packages/main/src/stores/MainStore.ts b/packages/main/src/stores/MainStore.ts
index f0d6472..18f5bf9 100644
--- a/packages/main/src/stores/MainStore.ts
+++ b/packages/main/src/stores/MainStore.ts
@@ -18,21 +18,14 @@
18 * SPDX-License-Identifier: AGPL-3.0-only 18 * SPDX-License-Identifier: AGPL-3.0-only
19 */ 19 */
20 20
21import { BrowserViewBounds, service } from '@sophie/shared'; 21import type { BrowserViewBounds } from '@sophie/shared';
22import { 22import { applySnapshot, Instance, types } from 'mobx-state-tree';
23 applySnapshot,
24 Instance,
25 resolveIdentifier,
26 types,
27} from 'mobx-state-tree';
28 23
29import { getLogger } from '../utils/log'; 24import { GlobalSettings } from './GlobalSettings';
30 25import { Profile } from './Profile';
31import type { Config } from './Config.js'; 26import { Service } from './Service';
32import { sharedStore } from './SharedStore'; 27import { sharedStore } from './SharedStore';
33 28
34const log = getLogger('mainStore');
35
36export const mainStore = types 29export const mainStore = types
37 .model('MainStore', { 30 .model('MainStore', {
38 browserViewBounds: types.optional( 31 browserViewBounds: types.optional(
@@ -47,26 +40,20 @@ export const mainStore = types
47 shared: types.optional(sharedStore, {}), 40 shared: types.optional(sharedStore, {}),
48 }) 41 })
49 .views((self) => ({ 42 .views((self) => ({
50 get config(): Config { 43 get settings(): GlobalSettings {
51 return self.shared.config; 44 return self.shared.settings;
45 },
46 get profiles(): Profile[] {
47 return self.shared.profiles;
48 },
49 get services(): Service[] {
50 return self.shared.services;
52 }, 51 },
53 })) 52 }))
54 .actions((self) => ({ 53 .actions((self) => ({
55 setSelectedServiceId(serviceId: string): void {
56 const serviceInstance = resolveIdentifier(service, self, serviceId);
57 if (serviceInstance === undefined) {
58 log.warn('Trying to select unknown service', serviceId);
59 return;
60 }
61 self.shared.selectedService = serviceInstance;
62 log.debug('Selected service', serviceId);
63 },
64 setBrowserViewBounds(bounds: BrowserViewBounds): void { 54 setBrowserViewBounds(bounds: BrowserViewBounds): void {
65 applySnapshot(self.browserViewBounds, bounds); 55 applySnapshot(self.browserViewBounds, bounds);
66 }, 56 },
67 setShouldUseDarkColors(shouldUseDarkColors: boolean): void {
68 self.shared.shouldUseDarkColors = shouldUseDarkColors;
69 },
70 })); 57 }));
71 58
72export interface MainStore extends Instance<typeof mainStore> {} 59export interface MainStore extends Instance<typeof mainStore> {}
diff --git a/packages/main/src/stores/Profile.ts b/packages/main/src/stores/Profile.ts
index 4705862..eaf23c4 100644
--- a/packages/main/src/stores/Profile.ts
+++ b/packages/main/src/stores/Profile.ts
@@ -18,34 +18,39 @@
18 * SPDX-License-Identifier: AGPL-3.0-only 18 * SPDX-License-Identifier: AGPL-3.0-only
19 */ 19 */
20 20
21import type { ProfileSnapshotIn } from '@sophie/shared'; 21import {
22 profile as originalProfile,
23 ProfileSettingsSnapshotIn,
24} from '@sophie/shared';
25import { getSnapshot, Instance } from 'mobx-state-tree';
22 26
27import SettingsWithId from '../utils/SettingsWithId';
23import generateId from '../utils/generateId'; 28import generateId from '../utils/generateId';
24 29
25export interface PartialProfileSnapshotIn 30export interface ProfileConfig extends ProfileSettingsSnapshotIn {
26 extends Omit<ProfileSnapshotIn, 'id'> {
27 id?: string | undefined; 31 id?: string | undefined;
28} 32}
29 33
34export const profile = originalProfile.views((self) => ({
35 get config(): ProfileConfig {
36 const { id, settings } = self;
37 return { ...getSnapshot(settings), id };
38 },
39}));
40
41export interface Profile extends Instance<typeof profile> {}
42
43export type ProfileSettingsSnapshotWithId =
44 SettingsWithId<ProfileSettingsSnapshotIn>;
45
30export function addMissingProfileIds( 46export function addMissingProfileIds(
31 partialProfiles: PartialProfileSnapshotIn[] | undefined, 47 profileConfigs: ProfileConfig[] | undefined,
32): ProfileSnapshotIn[] { 48): ProfileSettingsSnapshotWithId[] {
33 return (partialProfiles ?? []).map((profile) => { 49 return (profileConfigs ?? []).map((profileConfig) => {
34 const { name } = profile; 50 const { id, ...settings } = profileConfig;
35 let { id } = profile;
36 if (typeof id === 'undefined') {
37 id = generateId(name);
38 }
39 return { 51 return {
40 ...profile, 52 id: typeof id === 'undefined' ? generateId(settings.name) : id,
41 id, 53 settings,
42 }; 54 };
43 }); 55 });
44} 56}
45
46export type {
47 Profile,
48 ProfileSnapshotOut,
49 ProfileSnapshotIn,
50} from '@sophie/shared';
51export { profile } from '@sophie/shared';
diff --git a/packages/main/src/stores/RuntimeService.ts b/packages/main/src/stores/RuntimeService.ts
deleted file mode 100644
index ecb1942..0000000
--- a/packages/main/src/stores/RuntimeService.ts
+++ /dev/null
@@ -1,74 +0,0 @@
1/*
2 * Copyright (C) 2022 Kristóf Marussy <kristof@marussy.com>
3 *
4 * This file is part of Sophie.
5 *
6 * Sophie is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as
8 * published by the Free Software Foundation, version 3.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 *
18 * SPDX-License-Identifier: AGPL-3.0-only
19 */
20
21import { UnreadCount } from '@sophie/service-shared';
22import { runtimeService as originalRuntimeService } from '@sophie/shared';
23import { Instance } from 'mobx-state-tree';
24
25export const runtimeService = originalRuntimeService.actions((self) => ({
26 setLocation({
27 url,
28 canGoBack,
29 canGoForward,
30 }: {
31 url: string;
32 canGoBack: boolean;
33 canGoForward: boolean;
34 }): void {
35 self.url = url;
36 self.canGoBack = canGoBack;
37 self.canGoForward = canGoForward;
38 },
39 setTitle(title: string): void {
40 self.title = title;
41 },
42 hibernated(): void {
43 self.canGoBack = false;
44 self.canGoForward = false;
45 self.state = 'hibernated';
46 },
47 startedLoading(): void {
48 self.state = 'loading';
49 },
50 finishedLoading(): void {
51 if (self.state === 'loading') {
52 // Do not overwrite crashed state if the service haven't been reloaded yet.
53 self.state = 'loaded';
54 }
55 },
56 crashed(): void {
57 self.state = 'crashed';
58 },
59 setUnreadCount({ direct, indirect }: UnreadCount): void {
60 if (direct !== undefined) {
61 self.directMessageCount = direct;
62 }
63 if (indirect !== undefined) {
64 self.indirectMessageCount = indirect;
65 }
66 },
67}));
68
69export interface RuntimeService extends Instance<typeof runtimeService> {}
70
71export type {
72 RuntimeServiceSnapshotIn,
73 RuntimeServiceSnapshotOut,
74} from '@sophie/shared';
diff --git a/packages/main/src/stores/Service.ts b/packages/main/src/stores/Service.ts
index 9bc6a43..78c57cb 100644
--- a/packages/main/src/stores/Service.ts
+++ b/packages/main/src/stores/Service.ts
@@ -18,46 +18,95 @@
18 * SPDX-License-Identifier: AGPL-3.0-only 18 * SPDX-License-Identifier: AGPL-3.0-only
19 */ 19 */
20 20
21import type { ServiceSnapshotIn } from '@sophie/shared'; 21import type { UnreadCount } from '@sophie/service-shared';
22import {
23 service as originalService,
24 ServiceSettingsSnapshotIn,
25} from '@sophie/shared';
26import { Instance, getSnapshot, ReferenceIdentifier } from 'mobx-state-tree';
22 27
28import SettingsWithId from '../utils/SettingsWithId';
23import generateId from '../utils/generateId'; 29import generateId from '../utils/generateId';
30import overrideProps from '../utils/overrideProps';
24 31
25import type { ProfileSnapshotIn } from './Profile'; 32import { ProfileSettingsSnapshotWithId } from './Profile';
33import { serviceSettings } from './ServiceSettings';
26 34
27export interface PartialServiceSnapshotIn 35export interface ServiceConfig
28 extends Omit<ServiceSnapshotIn, 'id' | 'profile'> { 36 extends Omit<ServiceSettingsSnapshotIn, 'profile'> {
29 id?: string | undefined; 37 id?: string | undefined;
30 profile?: string | undefined; 38
39 profile?: ReferenceIdentifier | undefined;
31} 40}
32 41
42export const service = overrideProps(originalService, {
43 settings: serviceSettings,
44})
45 .views((self) => ({
46 get config(): ServiceConfig {
47 const { id, settings } = self;
48 return { ...getSnapshot(settings), id };
49 },
50 }))
51 .actions((self) => ({
52 setLocation({
53 url,
54 canGoBack,
55 canGoForward,
56 }: {
57 url: string;
58 canGoBack: boolean;
59 canGoForward: boolean;
60 }): void {
61 self.currentUrl = url;
62 self.canGoBack = canGoBack;
63 self.canGoForward = canGoForward;
64 },
65 setTitle(title: string): void {
66 self.title = title;
67 },
68 startedLoading(): void {
69 self.state = 'loading';
70 },
71 finishedLoading(): void {
72 if (self.state === 'loading') {
73 // Do not overwrite crashed state if the service haven't been reloaded yet.
74 self.state = 'loaded';
75 }
76 },
77 crashed(): void {
78 self.state = 'crashed';
79 },
80 setUnreadCount({ direct, indirect }: UnreadCount): void {
81 if (direct !== undefined) {
82 self.directMessageCount = direct;
83 }
84 if (indirect !== undefined) {
85 self.indirectMessageCount = indirect;
86 }
87 },
88 }));
89
90export interface Service extends Instance<typeof service> {}
91
92export type ServiceSettingsSnapshotWithId =
93 SettingsWithId<ServiceSettingsSnapshotIn>;
94
33export function addMissingServiceIdsAndProfiles( 95export function addMissingServiceIdsAndProfiles(
34 partialServices: PartialServiceSnapshotIn[] | undefined, 96 serviceConfigs: ServiceConfig[] | undefined,
35 profiles: ProfileSnapshotIn[], 97 profiles: ProfileSettingsSnapshotWithId[],
36): ServiceSnapshotIn[] { 98): ServiceSettingsSnapshotWithId[] {
37 return (partialServices ?? []).map((service) => { 99 return (serviceConfigs ?? []).map((serviceConfig) => {
38 const { name } = service; 100 const { id, ...settings } = serviceConfig;
39 let { id, profile } = service; 101 const { name } = settings;
40 if (typeof id === 'undefined') { 102 let { profile: profileId } = settings;
41 id = generateId(name); 103 if (profileId === undefined) {
42 } 104 profileId = generateId(name);
43 if (typeof profile === 'undefined') { 105 profiles.push({ id: profileId, settings: { name } });
44 profile = generateId(name);
45 profiles.push({
46 id: profile,
47 name: service.name,
48 });
49 } 106 }
50 return { 107 return {
51 ...service, 108 id: id === undefined ? generateId(name) : id,
52 id, 109 settings: { ...settings, profile: profileId },
53 profile,
54 }; 110 };
55 }); 111 });
56} 112}
57
58export type {
59 Service,
60 ServiceSnapshotOut,
61 ServiceSnapshotIn,
62} from '@sophie/shared';
63export { service } from '@sophie/shared';
diff --git a/packages/main/src/stores/ServiceSettings.ts b/packages/main/src/stores/ServiceSettings.ts
new file mode 100644
index 0000000..960de9b
--- /dev/null
+++ b/packages/main/src/stores/ServiceSettings.ts
@@ -0,0 +1,37 @@
1/*
2 * Copyright (C) 2022 Kristóf Marussy <kristof@marussy.com>
3 *
4 * This file is part of Sophie.
5 *
6 * Sophie is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as
8 * published by the Free Software Foundation, version 3.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 *
18 * SPDX-License-Identifier: AGPL-3.0-only
19 */
20
21import { serviceSettings as originalServiceSettings } from '@sophie/shared';
22import { Instance, types } from 'mobx-state-tree';
23
24import overrideProps from '../utils/overrideProps';
25
26import { profile } from './Profile';
27
28export const serviceSettings = overrideProps(originalServiceSettings, {
29 profile: types.reference(profile),
30});
31
32export interface ServiceSettings extends Instance<typeof serviceSettings> {}
33
34export type {
35 ServiceSettingsSnapshotIn,
36 ServiceSettingsSnapshotOut,
37} from '@sophie/shared';
diff --git a/packages/main/src/stores/SharedStore.ts b/packages/main/src/stores/SharedStore.ts
index 76ce05c..861c8ce 100644
--- a/packages/main/src/stores/SharedStore.ts
+++ b/packages/main/src/stores/SharedStore.ts
@@ -19,19 +19,111 @@
19 */ 19 */
20 20
21import { sharedStore as originalSharedStore } from '@sophie/shared'; 21import { sharedStore as originalSharedStore } from '@sophie/shared';
22import { Instance, types } from 'mobx-state-tree'; 22import {
23 applySnapshot,
24 getSnapshot,
25 Instance,
26 resolveIdentifier,
27 types,
28} from 'mobx-state-tree';
23 29
24import { config } from './Config'; 30import SettingsWithId from '../utils/SettingsWithId';
25import { runtimeService } from './RuntimeService'; 31import { getLogger } from '../utils/log';
32import overrideProps from '../utils/overrideProps';
33
34import { globalSettings, GlobalSettingsSnapshotIn } from './GlobalSettings';
35import { addMissingProfileIds, profile, ProfileConfig } from './Profile';
36import {
37 addMissingServiceIdsAndProfiles,
38 service,
39 ServiceConfig,
40} from './Service';
41
42const log = getLogger('sharedStore');
43
44export interface Config extends GlobalSettingsSnapshotIn {
45 profiles?: ProfileConfig[] | undefined;
46
47 services?: ServiceConfig[] | undefined;
48}
49
50function getConfigs<T>(models: { config: T }[]): T[] | undefined {
51 return models.length === 0 ? undefined : models.map((model) => model.config);
52}
53
54function reconcileSettings<T>(
55 originalSnapshots: SettingsWithId<T>[],
56 settingsSnapshotsWithId: SettingsWithId<T>[],
57): SettingsWithId<T>[] {
58 const idToOriginalSnapshots = new Map(
59 originalSnapshots.map((originalSnapshot) => [
60 originalSnapshot.id,
61 originalSnapshot,
62 ]),
63 );
64 return settingsSnapshotsWithId.map(({ id, settings }) => ({
65 ...idToOriginalSnapshots.get(id),
66 id,
67 settings,
68 }));
69}
70
71export const sharedStore = overrideProps(originalSharedStore, {
72 settings: types.optional(globalSettings, {}),
73 profiles: types.array(profile),
74 services: types.array(service),
75 selectedService: types.safeReference(service),
76})
77 .views((self) => ({
78 get config(): Config {
79 const { settings, profiles, services } = self;
80 const globalSettingsConfig = getSnapshot(settings);
81 return {
82 ...globalSettingsConfig,
83 profiles: getConfigs(profiles),
84 services: getConfigs(services),
85 };
86 },
87 }))
88 .actions((self) => ({
89 loadConfig(config: Config): void {
90 const snapshot = getSnapshot(self);
91 const { profiles, services, ...settings } = config;
92 const profileSettingsSnapshots = addMissingProfileIds(profiles);
93 const serviceSettingsSnapshots = addMissingServiceIdsAndProfiles(
94 services,
95 profileSettingsSnapshots,
96 );
97 applySnapshot(self, {
98 ...snapshot,
99 settings,
100 profiles: reconcileSettings(
101 snapshot.profiles,
102 profileSettingsSnapshots,
103 ),
104 services: reconcileSettings(
105 snapshot.services,
106 serviceSettingsSnapshots,
107 ),
108 });
109 },
110 setShouldUseDarkColors(shouldUseDarkColors: boolean): void {
111 self.shouldUseDarkColors = shouldUseDarkColors;
112 },
113 setSelectedServiceId(serviceId: string): void {
114 const serviceInstance = resolveIdentifier(service, self, serviceId);
115 if (serviceInstance === undefined) {
116 log.warn('Trying to select unknown service', serviceId);
117 return;
118 }
119 self.selectedService = serviceInstance;
120 log.debug('Selected service', serviceId);
121 },
122 }));
123
124export interface SharedStore extends Instance<typeof sharedStore> {}
26 125
27export type { 126export type {
28 SharedStoreSnapshotIn, 127 SharedStoreSnapshotIn,
29 SharedStoreSnapshotOut, 128 SharedStoreSnapshotOut,
30} from '@sophie/shared'; 129} from '@sophie/shared';
31
32export const sharedStore = originalSharedStore.props({
33 config: types.optional(config, {}),
34 runtimeServices: types.map(runtimeService),
35});
36
37export interface SharedStore extends Instance<typeof sharedStore> {}
diff --git a/packages/main/src/stores/__tests__/Config.spec.ts b/packages/main/src/stores/__tests__/SharedStore.spec.ts
index 22ccbc7..3ea187c 100644
--- a/packages/main/src/stores/__tests__/Config.spec.ts
+++ b/packages/main/src/stores/__tests__/SharedStore.spec.ts
@@ -18,28 +18,28 @@
18 * SPDX-License-Identifier: AGPL-3.0-only 18 * SPDX-License-Identifier: AGPL-3.0-only
19 */ 19 */
20 20
21import { config, Config, ConfigFileIn } from '../Config'; 21import type { ProfileConfig } from '../Profile';
22import type { PartialProfileSnapshotIn } from '../Profile'; 22import type { ServiceConfig } from '../Service';
23import type { PartialServiceSnapshotIn } from '../Service'; 23import { Config, sharedStore, SharedStore } from '../SharedStore';
24 24
25const profileProps: PartialProfileSnapshotIn = { 25const profileProps: ProfileConfig = {
26 name: 'Test profile', 26 name: 'Test profile',
27}; 27};
28 28
29const serviceProps: PartialServiceSnapshotIn = { 29const serviceProps: ServiceConfig = {
30 name: 'Test service', 30 name: 'Test service',
31 url: 'https://example.com', 31 url: 'https://example.com',
32}; 32};
33 33
34let sut: Config; 34let sut: SharedStore;
35 35
36beforeEach(() => { 36beforeEach(() => {
37 sut = config.create(); 37 sut = sharedStore.create();
38}); 38});
39 39
40describe('preprocessConfigFile', () => { 40describe('loadConfig', () => {
41 it('should load profiles with an ID', () => { 41 it('should load profiles with an ID', () => {
42 sut.loadFromConfigFile({ 42 sut.loadConfig({
43 profiles: [ 43 profiles: [
44 { 44 {
45 id: 'someId', 45 id: 'someId',
@@ -51,14 +51,14 @@ describe('preprocessConfigFile', () => {
51 }); 51 });
52 52
53 it('should generate an ID for profiles without and ID', () => { 53 it('should generate an ID for profiles without and ID', () => {
54 sut.loadFromConfigFile({ 54 sut.loadConfig({
55 profiles: [profileProps], 55 profiles: [profileProps],
56 }); 56 });
57 expect(sut.profiles[0].id).toBeDefined(); 57 expect(sut.profiles[0].id).toBeDefined();
58 }); 58 });
59 59
60 it('should load services with an ID and a profile', () => { 60 it('should load services with an ID and a profile', () => {
61 sut.loadFromConfigFile({ 61 sut.loadConfig({
62 profiles: [ 62 profiles: [
63 { 63 {
64 id: 'someProfileId', 64 id: 'someProfileId',
@@ -74,12 +74,12 @@ describe('preprocessConfigFile', () => {
74 ], 74 ],
75 }); 75 });
76 expect(sut.services[0].id).toBe('someServiceId'); 76 expect(sut.services[0].id).toBe('someServiceId');
77 expect(sut.services[0].profile).toBe(sut.profiles[0]); 77 expect(sut.services[0].settings.profile).toBe(sut.profiles[0]);
78 }); 78 });
79 79
80 it('should refuse to load a profile without a name', () => { 80 it('should refuse to load a profile without a name', () => {
81 expect(() => { 81 expect(() => {
82 sut.loadFromConfigFile({ 82 sut.loadConfig({
83 profiles: [ 83 profiles: [
84 { 84 {
85 id: 'someProfileId', 85 id: 'someProfileId',
@@ -87,13 +87,13 @@ describe('preprocessConfigFile', () => {
87 name: undefined, 87 name: undefined,
88 }, 88 },
89 ], 89 ],
90 } as unknown as ConfigFileIn); 90 } as unknown as Config);
91 }).toThrow(); 91 }).toThrow();
92 expect(sut.profiles).toHaveLength(0); 92 expect(sut.profiles).toHaveLength(0);
93 }); 93 });
94 94
95 it('should load services without an ID but with a profile', () => { 95 it('should load services without an ID but with a profile', () => {
96 sut.loadFromConfigFile({ 96 sut.loadConfig({
97 profiles: [ 97 profiles: [
98 { 98 {
99 id: 'someProfileId', 99 id: 'someProfileId',
@@ -108,11 +108,11 @@ describe('preprocessConfigFile', () => {
108 ], 108 ],
109 }); 109 });
110 expect(sut.services[0].id).toBeDefined(); 110 expect(sut.services[0].id).toBeDefined();
111 expect(sut.services[0].profile).toBe(sut.profiles[0]); 111 expect(sut.services[0].settings.profile).toBe(sut.profiles[0]);
112 }); 112 });
113 113
114 it('should create a profile for a service with an ID but no profile', () => { 114 it('should create a profile for a service with an ID but no profile', () => {
115 sut.loadFromConfigFile({ 115 sut.loadConfig({
116 services: [ 116 services: [
117 { 117 {
118 id: 'someServiceId', 118 id: 'someServiceId',
@@ -121,12 +121,14 @@ describe('preprocessConfigFile', () => {
121 ], 121 ],
122 }); 122 });
123 expect(sut.services[0].id).toBe('someServiceId'); 123 expect(sut.services[0].id).toBe('someServiceId');
124 expect(sut.services[0].profile).toBeDefined(); 124 expect(sut.services[0].settings.profile).toBeDefined();
125 expect(sut.services[0].profile.name).toBe(serviceProps.name); 125 expect(sut.services[0].settings.profile.settings.name).toBe(
126 serviceProps.name,
127 );
126 }); 128 });
127 129
128 it('should create a profile for a service without an ID or profile', () => { 130 it('should create a profile for a service without an ID or profile', () => {
129 sut.loadFromConfigFile({ 131 sut.loadConfig({
130 services: [ 132 services: [
131 { 133 {
132 ...serviceProps, 134 ...serviceProps,
@@ -134,13 +136,15 @@ describe('preprocessConfigFile', () => {
134 ], 136 ],
135 }); 137 });
136 expect(sut.services[0].id).toBeDefined(); 138 expect(sut.services[0].id).toBeDefined();
137 expect(sut.services[0].profile).toBeDefined(); 139 expect(sut.services[0].settings.profile).toBeDefined();
138 expect(sut.services[0].profile.name).toBe(serviceProps.name); 140 expect(sut.services[0].settings.profile.settings.name).toBe(
141 serviceProps.name,
142 );
139 }); 143 });
140 144
141 it('should refuse to load a service without a name', () => { 145 it('should refuse to load a service without a name', () => {
142 expect(() => { 146 expect(() => {
143 sut.loadFromConfigFile({ 147 sut.loadConfig({
144 services: [ 148 services: [
145 { 149 {
146 id: 'someServiceId', 150 id: 'someServiceId',
@@ -148,7 +152,7 @@ describe('preprocessConfigFile', () => {
148 name: undefined, 152 name: undefined,
149 }, 153 },
150 ], 154 ],
151 } as unknown as ConfigFileIn); 155 } as unknown as Config);
152 }).toThrow(); 156 }).toThrow();
153 expect(sut.profiles).toHaveLength(0); 157 expect(sut.profiles).toHaveLength(0);
154 expect(sut.services).toHaveLength(0); 158 expect(sut.services).toHaveLength(0);