public void GetFeatureState_ReturnsDisabledFeatureState_ForDisabledParentFeature()
        {
            // Arrange
            var moduleId        = new ModuleId("Test");
            var parentFeatureId = new FeatureId(moduleId, "ParentFeature");
            var parentFeature   = new TestFeature(parentFeatureId);
            var childFeatureId  = new FeatureId(moduleId, parentFeatureId, "ChildFeature");
            var childFeature    = new TestFeature(childFeatureId);
            var featureProvider = CreateFeatureProvider(parentFeature, childFeature);
            var configuration   = CreateConfiguration(new Dictionary <string, string>
            {
                ["Features:Test.ParentFeature:Enabled"] = "false",
                ["Features:Test.ParentFeature.ChildFeature:Enabled"] = "true"
            });
            var featureStateProvider = new FeatureStateProvider(featureProvider, configuration);

            // Act
            var state = featureStateProvider.GetFeatureState(childFeatureId);

            // Assert
            Assert.NotNull(state);
            Assert.Equal(childFeatureId, state.FeatureId);
            Assert.False(state.Enabled);
            Assert.NotNull(state.ConfigurationSection);
        }
Exemplo n.º 2
0
        public void CreateFeature_ReturnsFeature_ForDisabledFeatureService()
        {
            // Arrange
            var moduleId  = new ModuleId("Test");
            var featureId = new FeatureId(moduleId, "Test");
            var config    = new ConfigurationBuilder()
                            .AddInMemoryCollection(new Dictionary <string, string>
            {
                ["Features:Test.Test:Enabled"] = "false"
            })
                            .Build();
            var featureStateProvider = CreateFeatureStateProvider(
                new FeatureState(featureId, config.GetSection("Features:Test.Test"), false));
            var workContext = new WorkContext();

            var factory = new FeatureFactory <string>(featureStateProvider, workContext);

            // Act
            var feature = factory.CreateFeature(
                CreateServiceProvider((string)null),
                featureId);

            // Assert
            Assert.NotNull(feature);
            Assert.Null(feature.Service);
            Assert.False(feature.Enabled);
            Assert.True(feature.Missing);
        }
Exemplo n.º 3
0
            private bool ResolveEnabled(FeatureId featureId, IConfigurationSection section)
            {
                if (!featureId.ParentFeatureId.Equals(FeatureId.Empty))
                {
                    var parentState = GetFeatureState(featureId.ParentFeatureId);
                    if (parentState == null || !parentState.Enabled)
                    {
                        return(false);
                    }
                }

                if (bool.TryParse(section["Enabled"], out bool enabled))
                {
                    return(enabled);
                }

                if (bool.TryParse(section.Value, out enabled))
                {
                    return(enabled);
                }

                if (_rootScope != null)
                {
                    return(_rootScope.ResolveEnabled(featureId, _rootScope._section));
                }

                var feature = _featureProvider.GetFeature(featureId);

                if (feature != null)
                {
                    return(feature.EnabledByDefault);
                }

                return(false);
            }
Exemplo n.º 4
0
 /// <summary>
 /// Initialises a new instance of <see cref="Feature{TService}"/>.
 /// </summary>
 /// <param name="featureId">The feature id.</param>
 /// <param name="enabled">Is the feature enabled?</param>
 /// <param name="missing">Is the feature missing?</param>
 /// <param name="service">[Optional] The service instance.</param>
 /// <param name="configuration">[Optional] The configuration section.</param>
 public Feature(FeatureId featureId, bool enabled, bool missing, TService service = default(TService), IConfigurationSection configuration = null)
 {
     FeatureId     = featureId;
     Enabled       = enabled;
     Missing       = missing;
     Service       = service;
     Configuration = configuration;
 }
Exemplo n.º 5
0
        /// <inheritdoc />
        public FeatureState GetFeatureState(FeatureId featureId, TenantId tenantId)
        {
            if (_scopes.TryGetValue(tenantId, out FeatureStateProviderScope scope))
            {
                return(scope.GetFeatureState(featureId));
            }

            return(GetFeatureState(featureId));
        }
Exemplo n.º 6
0
        /// <summary>
        /// Resolves the feature id value.
        /// </summary>
        /// <param name="parentModuleId"></param>
        /// <param name="parentFeatureId"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        private static string ResolveValue(ModuleId parentModuleId, FeatureId parentFeatureId, string value)
        {
            if (parentFeatureId.Equals(FeatureId.Empty))
            {
                return($"{parentModuleId.Value}.{value}");
            }

            return($"{parentFeatureId.Value}.{value}");
        }
        private IFeatureStateProvider CreateFeatureStateProvider(FeatureId featureId, bool enabled)
        {
            var mock = new Mock <IFeatureStateProvider>();

            mock.Setup(fsp => fsp.GetFeatureState(It.Is <FeatureId>(fid => fid.Equals(featureId))))
            .Returns <FeatureId>(fid => new FeatureState(fid, null, enabled));

            return(mock.Object);
        }
Exemplo n.º 8
0
            /// <inheritdoc />
            public FeatureState GetFeatureState(FeatureId featureId)
            {
                if (featureId.Equals(FeatureId.Empty))
                {
                    throw new ArgumentException("The feature id must be provided and cannot be FeatureId.Empty",
                                                nameof(featureId));
                }

                return(_store.GetOrAdd(featureId, GetFeatureStateCore));
            }
Exemplo n.º 9
0
        /// <summary>
        /// Initialises a new instance of <see cref="FeatureState"/>.
        /// </summary>
        /// <param name="featureId">The feature id.</param>
        /// <param name="configurationSection">The configuration section.</param>
        /// <param name="enabled">Enabled state of the feature.</param>
        public FeatureState(FeatureId featureId, IConfigurationSection configurationSection, bool enabled)
        {
            if (!featureId.HasValue)
            {
                throw new ArgumentException("Feature id is required");
            }

            FeatureId            = featureId;
            Enabled              = enabled;
            ConfigurationSection = configurationSection;
        }
Exemplo n.º 10
0
        public void CanExplicitlyCast_FromFeatureId_ToString()
        {
            // Arrange
            var moduleId = new ModuleId("module");
            var id       = new FeatureId(moduleId, "feature");

            // Act
            string value = (string)id;

            // Assert
            Assert.Equal("module.feature", value);
        }
        private IFeature CreateFeature(FeatureId featureId, Action <FeatureInitialisationContext> onInit)
        {
            var mock = new Mock <IFeature>();

            mock.Setup(f => f.Id)
            .Returns(featureId);

            mock.Setup(f => f.Initialise(It.IsAny <FeatureInitialisationContext>()))
            .Callback <FeatureInitialisationContext>(onInit);

            return(mock.Object);
        }
Exemplo n.º 12
0
        public void WhenEquating_UsewCaseInsensitiveCompare()
        {
            // Arrange
            var moduleId = new ModuleId("module");
            var id       = new FeatureId(moduleId, "feature");

            // Act
            bool equals = id.Equals(new FeatureId(moduleId, "FEATURE"));

            // Assert
            Assert.True(equals);
        }
Exemplo n.º 13
0
        /// <summary>
        /// Initialises a new instance of <see cref="FeatureBase"/>.
        /// </summary>
        /// <param name="id">The feature id.</param>
        /// <param name="name">[Optional] The feature name.</param>
        /// <param name="description">[Optional] The feature description.</param>
        /// <param name="enabledByDefault">[Optional] Default enabled state.</param>
        protected FeatureBase(FeatureId id, string name = null, string description = null, bool enabledByDefault = false)
        {
            if (id.Equals(FeatureId.Empty))
            {
                throw new ArgumentException("The feature id value must be provided", nameof(id));
            }

            Id               = id;
            Name             = name;
            Description      = description;
            EnabledByDefault = enabledByDefault;
        }
Exemplo n.º 14
0
        public void WhenComparing_UsesCaseInsensitiveCompare()
        {
            // Arrange
            var    moduleId = new ModuleId("module");
            string value    = "feature";
            var    id       = new FeatureId(moduleId, value);

            // Act
            int compare = id.CompareTo("MODULE.FEATURE");

            // Assert
            Assert.Equal(0, compare);
        }
Exemplo n.º 15
0
        /// <inheritdoc />
        public int CompareTo(FeatureId other)
        {
            if (other.HasValue)
            {
                return(CompareTo(other.Value));
            }

            if (HasValue)
            {
                return(1);
            }

            return(0);
        }
Exemplo n.º 16
0
        public void ParentMdoule_InheritedFromParentFeature()
        {
            // Arrange
            var moduleId       = new ModuleId("module");
            var otherModuleId  = new ModuleId("otherModule");
            var featureId      = new FeatureId(moduleId, "feature");
            var otherFeatureId = new FeatureId(otherModuleId, featureId, "feature");

            // Act

            // Assert
            Assert.Equal(moduleId, otherFeatureId.ParentModuleId);
            Assert.Equal(otherModuleId, otherFeatureId.SourceModuleId);
        }
Exemplo n.º 17
0
        public void InitialisingFeatureId_CreatesNestedValue()
        {
            // Arrange
            var moduleId = new ModuleId("module");

            // Act
            var featureAId = new FeatureId(moduleId, "featureA");
            var featureBId = new FeatureId(moduleId, featureAId, "featureB");

            // Assert
            Assert.Equal("module.featureA", featureAId.Value);
            Assert.Equal("module.featureA.featureB", featureBId.Value);
            Assert.Equal(featureAId, featureBId.ParentFeatureId);
        }
Exemplo n.º 18
0
        public void Constructor_ValidatesArguments()
        {
            // Arrange
            var moduleId             = new ModuleId("Test");
            var featureId            = new FeatureId(moduleId, "Test");
            var config               = new ConfigurationBuilder().Build();
            var featureStateProvider = CreateFeatureStateProvider(
                new FeatureState(featureId, config.GetSection("Features:Test.Test"), true));

            // Act

            // Assert
            Assert.Throws <ArgumentNullException>(() => new FeatureFactory <string>(null /* featureStateProvider */, null /* workContext */));
            Assert.Throws <ArgumentNullException>(() => new FeatureFactory <string>(featureStateProvider, null /* workContext */));
        }
Exemplo n.º 19
0
            private FeatureState GetFeatureStateCore(FeatureId featureId)
            {
                var section = _section?.GetSection(featureId.Value);

                if (section == null)
                {
                    if (_rootScope != null)
                    {
                        return(_rootScope.GetFeatureState(featureId));
                    }
                    return(new FeatureState(featureId, null, false));
                }

                return(new FeatureState(featureId, section, ResolveEnabled(featureId, section)));
            }
Exemplo n.º 20
0
        public void CanEquate_AgainstFeatureId()
        {
            // Arrange
            var moduleId = new ModuleId("module");
            var id       = new FeatureId(moduleId, "feature");

            // Act
            bool equate0 = id.Equals(FeatureId.Empty);
            bool equate1 = id.Equals(new FeatureId(moduleId, "feature"));
            bool equate2 = id.Equals(new FeatureId(moduleId, "aaaa"));

            // Assert
            Assert.False(equate0);
            Assert.True(equate1);
            Assert.False(equate2);
        }
Exemplo n.º 21
0
        public void CanEquate_AgainstString()
        {
            // Arrange
            var moduleId = new ModuleId("module");
            var id       = new FeatureId(moduleId, "feature");

            // Act
            bool equate0 = id.Equals((string)null);
            bool equate1 = id.Equals("module.feature");
            bool equate2 = id.Equals("module.aaaa");

            // Assert
            Assert.False(equate0);
            Assert.True(equate1);
            Assert.False(equate2);
        }
Exemplo n.º 22
0
        public void InitialisedInstance_HasValue_WhenProvidingModuleId()
        {
            // Arrange
            var moduleId = new ModuleId("module");

            // Act
            var value = new FeatureId(moduleId, "feature");

            // Asset
            Assert.True(value.HasValue);
            Assert.True(value.ParentModuleId.HasValue);
            Assert.True(value.ParentModuleId.Equals(moduleId));
            Assert.True(value.SourceModuleId.HasValue);
            Assert.True(value.SourceModuleId.Equals(moduleId));
            Assert.Equal("feature", value.LocalValue);
            Assert.Equal("module.feature", value.Value);
        }
Exemplo n.º 23
0
        public void CanCompare_AgainstFeatureId()
        {
            // Arrange
            var moduleId = new ModuleId("module");
            var id       = new FeatureId(moduleId, "feature");

            // Act
            int compare0 = id.CompareTo(FeatureId.Empty);
            int compare1 = id.CompareTo(new FeatureId(moduleId, "feature"));
            int compare2 = id.CompareTo(new FeatureId(moduleId, "zzzz"));
            int compare3 = id.CompareTo(new FeatureId(moduleId, "aaaa"));

            // Assert
            Assert.True(1 == compare0);
            Assert.True(0 == compare1);
            Assert.True(-1 == compare2);
            Assert.True(1 == compare3);
        }
Exemplo n.º 24
0
        public void CanCompare_AgainstString()
        {
            // Arrange
            var moduleId = new ModuleId("module");
            var id       = new FeatureId(moduleId, "feature");

            // Act
            int compare0 = id.CompareTo((string)null);
            int compare1 = id.CompareTo("module.feature");
            int compare2 = id.CompareTo("module.zzzz");
            int compare3 = id.CompareTo("module.aaaa");

            // Assert
            Assert.True(1 == compare0);
            Assert.True(0 == compare1);
            Assert.True(-1 == compare2);
            Assert.True(1 == compare3);
        }
Exemplo n.º 25
0
        /// <inheritdoc />
        public IFeature <TService> CreateFeature(IServiceProvider serviceProvider, FeatureId featureId)
        {
            Ensure.IsNotNull(serviceProvider, nameof(serviceProvider));

            var state = (!_workContext.TenantId.Equals(TenantId.Empty) && !_workContext.TenantId.Equals(TenantId.Default))
                ? _featureStateProvider.GetFeatureState(featureId, _workContext.TenantId)
                : _featureStateProvider.GetFeatureState(featureId);

            var  service = serviceProvider.GetService <TService>();
            bool missing = Equals(default(TService), service);

            return(new Feature <TService>(
                       featureId,
                       state.Enabled,
                       missing,
                       service,
                       state.ConfigurationSection));
        }
Exemplo n.º 26
0
        public void GetFeatureState_ReturnsFeatureState_ForUnknownFeature()
        {
            // Arrange
            var moduleId        = new ModuleId("Test");
            var featureId       = new FeatureId(moduleId, "FeatureA");
            var featureProvider = CreateFeatureProvider();
            var configuration   = CreateConfiguration(new Dictionary <string, string>
            {
            });
            var featureStateProvider = new FeatureStateProvider(featureProvider, configuration);

            // Act
            var state = featureStateProvider.GetFeatureState(featureId);

            // Assert
            Assert.NotNull(state);
            Assert.Equal(featureId, state.FeatureId);
            Assert.False(state.Enabled);
            Assert.NotNull(state.ConfigurationSection);
        }
        public void Configure_SkipsFeatureInitialisation_WhenFeatureDisabled()
        {
            // Arrange
            FeatureInitialisationContext capturedContext = null;

            var featureId       = new FeatureId(new ModuleId("Test"), "Test");
            var serviceProvider = Mock.Of <IServiceProvider>();
            var filter          = new FeatureInitialiserStartupFilter(
                serviceProvider,
                CreateFeatureProvider(
                    CreateFeature(featureId, fic => capturedContext = fic)),
                CreateFeatureStateProvider(featureId, false));

            Action <IApplicationBuilder> configure = _ => { };

            // Act
            filter.Configure(configure);

            // Assert
            Assert.Null(capturedContext);
        }
Exemplo n.º 28
0
        public void GetFeatureState_ReturnsEnabledFeatureState_WhenConfigurationMissing_AndFeatureEnabledByDefault()
        {
            // Arrange
            var moduleId        = new ModuleId("Test");
            var featureId       = new FeatureId(moduleId, "FeatureA");
            var feature         = new TestFeature(featureId, enabledByDefault: true);
            var featureProvider = CreateFeatureProvider(feature);
            var configuration   = CreateConfiguration(new Dictionary <string, string>
            {
            });
            var featureStateProvider = new FeatureStateProvider(featureProvider, configuration);

            // Act
            var state = featureStateProvider.GetFeatureState(featureId);

            // Assert
            Assert.NotNull(state);
            Assert.Equal(featureId, state.FeatureId);
            Assert.True(state.Enabled);
            Assert.NotNull(state.ConfigurationSection);
        }
Exemplo n.º 29
0
        /// <summary>
        /// Initialises a new instance of <see cref="FeatureId"/>.
        /// </summary>
        /// <param name="sourceModuleId">The source module id.</param>
        /// <param name="parentFeatureId">The parent feature id.</param>
        /// <param name="value">The feature id value.</param>
        public FeatureId(ModuleId sourceModuleId, FeatureId parentFeatureId, string value)
        {
            if (sourceModuleId.Equals(ModuleId.Empty))
            {
                throw new ArgumentException("The source module id must be provided and cannot be ModuleId.Empty",
                                            nameof(sourceModuleId));
            }

            if (parentFeatureId.Equals(Empty))
            {
                throw new ArgumentException("The parent feature id must be provided and cannot be FeatureId.Empty",
                                            nameof(parentFeatureId));
            }

            HasValue              = true;
            ParentModuleId        = parentFeatureId.ParentModuleId;
            SourceModuleId        = sourceModuleId;
            _parentFeatureIdThunk = new Lazy <FeatureId>(() => parentFeatureId);

            LocalValue = Ensure.IsNotNullOrEmpty(value, nameof(value));
            Value      = ResolveValue(ParentModuleId, parentFeatureId, value);
        }
Exemplo n.º 30
0
        public void GetFeatureState_ReturnsDisabledFeatureState_ForNestedBooleanValue()
        {
            // Arrange
            var moduleId        = new ModuleId("Test");
            var featureId       = new FeatureId(moduleId, "FeatureA");
            var feature         = new TestFeature(featureId);
            var featureProvider = CreateFeatureProvider(feature);
            var configuration   = CreateConfiguration(new Dictionary <string, string>
            {
                ["Features:Test.FeatureA:Enabled"] = "false"
            });
            var featureStateProvider = new FeatureStateProvider(featureProvider, configuration);

            // Act
            var state = featureStateProvider.GetFeatureState(featureId);

            // Assert
            Assert.NotNull(state);
            Assert.Equal(featureId, state.FeatureId);
            Assert.False(state.Enabled);
            Assert.NotNull(state.ConfigurationSection);
        }