Skip to content

Commit

Permalink
Merge pull request #564 from POFerro/global_quote
Browse files Browse the repository at this point in the history
Global quote type = Initial should not override attribute quote type on value set
  • Loading branch information
JonathanMagnan authored Aug 19, 2024
2 parents bef7cc4 + bfbb42c commit fb2335d
Show file tree
Hide file tree
Showing 5 changed files with 273 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/HtmlAgilityPack.Shared/HtmlAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,9 @@ public string Value
_value = value;
if (!string.IsNullOrEmpty(_value) && this.QuoteType == AttributeValueQuote.WithoutValue)
{
this.InternalQuoteType = this.OwnerDocument.GlobalAttributeValueQuote ?? AttributeValueQuote.DoubleQuote;
this.InternalQuoteType = this.OwnerDocument.GlobalAttributeValueQuote != AttributeValueQuote.Initial ?
(this.OwnerDocument.GlobalAttributeValueQuote ?? AttributeValueQuote.DoubleQuote)
: AttributeValueQuote.DoubleQuote;
}

if (_ownernode != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<None Remove="files\*" />
<Content Include="files\*">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="xunit" Version="2.4.0" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
using System;
using System.IO;
using System.Linq;
using System.Xml.XPath;
using Xunit;

namespace HtmlAgilityPack.Tests.NetStandard2_0
{
public class HtmlDocumentPreserveOriginalTest
{
[Fact]
public void PreserveEmptyAttributesTest()
{
var d = new HtmlDocument();
d.OptionEmptyCollection = true;

d.GlobalAttributeValueQuote = AttributeValueQuote.Initial;

d.OptionDefaultUseOriginalName = true;
//d.OptionPreserveEmptyAttributes = true;

var html = @"
<form #editForm='ngForm' (ngSubmit)='OnSaveData()' name='globalForm' [dataSourceContext]='detailDataSourceContext'>
<page editable (beginEdit)='OnBeginEdit()' (cancelEdit)='OnCancelEdit($event)'>
<page-header pageHeaderIcon='_Lea_ mdi mdi-code-json'>
<page-header-actions>
<list-counter formErrorsCounter></list-counter>
<button mat-button *hasEveryPermission='permissionConstants.LeaProdutos.edit' enterEditButton>
</button>
<button mat-button *hasEveryPermission='permissionConstants.LeaProdutos.edit' cancelEditButton>
</button>
<button mat-button *hasEveryPermission='permissionConstants.LeaProdutos.edit' type='submit' confirmEditButton>
</button>
<refresh-button></refresh-button>
</page-header-actions>
</page-header>
<page-body>
</page-body>
</page>
</form>
";
d.LoadHtml(html);

var outer = d.DocumentNode.OuterHtml;

var xpath = XPathExpression.Compile("/form/page/page-header/page-header-actions/button[@enterEditButton]");
var nodes = d.DocumentNode.SelectNodes(xpath);

Assert.Equal(1, nodes?.Count);
Assert.Equal(html, d.DocumentNode.OuterHtml);
}

[Fact]
public void PreserveOriginalCasingTest()
{
var d = new HtmlDocument();
d.OptionEmptyCollection = true;

d.GlobalAttributeValueQuote = AttributeValueQuote.Initial;

d.OptionDefaultUseOriginalName = true;
//d.OptionPreserveEmptyAttributes = true;

var html = @"
<form #editForm='ngForm' (ngSubmit)='OnSaveData()' name='globalForm' [dataSourceContext]='detailDataSourceContext'>
<page editable (beginEdit)='OnBeginEdit()' (cancelEdit)='OnCancelEdit($event)'>
<page-Header pageHeaderIcon='_Lea_ mdi mdi-code-json'>
<page-Header-Actions>
<list-counter formErrorsCounter></list-counter>
<button mat-button *hasEveryPermission='permissionConstants.LeaProdutos.edit' enterEditButton>
</button>
<button mat-button *hasEveryPermission='permissionConstants.LeaProdutos.edit' cancelEditButton>
</button>
<button mat-button *hasEveryPermission='permissionConstants.LeaProdutos.edit' type='submit' confirmEditButton>
</button>
<refresh-button></refresh-button>
</page-Header-Actions>
</page-Header>
<page-body>
</page-body>
</page>
</form>
";
d.LoadHtml(html);

var xpath = XPathExpression.Compile("/form/page/page-Header/page-Header-Actions/button[@enterEditButton]");
var nodes = d.DocumentNode.SelectNodes(xpath);

Assert.Equal(1, nodes?.Count);
Assert.Equal(html, d.DocumentNode.OuterHtml);
}


[Fact]
public void PreserveOriginalQuoteTest()
{
var contentDirectory = Path.GetDirectoryName(typeof(HtmlDocumentPreserveOriginalTest).Assembly.Location).ToString() + "\\files\\";

var d = new HtmlDocument();
d.OptionEmptyCollection = true;

d.GlobalAttributeValueQuote = AttributeValueQuote.Initial;
d.OptionDefaultUseOriginalName = true;

var filePath = Path.Combine(contentDirectory, "attr_quote.html");
var filePathExpected = Path.Combine(contentDirectory, "attr_quote_expected.html");
d.Load(filePath);

var xpath = XPathExpression.Compile("/form/page/page-body/card/data-group/mat-form-field[@*[local-name() = 'xdt:Transform' and . = \"InsertAfter(mat-form-field[mat-select/@name = 'tipoProdutoId'])\"]]/mat-select/mat-option");
var nodes = d.DocumentNode.SelectNodes(xpath);

Assert.Equal(1, nodes?.Count);

nodes[0].ParentNode.Attributes["required"].Value = "true";

Assert.Equal(File.ReadAllText(filePathExpected), d.DocumentNode.OuterHtml);

var clone = nodes[0].CloneNode(true);

var expectedOuterNode = @"<mat-option *ngFor=""let dimension of lea546CATBEM$ | async | filterDimensionByValue:( simulationRequest.tipoProdutoId | commonData:lea508SUBPROD$:'id':'code')"" [value]=""dimension.dimensionId"">
{{ dimension.code }} - {{ dimension.description }}
</mat-option>";

Assert.Equal(expectedOuterNode, clone.OuterHtml);

}


[Fact]
public void PreserveClonedEmptyAttributesTest()
{
var d = new HtmlDocument();
d.GlobalAttributeValueQuote = AttributeValueQuote.Initial;
d.OptionDefaultUseOriginalName = true;

var html = @"<list-counter formErrorsCounter></list-counter>";
d.LoadHtml(html);

var cloned = d.DocumentNode.CloneNode(true);

Assert.Equal(@"<list-counter formErrorsCounter></list-counter>", cloned.OuterHtml);
}

[Fact]
public void PreserveQuoteTypeForLoadedAttributes()
{
var input = HtmlNode.CreateNode("<input checked></input>");
var checkedAttribute = input.Attributes.First();

// Result is: Value: '' (empty string)
Assert.Equal("", checkedAttribute.Value);

// Result is: QuoteType: WithoutValue
Assert.Equal(AttributeValueQuote.WithoutValue, checkedAttribute.QuoteType);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<form xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<page>

<page-body>
<form #simulatorForm="ngForm" xdt:Transform="InsertBefore(/form/page/page-body/card[1])"
fxFlex="50%" fxFlex.lt-md="100%"
[dataSourceContext]="simulatorDataSourceContext" name="simulatorForm">
<ng-container></ng-container>
</form>
<!--DADOS DE SIMULAÇÃO-->
<card xdt:Transform="SetAttributes(*)"
xdt:Locator="Condition(card-header/card-header-title-container/card-header-title = &quot;{{ 'Lea.Cotacoes.Cards.Dados de Simulação' | translate }}&quot;)"
editable
fxFlex="100%">
<data-group>

<!-- INSERT CategoriaBem AFTER mat-form-field with mat-select@name = 'tipoProdutoId' -->
<mat-form-field xdt:Transform="InsertAfter(mat-form-field[mat-select/@name = 'tipoProdutoId'])"
fxFlex="50%" fxFlex.lt-md="50%" fxFlex.lt-sm="100%" *ngIf="!!simulationRequest.tipoProdutoId">
<!-- CategoriaBem -->
<mat-label>
<span>{{ 'Lea.Cotacoes.Simulador.CodCategoriaBem' | translate}}</span>
</mat-label>
<mat-select name="codCategoriaBemId" required
(selectionChange)="GetProductDetails()"
[(ngModel)]="simulationRequest.categoriaBemId">
<mat-option *ngFor="let dimension of lea546CATBEM$ | async | filterDimensionByValue:( simulationRequest.tipoProdutoId | commonData:lea508SUBPROD$:'id':'code')" [value]="dimension.dimensionId">


{{ dimension.code }} - {{ dimension.description }}
</mat-option>
</mat-select>
<span readOnlyValue>{{ simulationRequest.categoriaBemId | commonData:lea546CATBEM$:'id':'code-desc' }}</span>
<field-error-alert matSuffix></field-error-alert>
<mat-error></mat-error>
</mat-form-field>

</data-group>

</card>


</page-body>


</page>
</form>
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<form xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<page>

<page-body>
<form #simulatorForm="ngForm" xdt:Transform="InsertBefore(/form/page/page-body/card[1])" fxFlex="50%" fxFlex.lt-md="100%" [dataSourceContext]="simulatorDataSourceContext" name="simulatorForm">
<ng-container></ng-container>
</form>
<!--DADOS DE SIMULAÇÃO-->
<card xdt:Transform="SetAttributes(*)" xdt:Locator="Condition(card-header/card-header-title-container/card-header-title = &quot;{{ 'Lea.Cotacoes.Cards.Dados de Simulação' | translate }}&quot;)" editable fxFlex="100%">
<data-group>

<!-- INSERT CategoriaBem AFTER mat-form-field with mat-select@name = 'tipoProdutoId' -->
<mat-form-field xdt:Transform="InsertAfter(mat-form-field[mat-select/@name = 'tipoProdutoId'])" fxFlex="50%" fxFlex.lt-md="50%" fxFlex.lt-sm="100%" *ngIf="!!simulationRequest.tipoProdutoId">
<!-- CategoriaBem -->
<mat-label>
<span>{{ 'Lea.Cotacoes.Simulador.CodCategoriaBem' | translate}}</span>
</mat-label>
<mat-select name="codCategoriaBemId" required="true" (selectionChange)="GetProductDetails()" [(ngModel)]="simulationRequest.categoriaBemId">
<mat-option *ngFor="let dimension of lea546CATBEM$ | async | filterDimensionByValue:( simulationRequest.tipoProdutoId | commonData:lea508SUBPROD$:'id':'code')" [value]="dimension.dimensionId">


{{ dimension.code }} - {{ dimension.description }}
</mat-option>
</mat-select>
<span readOnlyValue>{{ simulationRequest.categoriaBemId | commonData:lea546CATBEM$:'id':'code-desc' }}</span>
<field-error-alert matSuffix></field-error-alert>
<mat-error></mat-error>
</mat-form-field>

</data-group>

</card>


</page-body>


</page>
</form>

0 comments on commit fb2335d

Please sign in to comment.