* Bump version * Add IContextCache to deploy connectors (#13287) * Add IContextCache and implementations * Update connector interfaces to use IContextCache * Minor cleanup * Move DeployContextCache prefix to constant * Move default implementations to obsolete methods * Remove DeployContextCache and DictionaryCache Co-authored-by: Andy Butland <abutland73@gmail.com> * Add IContextCache to deploy connectors (#13287) * Add IContextCache and implementations * Update connector interfaces to use IContextCache * Minor cleanup * Move DeployContextCache prefix to constant * Move default implementations to obsolete methods * Remove DeployContextCache and DictionaryCache Co-authored-by: Andy Butland <abutland73@gmail.com> * Parse lockId as invariant (#13284) Co-authored-by: Zeegaan <nge@umbraco.dk> * Fix Sqlite database locking issue (#13246) * Add locking for creating scope * Lock the repository instead * Add scope in action instead of locking in service * Fix up post-merge Co-authored-by: Zeegaan <nge@umbraco.dk> * Bump version to next minor * Fix for UseExceptionHandler no longer working since v10.3 RC (#13218) * Fix for UseExceptionHandler no longer working since v10.3 RC * Update the management api path to match the new one Co-authored-by: Nikolaj <nikolajlauridsen@protonmail.ch> * New backoffice: Cleanup management API routes (#13296) * Rename ModelsBuilderDashboard folder to ModelsBuilder * Fix modelsbuilder paths and related naming * Rename analytics route to telemetry * Fix controller bases - routes and tags * Fix items route * Fix more controllerbase routes * Fix route * Fix OpenApi file * Merging DictionaryItem and Dictionary * Fix TrackedReferences naming * Update OpenApi file * Rename Analytics* related types to Telemetry* * New Backoffice: Return AnalyticsLevelViewModel from Telemetry/ (#13298) * Return TelemetryLevelViewModel instead of TelemetryLevel * Fix schema * Change telemetry/current to telemetry/level (cherry picked from commit f2b8494c669cbbf04b623753abbf1be211973aa9) * Add contants for tree and recycle-bin subpaths (cherry picked from commit 4449f56bc00832ea6d357a3854b454791c80e0e2) Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Updated Smidge, Npoco and MailKit (#13310) * Updated Smidge, Npoco and MailKit * Added missing command (after breaking interface in npoco) * OpenId Connect authentication for new management API (#13318) * First attempt at OpenIddict * Making headway and more TODOs * Redo current policies for multiple schemas + clean up auth controller * Fix bad merge * Clean up some more test code * Fix spacing * Include AddAuthentication() in OpenIddict addition * A little more clean-up * Move application creation to its own implementation + prepare for middleware to handle valid callback URL * Enable refresh token flow * Fix bad merge from v11/dev * Support auth for Swagger and Postman in non-production environments + use default login screen for back-office logins * Add workaround to client side login handling so the OAuth return URL is not corrupted before redirection * Add temporary configuration handling for new backoffice * Restructure the code somewhat, move singular responsibility from management API project * Add recurring task for cleaning up old tokens in the DB * Fix bad merge + make auth controller align with the new management API structure * Explicitly handle the new management API path as a backoffice path (NOTE: this is potentially behaviorally breaking!) * Redo handle the new management API requests as backoffice requests, this time in a non-breaking way * Add/update TODOs * Revert duplication of current auth policies for OpenIddict (as it breaks everything for V11 without the new management APIs) and introduce a dedicated PoC policy setup for OpenIddict. * Fix failing unit tests * Update src/Umbraco.Cms.ManagementApi/Security/BackOfficeApplicationManager.cs Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com> * Update src/Umbraco.Cms.ManagementApi/Security/BackOfficeApplicationManager.cs Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com> * Update src/Umbraco.Cms.ManagementApi/Security/BackOfficeApplicationManager.cs Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com> * Update src/Umbraco.Core/Routing/UmbracoRequestPaths.cs Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com> * V11: Using IFileProvider to access assets added from packages (#13141) * Creating a FileProviderFactory for getting the package.manifest and grid.editors.config.js files through a file provider * Collecting the package.manifest-s from different sources * Searching different sources for grid.editors.config.js * Using an IFileProvider to collect all tours * Refactoring IconService.cs * Typo * Optimizations when looping through the file system * Moving WebRootFileProviderFactory to Umbraco.Web.Common proj * Removes double registering * pluginLangFileSources includes the localPluginFileSources * Comments * Remove linq from foreach * Change workflow for grid.editors.config.js so we check first physical file, then RCL, then Embedded * Clean up * Check if config dir exists * Discover nested package.manifest files * Fix IFileInfo.PhysicalPath check * Revert 712810e1fd995720047832ee689f804185ea69d6 as that way files in content root are preferred over those in web root * Adding comments * Refactoring * Remove PhysicalPath check * Fix registration of WebRootFileProviderFactory * Use Swashbuckle instead of NSwag (#13350) * First attempt at OpenIddict * Making headway and more TODOs * Redo current policies for multiple schemas + clean up auth controller * Fix bad merge * Clean up some more test code * Fix spacing * Include AddAuthentication() in OpenIddict addition * A little more clean-up * Move application creation to its own implementation + prepare for middleware to handle valid callback URL * Enable refresh token flow * Fix bad merge from v11/dev * Support auth for Swagger and Postman in non-production environments + use default login screen for back-office logins * Add workaround to client side login handling so the OAuth return URL is not corrupted before redirection * Add temporary configuration handling for new backoffice * Restructure the code somewhat, move singular responsibility from management API project * Add recurring task for cleaning up old tokens in the DB * Fix bad merge + make auth controller align with the new management API structure * Explicitly handle the new management API path as a backoffice path (NOTE: this is potentially behaviorally breaking!) * Redo handle the new management API requests as backoffice requests, this time in a non-breaking way * Add/update TODOs * Replace NSwag with Swashbuckle and clean up unnecessary client secret workaround * Revert duplication of current auth policies for OpenIddict (as it breaks everything for V11 without the new management APIs) and introduce a dedicated PoC policy setup for OpenIddict. * Fix failing unit tests * A little niceness + export new OpenApi.json and fix path in contract unit test * Redo after merge with v11/dev + filter out unwanted mime types * Remove CreatedResult and NotFoundObjectResult where possible * Custom schema IDs - no more "ViewModel" postfix and make generic lists look less clunky too * A little more explanation for generic schema ID generation * Force Swashbuckle to use enum string names * Update OpenApi.json to match new enum string values * Add clarifying comment about weird looking construct * add workflow to schema (#13349) * add workflow to schema * add licenses to CMSDefinition - intentionally only adding to schema, not registered as options Co-authored-by: Nikolaj <nikolajlauridsen@protonmail.ch> Co-authored-by: Ronald Barendse <ronald@barend.se> Co-authored-by: Andy Butland <abutland73@gmail.com> Co-authored-by: Zeegaan <nge@umbraco.dk> Co-authored-by: Justin Neville <67802060+justin-nevitech@users.noreply.github.com> Co-authored-by: Elitsa Marinovska <21998037+elit0451@users.noreply.github.com> Co-authored-by: Bjarke Berg <mail@bergmania.dk> Co-authored-by: Kenn Jacobsen <kja@umbraco.dk> Co-authored-by: Nathan Woulfe <nathan@nathanw.com.au>
331 lines
14 KiB
C#
331 lines
14 KiB
C#
// Copyright (c) Umbraco.
|
|
// See LICENSE for more details.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using Newtonsoft.Json;
|
|
using NUnit.Framework;
|
|
using Umbraco.Cms.Core;
|
|
using Umbraco.Cms.Core.Deploy;
|
|
using Umbraco.Cms.Infrastructure.Serialization;
|
|
|
|
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.CoreThings;
|
|
|
|
[TestFixture]
|
|
public class UdiTests
|
|
{
|
|
[SetUp]
|
|
public void SetUp() => UdiParser.ResetUdiTypes();
|
|
|
|
[Test]
|
|
public void StringUdiCtorTest()
|
|
{
|
|
var udi = new StringUdi(Constants.UdiEntityType.AnyString, "test-id");
|
|
Assert.AreEqual(Constants.UdiEntityType.AnyString, udi.EntityType);
|
|
Assert.AreEqual("test-id", udi.Id);
|
|
Assert.AreEqual("umb://" + Constants.UdiEntityType.AnyString + "/test-id", udi.ToString());
|
|
}
|
|
|
|
[Test]
|
|
public void StringUdiParseTest()
|
|
{
|
|
var udi = UdiParser.Parse("umb://" + Constants.UdiEntityType.AnyString + "/test-id");
|
|
Assert.AreEqual(Constants.UdiEntityType.AnyString, udi.EntityType);
|
|
Assert.IsInstanceOf<StringUdi>(udi);
|
|
var stringEntityId = udi as StringUdi;
|
|
Assert.IsNotNull(stringEntityId);
|
|
Assert.AreEqual("test-id", stringEntityId.Id);
|
|
Assert.AreEqual("umb://" + Constants.UdiEntityType.AnyString + "/test-id", udi.ToString());
|
|
|
|
udi = UdiParser.Parse("umb://" + Constants.UdiEntityType.AnyString + "/DA845952BE474EE9BD6F6194272AC750");
|
|
Assert.IsInstanceOf<StringUdi>(udi);
|
|
}
|
|
|
|
[Test]
|
|
public void StringEncodingTest()
|
|
{
|
|
// absolute path is unescaped
|
|
var uri = new Uri("umb://" + Constants.UdiEntityType.AnyString + "/this%20is%20a%20test");
|
|
Assert.AreEqual("umb://" + Constants.UdiEntityType.AnyString + "/this is a test", uri.ToString());
|
|
Assert.AreEqual("umb://" + Constants.UdiEntityType.AnyString + "/this%20is%20a%20test", uri.AbsoluteUri);
|
|
Assert.AreEqual("/this%20is%20a%20test", uri.AbsolutePath);
|
|
|
|
Assert.AreEqual("/this is a test", Uri.UnescapeDataString(uri.AbsolutePath));
|
|
Assert.AreEqual("%2Fthis%20is%20a%20test", Uri.EscapeDataString("/this is a test"));
|
|
Assert.AreEqual("/this%20is%20a%20test", Uri.EscapeUriString("/this is a test"));
|
|
|
|
var udi = UdiParser.Parse("umb://" + Constants.UdiEntityType.AnyString + "/this%20is%20a%20test");
|
|
Assert.AreEqual(Constants.UdiEntityType.AnyString, udi.EntityType);
|
|
Assert.IsInstanceOf<StringUdi>(udi);
|
|
var stringEntityId = udi as StringUdi;
|
|
Assert.IsNotNull(stringEntityId);
|
|
Assert.AreEqual("this is a test", stringEntityId.Id);
|
|
Assert.AreEqual("umb://" + Constants.UdiEntityType.AnyString + "/this%20is%20a%20test", udi.ToString());
|
|
|
|
var udi2 = new StringUdi(Constants.UdiEntityType.AnyString, "this is a test");
|
|
Assert.AreEqual(udi, udi2);
|
|
|
|
var udi3 = new StringUdi(Constants.UdiEntityType.AnyString, "path to/this is a test.xyz");
|
|
Assert.AreEqual("umb://" + Constants.UdiEntityType.AnyString + "/path%20to/this%20is%20a%20test.xyz", udi3.ToString());
|
|
}
|
|
|
|
[Test]
|
|
public void StringEncodingTest2()
|
|
{
|
|
// reserved = : / ? # [ ] @ ! $ & ' ( ) * + , ; =
|
|
// unreserved = alpha digit - . _ ~
|
|
Assert.AreEqual("%3A%2F%3F%23%5B%5D%40%21%24%26%27%28%29%2B%2C%3B%3D.-_~%25", Uri.EscapeDataString(":/?#[]@!$&'()+,;=.-_~%"));
|
|
Assert.AreEqual(":/?#[]@!$&'()+,;=.-_~%25", Uri.EscapeUriString(":/?#[]@!$&'()+,;=.-_~%"));
|
|
|
|
// we cannot have reserved chars at random places
|
|
// we want to keep the / in string udis
|
|
var r = string.Join("/", "path/to/View[1].cshtml".Split('/').Select(Uri.EscapeDataString));
|
|
Assert.AreEqual("path/to/View%5B1%5D.cshtml", r);
|
|
Assert.IsTrue(Uri.IsWellFormedUriString("umb://partial-view-macro/" + r, UriKind.Absolute));
|
|
|
|
// with the proper fix in StringUdi this should work:
|
|
var udi1 = new StringUdi("partial-view-macro", "path/to/View[1].cshtml");
|
|
Assert.AreEqual("umb://partial-view-macro/path/to/View%5B1%5D.cshtml", udi1.ToString());
|
|
var udi2 = UdiParser.Parse("umb://partial-view-macro/path/to/View%5B1%5D.cshtml");
|
|
Assert.AreEqual("path/to/View[1].cshtml", ((StringUdi)udi2).Id);
|
|
}
|
|
|
|
[Test]
|
|
public void GuidUdiCtorTest()
|
|
{
|
|
var guid = Guid.NewGuid();
|
|
var udi = new GuidUdi(Constants.UdiEntityType.AnyGuid, guid);
|
|
Assert.AreEqual(Constants.UdiEntityType.AnyGuid, udi.EntityType);
|
|
Assert.AreEqual(guid, udi.Guid);
|
|
Assert.AreEqual("umb://" + Constants.UdiEntityType.AnyGuid + "/" + guid.ToString("N"), udi.ToString());
|
|
}
|
|
|
|
[Test]
|
|
public void GuidUdiParseTest()
|
|
{
|
|
var guid = Guid.NewGuid();
|
|
var s = "umb://" + Constants.UdiEntityType.AnyGuid + "/" + guid.ToString("N");
|
|
var udi = UdiParser.Parse(s);
|
|
Assert.AreEqual(Constants.UdiEntityType.AnyGuid, udi.EntityType);
|
|
Assert.IsInstanceOf<GuidUdi>(udi);
|
|
var gudi = udi as GuidUdi;
|
|
Assert.IsNotNull(gudi);
|
|
Assert.AreEqual(guid, gudi.Guid);
|
|
Assert.AreEqual(s, udi.ToString());
|
|
}
|
|
|
|
[Test]
|
|
public void EqualityTest()
|
|
{
|
|
var guid1 = Guid.NewGuid();
|
|
var guid2 = Guid.NewGuid();
|
|
|
|
Assert.IsTrue(new GuidUdi("type", guid1).Equals(new GuidUdi("type", guid1)));
|
|
Assert.IsTrue(new GuidUdi("type", guid1) == new GuidUdi("type", guid1));
|
|
|
|
Assert.IsTrue(new GuidUdi("type", guid1).Equals(new GuidUdi("type", guid1)));
|
|
Assert.IsTrue(new GuidUdi("type", guid1) == new GuidUdi("type", guid1));
|
|
|
|
Assert.IsFalse(new GuidUdi("type", guid1).Equals(new GuidUdi("typex", guid1)));
|
|
Assert.IsFalse(new GuidUdi("type", guid1) == new GuidUdi("typex", guid1));
|
|
Assert.IsFalse(new GuidUdi("type", guid1).Equals(new GuidUdi("type", guid2)));
|
|
Assert.IsFalse(new GuidUdi("type", guid1) == new GuidUdi("type", guid2));
|
|
|
|
Assert.IsTrue(new GuidUdi("type", guid1).ToString() == new StringUdi("type", guid1.ToString("N")).ToString());
|
|
Assert.IsFalse(new GuidUdi("type", guid1) == new StringUdi("type", guid1.ToString("N")));
|
|
}
|
|
|
|
[Test]
|
|
public void DistinctTest()
|
|
{
|
|
var guid1 = Guid.NewGuid();
|
|
GuidUdi[] entities =
|
|
{
|
|
new GuidUdi(Constants.UdiEntityType.AnyGuid, guid1),
|
|
new GuidUdi(Constants.UdiEntityType.AnyGuid, guid1),
|
|
new GuidUdi(Constants.UdiEntityType.AnyGuid, guid1),
|
|
};
|
|
Assert.AreEqual(1, entities.Distinct().Count());
|
|
}
|
|
|
|
[Test]
|
|
public void CreateTest()
|
|
{
|
|
var guid = Guid.NewGuid();
|
|
var udi = Udi.Create(Constants.UdiEntityType.AnyGuid, guid);
|
|
Assert.AreEqual(Constants.UdiEntityType.AnyGuid, udi.EntityType);
|
|
Assert.AreEqual(guid, ((GuidUdi)udi).Guid);
|
|
|
|
// *not* testing whether Udi.Create(type, invalidValue) throws
|
|
// because we don't throw anymore - see U4-10409
|
|
}
|
|
|
|
[Test]
|
|
public void RootUdiTest()
|
|
{
|
|
var stringUdi = new StringUdi(Constants.UdiEntityType.AnyString, string.Empty);
|
|
Assert.IsTrue(stringUdi.IsRoot);
|
|
Assert.AreEqual("umb://any-string/", stringUdi.ToString());
|
|
|
|
var guidUdi = new GuidUdi(Constants.UdiEntityType.AnyGuid, Guid.Empty);
|
|
Assert.IsTrue(guidUdi.IsRoot);
|
|
Assert.AreEqual("umb://any-guid/00000000000000000000000000000000", guidUdi.ToString());
|
|
|
|
var udi = UdiParser.Parse("umb://any-string/");
|
|
Assert.IsTrue(udi.IsRoot);
|
|
Assert.IsInstanceOf<StringUdi>(udi);
|
|
|
|
udi = UdiParser.Parse("umb://any-guid/00000000000000000000000000000000");
|
|
Assert.IsTrue(udi.IsRoot);
|
|
Assert.IsInstanceOf<GuidUdi>(udi);
|
|
|
|
udi = UdiParser.Parse("umb://any-guid/");
|
|
Assert.IsTrue(udi.IsRoot);
|
|
Assert.IsInstanceOf<GuidUdi>(udi);
|
|
}
|
|
|
|
[Test]
|
|
public void RangeTest()
|
|
{
|
|
// can parse open string udi
|
|
var stringUdiString = "umb://" + Constants.UdiEntityType.AnyString;
|
|
Assert.IsTrue(UdiParser.TryParse(stringUdiString, out var stringUdi));
|
|
Assert.AreEqual(string.Empty, ((StringUdi)stringUdi).Id);
|
|
|
|
// can parse open guid udi
|
|
var guidUdiString = "umb://" + Constants.UdiEntityType.AnyGuid;
|
|
Assert.IsTrue(UdiParser.TryParse(guidUdiString, out var guidUdi));
|
|
Assert.AreEqual(Guid.Empty, ((GuidUdi)guidUdi).Guid);
|
|
|
|
// can create a range
|
|
var range = new UdiRange(stringUdi, Constants.DeploySelector.ChildrenOfThis);
|
|
|
|
// cannot create invalid ranges
|
|
Assert.Throws<ArgumentException>(() => new UdiRange(guidUdi, "x"));
|
|
}
|
|
|
|
[Test]
|
|
public void SerializationTest()
|
|
{
|
|
var settings = new JsonSerializerSettings
|
|
{
|
|
Converters = new JsonConverter[] { new UdiJsonConverter(), new UdiRangeJsonConverter() },
|
|
};
|
|
|
|
var guid = Guid.NewGuid();
|
|
var udi = new GuidUdi(Constants.UdiEntityType.AnyGuid, guid);
|
|
var json = JsonConvert.SerializeObject(udi, settings);
|
|
Assert.AreEqual(string.Format("\"umb://any-guid/{0:N}\"", guid), json);
|
|
|
|
var dudi = JsonConvert.DeserializeObject<Udi>(json, settings);
|
|
Assert.AreEqual(Constants.UdiEntityType.AnyGuid, dudi.EntityType);
|
|
Assert.AreEqual(guid, ((GuidUdi)dudi).Guid);
|
|
|
|
var range = new UdiRange(udi, Constants.DeploySelector.ChildrenOfThis);
|
|
json = JsonConvert.SerializeObject(range, settings);
|
|
Assert.AreEqual(string.Format("\"umb://any-guid/{0:N}?children\"", guid), json);
|
|
|
|
var drange = JsonConvert.DeserializeObject<UdiRange>(json, settings);
|
|
Assert.AreEqual(udi, drange.Udi);
|
|
Assert.AreEqual(string.Format("umb://any-guid/{0:N}", guid), drange.Udi.UriValue.ToString());
|
|
Assert.AreEqual(Constants.DeploySelector.ChildrenOfThis, drange.Selector);
|
|
}
|
|
|
|
[Test]
|
|
public void ValidateUdiEntityType()
|
|
{
|
|
var types = UdiParser.GetKnownUdiTypes();
|
|
|
|
foreach (var fi in typeof(Constants.UdiEntityType).GetFields(BindingFlags.Public | BindingFlags.Static))
|
|
{
|
|
// IsLiteral determines if its value is written at
|
|
// compile time and not changeable
|
|
// IsInitOnly determine if the field can be set
|
|
// in the body of the constructor
|
|
// for C# a field which is readonly keyword would have both true
|
|
// but a const field would have only IsLiteral equal to true
|
|
if (fi.IsLiteral && fi.IsInitOnly == false)
|
|
{
|
|
var value = fi.GetValue(null).ToString();
|
|
|
|
if (types.ContainsKey(value) == false)
|
|
{
|
|
Assert.Fail("Error in class Constants.UdiEntityType, type \"{0}\" is not declared by GetTypes.", value);
|
|
}
|
|
|
|
types.Remove(value);
|
|
}
|
|
}
|
|
|
|
Assert.AreEqual(
|
|
0,
|
|
types.Count,
|
|
"Error in class Constants.UdiEntityType, GetTypes declares types that don't exist ({0}).",
|
|
string.Join(",", types.Keys.Select(x => "\"" + x + "\"")));
|
|
}
|
|
|
|
[Test]
|
|
public void KnownTypes()
|
|
{
|
|
// cannot parse an unknown type, udi is null
|
|
// this will scan
|
|
Assert.IsFalse(UdiParser.TryParse("umb://whatever/1234", out var udi));
|
|
Assert.IsNull(udi);
|
|
|
|
UdiParser.ResetUdiTypes();
|
|
|
|
// unless we want to know
|
|
Assert.IsFalse(UdiParser.TryParse("umb://whatever/1234", true, out udi));
|
|
Assert.AreEqual(Constants.UdiEntityType.Unknown, udi.EntityType);
|
|
Assert.AreEqual("Umbraco.Cms.Core.UnknownTypeUdi", udi.GetType().FullName);
|
|
|
|
UdiParser.ResetUdiTypes();
|
|
|
|
// not known
|
|
Assert.IsFalse(UdiParser.TryParse("umb://foo/A87F65C8D6B94E868F6949BA92C93045", true, out udi));
|
|
Assert.AreEqual(Constants.UdiEntityType.Unknown, udi.EntityType);
|
|
Assert.AreEqual("Umbraco.Cms.Core.UnknownTypeUdi", udi.GetType().FullName);
|
|
|
|
// scanned
|
|
UdiParserServiceConnectors
|
|
.RegisterServiceConnector<
|
|
FooConnector>(); // this is the equivalent of scanning but we'll just manually register this one
|
|
Assert.IsTrue(UdiParser.TryParse("umb://foo/A87F65C8D6B94E868F6949BA92C93045", out udi));
|
|
Assert.IsInstanceOf<GuidUdi>(udi);
|
|
|
|
// known
|
|
Assert.IsTrue(UdiParser.TryParse("umb://foo/A87F65C8D6B94E868F6949BA92C93045", true, out udi));
|
|
Assert.IsInstanceOf<GuidUdi>(udi);
|
|
|
|
// can get method for Deploy compatibility
|
|
var method = typeof(UdiParser).GetMethod("Parse", BindingFlags.Static | BindingFlags.Public, null, new[] { typeof(string), typeof(bool) }, null);
|
|
Assert.IsNotNull(method);
|
|
}
|
|
|
|
[UdiDefinition("foo", UdiType.GuidUdi)]
|
|
public class FooConnector : IServiceConnector
|
|
{
|
|
public IArtifact GetArtifact(Udi udi, IContextCache contextCache) => throw new NotImplementedException();
|
|
|
|
public IArtifact GetArtifact(object entity, IContextCache contextCache) => throw new NotImplementedException();
|
|
|
|
public ArtifactDeployState ProcessInit(IArtifact art, IDeployContext context) =>
|
|
throw new NotImplementedException();
|
|
|
|
public void Process(ArtifactDeployState dart, IDeployContext context, int pass) =>
|
|
throw new NotImplementedException();
|
|
|
|
public void Explode(UdiRange range, List<Udi> udis) => throw new NotImplementedException();
|
|
|
|
public NamedUdiRange GetRange(Udi udi, string selector) => throw new NotImplementedException();
|
|
|
|
public NamedUdiRange GetRange(string entityType, string sid, string selector) =>
|
|
throw new NotImplementedException();
|
|
|
|
public bool Compare(IArtifact art1, IArtifact art2, ICollection<Difference> differences = null) =>
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|