Skip to content

Commit

Permalink
Merge branch 'main' into feature/custom-primitive-types
Browse files Browse the repository at this point in the history
  • Loading branch information
exyi authored Aug 3, 2023
2 parents 5754127 + 29a3170 commit 21486c8
Show file tree
Hide file tree
Showing 51 changed files with 1,137 additions and 338 deletions.
9 changes: 9 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,15 @@ jobs:
# title: Analyzer Tests
# github-token: ${{ secrets.GITHUB_TOKEN }}
# target-framework: net7.0
- name: Adapters.WebForms.Tests (net472)
uses: ./.github/unittest
if: matrix.os == 'windows-2022'
with:
project: src/Adapters/Tests/WebForms
name: webforms-adapters-tests
title: WebForms Adapter Tests
github-token: ${{ secrets.GITHUB_TOKEN }}
target-framework: net472

js-tests:
runs-on: ubuntu-latest
Expand Down
5 changes: 5 additions & 0 deletions ci/scripts/Get-PublicProjects.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -108,5 +108,10 @@ return @(
Name = "DotVVM.Tracing.MiniProfiler.Owin";
Path = "src/Tracing/MiniProfiler.Owin";
Type = "standard"
},
[PSCustomObject]@{
Name = "DotVVM.Adapters.WebForms";
Path = "src/Adapters/WebForms";
Type = "standard"
}
)
28 changes: 28 additions & 0 deletions src/Adapters/Tests/WebForms/DotVVM.Adapters.WebForms.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net472</TargetFramework>
<IsPackable>false</IsPackable>

<!-- Required for CheckTestOutput to function correctly in a CI environment. -->
<DeterministicSourcePaths>false</DeterministicSourcePaths>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
<PackageReference Include="CheckTestOutput" Version="0.6.0" />
<PackageReference Include="GitHubActionsTestLogger" Version="2.0.0" PrivateAssets="all" />
</ItemGroup>

<ItemGroup>
<Reference Include="System.Web" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\Framework\Testing\DotVVM.Framework.Testing.csproj" />
<ProjectReference Include="..\..\WebForms\DotVVM.Adapters.WebForms.csproj" />
</ItemGroup>

</Project>
98 changes: 98 additions & 0 deletions src/Adapters/Tests/WebForms/HybridRouteLinkTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System.Web;
using CheckTestOutput;
using DotVVM.Framework.Configuration;
using DotVVM.Framework.Testing;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace DotVVM.Adapters.WebForms.Tests
{
[TestClass]
public class HybridRouteLinkTests
{
private static readonly ControlTestHelper cth = new ControlTestHelper(config: config => config.AddWebFormsAdapters());
OutputChecker check = new OutputChecker("testoutputs");

[ClassInitialize]
public static void Init(TestContext testContext)
{
WebFormsRouteTableInit.EnsureInitialized();
}

[TestMethod]
public async Task HybridRouteLink_NoBindings()
{
HttpContext.Current = new HttpContext(
new HttpRequest("", "http://tempuri.org", ""),
new HttpResponse(new StringWriter())
);

var r = await cth.RunPage(typeof(ControlTestViewModel), @"
<webforms:HybridRouteLink RouteName=NoParams Text='hello 1' />
<webforms:HybridRouteLink RouteName=SingleParam Param-Index=3 Text='hello 2' />
<webforms:HybridRouteLink RouteName=SingleParam Param-Index={resource: 15} Text='hello 3' />
<webforms:HybridRouteLink RouteName=MultipleOptionalParams Text='hello 4' />
<webforms:HybridRouteLink RouteName=MultipleOptionalParams Param-Tag=aaa Text='hello 5' />
<webforms:HybridRouteLink RouteName=MultipleOptionalParams Param-SubTag=bbb Text='hello 6' />
<webforms:HybridRouteLink RouteName=MultipleOptionalParams Param-Tag=aaa Param-SubTag=bbb Text='hello 6' />");

check.CheckString(r.FormattedHtml, fileExtension: "html");
}

[TestMethod]
public async Task HybridRouteLink_ValueBinding()
{
HttpContext.Current = new HttpContext(
new HttpRequest("", "http://tempuri.org", ""),
new HttpResponse(new StringWriter())
);

var r = await cth.RunPage(typeof(ControlTestViewModel), @"
<webforms:HybridRouteLink RouteName=SingleParam Param-Index={value: Value} Text='hello 3' />
<dot:Repeater DataSource={value: Items}>
<webforms:HybridRouteLink RouteName=SingleParam Param-Index={value: Id} Text={value: Name} />
</dot:Repeater>");

check.CheckString(r.FormattedHtml, fileExtension: "html");
}

[TestMethod]
public async Task HybridRouteLink_SuffixAndQueryString()
{
HttpContext.Current = new HttpContext(
new HttpRequest("", "http://tempuri.org", ""),
new HttpResponse(new StringWriter())
);

var r = await cth.RunPage(typeof(ControlTestViewModel), @"
<webforms:HybridRouteLink RouteName=SingleParam Param-Index={value: Value} UrlSuffix='?hello=1' Text='hello 1' />
<webforms:HybridRouteLink RouteName=SingleParam Param-Index={value: Value} UrlSuffix={value: '?hello=' + Value} Text='hello 2' />
<webforms:HybridRouteLink RouteName=SingleParam Param-Index={value: Value} UrlSuffix={value: '?hello=' + Value} Query-Test=1 Text='hello 3' />
<webforms:HybridRouteLink RouteName=SingleParam Param-Index={value: Value} UrlSuffix={value: '?hello=' + Value} Query-Test={value: Value * 2} Text='hello 4' />
<webforms:HybridRouteLink RouteName=SingleParam Param-Index={value: Value} Query-Test1={value: Value + Items.Count} Query-Id=abc Text='hello 5' />");

check.CheckString(r.FormattedHtml, fileExtension: "html");
}
}

class ControlTestViewModel
{
public int Value { get; set; } = 15;

public List<ControlTestChildViewModel> Items { get; set; } = new()
{
new ControlTestChildViewModel() { Id = 1, Name = "one" },
new ControlTestChildViewModel() { Id = 2, Name = "two" },
new ControlTestChildViewModel() { Id = 3, Name = "three" }
};
}

class ControlTestChildViewModel
{
public int Id { get; set; }
public string Name { get; set; }
}
}
31 changes: 31 additions & 0 deletions src/Adapters/Tests/WebForms/WebFormsRouteTableInit.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Routing;

namespace DotVVM.Adapters.WebForms.Tests
{
public static class WebFormsRouteTableInit
{

static WebFormsRouteTableInit()
{
RouteTable.Routes.Add("NoParams", new Route("", new EmptyHandler()));
RouteTable.Routes.Add("SingleParam", new Route("page/{Index}", new EmptyHandler()));
RouteTable.Routes.Add("MultipleOptionalParams", new Route("catalog/{Tag}/{SubTag}", new EmptyHandler()) { Defaults = new RouteValueDictionary(new { Tag = "xx", SubTag = "yy" })});
}

public static void EnsureInitialized()
{
}

}

public class EmptyHandler : IRouteHandler
{
public IHttpHandler GetHttpHandler(RequestContext requestContext) => throw new NotImplementedException();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<html>
<head></head>
<body>
<a href="/">hello 1</a>
<a href="/page/3">hello 2</a>
<a href="/page/15">hello 3</a>
<a href="/catalog">hello 4</a>
<a href="/catalog/aaa">hello 5</a>
<a href="/catalog/xx/bbb">hello 6</a>
<a href="/catalog/aaa/bbb">hello 6</a>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<html>
<head></head>
<body>
<a data-bind="attr: { 'href': &quot;/&quot;+dotvvm.buildRouteUrl(&quot;page/{Index}&quot;, {&quot;Index&quot;: Value})+&quot;?hello=1&quot;}" href="/page/15?hello=1">hello 1</a>
<a data-bind="attr: { 'href': &quot;/&quot;+dotvvm.buildRouteUrl(&quot;page/{Index}&quot;, {&quot;Index&quot;: Value})+&quot;?hello=&quot; + Value()}" href="/page/15?hello=15">hello 2</a>
<a data-bind="attr: { 'href': &quot;/&quot;+dotvvm.buildRouteUrl(&quot;page/{Index}&quot;, {&quot;Index&quot;: Value})+dotvvm.buildUrlSuffix(&quot;?hello=&quot; + Value(), {&quot;Test&quot;: &quot;1&quot;})}" href="/page/15?hello=15&amp;Test=1">hello 3</a>
<a data-bind="attr: { 'href': &quot;/&quot;+dotvvm.buildRouteUrl(&quot;page/{Index}&quot;, {&quot;Index&quot;: Value})+dotvvm.buildUrlSuffix(&quot;?hello=&quot; + Value(), {&quot;Test&quot;: Value() * 2})}" href="/page/15?hello=15&amp;Test=30">hello 4</a>
<a data-bind="attr: { 'href': &quot;/&quot;+dotvvm.buildRouteUrl(&quot;page/{Index}&quot;, {&quot;Index&quot;: Value})+dotvvm.buildUrlSuffix(&quot;&quot;, {&quot;Id&quot;: &quot;abc&quot;,&quot;Test1&quot;: Value() + Items()?.length})}" href="/page/15?Id=abc&amp;Test1=18">hello 5</a>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<html>
<head></head>
<body>
<a data-bind="attr: { 'href': &quot;/&quot;+dotvvm.buildRouteUrl(&quot;page/{Index}&quot;, {&quot;Index&quot;: Value})}" href="/page/15">hello 3</a>
<div data-bind="template: { foreach: Items, name: &quot;uEOag7AJw3xoMobIL1lXF5WbK01ZnznA1P04nkjfgBs=&quot; }"></div>

<!-- Resource uEOag7AJw3xoMobIL1lXF5WbK01ZnznA1P04nkjfgBs= of type TemplateResource. -->
<template id="uEOag7AJw3xoMobIL1lXF5WbK01ZnznA1P04nkjfgBs="><a data-bind="attr: { 'href': &quot;/&quot;+dotvvm.buildRouteUrl(&quot;page/{Index}&quot;, {&quot;Index&quot;: Id})}, text: Name"></a></template>
</body>
</html>
57 changes: 57 additions & 0 deletions src/Adapters/WebForms/Controls/HybridRouteLink.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using System;
using DotVVM.Framework.Controls;
using DotVVM.Framework.Hosting;

#if NETFRAMEWORK
using System.Web.Routing;
#endif

namespace DotVVM.Adapters.WebForms.Controls
{
/// <summary>
/// Renders a hyperlink pointing to the specified DotVVM route if such route exists; otherwise it falls back to a Web Forms route with the specified name.
/// </summary>
#if !NETFRAMEWORK
[Obsolete("This control is used only during the Web Forms migration and is not needed in .NET Core. Use the standard RouteLink control.")]
#endif
public class HybridRouteLink : CompositeControl
{
private readonly IDotvvmRequestContext context;

public HybridRouteLink(IDotvvmRequestContext context)
{
this.context = context;
}

public DotvvmControl GetContents(
HtmlCapability htmlCapability,
TextOrContentCapability textOrContent,
RouteLinkCapability routeLinkCapability
)
{
if (context.Configuration.RouteTable.Contains(routeLinkCapability.RouteName))
{
return GenerateDotvvmRouteLink(htmlCapability, textOrContent, routeLinkCapability);
}
#if NETFRAMEWORK
else if (RouteTable.Routes[routeLinkCapability.RouteName] is Route webFormsRoute)
{
return WebFormsLinkUtils.BuildWebFormsRouteLink(this, context, htmlCapability, textOrContent, routeLinkCapability, webFormsRoute);
}
#endif
else
{
throw new DotvvmControlException($"Route '{routeLinkCapability.RouteName}' does not exist.");
}
}

private static DotvvmControl GenerateDotvvmRouteLink(HtmlCapability htmlCapability, TextOrContentCapability textOrContent, RouteLinkCapability routeLinkCapability)
{
return new RouteLink()
.SetCapability(htmlCapability)
.SetCapability(textOrContent)
.SetCapability(routeLinkCapability);
}

}
}
Loading

0 comments on commit 21486c8

Please sign in to comment.