Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added detection for duplicate names in yaml sequence #714

Merged
merged 2 commits into from
Sep 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using Microsoft.PowerPlatform.PowerApps.Persistence;
using Microsoft.PowerPlatform.PowerApps.Persistence.PaYaml.Models;
using Microsoft.PowerPlatform.PowerApps.Persistence.PaYaml.Models.SchemaV3;
using Microsoft.PowerPlatform.PowerApps.Persistence.PaYaml.Serialization;

Expand Down Expand Up @@ -152,6 +154,14 @@ public void DeserializeExamplePaYamlSingleFileApp()
.And.ContainNames("Label1", "TextInput1");
}

[TestMethod]
public void DeserializeDuplicateControlNamesShouldFail()
{
var path = @"_TestData/InvalidYaml-CI/duplicate-control-in-sequence.pa.yaml";
var ex = Assert.ThrowsException<PersistenceLibraryException>(() => PaYamlSerializer.Deserialize<NamedObjectSequence<ControlInstance>>(File.ReadAllText(path)));
ex.ErrorCode.Should().Be(PersistenceErrorCode.DuplicateNameInSequence);
}

#endregion

#region RoundTrip from yaml
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
- Label1:
Control: Label
Properties:
X: =40
Y: =40
- Label1:
Control: Label
Properties:
X: =60
Y: =60
6 changes: 5 additions & 1 deletion src/Persistence/PaYaml/Serialization/PaYamlSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,11 @@ private static void WriteTextWriter<TValue>(TextWriter writer, in TValue? value,
}
catch (YamlException ex)
{
throw PersistenceLibraryException.FromYamlException(ex, PersistenceErrorCode.YamlInvalidSyntax);
var errorCode = PersistenceErrorCode.YamlInvalidSyntax;
if (ex.InnerException is ArgumentException && ex.InnerException.Message.Contains("An item with the same key has already been added"))
errorCode = PersistenceErrorCode.DuplicateNameInSequence;

throw PersistenceLibraryException.FromYamlException(ex, errorCode);
}

// TODO: Consider using FluentValidation nuget package to validate the deserialized object
Expand Down
2 changes: 2 additions & 0 deletions src/Persistence/PersistenceErrorCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public enum PersistenceErrorCode
InvalidEditorStateJson = 3300,
ControlInstanceInvalid = 3501,
RoundTripValidationFailed = 3502,
DuplicateNameInSequence = 3503,

//
MsappArchiveError = 5000,
Expand Down Expand Up @@ -64,6 +65,7 @@ internal static PersistenceErrorCode CheckArgumentInRange(this PersistenceErrorC
PersistenceErrorCode.InvalidEditorStateJson => "An editor state json file could not be deserialized due to being invalid.",
PersistenceErrorCode.ControlInstanceInvalid => "A control instance object in YAML has an invalid state.",
PersistenceErrorCode.RoundTripValidationFailed => "Round trip yaml validation failed.",
PersistenceErrorCode.DuplicateNameInSequence => "An item name was duplicated.",
PersistenceErrorCode.MsappArchiveError => "An error was detected in an msapp file.",
PersistenceErrorCode._LastErrorExclusive => throw new InvalidOperationException("The error code is out of range."),
_ => "An exception occurred in the persistence library.",
Expand Down
Loading