public void EnsureFeatureActivation_WhenWebScopedFeatureNotActivated_ShouldActivate()
        {
            using (var testScope = SiteTestScope.BlankSite())
            {
                // Arrange
                var web = testScope.SiteCollection.RootWeb;

                var featureDependency = new FeatureDependencyInfo()
                {
                    Name = "OOTB task list",
                    FeatureId = new Guid("00BFEA71-A83E-497E-9BA0-7A5C597D0107"),
                    FeatureActivationMode = FeatureActivationMode.CurrentWeb
                };

                using (var injectionScope = IntegrationTestServiceLocator.BeginLifetimeScope())
                {
                    var featureDependencyActivator = injectionScope.Resolve<IFeatureDependencyActivator>(new TypedParameter(typeof(SPWeb), web));

                    // Act
                    featureDependencyActivator.EnsureFeatureActivation(featureDependency);

                    // Assert
                    var isFeatureActivated = web.Features.Any(feature => feature.DefinitionId.Equals(featureDependency.FeatureId));
                    Assert.IsTrue(isFeatureActivated);
                }
            }
        }
        public void EnsureFeatureActivation_WhenSiteScopedFeatureNotActivated_ShouldActivate()
        {
            using (var testScope = SiteTestScope.BlankSite())
            {
                // Arrange
                var site = testScope.SiteCollection;

                // Use the "GSoft.Dynamite Javascript Imports" site scoped feature
                var featureDependency = new FeatureDependencyInfo()
                {
                    FeatureId = new Guid("7ed769f5-b01b-4597-9a91-3cfcdf8cc49a"),
                    FeatureActivationMode = FeatureActivationMode.CurrentSite
                };

                using (var injectionScope = IntegrationTestServiceLocator.BeginLifetimeScope())
                {
                    var featureDependencyActivator = injectionScope.Resolve<IFeatureDependencyActivator>(new TypedParameter(typeof(SPSite), site));

                    // Act
                    featureDependencyActivator.EnsureFeatureActivation(featureDependency);

                    // Assert
                    var isFeatureActivated = site.Features.Any(feature => feature.DefinitionId.Equals(featureDependency.FeatureId));
                    Assert.IsTrue(isFeatureActivated);
                }
            }
        }
        /// <summary>
        /// Ensures the feature activation.
        /// </summary>
        /// <param name="featureDependency">The feature dependency.</param>
        public void EnsureFeatureActivation(FeatureDependencyInfo featureDependency)
        {
            // Validate arguments
            if (featureDependency.FeatureId.Equals(Guid.Empty))
            {
                throw new ArgumentException("Feature ID is empty in FeatureDependencyInfo", "featureDependency");
            }

            switch (featureDependency.FeatureActivationMode)
            {
                case FeatureActivationMode.CurrentSite:

                    if (this.currentSite != null)
                    {
                        this.logger.Info(
                            "Activating the feature with id '{0}'on site '{1}'.",
                            featureDependency.FeatureId,
                            this.currentSite.Url);

                        this.InnerEnsureFeatureActivation(featureDependency, this.currentSite.Features);
                    }
                    else
                    {
                        throw new InvalidOperationException(@"Please ensure you specified the correct 'FeatureActivationMode' 
                            and injected the 'currentSite' parameter in the constructor.");
                    }

                    break;

                case FeatureActivationMode.CurrentWeb:

                    if (this.currentWeb != null)
                    {
                        this.logger.Info(
                            "Activating the feature with id '{0}'on web '{1}'.",
                            featureDependency.FeatureId,
                            this.currentWeb.Url);

                        this.InnerEnsureFeatureActivation(featureDependency, this.currentWeb.Features);
                    }
                    else
                    {
                        throw new InvalidOperationException(@"Please ensure you specified the correct 'FeatureActivationMode' 
                            and injected the 'currentWeb' parameter in the constructor.");
                    }

                    break;

                default:
                    throw new NotImplementedException("Only the 'CurrentSite' and 'CurrentWeb' activation modes are currently supported.");
            }
        }
        private void InnerEnsureFeatureActivation(FeatureDependencyInfo featureDependency, SPFeatureCollection featureCollection)
        {
            // If already activated
            if (featureCollection.Any(sf => sf.DefinitionId == featureDependency.FeatureId))
            {
                if (featureDependency.ForceReactivation)
                {
                    this.logger.Info(
                        "Disactivating the feature with id '{0}' because the 'ForceReactivation' property was used.",
                        featureDependency.FeatureId);

                    // Deactivate and reactivate feature
                    featureCollection.Remove(featureDependency.FeatureId);
                    featureCollection.Add(featureDependency.FeatureId);
                }
                else
                {
                    this.logger.Warn(
                        @"Feature with id '{0}' is already activated. If you wish to force 
                        it's reactivation, please use the 'ForceReactivation' property.",
                        featureDependency.FeatureId);
                }
            }
            else
            {
                // Activate feature
                featureCollection.Add(featureDependency.FeatureId);
            }
        }
        public void EnsureFeatureActivation_WhenFeatureActivatedWithNoIdSpecified_ShouldThrowArgumentException()
        {
            using (var testScope = SiteTestScope.BlankSite())
            {
                // Arrange
                var site = testScope.SiteCollection;

                var featureDependency = new FeatureDependencyInfo()
                {
                    Name = "Unknown feature because there's no ID",
                    FeatureActivationMode = FeatureActivationMode.CurrentSite
                };

                using (var injectionScope = IntegrationTestServiceLocator.BeginLifetimeScope())
                {
                    var featureDependencyActivator = injectionScope.Resolve<IFeatureDependencyActivator>(new TypedParameter(typeof(SPSite), site));

                    // Act
                    featureDependencyActivator.EnsureFeatureActivation(featureDependency);

                    // Assert argument exception
                }
            }
        }
        public void EnsureFeatureActivation_WhenWebScopedFeatureActivatedOnWrongScope_ShouldThrowInvalidOperationException()
        {
            using (var testScope = SiteTestScope.BlankSite())
            {
                // Arrange
                var site = testScope.SiteCollection;

                var featureDependency = new FeatureDependencyInfo()
                {
                    Name = "OOTB task list on wrong scope",
                    FeatureId = new Guid("00BFEA71-A83E-497E-9BA0-7A5C597D0107"),
                    FeatureActivationMode = FeatureActivationMode.CurrentSite
                };

                using (var injectionScope = IntegrationTestServiceLocator.BeginLifetimeScope())
                {
                    var featureDependencyActivator = injectionScope.Resolve<IFeatureDependencyActivator>(new TypedParameter(typeof(SPSite), site));

                    // Act
                    featureDependencyActivator.EnsureFeatureActivation(featureDependency);

                    // Assert invalid operation exception
                }
            }
        }