Skip to content

Commit

Permalink
feat(android-setup): Add most of the remaining state machine steps (#…
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
RobGallo authored Jun 15, 2020
1 parent b0f474a commit dc90ccb
Show file tree
Hide file tree
Showing 13 changed files with 331 additions and 7 deletions.
20 changes: 13 additions & 7 deletions src/electron/platform/android/setup/android-setup-steps-configs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
};
14 changes: 14 additions & 0 deletions src/electron/platform/android/setup/steps/detect-permissions.ts
Original file line number Diff line number Diff line change
@@ -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',
);
},
});
12 changes: 12 additions & 0 deletions src/electron/platform/android/setup/steps/detect-service.ts
Original file line number Diff line number Diff line change
@@ -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');
},
});
16 changes: 16 additions & 0 deletions src/electron/platform/android/setup/steps/installing-service.ts
Original file line number Diff line number Diff line change
@@ -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');
},
});
Original file line number Diff line number Diff line change
@@ -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');
},
},
});
Original file line number Diff line number Diff line change
@@ -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');
},
},
});
Original file line number Diff line number Diff line change
@@ -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');
},
},
});
Original file line number Diff line number Diff line change
@@ -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<boolean>(resolve => resolve(true));

const depsMock = Mock.ofType<AndroidSetupStepConfigDeps>(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<boolean>(resolve => resolve(false));

const depsMock = Mock.ofType<AndroidSetupStepConfigDeps>(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();
});
});
Original file line number Diff line number Diff line change
@@ -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<boolean>(resolve => resolve(true));

const depsMock = Mock.ofType<AndroidSetupStepConfigDeps>(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<boolean>(resolve => resolve(false));

const depsMock = Mock.ofType<AndroidSetupStepConfigDeps>(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();
});
});
Original file line number Diff line number Diff line change
@@ -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<AndroidSetupStepConfigDeps>(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<boolean>(resolve => resolve(true));

const depsMock = Mock.ofType<AndroidSetupStepConfigDeps>(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<boolean>(resolve => resolve(false));

const depsMock = Mock.ofType<AndroidSetupStepConfigDeps>(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();
});
});
Original file line number Diff line number Diff line change
@@ -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<AndroidSetupStepConfigDeps>(undefined, MockBehavior.Strict);
depsMock.setup(m => m.stepTransition('detect-adb')).verifiable(Times.once());

const step = promptConnectedStartTesting(depsMock.object);
step.actions.rescan();

depsMock.verifyAll();
});
});
Original file line number Diff line number Diff line change
@@ -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<AndroidSetupStepConfigDeps>(undefined, MockBehavior.Strict);
depsMock.setup(m => m.stepTransition('detect-permissions')).verifiable(Times.once());

const step = promptGrantPermissions(depsMock.object);
step.actions.next();

depsMock.verifyAll();
});
});
Original file line number Diff line number Diff line change
@@ -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<AndroidSetupStepConfigDeps>(undefined, MockBehavior.Strict);
depsMock.setup(m => m.stepTransition('installing-service')).verifiable(Times.once());

const step = promptInstallService(depsMock.object);
step.actions.next();

depsMock.verifyAll();
});
});

0 comments on commit dc90ccb

Please sign in to comment.