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

EES-4996 add api info to data set page #4863

Merged
merged 16 commits into from
May 20, 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
199 changes: 90 additions & 109 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

namespace GovUk.Education.ExploreEducationStatistics.Common.Tests.Converters.SystemJson;

public class ListJsonConverterTests
public class ReadOnlyListJsonConverterTests
{
private abstract class SampleClass<T>
{
Expand All @@ -28,13 +28,13 @@ private enum SampleEnum

private class ClassWithObjectConverter : SampleClass<SampleObject>
{
[JsonConverter(typeof(ListJsonConverter<SampleObject, SampleObjectJsonConverter>))]
[JsonConverter(typeof(ReadOnlyListJsonConverter<SampleObject, SampleObjectJsonConverter>))]
public override IReadOnlyList<SampleObject>? SampleField { get; set; }
}

private class ClassWithEnumConverter : SampleClass<SampleEnum>
{
[JsonConverter(typeof(ListJsonConverter<SampleEnum, JsonStringEnumConverter>))]
[JsonConverter(typeof(ReadOnlyListJsonConverter<SampleEnum, JsonStringEnumConverter>))]
public override IReadOnlyList<SampleEnum>? SampleField { get; set; }
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
#nullable enable
using GovUk.Education.ExploreEducationStatistics.Common.Utils;
using Semver;
using Xunit;

namespace GovUk.Education.ExploreEducationStatistics.Common.Tests.Utils;

public abstract class VersionUtilsTests
public static class VersionUtilsTests
{
public class TryParseTests : VersionUtilsTests
public class TryParseTests
{
[Theory]
[InlineData("1.0.0", 1, 0, 0)]
Expand All @@ -18,7 +18,14 @@ public class TryParseTests : VersionUtilsTests
[InlineData("2.0", 2, 0)]
[InlineData("1", 1)]
[InlineData("2", 2)]
public void ValidVersion_SuccessfullyParsed(string versionString, int expectedMajor, int expectedMinor = default, int expectedPatch = default)
[InlineData("v2.0.0", 2, 0, 0)]
[InlineData("v2.0", 2, 0)]
[InlineData("v2", 2)]
public void ValidVersion_SuccessfullyParsed(
string versionString,
int expectedMajor,
int expectedMinor = default,
int expectedPatch = default)
{
Assert.True(VersionUtils.TryParse(versionString, out var version));

Expand All @@ -31,7 +38,11 @@ public void ValidVersion_SuccessfullyParsed(string versionString, int expectedMa
[InlineData(" 1.1.1", 1, 1, 1)]
[InlineData("1.1.1 ", 1, 1, 1)]
[InlineData(" 1.1.1 ", 1, 1, 1)]
public void VersionWithEmptySpaces_SuccessfullyParsed(string versionString, int expectedMajor, int expectedMinor = default, int expectedPatch = default)
public void VersionWithEmptySpaces_SuccessfullyParsed(
string versionString,
int expectedMajor,
int expectedMinor = default,
int expectedPatch = default)
{
Assert.True(VersionUtils.TryParse(versionString, out var version));

Expand All @@ -49,10 +60,13 @@ public void VersionWithEmptySpaces_SuccessfullyParsed(string versionString, int
[InlineData("a 1")]
[InlineData("1 a")]
[InlineData("1.1.1.1")]
[InlineData("V1.1.1")]
[InlineData("V1.1")]
[InlineData("V1")]

public void InvalidVersion_FailsToParse(string versionString)
{
Assert.False(VersionUtils.TryParse(versionString, out var _));
Assert.False(VersionUtils.TryParse(versionString, out _));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace GovUk.Education.ExploreEducationStatistics.Common.Converters.SystemJson;

public class ListJsonConverter<T, TConverter> : JsonConverter<IReadOnlyList<T>>
public class ReadOnlyListJsonConverter<T, TConverter> : JsonConverter<IReadOnlyList<T>>
where TConverter : JsonConverter
{
public override IReadOnlyList<T> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#nullable enable
using Semver;

namespace GovUk.Education.ExploreEducationStatistics.Common.Utils;
Expand All @@ -9,7 +10,8 @@ public static bool TryParse(string versionString, out SemVersion version)
var successful = SemVersion.TryParse(
versionString,
SemVersionStyles.OptionalMinorPatch
| SemVersionStyles.AllowWhitespace,
| SemVersionStyles.AllowWhitespace
| SemVersionStyles.AllowLowerV,
out var sv);

version = sv;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,8 @@ await TestApp.AddTestData<PublicDataDbContext>(context =>
dataSetVersion.LocationMetas,
fm => fm.Level == locationMetaViewModel.Level);

Assert.Equal(locationMeta.Level.GetEnumLabel(), locationMetaViewModel.Label);

foreach (var locationOptionMetaViewModel in locationMetaViewModel.Options)
{
var locationOptionMeta = Assert.Single(
Expand Down Expand Up @@ -855,7 +857,10 @@ await TestApp.AddTestData<PublicDataDbContext>(context =>
}
}

Assert.Equal(dataSetVersion.LocationMetas.Select(lm => lm.Level), content.GeographicLevels);
Assert.All(
content.GeographicLevels,
level => Assert.Equal(level.Level.GetEnumLabel(), level.Label)
);

foreach (var indicator in content.Indicators)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using GovUk.Education.ExploreEducationStatistics.Common.Extensions;
using GovUk.Education.ExploreEducationStatistics.Common.Model;
using GovUk.Education.ExploreEducationStatistics.Common.Model.Data;
using GovUk.Education.ExploreEducationStatistics.Common.Utils;
using GovUk.Education.ExploreEducationStatistics.Public.Data.Api.Swagger;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
Expand Down Expand Up @@ -33,7 +34,7 @@ public class JsonConverterSchemaFilterTests
[InlineData(nameof(TestEnumConverters.StringEnumTyped))]
public void JsonStringEnumConverters(string propertyName)
{
var schema = GenerateTestEnumConvertersSchema();
var schema = GenerateSchema<TestEnumConverters>();

var schemaPropertyName = propertyName.CamelCase();
var propertySchema = schema.Properties[schemaPropertyName];
Expand All @@ -54,7 +55,7 @@ public void JsonStringEnumConverters(string propertyName)
[Fact]
public void EnumToEnumLabelConverter()
{
var schema = GenerateTestEnumConvertersSchema();
var schema = GenerateSchema<TestEnumConverters>();

var schemaPropertyName = nameof(TestEnumConverters.EnumToEnumLabel).CamelCase();
var propertySchema = schema.Properties[schemaPropertyName];
Expand All @@ -75,7 +76,7 @@ public void EnumToEnumLabelConverter()
[Fact]
public void EnumToEnumValueConverter()
{
var schema = GenerateTestEnumConvertersSchema();
var schema = GenerateSchema<TestEnumConverters>();

var schemaPropertyName = nameof(TestEnumConverters.EnumToEnumValue).CamelCase();
var propertySchema = schema.Properties[schemaPropertyName];
Expand All @@ -93,14 +94,60 @@ public void EnumToEnumValueConverter()
Assert.Equal(TestEnum.Sample2.GetEnumValue(), enumString2.Value);
}

[Fact]
public void ListConverter_GeographicLevelEnumLabels()
{
var schema = GenerateSchema<TestReadOnlyListEnumConverters>();

var schemaPropertyName = nameof(TestReadOnlyListEnumConverters.GeographicLevelEnumLabels).CamelCase();
var propertySchema = schema.Properties[schemaPropertyName];

Assert.Null(propertySchema.Reference);
Assert.Empty(propertySchema.AllOf);

Assert.Equal("array", propertySchema.Type);

Assert.Null(propertySchema.Items.Reference);
Assert.Empty(propertySchema.Items.AllOf);

var enumStrings = propertySchema.Items.Enum.Cast<OpenApiString>()
.Select(e => e.Value)
.ToList();

Assert.Equal(EnumUtil.GetEnumLabels<GeographicLevel>(), enumStrings);
}

[Fact]
public void ListConverter_GeographicLevelEnumValues()
{
var schema = GenerateSchema<TestReadOnlyListEnumConverters>();

var schemaPropertyName = nameof(TestReadOnlyListEnumConverters.GeographicLevelEnumValues).CamelCase();
var propertySchema = schema.Properties[schemaPropertyName];

Assert.Null(propertySchema.Reference);
Assert.Empty(propertySchema.AllOf);

Assert.Equal("array", propertySchema.Type);

Assert.Null(propertySchema.Items.Reference);
Assert.Empty(propertySchema.Items.AllOf);

var enumStrings = propertySchema.Items.Enum.Cast<OpenApiString>()
.Select(e => e.Value)
.ToList();

Assert.Equal(EnumUtil.GetEnumValues<GeographicLevel>(), enumStrings);
}

[Theory]
[InlineData(nameof(TestEnumConverters.GeographicLevelStringEnum))]
[InlineData(nameof(TestEnumConverters.GeographicLevelStringEnumTyped))]
[InlineData(nameof(TestEnumConverters.GeographicLevelEnumToEnumLabel))]
[InlineData(nameof(TestEnumConverters.GeographicLevelEnumToEnumValue))]
[InlineData(nameof(TestIgnoredEnumConverters.GeographicLevelStringEnum))]
[InlineData(nameof(TestIgnoredEnumConverters.GeographicLevelStringEnumTyped))]
[InlineData(nameof(TestIgnoredEnumConverters.GeographicLevelEnumToEnumLabel))]
[InlineData(nameof(TestIgnoredEnumConverters.GeographicLevelEnumToEnumValue))]
public void GeographicLevel_Ignored(string propertyName)
{
var schema = GenerateTestEnumConvertersSchema();
var schema = GenerateSchema<TestIgnoredEnumConverters>();

var schemaPropertyName = propertyName.CamelCase();
var propertySchema = schema.Properties[schemaPropertyName];
Expand All @@ -112,13 +159,13 @@ public void GeographicLevel_Ignored(string propertyName)
}

[Theory]
[InlineData(nameof(TestEnumConverters.TimeIdentifierStringEnum))]
[InlineData(nameof(TestEnumConverters.TimeIdentifierStringEnumTyped))]
[InlineData(nameof(TestEnumConverters.TimeIdentifierEnumToEnumLabel))]
[InlineData(nameof(TestEnumConverters.TimeIdentifierEnumToEnumValue))]
[InlineData(nameof(TestIgnoredEnumConverters.TimeIdentifierStringEnum))]
[InlineData(nameof(TestIgnoredEnumConverters.TimeIdentifierStringEnumTyped))]
[InlineData(nameof(TestIgnoredEnumConverters.TimeIdentifierEnumToEnumLabel))]
[InlineData(nameof(TestIgnoredEnumConverters.TimeIdentifierEnumToEnumValue))]
public void TimeIdentifier_Ignored(string propertyName)
{
var schema = GenerateTestEnumConvertersSchema();
var schema = GenerateSchema<TestIgnoredEnumConverters>();

var schemaPropertyName = propertyName.CamelCase();
var propertySchema = schema.Properties[schemaPropertyName];
Expand All @@ -129,12 +176,12 @@ public void TimeIdentifier_Ignored(string propertyName)
Assert.Empty(propertySchema.Enum);
}

private OpenApiSchema GenerateTestEnumConvertersSchema()
private OpenApiSchema GenerateSchema<TConverters>()
{
_schemaGenerator.GenerateSchema(typeof(TestEnum), _schemaRepository);
_schemaGenerator.GenerateSchema(typeof(TestEnumConverters), _schemaRepository);
_schemaGenerator.GenerateSchema(typeof(TConverters), _schemaRepository);

return _schemaRepository.Schemas[nameof(TestEnumConverters)];
return _schemaRepository.Schemas[typeof(TConverters).Name];
}

private class TestEnumConverters
Expand All @@ -150,7 +197,10 @@ private class TestEnumConverters

[JsonConverter(typeof(EnumToEnumValueJsonConverter<TestEnum>))]
public TestEnum EnumToEnumValue { get; init; }
}

private class TestIgnoredEnumConverters
{
[JsonConverter(typeof(JsonStringEnumConverter))]
public GeographicLevel GeographicLevelStringEnum { get; init; }

Expand All @@ -176,6 +226,15 @@ private class TestEnumConverters
public TimeIdentifier TimeIdentifierEnumToEnumValue { get; init; }
}

private class TestReadOnlyListEnumConverters
{
[JsonConverter(typeof(ReadOnlyListJsonConverter<GeographicLevel, EnumToEnumLabelJsonConverter<GeographicLevel>>))]
public IReadOnlyList<GeographicLevel> GeographicLevelEnumLabels { get; init; } = [];

[JsonConverter(typeof(ReadOnlyListJsonConverter<GeographicLevel, EnumToEnumValueJsonConverter<GeographicLevel>>))]
public IReadOnlyList<GeographicLevel> GeographicLevelEnumValues { get; init; } = [];
}

private enum TestEnum
{
[EnumLabelValue("Sample 1", "sample-1")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using GovUk.Education.ExploreEducationStatistics.Common.Extensions;
using GovUk.Education.ExploreEducationStatistics.Common.Model.Data;
using GovUk.Education.ExploreEducationStatistics.Common.Services.Interfaces.Security;
using GovUk.Education.ExploreEducationStatistics.Common.Utils;
using GovUk.Education.ExploreEducationStatistics.Public.Data.Api.Security.Extensions;
Expand Down Expand Up @@ -250,6 +251,11 @@ private async Task LoadMeta(

if (types.Contains(DataSetMetaType.Locations))
{
dataSetVersion.GeographicLevelMeta = await publicDataDbContext.GeographicLevelMetas
.AsNoTracking()
.Where(lm => lm.DataSetVersionId == dataSetVersion.Id)
.FirstOrDefaultAsync(cancellationToken: cancellationToken);

dataSetVersion.LocationMetas = await publicDataDbContext.LocationMetas
.AsNoTracking()
.Where(lm => lm.DataSetVersionId == dataSetVersion.Id)
Expand Down Expand Up @@ -286,9 +292,9 @@ private static DataSetMetaViewModel MapVersionMeta(DataSetVersion dataSetVersion
.OrderBy(im => im.Label)
.ToList();

var geographicLevels = dataSetVersion.LocationMetas
.Select(lm => lm.Level)
.ToList();
var geographicLevels = dataSetVersion.GeographicLevelMeta?.Levels
.Select(MapGeographicLevelMeta)
.ToList() ?? [];

var locations = dataSetVersion.LocationMetas
.Select(MapLocationMeta)
Expand All @@ -310,6 +316,15 @@ private static DataSetMetaViewModel MapVersionMeta(DataSetVersion dataSetVersion
};
}

private static GeographicLevelMetaViewModel MapGeographicLevelMeta(GeographicLevel level)
{
return new GeographicLevelMetaViewModel
{
Level = level,
Label = level.GetEnumLabel(),
};
}

private static FilterMetaViewModel MapFilterMeta(FilterMeta filterMeta)
{
var options = filterMeta.OptionLinks
Expand Down Expand Up @@ -357,6 +372,7 @@ private static LocationLevelMetaViewModel MapLocationMeta(LocationMeta locationM
return new LocationLevelMetaViewModel
{
Level = locationMeta.Level,
Label = locationMeta.Level.GetEnumLabel(),
Options = options,
};
}
Expand Down
Loading