Skip to content

Commit

Permalink
Run master vm through vm filters (#226).
Browse files Browse the repository at this point in the history
  • Loading branch information
dicky authored and dicky committed Nov 29, 2019
1 parent 6b59004 commit a53c707
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 19 deletions.
39 changes: 26 additions & 13 deletions DotNetifyLib.Core/VMController/VMController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ public virtual string OnRequestVM(string connectionId, string vmId, object vmArg
var vmData = vmInstance.Serialize();

// Send the view model data back to the browser client.
ResponseVMFilter.Invoke(vmId, vmInstance, vmData, filteredData => _vmResponse(connectionId, vmId, (string)filteredData));
ResponseVMFilter.Invoke(vmId, vmInstance, vmData, filteredData => _vmResponse(connectionId, vmId, (string) filteredData));

// Reset the changed property states.
vmInstance.AcceptChangedProperties();
Expand Down Expand Up @@ -356,11 +356,12 @@ protected virtual BaseVM CreateVM(string vmId, object vmArg = null, string vmNam

// If the view model Id is in the form of a delimited path, it has a master view model.
BaseVM masterVM = null;
string masterVMId = null;
var path = vmId.Split('.');
if (path.Length > 1)
{
// Get the master view model; create the instance if it doesn't exist.
var masterVMId = vmId.Remove(vmId.LastIndexOf('.'));
masterVMId = vmId.Remove(vmId.LastIndexOf('.'));
lock (_activeVMs)
{
if (!_activeVMs.ContainsKey(masterVMId))
Expand All @@ -384,19 +385,31 @@ protected virtual BaseVM CreateVM(string vmId, object vmArg = null, string vmNam
vmInstanceId = path[1];
}

// Get the view model instance from the master view model, and if not, create it ourselves here.
var vmInstance = masterVM?.GetSubVM(vmTypeName, vmInstanceId)
?? _vmFactory.GetInstance(vmTypeName, vmInstanceId, vmNamespace)
?? throw new Exception($"[dotNetify] ERROR: '{vmId}' is not a known view model! Its assembly must be registered through VMController.RegisterAssembly.");
BaseVM vmInstance = null;
void createVMAction(object data)
{
// Get the view model instance from the master view model, and if not, create it ourselves here.
vmInstance = masterVM?.GetSubVM(vmTypeName, vmInstanceId) ?? _vmFactory.GetInstance(vmTypeName, vmInstanceId, vmNamespace);
if (vmInstance != null)
{
// If there are view model arguments, set them into the instance.
if (data is JObject)
foreach (var prop in (data as JObject).Properties())
UpdateVM(vmInstance, prop.Name, prop.Value.ToString());

// If there are view model arguments, set them into the instance.
if (vmArg is JObject)
foreach (var prop in (vmArg as JObject).Properties())
UpdateVM(vmInstance, prop.Name, prop.Value.ToString());
// Pass the view model instance to the master view model.
masterVM?.OnSubVMCreated(vmInstance);
}
}

// Pass the view model instance to the master view model.
masterVM?.OnSubVMCreated(vmInstance);
// If there's a master view model, run it through the view model filter.
if (masterVM != null)
RequestVMFilter(masterVMId, masterVM, vmArg, createVMAction);
else
createVMAction(vmArg);

if (vmInstance == null)
throw new Exception($"[dotNetify] ERROR: '{vmId}' is not a known view model! Its assembly must be registered through VMController.RegisterAssembly.");
return vmInstance;
}

Expand Down Expand Up @@ -482,7 +495,7 @@ protected virtual void PushUpdates(VMInfo vmInfo, string vmData)

ResponseVMFilter.Invoke(vmInfo.Id, vmInfo.Instance, vmData, filteredData =>
{
_vmResponse(vmInfo.ConnectionId, vmInfo.Id, (string)filteredData);
_vmResponse(vmInfo.ConnectionId, vmInfo.Id, (string) filteredData);
});
}

Expand Down
69 changes: 69 additions & 0 deletions UnitTests/MasterDetailsVMTest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using DotNetify;
using DotNetify.Testing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
Expand All @@ -11,6 +13,7 @@ public class MasterDetailsVMTest
private MasterVM _masterVM = new MasterVM();
private string _detailsVMId = $"{nameof(MasterVM)}.{nameof(DetailsVM)}";

[CustomFilter]
private class MasterVM : BaseVM
{
private DetailsVM _detailsVM = new DetailsVM() { Value = int.MaxValue };
Expand All @@ -25,11 +28,39 @@ private class MasterVM : BaseVM
public override void OnSubVMDisposing(BaseVM subVM) => DisposedSubVM = subVM;
}

[CustomFilter]
private class DetailsVM : BaseVM
{
public int Value { get; set; }
}

[CustomFilter]
private class RootVM : BaseVM
{
}

private class CustomFilterAttribute : Attribute
{
}

private class CustomFilter : IVMFilter<CustomFilterAttribute>
{
public static event EventHandler<Tuple<CustomFilterAttribute, VMContext>> Invoked;

public static void Cleanup()
{
if (Invoked != null)
foreach (Delegate d in Invoked.GetInvocationList())
Invoked -= (EventHandler<Tuple<CustomFilterAttribute, VMContext>>) d;
}

public Task Invoke(CustomFilterAttribute attribute, VMContext context, NextFilterDelegate next)
{
Invoked?.Invoke(this, Tuple.Create(attribute, context));
return next.Invoke(context);
}
}

private HubEmulator _hubEmulator;

[TestInitialize]
Expand All @@ -41,6 +72,12 @@ public void Initialize()
.Build();
}

[TestCleanup]
public void Cleanup()
{
CustomFilter.Cleanup();
}

[TestMethod]
public void MasterDetailsVM_Request()
{
Expand All @@ -50,6 +87,38 @@ public void MasterDetailsVM_Request()
Assert.AreEqual(int.MaxValue, (int) response.Value);
}

[TestMethod]
public void MasterDetailsVM_RequestWithCustomFilter_FiltersInvoked()
{
var contexts = new List<VMContext>();
CustomFilter.Invoked += customFilter_Invoked;
void customFilter_Invoked(object sender, Tuple<CustomFilterAttribute, VMContext> e) => contexts?.Add(e.Item2);

var hubEmulator = new HubEmulatorBuilder()
.Register<RootVM>()
.Register<MasterVM>()
.Register<DetailsVM>()
.UseFilter<CustomFilter>()
.Build();

var client = hubEmulator.CreateClient();
client.Connect(_detailsVMId).As<dynamic>();
client.Destroy();

Assert.IsTrue(contexts.Count >= 2);
Assert.IsTrue(contexts[0].Instance is MasterVM);
Assert.IsTrue(contexts[1].Instance is DetailsVM);

contexts.Clear();

client.Connect("RootVM.MasterVM.DetailsVM").As<dynamic>();

Assert.IsTrue(contexts.Count >= 3);
Assert.IsTrue(contexts[0].Instance is RootVM);
Assert.IsTrue(contexts[1].Instance is MasterVM);
Assert.IsTrue(contexts[2].Instance is DetailsVM);
}

[TestMethod]
public void MasterDetailsVM_Update()
{
Expand Down
12 changes: 6 additions & 6 deletions UnitTests/VMSerializerTest.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using DotNetify;
using Microsoft.VisualStudio.TestTools.UnitTesting;

Expand All @@ -21,10 +21,10 @@ public void Serialize_SetsIgnoredPropertyNames()
Assert.IsNotNull(resolver);

var serializer = new VMSerializer();
var ignoredPropertyNames = new List<String> {"World"};
serializer.Serialize(new {Hello = "Hello", World = "World"}, ignoredPropertyNames);
var ignoredPropertyNames = new List<string> { "World" };
serializer.Serialize(new { Hello = "Hello", World = "World" }, ignoredPropertyNames);

Assert.AreSame(ignoredPropertyNames, resolver.IgnoredPropertyNames);
Assert.IsTrue(ignoredPropertyNames.All(name => resolver.IgnoredPropertyNames.Contains(name)));
}
}
}
}

0 comments on commit a53c707

Please sign in to comment.