Exemple #1
0
        public static FormFlowInstanceId GenerateForRouteValues(
            FormFlowDescriptor flowDescriptor,
            HttpRequest httpRequest,
            RouteData routeData)
        {
            if (flowDescriptor == null)
            {
                throw new ArgumentNullException(nameof(flowDescriptor));
            }

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

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

            if (flowDescriptor.IdGenerationSource != IdGenerationSource.RouteValues)
            {
                throw new ArgumentException(
                          $"{nameof(flowDescriptor)}'s {nameof(flowDescriptor.IdGenerationSource)} must be {IdGenerationSource.RouteValues}.");
            }

            if (!TryResolveForRouteValues(flowDescriptor, routeData, out var instanceId))
            {
                var routeParameterNameList = string.Join(", ", flowDescriptor.IdRouteParameterNames);
                throw new InvalidOperationException(
                          $"One or more route parameters are missing. Flow requires: {routeParameterNameList}.");
            }

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

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

            var httpContext = new DefaultHttpContext();

            var routeData = new RouteData();

            var actionDescriptor = new ActionDescriptor();

            actionDescriptor.SetProperty(flowDescriptor);

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

            var stateProvider = new Mock <IUserInstanceStateProvider>();

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

            // Act & Assert
            await Assert.ThrowsAsync <InvalidOperationException>(
                () => instanceFactory.GetOrCreateInstanceAsync(() => Task.FromResult(new AnotherTestState())));
        }
Exemple #3
0
        public static FormFlowInstanceId Generate(
            FormFlowDescriptor flowDescriptor,
            HttpRequest httpRequest,
            RouteData routeData)
        {
            if (flowDescriptor == null)
            {
                throw new ArgumentNullException(nameof(flowDescriptor));
            }

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

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

            if (flowDescriptor.IdGenerationSource == IdGenerationSource.RandomId)
            {
                return(GenerateForRandomId());
            }
            else if (flowDescriptor.IdGenerationSource == IdGenerationSource.RouteValues)
            {
                return(GenerateForRouteValues(flowDescriptor, httpRequest, routeData));
            }
            else
            {
                throw new NotSupportedException($"Unknown IdGenerationSource: '{flowDescriptor.IdGenerationSource}'.");
            }
        }
        public async Task GetOrCreateInstanceAsync_InstanceDoesNotAlreadyExist_CreatesNewInstance()
        {
            // 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 httpContext = new DefaultHttpContext();

            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);

            var newState = new TestState();

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

            // Assert
            Assert.NotNull(instance);
            Assert.Same(newState, instance.State);
        }
Exemple #5
0
 public FormFlowInstanceFactory(
     FormFlowDescriptor flowDescriptor,
     ActionContext actionContext,
     IUserInstanceStateProvider stateProvider)
 {
     _flowDescriptor = flowDescriptor ?? throw new ArgumentNullException(nameof(flowDescriptor));
     _actionContext  = actionContext ?? throw new ArgumentNullException(nameof(actionContext));
     _stateProvider  = stateProvider ?? throw new ArgumentNullException(nameof(stateProvider));
 }
        public void OnActionExecuting_OptionsHaveNullHandler_DoesNotSetResult()
        {
            // Arrange
            var key       = "key";
            var stateType = typeof(MyState);

            MissingInstanceHandler handler = null;

            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>();

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

            var filter = new MissingInstanceActionFilter();

            // Act
            filter.OnActionExecuting(context);

            // Assert
            Assert.Null(context.Result);
        }
        public void CreateInstance_CreatesInstanceWithStateProvider()
        {
            // Arrange
            var key       = "test-flow";
            var stateType = typeof(TestState);

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

            var httpContext = new DefaultHttpContext();

            var routeData = new RouteData();

            var actionDescriptor = new ActionDescriptor();

            actionDescriptor.SetProperty(flowDescriptor);

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

            var stateProvider = new InMemoryInstanceStateProvider();

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

            var state      = new TestState();
            var properties = new Dictionary <object, object>()
            {
                { "foo", 42 },
                { "bar", "baz" }
            };

            // Act
            var instance = instanceFactory.CreateInstance(state, properties);

            // Assert
            Assert.NotNull(instance);
            Assert.Equal(key, instance.Key);
            Assert.Equal(stateType, instance.StateType);
            Assert.Same(state, instance.State);
            Assert.Equal(2, instance.Properties.Count);
            Assert.Equal(42, instance.Properties["foo"]);
            Assert.Equal("baz", instance.Properties["bar"]);

            var feature = httpContext.Features.Get <FormFlowInstanceFeature>();

            Assert.NotNull(feature);
            Assert.Same(instance, feature.Instance);
        }
        public void TryResolve_RandomIdGenerationSourceMissingQueryParameter_ReturnsFalse()
        {
            // Arrange
            var flowDescriptor = new FormFlowDescriptor(
                key: "key",
                stateType: typeof(MyState),
                idGenerationSource: IdGenerationSource.RandomId);

            var httpContext = new DefaultHttpContext();

            var routeData = new RouteData();

            // Act
            var created = FormFlowInstanceId.TryResolve(flowDescriptor, httpContext.Request, routeData, out var instanceId);

            // Assert
            Assert.False(created);
        }
Exemple #9
0
        public static bool TryResolveForRouteValues(
            FormFlowDescriptor flowDescriptor,
            RouteData routeData,
            out FormFlowInstanceId instanceId)
        {
            if (flowDescriptor == null)
            {
                throw new ArgumentNullException(nameof(flowDescriptor));
            }

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

            if (flowDescriptor.IdGenerationSource != IdGenerationSource.RouteValues)
            {
                throw new ArgumentException(
                          $"{nameof(flowDescriptor)}'s {nameof(flowDescriptor.IdGenerationSource)} must be {IdGenerationSource.RouteValues}.");
            }

            var routeValues = routeData.Values;

            var instanceRouteValues = new RouteValueDictionary();

            foreach (var routeParam in flowDescriptor.IdRouteParameterNames)
            {
                var routeValue = routeValues[routeParam]?.ToString();

                if (string.IsNullOrEmpty(routeValue))
                {
                    instanceId = default;
                    return(false);
                }

                instanceRouteValues.Add(routeParam, routeValue);
            }

            var id = GenerateIdForRouteValues(flowDescriptor.Key, instanceRouteValues);

            instanceId = new FormFlowInstanceId(id, instanceRouteValues);
            return(true);
        }
        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);
        }
        public void TryResolve_RandomIdGenerationSourceContainsQueryParameter_ReturnsTrue()
        {
            // Arrange
            var flowDescriptor = new FormFlowDescriptor(
                key: "key",
                stateType: typeof(MyState),
                idGenerationSource: IdGenerationSource.RandomId);

            var httpContext = new DefaultHttpContext();

            httpContext.Request.QueryString = new QueryString("?ffiid=some-id");

            var routeData = new RouteData();

            // Act
            var created = FormFlowInstanceId.TryResolve(flowDescriptor, httpContext.Request, routeData, out var instanceId);

            // Assert
            Assert.True(created);
            Assert.Equal("some-id", instanceId.ToString());
        }
        public void CreateInstance_RouteValuesIdGenerationSource_CreatesInstanceWithGeneratedId()
        {
            // Arrange
            var key       = "test-flow";
            var stateType = typeof(TestState);

            var flowDescriptor = new FormFlowDescriptor(
                key,
                stateType,
                IdGenerationSource.RouteValues,
                idRouteParameterNames: new[] { "id1", "id2" });

            var httpContext = new DefaultHttpContext();

            var routeData = new RouteData(new RouteValueDictionary()
            {
                { "id1", "foo" },
                { "id2", "bar" }
            });

            var actionDescriptor = new ActionDescriptor();

            actionDescriptor.SetProperty(flowDescriptor);

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

            var stateProvider = new InMemoryInstanceStateProvider();

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

            var state = new TestState();

            // Act
            var instance = instanceFactory.CreateInstance(state);

            // Assert
            Assert.NotNull(instance);
            Assert.Equal("test-flow?id1=foo&id2=bar", instance.InstanceId);
        }
        public void TryResolve_RouteValuesGenerationSourceMissingRouteParameter_ReturnsFalse()
        {
            // Arrange
            var flowDescriptor = new FormFlowDescriptor(
                key: "key",
                stateType: typeof(MyState),
                idGenerationSource: IdGenerationSource.RouteValues,
                idRouteParameterNames: new[] { "id1", "id2" });

            var httpContext = new DefaultHttpContext();

            var routeData = new RouteData(new RouteValueDictionary()
            {
                { "id1", "foo" }
            });

            // Act
            var created = FormFlowInstanceId.TryResolve(flowDescriptor, httpContext.Request, routeData, out var instanceId);

            // Assert
            Assert.False(created);
        }
        public void TryResolve_RouteValuesGenerationSourceContainsAllRouteParameters_ReturnsTrue()
        {
            // Arrange
            var flowDescriptor = new FormFlowDescriptor(
                key: "key",
                stateType: typeof(MyState),
                idGenerationSource: IdGenerationSource.RouteValues,
                idRouteParameterNames: new[] { "id1", "id2" });

            var httpContext = new DefaultHttpContext();

            var routeData = new RouteData(new RouteValueDictionary()
            {
                { "id1", "foo" },
                { "id2", "bar" }
            });

            // Act
            var created = FormFlowInstanceId.TryResolve(flowDescriptor, httpContext.Request, routeData, out var instanceId);

            // Assert
            Assert.True(created);
            Assert.Equal("key?id1=foo&id2=bar", instanceId.ToString());
        }
        private void AddMetadataToAction(ActionModel action)
        {
            var descriptor = new FormFlowDescriptor(Key, StateType, IdGenerationSource, IdRouteParameterNames);

            action.Properties.Add(typeof(FormFlowDescriptor), descriptor);
        }