public Handler(
     FormFlowInstance <EditVenueFlowModel> formFlowInstance,
     ISearchClient <Onspd> onspdSearchClient)
 {
     _formFlowInstance  = formFlowInstance;
     _onspdSearchClient = onspdSearchClient;
 }
        public void Resolve_CannotExtractId_ReturnsNull()
        {
            // Arrange
            var key        = "test-flow";
            var instanceId = new FormFlowInstanceId("the-instance", new RouteValueDictionary());
            var stateType  = typeof(TestState);
            var state      = new TestState();

            var stateProvider = new Mock <IUserInstanceStateProvider>();

            stateProvider
            .Setup(s => s.GetInstance(instanceId))
            .Returns(FormFlowInstance.Create(stateProvider.Object, key, instanceId, stateType, state, properties: new Dictionary <object, object>()));

            var instanceResolver = new InstanceResolver(stateProvider.Object);

            var httpContext = new DefaultHttpContext();

            httpContext.Request.QueryString = new QueryString($"?");

            var routeData = new RouteData();

            var actionDescriptor = new ActionDescriptor();

            actionDescriptor.SetProperty(new FormFlowDescriptor(key, stateType, IdGenerationSource.RandomId));

            var actionContext = new ActionContext(httpContext, routeData, actionDescriptor);

            // Act
            var result = instanceResolver.Resolve(actionContext);

            // Assert
            Assert.Null(result);
        }
        public void OnActionExecuting(ActionExecutingContext context)
        {
            var flowDescriptor = context.ActionDescriptor.GetProperty <FormFlowDescriptor>();

            if (flowDescriptor == null)
            {
                return;
            }

            var options = context.HttpContext.RequestServices.GetRequiredService <IOptions <FormFlowOptions> >().Value;

            if (options.MissingInstanceHandler == null)
            {
                return;
            }

            var instanceParameters = context.ActionDescriptor.Parameters
                                     .Where(p => FormFlowInstance.IsFormFlowInstanceType(p.ParameterType))
                                     .ToArray();

            foreach (var p in instanceParameters)
            {
                if (!context.ActionArguments.TryGetValue(p.Name, out var instanceArgument) ||
                    instanceArgument == null)
                {
                    context.Result = options.MissingInstanceHandler(flowDescriptor, context.HttpContext);
                    return;
                }
            }
        }
Beispiel #4
0
 public async Task <IActionResult> Post(Command command, FormFlowInstance formFlowInstance) =>
 await _mediator.SendAndMapResponse(
     command,
     response => response.Match <IActionResult>(
         errors => this.ViewFromErrors("ApprenticeshipAssessment", errors),
         vm => RedirectToAction(nameof(GetConfirmation))
         .WithFormFlowInstanceId(formFlowInstance)));
        public FormFlowInstance CreateInstance(
            string key,
            FormFlowInstanceId instanceId,
            Type stateType,
            object state,
            IReadOnlyDictionary <object, object> properties)
        {
            _instances.Add(instanceId, new Entry()
            {
                Key        = key,
                StateType  = stateType,
                State      = state,
                Properties = properties
            });

            var instance = FormFlowInstance.Create(
                this,
                key,
                instanceId,
                stateType,
                state,
                properties ?? new Dictionary <object, object>());

            return(instance);
        }
Beispiel #6
0
 public async Task <IActionResult> PostConfirmation(
     ConfirmationCommand command,
     FormFlowInstance <FlowModel> formFlowInstance) =>
 await _mediator.SendAndMapResponse(
     command,
     success => RedirectToAction(
         nameof(ApprenticeshipQAController.ProviderSelected),
         "ApprenticeshipQA",
         new { providerId = formFlowInstance.State.ProviderId }));
        public FormFlowInstance GetInstance(FormFlowInstanceId instanceId)
        {
            _instances.TryGetValue(instanceId, out var entry);

            var instance = entry != null?
                           FormFlowInstance.Create(this, entry.Key, instanceId, entry.StateType, entry.State, entry.Properties) :
                               null;

            return(instance);
        }
Beispiel #8
0
        public IModelBinder GetBinder(ModelBinderProviderContext context)
        {
            if (FormFlowInstance.IsFormFlowInstanceType(context.Metadata.ModelType))
            {
                var stateProvider = context.Services.GetRequiredService <IUserInstanceStateProvider>();
                return(new InstanceModelBinder(stateProvider));
            }

            return(null);
        }
Beispiel #9
0
 public Handler(
     IProviderInfoCache providerInfoCache,
     IProviderOwnershipCache providerOwnershipCache,
     ICosmosDbQueryDispatcher cosmosDbQueryDispatcher,
     FormFlowInstance <FlowModel> formFlowInstance)
 {
     _providerInfoCache       = providerInfoCache;
     _providerOwnershipCache  = providerOwnershipCache;
     _cosmosDbQueryDispatcher = cosmosDbQueryDispatcher;
     _formFlowInstance        = formFlowInstance;
 }
Beispiel #10
0
 public Handler(
     FormFlowInstance <EditVenueFlowModel> formFlowInstance,
     IProviderOwnershipCache providerOwnershipCache,
     IProviderInfoCache providerInfoCache,
     ICosmosDbQueryDispatcher cosmosDbQueryDispatcher)
 {
     _formFlowInstance        = formFlowInstance;
     _providerOwnershipCache  = providerOwnershipCache;
     _providerInfoCache       = providerInfoCache;
     _cosmosDbQueryDispatcher = cosmosDbQueryDispatcher;
 }
Beispiel #11
0
 public Handler(
     FormFlowInstance <EditVenueFlowModel> formFlowInstance,
     ICosmosDbQueryDispatcher cosmosDbQueryDispatcher,
     ICurrentUserProvider currentUserProvider,
     IClock clock)
 {
     _formFlowInstance        = formFlowInstance;
     _cosmosDbQueryDispatcher = cosmosDbQueryDispatcher;
     _currentUserProvider     = currentUserProvider;
     _clock = clock;
 }
 public Handler(
     ISqlQueryDispatcher sqlQueryDispatcher,
     ICurrentUserProvider currentUserProvider,
     IClock clock,
     FormFlowInstance <FlowModel> formFlowInstance)
 {
     _sqlQueryDispatcher  = sqlQueryDispatcher;
     _currentUserProvider = currentUserProvider;
     _clock            = clock;
     _formFlowInstance = formFlowInstance;
 }
        public Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (!FormFlowInstance.IsFormFlowInstanceType(bindingContext.ModelType))
            {
                return(Task.CompletedTask);
            }

            var resolver = new InstanceResolver(_stateProvider);
            var instance = resolver.Resolve(bindingContext.ActionContext);

            if (instance != null)
            {
                bindingContext.Result = ModelBindingResult.Success(instance);
            }

            return(Task.CompletedTask);
        }
        public async Task GetOrCreateInstanceAsync_InstanceAlreadyExists_ReturnsExistingInstance()
        {
            // Arrange
            var key       = "test-flow";
            var stateType = typeof(TestState);
            var state     = new TestState();

            var flowDescriptor = new FormFlowDescriptor(key, stateType, IdGenerationSource.RandomId);

            var stateProvider = new InMemoryInstanceStateProvider();

            var instanceId = FormFlowInstanceId.GenerateForRandomId();

            var existingInstance = FormFlowInstance.Create(
                stateProvider,
                key,
                instanceId,
                stateType,
                state,
                new Dictionary <object, object>());

            var httpContext = new DefaultHttpContext();

            httpContext.Features.Set(new FormFlowInstanceFeature(existingInstance));

            var routeData = new RouteData();

            var actionDescriptor = new ActionDescriptor();

            actionDescriptor.SetProperty(flowDescriptor);

            var actionContext = new ActionContext(httpContext, routeData, actionDescriptor);

            var instanceFactory = new FormFlowInstanceFactory(flowDescriptor, actionContext, stateProvider);

            // Act
            var instance = await instanceFactory.GetOrCreateInstanceAsync(() => Task.FromResult(new TestState()));

            // Assert
            Assert.Same(existingInstance, instance);
        }
Beispiel #15
0
        public FormFlowInstance CreateInstance(
            string key,
            FormFlowInstanceId instanceId,
            Type stateType,
            object state,
            IReadOnlyDictionary <object, object> properties)
        {
            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }

            if (stateType == null)
            {
                throw new ArgumentNullException(nameof(stateType));
            }

            if (state == null)
            {
                throw new ArgumentNullException(nameof(state));
            }

            properties ??= new Dictionary <object, object>();

            var entry = new StoreEntry()
            {
                Key = key,
                StateTypeAssemblyQualifiedName = stateType.AssemblyQualifiedName,
                State      = state,
                Properties = properties,
                Completed  = false
            };
            var serialized = _stateSerializer.Serialize(entry);

            var storeKey = GetKeyForInstance(instanceId);

            _store.SetState(storeKey, serialized);

            return(FormFlowInstance.Create(this, key, instanceId, stateType, state, properties));
        }
Beispiel #16
0
        public void UpdateState_DeletedInstance_ThrowsInvalidOperationException()
        {
            // Arrange
            var instanceId = new FormFlowInstanceId("instance", new Microsoft.AspNetCore.Routing.RouteValueDictionary());

            var stateProvider = new Mock <IUserInstanceStateProvider>();

            var instance = (FormFlowInstance <MyState>)FormFlowInstance.Create(
                stateProvider.Object,
                "key",
                instanceId,
                typeof(MyState),
                new MyState(),
                properties: new Dictionary <object, object>());

            var newState = new MyState();

            instance.Complete();

            // Act & Assert
            Assert.Throws <InvalidOperationException>(() => instance.UpdateState(newState));
        }
Beispiel #17
0
        public void Delete_CallsDeleteOnStateProvider()
        {
            // Arrange
            var instanceId = new FormFlowInstanceId("instance", new Microsoft.AspNetCore.Routing.RouteValueDictionary());

            var stateProvider = new Mock <IUserInstanceStateProvider>();

            var instance = (FormFlowInstance <MyState>)FormFlowInstance.Create(
                stateProvider.Object,
                "key",
                instanceId,
                typeof(MyState),
                new MyState(),
                properties: new Dictionary <object, object>());

            var newState = new MyState();

            // Act
            instance.Complete();

            // Assert
            stateProvider.Verify(mock => mock.CompleteInstance(instanceId));
        }
Beispiel #18
0
        public FormFlowInstance GetInstance(FormFlowInstanceId instanceId)
        {
            var storeKey = GetKeyForInstance(instanceId);

            if (_store.TryGetState(storeKey, out var serialized))
            {
                var entry = (StoreEntry)_stateSerializer.Deserialize(serialized);

                var stateType = Type.GetType(entry.StateTypeAssemblyQualifiedName);

                return(FormFlowInstance.Create(
                           this,
                           entry.Key,
                           instanceId,
                           stateType,
                           entry.State,
                           entry.Properties,
                           entry.Completed));
            }
            else
            {
                return(null);
            }
        }
 public Handler(FormFlowInstance <EditVenueFlowModel> formFlowInstance)
 {
     _formFlowInstance = formFlowInstance;
 }
        public IActionResult Cancel(FormFlowInstance formFlowInstance)
        {
            formFlowInstance.Delete();

            return RedirectToAction("Index", "Venues");
        }
        public void OnActionExecuting_InstanceArgumentIsBound_DoesNotSetResult()
        {
            // Arrange
            var key       = "key";
            var stateType = typeof(MyState);

            MissingInstanceHandler handler = (flowDescriptor, httpContext) => new CustomResult();

            var options = new FormFlowOptions()
            {
                MissingInstanceHandler = handler
            };

            var services = new ServiceCollection()
                           .AddSingleton(Options.Create(options))
                           .BuildServiceProvider();

            var flowDescriptor = new FormFlowDescriptor(key, stateType, IdGenerationSource.RandomId);

            var httpContext = new DefaultHttpContext();

            httpContext.RequestServices = services;

            var routeData = new RouteData();

            var actionDescriptor = new ActionDescriptor()
            {
                Parameters = new List <ParameterDescriptor>()
                {
                    new ParameterDescriptor()
                    {
                        Name          = "instance",
                        ParameterType = typeof(FormFlowInstance)
                    }
                }
            };

            actionDescriptor.SetProperty(flowDescriptor);

            var actionContext = new ActionContext(httpContext, routeData, actionDescriptor);

            var actionArguments = new Dictionary <string, object>()
            {
                {
                    "instance",
                    FormFlowInstance.Create(
                        new InMemoryInstanceStateProvider(),
                        key,
                        FormFlowInstanceId.GenerateForRandomId(),
                        stateType,
                        new MyState(),
                        new Dictionary <object, object>())
                }
            };

            var context = new ActionExecutingContext(
                actionContext,
                new List <IFilterMetadata>(),
                actionArguments,
                controller: null);

            var filter = new MissingInstanceActionFilter();

            // Act
            filter.OnActionExecuting(context);

            // Assert
            Assert.Null(context.Result);
        }