示例#1
0
        public async Task <string> GetPreviousNode(string formKey, string currentNodeId)
        {
            var form = await _formRepository.GetForm(formKey);

            var currentNode  = form.Nodes.FindByKey(new Key(currentNodeId));
            var taskFormNode = currentNode.AssertType <PhysicalTaskFormNode>();

            var taskRouterNode = form.Nodes.FindByKey(Key.ForDecisionTaskRouter(taskFormNode.TaskId));

            taskRouterNode.AssertType <TaskRouterFormNode>();

            // We prevent queueing from the task list so that we don't have to iterate over other tasks
            var stopKey = Key.ForTaskList();

            var pathFinder = new GraphPathFinderBuilder <Key, FormNode>(PathFinderType.PriorityPathFinder)
                             .WithOnEdgeDiscoveredHandler((e, output) =>
            {
                if (e.ToNode.Key.Equals(stopKey))
                {
                    output.ShouldQueue = false;
                }
            })
                             .Build();

            var pathResult = pathFinder.FindPath(form, taskRouterNode, currentNode);

            // Skip the current node then find the first physical node
            var reversedPath = pathResult.Path.Reverse();
            var physicalNode = reversedPath.Skip(1).FirstOrDefault(x => !x.Value.IsDecisionNode);

            return(physicalNode is null?Key.ForTaskList().Value : physicalNode.Key.Value);
        }
        public async Task PathFindingTest()
        {
            var repo     = new Mock <IFormRepository>();
            var provider = new Mock <IStaticFormProvider>();
            var service  = new FormService(repo.Object, provider.Object);
            var form     = await service.InitialiseForm("test", FormType.Test);

            var fromNode = form.Nodes.FindByKey(Key.ForTaskList());
            var toNode   = form.Nodes.FindByKey(Key.ForPostTaskPage("last-task"));

            var stopKey = Key.ForTaskList();

            var pathFinder = new GraphPathFinderBuilder <Key, FormNode>(PathFinderType.PriorityPathFinder)
                             .WithOnEdgeDiscoveredHandler((e, output) =>
            {
                if (e.ToNode.Key.Equals(stopKey))
                {
                    output.ShouldQueue = false;
                }
            })
                             .Build();

            var result = pathFinder.FindPath(form, fromNode, toNode);

            Assert.Equal(18, result.Cost);
        }
示例#3
0
        public async Task <(int questionNumber, int totalQuestions)> GetQuestionNumber(string formKey, string questionPageNodeId)
        {
            var form = await _formRepository.GetForm(formKey);

            var questionPageFormNode = form.Nodes.FindByKey(new Key(questionPageNodeId));
            var questionPageValue    = questionPageFormNode.AssertType <TaskQuestionPageFormNode>();

            var taskListNode = form.Nodes.FindByKey(Key.ForTaskList());

            var taskRouterNode = taskListNode.Neighbors.First(x => x.IsTaskRouterNode(out var taskRouter) &&
                                                              taskRouter.TaskId == questionPageValue.TaskId);

            var taskItemRouterNode = taskRouterNode.Neighbors.First(x => x.IsTaskItemRouterNode(out var tir) &&
                                                                    tir.RepeatIndex ==
                                                                    questionPageValue.RepeatIndices.First());

            var postTaskNode = taskRouterNode.Neighbors.First(GraphNodePredicates.IsAnyPostTaskNode);

            var pathFinder = new GraphPathFinderBuilder <Key, FormNode>(PathFinderType.PriorityPathFinder)
                             .WithOnNodeDequeuedHandler((props, output) =>
            {
                // We don't need to queue beyond the PostTask as all the question nodes lie between the item router and post task nodes
                if ((props.Node.Value.IsDecisionNode && props.Node.Value is DecisionFormNode dfn && dfn.DecisionFormNodeType == DecisionFormNodeType.PostTaskGhost) ||
                    (!props.Node.Value.IsDecisionNode && props.Node.Value is PhysicalFormNode pfn && pfn.PhysicalFormNodeType == PhysicalFormNodeType.PostTask))
                {
                    output.Skip = true;
                }
            })
                             .Build();

            var taskItemToQuestionPath = pathFinder.FindPath(form, taskItemRouterNode, questionPageFormNode);
            var questionToSummaryPath  = pathFinder.FindPath(form, questionPageFormNode, postTaskNode);

            var questionNumber = taskItemToQuestionPath.Path.Count(GraphNodePredicates.IsTaskQuestionPageNode);

            var remainingQuestionCount = questionToSummaryPath.Path.Count(GraphNodePredicates.IsTaskQuestionPageNode) - 1; // -1 so we don't include the current question twice

            return(questionNumber, questionNumber + remainingQuestionCount);
        }