Merge remote-tracking branch 'origin/netcore/netcore' into netcore/task/6973-migrating-authenticationcontroller

# Conflicts:
#	src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs
#	src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs
#	src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs
#	src/Umbraco.Web/Editors/BackOfficeController.cs
#	src/Umbraco.Web/Mvc/UmbracoController.cs
This commit is contained in:
Shannon
2020-10-22 21:16:44 +11:00
238 changed files with 2413 additions and 3987 deletions

View File

@@ -1,224 +0,0 @@
using Moq;
using NUnit.Framework;
using Serilog;
using System;
using System.IO;
using System.Linq;
using Microsoft.Extensions.Logging;
using Umbraco.Core;
using Umbraco.Core.Logging.Viewer;
using Umbraco.Tests.TestHelpers;
namespace Umbraco.Tests.Logging
{
[TestFixture]
public class LogviewerTests
{
private ILogViewer _logViewer;
const string _logfileName = "UmbracoTraceLog.UNITTEST.20181112.json";
const string _searchfileName = "logviewer.searches.config.js";
private string _newLogfilePath;
private string _newLogfileDirPath;
private string _newSearchfilePath;
private string _newSearchfileDirPath;
private LogTimePeriod _logTimePeriod = new LogTimePeriod(
new DateTime(year: 2018, month: 11, day: 12, hour:0, minute:0, second:0),
new DateTime(year: 2018, month: 11, day: 13, hour: 0, minute: 0, second: 0)
);
[OneTimeSetUp]
public void Setup()
{
//Create an example JSON log file to check results
//As a one time setup for all tets in this class/fixture
var ioHelper = TestHelper.IOHelper;
var hostingEnv = TestHelper.GetHostingEnvironment();
var loggingConfiguration = TestHelper.GetLoggingConfiguration(hostingEnv);
var exampleLogfilePath = Path.Combine(TestContext.CurrentContext.TestDirectory, @"Logging\", _logfileName);
_newLogfileDirPath = loggingConfiguration.LogDirectory;
_newLogfilePath = Path.Combine(_newLogfileDirPath, _logfileName);
var exampleSearchfilePath = Path.Combine(TestContext.CurrentContext.TestDirectory, @"Logging\", _searchfileName);
_newSearchfileDirPath = Path.Combine(hostingEnv.ApplicationPhysicalPath, @"Config\");
_newSearchfilePath = Path.Combine(_newSearchfileDirPath, _searchfileName);
//Create/ensure Directory exists
ioHelper.EnsurePathExists(_newLogfileDirPath);
ioHelper.EnsurePathExists(_newSearchfileDirPath);
//Copy the sample files
File.Copy(exampleLogfilePath, _newLogfilePath, true);
File.Copy(exampleSearchfilePath, _newSearchfilePath, true);
var logger = Mock.Of<ILogger<SerilogJsonLogViewer>>();
var logViewerConfig = new LogViewerConfig(hostingEnv);
_logViewer = new SerilogJsonLogViewer(logger, logViewerConfig, loggingConfiguration, Log.Logger);
}
[OneTimeTearDown]
public void TearDown()
{
//Cleanup & delete the example log & search files off disk
//Once all tests in this class/fixture have run
if (File.Exists(_newLogfilePath))
File.Delete(_newLogfilePath);
if (File.Exists(_newSearchfilePath))
File.Delete(_newSearchfilePath);
}
[Test]
public void Logs_Contain_Correct_Error_Count()
{
var numberOfErrors = _logViewer.GetNumberOfErrors(_logTimePeriod);
//Our dummy log should contain 2 errors
Assert.AreEqual(2, numberOfErrors);
}
[Test]
public void Logs_Contain_Correct_Log_Level_Counts()
{
var logCounts = _logViewer.GetLogLevelCounts(_logTimePeriod);
Assert.AreEqual(1954, logCounts.Debug);
Assert.AreEqual(2, logCounts.Error);
Assert.AreEqual(0, logCounts.Fatal);
Assert.AreEqual(62, logCounts.Information);
Assert.AreEqual(7, logCounts.Warning);
}
[Test]
public void Logs_Contains_Correct_Message_Templates()
{
var templates = _logViewer.GetMessageTemplates(_logTimePeriod);
//Count no of templates
Assert.AreEqual(43, templates.Count());
//Verify all templates & counts are unique
CollectionAssert.AllItemsAreUnique(templates);
//Ensure the collection contains LogTemplate objects
CollectionAssert.AllItemsAreInstancesOfType(templates, typeof(LogTemplate));
//Get first item & verify its template & count are what we expect
var popularTemplate = templates.FirstOrDefault();
Assert.IsNotNull(popularTemplate);
Assert.AreEqual("{LogPrefix} Task added {TaskType}", popularTemplate.MessageTemplate);
Assert.AreEqual(689, popularTemplate.Count);
}
[Test]
public void Logs_Can_Open_As_Small_File()
{
//We are just testing a return value (as we know the example file is less than 200MB)
//But this test method does not test/check that
var canOpenLogs = _logViewer.CheckCanOpenLogs(_logTimePeriod);
Assert.IsTrue(canOpenLogs);
}
[Test]
public void Logs_Can_Be_Queried()
{
//Should get me the most 100 recent log entries & using default overloads for remaining params
var allLogs = _logViewer.GetLogs(_logTimePeriod, pageNumber: 1);
//Check we get 100 results back for a page & total items all good :)
Assert.AreEqual(100, allLogs.Items.Count());
Assert.AreEqual(2410, allLogs.TotalItems);
Assert.AreEqual(25, allLogs.TotalPages);
//Check collection all contain same object type
CollectionAssert.AllItemsAreInstancesOfType(allLogs.Items, typeof(LogMessage));
//Check first item is newest
var newestItem = allLogs.Items.First();
DateTimeOffset newDate;
DateTimeOffset.TryParse("2018-11-12T09:24:27.4057583Z", out newDate);
Assert.AreEqual(newDate, newestItem.Timestamp);
//Check we call method again with a smaller set of results & in ascending
var smallQuery = _logViewer.GetLogs(_logTimePeriod, pageNumber: 1, pageSize: 10, orderDirection: Direction.Ascending);
Assert.AreEqual(10, smallQuery.Items.Count());
Assert.AreEqual(241, smallQuery.TotalPages);
//Check first item is oldest
var oldestItem = smallQuery.Items.First();
DateTimeOffset oldDate;
DateTimeOffset.TryParse("2018-11-12T08:34:45.8371142Z", out oldDate);
Assert.AreEqual(oldDate, oldestItem.Timestamp);
//Check invalid log levels
//Rather than expect 0 items - get all items back & ignore the invalid levels
string[] invalidLogLevels = { "Invalid", "NotALevel" };
var queryWithInvalidLevels = _logViewer.GetLogs(_logTimePeriod, pageNumber: 1, logLevels: invalidLogLevels);
Assert.AreEqual(2410, queryWithInvalidLevels.TotalItems);
//Check we can call method with an array of logLevel (error & warning)
string [] logLevels = { "Warning", "Error" };
var queryWithLevels = _logViewer.GetLogs(_logTimePeriod, pageNumber: 1, logLevels: logLevels);
Assert.AreEqual(9, queryWithLevels.TotalItems);
//Query @Level='Warning' BUT we pass in array of LogLevels for Debug & Info (Expect to get 0 results)
string[] logLevelMismatch = { "Debug", "Information" };
var filterLevelQuery = _logViewer.GetLogs(_logTimePeriod, pageNumber: 1, filterExpression: "@Level='Warning'", logLevels: logLevelMismatch);
Assert.AreEqual(0, filterLevelQuery.TotalItems);
}
[TestCase("", 2410)]
[TestCase("Has(@Exception)", 2)]
[TestCase("Has(Duration) and Duration > 1000", 13)]
[TestCase("Not(@Level = 'Verbose') and Not(@Level= 'Debug')", 71)]
[TestCase("StartsWith(SourceContext, 'Umbraco.Core')", 1183)]
[TestCase("@MessageTemplate = '{EndMessage} ({Duration}ms) [Timing {TimingId}]'", 622)]
[TestCase("SortedComponentTypes[?] = 'Umbraco.Web.Search.ExamineComponent'", 1)]
[TestCase("Contains(SortedComponentTypes[?], 'DatabaseServer')", 1)]
[Test]
public void Logs_Can_Query_With_Expressions(string queryToVerify, int expectedCount)
{
var testQuery = _logViewer.GetLogs(_logTimePeriod, pageNumber: 1, filterExpression: queryToVerify);
Assert.AreEqual(expectedCount, testQuery.TotalItems);
}
[Test]
public void Log_Search_Can_Persist()
{
//Add a new search
_logViewer.AddSavedSearch("Unit Test Example", "Has(UnitTest)");
var searches = _logViewer.GetSavedSearches();
var savedSearch = new SavedLogSearch
{
Name = "Unit Test Example",
Query = "Has(UnitTest)"
};
//Check if we can find the newly added item from the results we get back
var findItem = searches.Where(x => x.Name == "Unit Test Example" && x.Query == "Has(UnitTest)");
Assert.IsNotNull(findItem, "We should have found the saved search, but get no results");
Assert.AreEqual(1, findItem.Count(), "Our list of searches should only contain one result");
// TODO: Need someone to help me find out why these don't work
//CollectionAssert.Contains(searches, savedSearch, "Can not find the new search that was saved");
//Assert.That(searches, Contains.Item(savedSearch));
//Remove the search from above & ensure it no longer exists
_logViewer.DeleteSavedSearch("Unit Test Example", "Has(UnitTest)");
searches = _logViewer.GetSavedSearches();
findItem = searches.Where(x => x.Name == "Unit Test Example" && x.Query == "Has(UnitTest)");
Assert.IsEmpty(findItem, "The search item should no longer exist");
}
}
}

File diff suppressed because one or more lines are too long

View File

@@ -1,42 +0,0 @@
[
{
"name": "Find all logs where the Level is NOT Verbose and NOT Debug",
"query": "Not(@Level='Verbose') and Not(@Level='Debug')"
},
{
"name": "Find all logs that has an exception property (Warning, Error & Critical with Exceptions)",
"query": "Has(@Exception)"
},
{
"name": "Find all logs that have the property 'Duration'",
"query": "Has(Duration)"
},
{
"name": "Find all logs that have the property 'Duration' and the duration is greater than 1000ms",
"query": "Has(Duration) and Duration > 1000"
},
{
"name": "Find all logs that are from the namespace 'Umbraco.Core'",
"query": "StartsWith(SourceContext, 'Umbraco.Core')"
},
{
"name": "Find all logs that use a specific log message template",
"query": "@MessageTemplate = '[Timing {TimingId}] {EndMessage} ({TimingDuration}ms)'"
},
{
"name": "Find logs where one of the items in the SortedComponentTypes property array is equal to",
"query": "SortedComponentTypes[?] = 'Umbraco.Web.Search.ExamineComponent'"
},
{
"name": "Find logs where one of the items in the SortedComponentTypes property array contains",
"query": "Contains(SortedComponentTypes[?], 'DatabaseServer')"
},
{
"name": "Find all logs that the message has localhost in it with SQL like",
"query": "@Message like '%localhost%'"
},
{
"name": "Find all logs that the message that starts with 'end' in it with SQL like",
"query": "@Message like 'end%'"
}
]

File diff suppressed because it is too large Load Diff

View File

@@ -1,214 +0,0 @@
using NUnit.Framework;
using Umbraco.Core.Models;
using Umbraco.Infrastructure.Media;
using Umbraco.Web.Models;
namespace Umbraco.Tests.Models
{
[TestFixture]
public class ImageProcessorImageUrlGeneratorTest
{
private const string MediaPath = "/media/1005/img_0671.jpg";
private static readonly ImageUrlGenerationOptions.CropCoordinates Crop = new ImageUrlGenerationOptions.CropCoordinates(0.58729977382575338m, 0.055768992440203169m, 0m, 0.32457553600198386m);
private static readonly ImageUrlGenerationOptions.FocalPointPosition Focus1 = new ImageUrlGenerationOptions.FocalPointPosition(0.80827067669172936m, 0.96m);
private static readonly ImageUrlGenerationOptions.FocalPointPosition Focus2 = new ImageUrlGenerationOptions.FocalPointPosition(0.41m, 0.4275m);
private static readonly ImageSharpImageUrlGenerator Generator = new ImageSharpImageUrlGenerator();
[Test]
public void GetCropUrl_CropAliasTest()
{
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { Crop = Crop, Width = 100, Height = 100 });
Assert.AreEqual(MediaPath + "?crop=0.58729977382575338,0.055768992440203169,0,0.32457553600198386&cropmode=percentage&width=100&height=100", urlString);
}
[Test]
public void GetCropUrl_WidthHeightTest()
{
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { FocalPoint = Focus1, Width = 200, Height = 300 });
Assert.AreEqual(MediaPath + "?center=0.80827067669172936,0.96&mode=crop&width=200&height=300", urlString);
}
[Test]
public void GetCropUrl_FocalPointTest()
{
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { FocalPoint = Focus1, Width = 100, Height = 100 });
Assert.AreEqual(MediaPath + "?center=0.80827067669172936,0.96&mode=crop&width=100&height=100", urlString);
}
[Test]
public void GetCropUrlFurtherOptionsTest()
{
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { FocalPoint = Focus1, Width = 200, Height = 300, FurtherOptions = "&filter=comic&roundedcorners=radius-26|bgcolor-fff" });
Assert.AreEqual(MediaPath + "?center=0.80827067669172936,0.96&mode=crop&width=200&height=300&filter=comic&roundedcorners=radius-26|bgcolor-fff", urlString);
}
/// <summary>
/// Test that if a crop alias has been specified that doesn't exist the method returns null
/// </summary>
[Test]
public void GetCropUrlNullTest()
{
var urlString = Generator.GetImageUrl(null);
Assert.AreEqual(null, urlString);
}
/// <summary>
/// Test that if a crop alias has been specified that doesn't exist the method returns null
/// </summary>
[Test]
public void GetCropUrlEmptyTest()
{
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(null));
Assert.AreEqual("?mode=crop", urlString);
}
/// <summary>
/// Test the GetCropUrl method on the ImageCropDataSet Model
/// </summary>
[Test]
public void GetBaseCropUrlFromModelTest()
{
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(null) { Crop = Crop, Width = 100, Height = 100 });
Assert.AreEqual("?crop=0.58729977382575338,0.055768992440203169,0,0.32457553600198386&cropmode=percentage&width=100&height=100", urlString);
}
/// <summary>
/// Test the height ratio mode with predefined crop dimensions
/// </summary>
[Test]
public void GetCropUrl_CropAliasHeightRatioModeTest()
{
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { Crop = Crop, Width = 100, HeightRatio = 1 });
Assert.AreEqual(MediaPath + "?crop=0.58729977382575338,0.055768992440203169,0,0.32457553600198386&cropmode=percentage&heightratio=1&width=100", urlString);
}
/// <summary>
/// Test the height ratio mode with manual width/height dimensions
/// </summary>
[Test]
public void GetCropUrl_WidthHeightRatioModeTest()
{
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { FocalPoint = Focus1, Width = 300, HeightRatio = 0.5m });
Assert.AreEqual(MediaPath + "?center=0.80827067669172936,0.96&mode=crop&heightratio=0.5&width=300", urlString);
}
/// <summary>
/// Test the height ratio mode with width/height dimensions
/// </summary>
[Test]
public void GetCropUrl_HeightWidthRatioModeTest()
{
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { FocalPoint = Focus1, Height = 150, WidthRatio = 2 });
Assert.AreEqual(MediaPath + "?center=0.80827067669172936,0.96&mode=crop&widthratio=2&height=150", urlString);
}
/// <summary>
/// Test that if Crop mode is specified as anything other than Crop the image doesn't use the crop
/// </summary>
[Test]
public void GetCropUrl_SpecifiedCropModeTest()
{
var urlStringMin = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { ImageCropMode = ImageCropMode.Min, Width = 300, Height = 150 });
var urlStringBoxPad = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { ImageCropMode = ImageCropMode.BoxPad, Width = 300, Height = 150 });
var urlStringPad = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { ImageCropMode = ImageCropMode.Pad, Width = 300, Height = 150 });
var urlStringMax = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { ImageCropMode = ImageCropMode.Max, Width = 300, Height = 150 });
var urlStringStretch = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { ImageCropMode = ImageCropMode.Stretch, Width = 300, Height = 150 });
Assert.AreEqual(MediaPath + "?mode=min&width=300&height=150", urlStringMin);
Assert.AreEqual(MediaPath + "?mode=boxpad&width=300&height=150", urlStringBoxPad);
Assert.AreEqual(MediaPath + "?mode=pad&width=300&height=150", urlStringPad);
Assert.AreEqual(MediaPath + "?mode=max&width=300&height=150", urlStringMax);
Assert.AreEqual(MediaPath + "?mode=stretch&width=300&height=150", urlStringStretch);
}
/// <summary>
/// Test for upload property type
/// </summary>
[Test]
public void GetCropUrl_UploadTypeTest()
{
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { ImageCropMode = ImageCropMode.Crop, ImageCropAnchor = ImageCropAnchor.Center, Width = 100, Height = 270 });
Assert.AreEqual(MediaPath + "?mode=crop&anchor=center&width=100&height=270", urlString);
}
/// <summary>
/// Test for preferFocalPoint when focal point is centered
/// </summary>
[Test]
public void GetCropUrl_PreferFocalPointCenter()
{
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { DefaultCrop = true, Width = 300, Height = 150 });
Assert.AreEqual(MediaPath + "?anchor=center&mode=crop&width=300&height=150", urlString);
}
/// <summary>
/// Test to check if height ratio is returned for a predefined crop without coordinates and focal point in centre when a width parameter is passed
/// </summary>
[Test]
public void GetCropUrl_PreDefinedCropNoCoordinatesWithWidth()
{
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { DefaultCrop = true, Width = 200, HeightRatio = 0.5962962962962962962962962963m });
Assert.AreEqual(MediaPath + "?anchor=center&mode=crop&heightratio=0.5962962962962962962962962963&width=200", urlString);
}
/// <summary>
/// Test to check if height ratio is returned for a predefined crop without coordinates and focal point is custom when a width parameter is passed
/// </summary>
[Test]
public void GetCropUrl_PreDefinedCropNoCoordinatesWithWidthAndFocalPoint()
{
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { FocalPoint = Focus2, Width = 200, HeightRatio = 0.5962962962962962962962962963m });
Assert.AreEqual(MediaPath + "?center=0.41,0.4275&mode=crop&heightratio=0.5962962962962962962962962963&width=200", urlString);
}
/// <summary>
/// Test to check if crop ratio is ignored if useCropDimensions is true
/// </summary>
[Test]
public void GetCropUrl_PreDefinedCropNoCoordinatesWithWidthAndFocalPointIgnore()
{
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { FocalPoint = Focus2, Width = 270, Height = 161 });
Assert.AreEqual(MediaPath + "?center=0.41,0.4275&mode=crop&width=270&height=161", urlString);
}
/// <summary>
/// Test to check if width ratio is returned for a predefined crop without coordinates and focal point in centre when a height parameter is passed
/// </summary>
[Test]
public void GetCropUrl_PreDefinedCropNoCoordinatesWithHeight()
{
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { DefaultCrop = true, Height = 200, WidthRatio = 1.6770186335403726708074534161m });
Assert.AreEqual(MediaPath + "?anchor=center&mode=crop&widthratio=1.6770186335403726708074534161&height=200", urlString);
}
/// <summary>
/// Test to check result when only a width parameter is passed, effectivly a resize only
/// </summary>
[Test]
public void GetCropUrl_WidthOnlyParameter()
{
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { DefaultCrop = true, Width = 200 });
Assert.AreEqual(MediaPath + "?anchor=center&mode=crop&width=200", urlString);
}
/// <summary>
/// Test to check result when only a height parameter is passed, effectivly a resize only
/// </summary>
[Test]
public void GetCropUrl_HeightOnlyParameter()
{
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { DefaultCrop = true, Height = 200 });
Assert.AreEqual(MediaPath + "?anchor=center&mode=crop&height=200", urlString);
}
/// <summary>
/// Test to check result when using a background color with padding
/// </summary>
[Test]
public void GetCropUrl_BackgroundColorParameter()
{
var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { ImageCropMode = ImageCropMode.Pad, Width = 400, Height = 400, FurtherOptions = "&bgcolor=fff" });
Assert.AreEqual(MediaPath + "?mode=pad&width=400&height=400&bgcolor=fff", urlString);
}
}
}

View File

@@ -1,597 +0,0 @@
using System;
using Microsoft.Extensions.Logging.Abstractions;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Models;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Services;
using Umbraco.Core.Strings;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Entities;
using Current = Umbraco.Web.Composing.Current;
namespace Umbraco.Tests.Models
{
[TestFixture]
public class VariationTests
{
private IFactory _factory;
private IShortStringHelper ShortStringHelper { get; } = TestHelper.ShortStringHelper;
[SetUp]
public void SetUp()
{
// well, this is also annoying, but...
// validating a value is performed by its data editor,
// based upon the configuration in the data type, so we
// need to be able to retrieve them all...
Current.Reset();
_factory = Mock.Of<IFactory>();
var dataTypeService = Mock.Of<IDataTypeService>();
var localizationService = Mock.Of<ILocalizationService>();
var dataEditors = new DataEditorCollection(new IDataEditor[]
{
new DataEditor(NullLoggerFactory.Instance, Mock.Of<IDataTypeService>(), Mock.Of<ILocalizationService>(), Mock.Of<ILocalizedTextService>(), Mock.Of<IShortStringHelper>()) { Alias = "editor", ExplicitValueEditor = MockedValueEditors.CreateDataValueEditor("view") }
});
var propertyEditors = new PropertyEditorCollection(dataEditors);
var dataType = Mock.Of<IDataType>();
Mock.Get(dataType)
.Setup(x => x.Configuration)
.Returns(null);
Mock.Get(dataTypeService)
.Setup(x => x.GetDataType(It.IsAny<int>()))
.Returns<int>(x => dataType);
var serviceContext = ServiceContext.CreatePartial(
dataTypeService: dataTypeService,
localizedTextService: Mock.Of<ILocalizedTextService>());
Mock.Get(_factory)
.Setup(x => x.GetInstance(It.IsAny<Type>()))
.Returns<Type>(x =>
{
//if (x == typeof(Configs)) return configs;
if (x == typeof(PropertyEditorCollection)) return propertyEditors;
if (x == typeof(ServiceContext)) return serviceContext;
if (x == typeof(ILocalizedTextService)) return serviceContext.LocalizationService;
throw new NotSupportedException(x.FullName);
});
}
[Test]
public void ValidateVariationTests()
{
// All tests:
// 1. if exact is set to true: culture cannot be null when the ContentVariation.Culture flag is set
// 2. if wildcards is set to false: fail when "*" is passed in as either culture or segment.
// 3. ContentVariation flag is ignored when wildcards are used.
// 4. Empty string is considered the same as null
#region Nothing
Assert4A(ContentVariation.Nothing, null, null, true);
Assert4A(ContentVariation.Nothing, null, "", true);
Assert4B(ContentVariation.Nothing, null, "*", true, false, false, true);
Assert4A(ContentVariation.Nothing, null, "segment", false);
Assert4A(ContentVariation.Nothing, "", null, true);
Assert4A(ContentVariation.Nothing, "", "", true);
Assert4B(ContentVariation.Nothing, "", "*", true, false, false, true);
Assert4A(ContentVariation.Nothing, "", "segment", false);
Assert4B(ContentVariation.Nothing, "*", null, true, false, false, true);
Assert4B(ContentVariation.Nothing, "*", "", true, false, false, true);
Assert4B(ContentVariation.Nothing, "*", "*", true, false, false, true);
Assert4A(ContentVariation.Nothing, "*", "segment", false);
Assert4A(ContentVariation.Nothing, "culture", null, false);
Assert4A(ContentVariation.Nothing, "culture", "", false);
Assert4A(ContentVariation.Nothing, "culture", "*", false);
Assert4A(ContentVariation.Nothing, "culture", "segment", false);
#endregion
#region Culture
Assert4B(ContentVariation.Culture, null, null, false, true, false, true);
Assert4B(ContentVariation.Culture, null, "", false, true, false, true);
Assert4B(ContentVariation.Culture, null, "*", false, false, false, true);
Assert4A(ContentVariation.Culture, null, "segment", false);
Assert4B(ContentVariation.Culture, "", null, false, true, false, true);
Assert4B(ContentVariation.Culture, "", "", false, true, false, true);
Assert4B(ContentVariation.Culture, "", "*", false, false, false, true);
Assert4A(ContentVariation.Culture, "", "segment", false);
Assert4B(ContentVariation.Culture, "*", null, true, false, false, true);
Assert4B(ContentVariation.Culture, "*", "", true, false, false, true);
Assert4B(ContentVariation.Culture, "*", "*", true, false, false, true);
Assert4A(ContentVariation.Culture, "*", "segment", false);
Assert4A(ContentVariation.Culture, "culture", null, true);
Assert4A(ContentVariation.Culture, "culture", "", true);
Assert4B(ContentVariation.Culture, "culture", "*", true, false, false, true);
Assert4A(ContentVariation.Culture, "culture", "segment", false);
#endregion
#region Segment
Assert4B(ContentVariation.Segment, null, null, true, true, true, true);
Assert4B(ContentVariation.Segment, null, "", true, true, true, true);
Assert4B(ContentVariation.Segment, null, "*", true, false, false, true);
Assert4A(ContentVariation.Segment, null, "segment", true);
Assert4B(ContentVariation.Segment, "", null, true, true, true, true);
Assert4B(ContentVariation.Segment, "", "", true, true, true, true);
Assert4B(ContentVariation.Segment, "", "*", true, false, false, true);
Assert4A(ContentVariation.Segment, "", "segment", true);
Assert4B(ContentVariation.Segment, "*", null, true, false, false, true);
Assert4B(ContentVariation.Segment, "*", "", true, false, false, true);
Assert4B(ContentVariation.Segment, "*", "*", true, false, false, true);
Assert4B(ContentVariation.Segment, "*", "segment", true, false, false, true);
Assert4A(ContentVariation.Segment, "culture", null, false);
Assert4A(ContentVariation.Segment, "culture", "", false);
Assert4A(ContentVariation.Segment, "culture", "*", false);
Assert4A(ContentVariation.Segment, "culture", "segment", false);
#endregion
#region CultureAndSegment
Assert4B(ContentVariation.CultureAndSegment, null, null, false, true, false, true);
Assert4B(ContentVariation.CultureAndSegment, null, "", false, true, false, true);
Assert4B(ContentVariation.CultureAndSegment, null, "*", false, false, false, true);
Assert4B(ContentVariation.CultureAndSegment, null, "segment", false, true, false, true);
Assert4B(ContentVariation.CultureAndSegment, "", null, false, true, false, true);
Assert4B(ContentVariation.CultureAndSegment, "", "", false, true, false, true);
Assert4B(ContentVariation.CultureAndSegment, "", "*", false, false, false, true);
Assert4B(ContentVariation.CultureAndSegment, "", "segment", false, true, false, true);
Assert4B(ContentVariation.CultureAndSegment, "*", null, true, false, false, true);
Assert4B(ContentVariation.CultureAndSegment, "*", "", true, false, false, true);
Assert4B(ContentVariation.CultureAndSegment, "*", "*", true, false, false, true);
Assert4B(ContentVariation.CultureAndSegment, "*", "segment", true, false, false, true);
Assert4B(ContentVariation.CultureAndSegment, "culture", null, true, true, true, true);
Assert4B(ContentVariation.CultureAndSegment, "culture", "", true, true, true, true);
Assert4B(ContentVariation.CultureAndSegment, "culture", "*", true, false, false, true);
Assert4B(ContentVariation.CultureAndSegment, "culture", "segment", true, true, true, true);
#endregion
}
/// <summary>
/// Asserts the result of <see cref="ContentVariationExtensions.ValidateVariation(ContentVariation, string, string, bool, bool, bool)"/>
/// </summary>
/// <param name="variation"></param>
/// <param name="culture"></param>
/// <param name="segment"></param>
/// <param name="exactAndWildcards">Validate using Exact + Wildcards flags</param>
/// <param name="nonExactAndNoWildcards">Validate using non Exact + no Wildcard flags</param>
/// <param name="exactAndNoWildcards">Validate using Exact + no Wildcard flags</param>
/// <param name="nonExactAndWildcards">Validate using non Exact + Wildcard flags</param>
private static void Assert4B(ContentVariation variation, string culture, string segment,
bool exactAndWildcards, bool nonExactAndNoWildcards, bool exactAndNoWildcards, bool nonExactAndWildcards)
{
Assert.AreEqual(exactAndWildcards, variation.ValidateVariation(culture, segment, true, true, false));
Assert.AreEqual(nonExactAndNoWildcards, variation.ValidateVariation(culture, segment, false, false, false));
Assert.AreEqual(exactAndNoWildcards, variation.ValidateVariation(culture, segment, true, false, false));
Assert.AreEqual(nonExactAndWildcards, variation.ValidateVariation(culture, segment, false, true, false));
}
/// <summary>
/// Asserts the result of <see cref="ContentVariationExtensions.ValidateVariation(ContentVariation, string, string, bool, bool, bool)"/>
/// where expectedResult matches all combinations of Exact + Wildcard
/// </summary>
/// <param name="variation"></param>
/// <param name="culture"></param>
/// <param name="segment"></param>
/// <param name="expectedResult"></param>
private static void Assert4A(ContentVariation variation, string culture, string segment, bool expectedResult)
{
Assert4B(variation, culture, segment, expectedResult, expectedResult, expectedResult, expectedResult);
}
[Test]
public void PropertyTests()
{
var propertyType = new PropertyType(TestHelper.ShortStringHelper, "editor", ValueStorageType.Nvarchar) { Alias = "prop" };
var prop = new Property(propertyType);
const string langFr = "fr-FR";
// can set value
// and get edited and published value
// because non-publishing
prop.SetValue("a");
Assert.AreEqual("a", prop.GetValue());
Assert.AreEqual("a", prop.GetValue(published: true));
// illegal, 'cos non-publishing
Assert.Throws<NotSupportedException>(() => prop.PublishValues());
// change
propertyType.SupportsPublishing = true;
// can get value
// and now published value is null
Assert.AreEqual("a", prop.GetValue());
Assert.IsNull(prop.GetValue(published: true));
// cannot set non-supported variation value
Assert.Throws<NotSupportedException>(() => prop.SetValue("x", langFr));
Assert.IsNull(prop.GetValue(langFr));
// can publish value
// and get edited and published values
prop.PublishValues();
Assert.AreEqual("a", prop.GetValue());
Assert.AreEqual("a", prop.GetValue(published: true));
// can set value
// and get edited and published values
prop.SetValue("b");
Assert.AreEqual("b", prop.GetValue());
Assert.AreEqual("a", prop.GetValue(published: true));
// can clear value
prop.UnpublishValues();
Assert.AreEqual("b", prop.GetValue());
Assert.IsNull(prop.GetValue(published: true));
// change - now we vary by culture
propertyType.Variations |= ContentVariation.Culture;
// can set value
// and get values
prop.SetValue("c", langFr);
Assert.IsNull(prop.GetValue()); // there is no invariant value anymore
Assert.IsNull(prop.GetValue(published: true));
Assert.AreEqual("c", prop.GetValue(langFr));
Assert.IsNull(prop.GetValue(langFr, published: true));
// can publish value
// and get edited and published values
prop.PublishValues(langFr);
Assert.IsNull(prop.GetValue());
Assert.IsNull(prop.GetValue(published: true));
Assert.AreEqual("c", prop.GetValue(langFr));
Assert.AreEqual("c", prop.GetValue(langFr, published: true));
// can clear all
prop.UnpublishValues("*");
Assert.IsNull(prop.GetValue());
Assert.IsNull(prop.GetValue(published: true));
Assert.AreEqual("c", prop.GetValue(langFr));
Assert.IsNull(prop.GetValue(langFr, published: true));
// can publish all
prop.PublishValues("*");
Assert.IsNull(prop.GetValue());
Assert.IsNull(prop.GetValue(published: true));
Assert.AreEqual("c", prop.GetValue(langFr));
Assert.AreEqual("c", prop.GetValue(langFr, published: true));
// same for culture
prop.UnpublishValues(langFr);
Assert.AreEqual("c", prop.GetValue(langFr));
Assert.IsNull(prop.GetValue(langFr, published: true));
prop.PublishValues(langFr);
Assert.AreEqual("c", prop.GetValue(langFr));
Assert.AreEqual("c", prop.GetValue(langFr, published: true));
prop.UnpublishValues(); // does not throw, internal, content item throws
Assert.IsNull(prop.GetValue());
Assert.IsNull(prop.GetValue(published: true));
prop.PublishValues(); // does not throw, internal, content item throws
Assert.IsNull(prop.GetValue());
Assert.IsNull(prop.GetValue(published: true));
}
[Test]
public void ContentNames()
{
var contentType = new ContentType(ShortStringHelper, -1) { Alias = "contentType" };
var content = new Content("content", -1, contentType) { Id = 1, VersionId = 1 };
const string langFr = "fr-FR";
const string langUk = "en-UK";
// throws if the content type does not support the variation
Assert.Throws<NotSupportedException>(() => content.SetCultureName("name-fr", langFr));
// now it will work
contentType.Variations = ContentVariation.Culture;
// recreate content to re-capture content type variations
content = new Content("content", -1, contentType) { Id = 1, VersionId = 1 };
// invariant name works
content.Name = "name";
Assert.AreEqual("name", content.GetCultureName(null));
content.SetCultureName("name2", null);
Assert.AreEqual("name2", content.Name);
Assert.AreEqual("name2", content.GetCultureName(null));
// variant names work
content.SetCultureName("name-fr", langFr);
content.SetCultureName("name-uk", langUk);
Assert.AreEqual("name-fr", content.GetCultureName(langFr));
Assert.AreEqual("name-uk", content.GetCultureName(langUk));
// variant dictionary of names work
Assert.AreEqual(2, content.CultureInfos.Count);
Assert.IsTrue(content.CultureInfos.ContainsKey(langFr));
Assert.AreEqual("name-fr", content.CultureInfos[langFr].Name);
Assert.IsTrue(content.CultureInfos.ContainsKey(langUk));
Assert.AreEqual("name-uk", content.CultureInfos[langUk].Name);
}
[Test]
public void ContentPublishValues()
{
const string langFr = "fr-FR";
var propertyType = new PropertyType(ShortStringHelper, "editor", ValueStorageType.Nvarchar) { Alias = "prop" };
var contentType = new ContentType(ShortStringHelper, -1) { Alias = "contentType" };
contentType.AddPropertyType(propertyType);
var content = new Content("content", -1, contentType) { Id = 1, VersionId = 1 };
// can set value
// and get edited value, published is null
// because publishing
content.SetValue("prop", "a");
Assert.AreEqual("a", content.GetValue("prop"));
Assert.IsNull(content.GetValue("prop", published: true));
// cannot set non-supported variation value
Assert.Throws<NotSupportedException>(() => content.SetValue("prop", "x", langFr));
Assert.IsNull(content.GetValue("prop", langFr));
// can publish value
// and get edited and published values
Assert.IsTrue(content.PublishCulture(CultureImpact.All));
Assert.AreEqual("a", content.GetValue("prop"));
Assert.AreEqual("a", content.GetValue("prop", published: true));
// can set value
// and get edited and published values
content.SetValue("prop", "b");
Assert.AreEqual("b", content.GetValue("prop"));
Assert.AreEqual("a", content.GetValue("prop", published: true));
// can clear value
content.UnpublishCulture();
Assert.AreEqual("b", content.GetValue("prop"));
Assert.IsNull(content.GetValue("prop", published: true));
// change - now we vary by culture
contentType.Variations |= ContentVariation.Culture;
propertyType.Variations |= ContentVariation.Culture;
content.ChangeContentType(contentType);
// can set value
// and get values
content.SetValue("prop", "c", langFr);
Assert.IsNull(content.GetValue("prop")); // there is no invariant value anymore
Assert.IsNull(content.GetValue("prop", published: true));
Assert.AreEqual("c", content.GetValue("prop", langFr));
Assert.IsNull(content.GetValue("prop", langFr, published: true));
// can publish value
// and get edited and published values
Assert.IsFalse(content.PublishCulture(CultureImpact.Explicit(langFr, false))); // no name
content.SetCultureName("name-fr", langFr);
Assert.IsTrue(content.PublishCulture(CultureImpact.Explicit(langFr, false)));
Assert.IsNull(content.GetValue("prop"));
Assert.IsNull(content.GetValue("prop", published: true));
Assert.AreEqual("c", content.GetValue("prop", langFr));
Assert.AreEqual("c", content.GetValue("prop", langFr, published: true));
// can clear all
content.UnpublishCulture("*");
Assert.IsNull(content.GetValue("prop"));
Assert.IsNull(content.GetValue("prop", published: true));
Assert.AreEqual("c", content.GetValue("prop", langFr));
Assert.IsNull(content.GetValue("prop", langFr, published: true));
// can publish all
Assert.IsTrue(content.PublishCulture(CultureImpact.All));
Assert.IsNull(content.GetValue("prop"));
Assert.IsNull(content.GetValue("prop", published: true));
Assert.AreEqual("c", content.GetValue("prop", langFr));
Assert.AreEqual("c", content.GetValue("prop", langFr, published: true));
// same for culture
content.UnpublishCulture(langFr);
Assert.AreEqual("c", content.GetValue("prop", langFr));
Assert.IsNull(content.GetValue("prop", langFr, published: true));
Assert.IsTrue(content.PublishCulture(CultureImpact.Explicit(langFr, false)));
Assert.AreEqual("c", content.GetValue("prop", langFr));
Assert.AreEqual("c", content.GetValue("prop", langFr, published: true));
content.UnpublishCulture(); // clears invariant props if any
Assert.IsNull(content.GetValue("prop"));
Assert.IsNull(content.GetValue("prop", published: true));
Assert.IsTrue(content.PublishCulture(CultureImpact.All)); // publishes invariant props if any
Assert.IsNull(content.GetValue("prop"));
Assert.IsNull(content.GetValue("prop", published: true));
var other = new Content("other", -1, contentType) { Id = 2, VersionId = 1 };
Assert.Throws<NotSupportedException>(() => other.SetValue("prop", "o")); // don't even try
other.SetValue("prop", "o1", langFr);
// can copy other's edited value
content.CopyFrom(other);
Assert.IsNull(content.GetValue("prop"));
Assert.IsNull(content.GetValue("prop", published: true));
Assert.AreEqual("o1", content.GetValue("prop", langFr));
Assert.AreEqual("c", content.GetValue("prop", langFr, published: true));
// can copy self's published value
content.CopyFrom(content);
Assert.IsNull(content.GetValue("prop"));
Assert.IsNull(content.GetValue("prop", published: true));
Assert.AreEqual("c", content.GetValue("prop", langFr));
Assert.AreEqual("c", content.GetValue("prop", langFr, published: true));
}
[Test]
public void ContentPublishValuesWithMixedPropertyTypeVariations()
{
var propertyValidationService = new PropertyValidationService(
_factory.GetInstance<PropertyEditorCollection>(),
_factory.GetInstance<ServiceContext>().DataTypeService,
_factory.GetInstance<ServiceContext>().TextService);
const string langFr = "fr-FR";
// content type varies by Culture
// prop1 varies by Culture
// prop2 is invariant
var contentType = new ContentType(ShortStringHelper, -1) { Alias = "contentType" };
contentType.Variations |= ContentVariation.Culture;
var variantPropType = new PropertyType(ShortStringHelper, "editor", ValueStorageType.Nvarchar) { Alias = "prop1", Variations = ContentVariation.Culture, Mandatory = true };
var invariantPropType = new PropertyType(ShortStringHelper, "editor", ValueStorageType.Nvarchar) { Alias = "prop2", Variations = ContentVariation.Nothing, Mandatory = true};
contentType.AddPropertyType(variantPropType);
contentType.AddPropertyType(invariantPropType);
var content = new Content("content", -1, contentType) { Id = 1, VersionId = 1 };
content.SetCultureName("hello", langFr);
//for this test we'll make the french culture the default one - this is needed for publishing invariant property values
var langFrImpact = CultureImpact.Explicit(langFr, true);
Assert.IsTrue(content.PublishCulture(langFrImpact)); // succeeds because names are ok (not validating properties here)
Assert.IsFalse(propertyValidationService.IsPropertyDataValid(content, out _, langFrImpact));// fails because prop1 is mandatory
content.SetValue("prop1", "a", langFr);
Assert.IsTrue(content.PublishCulture(langFrImpact)); // succeeds because names are ok (not validating properties here)
// fails because prop2 is mandatory and invariant and the item isn't published.
// Invariant is validated against the default language except when there isn't a published version, in that case it's always validated.
Assert.IsFalse(propertyValidationService.IsPropertyDataValid(content, out _, langFrImpact));
content.SetValue("prop2", "x");
Assert.IsTrue(content.PublishCulture(langFrImpact)); // still ok...
Assert.IsTrue(propertyValidationService.IsPropertyDataValid(content, out _, langFrImpact));// now it's ok
Assert.AreEqual("a", content.GetValue("prop1", langFr, published: true));
Assert.AreEqual("x", content.GetValue("prop2", published: true));
}
[Test]
public void ContentPublishVariations()
{
const string langFr = "fr-FR";
const string langUk = "en-UK";
const string langEs = "es-ES";
var propertyType = new PropertyType(ShortStringHelper, "editor", ValueStorageType.Nvarchar) { Alias = "prop" };
var contentType = new ContentType(ShortStringHelper, -1) { Alias = "contentType" };
contentType.AddPropertyType(propertyType);
var content = new Content("content", -1, contentType) { Id = 1, VersionId = 1 };
// change - now we vary by culture
contentType.Variations |= ContentVariation.Culture;
propertyType.Variations |= ContentVariation.Culture;
content.ChangeContentType(contentType);
Assert.Throws<NotSupportedException>(() => content.SetValue("prop", "a")); // invariant = no
content.SetValue("prop", "a-fr", langFr);
content.SetValue("prop", "a-uk", langUk);
content.SetValue("prop", "a-es", langEs);
// cannot publish without a name
Assert.IsFalse(content.PublishCulture(CultureImpact.Explicit(langFr, false)));
// works with a name
// and then FR is available, and published
content.SetCultureName("name-fr", langFr);
Assert.IsTrue(content.PublishCulture(CultureImpact.Explicit(langFr, false)));
// now UK is available too
content.SetCultureName("name-uk", langUk);
// test available, published
Assert.IsTrue(content.IsCultureAvailable(langFr));
Assert.IsTrue(content.IsCulturePublished(langFr));
Assert.AreEqual("name-fr", content.GetPublishName(langFr));
Assert.AreNotEqual(DateTime.MinValue, content.GetPublishDate(langFr));
Assert.IsFalse(content.IsCultureEdited(langFr)); // once published, edited is *wrong* until saved
Assert.IsTrue(content.IsCultureAvailable(langUk));
Assert.IsFalse(content.IsCulturePublished(langUk));
Assert.IsNull(content.GetPublishName(langUk));
Assert.IsNull(content.GetPublishDate(langUk)); // not published
Assert.IsFalse(content.IsCultureAvailable(langEs));
Assert.IsFalse(content.IsCultureEdited(langEs)); // not avail, so... not edited
Assert.IsFalse(content.IsCulturePublished(langEs));
// not published!
Assert.IsNull(content.GetPublishName(langEs));
Assert.IsNull(content.GetPublishDate(langEs));
// cannot test IsCultureEdited here - as that requires the content service and repository
// see: ContentServiceTests.Can_SaveRead_Variations
}
[Test]
public void IsDirtyTests()
{
var propertyType = new PropertyType(ShortStringHelper, "editor", ValueStorageType.Nvarchar) { Alias = "prop" };
var prop = new Property(propertyType);
var contentType = new ContentType(ShortStringHelper, -1) { Alias = "contentType" };
contentType.AddPropertyType(propertyType);
var content = new Content("content", -1, contentType) { Id = 1, VersionId = 1 };
prop.SetValue("a");
Assert.AreEqual("a", prop.GetValue());
Assert.IsNull(prop.GetValue(published: true));
Assert.IsTrue(prop.IsDirty());
content.SetValue("prop", "a");
Assert.AreEqual("a", content.GetValue("prop"));
Assert.IsNull(content.GetValue("prop", published: true));
Assert.IsTrue(content.IsDirty());
Assert.IsTrue(content.IsAnyUserPropertyDirty());
// how can we tell which variation was dirty?
}
[Test]
public void ValidationTests()
{
var propertyType = new PropertyType(ShortStringHelper, "editor", ValueStorageType.Nvarchar) { Alias = "prop", SupportsPublishing = true };
var prop = new Property(propertyType);
prop.SetValue("a");
Assert.AreEqual("a", prop.GetValue());
Assert.IsNull(prop.GetValue(published: true));
var propertyValidationService = new PropertyValidationService(
_factory.GetInstance<PropertyEditorCollection>(),
_factory.GetInstance<ServiceContext>().DataTypeService,
_factory.GetInstance<ServiceContext>().TextService
);
Assert.IsTrue(propertyValidationService.IsPropertyValid(prop));
propertyType.Mandatory = true;
Assert.IsTrue(propertyValidationService.IsPropertyValid(prop));
prop.SetValue(null);
Assert.IsFalse(propertyValidationService.IsPropertyValid(prop));
// can publish, even though invalid
prop.PublishValues();
}
}
}

View File

@@ -6,6 +6,7 @@ using Umbraco.Core.Models;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Entities;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using Umbraco.Core.Services;
using Umbraco.Tests.Testing;
@@ -15,13 +16,6 @@ namespace Umbraco.Tests.Publishing
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)]
public class PublishingStrategyTests : TestWithDatabaseBase
{
public override void SetUp()
{
base.SetUp();
//LegacyUmbracoSettings.SettingsFilePath = Current.IOHelper.MapPath(SystemDirectories.Config + Path.DirectorySeparatorChar, false);
}
private IContent _homePage;
[NUnit.Framework.Ignore("fixme - ignored test")]

View File

@@ -198,7 +198,7 @@ namespace Umbraco.Tests.Routing
public class CustomDocumentController : RenderMvcController
{
public CustomDocumentController(IOptions<GlobalSettings> globalSettings, IUmbracoContextAccessor umbracoContextAccessor, ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger, ILoggerFactory loggerFactory)
: base(globalSettings, umbracoContextAccessor, services, appCaches, profilingLogger, loggerFactory)
{
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,236 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Scoping;
using Umbraco.Core.Services;
using Umbraco.Core.Services.Implement;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Entities;
using Umbraco.Tests.Testing;
namespace Umbraco.Tests.Services
{
// these tests tend to fail from time to time esp. on VSTS
//
// read
// Lock Time-out: https://technet.microsoft.com/en-us/library/ms172402.aspx?f=255&MSPPError=-2147217396
// http://support.x-tensive.com/question/5242/strange-locking-exceptions-with-sqlserverce
// http://debuggingblog.com/wp/2009/05/07/high-cpu-usage-and-windows-forms-application-hang-with-sqlce-database-and-the-sqlcelocktimeoutexception/
//
// tried to increase it via connection string or via SET LOCK_TIMEOUT
// but still, the test fails on VSTS in most cases, so now ignoring it,
// as I could not figure out _why_ and it does not look like we are
// causing it, getting into __sysObjects locks, no idea why
[TestFixture]
[Apartment(ApartmentState.STA)]
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)]
public class ThreadSafetyServiceTest : TestWithDatabaseBase
{
public override void SetUp()
{
base.SetUp();
CreateTestData();
}
// not sure this is doing anything really
protected override string GetDbConnectionString()
{
// need a longer timeout for tests?
return base.GetDbConnectionString() + "default lock timeout=60000;";
}
private const int MaxThreadCount = 20;
private void Save(ContentService service, IContent content)
{
using (var scope = ScopeProvider.CreateScope())
{
scope.Database.Execute("SET LOCK_TIMEOUT 60000");
service.Save(content);
scope.Complete();
}
}
private void Save(MediaService service, IMedia media)
{
using (var scope = ScopeProvider.CreateScope())
{
scope.Database.Execute("SET LOCK_TIMEOUT 60000");
service.Save(media);
scope.Complete();
}
}
private ManualResetEventSlim TraceLocks()
{
var done = new ManualResetEventSlim(false);
// comment out to trace locks
return done;
//new Thread(() =>
//{
// using (var scope = ScopeProvider.CreateScope())
// while (done.IsSet == false)
// {
// var db = scope.Database;
// var info = db.Query<dynamic>("SELECT * FROM sys.lock_information;");
// Console.WriteLine("LOCKS:");
// foreach (var row in info)
// {
// Console.WriteLine("> " + row.request_spid + " " + row.resource_type + " " + row.resource_description + " " + row.request_mode + " " + row.resource_table + " " + row.resource_table_id + " " + row.request_status);
// }
// Thread.Sleep(50);
// }
//}).Start();
//return done;
}
[Test]
public void Ensure_All_Threads_Execute_Successfully_Content_Service()
{
if (Environment.GetEnvironmentVariable("UMBRACO_TMP") != null)
Assert.Ignore("Do not run on VSTS.");
// the ServiceContext in that each repository in a service (i.e. ContentService) is a singleton
var contentService = (ContentService)ServiceContext.ContentService;
var threads = new List<Thread>();
var exceptions = new List<Exception>();
Debug.WriteLine("Starting...");
var done = TraceLocks();
for (var i = 0; i < MaxThreadCount; i++)
{
var t = new Thread(() =>
{
try
{
Debug.WriteLine("[{0}] Running...", Thread.CurrentThread.ManagedThreadId);
var name1 = "test-" + Guid.NewGuid();
var content1 = contentService.Create(name1, -1, "umbTextpage");
Debug.WriteLine("[{0}] Saving content #1.", Thread.CurrentThread.ManagedThreadId);
Save(contentService, content1);
Thread.Sleep(100); //quick pause for maximum overlap!
var name2 = "test-" + Guid.NewGuid();
var content2 = contentService.Create(name2, -1, "umbTextpage");
Debug.WriteLine("[{0}] Saving content #2.", Thread.CurrentThread.ManagedThreadId);
Save(contentService, content2);
}
catch (Exception e)
{
lock (exceptions) { exceptions.Add(e); }
}
});
threads.Add(t);
}
// start all threads
Debug.WriteLine("Starting threads");
threads.ForEach(x => x.Start());
// wait for all to complete
Debug.WriteLine("Joining threads");
threads.ForEach(x => x.Join());
done.Set();
Debug.WriteLine("Checking exceptions");
if (exceptions.Count == 0)
{
//now look up all items, there should be 40!
var items = contentService.GetRootContent();
Assert.AreEqual(2 * MaxThreadCount, items.Count());
}
else
{
throw new Exception("Exceptions!", exceptions.First()); // rethrow the first one...
}
}
[Test]
public void Ensure_All_Threads_Execute_Successfully_Media_Service()
{
if (Environment.GetEnvironmentVariable("UMBRACO_TMP") != null)
Assert.Ignore("Do not run on VSTS.");
// mimick the ServiceContext in that each repository in a service (i.e. ContentService) is a singleton
var mediaService = (MediaService)ServiceContext.MediaService;
var threads = new List<Thread>();
var exceptions = new List<Exception>();
Debug.WriteLine("Starting...");
var done = TraceLocks();
for (var i = 0; i < MaxThreadCount; i++)
{
var t = new Thread(() =>
{
try
{
Debug.WriteLine("[{0}] Running...", Thread.CurrentThread.ManagedThreadId);
var name1 = "test-" + Guid.NewGuid();
var media1 = mediaService.CreateMedia(name1, -1, Constants.Conventions.MediaTypes.Folder);
Debug.WriteLine("[{0}] Saving media #1.", Thread.CurrentThread.ManagedThreadId);
Save(mediaService, media1);
Thread.Sleep(100); //quick pause for maximum overlap!
var name2 = "test-" + Guid.NewGuid();
var media2 = mediaService.CreateMedia(name2, -1, Constants.Conventions.MediaTypes.Folder);
Debug.WriteLine("[{0}] Saving media #2.", Thread.CurrentThread.ManagedThreadId);
Save(mediaService, media2);
}
catch (Exception e)
{
lock (exceptions) { exceptions.Add(e); }
}
});
threads.Add(t);
}
//start all threads
threads.ForEach(x => x.Start());
//wait for all to complete
threads.ForEach(x => x.Join());
done.Set();
if (exceptions.Count == 0)
{
// now look up all items, there should be 40!
var items = mediaService.GetRootMedia();
Assert.AreEqual(2 * MaxThreadCount, items.Count());
}
else
{
throw new Exception("Exceptions!", exceptions.First()); // rethrow the first one...
}
}
public void CreateTestData()
{
// Create and Save ContentType "umbTextpage" -> 1045
var contentType = MockedContentTypes.CreateSimpleContentType("umbTextpage", "Textpage");
contentType.Key = new Guid("1D3A8E6E-2EA9-4CC1-B229-1AEE19821522");
ServiceContext.ContentTypeService.Save(contentType);
}
}
}

View File

@@ -136,16 +136,14 @@
<Compile Include="IO\ShadowFileSystemTests.cs" />
<Compile Include="LegacyXmlPublishedCache\ContentXmlDto.cs" />
<Compile Include="LegacyXmlPublishedCache\PreviewXmlDto.cs" />
<Compile Include="Logging\LogviewerTests.cs" />
<Compile Include="Migrations\MigrationPlanTests.cs" />
<Compile Include="Migrations\MigrationTests.cs" />
<Compile Include="Models\ContentXmlTest.cs" />
<Compile Include="Models\ImageProcessorImageUrlGeneratorTest.cs" />
<Compile Include="Models\VariationTests.cs" />
<Compile Include="Persistence\Mappers\MapperTestBase.cs" />
<Compile Include="PublishedContent\SolidPublishedSnapshot.cs" />
<Compile Include="Published\ConvertersTests.cs" />
<Compile Include="Published\ModelTypeTests.cs" />
<Compile Include="Publishing\PublishingStrategyTests.cs" />
<Compile Include="Routing\BaseUrlProviderTest.cs" />
<Compile Include="Routing\UrlProviderWithHideTopLevelNodeFromPathTests.cs" />
<Compile Include="Scoping\ScopeEventDispatcherTests.cs" />
@@ -169,7 +167,6 @@
<Compile Include="Routing\RoutableDocumentFilterTests.cs" />
<Compile Include="Runtimes\StandaloneTests.cs" />
<Compile Include="Routing\GetContentUrlsTests.cs" />
<Compile Include="Services\ContentTypeServiceVariantsTests.cs" />
<Compile Include="TestHelpers\RandomIdRamDirectory.cs" />
<Compile Include="TestHelpers\Stubs\TestUserPasswordConfig.cs" />
<Compile Include="Testing\Objects\TestDataSource.cs" />
@@ -221,7 +218,6 @@
<Compile Include="Web\Controllers\BackOfficeControllerUnitTests.cs" />
<Compile Include="Web\HttpCookieExtensionsTests.cs" />
<Compile Include="Web\Mvc\HtmlStringUtilitiesTests.cs" />
<Compile Include="Web\Mvc\RenderIndexActionSelectorAttributeTests.cs" />
<Compile Include="Persistence\NPocoTests\PetaPocoCachesTest.cs" />
<Compile Include="Persistence\Repositories\DomainRepositoryTest.cs" />
<Compile Include="Persistence\Repositories\PartialViewRepositoryTests.cs" />
@@ -239,9 +235,7 @@
<Compile Include="Models\Collections\Item.cs" />
<Compile Include="Models\Collections\OrderItem.cs" />
<Compile Include="Models\Collections\SimpleOrder.cs" />
<Compile Include="Web\Mvc\RenderModelBinderTests.cs" />
<Compile Include="Web\Mvc\SurfaceControllerTests.cs" />
<Compile Include="Web\Mvc\UmbracoViewPageTests.cs" />
<Compile Include="Runtimes\CoreRuntimeTests.cs" />
<Compile Include="Runtimes\WebRuntimeComponentTests.cs" />
<Compile Include="Cache\ObjectAppCacheTests.cs" />
@@ -287,7 +281,6 @@
<Compile Include="PublishedContent\PublishedContentTests.cs" />
<Compile Include="PublishedContent\PublishedMediaTests.cs" />
<Compile Include="Web\Mvc\HtmlHelperExtensionMethodsTests.cs" />
<Compile Include="Models\ContentTests.cs" />
<Compile Include="Persistence\SqlCeTableByTableTest.cs" />
<Compile Include="Persistence\DatabaseContextTests.cs" />
<Compile Include="Persistence\Mappers\ContentMapperTest.cs" />
@@ -308,7 +301,6 @@
<Compile Include="Persistence\Repositories\ScriptRepositoryTest.cs" />
<Compile Include="Persistence\Repositories\StylesheetRepositoryTest.cs" />
<Compile Include="PublishedContent\PublishedContentMoreTests.cs" />
<Compile Include="Publishing\PublishingStrategyTests.cs" />
<Compile Include="Cache\PublishedCache\PublishedContentCacheTests.cs" />
<Compile Include="Routing\ContentFinderByAliasWithDomainsTests.cs" />
<Compile Include="Routing\DomainsAndCulturesTests.cs" />
@@ -320,7 +312,6 @@
<DesignTime>True</DesignTime>
<DependentUpon>ImportResources.resx</DependentUpon>
</Compile>
<Compile Include="Services\ThreadSafetyServiceTest.cs" />
<Compile Include="Web\Controllers\PluginControllerAreaTests.cs" />
<Compile Include="Cache\DistributedCache\DistributedCacheTests.cs" />
<Compile Include="TestHelpers\TestWithDatabaseBase.cs" />
@@ -428,12 +419,6 @@
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Content Include="Logging\logviewer.searches.config.js">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Logging\UmbracoTraceLog.UNITTEST.20181112.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Migrations\SqlScripts\MySqlTotal-480.sql" />
<Content Include="Migrations\SqlScripts\SqlCe-SchemaAndData-4110.sql" />
<Content Include="Migrations\SqlScripts\SqlCeTotal-480.sql" />
@@ -459,9 +444,6 @@
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<ItemGroup>
<Folder Include="Integration" />
</ItemGroup>
<!-- get NuGet packages directory -->
<PropertyGroup>
<NuGetPackages>$(NuGetPackageFolders.Split(';')[0])</NuGetPackages>
@@ -474,4 +456,4 @@
<Message Text="NuGetPackageFolders: $(NuGetPackageFolders)" Importance="high" />
<Message Text="NuGetPackages: $(NuGetPackages)" Importance="high" />
</Target>
</Project>
</Project>

View File

@@ -1,216 +0,0 @@
using System;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
using Umbraco.Core.Services;
using Umbraco.Tests.Common;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Stubs;
using Umbraco.Web;
using Umbraco.Web.Models;
using Umbraco.Web.Mvc;
using Umbraco.Web.PublishedCache;
using Umbraco.Web.Routing;
using Umbraco.Web.Security;
using Current = Umbraco.Web.Composing.Current;
namespace Umbraco.Tests.Web.Mvc
{
[TestFixture]
public class RenderIndexActionSelectorAttributeTests
{
[SetUp]
public void SetUp()
{
Current.UmbracoContextAccessor = new TestUmbracoContextAccessor();
Current.Factory = Mock.Of<IFactory>();
}
[TearDown]
public void TearDown()
{
Current.Reset();
}
private TestObjects TestObjects = new TestObjects(null);
private MethodInfo GetRenderMvcControllerIndexMethodFromCurrentType(Type currType)
{
return currType.GetMethods().Single(x =>
{
if (x.Name != "Index") return false;
if (x.ReturnParameter == null || x.ReturnParameter.ParameterType != typeof (ActionResult)) return false;
var p = x.GetParameters();
if (p.Length != 1) return false;
if (p[0].ParameterType != typeof (ContentModel)) return false;
return true;
});
}
[Test]
public void Matches_Default_Index()
{
var globalSettings = TestObjects.GetGlobalSettings();
var attr = new RenderIndexActionSelectorAttribute();
var req = new RequestContext();
var httpContextAccessor = TestHelper.GetHttpContextAccessor();
var umbracoContextFactory = new UmbracoContextFactory(
Current.UmbracoContextAccessor,
Mock.Of<IPublishedSnapshotService>(),
new TestVariationContextAccessor(),
new TestDefaultCultureAccessor(),
globalSettings,
Mock.Of<IUserService>(),
TestHelper.GetHostingEnvironment(),
TestHelper.UriUtility,
httpContextAccessor,
new AspNetCookieManager(httpContextAccessor));
var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext();
var umbCtx = umbracoContextReference.UmbracoContext;
var umbracoContextAccessor = new TestUmbracoContextAccessor(umbCtx);
var ctrl = new MatchesDefaultIndexController { UmbracoContextAccessor = umbracoContextAccessor };
var controllerCtx = new ControllerContext(req, ctrl);
var result = attr.IsValidForRequest(controllerCtx,
GetRenderMvcControllerIndexMethodFromCurrentType(ctrl.GetType()));
Assert.IsTrue(result);
}
[Test]
public void Matches_Overriden_Index()
{
var globalSettings = TestObjects.GetGlobalSettings();
var attr = new RenderIndexActionSelectorAttribute();
var req = new RequestContext();
var httpContextAccessor = TestHelper.GetHttpContextAccessor();
var umbracoContextFactory = new UmbracoContextFactory(
Current.UmbracoContextAccessor,
Mock.Of<IPublishedSnapshotService>(),
new TestVariationContextAccessor(),
new TestDefaultCultureAccessor(),
globalSettings,
Mock.Of<IUserService>(),
TestHelper.GetHostingEnvironment(),
TestHelper.UriUtility,
httpContextAccessor,
new AspNetCookieManager(httpContextAccessor));
var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext();
var umbCtx = umbracoContextReference.UmbracoContext;
var umbracoContextAccessor = new TestUmbracoContextAccessor(umbCtx);
var ctrl = new MatchesOverriddenIndexController { UmbracoContextAccessor = umbracoContextAccessor };
var controllerCtx = new ControllerContext(req, ctrl);
var result = attr.IsValidForRequest(controllerCtx,
GetRenderMvcControllerIndexMethodFromCurrentType(ctrl.GetType()));
Assert.IsTrue(result);
}
[Test]
public void Matches_Custom_Index()
{
var globalSettings = TestObjects.GetGlobalSettings();
var attr = new RenderIndexActionSelectorAttribute();
var req = new RequestContext();
var httpContextAccessor = TestHelper.GetHttpContextAccessor();
var umbracoContextFactory = new UmbracoContextFactory(
Current.UmbracoContextAccessor,
Mock.Of<IPublishedSnapshotService>(),
new TestVariationContextAccessor(),
new TestDefaultCultureAccessor(),
globalSettings,
Mock.Of<IUserService>(),
TestHelper.GetHostingEnvironment(),
TestHelper.UriUtility,
httpContextAccessor,
new AspNetCookieManager(httpContextAccessor));
var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext();
var umbCtx = umbracoContextReference.UmbracoContext;
var umbracoContextAccessor = new TestUmbracoContextAccessor(umbCtx);
var ctrl = new MatchesCustomIndexController { UmbracoContextAccessor = umbracoContextAccessor };
var controllerCtx = new ControllerContext(req, ctrl);
var result = attr.IsValidForRequest(controllerCtx,
GetRenderMvcControllerIndexMethodFromCurrentType(ctrl.GetType()));
Assert.IsFalse(result);
}
[Test]
public void Matches_Async_Index_Same_Signature()
{
var globalSettings = TestObjects.GetGlobalSettings();
var attr = new RenderIndexActionSelectorAttribute();
var req = new RequestContext();
var httpContextAccessor = TestHelper.GetHttpContextAccessor();
var umbracoContextFactory = new UmbracoContextFactory(
Current.UmbracoContextAccessor,
Mock.Of<IPublishedSnapshotService>(),
new TestVariationContextAccessor(),
new TestDefaultCultureAccessor(),
globalSettings,
Mock.Of<IUserService>(),
TestHelper.GetHostingEnvironment(),
TestHelper.UriUtility,
httpContextAccessor,
new AspNetCookieManager(httpContextAccessor));
var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext();
var umbCtx = umbracoContextReference.UmbracoContext;
var umbracoContextAccessor = new TestUmbracoContextAccessor(umbCtx);
var ctrl = new MatchesAsyncIndexController { UmbracoContextAccessor = umbracoContextAccessor };
var controllerCtx = new ControllerContext(req, ctrl);
var result = attr.IsValidForRequest(controllerCtx,
GetRenderMvcControllerIndexMethodFromCurrentType(ctrl.GetType()));
Assert.IsFalse(result);
}
public class MatchesDefaultIndexController : RenderMvcController
{
}
public class MatchesOverriddenIndexController : RenderMvcController
{
public override ActionResult Index(ContentModel model)
{
return base.Index(model);
}
}
public class MatchesCustomIndexController : RenderMvcController
{
public ActionResult Index(ContentModel model, int page)
{
return base.Index(model);
}
}
public class MatchesAsyncIndexController : RenderMvcController
{
public new async Task<ActionResult> Index(ContentModel model)
{
return await Task.FromResult(base.Index(model));
}
}
}
}

View File

@@ -1,181 +0,0 @@
using System.Collections.Generic;
using System.Globalization;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Moq;
using NUnit.Framework;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Tests.Common;
using Umbraco.Tests.TestHelpers.Stubs;
using Umbraco.Web.Models;
using Umbraco.Web.Mvc;
using Current = Umbraco.Web.Composing.Current;
namespace Umbraco.Tests.Web.Mvc
{
[TestFixture]
public class RenderModelBinderTests
{
[SetUp]
public void SetUp()
{
Current.UmbracoContextAccessor = new TestUmbracoContextAccessor();
}
[TearDown]
public void TearDown()
{
Current.Reset();
}
[Test]
public void Returns_Binder_For_IPublishedContent_And_IRenderModel()
{
var binder = ContentModelBinder.Instance;
var found = binder.GetBinder(typeof (IPublishedContent));
Assert.IsNotNull(found);
found = binder.GetBinder(typeof(ContentModel));
Assert.IsNotNull(found);
found = binder.GetBinder(typeof(MyContent));
Assert.IsNotNull(found);
found = binder.GetBinder(typeof(ContentModel<MyContent>));
Assert.IsNotNull(found);
found = binder.GetBinder(typeof(MyOtherContent));
Assert.IsNull(found);
found = binder.GetBinder(typeof(MyCustomContentModel));
Assert.IsNull(found);
found = binder.GetBinder(typeof(IContentModel));
Assert.IsNull(found);
}
[Test]
public void BindModel_Null_Source_Returns_Null()
{
Assert.IsNull(ContentModelBinder.BindModel(null, typeof(MyContent)));
}
[Test]
public void BindModel_Returns_If_Same_Type()
{
var content = new MyContent(Mock.Of<IPublishedContent>());
var bound = ContentModelBinder.BindModel(content, typeof (IPublishedContent));
Assert.AreSame(content, bound);
}
[Test]
public void BindModel_RenderModel_To_IPublishedContent()
{
var content = new MyContent(Mock.Of<IPublishedContent>());
var renderModel = new ContentModel(content);
var bound = ContentModelBinder.BindModel(renderModel, typeof(IPublishedContent));
Assert.AreSame(content, bound);
}
[Test]
public void BindModel_IPublishedContent_To_RenderModel()
{
var content = new MyContent(Mock.Of<IPublishedContent>());
var bound = (IContentModel)ContentModelBinder.BindModel(content, typeof(ContentModel));
Assert.AreSame(content, bound.Content);
}
[Test]
public void BindModel_IPublishedContent_To_Generic_RenderModel()
{
var content = new MyContent(Mock.Of<IPublishedContent>());
var bound = (IContentModel)ContentModelBinder.BindModel(content, typeof(ContentModel<MyContent>));
Assert.AreSame(content, bound.Content);
}
[Test]
public void No_DataToken_Returns_Null()
{
var binder = ContentModelBinder.Instance;
var routeData = new RouteData();
var result = binder.BindModel(new ControllerContext(Mock.Of<HttpContextBase>(), routeData, Mock.Of<ControllerBase>()),
new ModelBindingContext());
Assert.IsNull(result);
}
[Test]
public void Invalid_DataToken_Model_Type_Returns_Null()
{
var binder = ContentModelBinder.Instance;
var routeData = new RouteData();
routeData.DataTokens[Core.Constants.Web.UmbracoDataToken] = "hello";
//the value provider is the default implementation
var valueProvider = new Mock<IValueProvider>();
//also IUnvalidatedValueProvider
var invalidatedValueProvider = valueProvider.As<IUnvalidatedValueProvider>();
invalidatedValueProvider.Setup(x => x.GetValue(It.IsAny<string>(), It.IsAny<bool>())).Returns(() =>
new ValueProviderResult(null, "", CultureInfo.CurrentCulture));
var controllerCtx = new ControllerContext(
Mock.Of<HttpContextBase>(http => http.Items == new Dictionary<object, object>()),
routeData,
Mock.Of<ControllerBase>());
var result = binder.BindModel(controllerCtx,
new ModelBindingContext
{
ValueProvider = valueProvider.Object,
ModelMetadata = new ModelMetadata(new EmptyModelMetadataProvider(), null, () => null, typeof(IPublishedContent), "content")
});
Assert.IsNull(result);
}
[Test]
public void IPublishedContent_DataToken_Model_Type_Uses_DefaultImplementation()
{
var content = new MyContent(Mock.Of<IPublishedContent>());
var binder = ContentModelBinder.Instance;
var routeData = new RouteData();
routeData.DataTokens[Core.Constants.Web.UmbracoDataToken] = content;
//the value provider is the default implementation
var valueProvider = new Mock<IValueProvider>();
//also IUnvalidatedValueProvider
var invalidatedValueProvider = valueProvider.As<IUnvalidatedValueProvider>();
invalidatedValueProvider.Setup(x => x.GetValue(It.IsAny<string>(), It.IsAny<bool>())).Returns(() =>
new ValueProviderResult(content, "content", CultureInfo.CurrentCulture));
var controllerCtx = new ControllerContext(
Mock.Of<HttpContextBase>(http => http.Items == new Dictionary<object, object>()),
routeData,
Mock.Of<ControllerBase>());
var result = binder.BindModel(controllerCtx,
new ModelBindingContext
{
ValueProvider = valueProvider.Object,
ModelMetadata = new ModelMetadata(new EmptyModelMetadataProvider(), null, () => null, typeof(IPublishedContent), "content")
});
Assert.AreEqual(content, result);
}
public class MyCustomContentModel : ContentModel
{
public MyCustomContentModel(IPublishedContent content)
: base(content)
{ }
}
public class MyOtherContent
{
}
public class MyContent : PublishedContentWrapped
{
public MyContent(IPublishedContent content) : base(content)
{
}
}
}
}

View File

@@ -1,466 +0,0 @@
using System;
using System.Globalization;
using System.Web.Mvc;
using System.Web.Routing;
using Microsoft.Extensions.Logging.Abstractions;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.Services;
using Umbraco.Tests.Common;
using Umbraco.Tests.LegacyXmlPublishedCache;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.Testing;
using Umbraco.Web;
using Umbraco.Web.Composing;
using Umbraco.Web.Models;
using Umbraco.Web.Mvc;
using Umbraco.Web.Routing;
using Umbraco.Web.Security;
namespace Umbraco.Tests.Web.Mvc
{
[TestFixture]
[UmbracoTest(WithApplication = true)]
public class UmbracoViewPageTests : UmbracoTestBase
{
private XmlPublishedSnapshotService _service;
[TearDown]
public override void TearDown()
{
if (_service == null) return;
_service.Dispose();
_service = null;
}
#region RenderModel To ...
[Test]
public void RenderModel_To_RenderModel()
{
var content = new ContentType1(null);
var model = new ContentModel(content);
var view = new RenderModelTestPage();
var viewData = new ViewDataDictionary(model);
view.ViewContext = GetViewContext();
view.SetViewDataX(viewData);
Assert.AreSame(model, view.Model);
}
[Test]
public void RenderModel_ContentType1_To_ContentType1()
{
var content = new ContentType1(null);
var model = new ContentModel(content);
var view = new ContentType1TestPage();
var viewData = new ViewDataDictionary(model);
view.ViewContext = GetViewContext();
view.SetViewDataX(viewData);
Assert.IsInstanceOf<ContentType1>(view.Model);
}
[Test]
public void RenderModel_ContentType2_To_ContentType1()
{
var content = new ContentType2(null);
var model = new ContentModel(content);
var view = new ContentType1TestPage();
var viewData = new ViewDataDictionary(model);
view.ViewContext = GetViewContext();
view.SetViewDataX(viewData);
Assert.IsInstanceOf<ContentType1>(view.Model);
}
[Test]
public void RenderModel_ContentType1_To_ContentType2()
{
var content = new ContentType1(null);
var model = new ContentModel(content);
var view = new ContentType2TestPage();
var viewData = new ViewDataDictionary(model);
view.ViewContext = GetViewContext();
Assert.Throws<ModelBindingException>(() => view.SetViewDataX(viewData));
}
[Test]
public void RenderModel_ContentType1_To_RenderModelOf_ContentType1()
{
var content = new ContentType1(null);
var model = new ContentModel(content);
var view = new RenderModelOfContentType1TestPage();
var viewData = new ViewDataDictionary(model);
view.ViewContext = GetViewContext();
view.SetViewDataX(viewData);
Assert.IsInstanceOf<ContentModel<ContentType1>>(view.Model);
Assert.IsInstanceOf<ContentType1>(view.Model.Content);
}
[Test]
public void RenderModel_ContentType2_To_RenderModelOf_ContentType1()
{
var content = new ContentType2(null);
var model = new ContentModel(content);
var view = new RenderModelOfContentType1TestPage();
var viewData = new ViewDataDictionary(model);
view.ViewContext = GetViewContext();
view.SetViewDataX(viewData);
Assert.IsInstanceOf<ContentModel<ContentType1>>(view.Model);
Assert.IsInstanceOf<ContentType2>(view.Model.Content);
}
[Test]
public void RenderModel_ContentType1_To_RenderModelOf_ContentType2()
{
var content = new ContentType1(null);
var model = new ContentModel(content);
var view = new RenderModelOfContentType2TestPage();
var viewData = new ViewDataDictionary(model);
view.ViewContext = GetViewContext();
Assert.Throws<ModelBindingException>(() => view.SetViewDataX(viewData));
}
#endregion
#region RenderModelOf To ...
[Test]
public void RenderModelOf_ContentType1_To_RenderModel()
{
var content = new ContentType1(null);
var model = new ContentModel<ContentType1>(content);
var view = new RenderModelTestPage();
var viewData = new ViewDataDictionary(model);
view.ViewContext = GetViewContext();
view.SetViewDataX(viewData);
Assert.AreSame(model, view.Model);
}
[Test]
public void RenderModelOf_ContentType1_To_ContentType1()
{
var content = new ContentType1(null);
var model = new ContentModel<ContentType1>(content);
var view = new ContentType1TestPage();
var viewData = new ViewDataDictionary(model);
view.ViewContext = GetViewContext();
view.SetViewDataX(viewData);
Assert.IsInstanceOf<ContentType1>(view.Model);
}
[Test]
public void RenderModelOf_ContentType2_To_ContentType1()
{
var content = new ContentType2(null);
var model = new ContentModel<ContentType2>(content);
var view = new ContentType1TestPage();
var viewData = new ViewDataDictionary(model);
view.ViewContext = GetViewContext();
view.SetViewDataX(viewData);
Assert.IsInstanceOf<ContentType1>(view.Model);
}
[Test]
public void RenderModelOf_ContentType1_To_ContentType2()
{
var content = new ContentType1(null);
var model = new ContentModel<ContentType1>(content);
var view = new ContentType2TestPage();
var viewData = new ViewDataDictionary(model);
view.ViewContext = GetViewContext();
Assert.Throws<ModelBindingException>(() => view.SetViewDataX(viewData));
}
[Test]
public void RenderModelOf_ContentType1_To_RenderModelOf_ContentType1()
{
var content = new ContentType1(null);
var model = new ContentModel<ContentType1>(content);
var view = new RenderModelOfContentType1TestPage();
var viewData = new ViewDataDictionary(model);
view.ViewContext = GetViewContext();
view.SetViewDataX(viewData);
Assert.IsInstanceOf<ContentModel<ContentType1>>(view.Model);
Assert.IsInstanceOf<ContentType1>(view.Model.Content);
}
[Test]
public void RenderModelOf_ContentType2_To_RenderModelOf_ContentType1()
{
var content = new ContentType2(null);
var model = new ContentModel<ContentType2>(content);
var view = new RenderModelOfContentType1TestPage();
var viewData = new ViewDataDictionary(model);
view.ViewContext = GetViewContext();
view.SetViewDataX(viewData);
Assert.IsInstanceOf<ContentModel<ContentType1>>(view.Model);
Assert.IsInstanceOf<ContentType2>(view.Model.Content);
}
[Test]
public void RenderModelOf_ContentType1_To_RenderModelOf_ContentType2()
{
var content = new ContentType1(null);
var model = new ContentModel<ContentType1>(content);
var view = new RenderModelOfContentType2TestPage();
var viewData = new ViewDataDictionary(model);
view.ViewContext = GetViewContext();
Assert.Throws<ModelBindingException>(() => view.SetViewDataX(viewData));
}
#endregion
#region ContentType To ...
[Test]
public void ContentType1_To_RenderModel()
{
var content = new ContentType1(null);
var view = new RenderModelTestPage();
var viewData = new ViewDataDictionary(content);
view.ViewContext = GetViewContext();
view.SetViewDataX(viewData);
Assert.IsInstanceOf<ContentModel>(view.Model);
}
[Test]
public void ContentType1_To_RenderModelOf_ContentType1()
{
var content = new ContentType1(null);
var view = new RenderModelOfContentType1TestPage();
var viewData = new ViewDataDictionary(content);
view.ViewContext = GetViewContext();
view.SetViewDataX(viewData);
Assert.IsInstanceOf<ContentModel<ContentType1>>(view.Model);
Assert.IsInstanceOf<ContentType1>(view.Model.Content);
}
[Test]
public void ContentType2_To_RenderModelOf_ContentType1()
{
var content = new ContentType2(null);
var view = new RenderModelOfContentType1TestPage();
var viewData = new ViewDataDictionary(content);
view.ViewContext = GetViewContext();
view.SetViewDataX(viewData);
Assert.IsInstanceOf<ContentModel<ContentType1>>(view.Model);
Assert.IsInstanceOf<ContentType1>(view.Model.Content);
}
[Test]
public void ContentType1_To_RenderModelOf_ContentType2()
{
var content = new ContentType1(null);
var view = new RenderModelOfContentType2TestPage();
var viewData = new ViewDataDictionary(content);
view.ViewContext = GetViewContext();
Assert.Throws<ModelBindingException>(() =>view.SetViewDataX(viewData));
}
[Test]
public void ContentType1_To_ContentType1()
{
var content = new ContentType1(null);
var view = new ContentType1TestPage();
var viewData = new ViewDataDictionary(content);
view.ViewContext = GetViewContext();
view.SetViewDataX(viewData);
Assert.IsInstanceOf<ContentType1>(view.Model);
}
[Test]
public void ContentType1_To_ContentType2()
{
var content = new ContentType1(null);
var view = new ContentType2TestPage();
var viewData = new ViewDataDictionary(content);
view.ViewContext = GetViewContext();
Assert.Throws<ModelBindingException>(() => view.SetViewDataX(viewData));
}
[Test]
public void ContentType2_To_ContentType1()
{
var content = new ContentType2(null);
var view = new ContentType1TestPage();
var viewData = new ViewDataDictionary(content);
view.ViewContext = GetViewContext();
view.SetViewDataX(viewData);
Assert.IsInstanceOf<ContentType1>(view.Model);
}
#endregion
#region Test elements
public class TestPage<TModel> : UmbracoViewPage<TModel>
{
public override void Execute()
{
throw new NotImplementedException();
}
public void SetViewDataX(ViewDataDictionary viewData)
{
SetViewData(viewData);
}
}
public class RenderModelTestPage : TestPage<ContentModel>
{ }
public class RenderModelOfContentType1TestPage : TestPage<ContentModel<ContentType1>>
{ }
public class RenderModelOfContentType2TestPage : TestPage<ContentModel<ContentType2>>
{ }
public class ContentType1TestPage : TestPage<ContentType1>
{ }
public class ContentType2TestPage : TestPage<ContentType2>
{ }
public class ContentType1 : PublishedContentWrapped
{
public ContentType1(IPublishedContent content) : base(content) {}
}
public class ContentType2 : ContentType1
{
public ContentType2(IPublishedContent content) : base(content) { }
}
#endregion
#region Test helpers
ServiceContext GetServiceContext()
{
return TestObjects.GetServiceContextMock();
}
ViewContext GetViewContext()
{
var umbracoContext = GetUmbracoContext("/dang", 0);
var webRoutingSettings = new WebRoutingSettings();
var publishedRouter = BaseWebTest.CreatePublishedRouter(webRoutingSettings);
var frequest = publishedRouter.CreateRequest(umbracoContext, new Uri("http://localhost/dang"));
frequest.Culture = CultureInfo.InvariantCulture;
umbracoContext.PublishedRequest = frequest;
var context = new ViewContext();
context.RouteData = new RouteData();
context.RouteData.DataTokens.Add(Core.Constants.Web.UmbracoContextDataToken, umbracoContext);
return context;
}
protected IUmbracoContext GetUmbracoContext(string url, int templateId, RouteData routeData = null, bool setSingleton = false)
{
var svcCtx = GetServiceContext();
var databaseFactory = TestObjects.GetDatabaseFactoryMock();
//var appCtx = new ApplicationContext(
// new DatabaseContext(databaseFactory, logger, Mock.Of<IRuntimeState>(), Mock.Of<IMigrationEntryService>()),
// svcCtx,
// CacheHelper.CreateDisabledCacheHelper(),
// new ProfilingLogger(logger, Mock.Of<IProfiler>())) { /*IsReady = true*/ };
var cache = NoAppCache.Instance;
//var provider = new ScopeUnitOfWorkProvider(databaseFactory, new RepositoryFactory(Mock.Of<IServiceContainer>()));
var scopeProvider = TestObjects.GetScopeProvider(NullLoggerFactory.Instance);
var factory = Mock.Of<IPublishedContentTypeFactory>();
var umbracoContextAccessor = Mock.Of<IUmbracoContextAccessor>();
_service = new XmlPublishedSnapshotService(svcCtx, factory, scopeProvider, cache,
null, null,
umbracoContextAccessor, null, null, null,
new TestDefaultCultureAccessor(),
Current.LoggerFactory, TestObjects.GetGlobalSettings(),
TestHelper.GetHostingEnvironment(),
TestHelper.GetHostingEnvironmentLifetime(),
ShortStringHelper,
new SiteDomainHelper(),
Factory.GetInstance<IEntityXmlSerializer>(),
null, true, false
); // no events
var http = GetHttpContextFactory(url, routeData).HttpContext;
var httpContextAccessor = TestHelper.GetHttpContextAccessor(http);
var globalSettings = TestObjects.GetGlobalSettings();
var ctx = new UmbracoContext(
httpContextAccessor,
_service,
Mock.Of<IBackOfficeSecurity>(),
globalSettings,
HostingEnvironment,
new TestVariationContextAccessor(),
UriUtility,
new AspNetCookieManager(httpContextAccessor));
//if (setSingleton)
//{
// UmbracoContext.Current = ctx;
//}
return ctx;
}
protected FakeHttpContextFactory GetHttpContextFactory(string url, RouteData routeData = null)
{
var factory = routeData != null
? new FakeHttpContextFactory(url, routeData)
: new FakeHttpContextFactory(url);
return factory;
}
#endregion
}
}