Skip to content

Commit 58e00cf

Browse files
committed
Fix roundtrip of Parse/ToString for include query string parameters
1 parent e9cb483 commit 58e00cf

File tree

2 files changed

+23
-17
lines changed

2 files changed

+23
-17
lines changed

src/JsonApiDotNetCore/Queries/Expressions/IncludeExpression.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public override string ToFullString()
5252
private string InnerToString(bool toFullString)
5353
{
5454
IReadOnlyCollection<ResourceFieldChainExpression> chains = IncludeChainConverter.GetRelationshipChains(this);
55-
return string.Join(",", chains.Select(field => toFullString ? field.ToFullString() : field.ToString()).OrderBy(name => name));
55+
return string.Join(",", chains.Select(field => toFullString ? field.ToFullString() : field.ToString()).Distinct().OrderBy(name => name));
5656
}
5757

5858
public override bool Equals(object? obj)

test/JsonApiDotNetCoreTests/UnitTests/QueryStringParameters/IncludeParseTests.cs

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -85,21 +85,26 @@ public void Reader_Read_Fails(string parameterName, string parameterValue, strin
8585
}
8686

8787
[Theory]
88-
[InlineData("includes", "", "")]
89-
[InlineData("includes", "owner", "owner")]
90-
[InlineData("includes", "posts", "posts")]
91-
[InlineData("includes", "owner.posts", "owner.posts")]
92-
[InlineData("includes", "posts.author", "posts.author")]
93-
[InlineData("includes", "posts.comments", "posts.comments")]
94-
[InlineData("includes", "posts,posts.comments", "posts.comments")]
95-
[InlineData("includes", "posts,posts.labels,posts.comments", "posts.comments,posts.labels")]
96-
[InlineData("includes", "owner.person.children.husband", "owner.person.children.husband,owner.person.children.husband")]
97-
[InlineData("includes", "owner.person.wife,owner.person.husband", "owner.person.husband,owner.person.wife")]
98-
[InlineData("includes", "owner.person.father.children.wife", "owner.person.father.children.wife,owner.person.father.children.wife")]
99-
[InlineData("includes", "owner.person.friends", "owner.person.friends,owner.person.friends")]
100-
[InlineData("includes", "owner.person.friends.friends",
101-
"owner.person.friends.friends,owner.person.friends.friends,owner.person.friends.friends,owner.person.friends.friends")]
102-
public void Reader_Read_Succeeds(string parameterName, string parameterValue, string valueExpected)
88+
[InlineData("includes", "", "", "")]
89+
[InlineData("includes", "owner", "owner", "blogs:owner")]
90+
[InlineData("includes", "posts", "posts", "blogs:posts")]
91+
[InlineData("includes", "owner.posts", "owner.posts", "blogs:owner.webAccounts:posts")]
92+
[InlineData("includes", "posts.author", "posts.author", "blogs:posts.blogPosts:author")]
93+
[InlineData("includes", "posts.comments", "posts.comments", "blogs:posts.blogPosts:comments")]
94+
[InlineData("includes", "posts,posts.comments", "posts.comments", "blogs:posts.blogPosts:comments")]
95+
[InlineData("includes", "posts,posts.labels,posts.comments", "posts.comments,posts.labels", "blogs:posts.blogPosts:comments,blogs:posts.blogPosts:labels")]
96+
[InlineData("includes", "owner.person.children.husband", "owner.person.children.husband",
97+
"blogs:owner.webAccounts:person.men:children.women:husband,blogs:owner.webAccounts:person.women:children.women:husband")]
98+
[InlineData("includes", "owner.person.wife,owner.person.husband", "owner.person.husband,owner.person.wife",
99+
"blogs:owner.webAccounts:person.men:wife,blogs:owner.webAccounts:person.women:husband")]
100+
[InlineData("includes", "owner.person.father.children.wife", "owner.person.father.children.wife",
101+
"blogs:owner.webAccounts:person.men:father.men:children.men:wife,blogs:owner.webAccounts:person.women:father.men:children.men:wife")]
102+
[InlineData("includes", "owner.person.friends", "owner.person.friends",
103+
"blogs:owner.webAccounts:person.men:friends,blogs:owner.webAccounts:person.women:friends")]
104+
[InlineData("includes", "owner.person.friends.friends", "owner.person.friends.friends",
105+
"blogs:owner.webAccounts:person.men:friends.men:friends,blogs:owner.webAccounts:person.men:friends.women:friends," +
106+
"blogs:owner.webAccounts:person.women:friends.men:friends,blogs:owner.webAccounts:person.women:friends.women:friends")]
107+
public void Reader_Read_Succeeds(string parameterName, string parameterValue, string stringExpected, string fullStringExpected)
103108
{
104109
// Act
105110
_reader.Read(parameterName, parameterValue);
@@ -111,6 +116,7 @@ public void Reader_Read_Succeeds(string parameterName, string parameterValue, st
111116
scope.Should().BeNull();
112117

113118
QueryExpression value = constraints.Select(expressionInScope => expressionInScope.Expression).Single();
114-
value.ToString().Should().Be(valueExpected);
119+
value.ToString().Should().Be(stringExpected);
120+
value.ToFullString().Should().Be(fullStringExpected);
115121
}
116122
}

0 commit comments

Comments
 (0)