async def get_fsm_problems(): fsm = FSM() problems = [] # noinspection PyTypeChecker async for problem in fsm.health_check(): problems.append(problem) return problems
def test_fsm_confused_state(): with patch_conf(settings_file=ENGINE_SETTINGS_FILE): fsm = FSM() reg = Register({}) req = Request(MockEmptyMessage(), reg) run(req.transform()) assert fsm._confused_state(req) == BaseTestState reg = Register({Register.STATE: 'tests.issue_0001.states.Hello'}) req = Request(MockEmptyMessage(), reg) run(req.transform()) assert fsm._confused_state(req) == Hello
def make_test_fsm() -> Tuple[FSM, TestPlatform]: """ Generate both a FSM and a test platform for unit testing purposes. The will use the current configuration to load stories and transitions. """ fsm = FSM() run(fsm.async_init()) platform = TestPlatform() # noinspection PyTypeChecker platform.on_message(fsm.handle_message) return fsm, platform
def test_fsm_init(): with patch_conf(settings_file=ENGINE_SETTINGS_FILE): fsm = FSM() assert isinstance(fsm.register, RedisRegisterStore) assert isinstance(fsm.transitions, list) for t in fsm.transitions: assert isinstance(t, Transition)
async def init(self): """ Creates the FSM and the cache. It can be called several times to reset stuff (like for unit tests...). It also runs all the health checks in order to see if everything is fit for running. """ self.fsm = FSM() checks = [] # noinspection PyTypeChecker async for check in self.fsm.health_check(): checks.append(check) logger.error('HEALTH CHECK FAIL #%s: %s', check.code, check.reason) if checks: exit(1) await self.fsm.async_init() self.platforms = {}
def test_fsm_find_trigger(reg): with patch_conf(settings_file=ENGINE_SETTINGS_FILE): fsm = FSM() req = Request(MockTextMessage('hello'), reg) run(req.transform()) trigger, state = run(fsm._find_trigger(req)) assert isinstance(trigger, trig.Text) assert state == Hello req = Request(MockChoiceMessage(), reg) run(req.transform()) trigger, state = run(fsm._find_trigger(req)) assert trigger is None assert state is None reg = Register({ Register.STATE: HowAreYou.name(), Register.TRANSITION: { 'choices': { 'yes': { 'text': 'Yes', 'intent': 'YES', }, 'no': { 'text': 'No', 'intent': 'NO' }, }, }, }) req = Request(MockChoiceMessage(), reg) run(req.transform()) trigger, state = run(fsm._find_trigger(req)) assert isinstance(trigger, trig.Choice) assert state == Great
class PlatformManager(object): """ That is the core of the system. This class has the responsibilities to: - Create the platform instances - Create the FSM - Hook the platforms to the FSM For unit testing purposes it can also wipe existing instances and start again. """ def __init__(self): self.fsm = None self.platforms = {} @property def _is_init(self): """ Check if initialization was done """ return self.fsm is not None async def init(self): """ Creates the FSM and the cache. It can be called several times to reset stuff (like for unit tests...). It also runs all the health checks in order to see if everything is fit for running. """ self.fsm = FSM() checks = [] # noinspection PyTypeChecker async for check in self.fsm.health_check(): checks.append(check) logger.error('HEALTH CHECK FAIL #%s: %s', check.code, check.reason) if checks: exit(1) await self.fsm.async_init() self.platforms = {} async def build_facebook(self): """ Build the Facebook platform. Nothing fancy. """ fb = Facebook() await fb.async_init() fb.on_message(self.fsm.handle_message) return fb async def get_platform(self, name: Text): """ Get a valid instance of the specified platform. Do not cache this object, it might change with configuration changes. """ if not self._is_init: await self.init() if name not in self.platforms: build = getattr(self, 'build_{}'.format(name), None) if not build: raise PlatformDoesNotExist( 'Platform "{}" does not exist'.format(name)) self.platforms[name] = await build() return self.platforms[name]