consul/ui/packages/consul-ui/app/locations/fsm-with-optional-test.js

79 lines
2.7 KiB
JavaScript

/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
import FSMWithOptionalLocation from './fsm-with-optional';
import { FSM, Location } from './fsm';
import { settled } from '@ember/test-helpers';
export default class FSMWithOptionalTestLocation extends FSMWithOptionalLocation {
implementation = 'fsm-with-optional-test';
static create() {
return new this(...arguments);
}
constructor() {
super(...arguments);
this.location = new Location();
this.machine = new FSM(this.location);
// Browsers add event listeners to the state machine via the
// document/defaultView
this.doc = {
defaultView: {
addEventListener: (event, cb) => {
this.machine = new FSM(this.location, cb);
},
removeEventListener: (event, cb) => {
this.machine = new FSM();
},
},
};
}
visit(path) {
const app = this.container;
const router = this.container.lookup('router:main');
// taken from emberjs/application/instance:visit but cleaned up a little
// https://github.com/emberjs/ember.js/blob/21bd70c773dcc4bfe4883d7943e8a68d203b5bad/packages/%40ember/application/instance.js#L236-L277
const handleTransitionResolve = async (_) => {
await settled();
return new Promise((resolve) => setTimeout(resolve(app), 0));
};
const handleTransitionReject = (error) => {
if (error.error) {
throw error.error;
} else if (error.name === 'TransitionAborted' && router._routerMicrolib.activeTransition) {
return router._routerMicrolib.activeTransition.then(
handleTransitionResolve,
handleTransitionReject
);
} else if (error.name === 'TransitionAborted') {
throw new Error(error.message);
} else {
throw error;
}
};
//
// the first time around, set up location via handleURL
if (this.location.pathname === '') {
// getting rootURL straight from env would be nicer but is non-standard
// and we still need access to router above
this.rootURL = router.rootURL.replace(/\/$/, '');
// do some pre-setup setup so getURL can work
// this is machine setup that would be nice to via machine
// instantiation, its basically initialState
// move machine instantiation here once its an event target
this.machine.state.path = this.location.pathname = `${this.rootURL}${path}`;
this.path = this.getURL();
// handleURL calls setupRouter for us
return app.handleURL(`${this.path}`).then(handleTransitionResolve, handleTransitionReject);
}
// anything else, just transitionTo like normal
return this.transitionTo(path).then(handleTransitionResolve, handleTransitionReject);
}
}