From dc90ccb10fa6c22e3f6af9a4823932daab99ed9e Mon Sep 17 00:00:00 2001 From: Rob Gallo <43080011+RobGallo@users.noreply.github.com> Date: Mon, 15 Jun 2020 16:26:33 -0400 Subject: [PATCH] feat(android-setup): Add most of the remaining state machine steps (#2873) * feat(android-setup): Add detect-service state machine step * feat:(android-setup): Add prompt-install-service state machine step * feat(setup-android): Add installing-service state machine step * feat(setup-android): Add detect-permissions state machine step * feat(android-setup): Add prompt-grant-permissions state machine step * feat(android-setup): Add prompt-connected-start-testing state machine step * feat(android-setup): Add new step configs to allAndroidSetupStepConfigs --- .../setup/android-setup-steps-configs.ts | 20 ++++--- .../android/setup/steps/detect-permissions.ts | 14 +++++ .../android/setup/steps/detect-service.ts | 12 ++++ .../android/setup/steps/installing-service.ts | 16 +++++ .../steps/prompt-connected-start-testing.ts | 12 ++++ .../setup/steps/prompt-grant-permissions.ts | 12 ++++ .../setup/steps/prompt-install-service.ts | 12 ++++ .../setup/steps/detect-permissions.test.ts | 52 ++++++++++++++++ .../setup/steps/detect-service.test.ts | 50 ++++++++++++++++ .../setup/steps/installing-service.test.ts | 60 +++++++++++++++++++ .../prompt-connected-start-testing.test.ts | 26 ++++++++ .../steps/prompt-grant-permissions.test.ts | 26 ++++++++ .../steps/prompt-install-service.test.ts | 26 ++++++++ 13 files changed, 331 insertions(+), 7 deletions(-) create mode 100644 src/electron/platform/android/setup/steps/detect-permissions.ts create mode 100644 src/electron/platform/android/setup/steps/detect-service.ts create mode 100644 src/electron/platform/android/setup/steps/installing-service.ts create mode 100644 src/electron/platform/android/setup/steps/prompt-connected-start-testing.ts create mode 100644 src/electron/platform/android/setup/steps/prompt-grant-permissions.ts create mode 100644 src/electron/platform/android/setup/steps/prompt-install-service.ts create mode 100644 src/tests/unit/tests/electron/platform/android/setup/steps/detect-permissions.test.ts create mode 100644 src/tests/unit/tests/electron/platform/android/setup/steps/detect-service.test.ts create mode 100644 src/tests/unit/tests/electron/platform/android/setup/steps/installing-service.test.ts create mode 100644 src/tests/unit/tests/electron/platform/android/setup/steps/prompt-connected-start-testing.test.ts create mode 100644 src/tests/unit/tests/electron/platform/android/setup/steps/prompt-grant-permissions.test.ts create mode 100644 src/tests/unit/tests/electron/platform/android/setup/steps/prompt-install-service.test.ts diff --git a/src/electron/platform/android/setup/android-setup-steps-configs.ts b/src/electron/platform/android/setup/android-setup-steps-configs.ts index 71950e8512b..edab0ea211e 100644 --- a/src/electron/platform/android/setup/android-setup-steps-configs.ts +++ b/src/electron/platform/android/setup/android-setup-steps-configs.ts @@ -6,7 +6,13 @@ import { AndroidSetupStoreCallbacks } from 'electron/flux/types/android-setup-st import { AndroidSetupDeps } from 'electron/platform/android/setup/android-setup-deps'; import { AndroidSetupStepId } from 'electron/platform/android/setup/android-setup-step-id'; import { detectDevices } from 'electron/platform/android/setup/steps/detect-devices'; +import { detectPermissions } from 'electron/platform/android/setup/steps/detect-permissions'; +import { detectService } from 'electron/platform/android/setup/steps/detect-service'; +import { installingService } from 'electron/platform/android/setup/steps/installing-service'; import { promptConnectToDevice } from 'electron/platform/android/setup/steps/prompt-connect-to-device'; +import { promptConnectedStartTesting } from 'electron/platform/android/setup/steps/prompt-connected-start-testing'; +import { promptGrantPermissions } from 'electron/platform/android/setup/steps/prompt-grant-permissions'; +import { promptInstallService } from 'electron/platform/android/setup/steps/prompt-install-service'; import { promptLocateAdb } from 'electron/platform/android/setup/steps/prompt-locate-adb'; import { StateMachineStepConfig, @@ -33,11 +39,11 @@ export const allAndroidSetupStepConfigs: AndroidSetupStepConfigs = { 'prompt-connect-to-device': promptConnectToDevice, 'detect-devices': detectDevices, 'prompt-choose-device': null, - 'detect-service': null, - 'prompt-install-service': null, - 'installing-service': null, - 'prompt-install-failed': null, - 'detect-permissions': null, - 'prompt-grant-permissions': null, - 'prompt-connected-start-testing': null, + 'detect-service': detectService, + 'prompt-install-service': promptInstallService, + 'installing-service': installingService, + 'prompt-install-failed': promptInstallService, + 'detect-permissions': detectPermissions, + 'prompt-grant-permissions': promptGrantPermissions, + 'prompt-connected-start-testing': promptConnectedStartTesting, }; diff --git a/src/electron/platform/android/setup/steps/detect-permissions.ts b/src/electron/platform/android/setup/steps/detect-permissions.ts new file mode 100644 index 00000000000..13ee3c8c5c2 --- /dev/null +++ b/src/electron/platform/android/setup/steps/detect-permissions.ts @@ -0,0 +1,14 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { AndroidSetupStepConfig } from 'electron/platform/android/setup/android-setup-steps-configs'; + +export const detectPermissions: AndroidSetupStepConfig = deps => ({ + actions: {}, + onEnter: async () => { + const detected = await deps.hasExpectedPermissions(); + deps.stepTransition( + detected ? 'prompt-connected-start-testing' : 'prompt-grant-permissions', + ); + }, +}); diff --git a/src/electron/platform/android/setup/steps/detect-service.ts b/src/electron/platform/android/setup/steps/detect-service.ts new file mode 100644 index 00000000000..a3d5a31d8d3 --- /dev/null +++ b/src/electron/platform/android/setup/steps/detect-service.ts @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { AndroidSetupStepConfig } from 'electron/platform/android/setup/android-setup-steps-configs'; + +export const detectService: AndroidSetupStepConfig = deps => ({ + actions: {}, + onEnter: async () => { + const detected = await deps.hasExpectedServiceVersion(); + deps.stepTransition(detected ? 'detect-permissions' : 'prompt-install-service'); + }, +}); diff --git a/src/electron/platform/android/setup/steps/installing-service.ts b/src/electron/platform/android/setup/steps/installing-service.ts new file mode 100644 index 00000000000..8bed75250fd --- /dev/null +++ b/src/electron/platform/android/setup/steps/installing-service.ts @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { AndroidSetupStepConfig } from 'electron/platform/android/setup/android-setup-steps-configs'; + +export const installingService: AndroidSetupStepConfig = deps => ({ + actions: { + cancel: () => { + deps.stepTransition('prompt-install-service'); + }, + }, + onEnter: async () => { + const installed = await deps.installService(); + deps.stepTransition(installed ? 'prompt-grant-permissions' : 'prompt-install-failed'); + }, +}); diff --git a/src/electron/platform/android/setup/steps/prompt-connected-start-testing.ts b/src/electron/platform/android/setup/steps/prompt-connected-start-testing.ts new file mode 100644 index 00000000000..679b925cf48 --- /dev/null +++ b/src/electron/platform/android/setup/steps/prompt-connected-start-testing.ts @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { AndroidSetupStepConfig } from 'electron/platform/android/setup/android-setup-steps-configs'; + +export const promptConnectedStartTesting: AndroidSetupStepConfig = deps => ({ + actions: { + rescan: () => { + deps.stepTransition('detect-adb'); + }, + }, +}); diff --git a/src/electron/platform/android/setup/steps/prompt-grant-permissions.ts b/src/electron/platform/android/setup/steps/prompt-grant-permissions.ts new file mode 100644 index 00000000000..5492e7b4236 --- /dev/null +++ b/src/electron/platform/android/setup/steps/prompt-grant-permissions.ts @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { AndroidSetupStepConfig } from 'electron/platform/android/setup/android-setup-steps-configs'; + +export const promptGrantPermissions: AndroidSetupStepConfig = deps => ({ + actions: { + next: () => { + deps.stepTransition('detect-permissions'); + }, + }, +}); diff --git a/src/electron/platform/android/setup/steps/prompt-install-service.ts b/src/electron/platform/android/setup/steps/prompt-install-service.ts new file mode 100644 index 00000000000..3ca14c665cb --- /dev/null +++ b/src/electron/platform/android/setup/steps/prompt-install-service.ts @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { AndroidSetupStepConfig } from 'electron/platform/android/setup/android-setup-steps-configs'; + +export const promptInstallService: AndroidSetupStepConfig = deps => ({ + actions: { + next: () => { + deps.stepTransition('installing-service'); + }, + }, +}); diff --git a/src/tests/unit/tests/electron/platform/android/setup/steps/detect-permissions.test.ts b/src/tests/unit/tests/electron/platform/android/setup/steps/detect-permissions.test.ts new file mode 100644 index 00000000000..b30fb8c2ab5 --- /dev/null +++ b/src/tests/unit/tests/electron/platform/android/setup/steps/detect-permissions.test.ts @@ -0,0 +1,52 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { AndroidSetupStepConfigDeps } from 'electron/platform/android/setup/android-setup-steps-configs'; +import { detectPermissions } from 'electron/platform/android/setup/steps/detect-permissions'; +import { Mock, MockBehavior, Times } from 'typemoq'; +import { checkExpectedActionsAreDefined } from './actions-tester'; + +describe('Android setup step: detectPermissions', () => { + it('has expected properties', () => { + const deps = {} as AndroidSetupStepConfigDeps; + const step = detectPermissions(deps); + checkExpectedActionsAreDefined(step, []); + expect(step.onEnter).toBeDefined(); + }); + + it('onEnter transitions to prompt-connected-start-testing as expected', async () => { + const p = new Promise(resolve => resolve(true)); + + const depsMock = Mock.ofType(undefined, MockBehavior.Strict); + depsMock + .setup(m => m.hasExpectedPermissions()) + .returns(_ => p) + .verifiable(Times.once()); + + depsMock + .setup(m => m.stepTransition('prompt-connected-start-testing')) + .verifiable(Times.once()); + + const step = detectPermissions(depsMock.object); + await step.onEnter(); + + depsMock.verifyAll(); + }); + + it('onEnter transitions to prompt-install-service as expected', async () => { + const p = new Promise(resolve => resolve(false)); + + const depsMock = Mock.ofType(undefined, MockBehavior.Strict); + depsMock + .setup(m => m.hasExpectedPermissions()) + .returns(_ => p) + .verifiable(Times.once()); + + depsMock.setup(m => m.stepTransition('prompt-grant-permissions')).verifiable(Times.once()); + + const step = detectPermissions(depsMock.object); + await step.onEnter(); + + depsMock.verifyAll(); + }); +}); diff --git a/src/tests/unit/tests/electron/platform/android/setup/steps/detect-service.test.ts b/src/tests/unit/tests/electron/platform/android/setup/steps/detect-service.test.ts new file mode 100644 index 00000000000..1744f81e6b6 --- /dev/null +++ b/src/tests/unit/tests/electron/platform/android/setup/steps/detect-service.test.ts @@ -0,0 +1,50 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { AndroidSetupStepConfigDeps } from 'electron/platform/android/setup/android-setup-steps-configs'; +import { detectService } from 'electron/platform/android/setup/steps/detect-service'; +import { Mock, MockBehavior, Times } from 'typemoq'; +import { checkExpectedActionsAreDefined } from './actions-tester'; + +describe('Android setup step: detectService', () => { + it('has expected properties', () => { + const deps = {} as AndroidSetupStepConfigDeps; + const step = detectService(deps); + checkExpectedActionsAreDefined(step, []); + expect(step.onEnter).toBeDefined(); + }); + + it('onEnter transitions to detect-permissions as expected', async () => { + const p = new Promise(resolve => resolve(true)); + + const depsMock = Mock.ofType(undefined, MockBehavior.Strict); + depsMock + .setup(m => m.hasExpectedServiceVersion()) + .returns(_ => p) + .verifiable(Times.once()); + + depsMock.setup(m => m.stepTransition('detect-permissions')).verifiable(Times.once()); + + const step = detectService(depsMock.object); + await step.onEnter(); + + depsMock.verifyAll(); + }); + + it('onEnter transitions to prompt-install-service as expected', async () => { + const p = new Promise(resolve => resolve(false)); + + const depsMock = Mock.ofType(undefined, MockBehavior.Strict); + depsMock + .setup(m => m.hasExpectedServiceVersion()) + .returns(_ => p) + .verifiable(Times.once()); + + depsMock.setup(m => m.stepTransition('prompt-install-service')).verifiable(Times.once()); + + const step = detectService(depsMock.object); + await step.onEnter(); + + depsMock.verifyAll(); + }); +}); diff --git a/src/tests/unit/tests/electron/platform/android/setup/steps/installing-service.test.ts b/src/tests/unit/tests/electron/platform/android/setup/steps/installing-service.test.ts new file mode 100644 index 00000000000..69ae4b09127 --- /dev/null +++ b/src/tests/unit/tests/electron/platform/android/setup/steps/installing-service.test.ts @@ -0,0 +1,60 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { AndroidSetupStepConfigDeps } from 'electron/platform/android/setup/android-setup-steps-configs'; +import { installingService } from 'electron/platform/android/setup/steps/installing-service'; +import { Mock, MockBehavior, Times } from 'typemoq'; +import { checkExpectedActionsAreDefined } from './actions-tester'; + +describe('Android setup step: installingService', () => { + it('has expected properties', () => { + const deps = {} as AndroidSetupStepConfigDeps; + const step = installingService(deps); + checkExpectedActionsAreDefined(step, ['cancel']); + expect(step.onEnter).toBeDefined(); + }); + + it('cancel transitions to prompt-grant-permissions as expected', () => { + const depsMock = Mock.ofType(undefined, MockBehavior.Strict); + depsMock.setup(m => m.stepTransition('prompt-install-service')).verifiable(Times.once()); + + const step = installingService(depsMock.object); + step.actions.cancel(); + + depsMock.verifyAll(); + }); + + it('onEnter transitions to prompt-grant-permissions as expected', async () => { + const p = new Promise(resolve => resolve(true)); + + const depsMock = Mock.ofType(undefined, MockBehavior.Strict); + depsMock + .setup(m => m.installService()) + .returns(_ => p) + .verifiable(Times.once()); + + depsMock.setup(m => m.stepTransition('prompt-grant-permissions')).verifiable(Times.once()); + + const step = installingService(depsMock.object); + await step.onEnter(); + + depsMock.verifyAll(); + }); + + it('onEnter transitions to prompt-install-service as expected', async () => { + const p = new Promise(resolve => resolve(false)); + + const depsMock = Mock.ofType(undefined, MockBehavior.Strict); + depsMock + .setup(m => m.installService()) + .returns(_ => p) + .verifiable(Times.once()); + + depsMock.setup(m => m.stepTransition('prompt-install-failed')).verifiable(Times.once()); + + const step = installingService(depsMock.object); + await step.onEnter(); + + depsMock.verifyAll(); + }); +}); diff --git a/src/tests/unit/tests/electron/platform/android/setup/steps/prompt-connected-start-testing.test.ts b/src/tests/unit/tests/electron/platform/android/setup/steps/prompt-connected-start-testing.test.ts new file mode 100644 index 00000000000..511f5e6a04a --- /dev/null +++ b/src/tests/unit/tests/electron/platform/android/setup/steps/prompt-connected-start-testing.test.ts @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { AndroidSetupStepConfigDeps } from 'electron/platform/android/setup/android-setup-steps-configs'; +import { promptConnectedStartTesting } from 'electron/platform/android/setup/steps/prompt-connected-start-testing'; +import { Mock, MockBehavior, Times } from 'typemoq'; +import { checkExpectedActionsAreDefined } from './actions-tester'; + +describe('Android setup step: promptConnectedStartTesting', () => { + it('has expected properties', () => { + const deps = {} as AndroidSetupStepConfigDeps; + const step = promptConnectedStartTesting(deps); + checkExpectedActionsAreDefined(step, ['rescan']); + expect(step.onEnter).not.toBeDefined(); + }); + + it('onEnter transitions to detect-adb as expected', () => { + const depsMock = Mock.ofType(undefined, MockBehavior.Strict); + depsMock.setup(m => m.stepTransition('detect-adb')).verifiable(Times.once()); + + const step = promptConnectedStartTesting(depsMock.object); + step.actions.rescan(); + + depsMock.verifyAll(); + }); +}); diff --git a/src/tests/unit/tests/electron/platform/android/setup/steps/prompt-grant-permissions.test.ts b/src/tests/unit/tests/electron/platform/android/setup/steps/prompt-grant-permissions.test.ts new file mode 100644 index 00000000000..a65ce6101d8 --- /dev/null +++ b/src/tests/unit/tests/electron/platform/android/setup/steps/prompt-grant-permissions.test.ts @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { AndroidSetupStepConfigDeps } from 'electron/platform/android/setup/android-setup-steps-configs'; +import { promptGrantPermissions } from 'electron/platform/android/setup/steps/prompt-grant-permissions'; +import { Mock, MockBehavior, Times } from 'typemoq'; +import { checkExpectedActionsAreDefined } from './actions-tester'; + +describe('Android setup step: promptGrantPermissions', () => { + it('has expected properties', () => { + const deps = {} as AndroidSetupStepConfigDeps; + const step = promptGrantPermissions(deps); + checkExpectedActionsAreDefined(step, ['next']); + expect(step.onEnter).not.toBeDefined(); + }); + + it('onEnter transitions to detect-permissions as expected', () => { + const depsMock = Mock.ofType(undefined, MockBehavior.Strict); + depsMock.setup(m => m.stepTransition('detect-permissions')).verifiable(Times.once()); + + const step = promptGrantPermissions(depsMock.object); + step.actions.next(); + + depsMock.verifyAll(); + }); +}); diff --git a/src/tests/unit/tests/electron/platform/android/setup/steps/prompt-install-service.test.ts b/src/tests/unit/tests/electron/platform/android/setup/steps/prompt-install-service.test.ts new file mode 100644 index 00000000000..aeca3c235b2 --- /dev/null +++ b/src/tests/unit/tests/electron/platform/android/setup/steps/prompt-install-service.test.ts @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { AndroidSetupStepConfigDeps } from 'electron/platform/android/setup/android-setup-steps-configs'; +import { promptInstallService } from 'electron/platform/android/setup/steps/prompt-install-service'; +import { Mock, MockBehavior, Times } from 'typemoq'; +import { checkExpectedActionsAreDefined } from './actions-tester'; + +describe('Android setup step: promptInstallService', () => { + it('has expected properties', () => { + const deps = {} as AndroidSetupStepConfigDeps; + const step = promptInstallService(deps); + checkExpectedActionsAreDefined(step, ['next']); + expect(step.onEnter).not.toBeDefined(); + }); + + it('onEnter transitions to installing-service as expected', () => { + const depsMock = Mock.ofType(undefined, MockBehavior.Strict); + depsMock.setup(m => m.stepTransition('installing-service')).verifiable(Times.once()); + + const step = promptInstallService(depsMock.object); + step.actions.next(); + + depsMock.verifyAll(); + }); +});