Skip to content

Commit

Permalink
Fix issue bagetter#89 (bagetter#90)
Browse files Browse the repository at this point in the history
* add tests

* add JsonConverter

* include PR bagetter#91

* include PR # 85

* add test for tags
  • Loading branch information
FroggieFrog authored Feb 26, 2024
1 parent 828e794 commit 78ef62c
Show file tree
Hide file tree
Showing 9 changed files with 329 additions and 17 deletions.
34 changes: 29 additions & 5 deletions src/BaGetter.Core/Extensions/PackageArchiveReaderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public static bool HasReadme(this PackageArchiveReader package)
public static bool HasEmbeddedIcon(this PackageArchiveReader package)
=> !string.IsNullOrEmpty(package.NuspecReader.GetIcon());

public async static Task<Stream> GetReadmeAsync(
public static async Task<Stream> GetReadmeAsync(
this PackageArchiveReader package,
CancellationToken cancellationToken)
{
Expand All @@ -34,7 +34,7 @@ public async static Task<Stream> GetReadmeAsync(
return await package.GetStreamAsync(readmePath, cancellationToken);
}

public async static Task<Stream> GetIconAsync(
public static async Task<Stream> GetIconAsync(
this PackageArchiveReader package,
CancellationToken cancellationToken)
{
Expand Down Expand Up @@ -111,18 +111,42 @@ private static Uri ParseUri(string uriString)

private static readonly char[] Separator = { ',', ';', '\t', '\n', '\r' };

/// <summary>
/// Parses the authors into a list of authors.
/// </summary>
/// <remarks>
/// Authors are delimited by comma.<br/>
/// See: <see href="https://learn.microsoft.com/en-us/nuget/reference/nuspec#authors"/>
/// </remarks>
/// <param name="authors">authors to be parsed</param>
/// <returns>A list of authors.</returns>
private static string[] ParseAuthors(string authors)
{
if (string.IsNullOrEmpty(authors)) return Array.Empty<string>();
if (string.IsNullOrEmpty(authors))
{
return Array.Empty<string>();
}

return authors.Split(Separator, StringSplitOptions.RemoveEmptyEntries);
}

/// <summary>
/// Parses the tags into a list of tags.
/// </summary>
/// <remarks>
/// Tags are delimited by space.<br/>
/// See: <see href="https://learn.microsoft.com/en-us/nuget/reference/nuspec#tags"/>
/// </remarks>
/// <param name="tags">tags to be parsed</param>
/// <returns>A list of tags.</returns>
private static string[] ParseTags(string tags)
{
if (string.IsNullOrEmpty(tags)) return Array.Empty<string>();
if (string.IsNullOrEmpty(tags))
{
return Array.Empty<string>();
}

return tags.Split(Separator, StringSplitOptions.RemoveEmptyEntries);
return tags.Split(' ', StringSplitOptions.RemoveEmptyEntries);
}

private static (Uri repositoryUrl, string repositoryType) GetRepositoryMetadata(NuspecReader nuspec)
Expand Down
27 changes: 20 additions & 7 deletions src/BaGetter.Core/Upstream/Clients/V3UpstreamClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
using System.Threading.Tasks;
using BaGetter.Protocol;
using BaGetter.Protocol.Models;
using NuGet.Versioning;
using Microsoft.Extensions.Logging;
using NuGet.Versioning;

namespace BaGetter.Core;

Expand All @@ -18,7 +18,8 @@ public class V3UpstreamClient : IUpstreamClient
{
private readonly NuGetClient _client;
private readonly ILogger<V3UpstreamClient> _logger;
private static readonly char[] Separator = { ',', ';', '\t', '\n', '\r' };
private static readonly char[] AuthorSeparator = [',', ';', '\t', '\n', '\r'];
private static readonly char[] TagSeparator = [' '];

public V3UpstreamClient(NuGetClient client, ILogger<V3UpstreamClient> logger)
{
Expand Down Expand Up @@ -110,7 +111,7 @@ private Package ToPackage(PackageMetadata metadata)
RepositoryUrl = null,
RepositoryType = null,
SemVerLevel = version.IsSemVer2 ? SemVerLevel.SemVer2 : SemVerLevel.Unknown,
Tags = metadata.Tags?.ToArray() ?? Array.Empty<string>(),
Tags = ParseTags(metadata.Tags),

Dependencies = ToDependencies(metadata)
};
Expand All @@ -130,11 +131,23 @@ private static Uri ParseUri(string uriString)

private static string[] ParseAuthors(string authors)
{
if (string.IsNullOrEmpty(authors)) return Array.Empty<string>();
if (string.IsNullOrEmpty(authors))
{
return Array.Empty<string>();
}

return authors.Split(AuthorSeparator, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
}

private static string[] ParseTags(IEnumerable<string> tags)
{
if (tags is null)
{
return Array.Empty<string>();
}

return authors
.Split(Separator, StringSplitOptions.RemoveEmptyEntries)
.Select(a => a.Trim())
return tags
.SelectMany(t => t.Split(TagSeparator, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries))
.ToArray();
}

Expand Down
2 changes: 2 additions & 0 deletions src/BaGetter.Protocol/Models/PackageMetadata.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using BaGetter.Protocol.Internal;

namespace BaGetter.Protocol.Models;

Expand Down Expand Up @@ -117,6 +118,7 @@ public class PackageMetadata
/// The package's tags.
/// </summary>
[JsonPropertyName("tags")]
[JsonConverter(typeof(StringOrStringArrayJsonConverter))]
public IReadOnlyList<string> Tags { get; set; }

/// <summary>
Expand Down
6 changes: 3 additions & 3 deletions tests/BaGetter.Core.Tests/Upstream/V3UpstreamClientTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
Expand Down Expand Up @@ -115,7 +115,7 @@ public async Task ReturnsPackages()
Summary = "Summary",
Title = "Title",

Tags = new List<string> { "Tag1", "Tag2" },
Tags = new List<string> { "Tag1 Tag2" },

Deprecation = new PackageDeprecation
{
Expand Down Expand Up @@ -150,7 +150,7 @@ public async Task ReturnsPackages()
var package = Assert.Single(result);

Assert.Equal("Foo", package.Id);
Assert.Equal(new[] { "Author1", "Author2"}, package.Authors);
Assert.Equal(new[] { "Author1", "Author2" }, package.Authors);
Assert.Equal("Description", package.Description);
Assert.False(package.HasReadme);
Assert.False(package.HasEmbeddedIcon);
Expand Down
150 changes: 150 additions & 0 deletions tests/BaGetter.Protocol.Tests/Models/PackageMetadataTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
using System.Text.Json;
using BaGetter.Protocol.Internal;
using BaGetter.Protocol.Models;
using Xunit;

namespace BaGetter.Protocol.Tests.Models;

public class PackageMetadataTests
{
private readonly JsonSerializerOptions _serializerOptions;

public PackageMetadataTests()
{
_serializerOptions = new JsonSerializerOptions();
_serializerOptions.Converters.Add(new StringOrStringArrayJsonConverter());
}

[Fact]
public void Tags_EmptyArray_ShouldDeserialize()
{
// Arrange
var stringToDeserialize = """
{
"@id": "https://nuget.pkg.github.com/FakeOrga/fakepkg/1.5.1.json",
"authors": "Someone",
"copyright": "",
"dependencyGroups": [ ],
"description": "Package Description",
"iconUrl": "",
"id": "fakepkg",
"isPrerelease": false,
"language": "",
"licenseUrl": "",
"packageContent": "https://nuget.pkg.github.com/FakeOrga/download/fakepkg/1.5.1/fakepkg.1.5.1.nupkg",
"projectUrl": "",
"requireLicenseAcceptance": false,
"summary": "",
"tags": [ ],
"version": "1.5.1"
}
""";

// Act
var result = JsonSerializer.Deserialize<PackageMetadata>(stringToDeserialize, _serializerOptions);

// Assert
Assert.NotNull(result.Tags);
Assert.Empty(result.Tags);
}

[Fact]
public void Tags_EmptyString_ShouldDeserialize()
{
// Arrange
var stringToDeserialize = """
{
"@id": "https://nuget.pkg.github.com/FakeOrga/fakepkg/1.5.1.json",
"authors": "Someone",
"copyright": "",
"dependencyGroups": [ ],
"description": "Package Description",
"iconUrl": "",
"id": "fakepkg",
"isPrerelease": false,
"language": "",
"licenseUrl": "",
"packageContent": "https://nuget.pkg.github.com/FakeOrga/download/fakepkg/1.5.1/fakepkg.1.5.1.nupkg",
"projectUrl": "",
"requireLicenseAcceptance": false,
"summary": "",
"tags": "",
"version": "1.5.1"
}
""";

// Act
var result = JsonSerializer.Deserialize<PackageMetadata>(stringToDeserialize, _serializerOptions);

// Assert
Assert.NotNull(result.Tags);
Assert.Single(result.Tags);
}

[Fact]
public void Tags_SingleEntry_ShouldDeserializeSingleTag()
{
// Arrange
var stringToDeserialize = """
{
"@id": "https://nuget.pkg.github.com/FakeOrga/fakepkg/1.5.1.json",
"authors": "Someone",
"copyright": "",
"dependencyGroups": [ ],
"description": "Package Description",
"iconUrl": "",
"id": "fakepkg",
"isPrerelease": false,
"language": "",
"licenseUrl": "",
"packageContent": "https://nuget.pkg.github.com/FakeOrga/download/fakepkg/1.5.1/fakepkg.1.5.1.nupkg",
"projectUrl": "",
"requireLicenseAcceptance": false,
"summary": "",
"tags": "tag1",
"version": "1.5.1"
}
""";

// Act
var result = JsonSerializer.Deserialize<PackageMetadata>(stringToDeserialize, _serializerOptions);

// Assert
Assert.NotNull(result.Tags);
Assert.Single(result.Tags);
}

[Fact]
public void Tags_HasMultipleEntries_ShouldDeserializeMultipleTags()
{
// Arrange
var stringToDeserialize = """
{
"@id": "https://nuget.pkg.github.com/FakeOrga/fakepkg/1.5.1.json",
"authors": "Someone",
"copyright": "",
"dependencyGroups": [ ],
"description": "Package Description",
"iconUrl": "",
"id": "fakepkg",
"isPrerelease": false,
"language": "",
"licenseUrl": "",
"packageContent": "https://nuget.pkg.github.com/FakeOrga/download/fakepkg/1.5.1/fakepkg.1.5.1.nupkg",
"projectUrl": "",
"requireLicenseAcceptance": false,
"summary": "",
"tags": ["tag1", "tag2"],
"version": "1.5.1"
}
""";

// Act
var result = JsonSerializer.Deserialize<PackageMetadata>(stringToDeserialize, _serializerOptions);

// Assert
Assert.NotNull(result.Tags);
Assert.Equal(2, result.Tags.Count);
}

}
30 changes: 29 additions & 1 deletion tests/BaGetter.Protocol.Tests/RawPackageMetadataClientTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System.Threading.Tasks;
using BaGetter.Protocol.Internal;
using NuGet.Versioning;
using Xunit;

namespace BaGetter.Protocol.Tests;
Expand Down Expand Up @@ -35,6 +34,35 @@ public async Task GetRegistrationIndexInlinedItems()
Assert.StartsWith(TestData.RegistrationIndexInlinedItemsUrl, result.Pages[1].RegistrationPageUrl);
}

[Fact]
public async Task GetRegistrationIndexLikeGithubPackages()
{
var result = await _target.GetRegistrationIndexOrNullAsync("my.github.pkg");

Assert.NotNull(result);
Assert.Equal(1, result.Count);
Assert.Collection(result.Pages, page =>
{
Assert.Equal(2, page.Count);
Assert.Collection(page.ItemsOrNull,
pkg1 =>
{
Assert.Equal("2.1.6", pkg1.PackageMetadata.Version);
Assert.Collection(pkg1.PackageMetadata.Tags,
tag1 => Assert.Equal("json bson serializer", tag1)
);
},
pkg2 =>
{
Assert.Equal("2.1.5", pkg2.PackageMetadata.Version);
Assert.Collection(pkg2.PackageMetadata.Tags,
tag1 => Assert.Equal("", tag1)
);
}
);
});
}

[Fact]
public async Task GetRegistrationIndexPagedItems()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public class TestDataHttpMessageHandler : HttpMessageHandler
//{ TestData.CatalogLeafInvalidDependencyVersionRangeUrl, () => TestData.CatalogLeafInvalidDependencyVersionRange },

{ TestData.RegistrationIndexInlinedItemsUrl, () => TestData.RegistrationIndexInlinedItems },
{ TestData.RegistrationIndexLikeGithubPackagesUrl, () => TestData.RegistrationIndexLikeGithubPackages },
{ TestData.RegistrationIndexPagedItemsUrl, () => TestData.RegistrationIndexPagedItems },
{ TestData.RegistrationLeafUnlistedUrl, () => TestData.RegistrationLeafUnlisted },
{ TestData.RegistrationLeafListedUrl, () => TestData.RegistrationLeafListed },
Expand Down
Loading

0 comments on commit 78ef62c

Please sign in to comment.