diff options
-rw-r--r-- | jest.config.js | 2 | ||||
-rw-r--r-- | jest.integ.config.cjs | 2 | ||||
-rw-r--r-- | packages/shared/src/stores/SharedStoreBase.ts | 24 | ||||
-rw-r--r-- | packages/shared/src/stores/__tests__/ServiceBase.test.ts | 46 | ||||
-rw-r--r-- | packages/shared/src/stores/__tests__/SharedStoreBase.test.ts | 76 | ||||
-rw-r--r-- | packages/shared/src/stores/__tests__/__fixtures__/serviceFixtures.ts | 63 |
6 files changed, 162 insertions, 51 deletions
diff --git a/jest.config.js b/jest.config.js index 3e1f9ce..be24800 100644 --- a/jest.config.js +++ b/jest.config.js | |||
@@ -1,7 +1,7 @@ | |||
1 | /** @type {import('@jest/types').Config.InitialOptions} */ | 1 | /** @type {import('@jest/types').Config.InitialOptions} */ |
2 | export default { | 2 | export default { |
3 | projects: ['<rootDir>/packages/*/jest.config.js'], | 3 | projects: ['<rootDir>/packages/*/jest.config.js'], |
4 | collectCoverageFrom: ['**/*.{ts,tsx}'], | 4 | collectCoverageFrom: ['**/*.{ts,tsx}', '!**/__fixtures__/**/*'], |
5 | /** @type {'v8'} */ | 5 | /** @type {'v8'} */ |
6 | coverageProvider: 'v8', | 6 | coverageProvider: 'v8', |
7 | /** @type {['cobertura', 'text']} */ | 7 | /** @type {['cobertura', 'text']} */ |
diff --git a/jest.integ.config.cjs b/jest.integ.config.cjs index dcb3a04..b9411bc 100644 --- a/jest.integ.config.cjs +++ b/jest.integ.config.cjs | |||
@@ -1,7 +1,7 @@ | |||
1 | /** @type {import('@jest/types').Config.InitialOptions} */ | 1 | /** @type {import('@jest/types').Config.InitialOptions} */ |
2 | module.exports = { | 2 | module.exports = { |
3 | projects: ['<rootDir>/packages/*/jest.integ.config.cjs'], | 3 | projects: ['<rootDir>/packages/*/jest.integ.config.cjs'], |
4 | collectCoverageFrom: ['**/*.{ts,tsx}'], | 4 | collectCoverageFrom: ['**/*.{ts,tsx}', '!**/__fixtures__/**/*'], |
5 | /** @type {'v8'} */ | 5 | /** @type {'v8'} */ |
6 | coverageProvider: 'v8', | 6 | coverageProvider: 'v8', |
7 | /** @type {['cobertura', 'text']} */ | 7 | /** @type {['cobertura', 'text']} */ |
diff --git a/packages/shared/src/stores/SharedStoreBase.ts b/packages/shared/src/stores/SharedStoreBase.ts index 4526c95..786dc5f 100644 --- a/packages/shared/src/stores/SharedStoreBase.ts +++ b/packages/shared/src/stores/SharedStoreBase.ts | |||
@@ -19,12 +19,12 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | import { | 21 | import { |
22 | IJsonPatch, | 22 | type IJsonPatch, |
23 | Instance, | 23 | type Instance, |
24 | types, | 24 | types, |
25 | SnapshotIn, | 25 | type SnapshotIn, |
26 | SnapshotOut, | 26 | type SnapshotOut, |
27 | IAnyModelType, | 27 | type IAnyModelType, |
28 | } from 'mobx-state-tree'; | 28 | } from 'mobx-state-tree'; |
29 | 29 | ||
30 | import GlobalSettingsBase from './GlobalSettingsBase.js'; | 30 | import GlobalSettingsBase from './GlobalSettingsBase.js'; |
@@ -51,6 +51,10 @@ export function defineSharedStoreModel< | |||
51 | writingDirection: types.optional(WritingDirection, 'ltr'), | 51 | writingDirection: types.optional(WritingDirection, 'ltr'), |
52 | }) | 52 | }) |
53 | .views((self) => ({ | 53 | .views((self) => ({ |
54 | get alwaysHideLocationBar(): boolean { | ||
55 | const settings = self.settings as GlobalSettingsBase; | ||
56 | return settings.selectedService === undefined; | ||
57 | }, | ||
54 | get alwaysShowLocationBar(): boolean { | 58 | get alwaysShowLocationBar(): boolean { |
55 | const settings = self.settings as GlobalSettingsBase; | 59 | const settings = self.settings as GlobalSettingsBase; |
56 | const selectedService = settings.selectedService as | 60 | const selectedService = settings.selectedService as |
@@ -62,14 +66,14 @@ export function defineSharedStoreModel< | |||
62 | .views((self) => ({ | 66 | .views((self) => ({ |
63 | get locationBarVisible(): boolean { | 67 | get locationBarVisible(): boolean { |
64 | const settings = self.settings as GlobalSettingsBase; | 68 | const settings = self.settings as GlobalSettingsBase; |
65 | return settings.showLocationBar || self.alwaysShowLocationBar; | ||
66 | }, | ||
67 | get canToggleLocationBar(): boolean { | ||
68 | return ( | 69 | return ( |
69 | !self.alwaysShowLocationBar && | 70 | !self.alwaysHideLocationBar && |
70 | self.settings.selectedService !== undefined | 71 | (self.alwaysShowLocationBar || settings.showLocationBar) |
71 | ); | 72 | ); |
72 | }, | 73 | }, |
74 | get canToggleLocationBar(): boolean { | ||
75 | return !(self.alwaysHideLocationBar || self.alwaysShowLocationBar); | ||
76 | }, | ||
73 | })); | 77 | })); |
74 | } | 78 | } |
75 | 79 | ||
diff --git a/packages/shared/src/stores/__tests__/ServiceBase.test.ts b/packages/shared/src/stores/__tests__/ServiceBase.test.ts index e2b0aa9..2fc9cbc 100644 --- a/packages/shared/src/stores/__tests__/ServiceBase.test.ts +++ b/packages/shared/src/stores/__tests__/ServiceBase.test.ts | |||
@@ -20,49 +20,15 @@ | |||
20 | 20 | ||
21 | import type { SnapshotIn } from 'mobx-state-tree'; | 21 | import type { SnapshotIn } from 'mobx-state-tree'; |
22 | 22 | ||
23 | import Certificate from '../Certificate.js'; | ||
24 | import Profile from '../Profile.js'; | ||
25 | import ServiceBase, { SecurityLabelKind } from '../ServiceBase.js'; | 23 | import ServiceBase, { SecurityLabelKind } from '../ServiceBase.js'; |
26 | import type { ServiceStateSnapshotIn } from '../ServiceState.js'; | 24 | import type { ServiceStateSnapshotIn } from '../ServiceState.js'; |
27 | import SharedStoreBase from '../SharedStoreBase.js'; | 25 | import SharedStoreBase from '../SharedStoreBase.js'; |
28 | 26 | ||
29 | const testProfile: SnapshotIn<typeof Profile> = { | 27 | import { |
30 | id: 'testProfile', | 28 | testCertificate, |
31 | settings: { | 29 | testProfile, |
32 | name: 'test profile', | 30 | testService, |
33 | }, | 31 | } from './__fixtures__/serviceFixtures.js'; |
34 | }; | ||
35 | |||
36 | const testService: SnapshotIn<typeof ServiceBase> = { | ||
37 | id: 'testService', | ||
38 | settings: { | ||
39 | name: 'testService', | ||
40 | url: 'https://example.org', | ||
41 | profile: 'testProfile', | ||
42 | }, | ||
43 | }; | ||
44 | |||
45 | const testCertificate: SnapshotIn<typeof Certificate> = { | ||
46 | data: '-----TEST DATA-----', | ||
47 | issuer: { | ||
48 | commonName: 'Test issuer', | ||
49 | country: '', | ||
50 | state: '', | ||
51 | locality: '', | ||
52 | }, | ||
53 | issuerName: 'Test issuer', | ||
54 | subject: { | ||
55 | commonName: 'Test subject', | ||
56 | country: '', | ||
57 | state: '', | ||
58 | locality: '', | ||
59 | }, | ||
60 | subjectName: 'Test subject', | ||
61 | serialNumber: '123456', | ||
62 | validStart: 1_653_551_516, | ||
63 | validExpiry: 1_685_087_516, | ||
64 | fingerprint: 'sha256/KUIHdVkSTzYmb2PGMotOPDm2ir52G1QyPW6rt6wUjZ0=', | ||
65 | }; | ||
66 | 32 | ||
67 | function createTestService( | 33 | function createTestService( |
68 | snapshot: Partial<SnapshotIn<typeof ServiceBase>>, | 34 | snapshot: Partial<SnapshotIn<typeof ServiceBase>>, |
@@ -166,6 +132,7 @@ test.each([ | |||
166 | const service = createTestService({ currentUrl: url }); | 132 | const service = createTestService({ currentUrl: url }); |
167 | 133 | ||
168 | expect(service.securityLabel).toBe(labelKind); | 134 | expect(service.securityLabel).toBe(labelKind); |
135 | expect(service.hasSecurityLabelWarning).toBe(hasWarning); | ||
169 | expect(service.alwaysShowLocationBar).toBe(hasWarning); | 136 | expect(service.alwaysShowLocationBar).toBe(hasWarning); |
170 | }, | 137 | }, |
171 | ); | 138 | ); |
@@ -181,5 +148,6 @@ test('shows a certificate error warning if there is a certificate error', () => | |||
181 | }); | 148 | }); |
182 | 149 | ||
183 | expect(service.securityLabel).toBe(SecurityLabelKind.CertificateError); | 150 | expect(service.securityLabel).toBe(SecurityLabelKind.CertificateError); |
151 | expect(service.hasSecurityLabelWarning).toBe(true); | ||
184 | expect(service.alwaysShowLocationBar).toBe(true); | 152 | expect(service.alwaysShowLocationBar).toBe(true); |
185 | }); | 153 | }); |
diff --git a/packages/shared/src/stores/__tests__/SharedStoreBase.test.ts b/packages/shared/src/stores/__tests__/SharedStoreBase.test.ts new file mode 100644 index 0000000..64f5c6b --- /dev/null +++ b/packages/shared/src/stores/__tests__/SharedStoreBase.test.ts | |||
@@ -0,0 +1,76 @@ | |||
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 | |||
21 | import { unprotect } from 'mobx-state-tree'; | ||
22 | |||
23 | import SharedStoreBase from '../SharedStoreBase.js'; | ||
24 | |||
25 | import { testProfile, testService } from './__fixtures__/serviceFixtures.js'; | ||
26 | |||
27 | describe.each([true, false])( | ||
28 | 'when showLocationBar is %j', | ||
29 | (showLocationBar) => { | ||
30 | test('hides the location bar if there is no selected service', () => { | ||
31 | const sharedStore = SharedStoreBase.create({ | ||
32 | settings: { showLocationBar }, | ||
33 | }); | ||
34 | |||
35 | expect(sharedStore.alwaysHideLocationBar).toBe(true); | ||
36 | expect(sharedStore.alwaysShowLocationBar).toBe(false); | ||
37 | expect(sharedStore.locationBarVisible).toBe(false); | ||
38 | expect(sharedStore.canToggleLocationBar).toBe(false); | ||
39 | }); | ||
40 | |||
41 | describe('and there is a selected service', () => { | ||
42 | let sharedStore: SharedStoreBase; | ||
43 | |||
44 | beforeEach(() => { | ||
45 | sharedStore = SharedStoreBase.create({ | ||
46 | settings: { | ||
47 | selectedService: testService.id, | ||
48 | showLocationBar, | ||
49 | }, | ||
50 | profilesById: { testProfile }, | ||
51 | servicesById: { testService }, | ||
52 | }); | ||
53 | }); | ||
54 | |||
55 | test('shows the location bar if requested by the user', () => { | ||
56 | expect(sharedStore.alwaysHideLocationBar).toBe(false); | ||
57 | expect(sharedStore.alwaysShowLocationBar).toBe(false); | ||
58 | expect(sharedStore.locationBarVisible).toBe(showLocationBar); | ||
59 | expect(sharedStore.canToggleLocationBar).toBe(true); | ||
60 | }); | ||
61 | |||
62 | test('show the location bar if forced by the service', () => { | ||
63 | unprotect(sharedStore); | ||
64 | const service = sharedStore.settings.selectedService!; | ||
65 | Object.defineProperty(service, 'alwaysShowLocationBar', { | ||
66 | value: true, | ||
67 | }); | ||
68 | |||
69 | expect(sharedStore.alwaysHideLocationBar).toBe(false); | ||
70 | expect(sharedStore.alwaysShowLocationBar).toBe(true); | ||
71 | expect(sharedStore.locationBarVisible).toBe(true); | ||
72 | expect(sharedStore.canToggleLocationBar).toBe(false); | ||
73 | }); | ||
74 | }); | ||
75 | }, | ||
76 | ); | ||
diff --git a/packages/shared/src/stores/__tests__/__fixtures__/serviceFixtures.ts b/packages/shared/src/stores/__tests__/__fixtures__/serviceFixtures.ts new file mode 100644 index 0000000..33e2f90 --- /dev/null +++ b/packages/shared/src/stores/__tests__/__fixtures__/serviceFixtures.ts | |||
@@ -0,0 +1,63 @@ | |||
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 | |||
21 | import type { SnapshotIn } from 'mobx-state-tree'; | ||
22 | |||
23 | import type Certificate from '../../Certificate.js'; | ||
24 | import type Profile from '../../Profile.js'; | ||
25 | import type ServiceBase from '../../ServiceBase.js'; | ||
26 | |||
27 | export const testProfile: SnapshotIn<typeof Profile> = { | ||
28 | id: 'testProfile', | ||
29 | settings: { | ||
30 | name: 'test profile', | ||
31 | }, | ||
32 | }; | ||
33 | |||
34 | export const testService: SnapshotIn<typeof ServiceBase> = { | ||
35 | id: 'testService', | ||
36 | settings: { | ||
37 | name: 'testService', | ||
38 | url: 'https://example.org', | ||
39 | profile: testProfile.id, | ||
40 | }, | ||
41 | }; | ||
42 | |||
43 | export const testCertificate: SnapshotIn<typeof Certificate> = { | ||
44 | data: '-----TEST DATA-----', | ||
45 | issuer: { | ||
46 | commonName: 'Test issuer', | ||
47 | country: '', | ||
48 | state: '', | ||
49 | locality: '', | ||
50 | }, | ||
51 | issuerName: 'Test issuer', | ||
52 | subject: { | ||
53 | commonName: 'Test subject', | ||
54 | country: '', | ||
55 | state: '', | ||
56 | locality: '', | ||
57 | }, | ||
58 | subjectName: 'Test subject', | ||
59 | serialNumber: '123456', | ||
60 | validStart: 1_653_551_516, | ||
61 | validExpiry: 1_685_087_516, | ||
62 | fingerprint: 'sha256/KUIHdVkSTzYmb2PGMotOPDm2ir52G1QyPW6rt6wUjZ0=', | ||
63 | }; | ||