diff --git a/DNN Platform/DotNetNuke.Abstractions/Application/IApplicationInfo.cs b/DNN Platform/DotNetNuke.Abstractions/Application/IApplicationInfo.cs new file mode 100644 index 00000000000..f60c655a2c0 --- /dev/null +++ b/DNN Platform/DotNetNuke.Abstractions/Application/IApplicationInfo.cs @@ -0,0 +1,113 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information + +namespace DotNetNuke.Abstractions.Application +{ + using System; + + /// + /// The Application class contains properties that describe the DotNetNuke Application. + /// + public interface IApplicationInfo + { + /// + /// Gets the company to which the DotNetNuke application is related. + /// + /// Fixed result: DotNetNuke Corporation. + string Company { get; } + + /// + /// Gets the version of the currently installed DotNetNuke framework/application + /// Can be prior to Version, if the application is pending to be upgraded. + /// + /// The version as retreieved from the database version table. + Version CurrentVersion { get; } + + /// + /// Gets the description of the application. + /// + /// Fixed result: DNN Platform. + string Description { get; } + + /// + /// Gets the help URL related to the DotNetNuke application. + /// + /// Fixed result: https://dnndocs.com/. + string HelpUrl { get; } + + /// + /// Gets the legal copyright. + /// + /// Dynamic: DNN Platform is copyright 2002-todays year by .NET Foundation". + string LegalCopyright { get; } + + /// + /// Gets the name of the application. + /// + /// Fixed result: DNNCORP.CE. + string Name { get; } + + /// + /// Gets the SKU (Stock Keeping Unit). + /// + /// Fixed result: DNN. + string SKU { get; } + + /// + /// Gets the status of the DotnetNuke application. + /// + /// + /// If the value is not be Stable, you will see the exactly status and version in page's title if allow display beta message in host setting. + /// + /// + /// The value can be: None, Alpha, Beta, RC, Stable. + /// + ReleaseMode Status { get; } + + /// + /// Gets the title of the application. + /// + /// Fixed value: DotNetNuke. + string Title { get; } + + /// + /// Gets the trademark. + /// + /// Fixed value: DotNetNuke,DNN. + string Trademark { get; } + + /// + /// Gets the type of the application. + /// + /// Fixed value: Framework. + string Type { get; } + + /// + /// Gets the upgrade URL. + /// + /// Fixed value: https://dnnplatform.io. + string UpgradeUrl { get; } + + /// + /// Gets the URL of the application. + /// + /// Fixed value: https://dnncommunity.org. + string Url { get; } + + /// + /// Gets the version of the DotNetNuke framework/application. + /// + /// The version as retreieved from the Executing assembly. + Version Version { get; } + + /// + /// Determine whether a product specific change is to be applied. + /// + /// list of product names. + /// true if product is within list of names. + /// + /// + bool ApplyToProduct(string productNames); + } +} diff --git a/DNN Platform/DotNetNuke.Abstractions/Application/IApplicationStatusInfo.cs b/DNN Platform/DotNetNuke.Abstractions/Application/IApplicationStatusInfo.cs new file mode 100644 index 00000000000..a1a1b7d9f18 --- /dev/null +++ b/DNN Platform/DotNetNuke.Abstractions/Application/IApplicationStatusInfo.cs @@ -0,0 +1,78 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information + +namespace DotNetNuke.Abstractions.Application +{ + using System; + + /// + /// The Application Status Info, includes information about installation + /// and database version. + /// + public interface IApplicationStatusInfo + { + /// + /// Gets the status of application. + /// + UpgradeStatus Status { get; } + + /// + /// Gets the application map path. + /// + /// + /// The application map path. + /// + string ApplicationMapPath { get; } + + /// + /// Gets the database version. + /// + Version DatabaseVersion { get; } + + /// + /// IsInstalled looks at various file artifacts to determine if DotNetNuke has already been installed. + /// + /// true if installed else false. + /// + /// If DotNetNuke has been installed, then we should treat database connection errors as real errors. + /// If DotNetNuke has not been installed, then we should expect to have database connection problems + /// since the connection string may not have been configured yet, which can occur during the installation + /// wizard. + /// + bool IsInstalled(); + + /// + /// Sets the status. + /// + /// The status. + void SetStatus(UpgradeStatus status); + + /// + /// Updates the database version. + /// + /// The version. + void UpdateDatabaseVersion(Version version); + + /// + /// Updates the database version. + /// + /// The version. + /// The increment. + void UpdateDatabaseVersionIncrement(Version version, int increment); + + /// + /// Needs documentation. + /// + /// The version. + /// true is success else false. + bool IncrementalVersionExists(Version version); + + /// + /// Get the last application iteration. + /// + /// The version. + /// The result. + int GetLastAppliedIteration(Version version); + } +} diff --git a/DNN Platform/DotNetNuke.Abstractions/Application/IDnnContext.cs b/DNN Platform/DotNetNuke.Abstractions/Application/IDnnContext.cs new file mode 100644 index 00000000000..c65e6a9e66e --- /dev/null +++ b/DNN Platform/DotNetNuke.Abstractions/Application/IDnnContext.cs @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information + +namespace DotNetNuke.Abstractions.Application +{ + /// + /// Defines the context for the environment of the DotNetNuke application. + /// + public interface IDnnContext + { + /// + /// Gets get the application. + /// + IApplicationInfo Application { get; } + } +} diff --git a/DNN Platform/DotNetNuke.Abstractions/Application/ReleaseMode.cs b/DNN Platform/DotNetNuke.Abstractions/Application/ReleaseMode.cs new file mode 100644 index 00000000000..c0d337ff250 --- /dev/null +++ b/DNN Platform/DotNetNuke.Abstractions/Application/ReleaseMode.cs @@ -0,0 +1,50 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information + +namespace DotNetNuke.Abstractions.Application +{ + /// + /// The enumeration of release mode. + /// + /// + /// + /// None: Not specified for the current release. + /// Alpha:Alpha release is an opportunity for customers to get an early look at a particular software feature. + /// Beta: Beta release is a mostly completed release, + /// At this point we will have implemented most of the major features planned for a specific release. + /// RC: RC release will be the Stable release if there is no major show-stopping bugs, + /// We have gone through all the major test scenarios and are just running through a final set of regression + /// tests and verifying the packaging. + /// Stable: Stable release is believed to be ready for use, + /// remember that only stable release can be used in production environment. + /// + /// + public enum ReleaseMode + { + /// + /// Not asssigned + /// + None = 0, + + /// + /// Alpha release + /// + Alpha = 1, + + /// + /// Beta release + /// + Beta = 2, + + /// + /// Release candidate + /// + RC = 3, + + /// + /// Stable release version + /// + Stable = 4, + } +} diff --git a/DNN Platform/DotNetNuke.Abstractions/Application/UpgradeStatus.cs b/DNN Platform/DotNetNuke.Abstractions/Application/UpgradeStatus.cs new file mode 100644 index 00000000000..b9304d4ad5b --- /dev/null +++ b/DNN Platform/DotNetNuke.Abstractions/Application/UpgradeStatus.cs @@ -0,0 +1,38 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information + +namespace DotNetNuke.Abstractions.Application +{ + /// + /// Enumeration Of Application upgrade status. + /// + public enum UpgradeStatus + { + /// + /// The application need update to a higher version. + /// + Upgrade = 0, + + /// + /// The application need to install itself. + /// + Install = 1, + + /// + /// The application is normal running. + /// + None = 2, + + /// + /// The application occur error when running. + /// + Error = 3, + + /// + /// The application status is unknown, + /// + /// This status should never be returned. its is only used as a flag that Status hasn't been determined. + Unknown = 4, + } +} diff --git a/DNN Platform/DotNetNuke.Web/Common/LazyServiceProvider.cs b/DNN Platform/DotNetNuke.Web/Common/LazyServiceProvider.cs index 9c65cea9926..bb29fbd71f0 100644 --- a/DNN Platform/DotNetNuke.Web/Common/LazyServiceProvider.cs +++ b/DNN Platform/DotNetNuke.Web/Common/LazyServiceProvider.cs @@ -5,28 +5,30 @@ namespace DotNetNuke.Web.Common { using System; - using System.Collections.Generic; - using System.Linq; - using System.Text; - using System.Threading.Tasks; + using System.ComponentModel; - public class LazyServiceProvider : IServiceProvider + public class LazyServiceProvider : IServiceProvider, INotifyPropertyChanged { - private IServiceProvider _serviceProvider; - + private IServiceProvider serviceProvider; + + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// public object GetService(Type serviceType) { - if (this._serviceProvider is null) + if (this.serviceProvider is null) { throw new Exception("Cannot resolve services until the service provider is built."); } - return this._serviceProvider.GetService(serviceType); + return this.serviceProvider.GetService(serviceType); } internal void SetProvider(IServiceProvider serviceProvider) { - this._serviceProvider = serviceProvider; + this.serviceProvider = serviceProvider; + this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(serviceProvider))); } } } diff --git a/DNN Platform/Library/Application/Application.cs b/DNN Platform/Library/Application/Application.cs index 194b44e673c..e1d0f12c589 100644 --- a/DNN Platform/Library/Application/Application.cs +++ b/DNN Platform/Library/Application/Application.cs @@ -1,233 +1,193 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information -namespace DotNetNuke.Application -{ - using System; - using System.Diagnostics; - using System.Reflection; +namespace DotNetNuke.Application +{ + using System; + using System.Diagnostics; + using System.Reflection; - using DotNetNuke.Common.Utilities; + using DotNetNuke.Abstractions.Application; + using DotNetNuke.Common.Utilities; using DotNetNuke.Data; - /// - /// The Application class contains properties that describe the DotNetNuke Application. - /// - /// - /// - public class Application - { - private static ReleaseMode _status = ReleaseMode.None; - - protected internal Application() - { - } - - /// - /// Gets the company to which the DotNetNuke application is related. - /// - /// Fixed result: DotNetNuke Corporation. - public string Company - { - get - { - return "DNN Corporation"; - } - } - - /// - /// Gets the version of the currently installed DotNetNuke framework/application - /// Can be prior to Version, if the application is pending to be upgraded. - /// - /// The version as retreieved from the database version table. - public virtual Version CurrentVersion - { - get - { - return DataProvider.Instance().GetVersion(); - } - } - - /// - /// Gets the description of the application. - /// - /// Fixed result: DNN Platform. - public virtual string Description - { - get - { - return "DNN Platform"; - } - } - - /// - /// Gets the help URL related to the DotNetNuke application. - /// - /// Fixed result: https://dnndocs.com/. - public string HelpUrl - { - get - { - return "https://dnndocs.com/"; - } - } - - /// - /// Gets the legal copyright. - /// - /// Dynamic: DNN Platform is copyright 2002-todays year by .NET Foundation". - public string LegalCopyright - { - get - { - return string.Concat("DNN Platform is copyright 2002-", DateTime.Today.ToString("yyyy"), " by .NET Foundation"); - } - } - - /// - /// Gets the name of the application. - /// - /// Fixed result: DNNCORP.CE. - public virtual string Name - { - get - { - return "DNNCORP.CE"; - } - } - - /// - /// Gets the SKU (Stock Keeping Unit). - /// - /// Fixed result: DNN. - public virtual string SKU - { - get - { - return "DNN"; - } - } - - /// - /// Gets the status of the DotnetNuke application. - /// - /// - /// If the value is not be Stable, you will see the exactly status and version in page's title if allow display beta message in host setting. - /// - /// - /// The value can be: None, Alpha, Beta, RC, Stable. - /// - public ReleaseMode Status - { - get - { - if (_status == ReleaseMode.None) - { - Assembly assy = Assembly.GetExecutingAssembly(); - if (Attribute.IsDefined(assy, typeof(AssemblyStatusAttribute))) - { - Attribute attr = Attribute.GetCustomAttribute(assy, typeof(AssemblyStatusAttribute)); - if (attr != null) - { - _status = ((AssemblyStatusAttribute)attr).Status; - } - } - } - - return _status; - } - } - - /// - /// Gets the title of the application. - /// - /// Fixed value: DotNetNuke. - public string Title - { - get - { - return "DotNetNuke"; - } - } - - /// - /// Gets the trademark. - /// - /// Fixed value: DotNetNuke,DNN. - public string Trademark - { - get - { - return "DotNetNuke,DNN"; - } - } - - /// - /// Gets the type of the application. - /// - /// Fixed value: Framework. - public string Type - { - get - { - return "Framework"; - } - } - - /// - /// Gets the upgrade URL. - /// - /// Fixed value: https://dnnplatform.io. - public string UpgradeUrl - { - get - { - var url = Config.GetSetting("UpdateServiceUrl"); - if (string.IsNullOrEmpty(url)) - { - return "https://dnnplatform.io"; - } - - return url; - } - } - - /// - /// Gets the URL of the application. - /// - /// Fixed value: https://dnncommunity.org. - public string Url - { - get - { - return "https://dnncommunity.org"; - } - } - - /// - /// Gets the version of the DotNetNuke framework/application. - /// - /// The version as retreieved from the Executing assembly. - public virtual Version Version - { - get - { - var assemblyLocation = Assembly.GetExecutingAssembly().Location; - var fileVersion = FileVersionInfo.GetVersionInfo(assemblyLocation).FileVersion; - return new Version(fileVersion); - } - } - - /// - /// Determine whether a product specific change is to be applied. - /// - /// list of product names. - /// true if product is within list of names. - /// - /// - public virtual bool ApplyToProduct(string productNames) - { - return productNames.Contains(this.Name); - } - } -} + using NewReleaseMode = DotNetNuke.Abstractions.Application.ReleaseMode; + + /// + public class Application : IApplicationInfo + { + private static NewReleaseMode status = NewReleaseMode.None; + + /// + /// Initializes a new instance of the class. + /// + public Application() + { + } + + /// + public string Company + { + get + { + return "DNN Corporation"; + } + } + + /// + public virtual Version CurrentVersion + { + get + { + return DataProvider.Instance().GetVersion(); + } + } + + /// + public virtual string Description + { + get + { + return "DNN Platform"; + } + } + + /// + public string HelpUrl + { + get + { + return "https://dnndocs.com/"; + } + } + + /// + public string LegalCopyright + { + get + { + return string.Concat("DNN Platform is copyright 2002-", DateTime.Today.ToString("yyyy"), " by .NET Foundation"); + } + } + + /// + public virtual string Name + { + get + { + return "DNNCORP.CE"; + } + } + + /// + public virtual string SKU + { + get + { + return "DNN"; + } + } + + /// + /// Gets the status of the DotnetNuke application. + /// + /// + /// If the value is not be Stable, you will see the exactly status and version in page's title if allow display beta message in host setting. + /// + /// + /// The value can be: None, Alpha, Beta, RC, Stable. + /// + [Obsolete("Deprecated in Platform 9.7.0. Use 'DotNetNuke.Abstractions.Application.IApplicationInfo' with Dependency Injection instead. Scheduled for removal in v11.0.0.")] + public ReleaseMode Status { get => (ReleaseMode)(this as IApplicationInfo).Status; } + + /// + NewReleaseMode IApplicationInfo.Status + { + get + { + if (status == NewReleaseMode.None) + { + Assembly assy = Assembly.GetExecutingAssembly(); + if (Attribute.IsDefined(assy, typeof(AssemblyStatusAttribute))) + { + Attribute attr = Attribute.GetCustomAttribute(assy, typeof(AssemblyStatusAttribute)); + if (attr != null) + { + status = (NewReleaseMode)((AssemblyStatusAttribute)attr).Status; + } + } + } + + return status; + } + } + + /// + public string Title + { + get + { + return "DotNetNuke"; + } + } + + /// + public string Trademark + { + get + { + return "DotNetNuke,DNN"; + } + } + + /// + public string Type + { + get + { + return "Framework"; + } + } + + /// + public string UpgradeUrl + { + get + { + var url = Config.GetSetting("UpdateServiceUrl"); + if (string.IsNullOrEmpty(url)) + { + return "https://dnnplatform.io"; + } + + return url; + } + } + + /// + public string Url + { + get + { + return "https://dnncommunity.org"; + } + } + + /// + public virtual Version Version + { + get + { + var assemblyLocation = Assembly.GetExecutingAssembly().Location; + var fileVersion = FileVersionInfo.GetVersionInfo(assemblyLocation).FileVersion; + return new Version(fileVersion); + } + } + + /// + public virtual bool ApplyToProduct(string productNames) + { + return productNames.Contains(this.Name); + } + } +} diff --git a/DNN Platform/Library/Application/ApplicationStatusInfo.cs b/DNN Platform/Library/Application/ApplicationStatusInfo.cs new file mode 100644 index 00000000000..ebfb3feac00 --- /dev/null +++ b/DNN Platform/Library/Application/ApplicationStatusInfo.cs @@ -0,0 +1,318 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information + +namespace DotNetNuke.Application +{ + using System; + using System.IO; + using System.Web; + + using DotNetNuke.Abstractions; + using DotNetNuke.Abstractions.Application; + using DotNetNuke.Common.Utilities; + using DotNetNuke.Data; + using DotNetNuke.Framework.Providers; + using DotNetNuke.Instrumentation; + using DotNetNuke.Services.Upgrade; + + + /// + public class ApplicationStatusInfo : IApplicationStatusInfo + { + private static readonly ILog Logger = LoggerSource.Instance.GetLogger(typeof(ApplicationStatusInfo)); + + private UpgradeStatus status = UpgradeStatus.Unknown; + private string applicationMapPath; + + private IApplicationInfo applicationInfo; + + /// + /// Initializes a new instance of the class. + /// + /// The application info. + /// + /// This constructor is designed to be used with Dependency Injection. + /// + public ApplicationStatusInfo(IApplicationInfo applicationInfo) + { + this.applicationInfo = applicationInfo; + } + + /// + public UpgradeStatus Status + { + get + { + if (this.status != UpgradeStatus.Unknown && this.status != UpgradeStatus.Error) + { + return this.status; + } + + Logger.Trace("Getting application status"); + var tempStatus = UpgradeStatus.None; + + // first call GetProviderPath - this insures that the Database is Initialised correctly + // and also generates the appropriate error message if it cannot be initialised correctly + string strMessage = DataProvider.Instance().GetProviderPath(); + + // get current database version from DB + if (!strMessage.StartsWith("ERROR:")) + { + try + { + this.DatabaseVersion = DataProvider.Instance().GetVersion(); + } + catch (Exception ex) + { + Logger.Error(ex); + strMessage = "ERROR:" + ex.Message; + } + } + + if (strMessage.StartsWith("ERROR")) + { + if (this.IsInstalled()) + { + // Errors connecting to the database after an initial installation should be treated as errors. + tempStatus = UpgradeStatus.Error; + } + else + { + // An error that occurs before the database has been installed should be treated as a new install + tempStatus = UpgradeStatus.Install; + } + } + else if (this.DatabaseVersion == null) + { + // No Db Version so Install + tempStatus = UpgradeStatus.Install; + } + else + { + var version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version; + if (version.Major > this.DatabaseVersion.Major) + { + // Upgrade Required (Major Version Upgrade) + tempStatus = UpgradeStatus.Upgrade; + } + else if (version.Major == this.DatabaseVersion.Major && version.Minor > this.DatabaseVersion.Minor) + { + // Upgrade Required (Minor Version Upgrade) + tempStatus = UpgradeStatus.Upgrade; + } + else if (version.Major == this.DatabaseVersion.Major && version.Minor == this.DatabaseVersion.Minor && + version.Build > this.DatabaseVersion.Build) + { + // Upgrade Required (Build Version Upgrade) + tempStatus = UpgradeStatus.Upgrade; + } + else if (version.Major == this.DatabaseVersion.Major && version.Minor == this.DatabaseVersion.Minor && + version.Build == this.DatabaseVersion.Build && this.IncrementalVersionExists(version)) + { + // Upgrade Required (Build Version Upgrade) + tempStatus = UpgradeStatus.Upgrade; + } + } + + this.status = tempStatus; + + Logger.Trace(string.Format("result of getting providerpath: {0}", strMessage)); + Logger.Trace("Application status is " + this.status); + + return this.status; + } + } + + /// + public Version DatabaseVersion { get; private set; } + + /// + public string ApplicationMapPath { get => this.applicationMapPath ?? (this.applicationMapPath = this.GetCurrentDomainDirectory()); } + + /// + public bool IsInstalled() + { + const int c_PassingScore = 4; + int installationdatefactor = Convert.ToInt32(this.HasInstallationDate() ? 1 : 0); + int dataproviderfactor = Convert.ToInt32(this.HasDataProviderLogFiles() ? 3 : 0); + int htmlmodulefactor = Convert.ToInt32(this.ModuleDirectoryExists("html") ? 2 : 0); + int portaldirectoryfactor = Convert.ToInt32(this.HasNonDefaultPortalDirectory() ? 2 : 0); + int localexecutionfactor = Convert.ToInt32(HttpContext.Current.Request.IsLocal ? c_PassingScore - 1 : 0); + + // This calculation ensures that you have a more than one item that indicates you have already installed DNN. + // While it is possible that you might not have an installation date or that you have deleted log files + // it is unlikely that you have removed every trace of an installation and yet still have a working install + bool isInstalled = (!this.IsInstallationURL()) && ((installationdatefactor + dataproviderfactor + htmlmodulefactor + portaldirectoryfactor + localexecutionfactor) >= c_PassingScore); + + // we need to tighten this check. We now are enforcing the existence of the InstallVersion value in web.config. If + // this value exists, then DNN was previously installed, and we should never try to re-install it + return isInstalled || this.HasInstallVersion(); + } + + /// + /// Sets the status. + /// + /// The status. + public void SetStatus(UpgradeStatus status) + { + this.status = status; + } + + /// + public void UpdateDatabaseVersion(Version version) + { + // update the version + DataProvider.Instance().UpdateDatabaseVersion(version.Major, version.Minor, version.Build, this.applicationInfo.Name); + this.DatabaseVersion = version; + } + + /// + public void UpdateDatabaseVersionIncrement(Version version, int increment) + { + // update the version and increment + DataProvider.Instance().UpdateDatabaseVersionIncrement(version.Major, version.Minor, version.Build, increment, DotNetNukeContext.Current.Application.Name); + this.DatabaseVersion = version; + } + + /// + public bool IncrementalVersionExists(Version version) + { + Provider currentdataprovider = Config.GetDefaultProvider("data"); + string providerpath = currentdataprovider.Attributes["providerPath"]; + + // If the provider path does not exist, then there can't be any log files + if (!string.IsNullOrEmpty(providerpath)) + { + providerpath = HttpRuntime.AppDomainAppPath + providerpath.Replace("~", string.Empty); + if (Directory.Exists(providerpath)) + { + var incrementalcount = Directory.GetFiles(providerpath, Upgrade.GetStringVersion(version) + ".*." + Upgrade.DefaultProvider).Length; + + if (incrementalcount > this.GetLastAppliedIteration(version)) + { + return true; + } + } + } + + return false; + } + + /// + public int GetLastAppliedIteration(Version version) + { + try + { + return DataProvider.Instance().GetLastAppliedIteration(version.Major, version.Minor, version.Build); + } + catch (Exception) + { + return 0; + } + } + + /// + /// Determines whether current request is for install. + /// + /// + /// true if current request is for install; otherwise, false. + /// + private bool IsInstallationURL() + { + string requestURL = HttpContext.Current.Request.RawUrl.ToLowerInvariant().Replace("\\", "/"); + return requestURL.Contains("/install.aspx") || requestURL.Contains("/installwizard.aspx"); + } + + /// + /// Determines whether has installation date. + /// + /// + /// true if has installation date; otherwise, false. + /// + private bool HasInstallationDate() + { + return Config.GetSetting("InstallationDate") != null; + } + + /// + /// Determines whether has data provider log files. + /// + /// + /// true if has data provider log files; otherwise, false. + /// + private bool HasDataProviderLogFiles() + { + Provider currentdataprovider = Config.GetDefaultProvider("data"); + string providerpath = currentdataprovider.Attributes["providerPath"]; + + // If the provider path does not exist, then there can't be any log files + if (!string.IsNullOrEmpty(providerpath)) + { + providerpath = HttpContext.Current.Server.MapPath(providerpath); + if (Directory.Exists(providerpath)) + { + return Directory.GetFiles(providerpath, "*.log.resources").Length > 0; + } + } + + return false; + } + + /// + /// Check whether the modules directory is exists. + /// + /// Name of the module. + /// + /// true if the module directory exist, otherwise, false. + /// + private bool ModuleDirectoryExists(string moduleName) + { + string dir = this.ApplicationMapPath + "\\desktopmodules\\" + moduleName; + return Directory.Exists(dir); + } + + /// + /// Determines whether has portal directory except default portal directory in portal path. + /// + /// + /// true if has portal directory except default portal directory in portal path; otherwise, false. + /// + private bool HasNonDefaultPortalDirectory() + { + string dir = this.ApplicationMapPath + "\\portals"; + if (Directory.Exists(dir)) + { + return Directory.GetDirectories(dir).Length > 1; + } + + return false; + } + + /// + /// Determines whether has InstallVersion set. + /// + /// + /// true if has installation date; otherwise, false. + /// + private bool HasInstallVersion() + { + return Config.GetSetting("InstallVersion") != null; + } + + /// + /// Get the current domain directory. + /// + /// returns the domain directory. + private string GetCurrentDomainDirectory() + { + var dir = AppDomain.CurrentDomain.BaseDirectory.Replace("/", "\\"); + if (dir.Length > 3 && dir.EndsWith("\\")) + { + dir = dir.Substring(0, dir.Length - 1); + } + + return dir; + } + } +} diff --git a/DNN Platform/Library/Application/AssemblyStatusAttribute.cs b/DNN Platform/Library/Application/AssemblyStatusAttribute.cs index ad09d72bd6b..3eb927c25ce 100644 --- a/DNN Platform/Library/Application/AssemblyStatusAttribute.cs +++ b/DNN Platform/Library/Application/AssemblyStatusAttribute.cs @@ -26,27 +26,27 @@ public enum ReleaseMode /// /// Not asssigned /// - None, + None = 0, /// /// Alpha release /// - Alpha, + Alpha = 1, /// /// Beta release /// - Beta, + Beta = 2, /// /// Release candidate /// - RC, + RC = 3, /// /// Stable release version /// - Stable, + Stable = 4, } /// diff --git a/DNN Platform/Library/Application/DotNetNukeContext.cs b/DNN Platform/Library/Application/DotNetNukeContext.cs index ef2ac0dd2c6..d39b34c09b6 100644 --- a/DNN Platform/Library/Application/DotNetNukeContext.cs +++ b/DNN Platform/Library/Application/DotNetNukeContext.cs @@ -1,105 +1,105 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information -namespace DotNetNuke.Application -{ - using System.Collections.Generic; - using DotNetNuke.Collections.Internal; - using DotNetNuke.UI.Containers.EventListeners; +namespace DotNetNuke.Application +{ + using System; + using System.Collections.Generic; + + using DotNetNuke.Abstractions.Application; + using DotNetNuke.Collections.Internal; + using DotNetNuke.Common; + using DotNetNuke.UI.Containers.EventListeners; using DotNetNuke.UI.Skins.EventListeners; - /// - /// Defines the context for the environment of the DotNetNuke application. - /// - public class DotNetNukeContext - { - private static DotNetNukeContext _current; - private readonly Application _application; - private readonly IList _containerEventListeners; - private readonly IList _skinEventListeners; - - /// - /// Initializes a new instance of the class. - /// - protected DotNetNukeContext() - : this(new Application()) - { - } - - /// - /// Initializes a new instance of the class using the provided application as base. - /// - /// The application. - protected DotNetNukeContext(Application application) - { - this._application = application; - this._containerEventListeners = new NaiveLockingList(); - this._skinEventListeners = new NaiveLockingList(); - } - - /// - /// Gets or sets the current app context. - /// - public static DotNetNukeContext Current - { - get - { - if (_current == null) - { - _current = new DotNetNukeContext(); - } - - return _current; - } - - set - { - _current = value; - } - } - - /// - /// Gets get the application. - /// - public Application Application - { - get - { - return this._application; - } - } - - /// - /// Gets the container event listeners. The listeners will be called in each life cycle of load container. - /// - /// - /// - /// - /// - /// - public IList ContainerEventListeners - { - get - { - return this._containerEventListeners; - } - } - - /// - /// Gets the skin event listeners. The listeners will be called in each life cycle of load skin. - /// - /// - /// - /// - /// - /// - public IList SkinEventListeners - { - get - { - return this._skinEventListeners; - } - } - } -} + using Microsoft.Extensions.DependencyInjection; + + /// + /// Defines the context for the environment of the DotNetNuke application. + /// + public class DotNetNukeContext : IDnnContext + { + private static IDnnContext current; + private readonly IApplicationInfo applicationInfo; + + /// + /// Initializes a new instance of the class. + /// + /// + /// Initialize using the public constructor for Dependency Injection, this method will be removed. + /// + [Obsolete("Deprecated in DotNetNuke 9.7.1. This constructor has been replaced by parameterized public constructor which is designed to be used with Dependency Injection. Resolve the new interface 'DotNetNuke.Abstractions.IDnnContext' instead. Scheduled removal in v11.0.0.")] + protected DotNetNukeContext() + : this(Globals.DependencyProvider.GetRequiredService()) + { } + + [Obsolete("Deprecated in DotNetNuke 9.7.1. This constructor has been replaced by the overload taking an IApplicationInfo, which should be resolved via Dependency Injection. Scheduled removal in v11.0.0.")] + protected DotNetNukeContext(Application application) + : this((IApplicationInfo)application) + { } + + /// + /// Initializes a new instance of the class using the provided application as base. + /// + /// The application. + /// + /// This constructor is designed to be used with Dependency Injection. + /// + public DotNetNukeContext(IApplicationInfo applicationInfo) + { + this.applicationInfo = applicationInfo; + this.ContainerEventListeners = new NaiveLockingList(); + this.SkinEventListeners = new NaiveLockingList(); + } + + /// + /// Gets or sets the current app context. + /// + public static DotNetNukeContext Current + { + get + { + if (current == null) + { + current = Globals.DependencyProvider.GetRequiredService(); + } + + return current is DotNetNukeContext context ? context : default(DotNetNukeContext); + } + + set + { + current = value; + } + } + + /// + /// Gets get the application. + /// + public Application Application { get => this.applicationInfo is Application app ? app : new Application(); } + + /// + IApplicationInfo IDnnContext.Application { get => this.applicationInfo; } + + /// + /// Gets the container event listeners. The listeners will be called in each life cycle of load container. + /// + /// + /// + /// + /// + /// + public IList ContainerEventListeners { get; } + + /// + /// Gets the skin event listeners. The listeners will be called in each life cycle of load skin. + /// + /// + /// + /// + /// + /// + public IList SkinEventListeners { get; } + } +} diff --git a/DNN Platform/Library/Common/Globals.cs b/DNN Platform/Library/Common/Globals.cs index 2fd0d408c82..98be4cf4119 100644 --- a/DNN Platform/Library/Common/Globals.cs +++ b/DNN Platform/Library/Common/Globals.cs @@ -5,7 +5,6 @@ namespace DotNetNuke.Common { using System; using System.Collections; - using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; @@ -25,15 +24,13 @@ namespace DotNetNuke.Common using System.Xml; using DotNetNuke.Abstractions; + using DotNetNuke.Abstractions.Application; using DotNetNuke.Abstractions.Portals; - using DotNetNuke.Application; using DotNetNuke.Collections.Internal; using DotNetNuke.Common.Internal; using DotNetNuke.Common.Lists; using DotNetNuke.Common.Utilities; using DotNetNuke.Data; - using DotNetNuke.Entities; - using DotNetNuke.Entities.Controllers; using DotNetNuke.Entities.Host; using DotNetNuke.Entities.Modules; using DotNetNuke.Entities.Modules.Actions; @@ -46,13 +43,10 @@ namespace DotNetNuke.Common using DotNetNuke.Security; using DotNetNuke.Security.Permissions; using DotNetNuke.Security.Roles; - using DotNetNuke.Services.Cache; using DotNetNuke.Services.Exceptions; using DotNetNuke.Services.FileSystem; using DotNetNuke.Services.Localization; - using DotNetNuke.Services.Upgrade; using DotNetNuke.Services.Url.FriendlyUrl; - using DotNetNuke.UI.Skins; using DotNetNuke.UI.Utilities; using Microsoft.Extensions.DependencyInjection; using Microsoft.VisualBasic.CompilerServices; @@ -215,19 +209,20 @@ public sealed class Globals private static readonly ILog Logger = LoggerSource.Instance.GetLogger(typeof(Globals)); private static string _applicationPath; - private static string _applicationMapPath; private static string _desktopModulePath; private static string _imagePath; private static string _hostMapPath; private static string _hostPath; private static string _installMapPath; private static string _installPath; - private static Version _dataBaseVersion; - private static UpgradeStatus _status = UpgradeStatus.Unknown; private static readonly Regex TabPathInvalidCharsRx = new Regex(_tabPathInvalidCharsEx, RegexOptions.Compiled); private static readonly Stopwatch AppStopwatch = Stopwatch.StartNew(); + private static IServiceProvider dependencyProvider; + private static IApplicationStatusInfo applicationStatusInfo; + private static INavigationManager navigationManager; + // global constants for the life of the application ( set in Application_Start ) @@ -316,28 +311,28 @@ public enum UpgradeStatus /// /// The application need update to a higher version. /// - Upgrade, + Upgrade = 0, /// /// The application need to install itself. /// - Install, + Install = 1, /// /// The application is normal running. /// - None, + None = 2, /// /// The application occur error when running. /// - Error, + Error = 3, /// /// The application status is unknown, /// /// This status should never be returned. its is only used as a flag that Status hasn't been determined. - Unknown, + Unknown = 4, } /// @@ -369,13 +364,8 @@ public static string ApplicationPath /// /// The application map path. /// - public static string ApplicationMapPath - { - get - { - return _applicationMapPath ?? (_applicationMapPath = GetCurrentDomainDirectory()); - } - } + [Obsolete("Deprecated in 9.7.1. Use Dependency Injection to resolve 'DotNetNuke.Abstractions.IApplicationStatusInfo' instead. Scheduled for removal in v11.0.0.")] + public static string ApplicationMapPath => applicationStatusInfo.ApplicationMapPath; /// /// Gets the desktop module path. @@ -414,13 +404,8 @@ public static string ImagePath /// /// Gets the database version. /// - public static Version DataBaseVersion - { - get - { - return _dataBaseVersion; - } - } + [Obsolete("Deprecated in 9.7.1. Use Dependency Injection to resolve 'DotNetNuke.Abstractions.IApplicationStatusInfo' instead. Scheduled for removal in v11.0.0.")] + public static Version DataBaseVersion { get => applicationStatusInfo.DatabaseVersion; } /// /// Gets the host map path. @@ -494,89 +479,8 @@ public static string InstallPath /// Gets the status of application. /// /// - public static UpgradeStatus Status - { - get - { - if (_status != UpgradeStatus.Unknown && _status != UpgradeStatus.Error) - { - return _status; - } - - Logger.Trace("Getting application status"); - var tempStatus = UpgradeStatus.None; - - // first call GetProviderPath - this insures that the Database is Initialised correctly - // and also generates the appropriate error message if it cannot be initialised correctly - string strMessage = DataProvider.Instance().GetProviderPath(); - - // get current database version from DB - if (!strMessage.StartsWith("ERROR:")) - { - try - { - _dataBaseVersion = DataProvider.Instance().GetVersion(); - } - catch (Exception ex) - { - Logger.Error(ex); - strMessage = "ERROR:" + ex.Message; - } - } - - if (strMessage.StartsWith("ERROR")) - { - if (IsInstalled()) - { - // Errors connecting to the database after an initial installation should be treated as errors. - tempStatus = UpgradeStatus.Error; - } - else - { - // An error that occurs before the database has been installed should be treated as a new install - tempStatus = UpgradeStatus.Install; - } - } - else if (DataBaseVersion == null) - { - // No Db Version so Install - tempStatus = UpgradeStatus.Install; - } - else - { - var version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version; - if (version.Major > DataBaseVersion.Major) - { - // Upgrade Required (Major Version Upgrade) - tempStatus = UpgradeStatus.Upgrade; - } - else if (version.Major == DataBaseVersion.Major && version.Minor > DataBaseVersion.Minor) - { - // Upgrade Required (Minor Version Upgrade) - tempStatus = UpgradeStatus.Upgrade; - } - else if (version.Major == DataBaseVersion.Major && version.Minor == DataBaseVersion.Minor && - version.Build > DataBaseVersion.Build) - { - // Upgrade Required (Build Version Upgrade) - tempStatus = UpgradeStatus.Upgrade; - } - else if (version.Major == DataBaseVersion.Major && version.Minor == DataBaseVersion.Minor && - version.Build == DataBaseVersion.Build && IncrementalVersionExists(version)) - { - // Upgrade Required (Build Version Upgrade) - tempStatus = UpgradeStatus.Upgrade; - } - } - - _status = tempStatus; - - Logger.Trace(string.Format("result of getting providerpath: {0}", strMessage)); - Logger.Trace("Application status is " + _status); - - return _status; - } - } + [Obsolete("Deprecated in 9.7.1. Use Dependency Injection to resolve 'DotNetNuke.Abstractions.IApplicationStatusInfo' instead. Scheduled for removal in v11.0.0.")] + public static UpgradeStatus Status { get => (UpgradeStatus)applicationStatusInfo.Status; } /// /// Gets image file types. @@ -637,6 +541,7 @@ public static TimeSpan ElapsedSinceAppStart /// public static Version NETFrameworkVersion { get; set; } + /// /// Gets or sets the database engine version. /// @@ -651,7 +556,22 @@ public static TimeSpan ElapsedSinceAppStart /// /// The Dependency Service. /// - internal static IServiceProvider DependencyProvider { get; set; } + internal static IServiceProvider DependencyProvider + { + get => dependencyProvider; + set + { + dependencyProvider = value; + if (dependencyProvider is INotifyPropertyChanged hasPropertyChanged) + { + hasPropertyChanged.PropertyChanged += OnDependencyProviderChanged; + } + else + { + OnDependencyProviderChanged(null, null); + } + } + } /// /// Redirects the specified URL. @@ -675,28 +595,8 @@ public static void Redirect(string url, bool endResponse) } } - public static bool IncrementalVersionExists(Version version) - { - Provider currentdataprovider = Config.GetDefaultProvider("data"); - string providerpath = currentdataprovider.Attributes["providerPath"]; - - // If the provider path does not exist, then there can't be any log files - if (!string.IsNullOrEmpty(providerpath)) - { - providerpath = HttpRuntime.AppDomainAppPath + providerpath.Replace("~", string.Empty); - if (Directory.Exists(providerpath)) - { - var incrementalcount = Directory.GetFiles(providerpath, Upgrade.GetStringVersion(version) + ".*." + Upgrade.DefaultProvider).Length; - - if (incrementalcount > Globals.GetLastAppliedIteration(version)) - { - return true; - } - } - } - - return false; - } + [Obsolete("Deprecated in 9.7.1. Use Dependency Injection to resolve 'DotNetNuke.Abstractions.IApplicationStatusInfo' instead. Scheduled for removal in v11.0.0.")] + public static bool IncrementalVersionExists(Version version) => applicationStatusInfo.IncrementalVersionExists(version); /// /// Builds the cross tab dataset. @@ -1073,36 +973,21 @@ public static bool FindDatabaseVersion(int Major, int Minor, int Build) /// Updates the database version. /// /// The version. - public static void UpdateDataBaseVersion(Version version) - { - // update the version - DataProvider.Instance().UpdateDatabaseVersion(version.Major, version.Minor, version.Build, DotNetNukeContext.Current.Application.Name); - _dataBaseVersion = version; - } + [Obsolete("Deprecated in 9.7.1. Use Dependency Injection to resolve 'DotNetNuke.Abstractions.IApplicationStatusInfo' instead. Scheduled for removal in v11.0.0.")] + public static void UpdateDataBaseVersion(Version version) => applicationStatusInfo.UpdateDatabaseVersion(version); /// /// Updates the database version. /// /// The version. /// The increment. - public static void UpdateDataBaseVersionIncrement(Version version, int increment) - { - // update the version and increment - DataProvider.Instance().UpdateDatabaseVersionIncrement(version.Major, version.Minor, version.Build, increment, DotNetNukeContext.Current.Application.Name); - _dataBaseVersion = version; - } + [Obsolete("Deprecated in 9.7.1. Use Dependency Injection to resolve 'DotNetNuke.Abstractions.IApplicationStatusInfo' instead. Scheduled for removal in v11.0.0.")] + public static void UpdateDataBaseVersionIncrement(Version version, int increment) => + applicationStatusInfo.UpdateDatabaseVersionIncrement(version, increment); - public static int GetLastAppliedIteration(Version version) - { - try - { - return DataProvider.Instance().GetLastAppliedIteration(version.Major, version.Minor, version.Build); - } - catch (Exception) - { - return 0; - } - } + [Obsolete("Deprecated in 9.7.1. Use Dependency Injection to resolve 'DotNetNuke.Abstractions.IApplicationStatusInfo' instead. Scheduled for removal in v11.0.0.")] + public static int GetLastAppliedIteration(Version version) => + applicationStatusInfo.GetLastAppliedIteration(version); /// /// Adds the port. @@ -1446,10 +1331,9 @@ public static int GetTotalRecords(ref IDataReader dr) /// Sets the status. /// /// The status. - public static void SetStatus(UpgradeStatus status) - { - _status = status; - } + [Obsolete("Deprecated in 9.7.1. Use Dependency Injection to resolve 'DotNetNuke.Abstractions.IApplicationStatusInfo' instead. Scheduled for removal in v11.0.0.")] + public static void SetStatus(UpgradeStatus status) => + applicationStatusInfo.SetStatus((DotNetNuke.Abstractions.Application.UpgradeStatus)status); /// ----------------------------------------------------------------------------- /// @@ -2425,7 +2309,6 @@ public static string AccessDeniedURL() /// URL to access denied view. public static string AccessDeniedURL(string Message) { - var navigationManager = DependencyProvider.GetRequiredService(); string strURL = string.Empty; PortalSettings _portalSettings = PortalController.Instance.GetCurrentPortalSettings(); if (HttpContext.Current.Request.IsAuthenticated) @@ -2802,7 +2685,6 @@ public static string LoginURL(string returnUrl, bool overrideSetting) /// Formatted URL. public static string LoginURL(string returnUrl, bool overrideSetting, PortalSettings portalSettings) { - var navigationManager = DependencyProvider.GetRequiredService(); string loginUrl; if (!string.IsNullOrEmpty(returnUrl)) { @@ -2854,7 +2736,7 @@ public static string UserProfileURL(int userId) string strURL = string.Empty; PortalSettings portalSettings = PortalController.Instance.GetCurrentPortalSettings(); - strURL = DependencyProvider.GetRequiredService().NavigateURL(portalSettings.UserTabId, string.Empty, string.Format("userId={0}", userId)); + strURL = navigationManager.NavigateURL(portalSettings.UserTabId, string.Empty, string.Format("userId={0}", userId)); return strURL; } @@ -2868,7 +2750,7 @@ public static string UserProfileURL(int userId) [Obsolete("Deprecated in Platform 9.4.2. Scheduled removal in v11.0.0.")] public static string NavigateURL() { - return DependencyProvider.GetRequiredService().NavigateURL(); + return navigationManager.NavigateURL(); } /// @@ -2881,7 +2763,7 @@ public static string NavigateURL() [Obsolete("Deprecated in Platform 9.4.2. Scheduled removal in v11.0.0.")] public static string NavigateURL(int tabID) { - return DependencyProvider.GetRequiredService().NavigateURL(tabID); + return navigationManager.NavigateURL(tabID); } /// @@ -2895,7 +2777,7 @@ public static string NavigateURL(int tabID) [Obsolete("Deprecated in Platform 9.4.2. Scheduled removal in v11.0.0.")] public static string NavigateURL(int tabID, bool isSuperTab) { - return DependencyProvider.GetRequiredService().NavigateURL(tabID, isSuperTab); + return navigationManager.NavigateURL(tabID, isSuperTab); } /// @@ -2908,7 +2790,7 @@ public static string NavigateURL(int tabID, bool isSuperTab) [Obsolete("Deprecated in Platform 9.4.2. Scheduled removal in v11.0.0.")] public static string NavigateURL(string controlKey) { - return DependencyProvider.GetRequiredService().NavigateURL(controlKey); + return navigationManager.NavigateURL(controlKey); } /// @@ -2922,7 +2804,7 @@ public static string NavigateURL(string controlKey) [Obsolete("Deprecated in Platform 9.4.2. Scheduled removal in v11.0.0.")] public static string NavigateURL(string controlKey, params string[] additionalParameters) { - return DependencyProvider.GetRequiredService().NavigateURL(controlKey, additionalParameters); + return navigationManager.NavigateURL(controlKey, additionalParameters); } /// @@ -2936,7 +2818,7 @@ public static string NavigateURL(string controlKey, params string[] additionalPa [Obsolete("Deprecated in Platform 9.4.2. Scheduled removal in v11.0.0.")] public static string NavigateURL(int tabID, string controlKey) { - return DependencyProvider.GetRequiredService().NavigateURL(tabID, controlKey); + return navigationManager.NavigateURL(tabID, controlKey); } /// @@ -2951,7 +2833,7 @@ public static string NavigateURL(int tabID, string controlKey) [Obsolete("Deprecated in Platform 9.4.2. Scheduled removal in v11.0.0.")] public static string NavigateURL(int tabID, string controlKey, params string[] additionalParameters) { - return DependencyProvider.GetRequiredService().NavigateURL(tabID, controlKey, additionalParameters); + return navigationManager.NavigateURL(tabID, controlKey, additionalParameters); } /// @@ -2967,7 +2849,7 @@ public static string NavigateURL(int tabID, string controlKey, params string[] a [Obsolete("Deprecated in Platform 9.4.2. Scheduled removal in v11.0.0.")] public static string NavigateURL(int tabID, PortalSettings settings, string controlKey, params string[] additionalParameters) { - return DependencyProvider.GetRequiredService().NavigateURL(tabID, settings, controlKey, additionalParameters); + return navigationManager.NavigateURL(tabID, settings, controlKey, additionalParameters); } /// @@ -2984,7 +2866,7 @@ public static string NavigateURL(int tabID, PortalSettings settings, string cont [Obsolete("Deprecated in Platform 9.4.2. Scheduled removal in v11.0.0.")] public static string NavigateURL(int tabID, bool isSuperTab, PortalSettings settings, string controlKey, params string[] additionalParameters) { - return DependencyProvider.GetRequiredService().NavigateURL(tabID, isSuperTab, settings, controlKey, additionalParameters); + return navigationManager.NavigateURL(tabID, isSuperTab, settings, controlKey, additionalParameters); } /// @@ -3000,7 +2882,7 @@ public static string NavigateURL(int tabID, bool isSuperTab, PortalSettings sett [Obsolete("Deprecated in Platform 9.4.2. Scheduled removal in v11.0.0.")] public static string NavigateURL(int tabID, bool isSuperTab, PortalSettings settings, string controlKey, string language, params string[] additionalParameters) { - return DependencyProvider.GetRequiredService().NavigateURL(tabID, isSuperTab, settings, controlKey, language, additionalParameters); + return navigationManager.NavigateURL(tabID, isSuperTab, settings, controlKey, language, additionalParameters); } /// @@ -3017,7 +2899,7 @@ public static string NavigateURL(int tabID, bool isSuperTab, PortalSettings sett [Obsolete("Deprecated in Platform 9.4.2. Scheduled removal in v11.0.0.")] public static string NavigateURL(int tabID, bool isSuperTab, PortalSettings settings, string controlKey, string language, string pageName, params string[] additionalParameters) { - return DependencyProvider.GetRequiredService().NavigateURL(tabID, isSuperTab, settings, controlKey, language, pageName, additionalParameters); + return navigationManager.NavigateURL(tabID, isSuperTab, settings, controlKey, language, pageName, additionalParameters); } /// @@ -3066,7 +2948,6 @@ public static string QueryStringDecode(string QueryString) /// Formatted url. public static string RegisterURL(string returnURL, string originalURL) { - var navigationManager = DependencyProvider.GetRequiredService(); string strURL; PortalSettings _portalSettings = PortalController.Instance.GetCurrentPortalSettings(); string extraParams = string.Empty; @@ -3345,7 +3226,7 @@ public static string LinkClick(string Link, int TabID, int ModuleID, bool TrackC switch (UrlType) { case TabType.Tab: - strLink = DependencyProvider.GetRequiredService().NavigateURL(int.Parse(Link)); + strLink = navigationManager.NavigateURL(int.Parse(Link)); break; default: strLink = Link; @@ -3836,31 +3717,15 @@ public static string PreventSQLInjection(string strSQL) /// /// IsInstalled looks at various file artifacts to determine if DotNetNuke has already been installed. /// - /// + /// true if installed else false. /// /// If DotNetNuke has been installed, then we should treat database connection errors as real errors. /// If DotNetNuke has not been installed, then we should expect to have database connection problems /// since the connection string may not have been configured yet, which can occur during the installation /// wizard. /// - internal static bool IsInstalled() - { - const int c_PassingScore = 4; - int installationdatefactor = Convert.ToInt32(HasInstallationDate() ? 1 : 0); - int dataproviderfactor = Convert.ToInt32(HasDataProviderLogFiles() ? 3 : 0); - int htmlmodulefactor = Convert.ToInt32(ModuleDirectoryExists("html") ? 2 : 0); - int portaldirectoryfactor = Convert.ToInt32(HasNonDefaultPortalDirectory() ? 2 : 0); - int localexecutionfactor = Convert.ToInt32(HttpContext.Current.Request.IsLocal ? c_PassingScore - 1 : 0); - - // This calculation ensures that you have a more than one item that indicates you have already installed DNN. - // While it is possible that you might not have an installation date or that you have deleted log files - // it is unlikely that you have removed every trace of an installation and yet still have a working install - bool isInstalled = (!IsInstallationURL()) && ((installationdatefactor + dataproviderfactor + htmlmodulefactor + portaldirectoryfactor + localexecutionfactor) >= c_PassingScore); - - // we need to tighten this check. We now are enforcing the existence of the InstallVersion value in web.config. If - // this value exists, then DNN was previously installed, and we should never try to re-install it - return isInstalled || HasInstallVersion(); - } + [Obsolete("Deprecated in 9.7.1. Use Dependency Injection to resolve 'DotNetNuke.Abstractions.IApplicationStatusInfo' instead. Scheduled for removal in v11.0.0.")] + internal static bool IsInstalled() => applicationStatusInfo.IsInstalled(); /// /// Gets the culture code of the tab. @@ -3894,105 +3759,6 @@ internal static void ResetAppStartElapseTime() AppStopwatch.Restart(); } - private static string GetCurrentDomainDirectory() - { - var dir = AppDomain.CurrentDomain.BaseDirectory.Replace("/", "\\"); - if (dir.Length > 3 && dir.EndsWith("\\")) - { - dir = dir.Substring(0, dir.Length - 1); - } - - return dir; - } - - /// - /// Determines whether has data provider log files. - /// - /// - /// true if has data provider log files; otherwise, false. - /// - private static bool HasDataProviderLogFiles() - { - Provider currentdataprovider = Config.GetDefaultProvider("data"); - string providerpath = currentdataprovider.Attributes["providerPath"]; - - // If the provider path does not exist, then there can't be any log files - if (!string.IsNullOrEmpty(providerpath)) - { - providerpath = HttpContext.Current.Server.MapPath(providerpath); - if (Directory.Exists(providerpath)) - { - return Directory.GetFiles(providerpath, "*.log.resources").Length > 0; - } - } - - return false; - } - - /// - /// Determines whether has installation date. - /// - /// - /// true if has installation date; otherwise, false. - /// - private static bool HasInstallationDate() - { - return Config.GetSetting("InstallationDate") != null; - } - - /// - /// Determines whether has InstallVersion set. - /// - /// - /// true if has installation date; otherwise, false. - /// - private static bool HasInstallVersion() - { - return Config.GetSetting("InstallVersion") != null; - } - - /// - /// Check whether the modules directory is exists. - /// - /// Name of the module. - /// - /// true if the module directory exist, otherwise, false. - /// - private static bool ModuleDirectoryExists(string moduleName) - { - string dir = ApplicationMapPath + "\\desktopmodules\\" + moduleName; - return Directory.Exists(dir); - } - - /// - /// Determines whether has portal directory except default portal directory in portal path. - /// - /// - /// true if has portal directory except default portal directory in portal path; otherwise, false. - /// - private static bool HasNonDefaultPortalDirectory() - { - string dir = ApplicationMapPath + "\\portals"; - if (Directory.Exists(dir)) - { - return Directory.GetDirectories(dir).Length > 1; - } - - return false; - } - - /// - /// Determines whether current request is for install. - /// - /// - /// true if current request is for install; otherwise, false. - /// - private static bool IsInstallationURL() - { - string requestURL = HttpContext.Current.Request.RawUrl.ToLowerInvariant().Replace("\\", "/"); - return requestURL.Contains("/install.aspx") || requestURL.Contains("/installwizard.aspx"); - } - private static void DeleteFile(string filePath) { try @@ -4061,5 +3827,16 @@ private static bool FilenameMatchesExtensions(string filename, string strExtensi return result; } + + /// + /// Resolves dependencies after the + /// has been initialized. This should only be called once to resolve all + /// dependencies used by the object. + /// + private static void OnDependencyProviderChanged(object sender, PropertyChangedEventArgs eventArguments) + { + applicationStatusInfo = DependencyProvider?.GetRequiredService(); + navigationManager = DependencyProvider?.GetRequiredService(); + } } } diff --git a/DNN Platform/Library/DotNetNuke.Library.csproj b/DNN Platform/Library/DotNetNuke.Library.csproj index f095e188971..607abd82722 100644 --- a/DNN Platform/Library/DotNetNuke.Library.csproj +++ b/DNN Platform/Library/DotNetNuke.Library.csproj @@ -192,6 +192,7 @@ + diff --git a/DNN Platform/Library/Startup.cs b/DNN Platform/Library/Startup.cs index e458f14da66..a56986c5434 100644 --- a/DNN Platform/Library/Startup.cs +++ b/DNN Platform/Library/Startup.cs @@ -2,26 +2,34 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information -namespace DotNetNuke -{ - using DotNetNuke.Abstractions; - using DotNetNuke.Common; - using DotNetNuke.DependencyInjection; - using DotNetNuke.Entities.Portals; - using DotNetNuke.UI.Modules; - using DotNetNuke.UI.Modules.Html5; - using Microsoft.Extensions.DependencyInjection; +namespace DotNetNuke +{ + using DotNetNuke.Abstractions; + using DotNetNuke.Abstractions.Application; + using DotNetNuke.Application; + using DotNetNuke.Common; + using DotNetNuke.DependencyInjection; + using DotNetNuke.Entities.Portals; + using DotNetNuke.UI.Modules; + using DotNetNuke.UI.Modules.Html5; + using Microsoft.Extensions.DependencyInjection; - public class Startup : IDnnStartup - { - public void ConfigureServices(IServiceCollection services) - { - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - - services.AddTransient(x => PortalController.Instance); - services.AddTransient(); - } - } -} + /// + public class Startup : IDnnStartup + { + /// + public void ConfigureServices(IServiceCollection services) + { + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + + services.AddTransient(x => PortalController.Instance); + services.AddScoped(); + + services.AddScoped(); + services.AddScoped(); + } + } +} diff --git a/DNN Platform/Tests/DotNetNuke.Tests.Content/AttachmentControllerTests.cs b/DNN Platform/Tests/DotNetNuke.Tests.Content/AttachmentControllerTests.cs index 1aef2da49e7..1e2f7f3bc49 100644 --- a/DNN Platform/Tests/DotNetNuke.Tests.Content/AttachmentControllerTests.cs +++ b/DNN Platform/Tests/DotNetNuke.Tests.Content/AttachmentControllerTests.cs @@ -4,22 +4,25 @@ namespace DotNetNuke.Tests.Content { - using System; using System.Collections.Generic; - using System.Data; - using System.Linq; - + using System.Linq; + using DotNetNuke.Abstractions; + using DotNetNuke.Abstractions.Application; + using DotNetNuke.Common; using DotNetNuke.Common.Utilities; using DotNetNuke.ComponentModel; using DotNetNuke.Entities.Content; - using DotNetNuke.Entities.Content.Common; using DotNetNuke.Entities.Content.Data; using DotNetNuke.Services.Cache; using DotNetNuke.Services.FileSystem; using DotNetNuke.Tests.Content.Mocks; using DotNetNuke.Tests.Utilities; - using DotNetNuke.Tests.Utilities.Mocks; + using DotNetNuke.Tests.Utilities.Mocks; + + using Microsoft.Extensions.DependencyInjection; + using Moq; + using NUnit.Framework; using FileController = DotNetNuke.Entities.Content.AttachmentController; @@ -33,6 +36,11 @@ public class AttachmentControllerTests [SetUp] public void SetUp() { + var serviceCollection = new ServiceCollection(); + serviceCollection.AddTransient(container => Mock.Of()); + serviceCollection.AddTransient(container => new DotNetNuke.Application.ApplicationStatusInfo(Mock.Of())); + Globals.DependencyProvider = serviceCollection.BuildServiceProvider(); + // Register MockCachingProvider this.mockCache = MockComponentProvider.CreateNew(); MockComponentProvider.CreateDataProvider().Setup(c => c.GetProviderPath()).Returns(string.Empty); @@ -41,6 +49,7 @@ public void SetUp() [TearDown] public void TearDown() { + Globals.DependencyProvider = null; MockComponentProvider.ResetContainer(); } diff --git a/DNN Platform/Tests/DotNetNuke.Tests.Content/ContentControllerTests.cs b/DNN Platform/Tests/DotNetNuke.Tests.Content/ContentControllerTests.cs index eba6e40c52e..f2d3bbc3131 100644 --- a/DNN Platform/Tests/DotNetNuke.Tests.Content/ContentControllerTests.cs +++ b/DNN Platform/Tests/DotNetNuke.Tests.Content/ContentControllerTests.cs @@ -7,8 +7,10 @@ namespace DotNetNuke.Tests.Content using System; using System.Collections.Generic; using System.Collections.Specialized; - using System.Linq; - + using System.Linq; + using DotNetNuke.Abstractions; + using DotNetNuke.Abstractions.Application; + using DotNetNuke.Common; using DotNetNuke.Common.Utilities; using DotNetNuke.ComponentModel; using DotNetNuke.Data; @@ -18,8 +20,12 @@ namespace DotNetNuke.Tests.Content using DotNetNuke.Services.Search.Entities; using DotNetNuke.Tests.Content.Mocks; using DotNetNuke.Tests.Utilities; - using DotNetNuke.Tests.Utilities.Mocks; + using DotNetNuke.Tests.Utilities.Mocks; + + using Microsoft.Extensions.DependencyInjection; + using Moq; + using NUnit.Framework; /// @@ -45,11 +51,20 @@ public void SetUp() this._mockSearchHelper.Setup(x => x.GetSearchTypeByName(It.IsAny())).Returns( (string searchTypeName) => new SearchType { SearchTypeName = searchTypeName, SearchTypeId = ModuleSearchTypeId }); + + var serviceCollection = new ServiceCollection(); + var mockApplicationStatusInfo = new Mock(); + mockApplicationStatusInfo.Setup(info => info.Status).Returns(UpgradeStatus.Install); + + serviceCollection.AddTransient(container => Mock.Of()); + serviceCollection.AddTransient(container => mockApplicationStatusInfo.Object); + Globals.DependencyProvider = serviceCollection.BuildServiceProvider(); } [TearDown] public void TearDown() { + Globals.DependencyProvider = null; MockComponentProvider.ResetContainer(); } diff --git a/DNN Platform/Tests/DotNetNuke.Tests.Content/ContentTypeControllerTests.cs b/DNN Platform/Tests/DotNetNuke.Tests.Content/ContentTypeControllerTests.cs index 44f600e3935..88f624fcfc8 100644 --- a/DNN Platform/Tests/DotNetNuke.Tests.Content/ContentTypeControllerTests.cs +++ b/DNN Platform/Tests/DotNetNuke.Tests.Content/ContentTypeControllerTests.cs @@ -5,16 +5,22 @@ namespace DotNetNuke.Tests.Content { using System; - using System.Linq; - + using System.Linq; + using DotNetNuke.Abstractions; + using DotNetNuke.Abstractions.Application; + using DotNetNuke.Common; using DotNetNuke.Common.Utilities; using DotNetNuke.Entities.Content; using DotNetNuke.Entities.Content.Data; using DotNetNuke.Services.Cache; using DotNetNuke.Tests.Content.Mocks; using DotNetNuke.Tests.Utilities; - using DotNetNuke.Tests.Utilities.Mocks; + using DotNetNuke.Tests.Utilities.Mocks; + + using Microsoft.Extensions.DependencyInjection; + using Moq; + using NUnit.Framework; /// @@ -28,6 +34,11 @@ public class ContentTypeControllerTests [SetUp] public void SetUp() { + var serviceCollection = new ServiceCollection(); + serviceCollection.AddTransient(container => Mock.Of()); + serviceCollection.AddTransient(container => new DotNetNuke.Application.ApplicationStatusInfo(Mock.Of())); + Globals.DependencyProvider = serviceCollection.BuildServiceProvider(); + // Register MockCachingProvider this.mockCache = MockComponentProvider.CreateNew(); MockComponentProvider.CreateDataProvider().Setup(c => c.GetProviderPath()).Returns(string.Empty); @@ -36,6 +47,7 @@ public void SetUp() [TearDown] public void TearDown() { + Globals.DependencyProvider = null; MockComponentProvider.ResetContainer(); } diff --git a/DNN Platform/Tests/DotNetNuke.Tests.Content/DotNetNuke.Tests.Content.csproj b/DNN Platform/Tests/DotNetNuke.Tests.Content/DotNetNuke.Tests.Content.csproj index 702d7839a45..626c6fdfa68 100644 --- a/DNN Platform/Tests/DotNetNuke.Tests.Content/DotNetNuke.Tests.Content.csproj +++ b/DNN Platform/Tests/DotNetNuke.Tests.Content/DotNetNuke.Tests.Content.csproj @@ -64,6 +64,12 @@ False ..\..\DotNetNuke.Log4net\bin\dotnetnuke.log4net.dll + + ..\..\..\packages\Microsoft.Extensions.DependencyInjection.2.1.1\lib\net461\Microsoft.Extensions.DependencyInjection.dll + + + ..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.1.1\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll + ..\..\..\Packages\Moq.4.2.1502.0911\lib\net40\Moq.dll @@ -100,6 +106,10 @@ + + {6928A9B1-F88A-4581-A132-D3EB38669BB0} + DotNetNuke.Abstractions + {04f77171-0634-46e0-a95e-d7477c88712e} DotNetNuke.Log4Net diff --git a/DNN Platform/Tests/DotNetNuke.Tests.Content/ScopeTypeControllerTests.cs b/DNN Platform/Tests/DotNetNuke.Tests.Content/ScopeTypeControllerTests.cs index e7b5f87d385..01f104f9c10 100644 --- a/DNN Platform/Tests/DotNetNuke.Tests.Content/ScopeTypeControllerTests.cs +++ b/DNN Platform/Tests/DotNetNuke.Tests.Content/ScopeTypeControllerTests.cs @@ -5,16 +5,22 @@ namespace DotNetNuke.Tests.Content { using System; - using System.Linq; - + using System.Linq; + using DotNetNuke.Abstractions; + using DotNetNuke.Abstractions.Application; + using DotNetNuke.Common; using DotNetNuke.Common.Utilities; using DotNetNuke.Entities.Content.Data; using DotNetNuke.Entities.Content.Taxonomy; using DotNetNuke.Services.Cache; using DotNetNuke.Tests.Content.Mocks; using DotNetNuke.Tests.Utilities; - using DotNetNuke.Tests.Utilities.Mocks; + using DotNetNuke.Tests.Utilities.Mocks; + + using Microsoft.Extensions.DependencyInjection; + using Moq; + using NUnit.Framework; /// @@ -28,6 +34,11 @@ public class ScopeTypeControllerTests [SetUp] public void SetUp() { + var serviceCollection = new ServiceCollection(); + serviceCollection.AddTransient(container => Mock.Of()); + serviceCollection.AddTransient(container => new DotNetNuke.Application.ApplicationStatusInfo(Mock.Of())); + Globals.DependencyProvider = serviceCollection.BuildServiceProvider(); + // Register MockCachingProvider this.mockCache = MockComponentProvider.CreateNew(); MockComponentProvider.CreateDataProvider().Setup(c => c.GetProviderPath()).Returns(string.Empty); @@ -36,6 +47,7 @@ public void SetUp() [TearDown] public void TearDown() { + Globals.DependencyProvider = null; MockComponentProvider.ResetContainer(); } diff --git a/DNN Platform/Tests/DotNetNuke.Tests.Content/TermControllerTests.cs b/DNN Platform/Tests/DotNetNuke.Tests.Content/TermControllerTests.cs index 32a80100d0e..0aeb25a7cd9 100644 --- a/DNN Platform/Tests/DotNetNuke.Tests.Content/TermControllerTests.cs +++ b/DNN Platform/Tests/DotNetNuke.Tests.Content/TermControllerTests.cs @@ -5,8 +5,10 @@ namespace DotNetNuke.Tests.Content { using System; - using System.Linq; - + using System.Linq; + using DotNetNuke.Abstractions; + using DotNetNuke.Abstractions.Application; + using DotNetNuke.Common; using DotNetNuke.Common.Utilities; using DotNetNuke.Entities.Content; using DotNetNuke.Entities.Content.Data; @@ -15,8 +17,12 @@ namespace DotNetNuke.Tests.Content using DotNetNuke.Services.Cache; using DotNetNuke.Tests.Content.Mocks; using DotNetNuke.Tests.Utilities; - using DotNetNuke.Tests.Utilities.Mocks; + using DotNetNuke.Tests.Utilities.Mocks; + + using Microsoft.Extensions.DependencyInjection; + using Moq; + using NUnit.Framework; /// @@ -30,6 +36,11 @@ public class TermControllerTests [SetUp] public void SetUp() { + var serviceCollection = new ServiceCollection(); + serviceCollection.AddTransient(container => Mock.Of()); + serviceCollection.AddTransient(container => new DotNetNuke.Application.ApplicationStatusInfo(Mock.Of())); + Globals.DependencyProvider = serviceCollection.BuildServiceProvider(); + Mock vocabularyController = MockHelper.CreateMockVocabularyController(); MockComponentProvider.CreateDataProvider().Setup(c => c.GetProviderPath()).Returns(string.Empty); @@ -40,6 +51,7 @@ public void SetUp() [TearDown] public void TearDown() { + Globals.DependencyProvider = null; MockComponentProvider.ResetContainer(); } diff --git a/DNN Platform/Tests/DotNetNuke.Tests.Content/VocabularyControllerTests.cs b/DNN Platform/Tests/DotNetNuke.Tests.Content/VocabularyControllerTests.cs index 86a1ad450f9..82e483e1941 100644 --- a/DNN Platform/Tests/DotNetNuke.Tests.Content/VocabularyControllerTests.cs +++ b/DNN Platform/Tests/DotNetNuke.Tests.Content/VocabularyControllerTests.cs @@ -5,16 +5,22 @@ namespace DotNetNuke.Tests.Content { using System; - using System.Linq; - + using System.Linq; + using DotNetNuke.Abstractions; + using DotNetNuke.Abstractions.Application; + using DotNetNuke.Common; using DotNetNuke.Common.Utilities; using DotNetNuke.Entities.Content.Data; using DotNetNuke.Entities.Content.Taxonomy; using DotNetNuke.Services.Cache; using DotNetNuke.Tests.Content.Mocks; using DotNetNuke.Tests.Utilities; - using DotNetNuke.Tests.Utilities.Mocks; + using DotNetNuke.Tests.Utilities.Mocks; + + using Microsoft.Extensions.DependencyInjection; + using Moq; + using NUnit.Framework; /// @@ -28,6 +34,11 @@ public class VocabularyControllerTests [SetUp] public void SetUp() { + var serviceCollection = new ServiceCollection(); + serviceCollection.AddTransient(container => Mock.Of()); + serviceCollection.AddTransient(container => new DotNetNuke.Application.ApplicationStatusInfo(Mock.Of())); + Globals.DependencyProvider = serviceCollection.BuildServiceProvider(); + // Register MockCachingProvider this.mockCache = MockComponentProvider.CreateNew(); MockComponentProvider.CreateDataProvider().Setup(c => c.GetProviderPath()).Returns(string.Empty); @@ -36,6 +47,7 @@ public void SetUp() [TearDown] public void TearDown() { + Globals.DependencyProvider = null; MockComponentProvider.ResetContainer(); } diff --git a/DNN Platform/Tests/DotNetNuke.Tests.Core/Controllers/Host/HostControllerTest.cs b/DNN Platform/Tests/DotNetNuke.Tests.Core/Controllers/Host/HostControllerTest.cs index 8e4f59968bf..4da0b21a1c8 100644 --- a/DNN Platform/Tests/DotNetNuke.Tests.Core/Controllers/Host/HostControllerTest.cs +++ b/DNN Platform/Tests/DotNetNuke.Tests.Core/Controllers/Host/HostControllerTest.cs @@ -7,15 +7,21 @@ namespace DotNetNuke.Tests.Core.Controllers.Host using System; using System.Collections.Generic; using System.Data; - using System.Linq; - + using System.Linq; + using DotNetNuke.Abstractions; + using DotNetNuke.Abstractions.Application; + using DotNetNuke.Common; using DotNetNuke.Common.Utilities; using DotNetNuke.Data; using DotNetNuke.Entities; using DotNetNuke.Entities.Controllers; using DotNetNuke.Services.Cache; - using DotNetNuke.Tests.Utilities.Mocks; + using DotNetNuke.Tests.Utilities.Mocks; + + using Microsoft.Extensions.DependencyInjection; + using Moq; + using NUnit.Framework; [TestFixture] @@ -28,6 +34,13 @@ public class HostControllerTest [SetUp] public void SetUp() { + var serviceCollection = new ServiceCollection(); + var mockApplicationStatusInfo = new Mock(); + mockApplicationStatusInfo.Setup(info => info.Status).Returns(UpgradeStatus.Install); + serviceCollection.AddTransient(container => Mock.Of()); + serviceCollection.AddTransient(container => mockApplicationStatusInfo.Object); + Globals.DependencyProvider = serviceCollection.BuildServiceProvider(); + this._mockCache = MockComponentProvider.CreateDataCacheProvider(); MockComponentProvider.CreateEventLogController(); @@ -59,6 +72,7 @@ public void SetUp() [TearDown] public void TearDown() { + Globals.DependencyProvider = null; MockComponentProvider.ResetContainer(); } diff --git a/DNN Platform/Tests/DotNetNuke.Tests.Core/Controllers/Messaging/MessagingControllerTests.cs b/DNN Platform/Tests/DotNetNuke.Tests.Core/Controllers/Messaging/MessagingControllerTests.cs index 5b7987e546c..f1d3419fb81 100644 --- a/DNN Platform/Tests/DotNetNuke.Tests.Core/Controllers/Messaging/MessagingControllerTests.cs +++ b/DNN Platform/Tests/DotNetNuke.Tests.Core/Controllers/Messaging/MessagingControllerTests.cs @@ -9,13 +9,14 @@ namespace DotNetNuke.Tests.Core.Controllers.Messaging using System.Collections.Generic; using System.Data; using System.Globalization; - using System.Text; - + using System.Text; + using DotNetNuke.Abstractions; + using DotNetNuke.Abstractions.Application; + using DotNetNuke.Common; using DotNetNuke.Common.Utilities; using DotNetNuke.ComponentModel; using DotNetNuke.Data; using DotNetNuke.Entities.Portals; - using DotNetNuke.Entities.Portals.Internal; using DotNetNuke.Entities.Users; using DotNetNuke.Security.Permissions; using DotNetNuke.Security.Roles; @@ -27,8 +28,12 @@ namespace DotNetNuke.Tests.Core.Controllers.Messaging using DotNetNuke.Services.Social.Messaging.Exceptions; using DotNetNuke.Services.Social.Messaging.Internal; using DotNetNuke.Tests.Utilities; - using DotNetNuke.Tests.Utilities.Mocks; + using DotNetNuke.Tests.Utilities.Mocks; + + using Microsoft.Extensions.DependencyInjection; + using Moq; + using NUnit.Framework; /// @@ -66,6 +71,13 @@ public class MessagingControllerTests [SetUp] public void SetUp() { + var serviceCollection = new ServiceCollection(); + var mockApplicationStatusInfo = new Mock(); + mockApplicationStatusInfo.Setup(info => info.Status).Returns(UpgradeStatus.Install); + serviceCollection.AddTransient(container => mockApplicationStatusInfo.Object); + serviceCollection.AddTransient(container => Mock.Of()); + Globals.DependencyProvider = serviceCollection.BuildServiceProvider(); + ComponentFactory.Container = new SimpleContainer(); this._mockDataService = new Mock(); this._dataProvider = MockComponentProvider.CreateDataProvider(); @@ -109,6 +121,7 @@ public void SetUp() [TearDown] public void TearDown() { + Globals.DependencyProvider = null; ComponentFactory.Container = null; PortalController.ClearInstance(); } diff --git a/DNN Platform/Tests/DotNetNuke.Tests.Core/Controllers/Messaging/NotificationsControllerTests.cs b/DNN Platform/Tests/DotNetNuke.Tests.Core/Controllers/Messaging/NotificationsControllerTests.cs index e7a78e589a3..2f9341d0b38 100644 --- a/DNN Platform/Tests/DotNetNuke.Tests.Core/Controllers/Messaging/NotificationsControllerTests.cs +++ b/DNN Platform/Tests/DotNetNuke.Tests.Core/Controllers/Messaging/NotificationsControllerTests.cs @@ -9,8 +9,10 @@ namespace DotNetNuke.Tests.Core.Controllers.Messaging using System.Collections.Generic; using System.Data; using System.Globalization; - using System.Text; - + using System.Text; + using DotNetNuke.Abstractions; + using DotNetNuke.Abstractions.Application; + using DotNetNuke.Common; using DotNetNuke.Common.Utilities; using DotNetNuke.ComponentModel; using DotNetNuke.Data; @@ -24,8 +26,12 @@ namespace DotNetNuke.Tests.Core.Controllers.Messaging using DotNetNuke.Services.Social.Notifications; using DotNetNuke.Services.Social.Notifications.Data; using DotNetNuke.Tests.Utilities; - using DotNetNuke.Tests.Utilities.Mocks; + using DotNetNuke.Tests.Utilities.Mocks; + + using Microsoft.Extensions.DependencyInjection; + using Moq; + using NUnit.Framework; [TestFixture] @@ -48,6 +54,13 @@ public class NotificationsControllerTests [SetUp] public void SetUp() { + var serviceCollection = new ServiceCollection(); + var mockApplicationStatusInfo = new Mock(); + mockApplicationStatusInfo.Setup(info => info.Status).Returns(UpgradeStatus.Install); + serviceCollection.AddTransient(container => mockApplicationStatusInfo.Object); + serviceCollection.AddTransient(container => Mock.Of()); + Globals.DependencyProvider = serviceCollection.BuildServiceProvider(); + ComponentFactory.Container = new SimpleContainer(); this._mockDataService = new Mock(); @@ -79,6 +92,7 @@ public void SetUp() [TearDown] public void TearDown() { + Globals.DependencyProvider = null; ComponentFactory.Container = null; MessagingController.ClearInstance(); PortalController.ClearInstance(); diff --git a/DNN Platform/Tests/DotNetNuke.Tests.Core/Controllers/Search/InternalSearchControllerTests.cs b/DNN Platform/Tests/DotNetNuke.Tests.Core/Controllers/Search/InternalSearchControllerTests.cs index 5066e44103b..709036f7cdb 100644 --- a/DNN Platform/Tests/DotNetNuke.Tests.Core/Controllers/Search/InternalSearchControllerTests.cs +++ b/DNN Platform/Tests/DotNetNuke.Tests.Core/Controllers/Search/InternalSearchControllerTests.cs @@ -8,8 +8,10 @@ namespace DotNetNuke.Tests.Core.Controllers.Search using System.Collections.Generic; using System.Data; using System.IO; - using System.Threading; - + using System.Threading; + using DotNetNuke.Abstractions; + using DotNetNuke.Abstractions.Application; + using DotNetNuke.Common; using DotNetNuke.ComponentModel; using DotNetNuke.Data; using DotNetNuke.Entities.Controllers; @@ -18,7 +20,8 @@ namespace DotNetNuke.Tests.Core.Controllers.Search using DotNetNuke.Services.Localization; using DotNetNuke.Services.Search.Entities; using DotNetNuke.Services.Search.Internals; - using DotNetNuke.Tests.Utilities.Mocks; + using DotNetNuke.Tests.Utilities.Mocks; + using Microsoft.Extensions.DependencyInjection; using Moq; using NUnit.Framework; @@ -95,6 +98,11 @@ public void SetUp() ComponentFactory.Container = new SimpleContainer(); MockComponentProvider.ResetContainer(); + var serviceCollection = new ServiceCollection(); + serviceCollection.AddTransient(container => Mock.Of()); + serviceCollection.AddTransient(container => new DotNetNuke.Application.ApplicationStatusInfo(Mock.Of())); + Globals.DependencyProvider = serviceCollection.BuildServiceProvider(); + this._mockDataProvider = MockComponentProvider.CreateDataProvider(); this._mockLocaleController = MockComponentProvider.CreateLocaleController(); this._mockCachingProvider = MockComponentProvider.CreateDataCacheProvider(); @@ -125,6 +133,7 @@ public void TearDown() SearchHelper.ClearInstance(); LuceneController.ClearInstance(); this._luceneController = null; + Globals.DependencyProvider = null; } [Test] diff --git a/DNN Platform/Tests/DotNetNuke.Tests.Core/Controllers/Search/LuceneControllerTests.cs b/DNN Platform/Tests/DotNetNuke.Tests.Core/Controllers/Search/LuceneControllerTests.cs index 5b26371f73f..58311a9a1c2 100644 --- a/DNN Platform/Tests/DotNetNuke.Tests.Core/Controllers/Search/LuceneControllerTests.cs +++ b/DNN Platform/Tests/DotNetNuke.Tests.Core/Controllers/Search/LuceneControllerTests.cs @@ -9,7 +9,9 @@ namespace DotNetNuke.Tests.Core.Controllers.Search using System.IO; using System.Linq; using System.Threading; - + using DotNetNuke.Abstractions; + using DotNetNuke.Abstractions.Application; + using DotNetNuke.Common; using DotNetNuke.ComponentModel; using DotNetNuke.Entities.Controllers; using DotNetNuke.Services.Cache; @@ -21,6 +23,7 @@ namespace DotNetNuke.Tests.Core.Controllers.Search using Lucene.Net.Index; using Lucene.Net.QueryParsers; using Lucene.Net.Search; + using Microsoft.Extensions.DependencyInjection; using Moq; using NUnit.Framework; @@ -65,6 +68,11 @@ public void SetUp() ComponentFactory.Container = new SimpleContainer(); this._cachingProvider = MockComponentProvider.CreateDataCacheProvider(); + var serviceCollection = new ServiceCollection(); + serviceCollection.AddTransient(container => Mock.Of()); + serviceCollection.AddTransient(container => new DotNetNuke.Application.ApplicationStatusInfo(Mock.Of())); + Globals.DependencyProvider = serviceCollection.BuildServiceProvider(); + this._mockHostController = new Mock(); this._mockHostController.Setup(c => c.GetString(Constants.SearchIndexFolderKey, It.IsAny())).Returns(SearchIndexFolder); this._mockHostController.Setup(c => c.GetDouble(Constants.SearchReaderRefreshTimeKey, It.IsAny())).Returns(this._readerStaleTimeSpan); @@ -92,6 +100,7 @@ public void TearDown() this._luceneController.Dispose(); this.DeleteIndexFolder(); SearchHelper.ClearInstance(); + Globals.DependencyProvider = null; } [Test] diff --git a/DNN Platform/Tests/DotNetNuke.Tests.Core/Controllers/Search/SearchControllerTests.cs b/DNN Platform/Tests/DotNetNuke.Tests.Core/Controllers/Search/SearchControllerTests.cs index c01cf4703ac..c8f6ce90b60 100644 --- a/DNN Platform/Tests/DotNetNuke.Tests.Core/Controllers/Search/SearchControllerTests.cs +++ b/DNN Platform/Tests/DotNetNuke.Tests.Core/Controllers/Search/SearchControllerTests.cs @@ -9,8 +9,10 @@ namespace DotNetNuke.Tests.Core.Controllers.Search using System.Data; using System.IO; using System.Linq; - using System.Threading; - + using System.Threading; + using DotNetNuke.Abstractions; + using DotNetNuke.Abstractions.Application; + using DotNetNuke.Common; using DotNetNuke.ComponentModel; using DotNetNuke.Data; using DotNetNuke.Entities.Controllers; @@ -21,7 +23,8 @@ namespace DotNetNuke.Tests.Core.Controllers.Search using DotNetNuke.Services.Search.Entities; using DotNetNuke.Services.Search.Internals; using DotNetNuke.Tests.Utilities.Mocks; - using Lucene.Net.Documents; + using Lucene.Net.Documents; + using Microsoft.Extensions.DependencyInjection; using Moq; using NUnit.Framework; @@ -139,6 +142,11 @@ public void SetUp() ComponentFactory.Container = new SimpleContainer(); MockComponentProvider.ResetContainer(); + var serviceCollection = new ServiceCollection(); + serviceCollection.AddTransient(container => Mock.Of()); + serviceCollection.AddTransient(container => new DotNetNuke.Application.ApplicationStatusInfo(Mock.Of())); + Globals.DependencyProvider = serviceCollection.BuildServiceProvider(); + this._mockDataProvider = MockComponentProvider.CreateDataProvider(); this._mockLocaleController = MockComponentProvider.CreateLocaleController(); this._mockCachingProvider = MockComponentProvider.CreateDataCacheProvider(); @@ -168,6 +176,7 @@ public void TearDown() SearchHelper.ClearInstance(); LuceneController.ClearInstance(); this._luceneController = null; + Globals.DependencyProvider = null; } [Test] diff --git a/DNN Platform/Tests/DotNetNuke.Tests.Core/Controllers/Search/SearchHelperTests.cs b/DNN Platform/Tests/DotNetNuke.Tests.Core/Controllers/Search/SearchHelperTests.cs index 8bc61cc7896..65d0ba2247a 100644 --- a/DNN Platform/Tests/DotNetNuke.Tests.Core/Controllers/Search/SearchHelperTests.cs +++ b/DNN Platform/Tests/DotNetNuke.Tests.Core/Controllers/Search/SearchHelperTests.cs @@ -6,15 +6,21 @@ namespace DotNetNuke.Tests.Core.Controllers.Search { using System; using System.Data; - using System.Linq; - + using System.Linq; + using DotNetNuke.Abstractions; + using DotNetNuke.Abstractions.Application; + using DotNetNuke.Common; using DotNetNuke.Common.Utilities; using DotNetNuke.ComponentModel; using DotNetNuke.Data; using DotNetNuke.Services.Cache; using DotNetNuke.Services.Search.Internals; - using DotNetNuke.Tests.Utilities.Mocks; + using DotNetNuke.Tests.Utilities.Mocks; + + using Microsoft.Extensions.DependencyInjection; + using Moq; + using NUnit.Framework; /// @@ -40,6 +46,13 @@ public class SearchHelperTests [SetUp] public void SetUp() { + var serviceCollection = new ServiceCollection(); + var mockApplicationStatusInfo = new Mock(); + mockApplicationStatusInfo.Setup(info => info.Status).Returns(UpgradeStatus.Install); + serviceCollection.AddTransient(container => Mock.Of()); + serviceCollection.AddTransient(container => mockApplicationStatusInfo.Object); + Globals.DependencyProvider = serviceCollection.BuildServiceProvider(); + ComponentFactory.Container = new SimpleContainer(); this._cachingProvider = MockComponentProvider.CreateDataCacheProvider(); this._dataProvider = MockComponentProvider.CreateDataProvider(); @@ -48,6 +61,12 @@ public void SetUp() DataCache.ClearCache(); } + [TearDown] + public void TearDown() + { + Globals.DependencyProvider = null; + } + [Test] public void SearchHelper_GetSynonyms_Two_Terms_Returns_Correct_Results() { diff --git a/DNN Platform/Tests/DotNetNuke.Tests.Core/Controllers/Social/RelationshipControllerTests.cs b/DNN Platform/Tests/DotNetNuke.Tests.Core/Controllers/Social/RelationshipControllerTests.cs index 0b764808687..1cedf9e940f 100644 --- a/DNN Platform/Tests/DotNetNuke.Tests.Core/Controllers/Social/RelationshipControllerTests.cs +++ b/DNN Platform/Tests/DotNetNuke.Tests.Core/Controllers/Social/RelationshipControllerTests.cs @@ -6,22 +6,26 @@ namespace DotNetNuke.Tests.Core.Controllers.Social { using System; using System.Collections.Generic; - using System.Data; - + using System.Data; + using DotNetNuke.Abstractions; + using DotNetNuke.Abstractions.Application; + using DotNetNuke.Common; using DotNetNuke.Common.Utilities; using DotNetNuke.ComponentModel; - using DotNetNuke.Entities; using DotNetNuke.Entities.Controllers; using DotNetNuke.Entities.Portals; using DotNetNuke.Entities.Users; using DotNetNuke.Entities.Users.Social; using DotNetNuke.Entities.Users.Social.Data; - using DotNetNuke.Entities.Users.Social.Internal; using DotNetNuke.Services.Cache; using DotNetNuke.Services.Log.EventLog; using DotNetNuke.Tests.Utilities; - using DotNetNuke.Tests.Utilities.Mocks; + using DotNetNuke.Tests.Utilities.Mocks; + + using Microsoft.Extensions.DependencyInjection; + using Moq; + using NUnit.Framework; /// @@ -42,6 +46,13 @@ public class RelationshipControllerTests [SetUp] public void SetUp() { + var serviceCollection = new ServiceCollection(); + var mockApplicationStatusInfo = new Mock(); + mockApplicationStatusInfo.Setup(info => info.Status).Returns(UpgradeStatus.Install); + serviceCollection.AddTransient(container => mockApplicationStatusInfo.Object); + serviceCollection.AddTransient(container => Mock.Of()); + Globals.DependencyProvider = serviceCollection.BuildServiceProvider(); + ComponentFactory.Container = new SimpleContainer(); var mockDataProvider = MockComponentProvider.CreateDataProvider(); mockDataProvider.Setup(dp => dp.GetProviderPath()).Returns(string.Empty); @@ -71,6 +82,7 @@ public void SetUp() [TearDown] public void TearDown() { + Globals.DependencyProvider = null; ComponentFactory.Container = null; PortalController.ClearInstance(); UserController.ClearInstance(); diff --git a/DNN Platform/Tests/DotNetNuke.Tests.Core/DotNetNuke.Tests.Core.csproj b/DNN Platform/Tests/DotNetNuke.Tests.Core/DotNetNuke.Tests.Core.csproj index af23f23244f..0e86957af68 100644 --- a/DNN Platform/Tests/DotNetNuke.Tests.Core/DotNetNuke.Tests.Core.csproj +++ b/DNN Platform/Tests/DotNetNuke.Tests.Core/DotNetNuke.Tests.Core.csproj @@ -83,6 +83,12 @@ ..\..\Components\Lucene.Net.Contrib\bin\Lucene.Net.Contrib.FastVectorHighlighter.dll + + ..\..\..\packages\Microsoft.Extensions.DependencyInjection.2.1.1\lib\net461\Microsoft.Extensions.DependencyInjection.dll + + + ..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.1.1\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll + ..\..\..\packages\Moq.4.2.1502.0911\lib\net40\Moq.dll diff --git a/DNN Platform/Tests/DotNetNuke.Tests.Core/Entities/Portals/PortalSettingsControllerTests.cs b/DNN Platform/Tests/DotNetNuke.Tests.Core/Entities/Portals/PortalSettingsControllerTests.cs index d2ce2d91fe9..dc91cadca39 100644 --- a/DNN Platform/Tests/DotNetNuke.Tests.Core/Entities/Portals/PortalSettingsControllerTests.cs +++ b/DNN Platform/Tests/DotNetNuke.Tests.Core/Entities/Portals/PortalSettingsControllerTests.cs @@ -7,8 +7,9 @@ namespace DotNetNuke.Tests.Core.Entities.Portals using System; using System.Collections.Generic; using System.Reflection; - using System.Runtime.Serialization; - + using System.Runtime.Serialization; + using DotNetNuke.Abstractions; + using DotNetNuke.Abstractions.Application; using DotNetNuke.Common; using DotNetNuke.Common.Utilities; using DotNetNuke.Entities.Controllers; @@ -16,7 +17,8 @@ namespace DotNetNuke.Tests.Core.Entities.Portals using DotNetNuke.Entities.Tabs; using DotNetNuke.Services.Localization; using DotNetNuke.Tests.Utilities.Mocks; - using DotNetNuke.UI.Skins; + using DotNetNuke.UI.Skins; + using Microsoft.Extensions.DependencyInjection; using Moq; using NUnit.Framework; @@ -44,6 +46,13 @@ public class PortalSettingsControllerTests public void SetUp() { MockComponentProvider.ResetContainer(); + + var serviceCollection = new ServiceCollection(); + var mockApplicationInfo = new Mock(); + mockApplicationInfo.Setup(info => info.ApplicationMapPath).Returns("path/to/application"); + serviceCollection.AddTransient(container => mockApplicationInfo.Object); + serviceCollection.AddTransient(container => Mock.Of()); + Globals.DependencyProvider = serviceCollection.BuildServiceProvider(); } [TearDown] @@ -51,6 +60,8 @@ public void TearDown() { PortalController.ClearInstance(); TabController.ClearInstance(); + Globals.DependencyProvider = null; + } [Test] diff --git a/DNN Platform/Tests/DotNetNuke.Tests.Core/FileSystemUtilsTests.cs b/DNN Platform/Tests/DotNetNuke.Tests.Core/FileSystemUtilsTests.cs index 2b183e8f691..daf3e6a847c 100644 --- a/DNN Platform/Tests/DotNetNuke.Tests.Core/FileSystemUtilsTests.cs +++ b/DNN Platform/Tests/DotNetNuke.Tests.Core/FileSystemUtilsTests.cs @@ -7,14 +7,17 @@ namespace DotNetNuke.Tests.Core using System; using System.IO; using System.Linq; - using System.Reflection; - + using System.Reflection; + using DotNetNuke.Abstractions; + using DotNetNuke.Abstractions.Application; using DotNetNuke.Common; using DotNetNuke.Common.Utilities; using DotNetNuke.ComponentModel; using DotNetNuke.Entities.Tabs; using DotNetNuke.Tests.Utilities.Mocks; - using ICSharpCode.SharpZipLib.Zip; + using ICSharpCode.SharpZipLib.Zip; + using Microsoft.Extensions.DependencyInjection; + using Moq; using NUnit.Framework; /// @@ -26,13 +29,22 @@ public class FileSystemUtilsTests [SetUp] public void SetUp() { - var field = typeof(Globals).GetField("_applicationMapPath", BindingFlags.Static | BindingFlags.NonPublic); - field.SetValue(null, null); - - var rootPath = Path.Combine(Globals.ApplicationMapPath, "FileSystemUtilsTest"); - this.PrepareRootPath(rootPath); + var applicationStatusInfo = new DotNetNuke.Application.ApplicationStatusInfo(Mock.Of()); + var rootPath = Path.Combine(applicationStatusInfo.ApplicationMapPath, "FileSystemUtilsTest"); + this.PrepareRootPath(rootPath, applicationStatusInfo.ApplicationMapPath); + + var serviceCollection = new ServiceCollection(); + var mock = new Mock(); + mock.Setup(info => info.ApplicationMapPath).Returns(rootPath); + serviceCollection.AddTransient(container => mock.Object); + serviceCollection.AddTransient(container => Mock.Of()); + Globals.DependencyProvider = serviceCollection.BuildServiceProvider(); + } - field.SetValue(null, rootPath); + [TearDown] + public void TearDown() + { + Globals.DependencyProvider = null; } [TestCase("/")] @@ -147,14 +159,14 @@ public void FixPath_Should_Change_Slashes_And_Trim(string input) } } - private void PrepareRootPath(string rootPath) + private void PrepareRootPath(string rootPath, string applicationMapPath) { if (!Directory.Exists(rootPath)) { Directory.CreateDirectory(rootPath); } - foreach (var file in Directory.GetFiles(Globals.ApplicationMapPath, "*.*", SearchOption.TopDirectoryOnly)) + foreach (var file in Directory.GetFiles(applicationMapPath, "*.*", SearchOption.TopDirectoryOnly)) { File.Copy(file, Path.Combine(rootPath, Path.GetFileName(file)), true); } diff --git a/DNN Platform/Tests/DotNetNuke.Tests.Core/Framework/JavaScriptLibraries/JavaScriptTests.cs b/DNN Platform/Tests/DotNetNuke.Tests.Core/Framework/JavaScriptLibraries/JavaScriptTests.cs index 63a2d0ca75b..fccd54a6765 100644 --- a/DNN Platform/Tests/DotNetNuke.Tests.Core/Framework/JavaScriptLibraries/JavaScriptTests.cs +++ b/DNN Platform/Tests/DotNetNuke.Tests.Core/Framework/JavaScriptLibraries/JavaScriptTests.cs @@ -9,13 +9,18 @@ namespace DotNetNuke.Tests.Core.Framework.JavaScriptLibraries using System.Linq; using System.Reflection; using System.Web; - + using DotNetNuke.Abstractions; + using DotNetNuke.Abstractions.Application; using DotNetNuke.Application; using DotNetNuke.Common; using DotNetNuke.Framework.JavaScriptLibraries; using DotNetNuke.Tests.Instance.Utilities; using DotNetNuke.Tests.Utilities.Mocks; + + using Microsoft.Extensions.DependencyInjection; + using Moq; + using NUnit.Framework; public class JavaScriptTests @@ -29,9 +34,21 @@ public class JavaScriptTests [SetUp] public void Setup() { - // fix Globals.Status - var status = typeof(Globals).GetField("_status", BindingFlags.Static | BindingFlags.NonPublic); - status.SetValue(null, Globals.UpgradeStatus.None); + var serviceCollection = new ServiceCollection(); + var mockApplicationStatusInfo = new Mock(); + mockApplicationStatusInfo.Setup(info => info.Status).Returns(UpgradeStatus.None); + + var mockApplication = new Mock(); + mockApplication.Setup(app => app.Version).Returns(new Version("1.0.0.0")); + + var dnnContext = new DotNetNukeContext(mockApplication.Object); + + serviceCollection.AddTransient(container => mockApplicationStatusInfo.Object); + serviceCollection.AddTransient(container => mockApplication.Object); + serviceCollection.AddTransient(container => dnnContext); + serviceCollection.AddTransient(container => Mock.Of()); + + Globals.DependencyProvider = serviceCollection.BuildServiceProvider(); var httpContextMock = new Mock { DefaultValue = DefaultValue.Mock, }; httpContextMock.Setup(c => c.Items).Returns(new Dictionary()); @@ -49,6 +66,7 @@ public void TearDown() { UnitTestHelper.ClearHttpContext(); JavaScriptLibraryController.ClearInstance(); + Globals.DependencyProvider = null; } [Test] diff --git a/DNN Platform/Tests/DotNetNuke.Tests.Core/Framework/ServicesFrameworkTests.cs b/DNN Platform/Tests/DotNetNuke.Tests.Core/Framework/ServicesFrameworkTests.cs index 08b3d132a8f..e2cd03159fd 100644 --- a/DNN Platform/Tests/DotNetNuke.Tests.Core/Framework/ServicesFrameworkTests.cs +++ b/DNN Platform/Tests/DotNetNuke.Tests.Core/Framework/ServicesFrameworkTests.cs @@ -4,11 +4,18 @@ namespace DotNetNuke.Tests.Core.Framework { - using System; - + using System; + using DotNetNuke.Abstractions; + using DotNetNuke.Abstractions.Application; + using DotNetNuke.Common; using DotNetNuke.Framework; using DotNetNuke.Tests.Instance.Utilities; - using DotNetNuke.Tests.Utilities; + using DotNetNuke.Tests.Utilities; + + using Microsoft.Extensions.DependencyInjection; + + using Moq; + using NUnit.Framework; public class ServicesFrameworkTests @@ -16,6 +23,13 @@ public class ServicesFrameworkTests [SetUp] public void Setup() { + var serviceCollection = new ServiceCollection(); + var mockApplicationStatusInfo = new Mock(); + mockApplicationStatusInfo.Setup(info => info.Status).Returns(UpgradeStatus.Install); + serviceCollection.AddTransient(container => mockApplicationStatusInfo.Object); + serviceCollection.AddTransient(container => Mock.Of()); + Globals.DependencyProvider = serviceCollection.BuildServiceProvider(); + HttpContextHelper.RegisterMockHttpContext(); var simulator = new Instance.Utilities.HttpSimulator.HttpSimulator("/", "c:\\"); simulator.SimulateRequest(new Uri("http://localhost/dnn/Default.aspx")); @@ -24,6 +38,7 @@ public void Setup() [TearDown] public void TearDown() { + Globals.DependencyProvider = null; UnitTestHelper.ClearHttpContext(); } diff --git a/DNN Platform/Tests/DotNetNuke.Tests.Core/Providers/Folder/FileContentTypeManagerTests.cs b/DNN Platform/Tests/DotNetNuke.Tests.Core/Providers/Folder/FileContentTypeManagerTests.cs index 2179f2b26ed..5b917da70d9 100644 --- a/DNN Platform/Tests/DotNetNuke.Tests.Core/Providers/Folder/FileContentTypeManagerTests.cs +++ b/DNN Platform/Tests/DotNetNuke.Tests.Core/Providers/Folder/FileContentTypeManagerTests.cs @@ -3,29 +3,19 @@ // See the LICENSE file in the project root for more information namespace DotNetNuke.Tests.Core.Providers.Folder -{ - using System; - using System.Collections.Generic; - using System.Data; - using System.Drawing; - using System.IO; - using System.Reflection; - using System.Text; - +{ + using DotNetNuke.Abstractions; + using DotNetNuke.Abstractions.Application; + using DotNetNuke.Common; using DotNetNuke.Common.Internal; using DotNetNuke.Common.Utilities; - using DotNetNuke.Data; - using DotNetNuke.Entities.Content; - using DotNetNuke.Entities.Content.Workflow; - using DotNetNuke.Entities.Content.Workflow.Entities; - using DotNetNuke.Entities.Portals; - using DotNetNuke.Security.Permissions; - using DotNetNuke.Services.Cache; using DotNetNuke.Services.FileSystem; - using DotNetNuke.Services.FileSystem.Internal; - using DotNetNuke.Tests.Utilities; - using DotNetNuke.Tests.Utilities.Mocks; + using DotNetNuke.Tests.Utilities.Mocks; + + using Microsoft.Extensions.DependencyInjection; + using Moq; + using NUnit.Framework; [TestFixture] @@ -34,6 +24,13 @@ public class FileContentTypeManagerTests [SetUp] public void Setup() { + var serviceCollection = new ServiceCollection(); + var mockApplicationStatusInfo = new Mock(); + mockApplicationStatusInfo.Setup(info => info.Status).Returns(UpgradeStatus.Install); + serviceCollection.AddTransient(container => mockApplicationStatusInfo.Object); + serviceCollection.AddTransient(container => Mock.Of()); + Globals.DependencyProvider = serviceCollection.BuildServiceProvider(); + var _mockData = MockComponentProvider.CreateDataProvider(); var _mockCache = MockComponentProvider.CreateDataCacheProvider(); var _globals = new Mock(); @@ -48,6 +45,7 @@ public void Setup() [TearDown] public void TearDown() { + Globals.DependencyProvider = null; TestableGlobals.ClearInstance(); CBO.ClearInstance(); } diff --git a/DNN Platform/Tests/DotNetNuke.Tests.Core/Providers/Folder/StandardFolderProviderTests.cs b/DNN Platform/Tests/DotNetNuke.Tests.Core/Providers/Folder/StandardFolderProviderTests.cs index efee9d35458..2b2a8848238 100644 --- a/DNN Platform/Tests/DotNetNuke.Tests.Core/Providers/Folder/StandardFolderProviderTests.cs +++ b/DNN Platform/Tests/DotNetNuke.Tests.Core/Providers/Folder/StandardFolderProviderTests.cs @@ -9,7 +9,8 @@ namespace DotNetNuke.Tests.Core.Providers.Folder using System.IO; using System.Linq; - using DotNetNuke.Abstractions; + using DotNetNuke.Abstractions; + using DotNetNuke.Abstractions.Application; using DotNetNuke.Common; using DotNetNuke.Common.Internal; using DotNetNuke.Common.Utilities; @@ -20,8 +21,12 @@ namespace DotNetNuke.Tests.Core.Providers.Folder using DotNetNuke.Services.FileSystem.Internal; using DotNetNuke.Services.Localization; using DotNetNuke.Tests.Utilities; - using DotNetNuke.Tests.Utilities.Mocks; + using DotNetNuke.Tests.Utilities.Mocks; + + using Microsoft.Extensions.DependencyInjection; + using Moq; + using NUnit.Framework; [TestFixture] @@ -42,10 +47,23 @@ public class StandardFolderProviderTests [TestFixtureSetUp] public void FixtureSetup() { - var navigationManagerMock = new Mock(); - var containerMock = new Mock(); - containerMock.Setup(x => x.GetService(typeof(INavigationManager))).Returns(navigationManagerMock.Object); - Globals.DependencyProvider = containerMock.Object; + var serviceCollection = new ServiceCollection(); + + var mockApplicationStatusInfo = new Mock(); + mockApplicationStatusInfo.Setup(info => info.Status).Returns(UpgradeStatus.Install); + + var navigationManagerMock = new Mock(); + + serviceCollection.AddTransient(container => mockApplicationStatusInfo.Object); + serviceCollection.AddTransient(container => navigationManagerMock.Object); + + Globals.DependencyProvider = serviceCollection.BuildServiceProvider(); + } + + [TestFixtureTearDown] + public void FixtureTearDown() + { + Globals.DependencyProvider = null; } [SetUp] diff --git a/DNN Platform/Tests/DotNetNuke.Tests.Core/Services/Mobile/RedirectionControllerTests.cs b/DNN Platform/Tests/DotNetNuke.Tests.Core/Services/Mobile/RedirectionControllerTests.cs index 1e76702fa13..e4cd277731a 100644 --- a/DNN Platform/Tests/DotNetNuke.Tests.Core/Services/Mobile/RedirectionControllerTests.cs +++ b/DNN Platform/Tests/DotNetNuke.Tests.Core/Services/Mobile/RedirectionControllerTests.cs @@ -11,7 +11,8 @@ namespace DotNetNuke.Tests.Core.Services.Mobile using System.Reflection; using System.Web; - using DotNetNuke.Abstractions; + using DotNetNuke.Abstractions; + using DotNetNuke.Abstractions.Application; using DotNetNuke.Common; using DotNetNuke.Common.Internal; using DotNetNuke.ComponentModel; @@ -25,7 +26,8 @@ namespace DotNetNuke.Tests.Core.Services.Mobile using DotNetNuke.Services.Mobile; using DotNetNuke.Tests.Core.Services.ClientCapability; using DotNetNuke.Tests.Instance.Utilities; - using DotNetNuke.Tests.Utilities.Mocks; + using DotNetNuke.Tests.Utilities.Mocks; + using Microsoft.Extensions.DependencyInjection; using Moq; using NUnit.Framework; @@ -109,11 +111,14 @@ public void SetUp() { dataProviderField.SetValue(tabController, this._dataProvider.Object); } + + } [TearDown] public void TearDown() { + Globals.DependencyProvider = null; TestableGlobals.ClearInstance(); PortalController.ClearInstance(); CachingProvider.Instance().PurgeCache(); @@ -476,11 +481,18 @@ public void RedirectionController_IsRedirectAllowedForTheSession_With_Nonmo_Para private void SetupContianer() { - var navigationManagerMock = new Mock(); - navigationManagerMock.Setup(x => x.NavigateURL(It.IsAny())).Returns(x => this.NavigateUrl(x)); - var containerMock = new Mock(); - containerMock.Setup(x => x.GetService(typeof(INavigationManager))).Returns(navigationManagerMock.Object); - Globals.DependencyProvider = containerMock.Object; + var serviceCollection = new ServiceCollection(); + + var mockNavigationManager = new Mock(); + mockNavigationManager.Setup(x => x.NavigateURL(It.IsAny())).Returns(x => this.NavigateUrl(x)); + + var mockApplicationStatusInfo = new Mock(); + mockApplicationStatusInfo.Setup(info => info.Status).Returns(UpgradeStatus.Install); + + serviceCollection.AddTransient(container => mockNavigationManager.Object); + serviceCollection.AddTransient(container => mockApplicationStatusInfo.Object); + + Globals.DependencyProvider = serviceCollection.BuildServiceProvider(); } private void SetupDataProvider() diff --git a/DNN Platform/Tests/DotNetNuke.Tests.Core/packages.config b/DNN Platform/Tests/DotNetNuke.Tests.Core/packages.config index fc659db1e84..a74abce4b51 100644 --- a/DNN Platform/Tests/DotNetNuke.Tests.Core/packages.config +++ b/DNN Platform/Tests/DotNetNuke.Tests.Core/packages.config @@ -1,5 +1,7 @@  + + diff --git a/DNN Platform/Tests/DotNetNuke.Tests.Web.Mvc/DotNetNuke.Tests.Web.Mvc.csproj b/DNN Platform/Tests/DotNetNuke.Tests.Web.Mvc/DotNetNuke.Tests.Web.Mvc.csproj index 238a681f5fb..14034c7b66d 100644 --- a/DNN Platform/Tests/DotNetNuke.Tests.Web.Mvc/DotNetNuke.Tests.Web.Mvc.csproj +++ b/DNN Platform/Tests/DotNetNuke.Tests.Web.Mvc/DotNetNuke.Tests.Web.Mvc.csproj @@ -120,6 +120,10 @@ + + {6928A9B1-F88A-4581-A132-D3EB38669BB0} + DotNetNuke.Abstractions + {0fca217a-5f9a-4f5b-a31b-86d64ae65198} DotNetNuke.DependencyInjection diff --git a/DNN Platform/Tests/DotNetNuke.Tests.Web.Mvc/Framework/ModuleDelegatingViewEngineTests.cs b/DNN Platform/Tests/DotNetNuke.Tests.Web.Mvc/Framework/ModuleDelegatingViewEngineTests.cs index 38b77160d60..d655c04d491 100644 --- a/DNN Platform/Tests/DotNetNuke.Tests.Web.Mvc/Framework/ModuleDelegatingViewEngineTests.cs +++ b/DNN Platform/Tests/DotNetNuke.Tests.Web.Mvc/Framework/ModuleDelegatingViewEngineTests.cs @@ -5,15 +5,19 @@ namespace DotNetNuke.Tests.Web.Mvc.Framework { using System.Linq; - using System.Web.Mvc; - + using System.Web.Mvc; + using DotNetNuke.Abstractions; + using DotNetNuke.Abstractions.Application; using DotNetNuke.Common; using DotNetNuke.Web.Mvc.Framework; using DotNetNuke.Web.Mvc.Framework.Controllers; using DotNetNuke.Web.Mvc.Framework.Modules; using DotNetNuke.Web.Mvc.Routing; + using Microsoft.Extensions.DependencyInjection; + using Moq; + using NUnit.Framework; [TestFixture] @@ -23,7 +27,13 @@ public class ModuleDelegatingViewEngineTests public void Setup() { var services = new ServiceCollection(); - services.AddSingleton(); + var mockApplicationStatusInfo = new Mock(); + mockApplicationStatusInfo.Setup(info => info.Status).Returns(UpgradeStatus.Install); + + services.AddTransient(container => mockApplicationStatusInfo.Object); + services.AddTransient(container => Mock.Of()); + services.AddSingleton(); + Globals.DependencyProvider = services.BuildServiceProvider(); } diff --git a/DNN Platform/Tests/DotNetNuke.Tests.Web.Mvc/Framework/Modules/ModuleApplicationTests.cs b/DNN Platform/Tests/DotNetNuke.Tests.Web.Mvc/Framework/Modules/ModuleApplicationTests.cs index af71811a030..286e158174a 100644 --- a/DNN Platform/Tests/DotNetNuke.Tests.Web.Mvc/Framework/Modules/ModuleApplicationTests.cs +++ b/DNN Platform/Tests/DotNetNuke.Tests.Web.Mvc/Framework/Modules/ModuleApplicationTests.cs @@ -5,17 +5,21 @@ namespace DotNetNuke.Tests.Web.Mvc.Framework.Modules { using System; - using System.Web; + using System.Web.Mvc; - using System.Web.Routing; - + using System.Web.Routing; + using DotNetNuke.Abstractions; + using DotNetNuke.Abstractions.Application; using DotNetNuke.Common; using DotNetNuke.Entities.Modules; using DotNetNuke.UI.Modules; using DotNetNuke.Web.Mvc.Framework.Controllers; using DotNetNuke.Web.Mvc.Framework.Modules; + using Microsoft.Extensions.DependencyInjection; + using Moq; + using NUnit.Framework; [TestFixture] @@ -28,7 +32,13 @@ public class ModuleApplicationTests public void Setup() { var services = new ServiceCollection(); + var mockApplicationStatusInfo = new Mock(); + mockApplicationStatusInfo.Setup(info => info.Status).Returns(UpgradeStatus.Install); + + services.AddTransient(container => mockApplicationStatusInfo.Object); + services.AddTransient(container => Mock.Of()); services.AddSingleton(); + Globals.DependencyProvider = services.BuildServiceProvider(); } diff --git a/DNN Platform/Tests/DotNetNuke.Tests.Web/Api/PortalAliasRouteManagerTests.cs b/DNN Platform/Tests/DotNetNuke.Tests.Web/Api/PortalAliasRouteManagerTests.cs index 064c87384f2..15a2a50c38d 100644 --- a/DNN Platform/Tests/DotNetNuke.Tests.Web/Api/PortalAliasRouteManagerTests.cs +++ b/DNN Platform/Tests/DotNetNuke.Tests.Web/Api/PortalAliasRouteManagerTests.cs @@ -9,12 +9,17 @@ namespace DotNetNuke.Tests.Web.Api using System.Collections.Generic; using System.Linq; - using DotNetNuke.Abstractions; + using DotNetNuke.Abstractions; + using DotNetNuke.Abstractions.Application; using DotNetNuke.Common; using DotNetNuke.Common.Internal; using DotNetNuke.Entities.Portals; - using DotNetNuke.Web.Api; + using DotNetNuke.Web.Api; + + using Microsoft.Extensions.DependencyInjection; + using Moq; + using NUnit.Framework; [TestFixture] @@ -23,15 +28,21 @@ public class PortalAliasRouteManagerTests [SetUp] public void SetUp() { - var navigationManagerMock = new Mock(); - var containerMock = new Mock(); - containerMock.Setup(x => x.GetService(typeof(INavigationManager))).Returns(navigationManagerMock.Object); - Globals.DependencyProvider = containerMock.Object; + var services = new ServiceCollection(); + var navigationManagerMock = new Mock(); + var mockApplicationStatusInfo = new Mock(); + mockApplicationStatusInfo.Setup(info => info.Status).Returns(UpgradeStatus.Install); + + services.AddTransient(container => mockApplicationStatusInfo.Object); + services.AddScoped(typeof(INavigationManager), (x) => navigationManagerMock.Object); + + Globals.DependencyProvider = services.BuildServiceProvider(); } [TearDown] public void TearDown() { + Globals.DependencyProvider = null; PortalController.ClearInstance(); PortalAliasController.ClearInstance(); TestableGlobals.ClearInstance(); diff --git a/DNN Platform/Tests/DotNetNuke.Tests.Web/Api/ServiceRoutingManagerTests.cs b/DNN Platform/Tests/DotNetNuke.Tests.Web/Api/ServiceRoutingManagerTests.cs index 2a5d8921ba8..a38296883e1 100644 --- a/DNN Platform/Tests/DotNetNuke.Tests.Web/Api/ServiceRoutingManagerTests.cs +++ b/DNN Platform/Tests/DotNetNuke.Tests.Web/Api/ServiceRoutingManagerTests.cs @@ -2,227 +2,230 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information -namespace DotNetNuke.Tests.Web.Api -{ - using System; - using System.Collections; - using System.Collections.Generic; - using System.Linq; - using System.Web.Routing; - - using DotNetNuke.Abstractions; - using DotNetNuke.Common; - using DotNetNuke.DependencyInjection; - using DotNetNuke.Entities.Portals; - using DotNetNuke.Framework.Internal.Reflection; - using DotNetNuke.Framework.Reflections; - using Microsoft.Extensions.DependencyInjection; - using Moq; - using NUnit.Framework; - - using ServicesRoutingManager = DotNetNuke.Web.Api.Internal.ServicesRoutingManager; - - [TestFixture] - public class ServiceRoutingManagerTests - { - // ReSharper disable UnusedMember.Local - private readonly List _emptyStringArrays = new List - { null, new string[0], new[] { string.Empty }, new string[] { null } }; - - // ReSharper restore UnusedMember.Local - private Mock _mockPortalController; - private IPortalController _portalController; - - [SetUp] - public void Setup() - { - FakeServiceRouteMapper.RegistrationCalls = 0; - - this._mockPortalController = new Mock(); - this._portalController = this._mockPortalController.Object; - PortalController.SetTestableInstance(this._portalController); - - var navigationManagerMock = new Mock(); - var services = new ServiceCollection(); - services.AddScoped(typeof(INavigationManager), (x) => navigationManagerMock.Object); - Globals.DependencyProvider = services.BuildServiceProvider(); - } - - [TearDown] - public void TearDown() - { - PortalController.ClearInstance(); - - if (Globals.DependencyProvider is IDisposable disposable) - { - disposable.Dispose(); - } - - Globals.DependencyProvider = null; - } - - [Test] - public void LocatesAllServiceRouteMappers() - { - var assemblyLocator = new Mock(); - - // including the assembly with object ensures that the assignabliity is done correctly - var assembliesToReflect = new IAssembly[2]; - assembliesToReflect[0] = new AssemblyWrapper(this.GetType().Assembly); - assembliesToReflect[1] = new AssemblyWrapper(typeof(object).Assembly); - - assemblyLocator.Setup(x => x.Assemblies).Returns(assembliesToReflect); - - var locator = new TypeLocator { AssemblyLocator = assemblyLocator.Object }; - - List types = locator.GetAllMatchingTypes(ServicesRoutingManager.IsValidServiceRouteMapper).ToList(); - - // if new ServiceRouteMapper classes are added to the assembly they willl likely need to be added here - CollectionAssert.AreEquivalent( - new[] - { - typeof(FakeServiceRouteMapper), - typeof(ReflectedServiceRouteMappers.EmbeddedServiceRouteMapper), - typeof(ExceptionOnCreateInstanceServiceRouteMapper), - typeof(ExceptionOnRegisterServiceRouteMapper), - }, types); - } - - [Test] - public void NameSpaceRequiredOnMapRouteCalls([ValueSource("_emptyStringArrays")] string[] namespaces) - { - var srm = new ServicesRoutingManager(new RouteCollection()); - - Assert.Throws(() => srm.MapHttpRoute("usm", "default", "url", null, namespaces)); - } - - [Test] - public void RegisterRoutesIsCalledOnAllServiceRouteMappersEvenWhenSomeThrowExceptions() - { - FakeServiceRouteMapper.RegistrationCalls = 0; - var assembly = new Mock(); - assembly.Setup(x => x.GetTypes()).Returns(new[] - { - typeof(ExceptionOnRegisterServiceRouteMapper), - typeof(ExceptionOnCreateInstanceServiceRouteMapper), - typeof(FakeServiceRouteMapper), - }); - var al = new Mock(); - al.Setup(x => x.Assemblies).Returns(new[] { assembly.Object }); - var tl = new TypeLocator { AssemblyLocator = al.Object }; - var srm = new ServicesRoutingManager(new RouteCollection()) { TypeLocator = tl }; - - srm.RegisterRoutes(); - - Assert.AreEqual(1, FakeServiceRouteMapper.RegistrationCalls); - } - - [Test] - public void RegisterRoutesIsCalledOnServiceRouteMappers() - { - FakeServiceRouteMapper.RegistrationCalls = 0; - var assembly = new Mock(); - assembly.Setup(x => x.GetTypes()).Returns(new[] { typeof(FakeServiceRouteMapper) }); - var al = new Mock(); - al.Setup(x => x.Assemblies).Returns(new[] { assembly.Object }); - var tl = new TypeLocator { AssemblyLocator = al.Object }; - var srm = new ServicesRoutingManager(new RouteCollection()) { TypeLocator = tl }; - - srm.RegisterRoutes(); - - Assert.AreEqual(1, FakeServiceRouteMapper.RegistrationCalls); - } - - [Test] - [TestCase("")] - [TestCase(null)] - public void UniqueNameRequiredOnMapRouteCalls(string uniqueName) - { - var srm = new ServicesRoutingManager(new RouteCollection()); - - Assert.Throws(() => srm.MapHttpRoute(uniqueName, "default", "url", null, new[] { "foo" })); - } - - [Test] - public void UrlCanStartWithSlash() - { - // Arrange - this._mockPortalController.Setup(x => x.GetPortals()).Returns(new ArrayList()); - - // Act - var srm = new ServicesRoutingManager(new RouteCollection()); - - // Assert - Assert.DoesNotThrow(() => srm.MapHttpRoute("name", "default", "/url", null, new[] { "foo" })); - } - - [Test] - public void NameIsInsertedInRouteDataTokens() - { - // Arrange - var portalInfo = new ArrayList { new PortalInfo { PortalID = 0 } }; - this._mockPortalController.Setup(x => x.GetPortals()).Returns(portalInfo); - var mockPac = new Mock(); - mockPac.Setup(x => x.GetPortalAliasesByPortalId(0)).Returns(new[] { new PortalAliasInfo { HTTPAlias = "www.foo.com" } }); - PortalAliasController.SetTestableInstance(mockPac.Object); - - var routeCollection = new RouteCollection(); - var srm = new ServicesRoutingManager(routeCollection); - - // Act - srm.MapHttpRoute("folder", "default", "url", new[] { "foo" }); - - // Assert - var route = (Route)routeCollection[0]; - Assert.AreEqual("folder-default-0", route.DataTokens["Name"]); - } - - [Test] - public void TwoRoutesOnTheSameFolderHaveSimilarNames() - { - // Arrange - var portalInfo = new ArrayList { new PortalInfo { PortalID = 0 } }; - this._mockPortalController.Setup(x => x.GetPortals()).Returns(portalInfo); - var mockPac = new Mock(); - mockPac.Setup(x => x.GetPortalAliasesByPortalId(0)).Returns(new[] { new PortalAliasInfo { HTTPAlias = "www.foo.com" } }); - PortalAliasController.SetTestableInstance(mockPac.Object); - - var routeCollection = new RouteCollection(); - var srm = new ServicesRoutingManager(routeCollection); - - // Act - srm.MapHttpRoute("folder", "default", "url", new[] { "foo" }); - srm.MapHttpRoute("folder", "another", "alt/url", new[] { "foo" }); - - // Assert - var route = (Route)routeCollection[0]; - Assert.AreEqual("folder-default-0", route.DataTokens["Name"]); - route = (Route)routeCollection[1]; - Assert.AreEqual("folder-default-0-old", route.DataTokens["Name"]); - } - - [Test] - public void RoutesShouldHaveBackwardCompability() - { - // Arrange - var portalInfo = new ArrayList { new PortalInfo { PortalID = 0 } }; - this._mockPortalController.Setup(x => x.GetPortals()).Returns(portalInfo); - var mockPac = new Mock(); - mockPac.Setup(x => x.GetPortalAliasesByPortalId(0)).Returns(new[] { new PortalAliasInfo { HTTPAlias = "www.foo.com" } }); - PortalAliasController.SetTestableInstance(mockPac.Object); - - var routeCollection = new RouteCollection(); - var srm = new ServicesRoutingManager(routeCollection); - - // Act - srm.MapHttpRoute("folder", "default", "url", new[] { "foo" }); - - // Assert - var route = (Route)routeCollection[0]; - Assert.AreEqual("folder-default-0", route.DataTokens["Name"]); - route = (Route)routeCollection[1]; - Assert.AreEqual("folder-default-0-old", route.DataTokens["Name"]); - Assert.IsTrue(route.Url.StartsWith("DesktopModules")); - } - } -} +namespace DotNetNuke.Tests.Web.Api +{ + using System; + using System.Collections; + using System.Collections.Generic; + using System.Linq; + using System.Web.Routing; + + using DotNetNuke.Abstractions; + using DotNetNuke.Abstractions.Application; + using DotNetNuke.Common; + using DotNetNuke.Entities.Portals; + using DotNetNuke.Framework.Internal.Reflection; + using DotNetNuke.Framework.Reflections; + using Microsoft.Extensions.DependencyInjection; + using Moq; + using NUnit.Framework; + + using ServicesRoutingManager = DotNetNuke.Web.Api.Internal.ServicesRoutingManager; + + [TestFixture] + public class ServiceRoutingManagerTests + { + // ReSharper disable UnusedMember.Local + private readonly List _emptyStringArrays = new List + { null, new string[0], new[] { string.Empty }, new string[] { null } }; + + // ReSharper restore UnusedMember.Local + private Mock _mockPortalController; + private IPortalController _portalController; + + [SetUp] + public void Setup() + { + FakeServiceRouteMapper.RegistrationCalls = 0; + + this._mockPortalController = new Mock(); + this._portalController = this._mockPortalController.Object; + PortalController.SetTestableInstance(this._portalController); + + var services = new ServiceCollection(); + var navigationManagerMock = new Mock(); + var mockApplicationStatusInfo = new Mock(); + mockApplicationStatusInfo.Setup(info => info.Status).Returns(UpgradeStatus.Install); + services.AddTransient(container => mockApplicationStatusInfo.Object); + services.AddScoped(typeof(INavigationManager), (x) => navigationManagerMock.Object); + Globals.DependencyProvider = services.BuildServiceProvider(); + } + + [TearDown] + public void TearDown() + { + PortalController.ClearInstance(); + + if (Globals.DependencyProvider is IDisposable disposable) + { + disposable.Dispose(); + } + + Globals.DependencyProvider = null; + } + + [Test] + public void LocatesAllServiceRouteMappers() + { + var assemblyLocator = new Mock(); + + // including the assembly with object ensures that the assignabliity is done correctly + var assembliesToReflect = new IAssembly[2]; + assembliesToReflect[0] = new AssemblyWrapper(this.GetType().Assembly); + assembliesToReflect[1] = new AssemblyWrapper(typeof(object).Assembly); + + assemblyLocator.Setup(x => x.Assemblies).Returns(assembliesToReflect); + + var locator = new TypeLocator { AssemblyLocator = assemblyLocator.Object }; + + List types = locator.GetAllMatchingTypes(ServicesRoutingManager.IsValidServiceRouteMapper).ToList(); + + // if new ServiceRouteMapper classes are added to the assembly they willl likely need to be added here + CollectionAssert.AreEquivalent( + new[] + { + typeof(FakeServiceRouteMapper), + typeof(ReflectedServiceRouteMappers.EmbeddedServiceRouteMapper), + typeof(ExceptionOnCreateInstanceServiceRouteMapper), + typeof(ExceptionOnRegisterServiceRouteMapper), + }, types); + } + + [Test] + public void NameSpaceRequiredOnMapRouteCalls([ValueSource("_emptyStringArrays")] string[] namespaces) + { + var srm = new ServicesRoutingManager(new RouteCollection()); + + Assert.Throws(() => srm.MapHttpRoute("usm", "default", "url", null, namespaces)); + } + + [Test] + public void RegisterRoutesIsCalledOnAllServiceRouteMappersEvenWhenSomeThrowExceptions() + { + FakeServiceRouteMapper.RegistrationCalls = 0; + var assembly = new Mock(); + assembly.Setup(x => x.GetTypes()).Returns(new[] + { + typeof(ExceptionOnRegisterServiceRouteMapper), + typeof(ExceptionOnCreateInstanceServiceRouteMapper), + typeof(FakeServiceRouteMapper), + }); + var al = new Mock(); + al.Setup(x => x.Assemblies).Returns(new[] { assembly.Object }); + var tl = new TypeLocator { AssemblyLocator = al.Object }; + var srm = new ServicesRoutingManager(new RouteCollection()) { TypeLocator = tl }; + + srm.RegisterRoutes(); + + Assert.AreEqual(1, FakeServiceRouteMapper.RegistrationCalls); + } + + [Test] + public void RegisterRoutesIsCalledOnServiceRouteMappers() + { + FakeServiceRouteMapper.RegistrationCalls = 0; + var assembly = new Mock(); + assembly.Setup(x => x.GetTypes()).Returns(new[] { typeof(FakeServiceRouteMapper) }); + var al = new Mock(); + al.Setup(x => x.Assemblies).Returns(new[] { assembly.Object }); + var tl = new TypeLocator { AssemblyLocator = al.Object }; + var srm = new ServicesRoutingManager(new RouteCollection()) { TypeLocator = tl }; + + srm.RegisterRoutes(); + + Assert.AreEqual(1, FakeServiceRouteMapper.RegistrationCalls); + } + + [Test] + [TestCase("")] + [TestCase(null)] + public void UniqueNameRequiredOnMapRouteCalls(string uniqueName) + { + var srm = new ServicesRoutingManager(new RouteCollection()); + + Assert.Throws(() => srm.MapHttpRoute(uniqueName, "default", "url", null, new[] { "foo" })); + } + + [Test] + public void UrlCanStartWithSlash() + { + // Arrange + this._mockPortalController.Setup(x => x.GetPortals()).Returns(new ArrayList()); + + // Act + var srm = new ServicesRoutingManager(new RouteCollection()); + + // Assert + Assert.DoesNotThrow(() => srm.MapHttpRoute("name", "default", "/url", null, new[] { "foo" })); + } + + [Test] + public void NameIsInsertedInRouteDataTokens() + { + // Arrange + var portalInfo = new ArrayList { new PortalInfo { PortalID = 0 } }; + this._mockPortalController.Setup(x => x.GetPortals()).Returns(portalInfo); + var mockPac = new Mock(); + mockPac.Setup(x => x.GetPortalAliasesByPortalId(0)).Returns(new[] { new PortalAliasInfo { HTTPAlias = "www.foo.com" } }); + PortalAliasController.SetTestableInstance(mockPac.Object); + + var routeCollection = new RouteCollection(); + var srm = new ServicesRoutingManager(routeCollection); + + // Act + srm.MapHttpRoute("folder", "default", "url", new[] { "foo" }); + + // Assert + var route = (Route)routeCollection[0]; + Assert.AreEqual("folder-default-0", route.DataTokens["Name"]); + } + + [Test] + public void TwoRoutesOnTheSameFolderHaveSimilarNames() + { + // Arrange + var portalInfo = new ArrayList { new PortalInfo { PortalID = 0 } }; + this._mockPortalController.Setup(x => x.GetPortals()).Returns(portalInfo); + var mockPac = new Mock(); + mockPac.Setup(x => x.GetPortalAliasesByPortalId(0)).Returns(new[] { new PortalAliasInfo { HTTPAlias = "www.foo.com" } }); + PortalAliasController.SetTestableInstance(mockPac.Object); + + var routeCollection = new RouteCollection(); + var srm = new ServicesRoutingManager(routeCollection); + + // Act + srm.MapHttpRoute("folder", "default", "url", new[] { "foo" }); + srm.MapHttpRoute("folder", "another", "alt/url", new[] { "foo" }); + + // Assert + var route = (Route)routeCollection[0]; + Assert.AreEqual("folder-default-0", route.DataTokens["Name"]); + route = (Route)routeCollection[1]; + Assert.AreEqual("folder-default-0-old", route.DataTokens["Name"]); + } + + [Test] + public void RoutesShouldHaveBackwardCompability() + { + // Arrange + var portalInfo = new ArrayList { new PortalInfo { PortalID = 0 } }; + this._mockPortalController.Setup(x => x.GetPortals()).Returns(portalInfo); + var mockPac = new Mock(); + mockPac.Setup(x => x.GetPortalAliasesByPortalId(0)).Returns(new[] { new PortalAliasInfo { HTTPAlias = "www.foo.com" } }); + PortalAliasController.SetTestableInstance(mockPac.Object); + + var routeCollection = new RouteCollection(); + var srm = new ServicesRoutingManager(routeCollection); + + // Act + srm.MapHttpRoute("folder", "default", "url", new[] { "foo" }); + + // Assert + var route = (Route)routeCollection[0]; + Assert.AreEqual("folder-default-0", route.DataTokens["Name"]); + route = (Route)routeCollection[1]; + Assert.AreEqual("folder-default-0-old", route.DataTokens["Name"]); + Assert.IsTrue(route.Url.StartsWith("DesktopModules")); + } + } +} diff --git a/DNN Platform/Tests/DotNetNuke.Tests.Web/InternalServices/SearchServiceControllerTests.cs b/DNN Platform/Tests/DotNetNuke.Tests.Web/InternalServices/SearchServiceControllerTests.cs index 9c7ce458aff..875786e47d6 100644 --- a/DNN Platform/Tests/DotNetNuke.Tests.Web/InternalServices/SearchServiceControllerTests.cs +++ b/DNN Platform/Tests/DotNetNuke.Tests.Web/InternalServices/SearchServiceControllerTests.cs @@ -2,724 +2,733 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information -namespace DotNetNuke.Tests.Web.InternalServices -{ - using System; - using System.Collections.Generic; - using System.Data; - using System.IO; - using System.Linq; - using System.Net.Http; - using System.Web.Http; - using System.Web.Http.Hosting; - - using DotNetNuke.Common.Utilities; - using DotNetNuke.ComponentModel; - using DotNetNuke.Data; - using DotNetNuke.Entities.Controllers; - using DotNetNuke.Entities.Modules; - using DotNetNuke.Entities.Portals; - using DotNetNuke.Entities.Portals.Data; - using DotNetNuke.Entities.Tabs; - using DotNetNuke.Entities.Users; - using DotNetNuke.Services.Cache; - using DotNetNuke.Services.Localization; - using DotNetNuke.Services.Search.Entities; - using DotNetNuke.Services.Search.Internals; - using DotNetNuke.Tests.Utilities.Mocks; - using DotNetNuke.Web.Api; - using DotNetNuke.Web.InternalServices; - using DotNetNuke.Web.InternalServices.Views.Search; - using Moq; - using NUnit.Framework; - - using Constants = DotNetNuke.Services.Search.Internals.Constants; - - /// - /// Testing grouping logic of GetGroupedBasicView and GetGroupedDetailView (SearchServiceController methods). - /// - [TestFixture] - public class SearchServiceControllerTests - { - private const int ModuleSearchTypeId = 1; - private const int TabSearchTypeId = 2; - private const int UserSearchTypeId = 3; - private const int UrlSearchTypeId = 5; - private const int PortalId0 = 0; - private const int HtmlModuleDefId = 20; - private const int HtmlModuleId = 25; - private const int RoleId731 = 731; - private const int RoleId0 = 0; - private const int HtmlModDefId = 116; - private const int TabId1 = 56; - private const int HtmlModuleId1 = 367; - private const int HtmlModuleId2 = 368; - private const int HtmlModuleId3 = 370; - private const string HtmlModuleTitle1 = "TitleWelcome"; - private const string HtmlModuleTitle2 = "TitleProducts"; - private const string HtmlModuleTitle3 = "TitleServices"; - private const int TabId2 = 57; - private const string HtmlModuleTitle4 = "TitleAboutUs"; - private const int HtmlModuleId4 = 378; - private const int UserId1 = 1; - private const string UserName1 = "User1"; - - private const string UserSearchTypeName = "user"; - private const string TabSearchTypeName = "tab"; - private const string UrlSearchTypeName = "url"; - - private const string FakeResultControllerClass = "DotNetNuke.Tests.Web.InternalServices.FakeResultController, DotNetNuke.Tests.Web"; - - private const string CultureEnUs = "en-US"; - - private const string SearchIndexFolder = @"App_Data\SearchTests"; - private const int DefaultSearchRetryTimes = 5; - - private readonly double _readerStaleTimeSpan = TimeSpan.FromMilliseconds(100).TotalSeconds; - private Mock _mockCBO; - private Mock _mockHostController; - private Mock _mockCachingProvider; - private Mock _mockDataProvider; - private Mock _mockLocaleController; - private Mock _mockDataService; - private Mock _mockUserController; - private Mock _mockModuleController; - private Mock _mockTabController; - private SearchServiceController _searchServiceController; - private IInternalSearchController _internalSearchController; - private LuceneControllerImpl _luceneController; - - [SetUp] - public void SetUp() - { - // Arrange - ComponentFactory.Container = new SimpleContainer(); - MockComponentProvider.ResetContainer(); - - this._mockDataProvider = MockComponentProvider.CreateDataProvider(); - this._mockLocaleController = MockComponentProvider.CreateLocaleController(); - this._mockCachingProvider = MockComponentProvider.CreateDataCacheProvider(); - this._mockDataService = new Mock(); - this._mockUserController = new Mock(); - this._mockModuleController = new Mock(); - this._mockTabController = new Mock(); - this._mockHostController = new Mock(); - - this.SetupDataProvider(); - this.SetupHostController(); - this.SetupUserController(); - this.SetupPortalSettings(); - this.SetupModuleController(); - this.DeleteIndexFolder(); - - TabController.SetTestableInstance(this._mockTabController.Object); - this._internalSearchController = InternalSearchController.Instance; - - this._mockCBO = new Mock(); - var tabKey = string.Format("{0}-{1}", TabSearchTypeId, 0); - var userKey = string.Format("{0}-{1}", UserSearchTypeId, 0); - this._mockCBO.Setup(c => c.GetCachedObject>(It.IsAny(), It.IsAny(), It.IsAny())) - .Returns(new Dictionary() { { tabKey, TabSearchTypeName }, { userKey, UserSearchTypeName } }); - CBO.SetTestableInstance(this._mockCBO.Object); - - // create instance of the SearchServiceController - var request = new HttpRequestMessage(); - var configuration = new HttpConfiguration(); - var provider = new Mock(); - ModuleInfo expectedModule; - provider.Setup(x => x.TryFindModuleInfo(request, out expectedModule)).Returns(true); - configuration.AddTabAndModuleInfoProvider(provider.Object); - request.Properties[HttpPropertyKeys.HttpConfigurationKey] = configuration; - this._searchServiceController = new SearchServiceController(HtmlModDefId) { Request = request }; - - this.CreateNewLuceneControllerInstance(); - } - - [TearDown] - public void TearDown() - { - this._luceneController.Dispose(); - this.DeleteIndexFolder(); - CBO.ClearInstance(); - TabController.ClearInstance(); - InternalSearchController.ClearInstance(); - UserController.ClearInstance(); - PortalController.ClearInstance(); - ModuleController.ClearInstance(); - } - - [Test] - public void GetSearchResultsDetailed() - { - const string keyword = "super"; - const string moduleBody = "super content is here"; - const string userUrl = "mysite/userid/1"; - const string tabUrl1 = "mysite/Home"; - const string tabUrl2 = "mysite/AboutUs"; - - // first tab with 2 modules - var doc1 = new SearchDocument { UniqueKey = "key01", TabId = TabId1, Url = tabUrl1, Title = keyword, SearchTypeId = TabSearchTypeId, ModifiedTimeUtc = DateTime.UtcNow }; - var doc2 = new SearchDocument { UniqueKey = "key02", TabId = TabId1, Title = keyword, Url = tabUrl1, SearchTypeId = ModuleSearchTypeId, ModifiedTimeUtc = DateTime.UtcNow, ModuleDefId = HtmlModuleDefId, ModuleId = HtmlModuleId2, Body = moduleBody, RoleId = 731 }; - var doc3 = new SearchDocument { UniqueKey = "key03", TabId = TabId1, Title = keyword, Url = tabUrl1, SearchTypeId = ModuleSearchTypeId, ModifiedTimeUtc = DateTime.UtcNow, ModuleDefId = HtmlModuleDefId, ModuleId = HtmlModuleId1, Body = moduleBody, RoleId = 731 }; - - // second tab with 1 module - var doc4 = new SearchDocument { UniqueKey = "key04", TabId = TabId2, Url = tabUrl2, Title = keyword, SearchTypeId = TabSearchTypeId, ModifiedTimeUtc = DateTime.UtcNow, RoleId = RoleId0 }; - var doc5 = new SearchDocument { UniqueKey = "key05", TabId = TabId2, Title = keyword, Url = tabUrl2, SearchTypeId = ModuleSearchTypeId, ModuleDefId = HtmlModuleId, ModuleId = HtmlModuleId3, ModifiedTimeUtc = DateTime.UtcNow, Body = moduleBody, RoleId = 731 }; - - // user doc - var userdoc = new SearchDocument { UniqueKey = "key06", Url = userUrl, Title = keyword, SearchTypeId = UserSearchTypeId, ModifiedTimeUtc = DateTime.UtcNow, RoleId = RoleId731 }; - this._internalSearchController.AddSearchDocument(doc1); - this._internalSearchController.AddSearchDocument(doc2); - this._internalSearchController.AddSearchDocument(doc3); - this._internalSearchController.AddSearchDocument(doc4); - this._internalSearchController.AddSearchDocument(doc5); - this._internalSearchController.AddSearchDocument(userdoc); - - var query = new SearchQuery - { - KeyWords = keyword, - SearchTypeIds = new[] { ModuleSearchTypeId, TabSearchTypeId, UserSearchTypeId }, - RoleId = 731, - }; - - // Run - var search = this.GetGroupedDetailViewResults(query); - - // Assert - var groupedDetailViews = search as List ?? search.ToList(); - - // Overall 3 groups - tab1, tab2 and user - Assert.AreEqual(3, groupedDetailViews.Count()); - - // Tab 1 has 2 DetailViews - Assert.AreEqual(2, groupedDetailViews.Single(x => x.DocumentUrl == tabUrl1).Results.Count()); - - // Tab 2 has 1 DetailViews - Assert.AreEqual(1, groupedDetailViews.Single(x => x.DocumentUrl == tabUrl2).Results.Count()); - - // UserUrl has 1 DetailViews - Assert.AreEqual(1, groupedDetailViews.Single(x => x.DocumentUrl == userUrl).Results.Count()); - } - - [Test] - public void GetSearchResultsBasic() - { - const string keyword = "awesome"; - const string userUrl = "mysite/userid/1"; - const string tabUrl1 = "mysite/Home"; - const string tabUrl2 = "mysite/AboutUs"; - - var now = DateTime.UtcNow; - var doc1 = new SearchDocument { UniqueKey = "key01", TabId = TabId1, Url = tabUrl1, Title = keyword, SearchTypeId = TabSearchTypeId, ModifiedTimeUtc = now, PortalId = PortalId0, RoleId = RoleId731 }; - var doc2 = new SearchDocument { UniqueKey = "key02", TabId = TabId2, Url = tabUrl2, Title = keyword, SearchTypeId = TabSearchTypeId, ModifiedTimeUtc = now, PortalId = PortalId0, RoleId = RoleId0 }; - var userdoc = new SearchDocument { UniqueKey = "key03", Url = userUrl, Title = keyword, SearchTypeId = UserSearchTypeId, ModifiedTimeUtc = now, PortalId = PortalId0, RoleId = RoleId0 }; - - this._internalSearchController.AddSearchDocument(doc1); - this._internalSearchController.AddSearchDocument(doc2); - this._internalSearchController.AddSearchDocument(userdoc); - this._internalSearchController.Commit(); - - var query = new SearchQuery - { - KeyWords = keyword, - PortalIds = new List { PortalId0 }, - SearchTypeIds = new[] { ModuleSearchTypeId, TabSearchTypeId, UserSearchTypeId }, - BeginModifiedTimeUtc = now.AddMinutes(-1), - EndModifiedTimeUtc = now.AddMinutes(+1), - PageIndex = 1, - PageSize = 15, - SortField = 0, - TitleSnippetLength = 120, - BodySnippetLength = 300, - WildCardSearch = true, - }; - - // Run - var search = this.GetGroupBasicViewResults(query); - - // Assert - overall 2 groups: tabs and users - var groupedBasicViews = search as List ?? search.ToList(); - Assert.AreEqual(2, groupedBasicViews.Count()); - - // 1 User results - Assert.AreEqual(1, groupedBasicViews.Single(x => x.DocumentTypeName == "user").Results.Count()); - - // User result should have 1 attribute(avatar) - Assert.AreEqual(1, groupedBasicViews.Single(x => x.DocumentTypeName == "user").Results.ElementAt(0).Attributes.Count()); - - // 2 Tabs results - Assert.AreEqual(2, groupedBasicViews.Single(x => x.DocumentTypeName == "tab").Results.Count()); - } - - [Test] - public void ModifyingDocumentsDoesNotCreateDuplicates() - { - // Arrange - const string tabUrl = "mysite/ContentUrl"; - const string title = "content title"; - const string contentBody = "content body"; - const string titleModified = title + " modified"; - var uniqueKey = Guid.NewGuid().ToString(); - var now = DateTime.UtcNow; - - var originalDocument = new SearchDocument - { - UniqueKey = uniqueKey, - TabId = TabId1, - Url = tabUrl, - Title = title, - Body = contentBody, - SearchTypeId = TabSearchTypeId, - ModifiedTimeUtc = now, - PortalId = PortalId0, - RoleId = RoleId731, - Keywords = { { "description", "mycontent" } }, - NumericKeys = { { "points", 5 } }, - }; - - this._internalSearchController.AddSearchDocument(originalDocument); - this._internalSearchController.Commit(); - - var modifiedDocument = new SearchDocument - { - UniqueKey = uniqueKey, - TabId = TabId1, - Url = tabUrl, - Title = titleModified, - Body = contentBody + " modified", - SearchTypeId = TabSearchTypeId, - ModifiedTimeUtc = now, - PortalId = PortalId0, - RoleId = RoleId731, - Keywords = { { "description", "mycontent_modified" }, { "description2", "mycontent_modified" } }, - NumericKeys = { { "points", 8 }, { "point2", 7 } }, - }; - - this._internalSearchController.AddSearchDocument(modifiedDocument); - this._internalSearchController.Commit(); - - var query = new SearchQuery - { - KeyWords = title, - PortalIds = new List { PortalId0 }, - SearchTypeIds = new[] { ModuleSearchTypeId, TabSearchTypeId, UserSearchTypeId }, - BeginModifiedTimeUtc = now.AddMinutes(-1), - EndModifiedTimeUtc = now.AddMinutes(+1), - PageIndex = 1, - PageSize = 15, - SortField = 0, - TitleSnippetLength = 120, - BodySnippetLength = 300, - WildCardSearch = true, - }; - - // Run - var searchResults = this.GetGroupedDetailViewResults(query).ToList(); - - // Assert - Assert.AreEqual(1, searchResults.Count()); - Assert.AreEqual(1, searchResults.First().Results.Count); - Assert.AreEqual(tabUrl, searchResults.First().Results.First().DocumentUrl); - Assert.AreEqual(titleModified, searchResults.First().Results.First().Title); - } - - private void CreateNewLuceneControllerInstance() - { - if (this._luceneController != null) - { - LuceneController.ClearInstance(); - this._luceneController.Dispose(); - } - - this._luceneController = new LuceneControllerImpl(); - LuceneController.SetTestableInstance(this._luceneController); - } - - private void SetupUserController() - { - this._mockUserController.Setup(c => c.GetUserById(It.IsAny(), It.IsAny())).Returns( - new UserInfo { UserID = UserId1, Username = UserName1, Profile = new UserProfile { } }); - UserController.SetTestableInstance(this._mockUserController.Object); - } - - private void SetupHostController() - { - this._mockHostController.Setup(c => c.GetString(Constants.SearchIndexFolderKey, It.IsAny())).Returns( - SearchIndexFolder); - this._mockHostController.Setup(c => c.GetDouble(Constants.SearchReaderRefreshTimeKey, It.IsAny())). - Returns(this._readerStaleTimeSpan); - this._mockHostController.Setup(c => c.GetInteger(Constants.SearchTitleBoostSetting, It.IsAny())).Returns( - Constants.DefaultSearchTitleBoost); - this._mockHostController.Setup(c => c.GetInteger(Constants.SearchTagBoostSetting, It.IsAny())).Returns( - Constants.DefaultSearchTagBoost); - this._mockHostController.Setup(c => c.GetInteger(Constants.SearchContentBoostSetting, It.IsAny())).Returns( - Constants.DefaultSearchKeywordBoost); - this._mockHostController.Setup(c => c.GetInteger(Constants.SearchDescriptionBoostSetting, It.IsAny())). - Returns(Constants.DefaultSearchDescriptionBoost); - this._mockHostController.Setup(c => c.GetInteger(Constants.SearchAuthorBoostSetting, It.IsAny())).Returns( - Constants.DefaultSearchAuthorBoost); - this._mockHostController.Setup(c => c.GetInteger(Constants.SearchMinLengthKey, It.IsAny())).Returns( - Constants.DefaultMinLen); - this._mockHostController.Setup(c => c.GetInteger(Constants.SearchMaxLengthKey, It.IsAny())).Returns( - Constants.DefaultMaxLen); - this._mockHostController.Setup(c => c.GetInteger(Constants.SearchRetryTimesKey, It.IsAny())).Returns( - DefaultSearchRetryTimes); - HostController.RegisterInstance(this._mockHostController.Object); - } - - private void SetupDataProvider() - { - // Standard DataProvider Path for Logging - this._mockDataProvider.Setup(d => d.GetProviderPath()).Returns(string.Empty); - - this._mockDataProvider.Setup(d => d.GetPortals(It.IsAny())).Returns(this.GetPortalsCallBack); - this._mockDataProvider.Setup(d => d.GetSearchModules(It.IsAny())).Returns(this.GetSearchModules); - this._mockDataProvider.Setup(d => d.GetModuleDefinitions()).Returns(this.GetModuleDefinitions); - this._mockDataProvider.Setup(d => d.GetAllSearchTypes()).Returns(this.GetAllSearchTypes); - this._mockDataProvider.Setup(d => d.GetUser(It.IsAny(), It.IsAny())).Returns(this.GetUser); - this._mockDataProvider.Setup(d => d.GetTabs(It.IsAny())).Returns(this.GetTabs); - this._mockDataService.Setup(ds => ds.GetPortalGroups()).Returns(this.GetPortalGroups); - - DataService.RegisterInstance(this._mockDataService.Object); - } - - private void SetupPortalSettings() - { - var mockPortalController = new Mock(); - mockPortalController.Setup(x => x.GetPortal(It.IsAny())).Returns(new PortalInfo { PortalID = PortalId0, PortalGroupID = -1, UserTabId = TabId1, }); - PortalController.SetTestableInstance(mockPortalController.Object); - } - - private void SetupModuleController() - { - this._mockModuleController.Setup(mc => mc.GetModule(It.Is(m => m == HtmlModuleId1), It.Is(p => p == PortalId0), false)).Returns( - new ModuleInfo { ModuleID = HtmlModuleId1, ModuleDefID = HtmlModDefId, ModuleTitle = HtmlModuleTitle1 }); - this._mockModuleController.Setup(mc => mc.GetModule(It.Is(m => m == HtmlModuleId2), It.Is(p => p == PortalId0), false)).Returns( - new ModuleInfo { ModuleID = HtmlModuleId2, ModuleDefID = HtmlModDefId, ModuleTitle = HtmlModuleTitle2 }); - this._mockModuleController.Setup(mc => mc.GetModule(It.Is(m => m == HtmlModuleId3), It.Is(p => p == PortalId0), false)).Returns( - new ModuleInfo { ModuleID = HtmlModuleId3, ModuleDefID = HtmlModDefId, ModuleTitle = HtmlModuleTitle3 }); - - this._mockModuleController.Setup(mc => mc.GetModule(It.Is(m => m == HtmlModuleId4), It.Is(p => p == PortalId0), false)).Returns( - new ModuleInfo { ModuleID = HtmlModuleId4, ModuleDefID = HtmlModDefId, ModuleTitle = HtmlModuleTitle4 }); - ModuleController.SetTestableInstance(this._mockModuleController.Object); - } - - private void DeleteIndexFolder() - { - try - { - if (Directory.Exists(SearchIndexFolder)) - { - Directory.Delete(SearchIndexFolder, true); - } - } - catch (Exception ex) - { - Console.WriteLine(ex); - } - } - - private IDataReader GetUser() - { - var table = new DataTable("Users"); - table.Columns.Add("UserID", typeof(int)); - table.Columns.Add("PortalId", typeof(int)); - table.Columns.Add("UserName", typeof(string)); - table.Columns.Add("FirstName", typeof(string)); - table.Columns.Add("LastName", typeof(string)); - table.Columns.Add("DisplayName", typeof(string)); - table.Columns.Add("IsSuperUser", typeof(byte)); - table.Columns.Add("Email", typeof(string)); - table.Columns.Add("VanityUrl", typeof(string)); - table.Columns.Add("AffiliateId", typeof(int)); - table.Columns.Add("IsDeleted", typeof(byte)); - table.Columns.Add("RefreshRoles", typeof(byte)); - table.Columns.Add("LastIPAddress", typeof(string)); - table.Columns.Add("UpdatePassword", typeof(byte)); - table.Columns.Add("PasswordResetToken", typeof(Guid)); - table.Columns.Add("PasswordResetExpiration", typeof(DateTime)); - table.Columns.Add("Authorised", typeof(byte)); - - table.Columns.Add("CreatedByUserID", typeof(int)); - table.Columns.Add("CreatedOnDate", typeof(DateTime)); - table.Columns.Add("LastModifiedByUserID", typeof(int)); - table.Columns.Add("LastModifiedOnDate", typeof(DateTime)); - - table.Rows.Add(1, null, UserName1, UserName1, UserName1, UserName1, 1, "host@changeme.invalid", null, null, 0, null, - "127.0.0.1", 0, "8D3C800F-7A40-45D6-BA4D-E59A393F9800", DateTime.Now, null, -1, DateTime.Now, - -1, DateTime.Now); - return table.CreateDataReader(); - } - - private IDataReader GetPortalGroups() - { - var table = new DataTable("ModuleDefinitions"); - var pkId = table.Columns.Add("PortalGroupID", typeof(int)); - table.Columns.Add("MasterPortalID", typeof(int)); - table.Columns.Add("PortalGroupName", typeof(string)); - table.Columns.Add("PortalGroupDescription", typeof(string)); - table.Columns.Add("AuthenticationDomain", typeof(string)); - table.Columns.Add("CreatedByUserID", typeof(int)); - table.Columns.Add("CreatedOnDate", typeof(DateTime)); - table.Columns.Add("LastModifiedByUserID", typeof(int)); - table.Columns.Add("LastModifiedOnDate", typeof(DateTime)); - table.PrimaryKey = new[] { pkId }; - - table.Rows.Add(0, 0, "test", "descr", "domain", -1, DateTime.Now, -1, DateTime.Now); - return table.CreateDataReader(); - } - - // return 2 test tabs(TabId 56 - Home, TabId 57 - AboutUs) - private IDataReader GetTabs() - { - var table = new DataTable("Tabs"); - table.Columns.Add("TabID", typeof(int)); - table.Columns.Add("TabOrder", typeof(int)); - table.Columns.Add("PortalID", typeof(int)); - table.Columns.Add("TabName", typeof(string)); - table.Columns.Add("ParentID", typeof(int)); - table.Columns.Add("Level", typeof(int)); - table.Columns.Add("TabPath", typeof(string)); - table.Columns.Add("UniqueId", typeof(Guid)); - table.Columns.Add("VersionGuid", typeof(Guid)); - table.Columns.Add("DefaultLanguageGuid", typeof(Guid)); - table.Columns.Add("LocalizedVersionGuid", typeof(Guid)); - table.Columns.Add("IsVisible", typeof(byte)); - table.Columns.Add("IconFile", typeof(string)); - table.Columns.Add("IconFileLarge", typeof(string)); - table.Columns.Add("DisableLink", typeof(byte)); - table.Columns.Add("Title", typeof(string)); - table.Columns.Add("Description", typeof(string)); - table.Columns.Add("KeyWords", typeof(string)); - table.Columns.Add("IsDeleted", typeof(byte)); - table.Columns.Add("SkinSrc", typeof(string)); - table.Columns.Add("ContainerSrc", typeof(string)); - table.Columns.Add("StartDate", typeof(DateTime)); - table.Columns.Add("EndDate", typeof(DateTime)); - table.Columns.Add("Url", typeof(string)); - table.Columns.Add("HasChildren", typeof(string)); - table.Columns.Add("RefreshInterval", typeof(int)); - table.Columns.Add("PageHeadText", typeof(string)); - table.Columns.Add("IsSecure", typeof(byte)); - table.Columns.Add("PermanentRedirect", typeof(byte)); - table.Columns.Add("SiteMapPriority", typeof(float)); - table.Columns.Add("ContentItemId", typeof(int)); - table.Columns.Add("Content", typeof(string)); - table.Columns.Add("ContentTypeID", typeof(int)); - table.Columns.Add("ModuleID", typeof(int)); - table.Columns.Add("ContentKey", typeof(string)); - table.Columns.Add("Indexed", typeof(byte)); - table.Columns.Add("StateID", typeof(int)); - table.Columns.Add("CultureCode", typeof(string)); - table.Columns.Add("CreatedByUserID", typeof(int)); - table.Columns.Add("CreatedOnDate", typeof(DateTime)); - table.Columns.Add("LastModifiedByUserID", typeof(int)); - table.Columns.Add("LastModifiedOnDate", typeof(DateTime)); - - table.Rows.Add(56, 5, 0, "Home", null, 0, "//Home", "C3174A2E-374D-4779-BE5F-BCDFF410E097", "A111A742-C18F-495D-8A23-BD0ECC70BBFE", null, "3A34424A-3CCA-4934-AE15-B9A80EB6D259", 1, null, null, 0, null, null, null, 0, "[G]Skins/Xcillion/Inner.ascx", "[G]Containers/Xcillion/NoTitle.ascx", null, null, null, "false", null, null, 0, 0, 0.5, 86, "Home", 1, -1, null, 0, null, null, -1, DateTime.Now, -1, DateTime.Now); - table.Rows.Add(57, 13, 0, "About Us", null, 0, "//AboutUs", "26A4236F-3AAA-4E15-8908-45D35675C677", "8426D3BC-E930-49CA-BDEB-4D41F194B6AC", null, "1461572D-97E8-41F8-BB1A-916DCA48890A", 1, null, null, 0, null, null, null, 0, "[G]Skins/Xcillion/Inner.ascx", "[G]Containers/Xcillion/NoTitle.ascx", null, null, null, "true", null, null, 0, 0, 0.5, 97, "About Us", 1, -1, null, 0, null, null, -1, DateTime.Now, -1, DateTime.Now); - - return table.CreateDataReader(); - } - - // return 4 html modules (TabId 56 - Home: ModuleIDs:367, 368, 370 TabId 57 - AboutUs: 378//) - private IDataReader GetSearchModules() - { - var table = new DataTable("SearchModules"); - table.Columns.Add("OwnerPortalID", typeof(int)); - table.Columns.Add("PortalID", typeof(int)); - table.Columns.Add("TabID", typeof(int)); - table.Columns.Add("TabModuleID", typeof(int)); - table.Columns.Add("ModuleID", typeof(int)); - table.Columns.Add("ModuleDefID", typeof(int)); - table.Columns.Add("ModuleOrder", typeof(int)); - table.Columns.Add("PaneName", typeof(string)); - table.Columns.Add("ModuleTitle", typeof(string)); - table.Columns.Add("CacheTime", typeof(int)); - table.Columns.Add("CacheMethod", typeof(string)); - table.Columns.Add("Alignment", typeof(string)); - table.Columns.Add("Color", typeof(string)); - table.Columns.Add("Border", typeof(string)); - table.Columns.Add("IconFile", typeof(string)); - table.Columns.Add("AllTabs", typeof(byte)); - table.Columns.Add("Visibility", typeof(int)); - table.Columns.Add("IsDeleted", typeof(byte)); - table.Columns.Add("Header", typeof(string)); - table.Columns.Add("Footer", typeof(string)); - table.Columns.Add("StartDate", typeof(DateTime)); - table.Columns.Add("EndDate", typeof(DateTime)); - table.Columns.Add("ContainerSrc", typeof(string)); - table.Columns.Add("DisplayTitle", typeof(byte)); - table.Columns.Add("DisplayPrint", typeof(byte)); - table.Columns.Add("DisplaySyndicate", typeof(byte)); - table.Columns.Add("IsWebSlice", typeof(byte)); - table.Columns.Add("WebSliceTitle", typeof(string)); - table.Columns.Add("WebSliceExpiryDate", typeof(DateTime)); - table.Columns.Add("WebSliceTTL", typeof(int)); - table.Columns.Add("InheritViewPermissions", typeof(int)); - table.Columns.Add("IsShareable", typeof(int)); - table.Columns.Add("IsShareableViewOnly", typeof(int)); - table.Columns.Add("DesktopModuleID", typeof(int)); - table.Columns.Add("DefaultCacheTime", typeof(int)); - table.Columns.Add("ModuleControlID", typeof(int)); - table.Columns.Add("BusinessControllerClass", typeof(string)); - table.Columns.Add("IsAdmin", typeof(byte)); - table.Columns.Add("SupportedFeatures", typeof(int)); - table.Columns.Add("ContentItemID", typeof(int)); - table.Columns.Add("Content", typeof(string)); - table.Columns.Add("ContentTypeID", typeof(int)); - table.Columns.Add("ContentKey", typeof(string)); - table.Columns.Add("Indexed", typeof(byte)); - table.Columns.Add("StateID", typeof(int)); - table.Columns.Add("CreatedByUserID", typeof(int)); - table.Columns.Add("CreatedOnDate", typeof(DateTime)); - table.Columns.Add("LastModifiedByUserID", typeof(int)); - table.Columns.Add("LastModifiedOnDate", typeof(DateTime)); - table.Columns.Add("LastContentModifiedOnDate", typeof(DateTime)); - table.Columns.Add("UniqueId", typeof(Guid)); - table.Columns.Add("VersionGuid", typeof(Guid)); - table.Columns.Add("defaultLanguageGuid", typeof(Guid)); - table.Columns.Add("localizedVersionGuid", typeof(Guid)); - table.Columns.Add("CultureCode", typeof(string)); - - table.Rows.Add(0, 0, 56, 57, 368, 116, 1, "contentpane", "Text/HTML", 1200, - "FileModuleCachingProvider", null, null, null, string.Empty, 0, 0, 0, null, null, null, null, - "[G]Containers/Xcillion/NoTitle.ascx", 1, 0, 0, 0, null, null, 0, 1, 1, 1, - 74, 1200, 238, - "DotNetNuke.Modules.Html.HtmlTextController, DotNetNuke.Modules.Html", 0, 7, 92, - "Text/HTML", 2, null, 0, null, -1, "2014-02-18 10:39:45.170", -1, - "2014-02-18 10:39:45.170", "2014-02-18 10:39:45.190", - "A0B23459-676C-4DE4-BCA1-33E222F8405A", "85AF4947-EB80-475D-9D8D-0BAD6B026A2B", null, - "664BAA98-7E24-461F-8180-36527619D042", string.Empty); - - table.Rows.Add(0, 0, 56, 56, 367, 116, 1, "contentpane", "Header Images", 1200, - "FileModuleCachingProvider", null, null, null, string.Empty, 0, 0, 0, null, null, null, null, - "[G]Containers/Xcillion/NoTitle.ascx", 1, 0, 0, 0, null, null, 0, 1, 1, 1, - 74, 1200, 238, - "DotNetNuke.Modules.Html.HtmlTextController, DotNetNuke.Modules.Html", 0, 7, 91, - "Header Images", 2, null, 0, null, -1, "2014-02-18 10:39:45.170", -1, - "2014-02-18 10:39:45.170", "2014-02-18 10:39:45.190", - "A0B23459-676C-4DE4-BCA1-33E222F8405A", "85AF4947-EB80-475D-9D8D-0BAD6B026A2B", null, - "664BAA98-7E24-461F-8180-36527619D042", string.Empty); - - table.Rows.Add(0, 0, 56, 59, 370, 116, 1, "contentpane", "Customer Support", 1200, - "FileModuleCachingProvider", null, null, null, string.Empty, 0, 0, 0, null, null, null, null, - "[G]Containers/Xcillion/NoTitle.ascx", 1, 0, 0, 0, null, null, 0, 1, 1, 1, - 74, 1200, 238, - "DotNetNuke.Modules.Html.HtmlTextController, DotNetNuke.Modules.Html", 0, 7, 94, - "Customer Support", 2, null, 0, null, -1, "2014-02-18 10:39:45.170", -1, - "2014-02-18 10:39:45.170", "2014-02-18 10:39:45.190", - "A0B23459-676C-4DE4-BCA1-33E222F8405A", "85AF4947-EB80-475D-9D8D-0BAD6B026A2B", null, - "664BAA98-7E24-461F-8180-36527619D042", string.Empty); - - table.Rows.Add(0, 0, 57, 67, 378, 116, 1, "contentpane", "About Us", 1200, - "FileModuleCachingProvider", null, null, null, string.Empty, 0, 0, 0, null, null, null, null, - "[G]Containers/Xcillion/NoTitle.ascx", 1, 0, 0, 0, null, null, 0, 1, 1, 1, - 74, 1200, 238, - "DotNetNuke.Modules.Html.HtmlTextController, DotNetNuke.Modules.Html", 0, 7, 103, - "Text/HTML", 2, null, 0, null, -1, "2014-02-18 10:39:45.170", -1, - "2014-02-18 10:39:45.170", "2014-02-18 10:39:45.190", - "A0B23459-676C-4DE4-BCA1-33E222F8405A", "85AF4947-EB80-475D-9D8D-0BAD6B026A2B", null, - "664BAA98-7E24-461F-8180-36527619D042", string.Empty); - return table.CreateDataReader(); - } - - // returns 2 moduledefinitions - Text/HTML and Journal - private IDataReader GetModuleDefinitions() - { - var table = new DataTable("ModuleDefinitions"); - var pkId = table.Columns.Add("ModuleDefID", typeof(int)); - table.Columns.Add("FriendlyName", typeof(string)); - table.Columns.Add("DesktopModuleID", typeof(int)); - table.Columns.Add("DefaultCacheTime", typeof(int)); - table.Columns.Add("CreatedByUserID", typeof(int)); - table.Columns.Add("CreatedOnDate", typeof(DateTime)); - table.Columns.Add("LastModifiedByUserID", typeof(int)); - table.Columns.Add("LastModifiedOnDate", typeof(DateTime)); - table.Columns.Add("DefinitionName", typeof(string)); - table.PrimaryKey = new[] { pkId }; - - table.Rows.Add(116, "Text/HTML", 74, 1200, -1, DateTime.Now, -1, DateTime.Now, "Text/HTML"); - table.Rows.Add(117, "Journal", 75, 0, -1, DateTime.Now, -1, DateTime.Now, "Journal"); - - return table.CreateDataReader(); - } - - // returns all search types - 3 SearchTypes - module, tab, user - private IDataReader GetAllSearchTypes() - { - var table = new DataTable("SearchTypes"); - var pkId = table.Columns.Add("SearchTypeId", typeof(int)); - table.Columns.Add("SearchTypeName", typeof(string)); - table.Columns.Add("SearchResultClass", typeof(string)); - table.Columns.Add("IsPrivate", typeof(byte)); - table.PrimaryKey = new[] { pkId }; - - table.Rows.Add(1, "module", FakeResultControllerClass, 0); - table.Rows.Add(2, "tab", FakeResultControllerClass, 0); - table.Rows.Add(3, "user", FakeResultControllerClass, 0); - return table.CreateDataReader(); - } - - private IDataReader GetPortalsCallBack(string culture) - { - return this.GetPortalCallBack(PortalId0, CultureEnUs); - } - - private IDataReader GetPortalCallBack(int portalId, string culture) - { - DataTable table = new DataTable("Portal"); - - var cols = new string[] - { - "PortalID", "PortalGroupID", "PortalName", "LogoFile", "FooterText", "ExpiryDate", - "UserRegistration", "BannerAdvertising", "AdministratorId", "Currency", "HostFee", - "HostSpace", "PageQuota", "UserQuota", "AdministratorRoleId", "RegisteredRoleId", - "Description", "KeyWords", "BackgroundFile", "GUID", "PaymentProcessor", - "ProcessorUserId", - "ProcessorPassword", "SiteLogHistory", "Email", "DefaultLanguage", "TimezoneOffset", - "AdminTabId", "HomeDirectory", "SplashTabId", "HomeTabId", "LoginTabId", "RegisterTabId", - "UserTabId", "SearchTabId", "Custom404TabId", "Custom500TabId", "TermsTabId", "PrivacyTabId", "SuperTabId", - "CreatedByUserID", "CreatedOnDate", "LastModifiedByUserID", "LastModifiedOnDate", - "CultureCode", - }; - - foreach (var col in cols) - { - table.Columns.Add(col); - } - - var homePage = 1; - table.Rows.Add(portalId, null, "My Website", "Logo.png", "Copyright 2011 by DotNetNuke Corporation", null, - "2", "0", "2", "USD", "0", "0", "0", "0", "0", "1", "My Website", - "DotNetNuke, DNN, Content, Management, CMS", null, "1057AC7A-3C08-4849-A3A6-3D2AB4662020", - null, null, null, "0", "admin@changeme.invalid", "en-US", "-8", "58", "Portals/0", null, - homePage.ToString(), null, null, "57", "56", "-1", "-1", null, null, "7", "-1", "2011-08-25 07:34:11", - "-1", "2011-08-25 07:34:29", culture); - - return table.CreateDataReader(); - } - - private IEnumerable GetGroupBasicViewResults(SearchQuery query) - { - var userSearchContentSource = new SearchContentSource - { - SearchTypeId = UrlSearchTypeId, - SearchTypeName = UrlSearchTypeName, - SearchResultClass = FakeResultControllerClass, - LocalizedName = UserSearchTypeName, - ModuleDefinitionId = 0, - }; - var results = this._searchServiceController.GetGroupedBasicViews(query, userSearchContentSource, PortalId0); - return results; - } - - private IEnumerable GetGroupedDetailViewResults(SearchQuery searchQuery) - { - bool more = false; - int totalHits = 0; - var results = this._searchServiceController.GetGroupedDetailViews(searchQuery, UserSearchTypeId, out totalHits, out more); - return results; - } - } -} +namespace DotNetNuke.Tests.Web.InternalServices +{ + using System; + using System.Collections.Generic; + using System.Data; + using System.IO; + using System.Linq; + using System.Net.Http; + using System.Web.Http; + using System.Web.Http.Hosting; + using DotNetNuke.Abstractions; + using DotNetNuke.Abstractions.Application; + using DotNetNuke.Common; + using DotNetNuke.Common.Utilities; + using DotNetNuke.ComponentModel; + using DotNetNuke.Data; + using DotNetNuke.Entities.Controllers; + using DotNetNuke.Entities.Modules; + using DotNetNuke.Entities.Portals; + using DotNetNuke.Entities.Portals.Data; + using DotNetNuke.Entities.Tabs; + using DotNetNuke.Entities.Users; + using DotNetNuke.Services.Cache; + using DotNetNuke.Services.Localization; + using DotNetNuke.Services.Search.Entities; + using DotNetNuke.Services.Search.Internals; + using DotNetNuke.Tests.Utilities.Mocks; + using DotNetNuke.Web.Api; + using DotNetNuke.Web.InternalServices; + using DotNetNuke.Web.InternalServices.Views.Search; + using Microsoft.Extensions.DependencyInjection; + using Moq; + using NUnit.Framework; + + using Constants = DotNetNuke.Services.Search.Internals.Constants; + + /// + /// Testing grouping logic of GetGroupedBasicView and GetGroupedDetailView (SearchServiceController methods). + /// + [TestFixture] + public class SearchServiceControllerTests + { + private const int ModuleSearchTypeId = 1; + private const int TabSearchTypeId = 2; + private const int UserSearchTypeId = 3; + private const int UrlSearchTypeId = 5; + private const int PortalId0 = 0; + private const int HtmlModuleDefId = 20; + private const int HtmlModuleId = 25; + private const int RoleId731 = 731; + private const int RoleId0 = 0; + private const int HtmlModDefId = 116; + private const int TabId1 = 56; + private const int HtmlModuleId1 = 367; + private const int HtmlModuleId2 = 368; + private const int HtmlModuleId3 = 370; + private const string HtmlModuleTitle1 = "TitleWelcome"; + private const string HtmlModuleTitle2 = "TitleProducts"; + private const string HtmlModuleTitle3 = "TitleServices"; + private const int TabId2 = 57; + private const string HtmlModuleTitle4 = "TitleAboutUs"; + private const int HtmlModuleId4 = 378; + private const int UserId1 = 1; + private const string UserName1 = "User1"; + + private const string UserSearchTypeName = "user"; + private const string TabSearchTypeName = "tab"; + private const string UrlSearchTypeName = "url"; + + private const string FakeResultControllerClass = "DotNetNuke.Tests.Web.InternalServices.FakeResultController, DotNetNuke.Tests.Web"; + + private const string CultureEnUs = "en-US"; + + private const string SearchIndexFolder = @"App_Data\SearchTests"; + private const int DefaultSearchRetryTimes = 5; + + private readonly double _readerStaleTimeSpan = TimeSpan.FromMilliseconds(100).TotalSeconds; + private Mock _mockCBO; + private Mock _mockHostController; + private Mock _mockCachingProvider; + private Mock _mockDataProvider; + private Mock _mockLocaleController; + private Mock _mockDataService; + private Mock _mockUserController; + private Mock _mockModuleController; + private Mock _mockTabController; + private SearchServiceController _searchServiceController; + private IInternalSearchController _internalSearchController; + private LuceneControllerImpl _luceneController; + + [SetUp] + public void SetUp() + { + // Arrange + ComponentFactory.Container = new SimpleContainer(); + MockComponentProvider.ResetContainer(); + + var serviceCollection = new ServiceCollection(); + serviceCollection.AddTransient(container => new DotNetNuke.Application.ApplicationStatusInfo(Mock.Of())); + serviceCollection.AddTransient(container => Mock.Of()); + Globals.DependencyProvider = serviceCollection.BuildServiceProvider(); + + this._mockDataProvider = MockComponentProvider.CreateDataProvider(); + this._mockLocaleController = MockComponentProvider.CreateLocaleController(); + this._mockCachingProvider = MockComponentProvider.CreateDataCacheProvider(); + this._mockDataService = new Mock(); + this._mockUserController = new Mock(); + this._mockModuleController = new Mock(); + this._mockTabController = new Mock(); + this._mockHostController = new Mock(); + + this.SetupDataProvider(); + this.SetupHostController(); + this.SetupUserController(); + this.SetupPortalSettings(); + this.SetupModuleController(); + this.DeleteIndexFolder(); + + TabController.SetTestableInstance(this._mockTabController.Object); + this._internalSearchController = InternalSearchController.Instance; + + this._mockCBO = new Mock(); + var tabKey = string.Format("{0}-{1}", TabSearchTypeId, 0); + var userKey = string.Format("{0}-{1}", UserSearchTypeId, 0); + this._mockCBO.Setup(c => c.GetCachedObject>(It.IsAny(), It.IsAny(), It.IsAny())) + .Returns(new Dictionary() { { tabKey, TabSearchTypeName }, { userKey, UserSearchTypeName } }); + CBO.SetTestableInstance(this._mockCBO.Object); + + // create instance of the SearchServiceController + var request = new HttpRequestMessage(); + var configuration = new HttpConfiguration(); + var provider = new Mock(); + ModuleInfo expectedModule; + provider.Setup(x => x.TryFindModuleInfo(request, out expectedModule)).Returns(true); + configuration.AddTabAndModuleInfoProvider(provider.Object); + request.Properties[HttpPropertyKeys.HttpConfigurationKey] = configuration; + this._searchServiceController = new SearchServiceController(HtmlModDefId) { Request = request }; + + this.CreateNewLuceneControllerInstance(); + } + + [TearDown] + public void TearDown() + { + Globals.DependencyProvider = null; + this._luceneController.Dispose(); + this.DeleteIndexFolder(); + CBO.ClearInstance(); + TabController.ClearInstance(); + InternalSearchController.ClearInstance(); + UserController.ClearInstance(); + PortalController.ClearInstance(); + ModuleController.ClearInstance(); + } + + [Test] + public void GetSearchResultsDetailed() + { + const string keyword = "super"; + const string moduleBody = "super content is here"; + const string userUrl = "mysite/userid/1"; + const string tabUrl1 = "mysite/Home"; + const string tabUrl2 = "mysite/AboutUs"; + + // first tab with 2 modules + var doc1 = new SearchDocument { UniqueKey = "key01", TabId = TabId1, Url = tabUrl1, Title = keyword, SearchTypeId = TabSearchTypeId, ModifiedTimeUtc = DateTime.UtcNow }; + var doc2 = new SearchDocument { UniqueKey = "key02", TabId = TabId1, Title = keyword, Url = tabUrl1, SearchTypeId = ModuleSearchTypeId, ModifiedTimeUtc = DateTime.UtcNow, ModuleDefId = HtmlModuleDefId, ModuleId = HtmlModuleId2, Body = moduleBody, RoleId = 731 }; + var doc3 = new SearchDocument { UniqueKey = "key03", TabId = TabId1, Title = keyword, Url = tabUrl1, SearchTypeId = ModuleSearchTypeId, ModifiedTimeUtc = DateTime.UtcNow, ModuleDefId = HtmlModuleDefId, ModuleId = HtmlModuleId1, Body = moduleBody, RoleId = 731 }; + + // second tab with 1 module + var doc4 = new SearchDocument { UniqueKey = "key04", TabId = TabId2, Url = tabUrl2, Title = keyword, SearchTypeId = TabSearchTypeId, ModifiedTimeUtc = DateTime.UtcNow, RoleId = RoleId0 }; + var doc5 = new SearchDocument { UniqueKey = "key05", TabId = TabId2, Title = keyword, Url = tabUrl2, SearchTypeId = ModuleSearchTypeId, ModuleDefId = HtmlModuleId, ModuleId = HtmlModuleId3, ModifiedTimeUtc = DateTime.UtcNow, Body = moduleBody, RoleId = 731 }; + + // user doc + var userdoc = new SearchDocument { UniqueKey = "key06", Url = userUrl, Title = keyword, SearchTypeId = UserSearchTypeId, ModifiedTimeUtc = DateTime.UtcNow, RoleId = RoleId731 }; + this._internalSearchController.AddSearchDocument(doc1); + this._internalSearchController.AddSearchDocument(doc2); + this._internalSearchController.AddSearchDocument(doc3); + this._internalSearchController.AddSearchDocument(doc4); + this._internalSearchController.AddSearchDocument(doc5); + this._internalSearchController.AddSearchDocument(userdoc); + + var query = new SearchQuery + { + KeyWords = keyword, + SearchTypeIds = new[] { ModuleSearchTypeId, TabSearchTypeId, UserSearchTypeId }, + RoleId = 731, + }; + + // Run + var search = this.GetGroupedDetailViewResults(query); + + // Assert + var groupedDetailViews = search as List ?? search.ToList(); + + // Overall 3 groups - tab1, tab2 and user + Assert.AreEqual(3, groupedDetailViews.Count()); + + // Tab 1 has 2 DetailViews + Assert.AreEqual(2, groupedDetailViews.Single(x => x.DocumentUrl == tabUrl1).Results.Count()); + + // Tab 2 has 1 DetailViews + Assert.AreEqual(1, groupedDetailViews.Single(x => x.DocumentUrl == tabUrl2).Results.Count()); + + // UserUrl has 1 DetailViews + Assert.AreEqual(1, groupedDetailViews.Single(x => x.DocumentUrl == userUrl).Results.Count()); + } + + [Test] + public void GetSearchResultsBasic() + { + const string keyword = "awesome"; + const string userUrl = "mysite/userid/1"; + const string tabUrl1 = "mysite/Home"; + const string tabUrl2 = "mysite/AboutUs"; + + var now = DateTime.UtcNow; + var doc1 = new SearchDocument { UniqueKey = "key01", TabId = TabId1, Url = tabUrl1, Title = keyword, SearchTypeId = TabSearchTypeId, ModifiedTimeUtc = now, PortalId = PortalId0, RoleId = RoleId731 }; + var doc2 = new SearchDocument { UniqueKey = "key02", TabId = TabId2, Url = tabUrl2, Title = keyword, SearchTypeId = TabSearchTypeId, ModifiedTimeUtc = now, PortalId = PortalId0, RoleId = RoleId0 }; + var userdoc = new SearchDocument { UniqueKey = "key03", Url = userUrl, Title = keyword, SearchTypeId = UserSearchTypeId, ModifiedTimeUtc = now, PortalId = PortalId0, RoleId = RoleId0 }; + + this._internalSearchController.AddSearchDocument(doc1); + this._internalSearchController.AddSearchDocument(doc2); + this._internalSearchController.AddSearchDocument(userdoc); + this._internalSearchController.Commit(); + + var query = new SearchQuery + { + KeyWords = keyword, + PortalIds = new List { PortalId0 }, + SearchTypeIds = new[] { ModuleSearchTypeId, TabSearchTypeId, UserSearchTypeId }, + BeginModifiedTimeUtc = now.AddMinutes(-1), + EndModifiedTimeUtc = now.AddMinutes(+1), + PageIndex = 1, + PageSize = 15, + SortField = 0, + TitleSnippetLength = 120, + BodySnippetLength = 300, + WildCardSearch = true, + }; + + // Run + var search = this.GetGroupBasicViewResults(query); + + // Assert - overall 2 groups: tabs and users + var groupedBasicViews = search as List ?? search.ToList(); + Assert.AreEqual(2, groupedBasicViews.Count()); + + // 1 User results + Assert.AreEqual(1, groupedBasicViews.Single(x => x.DocumentTypeName == "user").Results.Count()); + + // User result should have 1 attribute(avatar) + Assert.AreEqual(1, groupedBasicViews.Single(x => x.DocumentTypeName == "user").Results.ElementAt(0).Attributes.Count()); + + // 2 Tabs results + Assert.AreEqual(2, groupedBasicViews.Single(x => x.DocumentTypeName == "tab").Results.Count()); + } + + [Test] + public void ModifyingDocumentsDoesNotCreateDuplicates() + { + // Arrange + const string tabUrl = "mysite/ContentUrl"; + const string title = "content title"; + const string contentBody = "content body"; + const string titleModified = title + " modified"; + var uniqueKey = Guid.NewGuid().ToString(); + var now = DateTime.UtcNow; + + var originalDocument = new SearchDocument + { + UniqueKey = uniqueKey, + TabId = TabId1, + Url = tabUrl, + Title = title, + Body = contentBody, + SearchTypeId = TabSearchTypeId, + ModifiedTimeUtc = now, + PortalId = PortalId0, + RoleId = RoleId731, + Keywords = { { "description", "mycontent" } }, + NumericKeys = { { "points", 5 } }, + }; + + this._internalSearchController.AddSearchDocument(originalDocument); + this._internalSearchController.Commit(); + + var modifiedDocument = new SearchDocument + { + UniqueKey = uniqueKey, + TabId = TabId1, + Url = tabUrl, + Title = titleModified, + Body = contentBody + " modified", + SearchTypeId = TabSearchTypeId, + ModifiedTimeUtc = now, + PortalId = PortalId0, + RoleId = RoleId731, + Keywords = { { "description", "mycontent_modified" }, { "description2", "mycontent_modified" } }, + NumericKeys = { { "points", 8 }, { "point2", 7 } }, + }; + + this._internalSearchController.AddSearchDocument(modifiedDocument); + this._internalSearchController.Commit(); + + var query = new SearchQuery + { + KeyWords = title, + PortalIds = new List { PortalId0 }, + SearchTypeIds = new[] { ModuleSearchTypeId, TabSearchTypeId, UserSearchTypeId }, + BeginModifiedTimeUtc = now.AddMinutes(-1), + EndModifiedTimeUtc = now.AddMinutes(+1), + PageIndex = 1, + PageSize = 15, + SortField = 0, + TitleSnippetLength = 120, + BodySnippetLength = 300, + WildCardSearch = true, + }; + + // Run + var searchResults = this.GetGroupedDetailViewResults(query).ToList(); + + // Assert + Assert.AreEqual(1, searchResults.Count()); + Assert.AreEqual(1, searchResults.First().Results.Count); + Assert.AreEqual(tabUrl, searchResults.First().Results.First().DocumentUrl); + Assert.AreEqual(titleModified, searchResults.First().Results.First().Title); + } + + private void CreateNewLuceneControllerInstance() + { + if (this._luceneController != null) + { + LuceneController.ClearInstance(); + this._luceneController.Dispose(); + } + + this._luceneController = new LuceneControllerImpl(); + LuceneController.SetTestableInstance(this._luceneController); + } + + private void SetupUserController() + { + this._mockUserController.Setup(c => c.GetUserById(It.IsAny(), It.IsAny())).Returns( + new UserInfo { UserID = UserId1, Username = UserName1, Profile = new UserProfile { } }); + UserController.SetTestableInstance(this._mockUserController.Object); + } + + private void SetupHostController() + { + this._mockHostController.Setup(c => c.GetString(Constants.SearchIndexFolderKey, It.IsAny())).Returns( + SearchIndexFolder); + this._mockHostController.Setup(c => c.GetDouble(Constants.SearchReaderRefreshTimeKey, It.IsAny())). + Returns(this._readerStaleTimeSpan); + this._mockHostController.Setup(c => c.GetInteger(Constants.SearchTitleBoostSetting, It.IsAny())).Returns( + Constants.DefaultSearchTitleBoost); + this._mockHostController.Setup(c => c.GetInteger(Constants.SearchTagBoostSetting, It.IsAny())).Returns( + Constants.DefaultSearchTagBoost); + this._mockHostController.Setup(c => c.GetInteger(Constants.SearchContentBoostSetting, It.IsAny())).Returns( + Constants.DefaultSearchKeywordBoost); + this._mockHostController.Setup(c => c.GetInteger(Constants.SearchDescriptionBoostSetting, It.IsAny())). + Returns(Constants.DefaultSearchDescriptionBoost); + this._mockHostController.Setup(c => c.GetInteger(Constants.SearchAuthorBoostSetting, It.IsAny())).Returns( + Constants.DefaultSearchAuthorBoost); + this._mockHostController.Setup(c => c.GetInteger(Constants.SearchMinLengthKey, It.IsAny())).Returns( + Constants.DefaultMinLen); + this._mockHostController.Setup(c => c.GetInteger(Constants.SearchMaxLengthKey, It.IsAny())).Returns( + Constants.DefaultMaxLen); + this._mockHostController.Setup(c => c.GetInteger(Constants.SearchRetryTimesKey, It.IsAny())).Returns( + DefaultSearchRetryTimes); + HostController.RegisterInstance(this._mockHostController.Object); + } + + private void SetupDataProvider() + { + // Standard DataProvider Path for Logging + this._mockDataProvider.Setup(d => d.GetProviderPath()).Returns(string.Empty); + + this._mockDataProvider.Setup(d => d.GetPortals(It.IsAny())).Returns(this.GetPortalsCallBack); + this._mockDataProvider.Setup(d => d.GetSearchModules(It.IsAny())).Returns(this.GetSearchModules); + this._mockDataProvider.Setup(d => d.GetModuleDefinitions()).Returns(this.GetModuleDefinitions); + this._mockDataProvider.Setup(d => d.GetAllSearchTypes()).Returns(this.GetAllSearchTypes); + this._mockDataProvider.Setup(d => d.GetUser(It.IsAny(), It.IsAny())).Returns(this.GetUser); + this._mockDataProvider.Setup(d => d.GetTabs(It.IsAny())).Returns(this.GetTabs); + this._mockDataService.Setup(ds => ds.GetPortalGroups()).Returns(this.GetPortalGroups); + + DataService.RegisterInstance(this._mockDataService.Object); + } + + private void SetupPortalSettings() + { + var mockPortalController = new Mock(); + mockPortalController.Setup(x => x.GetPortal(It.IsAny())).Returns(new PortalInfo { PortalID = PortalId0, PortalGroupID = -1, UserTabId = TabId1, }); + PortalController.SetTestableInstance(mockPortalController.Object); + } + + private void SetupModuleController() + { + this._mockModuleController.Setup(mc => mc.GetModule(It.Is(m => m == HtmlModuleId1), It.Is(p => p == PortalId0), false)).Returns( + new ModuleInfo { ModuleID = HtmlModuleId1, ModuleDefID = HtmlModDefId, ModuleTitle = HtmlModuleTitle1 }); + this._mockModuleController.Setup(mc => mc.GetModule(It.Is(m => m == HtmlModuleId2), It.Is(p => p == PortalId0), false)).Returns( + new ModuleInfo { ModuleID = HtmlModuleId2, ModuleDefID = HtmlModDefId, ModuleTitle = HtmlModuleTitle2 }); + this._mockModuleController.Setup(mc => mc.GetModule(It.Is(m => m == HtmlModuleId3), It.Is(p => p == PortalId0), false)).Returns( + new ModuleInfo { ModuleID = HtmlModuleId3, ModuleDefID = HtmlModDefId, ModuleTitle = HtmlModuleTitle3 }); + + this._mockModuleController.Setup(mc => mc.GetModule(It.Is(m => m == HtmlModuleId4), It.Is(p => p == PortalId0), false)).Returns( + new ModuleInfo { ModuleID = HtmlModuleId4, ModuleDefID = HtmlModDefId, ModuleTitle = HtmlModuleTitle4 }); + ModuleController.SetTestableInstance(this._mockModuleController.Object); + } + + private void DeleteIndexFolder() + { + try + { + if (Directory.Exists(SearchIndexFolder)) + { + Directory.Delete(SearchIndexFolder, true); + } + } + catch (Exception ex) + { + Console.WriteLine(ex); + } + } + + private IDataReader GetUser() + { + var table = new DataTable("Users"); + table.Columns.Add("UserID", typeof(int)); + table.Columns.Add("PortalId", typeof(int)); + table.Columns.Add("UserName", typeof(string)); + table.Columns.Add("FirstName", typeof(string)); + table.Columns.Add("LastName", typeof(string)); + table.Columns.Add("DisplayName", typeof(string)); + table.Columns.Add("IsSuperUser", typeof(byte)); + table.Columns.Add("Email", typeof(string)); + table.Columns.Add("VanityUrl", typeof(string)); + table.Columns.Add("AffiliateId", typeof(int)); + table.Columns.Add("IsDeleted", typeof(byte)); + table.Columns.Add("RefreshRoles", typeof(byte)); + table.Columns.Add("LastIPAddress", typeof(string)); + table.Columns.Add("UpdatePassword", typeof(byte)); + table.Columns.Add("PasswordResetToken", typeof(Guid)); + table.Columns.Add("PasswordResetExpiration", typeof(DateTime)); + table.Columns.Add("Authorised", typeof(byte)); + + table.Columns.Add("CreatedByUserID", typeof(int)); + table.Columns.Add("CreatedOnDate", typeof(DateTime)); + table.Columns.Add("LastModifiedByUserID", typeof(int)); + table.Columns.Add("LastModifiedOnDate", typeof(DateTime)); + + table.Rows.Add(1, null, UserName1, UserName1, UserName1, UserName1, 1, "host@changeme.invalid", null, null, 0, null, + "127.0.0.1", 0, "8D3C800F-7A40-45D6-BA4D-E59A393F9800", DateTime.Now, null, -1, DateTime.Now, + -1, DateTime.Now); + return table.CreateDataReader(); + } + + private IDataReader GetPortalGroups() + { + var table = new DataTable("ModuleDefinitions"); + var pkId = table.Columns.Add("PortalGroupID", typeof(int)); + table.Columns.Add("MasterPortalID", typeof(int)); + table.Columns.Add("PortalGroupName", typeof(string)); + table.Columns.Add("PortalGroupDescription", typeof(string)); + table.Columns.Add("AuthenticationDomain", typeof(string)); + table.Columns.Add("CreatedByUserID", typeof(int)); + table.Columns.Add("CreatedOnDate", typeof(DateTime)); + table.Columns.Add("LastModifiedByUserID", typeof(int)); + table.Columns.Add("LastModifiedOnDate", typeof(DateTime)); + table.PrimaryKey = new[] { pkId }; + + table.Rows.Add(0, 0, "test", "descr", "domain", -1, DateTime.Now, -1, DateTime.Now); + return table.CreateDataReader(); + } + + // return 2 test tabs(TabId 56 - Home, TabId 57 - AboutUs) + private IDataReader GetTabs() + { + var table = new DataTable("Tabs"); + table.Columns.Add("TabID", typeof(int)); + table.Columns.Add("TabOrder", typeof(int)); + table.Columns.Add("PortalID", typeof(int)); + table.Columns.Add("TabName", typeof(string)); + table.Columns.Add("ParentID", typeof(int)); + table.Columns.Add("Level", typeof(int)); + table.Columns.Add("TabPath", typeof(string)); + table.Columns.Add("UniqueId", typeof(Guid)); + table.Columns.Add("VersionGuid", typeof(Guid)); + table.Columns.Add("DefaultLanguageGuid", typeof(Guid)); + table.Columns.Add("LocalizedVersionGuid", typeof(Guid)); + table.Columns.Add("IsVisible", typeof(byte)); + table.Columns.Add("IconFile", typeof(string)); + table.Columns.Add("IconFileLarge", typeof(string)); + table.Columns.Add("DisableLink", typeof(byte)); + table.Columns.Add("Title", typeof(string)); + table.Columns.Add("Description", typeof(string)); + table.Columns.Add("KeyWords", typeof(string)); + table.Columns.Add("IsDeleted", typeof(byte)); + table.Columns.Add("SkinSrc", typeof(string)); + table.Columns.Add("ContainerSrc", typeof(string)); + table.Columns.Add("StartDate", typeof(DateTime)); + table.Columns.Add("EndDate", typeof(DateTime)); + table.Columns.Add("Url", typeof(string)); + table.Columns.Add("HasChildren", typeof(string)); + table.Columns.Add("RefreshInterval", typeof(int)); + table.Columns.Add("PageHeadText", typeof(string)); + table.Columns.Add("IsSecure", typeof(byte)); + table.Columns.Add("PermanentRedirect", typeof(byte)); + table.Columns.Add("SiteMapPriority", typeof(float)); + table.Columns.Add("ContentItemId", typeof(int)); + table.Columns.Add("Content", typeof(string)); + table.Columns.Add("ContentTypeID", typeof(int)); + table.Columns.Add("ModuleID", typeof(int)); + table.Columns.Add("ContentKey", typeof(string)); + table.Columns.Add("Indexed", typeof(byte)); + table.Columns.Add("StateID", typeof(int)); + table.Columns.Add("CultureCode", typeof(string)); + table.Columns.Add("CreatedByUserID", typeof(int)); + table.Columns.Add("CreatedOnDate", typeof(DateTime)); + table.Columns.Add("LastModifiedByUserID", typeof(int)); + table.Columns.Add("LastModifiedOnDate", typeof(DateTime)); + + table.Rows.Add(56, 5, 0, "Home", null, 0, "//Home", "C3174A2E-374D-4779-BE5F-BCDFF410E097", "A111A742-C18F-495D-8A23-BD0ECC70BBFE", null, "3A34424A-3CCA-4934-AE15-B9A80EB6D259", 1, null, null, 0, null, null, null, 0, "[G]Skins/Xcillion/Inner.ascx", "[G]Containers/Xcillion/NoTitle.ascx", null, null, null, "false", null, null, 0, 0, 0.5, 86, "Home", 1, -1, null, 0, null, null, -1, DateTime.Now, -1, DateTime.Now); + table.Rows.Add(57, 13, 0, "About Us", null, 0, "//AboutUs", "26A4236F-3AAA-4E15-8908-45D35675C677", "8426D3BC-E930-49CA-BDEB-4D41F194B6AC", null, "1461572D-97E8-41F8-BB1A-916DCA48890A", 1, null, null, 0, null, null, null, 0, "[G]Skins/Xcillion/Inner.ascx", "[G]Containers/Xcillion/NoTitle.ascx", null, null, null, "true", null, null, 0, 0, 0.5, 97, "About Us", 1, -1, null, 0, null, null, -1, DateTime.Now, -1, DateTime.Now); + + return table.CreateDataReader(); + } + + // return 4 html modules (TabId 56 - Home: ModuleIDs:367, 368, 370 TabId 57 - AboutUs: 378//) + private IDataReader GetSearchModules() + { + var table = new DataTable("SearchModules"); + table.Columns.Add("OwnerPortalID", typeof(int)); + table.Columns.Add("PortalID", typeof(int)); + table.Columns.Add("TabID", typeof(int)); + table.Columns.Add("TabModuleID", typeof(int)); + table.Columns.Add("ModuleID", typeof(int)); + table.Columns.Add("ModuleDefID", typeof(int)); + table.Columns.Add("ModuleOrder", typeof(int)); + table.Columns.Add("PaneName", typeof(string)); + table.Columns.Add("ModuleTitle", typeof(string)); + table.Columns.Add("CacheTime", typeof(int)); + table.Columns.Add("CacheMethod", typeof(string)); + table.Columns.Add("Alignment", typeof(string)); + table.Columns.Add("Color", typeof(string)); + table.Columns.Add("Border", typeof(string)); + table.Columns.Add("IconFile", typeof(string)); + table.Columns.Add("AllTabs", typeof(byte)); + table.Columns.Add("Visibility", typeof(int)); + table.Columns.Add("IsDeleted", typeof(byte)); + table.Columns.Add("Header", typeof(string)); + table.Columns.Add("Footer", typeof(string)); + table.Columns.Add("StartDate", typeof(DateTime)); + table.Columns.Add("EndDate", typeof(DateTime)); + table.Columns.Add("ContainerSrc", typeof(string)); + table.Columns.Add("DisplayTitle", typeof(byte)); + table.Columns.Add("DisplayPrint", typeof(byte)); + table.Columns.Add("DisplaySyndicate", typeof(byte)); + table.Columns.Add("IsWebSlice", typeof(byte)); + table.Columns.Add("WebSliceTitle", typeof(string)); + table.Columns.Add("WebSliceExpiryDate", typeof(DateTime)); + table.Columns.Add("WebSliceTTL", typeof(int)); + table.Columns.Add("InheritViewPermissions", typeof(int)); + table.Columns.Add("IsShareable", typeof(int)); + table.Columns.Add("IsShareableViewOnly", typeof(int)); + table.Columns.Add("DesktopModuleID", typeof(int)); + table.Columns.Add("DefaultCacheTime", typeof(int)); + table.Columns.Add("ModuleControlID", typeof(int)); + table.Columns.Add("BusinessControllerClass", typeof(string)); + table.Columns.Add("IsAdmin", typeof(byte)); + table.Columns.Add("SupportedFeatures", typeof(int)); + table.Columns.Add("ContentItemID", typeof(int)); + table.Columns.Add("Content", typeof(string)); + table.Columns.Add("ContentTypeID", typeof(int)); + table.Columns.Add("ContentKey", typeof(string)); + table.Columns.Add("Indexed", typeof(byte)); + table.Columns.Add("StateID", typeof(int)); + table.Columns.Add("CreatedByUserID", typeof(int)); + table.Columns.Add("CreatedOnDate", typeof(DateTime)); + table.Columns.Add("LastModifiedByUserID", typeof(int)); + table.Columns.Add("LastModifiedOnDate", typeof(DateTime)); + table.Columns.Add("LastContentModifiedOnDate", typeof(DateTime)); + table.Columns.Add("UniqueId", typeof(Guid)); + table.Columns.Add("VersionGuid", typeof(Guid)); + table.Columns.Add("defaultLanguageGuid", typeof(Guid)); + table.Columns.Add("localizedVersionGuid", typeof(Guid)); + table.Columns.Add("CultureCode", typeof(string)); + + table.Rows.Add(0, 0, 56, 57, 368, 116, 1, "contentpane", "Text/HTML", 1200, + "FileModuleCachingProvider", null, null, null, string.Empty, 0, 0, 0, null, null, null, null, + "[G]Containers/Xcillion/NoTitle.ascx", 1, 0, 0, 0, null, null, 0, 1, 1, 1, + 74, 1200, 238, + "DotNetNuke.Modules.Html.HtmlTextController, DotNetNuke.Modules.Html", 0, 7, 92, + "Text/HTML", 2, null, 0, null, -1, "2014-02-18 10:39:45.170", -1, + "2014-02-18 10:39:45.170", "2014-02-18 10:39:45.190", + "A0B23459-676C-4DE4-BCA1-33E222F8405A", "85AF4947-EB80-475D-9D8D-0BAD6B026A2B", null, + "664BAA98-7E24-461F-8180-36527619D042", string.Empty); + + table.Rows.Add(0, 0, 56, 56, 367, 116, 1, "contentpane", "Header Images", 1200, + "FileModuleCachingProvider", null, null, null, string.Empty, 0, 0, 0, null, null, null, null, + "[G]Containers/Xcillion/NoTitle.ascx", 1, 0, 0, 0, null, null, 0, 1, 1, 1, + 74, 1200, 238, + "DotNetNuke.Modules.Html.HtmlTextController, DotNetNuke.Modules.Html", 0, 7, 91, + "Header Images", 2, null, 0, null, -1, "2014-02-18 10:39:45.170", -1, + "2014-02-18 10:39:45.170", "2014-02-18 10:39:45.190", + "A0B23459-676C-4DE4-BCA1-33E222F8405A", "85AF4947-EB80-475D-9D8D-0BAD6B026A2B", null, + "664BAA98-7E24-461F-8180-36527619D042", string.Empty); + + table.Rows.Add(0, 0, 56, 59, 370, 116, 1, "contentpane", "Customer Support", 1200, + "FileModuleCachingProvider", null, null, null, string.Empty, 0, 0, 0, null, null, null, null, + "[G]Containers/Xcillion/NoTitle.ascx", 1, 0, 0, 0, null, null, 0, 1, 1, 1, + 74, 1200, 238, + "DotNetNuke.Modules.Html.HtmlTextController, DotNetNuke.Modules.Html", 0, 7, 94, + "Customer Support", 2, null, 0, null, -1, "2014-02-18 10:39:45.170", -1, + "2014-02-18 10:39:45.170", "2014-02-18 10:39:45.190", + "A0B23459-676C-4DE4-BCA1-33E222F8405A", "85AF4947-EB80-475D-9D8D-0BAD6B026A2B", null, + "664BAA98-7E24-461F-8180-36527619D042", string.Empty); + + table.Rows.Add(0, 0, 57, 67, 378, 116, 1, "contentpane", "About Us", 1200, + "FileModuleCachingProvider", null, null, null, string.Empty, 0, 0, 0, null, null, null, null, + "[G]Containers/Xcillion/NoTitle.ascx", 1, 0, 0, 0, null, null, 0, 1, 1, 1, + 74, 1200, 238, + "DotNetNuke.Modules.Html.HtmlTextController, DotNetNuke.Modules.Html", 0, 7, 103, + "Text/HTML", 2, null, 0, null, -1, "2014-02-18 10:39:45.170", -1, + "2014-02-18 10:39:45.170", "2014-02-18 10:39:45.190", + "A0B23459-676C-4DE4-BCA1-33E222F8405A", "85AF4947-EB80-475D-9D8D-0BAD6B026A2B", null, + "664BAA98-7E24-461F-8180-36527619D042", string.Empty); + return table.CreateDataReader(); + } + + // returns 2 moduledefinitions - Text/HTML and Journal + private IDataReader GetModuleDefinitions() + { + var table = new DataTable("ModuleDefinitions"); + var pkId = table.Columns.Add("ModuleDefID", typeof(int)); + table.Columns.Add("FriendlyName", typeof(string)); + table.Columns.Add("DesktopModuleID", typeof(int)); + table.Columns.Add("DefaultCacheTime", typeof(int)); + table.Columns.Add("CreatedByUserID", typeof(int)); + table.Columns.Add("CreatedOnDate", typeof(DateTime)); + table.Columns.Add("LastModifiedByUserID", typeof(int)); + table.Columns.Add("LastModifiedOnDate", typeof(DateTime)); + table.Columns.Add("DefinitionName", typeof(string)); + table.PrimaryKey = new[] { pkId }; + + table.Rows.Add(116, "Text/HTML", 74, 1200, -1, DateTime.Now, -1, DateTime.Now, "Text/HTML"); + table.Rows.Add(117, "Journal", 75, 0, -1, DateTime.Now, -1, DateTime.Now, "Journal"); + + return table.CreateDataReader(); + } + + // returns all search types - 3 SearchTypes - module, tab, user + private IDataReader GetAllSearchTypes() + { + var table = new DataTable("SearchTypes"); + var pkId = table.Columns.Add("SearchTypeId", typeof(int)); + table.Columns.Add("SearchTypeName", typeof(string)); + table.Columns.Add("SearchResultClass", typeof(string)); + table.Columns.Add("IsPrivate", typeof(byte)); + table.PrimaryKey = new[] { pkId }; + + table.Rows.Add(1, "module", FakeResultControllerClass, 0); + table.Rows.Add(2, "tab", FakeResultControllerClass, 0); + table.Rows.Add(3, "user", FakeResultControllerClass, 0); + return table.CreateDataReader(); + } + + private IDataReader GetPortalsCallBack(string culture) + { + return this.GetPortalCallBack(PortalId0, CultureEnUs); + } + + private IDataReader GetPortalCallBack(int portalId, string culture) + { + DataTable table = new DataTable("Portal"); + + var cols = new string[] + { + "PortalID", "PortalGroupID", "PortalName", "LogoFile", "FooterText", "ExpiryDate", + "UserRegistration", "BannerAdvertising", "AdministratorId", "Currency", "HostFee", + "HostSpace", "PageQuota", "UserQuota", "AdministratorRoleId", "RegisteredRoleId", + "Description", "KeyWords", "BackgroundFile", "GUID", "PaymentProcessor", + "ProcessorUserId", + "ProcessorPassword", "SiteLogHistory", "Email", "DefaultLanguage", "TimezoneOffset", + "AdminTabId", "HomeDirectory", "SplashTabId", "HomeTabId", "LoginTabId", "RegisterTabId", + "UserTabId", "SearchTabId", "Custom404TabId", "Custom500TabId", "TermsTabId", "PrivacyTabId", "SuperTabId", + "CreatedByUserID", "CreatedOnDate", "LastModifiedByUserID", "LastModifiedOnDate", + "CultureCode", + }; + + foreach (var col in cols) + { + table.Columns.Add(col); + } + + var homePage = 1; + table.Rows.Add(portalId, null, "My Website", "Logo.png", "Copyright 2011 by DotNetNuke Corporation", null, + "2", "0", "2", "USD", "0", "0", "0", "0", "0", "1", "My Website", + "DotNetNuke, DNN, Content, Management, CMS", null, "1057AC7A-3C08-4849-A3A6-3D2AB4662020", + null, null, null, "0", "admin@changeme.invalid", "en-US", "-8", "58", "Portals/0", null, + homePage.ToString(), null, null, "57", "56", "-1", "-1", null, null, "7", "-1", "2011-08-25 07:34:11", + "-1", "2011-08-25 07:34:29", culture); + + return table.CreateDataReader(); + } + + private IEnumerable GetGroupBasicViewResults(SearchQuery query) + { + var userSearchContentSource = new SearchContentSource + { + SearchTypeId = UrlSearchTypeId, + SearchTypeName = UrlSearchTypeName, + SearchResultClass = FakeResultControllerClass, + LocalizedName = UserSearchTypeName, + ModuleDefinitionId = 0, + }; + var results = this._searchServiceController.GetGroupedBasicViews(query, userSearchContentSource, PortalId0); + return results; + } + + private IEnumerable GetGroupedDetailViewResults(SearchQuery searchQuery) + { + bool more = false; + int totalHits = 0; + var results = this._searchServiceController.GetGroupedDetailViews(searchQuery, UserSearchTypeId, out totalHits, out more); + return results; + } + } +}