From a7740edc67d7f8907038904ac4cf563cea2420d5 Mon Sep 17 00:00:00 2001 From: griffri Date: Tue, 28 May 2024 11:50:49 +0100 Subject: [PATCH 01/30] Remove WcDeliveryChannels from API and HydraModel, remove OldHydraDeliveryChannelsConverter --- .../OldHydraDeliveryChannelsConverterTests.cs | 151 ------------------ .../API/Converters/AssetConverter.cs | 11 +- .../API/Converters/LegacyModeConverter.cs | 2 +- .../Customer/CustomerImagesController.cs | 2 +- .../OldHydraDeliveryChannelsConverter.cs | 69 -------- .../API/Features/Image/ImageController.cs | 37 +---- .../API/Features/Image/ImagesController.cs | 4 +- .../Image/Validation/HydraImageValidator.cs | 51 ------ .../Validation/ImageBatchPatchValidator.cs | 1 - .../Queues/CustomerQueueController.cs | 31 +--- .../Queues/Validation/QueuePostValidator.cs | 2 - src/protagonist/API/Startup.cs | 1 - src/protagonist/DLCS.HydraModel/Image.cs | 5 - 13 files changed, 15 insertions(+), 352 deletions(-) delete mode 100644 src/protagonist/API.Tests/Features/DeliveryChannels/Converters/OldHydraDeliveryChannelsConverterTests.cs delete mode 100644 src/protagonist/API/Features/DeliveryChannels/Converters/OldHydraDeliveryChannelsConverter.cs diff --git a/src/protagonist/API.Tests/Features/DeliveryChannels/Converters/OldHydraDeliveryChannelsConverterTests.cs b/src/protagonist/API.Tests/Features/DeliveryChannels/Converters/OldHydraDeliveryChannelsConverterTests.cs deleted file mode 100644 index aa279c7d9..000000000 --- a/src/protagonist/API.Tests/Features/DeliveryChannels/Converters/OldHydraDeliveryChannelsConverterTests.cs +++ /dev/null @@ -1,151 +0,0 @@ -using System.Collections.Generic; -using API.Features.DeliveryChannels.Converters; -using DLCS.HydraModel; - -namespace API.Tests.Features.DeliveryChannels.Converters; - -public class OldHydraDeliveryChannelsConverterTests -{ - private readonly OldHydraDeliveryChannelsConverter sut; - - public OldHydraDeliveryChannelsConverterTests() - { - sut = new OldHydraDeliveryChannelsConverter(); - } - - [Fact] - public void Convert_TranslatesImageChannel() - { - // Arrange - var image = new Image() - { - WcDeliveryChannels = new[]{"iiif-img"}, - }; - - // Act - var result = sut.Convert(image); - - // Assert - result.Should().BeEquivalentTo(new List() - { - new() - { - Channel = "iiif-img", - Policy = "default", - }, - new() - { - Channel = "thumbs", - Policy = null, - }, - }); - } - - [Fact] - public void Convert_TranslatesImageChannel_WithUseOriginalPolicy() - { - // Arrange - var image = new Image() - { - WcDeliveryChannels = new[]{"iiif-img"}, - ImageOptimisationPolicy = "use-original" - }; - - // Act - var result = sut.Convert(image); - - // Assert - result.Should().BeEquivalentTo(new List() - { - new() - { - Channel = "iiif-img", - Policy = "use-original" - }, - new() - { - Channel = "thumbs", - Policy = null, - } - }); - } - - [Fact] - public void Convert_TranslatesAvChannel() - { - // Arrange - var image = new Image() - { - WcDeliveryChannels = new[]{"iiif-av"} - }; - - // Act - var result = sut.Convert(image); - - // Assert - result.Should().BeEquivalentTo(new List() - { - new() - { - Channel = "iiif-av", - Policy = null, - } - }); - } - - [Fact] - public void Convert_TranslatesFileChannel() - { - // Arrange - var image = new Image() - { - WcDeliveryChannels = new[]{"file"} - }; - - // Act - var result = sut.Convert(image); - - // Assert - result.Should().BeEquivalentTo(new List() - { - new() - { - Channel = "file", - Policy = "none" - } - }); - } - - [Fact] - public void Convert_TranslatesMultipleChannels() - { - // Arrange - var image = new Image() - { - WcDeliveryChannels = new[]{"iiif-img","thumbs","file"} - }; - - // Act - var result = sut.Convert(image); - - // Assert - result.Should().BeEquivalentTo(new List() - { - new() - { - Channel = "iiif-img", - Policy = "default", - }, - new() - { - Channel = "thumbs", - Policy = null, - }, - new() - { - Channel = "file", - Policy = "none" - } - }); - } -} \ No newline at end of file diff --git a/src/protagonist/API/Converters/AssetConverter.cs b/src/protagonist/API/Converters/AssetConverter.cs index 3666c8055..13c93df44 100644 --- a/src/protagonist/API/Converters/AssetConverter.cs +++ b/src/protagonist/API/Converters/AssetConverter.cs @@ -24,7 +24,7 @@ public static class AssetConverter /// The domain name of the API and orchestrator applications /// Includes delivery channels in the old format in the returned model /// - public static Image ToHydra(this Asset dbAsset, UrlRoots urlRoots, bool emulateWcDeliveryChannels = false) + public static Image ToHydra(this Asset dbAsset, UrlRoots urlRoots) { if (dbAsset.Id.Customer != dbAsset.Customer || dbAsset.Id.Space != dbAsset.Space) { @@ -87,10 +87,6 @@ public static Image ToHydra(this Asset dbAsset, UrlRoots urlRoots, bool emulateW ? c.DeliveryChannelPolicy.Name : $"{urlRoots.BaseUrl}/customers/{c.DeliveryChannelPolicy.Customer}/deliveryChannelPolicies/{c.Channel}/{c.DeliveryChannelPolicy.Name}" }).ToArray(); - if (emulateWcDeliveryChannels) - { - image.WcDeliveryChannels = ConvertImageDeliveryChannelsToWc(dbAsset.ImageDeliveryChannels); - } } else { @@ -291,11 +287,6 @@ public static Asset ToDlcsModel(this Image hydraImage, int customerId, int? spac asset.MediaType = hydraImage.MediaType; } - if (hydraImage.WcDeliveryChannels != null) - { - asset.DeliveryChannels = hydraImage.WcDeliveryChannels.OrderBy(dc => dc).Select(dc => dc.ToLower()).ToArray(); - } - var thumbnailPolicy = hydraImage.ThumbnailPolicy.GetLastPathElement("thumbnailPolicies/"); if (thumbnailPolicy != null) { diff --git a/src/protagonist/API/Converters/LegacyModeConverter.cs b/src/protagonist/API/Converters/LegacyModeConverter.cs index 51f20b6fb..ae2c62468 100644 --- a/src/protagonist/API/Converters/LegacyModeConverter.cs +++ b/src/protagonist/API/Converters/LegacyModeConverter.cs @@ -26,7 +26,7 @@ public static T VerifyAndConvertToModernFormat(T image) image.MediaType = MIMEHelper.GetContentTypeForExtension(contentType) ?? DefaultMediaType; - if (image.Origin is not null && image.Family is null && image.WcDeliveryChannels.IsNullOrEmpty()) + if (image.Origin is not null && image.Family is null) { image.Family = AssetFamily.Image; } diff --git a/src/protagonist/API/Features/Customer/CustomerImagesController.cs b/src/protagonist/API/Features/Customer/CustomerImagesController.cs index f71e2522e..7dd23422f 100644 --- a/src/protagonist/API/Features/Customer/CustomerImagesController.cs +++ b/src/protagonist/API/Features/Customer/CustomerImagesController.cs @@ -62,7 +62,7 @@ public async Task GetAllImages( return await HandleListFetch( request, - a => a.ToHydra(GetUrlRoots(), Settings.EmulateOldDeliveryChannelProperties), + a => a.ToHydra(GetUrlRoots()), "Get customer images failed", cancellationToken: cancellationToken); } diff --git a/src/protagonist/API/Features/DeliveryChannels/Converters/OldHydraDeliveryChannelsConverter.cs b/src/protagonist/API/Features/DeliveryChannels/Converters/OldHydraDeliveryChannelsConverter.cs deleted file mode 100644 index dfa05a5f1..000000000 --- a/src/protagonist/API/Features/DeliveryChannels/Converters/OldHydraDeliveryChannelsConverter.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System.Collections.Generic; -using DLCS.Core.Collections; -using DLCS.HydraModel; -using DLCS.Model.Assets; - -namespace API.Features.DeliveryChannels.Converters; - -/// -/// Conversion between asset.WcDeliveryChannels and asset.DeliveryChannels -/// -public class OldHydraDeliveryChannelsConverter -{ - private const string ImageDefaultPolicy = "default"; - private const string ImageUseOriginalPolicy = "use-original"; - private const string FileNonePolicy = "none"; - - /// - /// Convert an asset's WcDeliveryChannels into a list of HydraModel.DeliveryChannel objects - /// - public DeliveryChannel[]? Convert(DLCS.HydraModel.Image hydraImage) - { - if (hydraImage.WcDeliveryChannels.IsNullOrEmpty()) return null; - - var convertedDeliveryChannels = new List(); - - foreach (var wcDeliveryChannel in hydraImage.WcDeliveryChannels) - { - var matchedDeliveryChannels = wcDeliveryChannel switch - { - AssetDeliveryChannels.Image => new List(){ - new() - { - Channel = AssetDeliveryChannels.Image, - Policy = hydraImage.ImageOptimisationPolicy == ImageUseOriginalPolicy - ? ImageUseOriginalPolicy - : ImageDefaultPolicy - }, - new() - { - Channel = AssetDeliveryChannels.Thumbnails - }, - }, - AssetDeliveryChannels.File => new List() - { - new() - { - Channel = AssetDeliveryChannels.File, - Policy = FileNonePolicy - } - }, - AssetDeliveryChannels.Timebased => new List() - { - new() - { - Channel = wcDeliveryChannel, - } - }, - _ => null - }; - - if (matchedDeliveryChannels != null) - { - convertedDeliveryChannels.AddRange(matchedDeliveryChannels); - } - } - - return convertedDeliveryChannels.ToArray(); - } -} \ No newline at end of file diff --git a/src/protagonist/API/Features/Image/ImageController.cs b/src/protagonist/API/Features/Image/ImageController.cs index f157db8c8..b76da9c80 100644 --- a/src/protagonist/API/Features/Image/ImageController.cs +++ b/src/protagonist/API/Features/Image/ImageController.cs @@ -27,16 +27,13 @@ namespace API.Features.Image; public class ImageController : HydraController { private readonly ILogger logger; - private readonly OldHydraDeliveryChannelsConverter oldHydraDcConverter; public ImageController( IMediator mediator, IOptions options, - ILogger logger, - OldHydraDeliveryChannelsConverter oldHydraDcConverter) : base(options.Value, mediator) + ILogger logger) : base(options.Value, mediator) { this.logger = logger; - this.oldHydraDcConverter = oldHydraDcConverter; } /// @@ -54,7 +51,7 @@ public async Task GetImage(int customerId, int spaceId, string im { return this.HydraNotFound(); } - return Ok(dbImage.ToHydra(GetUrlRoots(), Settings.EmulateOldDeliveryChannelProperties)); + return Ok(dbImage.ToHydra(GetUrlRoots())); } /// @@ -103,14 +100,7 @@ public async Task PutImage( hydraAsset = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraAsset); } - if (Settings.EmulateOldDeliveryChannelProperties && - hydraAsset.WcDeliveryChannels != null) - { - hydraAsset.DeliveryChannels = oldHydraDcConverter.Convert(hydraAsset); - } - - if(!Settings.EmulateOldDeliveryChannelProperties && - (hydraAsset.ImageOptimisationPolicy != null || hydraAsset.ThumbnailPolicy != null)) + if(hydraAsset.ImageOptimisationPolicy != null || hydraAsset.ThumbnailPolicy != null) { return this.HydraProblem("ImageOptimisationPolicy and ThumbnailPolicy are disabled", null, 400, "Bad Request"); @@ -171,22 +161,7 @@ public async Task PatchImage( [FromServices] HydraImageValidator validator, CancellationToken cancellationToken) { - if (!hydraAsset.WcDeliveryChannels.IsNullOrEmpty()) - { - if (!Settings.DeliveryChannelsEnabled) - { - var assetId = new AssetId(customerId, spaceId, imageId); - return this.HydraProblem("Delivery channels are disabled", assetId.ToString(), 400, "Bad Request"); - } - - if (Settings.EmulateOldDeliveryChannelProperties) - { - hydraAsset.DeliveryChannels = oldHydraDcConverter.Convert(hydraAsset); - } - } - - if(!Settings.EmulateOldDeliveryChannelProperties && - (hydraAsset.ImageOptimisationPolicy != null || hydraAsset.ThumbnailPolicy != null)) + if(hydraAsset.ImageOptimisationPolicy != null || hydraAsset.ThumbnailPolicy != null) { return this.HydraProblem("ImageOptimisationPolicy and ThumbnailPolicy are disabled", null, 400, "Bad Request"); @@ -245,7 +220,7 @@ public Task ReingestAsset([FromRoute] int customerId, [FromRoute] { var reingestRequest = new ReingestAsset(customerId, spaceId, imageId); return HandleUpsert(reingestRequest, - asset => asset.ToHydra(GetUrlRoots(), Settings.EmulateOldDeliveryChannelProperties), + asset => asset.ToHydra(GetUrlRoots()), reingestRequest.AssetId.ToString(), "Reingest Failed", cancellationToken); } @@ -325,7 +300,7 @@ private Task PutOrPatchAsset(int customerId, int spaceId, string return HandleUpsert( createOrUpdateRequest, - asset => asset.ToHydra(GetUrlRoots(), Settings.EmulateOldDeliveryChannelProperties), + asset => asset.ToHydra(GetUrlRoots()), assetId.ToString(), "Upsert asset failed", cancellationToken); } diff --git a/src/protagonist/API/Features/Image/ImagesController.cs b/src/protagonist/API/Features/Image/ImagesController.cs index 7fe1a2717..8bf4f3c9c 100644 --- a/src/protagonist/API/Features/Image/ImagesController.cs +++ b/src/protagonist/API/Features/Image/ImagesController.cs @@ -74,7 +74,7 @@ public async Task GetImages( var imagesRequest = new GetSpaceImages(spaceId, customerId, assetFilter); return await HandlePagedFetch( imagesRequest, - image => image.ToHydra(GetUrlRoots(), Settings.EmulateOldDeliveryChannelProperties), + image => image.ToHydra(GetUrlRoots()), errorTitle: "Get Space Images failed", cancellationToken: cancellationToken ); @@ -159,7 +159,7 @@ public async Task PatchImages( var output = new HydraCollection { WithContext = true, - Members = patchedAssets.Select(a => a.ToHydra(urlRoots, Settings.EmulateOldDeliveryChannelProperties)).ToArray(), + Members = patchedAssets.Select(a => a.ToHydra(urlRoots)).ToArray(), TotalItems = patchedAssets.Count, Id = Request.GetDisplayUrl() + "?patch_" + Guid.NewGuid() }; diff --git a/src/protagonist/API/Features/Image/Validation/HydraImageValidator.cs b/src/protagonist/API/Features/Image/Validation/HydraImageValidator.cs index 910c1aa36..0b1aa75d4 100644 --- a/src/protagonist/API/Features/Image/Validation/HydraImageValidator.cs +++ b/src/protagonist/API/Features/Image/Validation/HydraImageValidator.cs @@ -28,29 +28,12 @@ public HydraImageValidator(IOptions apiSettings) RuleFor(a => a.MediaType).NotEmpty().WithMessage("Media type must be specified"); }); - When(a => !a.WcDeliveryChannels.IsNullOrEmpty(), DeliveryChannelDependantValidation) - .Otherwise(() => - { - RuleFor(a => a.Width).Empty().WithMessage("Should not include width"); - RuleFor(a => a.Height).Empty().WithMessage("Should not include height"); - RuleFor(a => a.Duration).Empty().WithMessage("Should not include duration"); - }); - When(a => !a.DeliveryChannels.IsNullOrEmpty(), ImageDeliveryChannelDependantValidation); // System edited fields RuleFor(a => a.Batch).Empty().WithMessage("Should not include batch"); RuleFor(a => a.Finished).Empty().WithMessage("Should not include finished"); RuleFor(a => a.Created).Empty().WithMessage("Should not include created"); - - // Other validation - RuleFor(a => a.WcDeliveryChannels).Must(d => d.IsNullOrEmpty()) - .When(_ => !apiSettings.Value.DeliveryChannelsEnabled) - .WithMessage("Delivery channels are disabled"); - - RuleForEach(a => a.WcDeliveryChannels) - .Must(AssetDeliveryChannels.IsValidChannel) - .WithMessage($"DeliveryChannel must be one of {AssetDeliveryChannels.AllString}"); } private void ImageDeliveryChannelDependantValidation() @@ -77,38 +60,4 @@ private void ImageDeliveryChannelDependantValidation() .Must((a, c) => a.DeliveryChannels!.Count(dc => dc.Channel == c.Channel) <= 1) .WithMessage("'deliveryChannels' cannot contain duplicate channels."); } - - // Validation rules that depend on DeliveryChannel being populated - private void DeliveryChannelDependantValidation() - { - RuleFor(a => a.ImageOptimisationPolicy) - .Must(iop => !KnownImageOptimisationPolicy.IsNoOpIdentifier(iop)) - .When(a => !a.WcDeliveryChannels.ContainsOnly(AssetDeliveryChannels.File)) - .WithMessage( - $"ImageOptimisationPolicy {KnownImageOptimisationPolicy.NoneId} only valid for 'file' delivery channel"); - - RuleFor(a => a.Width) - .Empty() - .WithMessage("Should not include width") - .Unless(a => - a.WcDeliveryChannels.ContainsOnly(AssetDeliveryChannels.File) && !MIMEHelper.IsAudio(a.MediaType)); - - RuleFor(a => a.Height) - .Empty() - .WithMessage("Should not include height") - .Unless(a => - a.WcDeliveryChannels.ContainsOnly(AssetDeliveryChannels.File) && !MIMEHelper.IsAudio(a.MediaType)); - - RuleFor(a => a.Duration) - .Empty() - .WithMessage("Should not include duration") - .Unless(a => - a.WcDeliveryChannels.ContainsOnly(AssetDeliveryChannels.File) && !MIMEHelper.IsImage(a.MediaType)); - - RuleFor(a => a.ImageOptimisationPolicy) - .Must(iop => !KnownImageOptimisationPolicy.IsUseOriginalIdentifier(iop)) - .When(a => !a.WcDeliveryChannels!.Contains(AssetDeliveryChannels.Image)) - .WithMessage( - $"ImageOptimisationPolicy '{KnownImageOptimisationPolicy.UseOriginalId}' only valid for image delivery-channel"); - } } \ No newline at end of file diff --git a/src/protagonist/API/Features/Image/Validation/ImageBatchPatchValidator.cs b/src/protagonist/API/Features/Image/Validation/ImageBatchPatchValidator.cs index 7646b7e41..bcf569fd3 100644 --- a/src/protagonist/API/Features/Image/Validation/ImageBatchPatchValidator.cs +++ b/src/protagonist/API/Features/Image/Validation/ImageBatchPatchValidator.cs @@ -35,7 +35,6 @@ public ImageBatchPatchValidator(IOptions apiSettings) members.RuleFor(a => a.Origin).Empty().WithMessage("Origin cannot be set in a bulk patching operation"); members.RuleFor(a => a.ImageOptimisationPolicy).Empty().WithMessage("Image optimisation policies cannot be set in a bulk patching operation"); members.RuleFor(a => a.MaxUnauthorised).Empty().WithMessage("MaxUnauthorised cannot be set in a bulk patching operation"); - members.RuleFor(a => a.WcDeliveryChannels).Empty().WithMessage("Delivery channels cannot be set in a bulk patching operation"); members.RuleFor(a => a.DeliveryChannels).Empty().WithMessage("Delivery channels cannot be set in a bulk patching operation"); members.RuleFor(a => a.ThumbnailPolicy).Empty().WithMessage("Thumbnail policy cannot be set in a bulk patching operation"); }); diff --git a/src/protagonist/API/Features/Queues/CustomerQueueController.cs b/src/protagonist/API/Features/Queues/CustomerQueueController.cs index 66025e5f9..a6625b973 100644 --- a/src/protagonist/API/Features/Queues/CustomerQueueController.cs +++ b/src/protagonist/API/Features/Queues/CustomerQueueController.cs @@ -28,13 +28,8 @@ namespace API.Features.Queues; [ApiController] public class CustomerQueueController : HydraController { - private readonly ApiSettings apiSettings; - private readonly OldHydraDeliveryChannelsConverter oldHydraDcConverter; - public CustomerQueueController(IOptions settings, IMediator mediator, - OldHydraDeliveryChannelsConverter oldHydraDcConverter) : base(settings.Value, mediator) + public CustomerQueueController(IOptions settings, IMediator mediator) : base(settings.Value, mediator) { - apiSettings = settings.Value; - this.oldHydraDcConverter = oldHydraDcConverter; } /// @@ -225,7 +220,7 @@ public async Task GetBatchImages([FromRoute] int customerId, [Fro return await HandlePagedFetch( getCustomerRequest, - image => image.ToHydra(GetUrlRoots(), apiSettings.EmulateOldDeliveryChannelProperties), + image => image.ToHydra(GetUrlRoots()), errorTitle: "Get Batch Images failed", cancellationToken: cancellationToken ); @@ -370,11 +365,11 @@ private void UpdateMembers(int customerId, IList? members { if (members == null) return; - if (apiSettings.LegacyModeEnabledForCustomer(customerId)) + if (Settings.LegacyModeEnabledForCustomer(customerId)) { for (int i = 0; i < members.Count; i++) { - if (apiSettings.LegacyModeEnabledForSpace(customerId, members[i].Space)) + if (Settings.LegacyModeEnabledForSpace(customerId, members[i].Space)) { members[i] = LegacyModeConverter.VerifyAndConvertToModernFormat(members[i]); } @@ -385,23 +380,5 @@ private void UpdateMembers(int customerId, IList? members { image.ModelId = Guid.NewGuid().ToString(); } - - if (apiSettings.EmulateOldDeliveryChannelProperties) - { - ConvertOldDeliveryChannelsForMembers(members); - } - } - - /// - /// Converts WcDeliveryChannels (if set) to DeliveryChannels for a list of assets - /// - /// The assets to update - private void ConvertOldDeliveryChannelsForMembers(IList members) - { - foreach (var hydraAsset in members) - { - if (hydraAsset.WcDeliveryChannels.IsNullOrEmpty()) continue; - hydraAsset.DeliveryChannels = oldHydraDcConverter.Convert(hydraAsset); - } } } \ No newline at end of file diff --git a/src/protagonist/API/Features/Queues/Validation/QueuePostValidator.cs b/src/protagonist/API/Features/Queues/Validation/QueuePostValidator.cs index 959f3ce6d..b5b502685 100644 --- a/src/protagonist/API/Features/Queues/Validation/QueuePostValidator.cs +++ b/src/protagonist/API/Features/Queues/Validation/QueuePostValidator.cs @@ -42,12 +42,10 @@ public QueuePostValidator(IOptions apiSettings) members.RuleFor(a => a.ImageOptimisationPolicy) .Null() - .When(_ => !apiSettings.Value.EmulateOldDeliveryChannelProperties) .WithMessage("ImageOptimisationPolicy is disabled"); members.RuleFor(a => a.ThumbnailPolicy) .Null() - .When(_ => !apiSettings.Value.EmulateOldDeliveryChannelProperties) .WithMessage("ThumbnailPolicy is disabled"); }); } diff --git a/src/protagonist/API/Startup.cs b/src/protagonist/API/Startup.cs index 78ed22163..ad4a1a181 100644 --- a/src/protagonist/API/Startup.cs +++ b/src/protagonist/API/Startup.cs @@ -78,7 +78,6 @@ public void ConfigureServices(IServiceCollection services) .AddScoped() .AddTransient() .AddScoped() - .AddSingleton() .AddValidatorsFromAssemblyContaining() .ConfigureMediatR() .AddNamedQueriesCore() diff --git a/src/protagonist/DLCS.HydraModel/Image.cs b/src/protagonist/DLCS.HydraModel/Image.cs index 8091b719f..54d481169 100644 --- a/src/protagonist/DLCS.HydraModel/Image.cs +++ b/src/protagonist/DLCS.HydraModel/Image.cs @@ -196,11 +196,6 @@ public Image(string baseUrl, int customerId, int space, string modelId) [JsonConverter(typeof(ImageDeliveryChannelsConverter))] public DeliveryChannel[]? DeliveryChannels { get; set; } - [RdfProperty(Description = "Delivery channel specifying how the asset will be available.", - Range = Names.XmlSchema.String, ReadOnly = false, WriteOnly = false)] - [JsonProperty(Order = 141, PropertyName = "wcDeliveryChannels")] - public string[]? WcDeliveryChannels { get; set; } - [RdfProperty(Description = "The role or roles that a user must possess to view this image above maxUnauthorised. " + "These are URIs of roles e.g., https://api.dlcs.io/customers/1/roles/requiresRegistration", Range = "vocab:Role", ReadOnly = false, WriteOnly = false, SetManually = true)] From 39dd79050ad3d456fe2fd873e870782bdea36459 Mon Sep 17 00:00:00 2001 From: griffri Date: Tue, 28 May 2024 14:46:59 +0100 Subject: [PATCH 02/30] Update/remove tests that used wcDeliveryChannels Re-include Width, Height, Duration checks in HydraImageValidator --- .../Converters/AssetConverterTests.cs | 78 +-- .../Validation/HydraImageValidatorTests.cs | 174 +----- .../ImageBatchPatchValidatorTests.cs | 11 - .../Validation/QueuePostValidatorTests.cs | 61 +- .../Integration/CustomerQueueTests.cs | 76 ++- ...eueWithOldDeliveryChannelEmulationTests.cs | 322 ---------- .../API.Tests/Integration/ModifyAssetTests.cs | 40 +- ...setWithOldDeliveryChannelEmulationTests.cs | 584 ------------------ ...ModifyAssetWithoutDeliveryChannelsTests.cs | 58 -- .../API/Converters/AssetConverter.cs | 12 - .../Image/Validation/HydraImageValidator.cs | 3 + 11 files changed, 66 insertions(+), 1353 deletions(-) delete mode 100644 src/protagonist/API.Tests/Integration/CustomerQueueWithOldDeliveryChannelEmulationTests.cs delete mode 100644 src/protagonist/API.Tests/Integration/ModifyAssetWithOldDeliveryChannelEmulationTests.cs delete mode 100644 src/protagonist/API.Tests/Integration/ModifyAssetWithoutDeliveryChannelsTests.cs diff --git a/src/protagonist/API.Tests/Converters/AssetConverterTests.cs b/src/protagonist/API.Tests/Converters/AssetConverterTests.cs index 01a178e36..7e69ea20e 100644 --- a/src/protagonist/API.Tests/Converters/AssetConverterTests.cs +++ b/src/protagonist/API.Tests/Converters/AssetConverterTests.cs @@ -1,12 +1,9 @@ using System; -using System.Collections.Generic; using API.Converters; using API.Exceptions; using DLCS.Core.Types; using DLCS.HydraModel; -using DLCS.Model.Assets; using AssetFamily = DLCS.HydraModel.AssetFamily; -using DeliveryChannelPolicy = DLCS.Model.Policies.DeliveryChannelPolicy; namespace API.Tests.Converters; @@ -106,7 +103,6 @@ public void ToDlcsModel_All_Fields_Should_Convert() var origin = "https://example.org/origin"; var roles = new[] { "role1", "role2" }; var tags = new[] { "tag1", "tag2" }; - var deliveryChannel = new[] { "iiif-av", "iiif-img" }; var mediaType = "image/jpeg"; var thumbnailPolicy = "https://dlcs.io/thumbnailPolicies/thumb100"; @@ -135,7 +131,6 @@ public void ToDlcsModel_All_Fields_Should_Convert() MaxUnauthorised = 400, MediaType = mediaType, ThumbnailPolicy = thumbnailPolicy, - WcDeliveryChannels = deliveryChannel }; var asset = hydraImage.ToDlcsModel(1); @@ -159,80 +154,9 @@ public void ToDlcsModel_All_Fields_Should_Convert() asset.Reference3.Should().Be("3"); asset.Roles.Split(',').Should().BeEquivalentTo(roles); asset.Tags.Split(',').Should().BeEquivalentTo(tags); - asset.DeliveryChannels.Should().BeEquivalentTo(deliveryChannel); + asset.DeliveryChannels.Should().BeEmpty(); asset.MaxUnauthorised.Should().Be(400); asset.MediaType.Should().Be(mediaType); asset.ThumbnailPolicy.Should().Be("thumb100"); } - - [Fact] - public void ToDlcsModel_ReordersDeliveryChannel() - { - // Arrange - var deliveryChannel = new[] { "iiif-img", "file", "iiif-av" }; - - var hydraImage = new Image - { - Id = AssetApiId, - Space = 99, - WcDeliveryChannels = deliveryChannel - }; - - // Act - var asset = hydraImage.ToDlcsModel(1); - - // Assert - asset.DeliveryChannels.Should().BeInAscendingOrder(); - } - - [Fact] - public void ToHydraModel_Converts_ImageDeliveryChannels_To_WcDeliveryChannels() - { - // Arrange - var dlcsAssetId = new AssetId(0, 1, "test-asset"); - var dlcsAssetUrlRoot = new UrlRoots() - { - BaseUrl = "https://api.example.com/", - ResourceRoot = "https://resource.example.com/" - }; - var dlcsAsset = new Asset(dlcsAssetId) - { - Origin = "https://example-origin.com/my-image.jpeg", - ImageDeliveryChannels = new List() - { - new() - { - Channel = "iiif-img", - DeliveryChannelPolicy = new DeliveryChannelPolicy() - { - Name = "img-policy" - } - }, - new() - { - Channel = "thumbs", - DeliveryChannelPolicy = new DeliveryChannelPolicy() - { - Name = "thumbs-policy" - } - }, - new() - { - Channel = "file", - DeliveryChannelPolicy = new DeliveryChannelPolicy() - { - Name = "none", - } - } - } - }; - var assetPreparationResult = AssetPreparer.PrepareAssetForUpsert(null, dlcsAsset, false, - false, new []{' '}); - - // Act - var hydraAsset = assetPreparationResult.UpdatedAsset!.ToHydra(dlcsAssetUrlRoot, true); - - // Assert - hydraAsset.WcDeliveryChannels.Should().BeEquivalentTo("iiif-img", "file"); - } } \ No newline at end of file diff --git a/src/protagonist/API.Tests/Features/Images/Validation/HydraImageValidatorTests.cs b/src/protagonist/API.Tests/Features/Images/Validation/HydraImageValidatorTests.cs index ffc9658d4..eea7db29d 100644 --- a/src/protagonist/API.Tests/Features/Images/Validation/HydraImageValidatorTests.cs +++ b/src/protagonist/API.Tests/Features/Images/Validation/HydraImageValidatorTests.cs @@ -2,7 +2,6 @@ using API.Features.Image.Validation; using API.Settings; using DLCS.HydraModel; -using DLCS.Model.Policies; using FluentValidation.TestHelper; using Microsoft.Extensions.Options; @@ -14,7 +13,7 @@ public class HydraImageValidatorTests public HydraImageValidatorTests() { - var apiSettings = new ApiSettings() { DeliveryChannelsEnabled = true, RestrictedAssetIdCharacterString = "\\ "}; + var apiSettings = new ApiSettings() { RestrictedAssetIdCharacterString = "\\ "}; sut = new HydraImageValidator(Options.Create(apiSettings)); } @@ -46,36 +45,6 @@ public void Width_Provided() .ShouldHaveValidationErrorFor(a => a.Width) .WithErrorMessage("Should not include width"); } - - [Theory] - [InlineData("image/jpeg", "file,iiif-img")] - [InlineData("video/mp4", "file,iiif-av")] - [InlineData("audio/mp4", "file")] - public void Width_Provided_NotFileOnly_OrAudio(string mediaType, string dc) - { - var model = new Image - { - Width = 10, WcDeliveryChannels = dc.Split(","), MediaType = mediaType - }; - var result = sut.TestValidate(model); - result - .ShouldHaveValidationErrorFor(a => a.Width) - .WithErrorMessage("Should not include width"); - } - - [Theory] - [InlineData("image/jpeg")] - [InlineData("video/mp4")] - [InlineData("application/pdf")] - public void Width_Allowed_IfFileOnly_AndVideoOrImage(string mediaType) - { - var model = new Image - { - MediaType = mediaType, WcDeliveryChannels = new[] { "file" }, Width = 10 - }; - var result = sut.TestValidate(model); - result.ShouldNotHaveValidationErrorFor(a => a.Width); - } [Fact] public void Height_Provided() @@ -87,36 +56,6 @@ public void Height_Provided() .WithErrorMessage("Should not include height"); } - [Theory] - [InlineData("image/jpeg", "file,iiif-img")] - [InlineData("video/mp4", "file,iiif-av")] - [InlineData("audio/mp4", "file")] - public void Height_Provided_NotFileOnly_OrAudio(string mediaType, string dc) - { - var model = new Image - { - Height = 10, WcDeliveryChannels = dc.Split(","), MediaType = mediaType - }; - var result = sut.TestValidate(model); - result - .ShouldHaveValidationErrorFor(a => a.Height) - .WithErrorMessage("Should not include height"); - } - - [Theory] - [InlineData("image/jpeg")] - [InlineData("video/mp4")] - [InlineData("application/pdf")] - public void Height_Allowed_IfFileOnly_AndVideoOrImage(string mediaType) - { - var model = new Image - { - MediaType = mediaType, WcDeliveryChannels = new[] { "file" }, Height = 10 - }; - var result = sut.TestValidate(model); - result.ShouldNotHaveValidationErrorFor(a => a.Height); - } - [Fact] public void Duration_Provided() { @@ -126,37 +65,7 @@ public void Duration_Provided() .ShouldHaveValidationErrorFor(a => a.Duration) .WithErrorMessage("Should not include duration"); } - - [Theory] - [InlineData("image/jpeg", "file")] - [InlineData("video/mp4", "file,iiif-av")] - [InlineData("audio/mp4", "file,iiif-av")] - public void Duration_Provided_NotFileOnly_OrImage(string mediaType, string dc) - { - var model = new Image - { - Duration = 10, WcDeliveryChannels = dc.Split(","), MediaType = mediaType - }; - var result = sut.TestValidate(model); - result - .ShouldHaveValidationErrorFor(a => a.Duration) - .WithErrorMessage("Should not include duration"); - } - [Theory] - [InlineData("audio/mp4")] - [InlineData("video/mp4")] - [InlineData("application/pdf")] - public void Duration_Allowed_IfFileOnly_AndVideoOrAudio(string mediaType) - { - var model = new Image - { - MediaType = mediaType, WcDeliveryChannels = new[] { "file" }, Duration = 10 - }; - var result = sut.TestValidate(model); - result.ShouldNotHaveValidationErrorFor(a => a.Duration); - } - [Fact] public void Finished_Provided() { @@ -172,87 +81,6 @@ public void Created_Provided() var result = sut.TestValidate(model); result.ShouldHaveValidationErrorFor(a => a.Created); } - - [Theory] - [InlineData("file")] - [InlineData("file,iiif-av")] - [InlineData("iiif-av")] - public void UseOriginalPolicy_NotImage(string dc) - { - var model = new Image - { - WcDeliveryChannels = dc.Split(","), - MediaType = "image/jpeg", - ImageOptimisationPolicy = KnownImageOptimisationPolicy.UseOriginalId - }; - var result = sut.TestValidate(model); - result - .ShouldHaveValidationErrorFor(a => a.ImageOptimisationPolicy) - .WithErrorMessage("ImageOptimisationPolicy 'use-original' only valid for image delivery-channel"); - } - - [Theory] - [InlineData("iiif-img")] - [InlineData("file,iiif-img")] - public void UseOriginalPolicy_Image(string dc) - { - var model = new Image - { - WcDeliveryChannels = dc.Split(","), - MediaType = "image/jpeg", - ImageOptimisationPolicy = KnownImageOptimisationPolicy.UseOriginalId - }; - var result = sut.TestValidate(model); - result.ShouldNotHaveValidationErrorFor(a => a.ImageOptimisationPolicy); - } - - [Fact] - public void WcDeliveryChannel_CanBeEmpty() - { - var model = new Image(); - var result = sut.TestValidate(model); - result.ShouldNotHaveValidationErrorFor(a => a.WcDeliveryChannels); - } - - [Theory] - [InlineData("file")] - [InlineData("iiif-av")] - [InlineData("iiif-img")] - [InlineData("file,iiif-av,iiif-img")] - public void WcDeliveryChannel_CanContainKnownValues(string knownValues) - { - var model = new Image { WcDeliveryChannels = knownValues.Split(',') }; - var result = sut.TestValidate(model); - result.ShouldNotHaveValidationErrorFor(a => a.WcDeliveryChannels); - } - - [Fact] - public void WcDeliveryChannel_UnknownValue() - { - var model = new Image { WcDeliveryChannels = new[] { "foo" } }; - var result = sut.TestValidate(model); - result.ShouldHaveValidationErrorFor(a => a.WcDeliveryChannels); - } - - [Fact] - public void WcDeliveryChannel_ValidationError_WhenDeliveryChannelsDisabled() - { - var apiSettings = new ApiSettings(); - var imageValidator = new HydraImageValidator(Options.Create(apiSettings)); - var model = new Image { WcDeliveryChannels = new[] { "iiif-img" } }; - var result = imageValidator.TestValidate(model); - result.ShouldHaveValidationErrorFor(a => a.WcDeliveryChannels); - } - - [Fact] - public void WcDeliveryChannel_NoValidationError_WhenDeliveryChannelsDisabled() - { - var apiSettings = new ApiSettings(); - var imageValidator = new HydraImageValidator(Options.Create(apiSettings)); - var model = new Image(); - var result = imageValidator.TestValidate(model); - result.ShouldNotHaveValidationErrorFor(a => a.WcDeliveryChannels); - } [Fact] public void DeliveryChannel_ValidationError_DeliveryChannelMissingChannel() diff --git a/src/protagonist/API.Tests/Features/Images/Validation/ImageBatchPatchValidatorTests.cs b/src/protagonist/API.Tests/Features/Images/Validation/ImageBatchPatchValidatorTests.cs index f6f0d3bed..c34db2e8a 100644 --- a/src/protagonist/API.Tests/Features/Images/Validation/ImageBatchPatchValidatorTests.cs +++ b/src/protagonist/API.Tests/Features/Images/Validation/ImageBatchPatchValidatorTests.cs @@ -132,17 +132,6 @@ public void Member_MaxUnauthorised_Provided() result.ShouldHaveValidationErrorFor("Members[0].MaxUnauthorised"); } - [Fact] - public void Member_WcDeliveryChannels_Provided() - { - var model = new HydraCollection { Members = new[] - { - new Image { WcDeliveryChannels = new []{"iiif-img","thumbs"}} - } }; - var result = sut.TestValidate(model); - result.ShouldHaveValidationErrorFor("Members[0].WcDeliveryChannels"); - } - [Fact] public void Member_ThumbnailPolicy_Provided() { diff --git a/src/protagonist/API.Tests/Features/Queues/Validation/QueuePostValidatorTests.cs b/src/protagonist/API.Tests/Features/Queues/Validation/QueuePostValidatorTests.cs index 2083b7d81..e4711cfb9 100644 --- a/src/protagonist/API.Tests/Features/Queues/Validation/QueuePostValidatorTests.cs +++ b/src/protagonist/API.Tests/Features/Queues/Validation/QueuePostValidatorTests.cs @@ -10,12 +10,11 @@ namespace API.Tests.Features.Queues.Validation; public class QueuePostValidatorTests { - private QueuePostValidator GetSut(bool emulateOldDeliveryChannels) + private QueuePostValidator GetSut() { var apiSettings = new ApiSettings { - MaxBatchSize = 4, - EmulateOldDeliveryChannelProperties = emulateOldDeliveryChannels + MaxBatchSize = 4 }; return new QueuePostValidator(Options.Create(apiSettings)); @@ -24,7 +23,7 @@ private QueuePostValidator GetSut(bool emulateOldDeliveryChannels) [Fact] public void Members_Null() { - var sut = GetSut(false); + var sut = GetSut(); var model = new HydraCollection(); var result = sut.TestValidate(model); result.ShouldHaveValidationErrorFor(r => r.Members); @@ -33,7 +32,7 @@ public void Members_Null() [Fact] public void Members_Empty() { - var sut = GetSut(false); + var sut = GetSut(); var model = new HydraCollection { Members = Array.Empty() }; var result = sut.TestValidate(model); result.ShouldHaveValidationErrorFor(r => r.Members); @@ -42,7 +41,7 @@ public void Members_Empty() [Fact] public void Members_GreaterThanMaxBatchSize() { - var sut = GetSut(false); + var sut = GetSut(); var model = new HydraCollection { Members = new[] @@ -62,7 +61,7 @@ public void Members_GreaterThanMaxBatchSize() [Fact] public void Members_EqualMaxBatchSize_Valid() { - var sut = GetSut(false); + var sut = GetSut(); var model = new HydraCollection { Members = new[] @@ -80,7 +79,7 @@ public void Members_EqualMaxBatchSize_Valid() [Fact] public void Members_ContainsDuplicateIds() { - var sut = GetSut(false); + var sut = GetSut(); var model = new HydraCollection { Members = new[] @@ -102,7 +101,7 @@ public void Members_ContainsDuplicateIds() [InlineData(" ")] public void Member_ModelId_NullOrEmpty(string id) { - var sut = GetSut(false); + var sut = GetSut(); var model = new HydraCollection { Members = new[] { new Image { ModelId = id } } }; var result = sut.TestValidate(model); result.ShouldHaveValidationErrorFor("Members[0].ModelId"); @@ -111,7 +110,7 @@ public void Member_ModelId_NullOrEmpty(string id) [Fact] public void Member_Space_Default() { - var sut = GetSut(false); + var sut = GetSut(); var model = new HydraCollection { Members = new[] { new Image { Space = 0 } } }; var result = sut.TestValidate(model); result.ShouldHaveValidationErrorFor("Members[0].Space"); @@ -123,7 +122,7 @@ public void Member_Space_Default() [InlineData(" ")] public void Member_MediaType_NullOrEmpty(string mediaType) { - var sut = GetSut(false); + var sut = GetSut(); var model = new HydraCollection { Members = new[] { new Image { MediaType = mediaType } } }; var result = sut.TestValidate(model); result.ShouldHaveValidationErrorFor("Members[0].MediaType"); @@ -132,7 +131,7 @@ public void Member_MediaType_NullOrEmpty(string mediaType) [Fact] public void Member_Batch_Provided() { - var sut = GetSut(false); + var sut = GetSut(); var model = new HydraCollection { Members = new[] { new Image { Batch = "10" } } }; var result = sut.TestValidate(model); result.ShouldHaveValidationErrorFor("Members[0].Batch"); @@ -141,7 +140,7 @@ public void Member_Batch_Provided() [Fact] public void Member_Width_Provided() { - var sut = GetSut(false); + var sut = GetSut(); var model = new HydraCollection { Members = new[] { new Image { Width = 10 } } }; var result = sut.TestValidate(model); result @@ -152,7 +151,7 @@ public void Member_Width_Provided() [Fact] public void Member_Height_Provided() { - var sut = GetSut(false); + var sut = GetSut(); var model = new HydraCollection { Members = new[] { new Image { Height = 10 } } }; var result = sut.TestValidate(model); result @@ -163,7 +162,7 @@ public void Member_Height_Provided() [Fact] public void Member_Duration_Provided() { - var sut = GetSut(false); + var sut = GetSut(); var model = new HydraCollection { Members = new[] { new Image { Duration = 10 } } }; var result = sut.TestValidate(model); result @@ -174,7 +173,7 @@ public void Member_Duration_Provided() [Fact] public void Member_Finished_Provided() { - var sut = GetSut(false); + var sut = GetSut(); var model = new HydraCollection { Members = new[] { new Image { Finished = DateTime.Today } } }; var result = sut.TestValidate(model); result.ShouldHaveValidationErrorFor("Members[0].Finished"); @@ -183,45 +182,27 @@ public void Member_Finished_Provided() [Fact] public void Member_Created_Provided() { - var sut = GetSut(false); + var sut = GetSut(); var model = new HydraCollection { Members = new[] { new Image { Created = DateTime.Today } } }; var result = sut.TestValidate(model); result.ShouldHaveValidationErrorFor("Members[0].Created"); } [Fact] - public void Member_ImageOptimisationPolicy_Null_WhenOldDeliveryChannelEmulationDisabled() + public void Member_ImageOptimisationPolicy_Provided() { - var sut = GetSut(false); + var sut = GetSut(); var model = new HydraCollection { Members = new[] { new Image { ImageOptimisationPolicy = "my-policy" } } }; var result = sut.TestValidate(model); result.ShouldHaveValidationErrorFor("Members[0].ImageOptimisationPolicy"); } - + [Fact] - public void Member_ThumbnailPolicy_Null_WhenOldDeliveryChannelEmulationDisabled() + public void Member_ThumbnailPolicy_Provided() { - var sut = GetSut(false); + var sut = GetSut(); var model = new HydraCollection { Members = new[] { new Image { ThumbnailPolicy = "my-policy" } } }; var result = sut.TestValidate(model); result.ShouldHaveValidationErrorFor("Members[0].ThumbnailPolicy"); } - - [Fact] - public void Member_ImageOptimisationPolicy_Allowed_WhenOldDeliveryChannelEmulationEnabled() - { - var sut = GetSut(true); - var model = new HydraCollection { Members = new[] { new Image { ImageOptimisationPolicy = "my-policy" } } }; - var result = sut.TestValidate(model); - result.ShouldNotHaveValidationErrorFor("Members[0].ImageOptimisationPolicy"); - } - - [Fact] - public void Member_ThumbnailPolicy_Allowed_WhenOldDeliveryChannelEmulationEnabled() - { - var sut = GetSut(true); - var model = new HydraCollection { Members = new[] { new Image { ThumbnailPolicy = "my-policy" } } }; - var result = sut.TestValidate(model); - result.ShouldNotHaveValidationErrorFor("Members[0].ThumbnailPolicy"); - } } \ No newline at end of file diff --git a/src/protagonist/API.Tests/Integration/CustomerQueueTests.cs b/src/protagonist/API.Tests/Integration/CustomerQueueTests.cs index 433529ac9..8a66746c8 100644 --- a/src/protagonist/API.Tests/Integration/CustomerQueueTests.cs +++ b/src/protagonist/API.Tests/Integration/CustomerQueueTests.cs @@ -6,12 +6,10 @@ using System.Text; using System.Text.Json; using System.Threading; -using System.Threading.Tasks; using API.Client; using API.Tests.Integration.Infrastructure; using DLCS.Core.Types; using DLCS.Model.Assets; -using DLCS.Model.Messaging; using DLCS.Repository; using DLCS.Repository.Messaging; using FakeItEasy; @@ -42,7 +40,6 @@ public CustomerQueueTests(DlcsDatabaseFixture dbFixture, ProtagonistAppFactory { services.AddScoped(_ => EngineClient); @@ -760,7 +757,7 @@ public async Task Post_CreateBatch_400_IfSpaceNotFound() } [Fact] - public async Task Post_CreateBatch_400_IfThumbnailPolicySet_AndOldDeliveryChannelEmulationDisabled() + public async Task Post_CreateBatch_400_IfThumbnailPolicySet() { const int customerId = 15; const int space = 4; @@ -796,7 +793,7 @@ public async Task Post_CreateBatch_400_IfThumbnailPolicySet_AndOldDeliveryChanne } [Fact] - public async Task Post_CreateBatch_400_IfImageOptimisationPolicySet_AndOldDeliveryChannelEmulationDisabled() + public async Task Post_CreateBatch_400_IfImageOptimisationPolicySet() { const int customerId = 15; const int space = 4; @@ -1057,45 +1054,46 @@ public async Task Post_CreatePriorityBatch_UpdatesQueueAndCounts() const int customerId = 1900; await dbContext.Customers.AddTestCustomer(customerId); await dbContext.Spaces.AddTestSpace(customerId, 2); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customerId); await dbContext.CustomerStorages.AddTestCustomerStorage(customerId); await dbContext.SaveChangesAsync(); // a batch of 4 images - 1 with Family, 1 with DC, 1 with both, and 1 without var hydraImageBody = @"{ - ""@context"": ""http://www.w3.org/ns/hydra/context.jsonld"", - ""@type"": ""Collection"", - ""member"": [ - { - ""id"": ""one"", - ""origin"": ""https://example.org/foo.jpg"", - ""space"": 2, - ""wcDeliveryChannels"": [""iiif-img""], - ""family"": ""I"", - ""mediaType"": ""image/jpeg"" - }, - { - ""id"": ""two"", - ""origin"": ""https://example.org/foo.png"", - ""wcDeliveryChannels"": [""iiif-img""], - ""space"": 2, - ""mediaType"": ""image/png"" - }, - { - ""id"": ""three"", - ""origin"": ""https://example.org/foo.tiff"", - ""family"": ""I"", - ""space"": 2, - ""mediaType"": ""image/tiff"" - }, - { - ""id"": ""four"", - ""origin"": ""https://example.org/foo.tiff"", - ""space"": 2, - ""mediaType"": ""image/tiff"" - } - ] -}"; - + ""@context"": ""http://www.w3.org/ns/hydra/context.jsonld"", + ""@type"": ""Collection"", + ""member"": [ + { + ""id"": ""one"", + ""origin"": ""https://example.org/foo.jpg"", + ""space"": 2, + ""deliveryChannels"": [""iiif-img""], + ""family"": ""I"", + ""mediaType"": ""image/jpeg"" + }, + { + ""id"": ""two"", + ""origin"": ""https://example.org/foo.png"", + ""deliveryChannels"": [""iiif-img""], + ""space"": 2, + ""mediaType"": ""image/png"" + }, + { + ""id"": ""three"", + ""origin"": ""https://example.org/foo.tiff"", + ""family"": ""I"", + ""space"": 2, + ""mediaType"": ""image/tiff"" + }, + { + ""id"": ""four"", + ""origin"": ""https://example.org/foo.tiff"", + ""space"": 2, + ""mediaType"": ""image/tiff"" + } + ] + }"; + A.CallTo(() => EngineClient.AsynchronousIngestBatch( A>._, true, diff --git a/src/protagonist/API.Tests/Integration/CustomerQueueWithOldDeliveryChannelEmulationTests.cs b/src/protagonist/API.Tests/Integration/CustomerQueueWithOldDeliveryChannelEmulationTests.cs deleted file mode 100644 index f86955ec8..000000000 --- a/src/protagonist/API.Tests/Integration/CustomerQueueWithOldDeliveryChannelEmulationTests.cs +++ /dev/null @@ -1,322 +0,0 @@ -using System.Net; -using System.Net.Http; -using System.Text; -using API.Tests.Integration.Infrastructure; -using DLCS.Repository; -using DLCS.Repository.Assets; -using DLCS.Repository.Messaging; -using FakeItEasy; -using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Mvc.Testing; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Test.Helpers.Integration; -using Test.Helpers.Integration.Infrastructure; - -namespace API.Tests.Integration; - -[Trait("Category", "Integration")] -[Collection(CollectionDefinitions.DatabaseCollection.CollectionName)] -public class CustomerQueueWithOldDeliveryChannelEmulationTests : IClassFixture> -{ - private readonly DlcsContext dbContext; - private readonly HttpClient httpClient; - private static readonly IEngineClient EngineClient = A.Fake(); - - public CustomerQueueWithOldDeliveryChannelEmulationTests(DlcsDatabaseFixture dbFixture, ProtagonistAppFactory factory) - { - dbContext = dbFixture.DbContext; - httpClient = factory - .WithConnectionString(dbFixture.ConnectionString) - .WithConfigValue("DeliveryChannelsEnabled", "true") - .WithConfigValue("EmulateOldDeliveryChannelProperties", "true") - .WithTestServices(services => - { - services.AddScoped(_ => EngineClient); - services.AddAuthentication("API-Test") - .AddScheme( - "API-Test", _ => { }); - }) - .CreateClient(new WebApplicationFactoryClientOptions - { - AllowAutoRedirect = false - }); - dbFixture.CleanUp(); - } - - [Fact] - public async Task Post_CreateBatch_201_SupportsOldDeliveryChannelEmulation_ForImageChannel() - { - const int customerId = 99; - const int space = 1; - - // Arrange - var hydraImageBody = $@"{{ - ""@context"": ""http://www.w3.org/ns/hydra/context.jsonld"", - ""@type"": ""Collection"", - ""member"": [ - {{ - ""id"": ""{nameof(Post_CreateBatch_201_SupportsOldDeliveryChannelEmulation_ForImageChannel)}"", - ""origin"": ""https://example.org/img.tiff"", - ""space"": 1, - ""family"": ""I"", - ""mediaType"": ""image/tiff"", - ""wcDeliveryChannels"": [""iiif-img""] - }} - ] - }}"; - - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var path = $"/customers/{customerId}/queue"; - - // Act - var response = await httpClient.AsCustomer(customerId).PostAsync(path, content); - - // Assert - response.StatusCode.Should().Be(HttpStatusCode.Created); - - var assetInDatabase = await dbContext.Images - .IncludeDeliveryChannelsWithPolicy() - .SingleAsync(a => a.Customer == customerId && a.Space == space); - - assetInDatabase.ImageDeliveryChannels.Should().Satisfy( - dc => dc.Channel == "iiif-img" && dc.DeliveryChannelPolicy.Name == "default", - dc => dc.Channel == "thumbs" && dc.DeliveryChannelPolicy.Name == "default"); - } - - [Fact] - public async Task Post_CreateBatch_201_SupportsOldDeliveryChannelEmulation_ForImageChannel_WithUseOriginalPolicy() - { - const int customerId = 99; - const int space = 1; - - // Arrange - var hydraImageBody = $@"{{ - ""@context"": ""http://www.w3.org/ns/hydra/context.jsonld"", - ""@type"": ""Collection"", - ""member"": [ - {{ - ""id"": ""{nameof(Post_CreateBatch_201_SupportsOldDeliveryChannelEmulation_ForImageChannel_WithUseOriginalPolicy)}"", - ""origin"": ""https://example.org/img.tiff"", - ""space"": 1, - ""family"": ""I"", - ""mediaType"": ""image/tiff"", - ""imageOptimisationPolicy"": ""use-original"", - ""wcDeliveryChannels"": [""iiif-img""] - }} - ] - }}"; - - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var path = $"/customers/{customerId}/queue"; - - // Act - var response = await httpClient.AsCustomer(customerId).PostAsync(path, content); - - // Assert - response.StatusCode.Should().Be(HttpStatusCode.Created); - - var assetInDatabase = await dbContext.Images - .IncludeDeliveryChannelsWithPolicy() - .SingleAsync(a => a.Customer == customerId && a.Space == space); - - assetInDatabase.ImageDeliveryChannels.Should().Satisfy( - dc => dc.Channel == "iiif-img" && dc.DeliveryChannelPolicy.Name == "use-original", - dc => dc.Channel == "thumbs" && dc.DeliveryChannelPolicy.Name == "default"); - } - - [Fact] - public async Task Post_CreateBatch_201_SupportsOldDeliveryChannelEmulation_ForAvChannel_Video() - { - const int customerId = 99; - const int space = 1; - - // Arrange - var hydraImageBody = $@"{{ - ""@context"": ""http://www.w3.org/ns/hydra/context.jsonld"", - ""@type"": ""Collection"", - ""member"": [ - {{ - ""id"": ""{nameof(Post_CreateBatch_201_SupportsOldDeliveryChannelEmulation_ForAvChannel_Video)}"", - ""origin"": ""https://example.org/video.mp4"", - ""space"": 1, - ""family"": ""T"", - ""mediaType"": ""video/mp4"", - ""wcDeliveryChannels"": [""iiif-av""] - }} - ] - }}"; - - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var path = $"/customers/{customerId}/queue"; - - // Act - var response = await httpClient.AsCustomer(customerId).PostAsync(path, content); - - // Assert - response.StatusCode.Should().Be(HttpStatusCode.Created); - - var assetInDatabase = await dbContext.Images - .IncludeDeliveryChannelsWithPolicy() - .SingleAsync(a => a.Customer == customerId && a.Space == space); - - assetInDatabase.ImageDeliveryChannels.Should().Satisfy( - dc => dc.Channel == "iiif-av" && - dc.DeliveryChannelPolicy.Name == "default-video"); - } - - [Fact] - public async Task Post_CreateBatch_201_SupportsOldDeliveryChannelEmulation_ForAvChannel_Audio() - { - const int customerId = 99; - const int space = 1; - - // Arrange - var hydraImageBody = $@"{{ - ""@context"": ""http://www.w3.org/ns/hydra/context.jsonld"", - ""@type"": ""Collection"", - ""member"": [ - {{ - ""id"": ""{nameof(Post_CreateBatch_201_SupportsOldDeliveryChannelEmulation_ForAvChannel_Audio)}"", - ""origin"": ""https://example.org/audio.mp3"", - ""space"": 1, - ""family"": ""T"", - ""mediaType"": ""audio/mp3"", - ""wcDeliveryChannels"": [""iiif-av""] - }} - ] - }}"; - - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var path = $"/customers/{customerId}/queue"; - - // Act - var response = await httpClient.AsCustomer(customerId).PostAsync(path, content); - - // Assert - response.StatusCode.Should().Be(HttpStatusCode.Created); - - var assetInDatabase = await dbContext.Images - .IncludeDeliveryChannelsWithPolicy() - .SingleAsync(a => a.Customer == customerId && a.Space == space); - - assetInDatabase.ImageDeliveryChannels.Should().Satisfy( - dc => dc.Channel == "iiif-av" && - dc.DeliveryChannelPolicy.Name == "default-audio"); - } - - [Fact] - public async Task Post_CreateBatch_201_SupportsOldDeliveryChannelEmulation_ForFileChannel() - { - const int customerId = 99; - const int space = 1; - - // Arrange - var hydraImageBody = $@"{{ - ""@context"": ""http://www.w3.org/ns/hydra/context.jsonld"", - ""@type"": ""Collection"", - ""member"": [ - {{ - ""id"": ""{nameof(Post_CreateBatch_201_SupportsOldDeliveryChannelEmulation_ForFileChannel)}"", - ""origin"": ""https://example.org/vid.mp4"", - ""space"": 1, - ""family"": ""T"", - ""mediaType"": ""video/mp4"", - ""wcDeliveryChannels"": [""file""] - }} - ] - }}"; - - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var path = $"/customers/{customerId}/queue"; - - // Act - var response = await httpClient.AsCustomer(customerId).PostAsync(path, content); - - // Assert - response.StatusCode.Should().Be(HttpStatusCode.Created); - - var assetInDatabase = await dbContext.Images - .IncludeDeliveryChannelsWithPolicy() - .SingleAsync(a => a.Customer == customerId && a.Space == space); - - assetInDatabase.ImageDeliveryChannels.Should().Satisfy( - dc => dc.Channel == "file" && - dc.DeliveryChannelPolicy.Name == "none"); - } - - [Fact] - public async Task Post_CreateBatch_201_SupportsOldDeliveryChannelEmulation_ForMultipleChannels() - { - const int customerId = 99; - const int space = 1; - - // Arrange - var hydraImageBody = $@"{{ - ""@context"": ""http://www.w3.org/ns/hydra/context.jsonld"", - ""@type"": ""Collection"", - ""member"": [ - {{ - ""id"": ""{nameof(Post_CreateBatch_201_SupportsOldDeliveryChannelEmulation_ForMultipleChannels)}"", - ""origin"": ""https://example.org/img.tiff"", - ""space"": 1, - ""family"": ""I"", - ""mediaType"": ""image/tiff"", - ""wcDeliveryChannels"": [""iiif-img"",""file""] - }} - ] - }}"; - - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var path = $"/customers/{customerId}/queue"; - - // Act - var response = await httpClient.AsCustomer(customerId).PostAsync(path, content); - - // Assert - response.StatusCode.Should().Be(HttpStatusCode.Created); - - var assetInDatabase = await dbContext.Images - .IncludeDeliveryChannelsWithPolicy() - .SingleAsync(a => a.Customer == customerId && a.Space == space); - - assetInDatabase.ImageDeliveryChannels.Should().Satisfy( - dc => dc.Channel == "iiif-img" && - dc.DeliveryChannelPolicy.Name == "default", - dc => dc.Channel == "thumbs" && - dc.DeliveryChannelPolicy.Name == "default", - dc => dc.Channel == "file" && - dc.DeliveryChannelPolicy.Name == "none"); - } - - [Fact] - public async Task Post_CreateBatch_400_IfWcDeliveryChannelInvalid() - { - const int customerId = 99; - - // Arrange - var hydraImageBody = $@"{{ - ""@context"": ""http://www.w3.org/ns/hydra/context.jsonld"", - ""@type"": ""Collection"", - ""member"": [ - {{ - ""id"": ""{nameof(Post_CreateBatch_201_SupportsOldDeliveryChannelEmulation_ForFileChannel)}"", - ""origin"": ""https://example.org/vid.mp4"", - ""space"": 1, - ""family"": ""T"", - ""mediaType"": ""video/mp4"", - ""wcDeliveryChannels"": [""not-a-channel""] - }} - ] - }}"; - - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var path = $"/customers/{customerId}/queue"; - - // Act - var response = await httpClient.AsCustomer(customerId).PostAsync(path, content); - - // Assert - response.StatusCode.Should().Be(HttpStatusCode.BadRequest); - } -} \ No newline at end of file diff --git a/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs b/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs index 114c785f4..9a03845f2 100644 --- a/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs +++ b/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs @@ -63,7 +63,6 @@ public ModifyAssetTests( .AddScheme( "API-Test", _ => { }); }) - .WithConfigValue("DeliveryChannelsEnabled", "true") .CreateClient(new WebApplicationFactoryClientOptions { AllowAutoRedirect = false @@ -924,34 +923,6 @@ public async Task Put_New_Asset_Requires_Origin() response.StatusCode.Should().Be(HttpStatusCode.BadRequest); } - [Fact] - public async Task Put_New_Asset_Supports_WcDeliveryChannels() - { - var assetId = new AssetId(99, 1, nameof(Put_New_Asset_Supports_WcDeliveryChannels)); - var hydraImageBody = $@"{{ - ""@type"": ""Image"", - ""origin"": ""https://example.org/{assetId.Asset}.tiff"", - ""family"": ""I"", - ""mediaType"": ""image/tiff"", - ""wcDeliveryChannels"": [""file""] - }}"; - - A.CallTo(() => - EngineClient.SynchronousIngest( - A.That.Matches(r => r.Id == assetId), - A._)) - .Returns(HttpStatusCode.OK); - - // act - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(99).PutAsync(assetId.ToApiResourcePath(), content); - - // assert - response.StatusCode.Should().Be(HttpStatusCode.Created); - var asset = await dbContext.Images.FindAsync(assetId); - asset.DeliveryChannels.Should().BeEquivalentTo("file"); - } - [Fact] public async Task Put_Asset_Fails_When_ThumbnailPolicy_Is_Provided() { @@ -962,9 +933,6 @@ public async Task Put_Asset_Fails_When_ThumbnailPolicy_Is_Provided() ""mediaType"":""image/tiff"", ""origin"": ""https://example.org/{assetId.Asset}.tiff"", ""family"": ""I"", - ""wcDeliveryChannels"": [ - ""iiif-img"" - ], ""thumbnailPolicy"": ""thumbs-policy"" }}"; @@ -976,7 +944,7 @@ public async Task Put_Asset_Fails_When_ThumbnailPolicy_Is_Provided() response.StatusCode.Should().Be(HttpStatusCode.BadRequest); var body = await response.Content.ReadAsStringAsync(); - body.Should().Contain("ImageOptimisationPolicy and ThumbnailPolicy are disabled"); + body.Should().Contain("'ThumbnailPolicy' is disabled"); } [Fact] @@ -989,9 +957,7 @@ public async Task Put_Asset_Fails_When_ImageOptimisationPolicy_Is_Provided() ""mediaType"":""image/tiff"", ""origin"": ""https://example.org/{assetId.Asset}.tiff"", ""family"": ""I"", - ""wcDeliveryChannels"": [ - ""iiif-img"" - ], + ""deliveryChannels"": [""iiif-img""], ""imageOptimisationPolicy"": ""image-optimisation-policy"" }}"; @@ -1003,7 +969,7 @@ public async Task Put_Asset_Fails_When_ImageOptimisationPolicy_Is_Provided() response.StatusCode.Should().Be(HttpStatusCode.BadRequest); var body = await response.Content.ReadAsStringAsync(); - body.Should().Contain("ImageOptimisationPolicy and ThumbnailPolicy are disabled"); + body.Should().Contain("'ImageOptimisationPolicy' is disabled"); } [Fact] diff --git a/src/protagonist/API.Tests/Integration/ModifyAssetWithOldDeliveryChannelEmulationTests.cs b/src/protagonist/API.Tests/Integration/ModifyAssetWithOldDeliveryChannelEmulationTests.cs deleted file mode 100644 index 7f8c2f910..000000000 --- a/src/protagonist/API.Tests/Integration/ModifyAssetWithOldDeliveryChannelEmulationTests.cs +++ /dev/null @@ -1,584 +0,0 @@ -using System.Linq; -using System.Net; -using System.Net.Http; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using API.Infrastructure.Messaging; -using API.Tests.Integration.Infrastructure; -using DLCS.Core.Types; -using DLCS.Model.Assets; -using DLCS.Model.Policies; -using DLCS.Repository; -using DLCS.Repository.Messaging; -using FakeItEasy; -using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Mvc.Testing; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Test.Helpers.Integration; -using Test.Helpers.Integration.Infrastructure; -using AssetFamily = DLCS.HydraModel.AssetFamily; - -namespace API.Tests.Integration; - -[Trait("Category", "Integration")] -[Collection(StorageCollection.CollectionName)] -public class ModifyAssetWithOldDeliveryChannelEmulationTests : IClassFixture> -{ - private readonly DlcsContext dbContext; - private readonly HttpClient httpClient; - private static readonly IAssetNotificationSender NotificationSender = A.Fake(); - private static readonly IEngineClient EngineClient = A.Fake(); - - public ModifyAssetWithOldDeliveryChannelEmulationTests( - StorageFixture storageFixture, - ProtagonistAppFactory factory) - { - var dbFixture = storageFixture.DbFixture; - dbContext = dbFixture.DbContext; - - httpClient = factory - .WithConnectionString(dbFixture.ConnectionString) - .WithLocalStack(storageFixture.LocalStackFixture) - .WithTestServices(services => - { - services.AddSingleton(_ => NotificationSender); - services.AddScoped(_ => EngineClient); - services.AddAuthentication("API-Test") - .AddScheme( - "API-Test", _ => { }); - }) - .WithConfigValue("DeliveryChannelsEnabled", "true") - .WithConfigValue("EmulateOldDeliveryChannelProperties", "true") - .CreateClient(new WebApplicationFactoryClientOptions - { - AllowAutoRedirect = false - }); - - dbFixture.CleanUp(); - } - - [Theory] - [InlineData(AssetFamily.File, "application/pdf", "pdf", false)] - [InlineData(AssetFamily.Image, "image/tiff", "tiff", false)] - [InlineData(AssetFamily.Timebased, "video/mp4", "mp4", true)] - public async Task Put_New_Asset_Translates_FileWcDeliveryChannel(AssetFamily assetFamily, string mediaType, - string fileExtension, bool isIngestedAsync) - { - var assetId = new AssetId(99, 1, $"{nameof(Put_New_Asset_Translates_FileWcDeliveryChannel)}-${fileExtension}"); - var hydraImageBody = $@"{{ - ""@type"": ""Image"", - ""origin"": ""https://example.org/{assetId.Asset}.{fileExtension}"", - ""family"": ""{assetFamily}"", - ""mediaType"": ""{mediaType}"", - ""wcDeliveryChannels"": [""file""] - }}"; - - if (isIngestedAsync) - { - A.CallTo(() => - EngineClient.AsynchronousIngest( - A.That.Matches(r => r.Id == assetId), - A._)) - .Returns(true); - } - else - { - A.CallTo(() => - EngineClient.SynchronousIngest( - A.That.Matches(r => r.Id == assetId), - A._)) - .Returns(HttpStatusCode.OK); - } - - // act - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(99).PutAsync(assetId.ToApiResourcePath(), content); - - // assert - response.StatusCode.Should().Be(HttpStatusCode.Created); - - var asset = dbContext.Images.Include(i => i.ImageDeliveryChannels) - .ThenInclude(dc => dc.DeliveryChannelPolicy).Single(x => x.Id == assetId); - asset.ImageDeliveryChannels.Should().Satisfy( - dc => dc.Channel == "file" && - dc.DeliveryChannelPolicy.Name == "none"); - } - - [Fact] - public async Task Put_New_Asset_Translates_MultipleWcDeliveryChannels() - { - var assetId = new AssetId(99, 1, nameof(Put_New_Asset_Translates_MultipleWcDeliveryChannels)); - var hydraImageBody = $@"{{ - ""@type"": ""Image"", - ""origin"": ""https://example.org/{assetId.Asset}.tiff"", - ""family"": ""I"", - ""mediaType"": ""image/tiff"", - ""wcDeliveryChannels"": [""iiif-img"",""thumbs"",""file""] - }}"; - - A.CallTo(() => - EngineClient.SynchronousIngest( - A.That.Matches(r => r.Id == assetId), - A._)) - .Returns(HttpStatusCode.OK); - - // act - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(99).PutAsync(assetId.ToApiResourcePath(), content); - - // assert - response.StatusCode.Should().Be(HttpStatusCode.Created); - - var asset = dbContext.Images.Include(i => i.ImageDeliveryChannels) - .ThenInclude(dc => dc.DeliveryChannelPolicy).Single(x => x.Id == assetId); - asset.ImageDeliveryChannels.Should().Satisfy( - dc => dc.Channel == "iiif-img" && - dc.DeliveryChannelPolicy.Name == "default", - dc => dc.Channel == "thumbs" && - dc.DeliveryChannelPolicy.Name == "default", - dc => dc.Channel == "file" && - dc.DeliveryChannelPolicy.Name == "none"); - } - - [Fact] - public async Task Put_New_Asset_Translates_ImageWcDeliveryChannel() - { - var assetId = new AssetId(99, 1, nameof(Put_New_Asset_Translates_ImageWcDeliveryChannel)); - var hydraImageBody = $@"{{ - ""@type"": ""Image"", - ""origin"": ""https://example.org/{assetId.Asset}.tiff"", - ""family"": ""I"", - ""mediaType"": ""image/tiff"", - ""wcDeliveryChannels"": [""iiif-img""] - }}"; - - A.CallTo(() => - EngineClient.SynchronousIngest( - A.That.Matches(r => r.Id == assetId), - A._)) - .Returns(HttpStatusCode.OK); - - // act - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(99).PutAsync(assetId.ToApiResourcePath(), content); - - // assert - response.StatusCode.Should().Be(HttpStatusCode.Created); - - var asset = dbContext.Images.Include(i => i.ImageDeliveryChannels) - .ThenInclude(dc => dc.DeliveryChannelPolicy).Single(x => x.Id == assetId); - asset.ImageDeliveryChannels.Should().Satisfy( - dc => dc.Channel == "iiif-img" && dc.DeliveryChannelPolicy.Name == "default", - dc => dc.Channel == "thumbs" && dc.DeliveryChannelPolicy.Name == "default"); - } - - [Fact] - public async Task Put_New_Asset_Translates_ImageWcDeliveryChannel_WithUseOriginalPolicy() - { - var assetId = new AssetId(99, 1, nameof(Put_New_Asset_Translates_ImageWcDeliveryChannel_WithUseOriginalPolicy)); - var hydraImageBody = $@"{{ - ""@type"": ""Image"", - ""origin"": ""https://example.org/{assetId.Asset}.tiff"", - ""family"": ""I"", - ""mediaType"": ""image/tiff"", - ""imageOptimisationPolicy"": ""use-original"", - ""wcDeliveryChannels"": [""iiif-img""] - }}"; - - A.CallTo(() => - EngineClient.SynchronousIngest( - A.That.Matches(r => r.Id == assetId), - A._)) - .Returns(HttpStatusCode.OK); - - // act - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(99).PutAsync(assetId.ToApiResourcePath(), content); - - // assert - response.StatusCode.Should().Be(HttpStatusCode.Created); - - var asset = dbContext.Images.Include(i => i.ImageDeliveryChannels) - .ThenInclude(dc => dc.DeliveryChannelPolicy).Single(x => x.Id == assetId); - asset.ImageDeliveryChannels.Should().Satisfy( - dc => dc.Channel == "iiif-img" && dc.DeliveryChannelPolicy.Name == "use-original", - dc => dc.Channel == "thumbs" && dc.DeliveryChannelPolicy.Name == "default"); - } - - [Fact] - public async Task Put_New_Asset_Translates_AvWcDeliveryChannel_Video() - { - var assetId = new AssetId(99, 1, nameof(Put_New_Asset_Translates_AvWcDeliveryChannel_Video)); - var hydraImageBody = $@"{{ - ""@type"": ""Image"", - ""origin"": ""https://example.org/{assetId.Asset}.mp4"", - ""family"": ""T"", - ""mediaType"": ""video/mp4"", - ""wcDeliveryChannels"": [""iiif-av""] - }}"; - - A.CallTo(() => - EngineClient.AsynchronousIngest( - A.That.Matches(r => r.Id == assetId), - A._)) - .Returns(true); - - // act - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(99).PutAsync(assetId.ToApiResourcePath(), content); - - // assert - response.StatusCode.Should().Be(HttpStatusCode.Created); - - var asset = dbContext.Images.Include(i => i.ImageDeliveryChannels) - .ThenInclude(dc => dc.DeliveryChannelPolicy).Single(x => x.Id == assetId); - asset.ImageDeliveryChannels.Should().Satisfy( - dc => dc.Channel == "iiif-av" && - dc.DeliveryChannelPolicy.Name == "default-video"); - } - - [Fact] - public async Task Put_New_Asset_Translates_AvWcDeliveryChannel_Audio() - { - var assetId = new AssetId(99, 1, nameof(Put_New_Asset_Translates_AvWcDeliveryChannel_Audio)); - var hydraImageBody = $@"{{ - ""@type"": ""Image"", - ""origin"": ""https://example.org/{assetId.Asset}.mp3"", - ""family"": ""T"", - ""mediaType"": ""audio/mp3"", - ""wcDeliveryChannels"": [""iiif-av""] - }}"; - - A.CallTo(() => - EngineClient.AsynchronousIngest( - A.That.Matches(r => r.Id == assetId), - A._)) - .Returns(true); - - // act - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(99).PutAsync(assetId.ToApiResourcePath(), content); - - // assert - response.StatusCode.Should().Be(HttpStatusCode.Created); - - var asset = dbContext.Images.Include(i => i.ImageDeliveryChannels) - .ThenInclude(dc => dc.DeliveryChannelPolicy).Single(x => x.Id == assetId); - asset.ImageDeliveryChannels.Should().Satisfy( - dc => dc.Channel == "iiif-av" && - dc.DeliveryChannelPolicy.Name == "default-audio"); - } - - [Fact] - public async Task Put_New_Asset_BadRequest_IfWcDeliveryChannelInvalid() - { - var assetId = new AssetId(99, 1, nameof(Put_New_Asset_BadRequest_IfWcDeliveryChannelInvalid)); - var hydraImageBody = $@"{{ - ""@type"": ""Image"", - ""origin"": ""https://example.org/{assetId.Asset}.mp3"", - ""family"": ""T"", - ""mediaType"": ""audio/mp3"", - ""wcDeliveryChannels"": [""not-a-channel""] - }}"; - - A.CallTo(() => - EngineClient.AsynchronousIngest( - A.That.Matches(r => r.Id == assetId), - A._)) - .Returns(true); - - // act - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(99).PutAsync(assetId.ToApiResourcePath(), content); - - // assert - response.StatusCode.Should().Be(HttpStatusCode.BadRequest); - } - - [Theory] - [InlineData(DLCS.Model.Assets.AssetFamily.File, "application/pdf", "pdf", false)] - [InlineData(DLCS.Model.Assets.AssetFamily.Image, "image/tiff", "tiff", false)] - [InlineData(DLCS.Model.Assets.AssetFamily.Timebased, "video/mp4", "mp4", true)] - public async Task Patch_Asset_Translates_FileWcDeliveryChannel(DLCS.Model.Assets.AssetFamily assetFamily, string mediaType, - string fileExtension, bool isIngestedAsync) - { - var assetId = new AssetId(99, 1, $"{nameof(Patch_Asset_Translates_FileWcDeliveryChannel)}-${fileExtension}"); - var hydraImageBody = @"{ - ""wcDeliveryChannels"": [""file""] - }"; - - await dbContext.Images.AddTestAsset(assetId, origin: $"https://example.org/{assetId.Asset}.{fileExtension}", - mediaType: mediaType, family: assetFamily); - await dbContext.SaveChangesAsync(); - - if (isIngestedAsync) - { - A.CallTo(() => - EngineClient.AsynchronousIngest( - A.That.Matches(r => r.Id == assetId), - A._)) - .Returns(true); - } - else - { - A.CallTo(() => - EngineClient.SynchronousIngest( - A.That.Matches(r => r.Id == assetId), - A._)) - .Returns(HttpStatusCode.OK); - } - - // act - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(99).PatchAsync(assetId.ToApiResourcePath(), content); - - // assert - response.StatusCode.Should().Be(HttpStatusCode.OK); - - var asset = dbContext.Images.Include(i => i.ImageDeliveryChannels) - .ThenInclude(dc => dc.DeliveryChannelPolicy).Single(x => x.Id == assetId); - asset.ImageDeliveryChannels.Should().Satisfy( - dc => dc.Channel == "file" && - dc.DeliveryChannelPolicy.Name == "none"); - } - - [Fact] - public async Task Patch_Asset_Translates_MultipleWcDeliveryChannels() - { - var assetId = new AssetId(99, 1, nameof(Patch_Asset_Translates_MultipleWcDeliveryChannels)); - var hydraImageBody = @"{ - ""wcDeliveryChannels"": [""iiif-img"",""thumbs"",""file""] - }"; - - await dbContext.Images.AddTestAsset(assetId, origin: $"https://example.org/{assetId.Asset}.tiff", - mediaType: "image/tiff", family: DLCS.Model.Assets.AssetFamily.Image); - await dbContext.SaveChangesAsync(); - - A.CallTo(() => - EngineClient.SynchronousIngest( - A.That.Matches(r => r.Id == assetId), - A._)) - .Returns(HttpStatusCode.OK); - - // act - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(99).PatchAsync(assetId.ToApiResourcePath(), content); - - // assert - response.StatusCode.Should().Be(HttpStatusCode.OK); - - var asset = dbContext.Images.Include(i => i.ImageDeliveryChannels) - .ThenInclude(dc => dc.DeliveryChannelPolicy).Single(x => x.Id == assetId); - asset.ImageDeliveryChannels.Should().Satisfy( - dc => dc.Channel == "iiif-img" && - dc.DeliveryChannelPolicy.Name == "default", - dc => dc.Channel == "thumbs" && - dc.DeliveryChannelPolicy.Name == "default", - dc => dc.Channel == "file" && - dc.DeliveryChannelPolicy.Name == "none"); - } - - [Fact] - public async Task Patch_Asset_Translates_ImageWcDeliveryChannel() - { - var assetId = new AssetId(99, 1, nameof(Patch_Asset_Translates_ImageWcDeliveryChannel)); - var hydraImageBody = @"{ - ""wcDeliveryChannels"": [""iiif-img""] - }"; - - await dbContext.Images.AddTestAsset(assetId, origin: $"https://example.org/{assetId.Asset}.tiff", - mediaType: "image/tiff", family: DLCS.Model.Assets.AssetFamily.Image); - await dbContext.SaveChangesAsync(); - - A.CallTo(() => - EngineClient.SynchronousIngest( - A.That.Matches(r => r.Id == assetId), - A._)) - .Returns(HttpStatusCode.OK); - - // act - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(99).PatchAsync(assetId.ToApiResourcePath(), content); - - // assert - response.StatusCode.Should().Be(HttpStatusCode.OK); - - var asset = dbContext.Images.Include(i => i.ImageDeliveryChannels) - .ThenInclude(dc => dc.DeliveryChannelPolicy).Single(x => x.Id == assetId); - asset.ImageDeliveryChannels.Should().Satisfy( - dc => dc.Channel == "iiif-img" && dc.DeliveryChannelPolicy.Name == "default", - dc => dc.Channel == "thumbs" && dc.DeliveryChannelPolicy.Name == "default"); - } - - [Fact] - public async Task Patch_Asset_Translates_ImageWcDeliveryChannel_WithUseOriginalPolicy() - { - var assetId = new AssetId(99, 1, nameof(Patch_Asset_Translates_ImageWcDeliveryChannel_WithUseOriginalPolicy)); - var hydraImageBody = @"{ - ""imageOptimisationPolicy"": ""use-original"", - ""wcDeliveryChannels"": [""iiif-img""] - }"; - - await dbContext.Images.AddTestAsset(assetId, origin: $"https://example.org/{assetId.Asset}.tiff", - mediaType: "image/tiff", family: DLCS.Model.Assets.AssetFamily.Image); - await dbContext.SaveChangesAsync(); - - A.CallTo(() => - EngineClient.SynchronousIngest( - A.That.Matches(r => r.Id == assetId), - A._)) - .Returns(HttpStatusCode.OK); - - // act - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(99).PatchAsync(assetId.ToApiResourcePath(), content); - - // assert - response.StatusCode.Should().Be(HttpStatusCode.OK); - - var asset = dbContext.Images.Include(i => i.ImageDeliveryChannels) - .ThenInclude(dc => dc.DeliveryChannelPolicy).Single(x => x.Id == assetId); - asset.ImageDeliveryChannels.Should().Satisfy( - dc => dc.Channel == "iiif-img" && dc.DeliveryChannelPolicy.Name == "use-original", - dc => dc.Channel == "thumbs" && dc.DeliveryChannelPolicy.Name == "default"); - } - - [Fact] - public async Task Patch_Asset_Translates_AvWcDeliveryChannel_Video() - { - var assetId = new AssetId(99, 1, nameof(Patch_Asset_Translates_AvWcDeliveryChannel_Video)); - var hydraImageBody = $@"{{ - ""@type"": ""Image"", - ""origin"": ""https://example.org/{assetId.Asset}.mp4"", - ""family"": ""T"", - ""mediaType"": ""video/mp4"", - ""wcDeliveryChannels"": [""iiif-av""] - }}"; - - await dbContext.Images.AddTestAsset(assetId, origin: $"https://example.org/{assetId.Asset}.mp3", - mediaType: "video/mp4", family: DLCS.Model.Assets.AssetFamily.Timebased); - await dbContext.SaveChangesAsync(); - - A.CallTo(() => - EngineClient.AsynchronousIngest( - A.That.Matches(r => r.Id == assetId), - A._)) - .Returns(true); - - // act - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(99).PatchAsync(assetId.ToApiResourcePath(), content); - - // assert - response.StatusCode.Should().Be(HttpStatusCode.OK); - - var asset = dbContext.Images.Include(i => i.ImageDeliveryChannels) - .ThenInclude(dc => dc.DeliveryChannelPolicy).Single(x => x.Id == assetId); - asset.ImageDeliveryChannels.Should().Satisfy( - dc => dc.Channel == "iiif-av" && - dc.DeliveryChannelPolicy.Name == "default-video"); - } - - [Fact] - public async Task Patch_Asset_Translates_AvWcDeliveryChannel_Audio() - { - var assetId = new AssetId(99, 1, nameof(Patch_Asset_Translates_AvWcDeliveryChannel_Audio)); - var hydraImageBody = $@"{{ - ""wcDeliveryChannels"": [""iiif-av""] - }}"; - - await dbContext.Images.AddTestAsset(assetId, origin: $"https://example.org/{assetId.Asset}.mp3", - mediaType: "audio/mp3", family: DLCS.Model.Assets.AssetFamily.Timebased); - await dbContext.SaveChangesAsync(); - - A.CallTo(() => - EngineClient.AsynchronousIngest( - A.That.Matches(r => r.Id == assetId), - A._)) - .Returns(true); - - // act - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(99).PatchAsync(assetId.ToApiResourcePath(), content); - - // assert - response.StatusCode.Should().Be(HttpStatusCode.OK); - - var asset = dbContext.Images.Include(i => i.ImageDeliveryChannels) - .ThenInclude(dc => dc.DeliveryChannelPolicy).Single(x => x.Id == assetId); - asset.ImageDeliveryChannels.Should().Satisfy( - dc => dc.Channel == "iiif-av" && - dc.DeliveryChannelPolicy.Name == "default-audio"); - } - - [Fact] - public async Task Patch_Asset_BadRequest_IfWcDeliveryChannelInvalid() - { - var assetId = new AssetId(99, 1, nameof(Patch_Asset_BadRequest_IfWcDeliveryChannelInvalid)); - var hydraImageBody = @"{ - ""wcDeliveryChannels"": [""not-a-channel""] - }"; - - await dbContext.Images.AddTestAsset(assetId, origin: $"https://example.org/{assetId.Asset}.mp3", - mediaType: "audio/mp3", family: DLCS.Model.Assets.AssetFamily.Timebased); - await dbContext.SaveChangesAsync(); - - A.CallTo(() => - EngineClient.AsynchronousIngest( - A.That.Matches(r => r.Id == assetId), - A._)) - .Returns(true); - - // act - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(99).PatchAsync(assetId.ToApiResourcePath(), content); - - // assert - response.StatusCode.Should().Be(HttpStatusCode.BadRequest); - } - - [Fact] - public async Task Patch_Asset_Change_ImageOptimisationPolicy_Allowed() - { - var assetId = new AssetId(99, 1, nameof(Patch_Asset_Change_ImageOptimisationPolicy_Allowed)); - - var asset = (await dbContext.Images.AddTestAsset(assetId, origin: "https://images.org/image1.tiff")).Entity; - var testPolicy = new ImageOptimisationPolicy - { - Id = "test-policy", - Name = "Test Policy", - TechnicalDetails = new[] { "1010101" } - }; - dbContext.ImageOptimisationPolicies.Add(testPolicy); - await dbContext.SaveChangesAsync(); - - var hydraImageBody = $@"{{ - ""@type"": ""Image"", - ""imageOptimisationPolicy"": ""http://localhost/imageOptimisationPolicies/test-policy"" - }}"; - - A.CallTo(() => - EngineClient.SynchronousIngest( - A.That.Matches(r => r.Id == assetId), - A._)) - .Returns(HttpStatusCode.OK); - - // act - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(99).PatchAsync(assetId.ToApiResourcePath(), content); - - // assert - A.CallTo(() => - EngineClient.SynchronousIngest( - A.That.Matches(r => r.Id == assetId), - A._)) - .MustHaveHappened(); - - response.StatusCode.Should().Be(HttpStatusCode.OK); - - await dbContext.Entry(asset).ReloadAsync(); - asset.ImageOptimisationPolicy.Should().Be("test-policy"); - } -} \ No newline at end of file diff --git a/src/protagonist/API.Tests/Integration/ModifyAssetWithoutDeliveryChannelsTests.cs b/src/protagonist/API.Tests/Integration/ModifyAssetWithoutDeliveryChannelsTests.cs deleted file mode 100644 index 6f43ad192..000000000 --- a/src/protagonist/API.Tests/Integration/ModifyAssetWithoutDeliveryChannelsTests.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System.Net; -using System.Net.Http; -using System.Text; -using System.Threading.Tasks; -using DLCS.Core.Types; -using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Mvc.Testing; -using Microsoft.Extensions.DependencyInjection; -using Test.Helpers.Integration; -using Test.Helpers.Integration.Infrastructure; - -namespace API.Tests.Integration; - -[Trait("Category", "Integration")] -public class ModifyAssetWithoutDeliveryChannelsTests : IClassFixture> -{ - private readonly HttpClient httpClient; - - public ModifyAssetWithoutDeliveryChannelsTests( - ProtagonistAppFactory factory) - { - httpClient = factory - .WithTestServices(services => - { - services.AddAuthentication("API-Test") - .AddScheme( - "API-Test", _ => { }); - }) - .CreateClient(new WebApplicationFactoryClientOptions - { - AllowAutoRedirect = false - }); - } - - [Fact] - public async Task Patch_Asset_Fails_When_Delivery_Channels_Are_Disabled() - { - // Arrange - var assetId = new AssetId(99, 1, $"{nameof(Patch_Asset_Fails_When_Delivery_Channels_Are_Disabled)}"); - var hydraImageBody = $@"{{ - ""@type"": ""Image"", - ""string1"": ""I am edited"", - ""wcDeliveryChannels"": [ - ""iiif-img"" - ] - }}"; - - // Act - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(99).PatchAsync(assetId.ToApiResourcePath(), content); - - // Assert - response.StatusCode.Should().Be(HttpStatusCode.BadRequest); - - var body = await response.Content.ReadAsStringAsync(); - body.Should().Contain("Delivery channels are disabled"); - } -} \ No newline at end of file diff --git a/src/protagonist/API/Converters/AssetConverter.cs b/src/protagonist/API/Converters/AssetConverter.cs index 13c93df44..584a492cb 100644 --- a/src/protagonist/API/Converters/AssetConverter.cs +++ b/src/protagonist/API/Converters/AssetConverter.cs @@ -22,7 +22,6 @@ public static class AssetConverter /// /// /// The domain name of the API and orchestrator applications - /// Includes delivery channels in the old format in the returned model /// public static Image ToHydra(this Asset dbAsset, UrlRoots urlRoots) { @@ -415,15 +414,4 @@ public static ImageQuery ToImageQuery(this AssetFilter assetFilter) return assetFilter; } - - /// - /// Converts ImageDeliveryChannels into the old format (WcDeliveryChannels) - /// - private static string[] ConvertImageDeliveryChannelsToWc(ICollection imageDeliveryChannels) - { - return imageDeliveryChannels.Select(dc => dc.Channel) - // The thumbs channel should not be included when emulating the old delivery channel format - .Where(dc => dc != AssetDeliveryChannels.Thumbnails) - .ToArray(); - } } \ No newline at end of file diff --git a/src/protagonist/API/Features/Image/Validation/HydraImageValidator.cs b/src/protagonist/API/Features/Image/Validation/HydraImageValidator.cs index 0b1aa75d4..ea3816c84 100644 --- a/src/protagonist/API/Features/Image/Validation/HydraImageValidator.cs +++ b/src/protagonist/API/Features/Image/Validation/HydraImageValidator.cs @@ -31,6 +31,9 @@ public HydraImageValidator(IOptions apiSettings) When(a => !a.DeliveryChannels.IsNullOrEmpty(), ImageDeliveryChannelDependantValidation); // System edited fields + RuleFor(a => a.Width).Empty().WithMessage("Should not include width"); + RuleFor(a => a.Height).Empty().WithMessage("Should not include height"); + RuleFor(a => a.Duration).Empty().WithMessage("Should not include duration"); RuleFor(a => a.Batch).Empty().WithMessage("Should not include batch"); RuleFor(a => a.Finished).Empty().WithMessage("Should not include finished"); RuleFor(a => a.Created).Empty().WithMessage("Should not include created"); From bb63a298339ea5d2ba3d6343a06fb4877777cc3a Mon Sep 17 00:00:00 2001 From: griffri Date: Wed, 29 May 2024 09:06:01 +0100 Subject: [PATCH 03/30] Update EmulateOldDeliveryChannelProperties summary, reject IOP/TP in HydraImageValidator if legacy disabled --- src/protagonist/API/Features/Image/ImageController.cs | 6 ------ .../Features/Image/Validation/HydraImageValidator.cs | 11 +++++++++++ src/protagonist/API/Settings/ApiSettings.cs | 6 +++--- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/protagonist/API/Features/Image/ImageController.cs b/src/protagonist/API/Features/Image/ImageController.cs index b76da9c80..2456b6279 100644 --- a/src/protagonist/API/Features/Image/ImageController.cs +++ b/src/protagonist/API/Features/Image/ImageController.cs @@ -100,12 +100,6 @@ public async Task PutImage( hydraAsset = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraAsset); } - if(hydraAsset.ImageOptimisationPolicy != null || hydraAsset.ThumbnailPolicy != null) - { - return this.HydraProblem("ImageOptimisationPolicy and ThumbnailPolicy are disabled", null, - 400, "Bad Request"); - } - if (hydraAsset.ModelId == null) { hydraAsset.ModelId = imageId; diff --git a/src/protagonist/API/Features/Image/Validation/HydraImageValidator.cs b/src/protagonist/API/Features/Image/Validation/HydraImageValidator.cs index ea3816c84..379210282 100644 --- a/src/protagonist/API/Features/Image/Validation/HydraImageValidator.cs +++ b/src/protagonist/API/Features/Image/Validation/HydraImageValidator.cs @@ -30,6 +30,17 @@ public HydraImageValidator(IOptions apiSettings) When(a => !a.DeliveryChannels.IsNullOrEmpty(), ImageDeliveryChannelDependantValidation); + // Legacy policy fields + RuleFor(a => a.ImageOptimisationPolicy) + .Null() + .When(_ => !apiSettings.Value.EmulateOldDeliveryChannelProperties) + .WithMessage("'ImageOptimisationPolicy' is disabled"); + + RuleFor(a => a.ThumbnailPolicy) + .Null() + .When(_ => !apiSettings.Value.EmulateOldDeliveryChannelProperties) + .WithMessage("'ThumbnailPolicy' is disabled"); + // System edited fields RuleFor(a => a.Width).Empty().WithMessage("Should not include width"); RuleFor(a => a.Height).Empty().WithMessage("Should not include height"); diff --git a/src/protagonist/API/Settings/ApiSettings.cs b/src/protagonist/API/Settings/ApiSettings.cs index d2979625d..483075231 100644 --- a/src/protagonist/API/Settings/ApiSettings.cs +++ b/src/protagonist/API/Settings/ApiSettings.cs @@ -106,8 +106,8 @@ public string RestrictedAssetIdCharacterString } /// - /// Whether incoming old delivery channel properties (e.g wcDeliveryChannels, imageOptimisationPolicy, - /// thumbnailPolicy) are supported and translated into the new format + /// Whether old delivery channel properties (e.g imageOptimisationPolicy, thumbnailPolicy) + /// on legacy payloads are supported and translated into the new format /// - public bool EmulateOldDeliveryChannelProperties { get; set; } = false; + public bool EmulateOldDeliveryChannelProperties { get; set; } } \ No newline at end of file From 9e8de2b9e7f695efd3768e467a946f3055daaa3d Mon Sep 17 00:00:00 2001 From: Donald Gray Date: Wed, 29 May 2024 09:24:39 +0100 Subject: [PATCH 04/30] Reinstate INSERT to migrateImageDeliveryChannels script --- scripts/DeliveryChannels/0002-migrateImageDeliveryChannels.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/DeliveryChannels/0002-migrateImageDeliveryChannels.sql b/scripts/DeliveryChannels/0002-migrateImageDeliveryChannels.sql index 8062c129a..dfe6587d8 100644 --- a/scripts/DeliveryChannels/0002-migrateImageDeliveryChannels.sql +++ b/scripts/DeliveryChannels/0002-migrateImageDeliveryChannels.sql @@ -32,6 +32,7 @@ WHERE i."Family" = 'I' AND i."NotForDelivery" = false; -- convert timebased +INSERT INTO "ImageDeliveryChannels" ("ImageId", "Channel", "DeliveryChannelPolicyId") SELECT i."Id", 'iiif-av', CASE From 022beabd90e2cbe2c7271e8f40c4b6a1085a0189 Mon Sep 17 00:00:00 2001 From: griffri Date: Wed, 29 May 2024 11:39:19 +0100 Subject: [PATCH 05/30] Remove ImageOptimisationPolicy/ThumbnailPolicy check from PATCH image --- src/protagonist/API/Features/Image/ImageController.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/protagonist/API/Features/Image/ImageController.cs b/src/protagonist/API/Features/Image/ImageController.cs index 2456b6279..cddaab18d 100644 --- a/src/protagonist/API/Features/Image/ImageController.cs +++ b/src/protagonist/API/Features/Image/ImageController.cs @@ -155,12 +155,6 @@ public async Task PatchImage( [FromServices] HydraImageValidator validator, CancellationToken cancellationToken) { - if(hydraAsset.ImageOptimisationPolicy != null || hydraAsset.ThumbnailPolicy != null) - { - return this.HydraProblem("ImageOptimisationPolicy and ThumbnailPolicy are disabled", null, - 400, "Bad Request"); - } - var validationResult = await validator.ValidateAsync(hydraAsset, strategy => strategy.IncludeRuleSets("default", "patch"), cancellationToken); if (!validationResult.IsValid) From ad5b31f9d4e0a71eb3b2b2384b5da9a1a50474c3 Mon Sep 17 00:00:00 2001 From: griffri Date: Wed, 29 May 2024 12:57:48 +0100 Subject: [PATCH 06/30] Add tests for EmulateOldDeliveryChannelProperties in QueuePostValidator + HydraImageValidator Update expected IOP/TP response messages in ModifyAssetTests --- .../Validation/HydraImageValidatorTests.cs | 103 +++++++++++++----- .../Validation/QueuePostValidatorTests.cs | 21 +++- .../API.Tests/Integration/ModifyAssetTests.cs | 4 +- .../Queues/Validation/QueuePostValidator.cs | 6 +- 4 files changed, 103 insertions(+), 31 deletions(-) diff --git a/src/protagonist/API.Tests/Features/Images/Validation/HydraImageValidatorTests.cs b/src/protagonist/API.Tests/Features/Images/Validation/HydraImageValidatorTests.cs index eea7db29d..7c09d77cd 100644 --- a/src/protagonist/API.Tests/Features/Images/Validation/HydraImageValidatorTests.cs +++ b/src/protagonist/API.Tests/Features/Images/Validation/HydraImageValidatorTests.cs @@ -9,20 +9,24 @@ namespace API.Tests.Features.Images.Validation; public class HydraImageValidatorTests { - private readonly HydraImageValidator sut; - - public HydraImageValidatorTests() + public HydraImageValidator GetSut(bool emulateOldDeliveryChannelProperties = false) { - var apiSettings = new ApiSettings() { RestrictedAssetIdCharacterString = "\\ "}; - sut = new HydraImageValidator(Options.Create(apiSettings)); + var apiSettings = new ApiSettings() + { + RestrictedAssetIdCharacterString = "\\ ", + EmulateOldDeliveryChannelProperties = emulateOldDeliveryChannelProperties + }; + return new HydraImageValidator(Options.Create(apiSettings)); } + [Theory] [InlineData(null)] [InlineData("")] [InlineData(" ")] public void MediaType_NullOrEmpty_OnCreate(string mediaType) { + var sut = GetSut(); var model = new Image { MediaType = mediaType }; var result = sut.TestValidate(model, options => options.IncludeRuleSets("default", "create")); result.ShouldHaveValidationErrorFor(a => a.MediaType); @@ -31,6 +35,7 @@ public void MediaType_NullOrEmpty_OnCreate(string mediaType) [Fact] public void Batch_Provided() { + var sut = GetSut(); var model = new Image { Batch = "10" }; var result = sut.TestValidate(model); result.ShouldHaveValidationErrorFor(a => a.Batch); @@ -39,6 +44,7 @@ public void Batch_Provided() [Fact] public void Width_Provided() { + var sut = GetSut(); var model = new Image { Width = 10 }; var result = sut.TestValidate(model); result @@ -49,6 +55,7 @@ public void Width_Provided() [Fact] public void Height_Provided() { + var sut = GetSut(); var model = new Image { Height = 10 }; var result = sut.TestValidate(model); result @@ -59,6 +66,7 @@ public void Height_Provided() [Fact] public void Duration_Provided() { + var sut = GetSut(); var model = new Image { Duration = 10 }; var result = sut.TestValidate(model); result @@ -69,6 +77,7 @@ public void Duration_Provided() [Fact] public void Finished_Provided() { + var sut = GetSut(); var model = new Image { Finished = DateTime.Today }; var result = sut.TestValidate(model); result.ShouldHaveValidationErrorFor(a => a.Finished); @@ -77,6 +86,7 @@ public void Finished_Provided() [Fact] public void Created_Provided() { + var sut = GetSut(); var model = new Image { Created = DateTime.Today }; var result = sut.TestValidate(model); result.ShouldHaveValidationErrorFor(a => a.Created); @@ -85,8 +95,7 @@ public void Created_Provided() [Fact] public void DeliveryChannel_ValidationError_DeliveryChannelMissingChannel() { - var apiSettings = new ApiSettings(); - var imageValidator = new HydraImageValidator(Options.Create(apiSettings)); + var sut = GetSut(); var model = new Image { DeliveryChannels = new[] { new DeliveryChannel() @@ -98,15 +107,14 @@ public void DeliveryChannel_ValidationError_DeliveryChannelMissingChannel() Channel = "file" } } }; - var result = imageValidator.TestValidate(model); + var result = sut.TestValidate(model); result.ShouldHaveValidationErrorFor(a => a.DeliveryChannels); } [Fact] public void DeliveryChannel_ValidationError_WhenNoneAndMoreDeliveryChannels() { - var apiSettings = new ApiSettings(); - var imageValidator = new HydraImageValidator(Options.Create(apiSettings)); + var sut = GetSut(); var model = new Image { DeliveryChannels = new[] { new DeliveryChannel() @@ -118,15 +126,14 @@ public void DeliveryChannel_ValidationError_WhenNoneAndMoreDeliveryChannels() Channel = "file" } } }; - var result = imageValidator.TestValidate(model); + var result = sut.TestValidate(model); result.ShouldHaveValidationErrorFor(a => a.DeliveryChannels); } [Fact] public void DeliveryChannel_NoValidationError_WhenDeliveryChannelsWithNoNone() { - var apiSettings = new ApiSettings(); - var imageValidator = new HydraImageValidator(Options.Create(apiSettings)); + var sut = GetSut(); var model = new Image { DeliveryChannels = new[] { new DeliveryChannel() @@ -138,15 +145,14 @@ public void DeliveryChannel_NoValidationError_WhenDeliveryChannelsWithNoNone() Channel = "file" } } }; - var result = imageValidator.TestValidate(model); + var result = sut.TestValidate(model); result.ShouldNotHaveValidationErrorFor(a => a.DeliveryChannels); } [Fact] public void DeliveryChannel_NoValidationError_WhenOnlyNone() { - var apiSettings = new ApiSettings(); - var imageValidator = new HydraImageValidator(Options.Create(apiSettings)); + var sut = GetSut(); var model = new Image { DeliveryChannels = new[] { new DeliveryChannel() @@ -154,7 +160,7 @@ public void DeliveryChannel_NoValidationError_WhenOnlyNone() Channel = "none" } } }; - var result = imageValidator.TestValidate(model); + var result = sut.TestValidate(model); result.ShouldNotHaveValidationErrorFor(a => a.DeliveryChannels); } @@ -173,8 +179,7 @@ public void DeliveryChannel_NoValidationError_WhenOnlyNone() [InlineData("application/pdf", "none")] public void DeliveryChannel_NoValidationError_WhenChannelValidForMediaType(string mediaType, string channel) { - var apiSettings = new ApiSettings(); - var imageValidator = new HydraImageValidator(Options.Create(apiSettings)); + var sut = GetSut(); var model = new Image { MediaType = mediaType, DeliveryChannels = new[] @@ -184,7 +189,7 @@ public void DeliveryChannel_NoValidationError_WhenChannelValidForMediaType(strin Channel = channel, } } }; - var result = imageValidator.TestValidate(model); + var result = sut.TestValidate(model); result.ShouldNotHaveValidationErrorFor(a => a.DeliveryChannels); } @@ -197,8 +202,7 @@ public void DeliveryChannel_NoValidationError_WhenChannelValidForMediaType(strin [InlineData("application/pdf", "iiif-av")] public void DeliveryChannel_ValidationError_WhenWrongChannelForMediaType(string mediaType, string channel) { - var apiSettings = new ApiSettings(); - var imageValidator = new HydraImageValidator(Options.Create(apiSettings)); + var sut = GetSut(); var model = new Image { MediaType = mediaType, DeliveryChannels = new[] @@ -208,21 +212,68 @@ public void DeliveryChannel_ValidationError_WhenWrongChannelForMediaType(string Channel = channel, } } }; - var result = imageValidator.TestValidate(model); + var result = sut.TestValidate(model); result.ShouldHaveValidationErrorFor(a => a.DeliveryChannels); } [Fact] public void DeliveryChannel_ValidationError_WhenEmpty_OnPatch() { - var apiSettings = new ApiSettings(); - var imageValidator = new HydraImageValidator(Options.Create(apiSettings)); + var sut = GetSut(); var model = new Image { DeliveryChannels = Array.Empty() }; - var result = imageValidator.TestValidate(model, options => + var result = sut.TestValidate(model, options => options.IncludeRuleSets("default", "patch")); result.ShouldHaveValidationErrorFor(a => a.DeliveryChannels); } + + [Fact] + public void ImageOptimisationPolicy_ValidationError_WhenOldDeliveryChannelEmulationDisabled() + { + var sut = GetSut(); + var model = new Image + { + ImageOptimisationPolicy = "some-iop-policy" + }; + var result = sut.TestValidate(model); + result.ShouldHaveValidationErrorFor(a => a.ImageOptimisationPolicy); + } + + [Fact] + public void ThumbnailPolicy_ValidationError_WhenOldDeliveryChannelEmulationDisabled() + { + var sut = GetSut(); + var model = new Image + { + ThumbnailPolicy = "some-tp-policy" + }; + var result = sut.TestValidate(model); + result.ShouldHaveValidationErrorFor(a => a.ThumbnailPolicy); + } + + [Fact] + public void ImageOptimisationPolicy_NoValidationError_WhenOldDeliveryChannelEmulationEnabled() + { + var sut = GetSut(true); + var model = new Image + { + ImageOptimisationPolicy = "some-iop-policy" + }; + var result = sut.TestValidate(model); + result.ShouldNotHaveValidationErrorFor(a => a.ImageOptimisationPolicy); + } + + [Fact] + public void ThumbnailPolicy_NoValidationError_WhenOldDeliveryChannelEmulationEnabled() + { + var sut = GetSut(true); + var model = new Image + { + ThumbnailPolicy = "some-tp-policy" + }; + var result = sut.TestValidate(model); + result.ShouldNotHaveValidationErrorFor(a => a.ThumbnailPolicy); + } } \ No newline at end of file diff --git a/src/protagonist/API.Tests/Features/Queues/Validation/QueuePostValidatorTests.cs b/src/protagonist/API.Tests/Features/Queues/Validation/QueuePostValidatorTests.cs index e4711cfb9..d7c800aaa 100644 --- a/src/protagonist/API.Tests/Features/Queues/Validation/QueuePostValidatorTests.cs +++ b/src/protagonist/API.Tests/Features/Queues/Validation/QueuePostValidatorTests.cs @@ -10,10 +10,11 @@ namespace API.Tests.Features.Queues.Validation; public class QueuePostValidatorTests { - private QueuePostValidator GetSut() + private QueuePostValidator GetSut(bool emulateOldDeliveryChannelProperties = false) { var apiSettings = new ApiSettings { + EmulateOldDeliveryChannelProperties = emulateOldDeliveryChannelProperties, MaxBatchSize = 4 }; @@ -205,4 +206,22 @@ public void Member_ThumbnailPolicy_Provided() var result = sut.TestValidate(model); result.ShouldHaveValidationErrorFor("Members[0].ThumbnailPolicy"); } + + [Fact] + public void Member_ImageOptimisationPolicy_Allowed_WhenOldDeliveryChannelEmulationEnabled() + { + var sut = GetSut(true); + var model = new HydraCollection { Members = new[] { new Image { ImageOptimisationPolicy = "my-policy" } } }; + var result = sut.TestValidate(model); + result.ShouldNotHaveValidationErrorFor("Members[0].ImageOptimisationPolicy"); + } + + [Fact] + public void Member_ThumbnailPolicy_Allowed_WhenOldDeliveryChannelEmulationEnabled() + { + var sut = GetSut(true); + var model = new HydraCollection { Members = new[] { new Image { ThumbnailPolicy = "my-policy" } } }; + var result = sut.TestValidate(model); + result.ShouldNotHaveValidationErrorFor("Members[0].ThumbnailPolicy"); + } } \ No newline at end of file diff --git a/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs b/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs index 9a03845f2..09d44bd57 100644 --- a/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs +++ b/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs @@ -1484,7 +1484,7 @@ public async Task Patch_Asset_Fails_When_ThumbnailPolicy_Is_Provided() response.StatusCode.Should().Be(HttpStatusCode.BadRequest); var body = await response.Content.ReadAsStringAsync(); - body.Should().Contain("ImageOptimisationPolicy and ThumbnailPolicy are disabled"); + body.Should().Contain("'ThumbnailPolicy' is disabled"); } [Fact] @@ -1504,7 +1504,7 @@ public async Task Patch_Asset_Fails_When_ImageOptimisationPolicy_Is_Provided() response.StatusCode.Should().Be(HttpStatusCode.BadRequest); var body = await response.Content.ReadAsStringAsync(); - body.Should().Contain("ImageOptimisationPolicy and ThumbnailPolicy are disabled"); + body.Should().Contain("'ImageOptimisationPolicy' is disabled"); } [Fact] diff --git a/src/protagonist/API/Features/Queues/Validation/QueuePostValidator.cs b/src/protagonist/API/Features/Queues/Validation/QueuePostValidator.cs index b5b502685..8126f998b 100644 --- a/src/protagonist/API/Features/Queues/Validation/QueuePostValidator.cs +++ b/src/protagonist/API/Features/Queues/Validation/QueuePostValidator.cs @@ -42,11 +42,13 @@ public QueuePostValidator(IOptions apiSettings) members.RuleFor(a => a.ImageOptimisationPolicy) .Null() - .WithMessage("ImageOptimisationPolicy is disabled"); + .When(_ => !apiSettings.Value.EmulateOldDeliveryChannelProperties) + .WithMessage("'ImageOptimisationPolicy' is disabled"); members.RuleFor(a => a.ThumbnailPolicy) .Null() - .WithMessage("ThumbnailPolicy is disabled"); + .When(_ => !apiSettings.Value.EmulateOldDeliveryChannelProperties) + .WithMessage("'ThumbnailPolicy' is disabled"); }); } } \ No newline at end of file From f9b2b7a72fb6adad5f7c6bf09551bccbf8f2e99f Mon Sep 17 00:00:00 2001 From: griffri Date: Wed, 29 May 2024 13:20:04 +0100 Subject: [PATCH 07/30] Remove redundant `DeliveryChannelsEnabled` property from ApiSettings --- src/protagonist/API/Settings/ApiSettings.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/protagonist/API/Settings/ApiSettings.cs b/src/protagonist/API/Settings/ApiSettings.cs index 483075231..45f4e67a9 100644 --- a/src/protagonist/API/Settings/ApiSettings.cs +++ b/src/protagonist/API/Settings/ApiSettings.cs @@ -82,11 +82,6 @@ public bool LegacyModeEnabledForCustomer(int customerId) ? settings.LegacySupport : DefaultLegacySupport; - /// - /// Whether the delivery channel feature is enabled - /// - public bool DeliveryChannelsEnabled { get; set; } - /// /// Characters that are not allowed in an asset id /// From 52372e44a5cdbd321792cd554e0012022408bc66 Mon Sep 17 00:00:00 2001 From: griffri Date: Wed, 29 May 2024 15:12:23 +0100 Subject: [PATCH 08/30] Translate IOP/TP in LegacyModeConverter when EmulateOldDeliveryChannelProperties is enabled, add tests --- .../Converters/LegacyModeConverterTests.cs | 252 +++++++++++++++++- .../API/Converters/LegacyModeConverter.cs | 84 +++++- .../API/Features/Image/ImageController.cs | 3 +- .../Queues/CustomerQueueController.cs | 3 +- 4 files changed, 331 insertions(+), 11 deletions(-) diff --git a/src/protagonist/API.Tests/Converters/LegacyModeConverterTests.cs b/src/protagonist/API.Tests/Converters/LegacyModeConverterTests.cs index abcd1eaf2..9e40c82a5 100644 --- a/src/protagonist/API.Tests/Converters/LegacyModeConverterTests.cs +++ b/src/protagonist/API.Tests/Converters/LegacyModeConverterTests.cs @@ -1,5 +1,7 @@ using API.Converters; using DLCS.HydraModel; +using DLCS.Model.Assets; +using AssetFamily = DLCS.HydraModel.AssetFamily; namespace API.Tests.Converters; @@ -12,7 +14,7 @@ public void VerifyAndConvertToModernFormat_ChangesNothing_WithNewFormat() var hydraImage = new Image{ MediaType = "type", MaxUnauthorised = 5, Family = AssetFamily.File}; // Act - var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage); + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, false); // Assert convertedImage.MediaType.Should().Be(hydraImage.MediaType); @@ -27,7 +29,7 @@ public void VerifyAndConvertToModernFormat_SetsMediaType_WithNotSet() var hydraImage = new Image{ MaxUnauthorised = 5, Family = AssetFamily.File}; // Act - var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage); + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, false); // Assert convertedImage.MediaType.Should().Be("image/unknown"); @@ -42,7 +44,7 @@ public void VerifyAndConvertToModernFormat_InferMediaType_WhenOriginSet() var hydraImage = new Image{ Origin = "something.jpg",MaxUnauthorised = 5, Family = AssetFamily.File}; // Act - var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage); + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage,false); // Assert convertedImage.MediaType.Should().Be("image/jpeg"); @@ -57,7 +59,7 @@ public void VerifyAndConvertToModernFormat_SetMaxUnauthorised_WhenSetToOldFormat var hydraImage = new Image{ Origin = "something.jpg",MaxUnauthorised = 0, Family = AssetFamily.File}; // Act - var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage); + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, false); // Assert convertedImage.MediaType.Should().Be("image/jpeg"); @@ -72,7 +74,7 @@ public void VerifyAndConvertToModernFormat_SetFamily_WhenNotSet() var hydraImage = new Image{ Origin = "something.jpg"}; // Act - var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage); + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, false); // Assert convertedImage.MediaType.Should().Be("image/jpeg"); @@ -87,7 +89,7 @@ public void VerifyAndConvertToModernFormat_MaxUnauthorisedUnchanged_WhenRolesSet var hydraImage = new Image{ Origin = "something.jpg", Roles = new []{ "some role" }}; // Act - var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage); + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, false); // Assert convertedImage.MediaType.Should().Be("image/jpeg"); @@ -102,9 +104,245 @@ public void VerifyAndConvertToModernFormat_ModelIdSet_WhenNoModelId() var hydraImage = new Image{ Id = "https://test/someId", MediaType = "something"}; // Act - var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage); + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, false); // Assert convertedImage.ModelId.Should().Be("someId"); } + + [Fact] + public void VerifyAndConvertToModernFormat_AddsNoDeliveryChannels_WhenOldDeliveryChannelEmulationDisabled() + { + // Arrange + var hydraImage = new Image() + { + Family = AssetFamily.Image, + Origin = "something.jpg", + }; + + // Act + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, false); + + // Assert + convertedImage.DeliveryChannels.Should().BeNullOrEmpty(); + } + + [Fact] + public void VerifyAndConvertToModernFormat_AddsDeliveryChannels_WhenNotSet_ForImage() + { + // Arrange + var hydraImage = new Image() + { + Family = AssetFamily.Image, + Origin = "something.jpg", + }; + + // Act + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, true); + + // Assert + convertedImage.DeliveryChannels.Should().Satisfy( + dc => dc.Channel == AssetDeliveryChannels.Image && + dc.Policy == null, + dc => dc.Channel == AssetDeliveryChannels.Thumbnails && + dc.Policy == null); + } + + [Fact] + public void VerifyAndConvertToModernFormat_AddsDeliveryChannels_WhenNotSet_ForVideo() + { + // Arrange + var hydraImage = new Image() + { + Family = AssetFamily.Timebased, + Origin = "something.mp4", + }; + + // Act + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, true); + + // Assert + convertedImage.DeliveryChannels.Should().Satisfy( + dc => dc.Channel == AssetDeliveryChannels.Timebased && + dc.Policy == null); + } + + [Fact] + public void VerifyAndConvertToModernFormat_AddsDeliveryChannels_WhenNotSet_ForAudio() + { + // Arrange + var hydraImage = new Image() + { + Family = AssetFamily.Timebased, + Origin = "something.mp3", + }; + + // Act + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, true); + + // Assert + convertedImage.DeliveryChannels.Should().Satisfy( + dc => dc.Channel == AssetDeliveryChannels.Timebased && + dc.Policy == null); + } + + [Fact] + public void VerifyAndConvertToModernFormat_AddsDeliveryChannels_WhenNotSet_ForFile() + { + // Arrange + var hydraImage = new Image() + { + Family = AssetFamily.File, + Origin = "something.pdf", + }; + + // Act + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, true); + + // Assert + convertedImage.DeliveryChannels.Should().Satisfy( + dc => dc.Channel == AssetDeliveryChannels.File && + dc.Policy == "none"); + } + + [Theory] + [InlineData("mp3")] + [InlineData("mp4")] + [InlineData("pdf")] + public void VerifyAndConvertToModernFormat_TreatsAsImage_ForNonImagesWithoutFamily(string fileExtension) + { + // Arrange + var hydraImage = new Image() + { + Origin = $"something.{fileExtension}", + }; + + // Act + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, true); + + // Assert + convertedImage.DeliveryChannels.Should().Satisfy( + dc => dc.Channel == AssetDeliveryChannels.Image, + dc => dc.Channel == AssetDeliveryChannels.Thumbnails); + } + + [Theory] + [InlineData("fast-higher")] + [InlineData("https://api.dlc.services/imageOptimisationPolicies/fast-higher")] + public void VerifyAndConvertToModernFormat_AddsImageDeliveryChannelsWithPolicies_WhenFastHigherImageOptimisationPolicySpecified( + string imageOptimisationPolicy) + { + // Arrange + var hydraImage = new Image() + { + Origin = "something.jpg", + ImageOptimisationPolicy = imageOptimisationPolicy + }; + + // Act + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, true); + + // Assert + convertedImage.DeliveryChannels.Should().Satisfy( + dc => dc.Channel == AssetDeliveryChannels.Image && + dc.Policy == "default", + dc => dc.Channel == AssetDeliveryChannels.Thumbnails && + dc.Policy == null); + } + + [Theory] + [InlineData("default")] + [InlineData("https://api.dlc.services/thumbnailPolicies/default")] + public void VerifyAndConvertToModernFormat_AddsImageDeliveryChannelsWithPolicies_WhenDefaultThumbnailPolicySpecified( + string thumbnailPolicy) + { + // Arrange + var hydraImage = new Image() + { + Origin = "something.jpg", + ThumbnailPolicy = thumbnailPolicy + }; + + // Act + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, true); + + // Assert + convertedImage.DeliveryChannels.Should().Satisfy( + dc => dc.Channel == AssetDeliveryChannels.Image && + dc.Policy == null, + dc => dc.Channel == AssetDeliveryChannels.Thumbnails && + dc.Policy == "default"); + } + + [Theory] + [InlineData("fast-higher", "default")] + [InlineData("https://api.dlc.services/imageOptimisationPolicies/fast-higher", + "https://api.dlc.services/thumbnailPolicies/default")] + public void VerifyAndConvertToModernFormat_AddsImageDeliveryChannelsWithPolicies_WithBothPolicyTypesSpecified( + string imageOptimisationPolicy, string thumbnailPolicy) + { + // Arrange + var hydraImage = new Image() + { + Origin = "something.jpg", + ImageOptimisationPolicy = imageOptimisationPolicy, + ThumbnailPolicy = thumbnailPolicy + }; + + // Act + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, true); + + // Assert + convertedImage.DeliveryChannels.Should().Satisfy( + dc => dc.Channel == AssetDeliveryChannels.Image && + dc.Policy == "default", + dc => dc.Channel == AssetDeliveryChannels.Thumbnails && + dc.Policy == "default"); + } + + [Theory] + [InlineData("video-max")] + [InlineData("https://api.dlc.services/imageOptimisationPolicy/video-max")] + public void VerifyAndConvertToModernFormat_AddsTimebasedDeliveryChannelWithPolicy_WhenVideoMaxSpecified( + string imageOptimisationPolicy) + { + // Arrange + var hydraImage = new Image() + { + Family = AssetFamily.Timebased, + Origin = "something.mp4", + ImageOptimisationPolicy = imageOptimisationPolicy + }; + + // Act + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, true); + + // Assert + convertedImage.DeliveryChannels.Should().Satisfy( + dc => dc.Channel == AssetDeliveryChannels.Timebased && + dc.Policy == "default-video"); + } + + [Theory] + [InlineData("audio-max")] + [InlineData("https://api.dlc.services/imageOptimisationPolicy/audio-max")] + public void VerifyAndConvertToModernFormat_AddsTimebasedDeliveryChannelWithPolicy_WhenAudioMaxSpecified( + string imageOptimisationPolicy) + { + // Arrange + var hydraImage = new Image() + { + Family = AssetFamily.Timebased, + Origin = "something.mp3", + ImageOptimisationPolicy = imageOptimisationPolicy + }; + + // Act + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, true); + + // Assert + convertedImage.DeliveryChannels.Should().Satisfy( + dc => dc.Channel == AssetDeliveryChannels.Timebased && + dc.Policy == "default-audio"); + } } \ No newline at end of file diff --git a/src/protagonist/API/Converters/LegacyModeConverter.cs b/src/protagonist/API/Converters/LegacyModeConverter.cs index ae2c62468..f0d7861d0 100644 --- a/src/protagonist/API/Converters/LegacyModeConverter.cs +++ b/src/protagonist/API/Converters/LegacyModeConverter.cs @@ -1,7 +1,9 @@ using DLCS.Core; using DLCS.Core.Collections; using DLCS.HydraModel; +using DLCS.Model.Assets; using Hydra; +using AssetFamily = DLCS.HydraModel.AssetFamily; namespace API.Converters; @@ -16,8 +18,10 @@ public static class LegacyModeConverter /// Converts from legacy format to new format /// /// The image to convert + /// Whether old thumbnailPolicy/imageOptimisation behaviour + /// should be emulated /// A converted image - public static T VerifyAndConvertToModernFormat(T image) + public static T VerifyAndConvertToModernFormat(T image, bool emulateOldDeliveryChannelProperties) where T : Image { if (image.MediaType.IsNullOrEmpty()) @@ -28,7 +32,7 @@ public static T VerifyAndConvertToModernFormat(T image) if (image.Origin is not null && image.Family is null) { - image.Family = AssetFamily.Image; + image.Family = DLCS.HydraModel.AssetFamily.Image; } } @@ -42,6 +46,82 @@ public static T VerifyAndConvertToModernFormat(T image) image.MaxUnauthorised = -1; } + if (emulateOldDeliveryChannelProperties) + { + image.DeliveryChannels = GetDeliveryChannelsForLegacyAsset(image); + } + return image; } + + public static DeliveryChannel[]? GetDeliveryChannelsForLegacyAsset(T image) + where T : Image + { + var thumbnailPolicy = image.ThumbnailPolicy.GetLastPathElement() ?? image.ThumbnailPolicy; + var imageOptimisationPolicy = image.ImageOptimisationPolicy.GetLastPathElement() ?? image.ImageOptimisationPolicy; + + if (image.Family == AssetFamily.Image) + { + return new DeliveryChannel[] + { + new() + { + Channel = AssetDeliveryChannels.Image, + Policy = imageOptimisationPolicy == "fast-higher" + ? "default" + : null + }, + new() + { + Channel = AssetDeliveryChannels.Thumbnails, + Policy = thumbnailPolicy == "default" + ? "default" + : null + }, + }; + } + if (image.Family == AssetFamily.Timebased) + { + if(MIMEHelper.IsVideo(image.MediaType)) + { + return new DeliveryChannel[] + { + new() + { + Channel = AssetDeliveryChannels.Timebased, + Policy = imageOptimisationPolicy == "video-max" + ? "default-video" + : null + } + }; + } + if (MIMEHelper.IsAudio(image.MediaType)) + { + return new DeliveryChannel[] + { + new() + { + Channel = AssetDeliveryChannels.Timebased, + Policy = imageOptimisationPolicy == "audio-max" + ? "default-audio" + : null + } + }; + } + } + if (image.Family == AssetFamily.File) + { + return new DeliveryChannel[] + { + new() + { + Channel = AssetDeliveryChannels.File, + Policy = "none" + } + }; + } + + return Array.Empty(); + } + } \ No newline at end of file diff --git a/src/protagonist/API/Features/Image/ImageController.cs b/src/protagonist/API/Features/Image/ImageController.cs index cddaab18d..be67e31cd 100644 --- a/src/protagonist/API/Features/Image/ImageController.cs +++ b/src/protagonist/API/Features/Image/ImageController.cs @@ -97,7 +97,8 @@ public async Task PutImage( { if (Settings.LegacyModeEnabledForSpace(customerId, spaceId)) { - hydraAsset = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraAsset); + hydraAsset = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraAsset, + Settings.EmulateOldDeliveryChannelProperties); } if (hydraAsset.ModelId == null) diff --git a/src/protagonist/API/Features/Queues/CustomerQueueController.cs b/src/protagonist/API/Features/Queues/CustomerQueueController.cs index a6625b973..e31776a2d 100644 --- a/src/protagonist/API/Features/Queues/CustomerQueueController.cs +++ b/src/protagonist/API/Features/Queues/CustomerQueueController.cs @@ -371,7 +371,8 @@ private void UpdateMembers(int customerId, IList? members { if (Settings.LegacyModeEnabledForSpace(customerId, members[i].Space)) { - members[i] = LegacyModeConverter.VerifyAndConvertToModernFormat(members[i]); + members[i] = LegacyModeConverter.VerifyAndConvertToModernFormat(members[i], + Settings.EmulateOldDeliveryChannelProperties); } } } From 41ca7e8b57f1a94ca1bcb7941a5d73c00fe93af6 Mon Sep 17 00:00:00 2001 From: griffri Date: Wed, 29 May 2024 17:15:43 +0100 Subject: [PATCH 09/30] Add tests for creating new image assets with legacy + old delivery channel property emulation enabled Add test method for creating delivery channel policies for a user --- ...etWithOldDeliveryChannelPropertiesTests.cs | 160 ++++++++++++++++++ .../Integration/DatabaseTestDataPopulation.cs | 17 +- 2 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 src/protagonist/API.Tests/Integration/ModifyAssetWithOldDeliveryChannelPropertiesTests.cs diff --git a/src/protagonist/API.Tests/Integration/ModifyAssetWithOldDeliveryChannelPropertiesTests.cs b/src/protagonist/API.Tests/Integration/ModifyAssetWithOldDeliveryChannelPropertiesTests.cs new file mode 100644 index 000000000..2691ba9e3 --- /dev/null +++ b/src/protagonist/API.Tests/Integration/ModifyAssetWithOldDeliveryChannelPropertiesTests.cs @@ -0,0 +1,160 @@ +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Text; +using System.Threading; +using Amazon.S3; +using API.Infrastructure.Messaging; +using API.Tests.Integration.Infrastructure; +using DLCS.Core.Types; +using DLCS.Model.Assets; +using DLCS.Model.Policies; +using DLCS.Repository; +using DLCS.Repository.Messaging; +using FakeItEasy; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Test.Helpers.Integration; +using Test.Helpers.Integration.Infrastructure; +using AssetFamily = DLCS.Model.Assets.AssetFamily; + +namespace API.Tests.Integration; + +[Trait("Category", "Integration")] +[Collection(StorageCollection.CollectionName)] +public class ModifyAssetWithOldDeliveryChannelPropertiesTests : IClassFixture> +{ + private readonly DlcsContext dbContext; + private readonly HttpClient httpClient; + private static readonly IAssetNotificationSender NotificationSender = A.Fake(); + private readonly IAmazonS3 amazonS3; + private static readonly IEngineClient EngineClient = A.Fake(); + + public ModifyAssetWithOldDeliveryChannelPropertiesTests( + StorageFixture storageFixture, + ProtagonistAppFactory factory) + { + var dbFixture = storageFixture.DbFixture; + amazonS3 = storageFixture.LocalStackFixture.AWSS3ClientFactory(); + + dbContext = dbFixture.DbContext; + + httpClient = factory + .WithConnectionString(dbFixture.ConnectionString) + .WithLocalStack(storageFixture.LocalStackFixture) + .WithTestServices(services => + { + services.AddSingleton(_ => NotificationSender); + services.AddScoped(_ => EngineClient); + services.AddAuthentication("API-Test") + .AddScheme( + "API-Test", _ => { }); + }) + .WithConfigValue("EmulateOldDeliveryChannelProperties", "true") + .CreateClient(new WebApplicationFactoryClientOptions + { + AllowAutoRedirect = false + }); + + dbFixture.CleanUp(); + } + + [Theory] + [InlineData("default")] + [InlineData("https://api.dlc.services/thumbnailPolicies/default")] + public async Task Put_NewImageAsset_WithThumbnailPolicy_Creates_Asset_WhenLegacyEnabled(string thumbnailPolicy) + { + const int customer = 325665; + const int space = 2; + var assetId = new AssetId(customer, space, nameof(Put_NewImageAsset_WithThumbnailPolicy_Creates_Asset_WhenLegacyEnabled)); + + await dbContext.Customers.AddTestCustomer(customer); + await dbContext.Spaces.AddTestSpace(customer, space); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); + await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); + await dbContext.SaveChangesAsync(); + + var hydraImageBody = $@"{{ + ""@type"": ""Image"", + ""origin"": ""https://example.org/{assetId.Asset}.tiff"", + ""thumbnailPolicy"": ""{thumbnailPolicy}"" + }}"; + + A.CallTo(() => + EngineClient.SynchronousIngest( + A.That.Matches(r => r.Id == assetId), + A._)) + .Returns(HttpStatusCode.OK); + + // act + var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); + var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + + // assert + var test = response.Content.ReadAsStringAsync(); + + response.StatusCode.Should().Be(HttpStatusCode.Created); + + var asset = dbContext.Images.Include(i => i.ImageDeliveryChannels) + .ThenInclude(i => i.DeliveryChannelPolicy).Single(i => i.Id == assetId); + asset.Id.Should().Be(assetId); + asset.MediaType.Should().Be("image/tiff"); + asset.Family.Should().Be(AssetFamily.Image); + asset.ThumbnailPolicy.Should().Be("default"); + asset.ImageOptimisationPolicy.Should().BeEmpty(); + asset.ImageDeliveryChannels.Count.Should().Be(2); + asset.ImageDeliveryChannels.Should().ContainSingle(x => x.Channel == "iiif-img" && + x.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ImageDefault); + asset.ImageDeliveryChannels.Should().ContainSingle(x => x.Channel == "thumbs" && + x.DeliveryChannelPolicy.Name == "default"); + } + + [Theory] + [InlineData("fast-higher")] + [InlineData("https://api.dlc.services/imageOptimisationPolicies/fast-higher")] + public async Task Put_NewImageAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled(string imageOptimisationPolicy) + { + const int customer = 325665; + const int space = 2; + var assetId = new AssetId(customer, space, nameof(Put_NewImageAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled)); + await dbContext.Customers.AddTestCustomer(customer); + await dbContext.Spaces.AddTestSpace(customer, space); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); + await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); + await dbContext.SaveChangesAsync(); + + var hydraImageBody = $@"{{ + ""@type"": ""Image"", + ""origin"": ""https://example.org/{assetId.Asset}.tiff"", + ""imageOptimisationPolicy"" : ""{imageOptimisationPolicy}"" + }}"; + + A.CallTo(() => + EngineClient.SynchronousIngest( + A.That.Matches(r => r.Id == assetId), + A._)) + .Returns(HttpStatusCode.OK); + + // act + var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); + var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + + // assert + response.StatusCode.Should().Be(HttpStatusCode.Created); + + var asset = dbContext.Images.Include(i => i.ImageDeliveryChannels) + .ThenInclude(i => i.DeliveryChannelPolicy).Single(i => i.Id == assetId); + asset.Id.Should().Be(assetId); + asset.MediaType.Should().Be("image/tiff"); + asset.Family.Should().Be(AssetFamily.Image); + asset.ImageOptimisationPolicy.Should().Be("fast-higher"); + asset.ThumbnailPolicy.Should().BeEmpty(); + asset.ImageDeliveryChannels.Count.Should().Be(2); + asset.ImageDeliveryChannels.Should().ContainSingle(x => x.Channel == "iiif-img" && + x.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ImageDefault); + asset.ImageDeliveryChannels.Should().ContainSingle(x => x.Channel == "thumbs" && + x.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ThumbsDefault); + } +} \ No newline at end of file diff --git a/src/protagonist/Test.Helpers/Integration/DatabaseTestDataPopulation.cs b/src/protagonist/Test.Helpers/Integration/DatabaseTestDataPopulation.cs index ffa9c5a1c..75c5da816 100644 --- a/src/protagonist/Test.Helpers/Integration/DatabaseTestDataPopulation.cs +++ b/src/protagonist/Test.Helpers/Integration/DatabaseTestDataPopulation.cs @@ -138,7 +138,22 @@ public static Task AddTestDefaultDeliveryChannels(this DbSet deliveryChannelPolicies, + int customerId) => + deliveryChannelPolicies.AddRangeAsync(deliveryChannelPolicies.Where(p => p.Customer == 1 && !p.System) + .Select(x => new DeliveryChannelPolicy() + { + Customer = customerId, + Name = x.Name, + Channel = x.Channel, + DisplayName = x.DisplayName, + PolicyData = x.PolicyData, + Created = x. Created, + Modified = x.Modified, + System = false, + })); + public static ValueTask> AddTestUser(this DbSet users, int customer, string email, string password = "password123") => users.AddAsync(new User { From c268c6f4973afd469168f4e3368af19e7149c1c2 Mon Sep 17 00:00:00 2001 From: griffri Date: Wed, 29 May 2024 17:38:57 +0100 Subject: [PATCH 10/30] Add legacy video-max/audio-max IOP tests --- ...etWithOldDeliveryChannelPropertiesTests.cs | 107 ++++++++++++++++-- .../API/Converters/LegacyModeConverter.cs | 6 +- 2 files changed, 101 insertions(+), 12 deletions(-) diff --git a/src/protagonist/API.Tests/Integration/ModifyAssetWithOldDeliveryChannelPropertiesTests.cs b/src/protagonist/API.Tests/Integration/ModifyAssetWithOldDeliveryChannelPropertiesTests.cs index 2691ba9e3..8074c7819 100644 --- a/src/protagonist/API.Tests/Integration/ModifyAssetWithOldDeliveryChannelPropertiesTests.cs +++ b/src/protagonist/API.Tests/Integration/ModifyAssetWithOldDeliveryChannelPropertiesTests.cs @@ -105,10 +105,10 @@ public async Task Put_NewImageAsset_WithThumbnailPolicy_Creates_Asset_WhenLegacy asset.ThumbnailPolicy.Should().Be("default"); asset.ImageOptimisationPolicy.Should().BeEmpty(); asset.ImageDeliveryChannels.Count.Should().Be(2); - asset.ImageDeliveryChannels.Should().ContainSingle(x => x.Channel == "iiif-img" && - x.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ImageDefault); - asset.ImageDeliveryChannels.Should().ContainSingle(x => x.Channel == "thumbs" && - x.DeliveryChannelPolicy.Name == "default"); + asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == "iiif-img" && + dc.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ImageDefault); + asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == "thumbs" && + dc.DeliveryChannelPolicy.Name == "default"); } [Theory] @@ -126,7 +126,6 @@ public async Task Put_NewImageAsset_WithImageOptimisationPolicy_Creates_Asset_Wh await dbContext.SaveChangesAsync(); var hydraImageBody = $@"{{ - ""@type"": ""Image"", ""origin"": ""https://example.org/{assetId.Asset}.tiff"", ""imageOptimisationPolicy"" : ""{imageOptimisationPolicy}"" }}"; @@ -152,9 +151,99 @@ public async Task Put_NewImageAsset_WithImageOptimisationPolicy_Creates_Asset_Wh asset.ImageOptimisationPolicy.Should().Be("fast-higher"); asset.ThumbnailPolicy.Should().BeEmpty(); asset.ImageDeliveryChannels.Count.Should().Be(2); - asset.ImageDeliveryChannels.Should().ContainSingle(x => x.Channel == "iiif-img" && - x.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ImageDefault); - asset.ImageDeliveryChannels.Should().ContainSingle(x => x.Channel == "thumbs" && - x.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ThumbsDefault); + asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == "iiif-img" && + dc.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ImageDefault); + asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == "thumbs" && + dc.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ThumbsDefault); + } + + [Theory] + [InlineData("video-max")] + [InlineData("https://api.dlc.services/imageOptimisationPolicy/video-max")] + public async Task Put_NewVideoAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled(string imageOptimisationPolicy) + { + const int customer = 325665; + const int space = 2; + var assetId = new AssetId(customer, space, nameof(Put_NewImageAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled)); + await dbContext.Customers.AddTestCustomer(customer); + await dbContext.Spaces.AddTestSpace(customer, space); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); + await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); + await dbContext.SaveChangesAsync(); + + var hydraImageBody = $@"{{ + ""family"": ""T"", + ""origin"": ""https://example.org/{assetId.Asset}.mp4"", + ""imageOptimisationPolicy"" : ""{imageOptimisationPolicy}"" + }}"; + + A.CallTo(() => + EngineClient.AsynchronousIngest( + A.That.Matches(r => r.Id == assetId), + A._)) + .Returns(true); + + // act + var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); + var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + + // assert + response.StatusCode.Should().Be(HttpStatusCode.Created); + + var asset = dbContext.Images.Include(i => i.ImageDeliveryChannels) + .ThenInclude(i => i.DeliveryChannelPolicy).Single(i => i.Id == assetId); + asset.Id.Should().Be(assetId); + asset.MediaType.Should().Be("video/mp4"); + asset.Family.Should().Be(AssetFamily.Timebased); + asset.ImageOptimisationPolicy.Should().Be(imageOptimisationPolicy); + asset.ThumbnailPolicy.Should().BeEmpty(); + asset.ImageDeliveryChannels.Count.Should().Be(1); + asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == "iiif-av" && + dc.DeliveryChannelPolicy.Name == "default-video"); + } + + [Theory] + [InlineData("audio-max")] + [InlineData("https://api.dlc.services/imageOptimisationPolicy/audio-max")] + public async Task Put_NewAudioAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled(string imageOptimisationPolicy) + { + const int customer = 325665; + const int space = 2; + var assetId = new AssetId(customer, space, nameof(Put_NewImageAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled)); + await dbContext.Customers.AddTestCustomer(customer); + await dbContext.Spaces.AddTestSpace(customer, space); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); + await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); + await dbContext.SaveChangesAsync(); + + var hydraImageBody = $@"{{ + ""family"": ""T"", + ""origin"": ""https://example.org/{assetId.Asset}.mp3"", + ""imageOptimisationPolicy"" : ""{imageOptimisationPolicy}"" + }}"; + + A.CallTo(() => + EngineClient.AsynchronousIngest( + A.That.Matches(r => r.Id == assetId), + A._)) + .Returns(true); + + // act + var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); + var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + + // assert + response.StatusCode.Should().Be(HttpStatusCode.Created); + + var asset = dbContext.Images.Include(i => i.ImageDeliveryChannels) + .ThenInclude(i => i.DeliveryChannelPolicy).Single(i => i.Id == assetId); + asset.Id.Should().Be(assetId); + asset.MediaType.Should().Be("audio/mp3"); + asset.Family.Should().Be(AssetFamily.Timebased); + asset.ImageOptimisationPolicy.Should().Be(imageOptimisationPolicy); + asset.ThumbnailPolicy.Should().BeEmpty(); + asset.ImageDeliveryChannels.Count.Should().Be(1); + asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == "iiif-av" && + dc.DeliveryChannelPolicy.Name == "default-audio"); } } \ No newline at end of file diff --git a/src/protagonist/API/Converters/LegacyModeConverter.cs b/src/protagonist/API/Converters/LegacyModeConverter.cs index f0d7861d0..8f05adf77 100644 --- a/src/protagonist/API/Converters/LegacyModeConverter.cs +++ b/src/protagonist/API/Converters/LegacyModeConverter.cs @@ -18,8 +18,8 @@ public static class LegacyModeConverter /// Converts from legacy format to new format /// /// The image to convert - /// Whether old thumbnailPolicy/imageOptimisation behaviour - /// should be emulated + /// Whether old thumbnailPolicy/imageOptimisationPolicy fields + /// should be emulated and translated into delivery channels /// A converted image public static T VerifyAndConvertToModernFormat(T image, bool emulateOldDeliveryChannelProperties) where T : Image @@ -32,7 +32,7 @@ public static T VerifyAndConvertToModernFormat(T image, bool emulateOldDelive if (image.Origin is not null && image.Family is null) { - image.Family = DLCS.HydraModel.AssetFamily.Image; + image.Family = AssetFamily.Image; } } From e68bf3fdc390641073a4090804773ab80a9dec41 Mon Sep 17 00:00:00 2001 From: griffri Date: Fri, 31 May 2024 13:46:00 +0100 Subject: [PATCH 11/30] Add further tests for disabled old delivery channel properties --- .../Converters/LegacyModeConverterTests.cs | 99 ++++++++++++++++++- 1 file changed, 98 insertions(+), 1 deletion(-) diff --git a/src/protagonist/API.Tests/Converters/LegacyModeConverterTests.cs b/src/protagonist/API.Tests/Converters/LegacyModeConverterTests.cs index 9e40c82a5..74769fd35 100644 --- a/src/protagonist/API.Tests/Converters/LegacyModeConverterTests.cs +++ b/src/protagonist/API.Tests/Converters/LegacyModeConverterTests.cs @@ -111,7 +111,7 @@ public void VerifyAndConvertToModernFormat_ModelIdSet_WhenNoModelId() } [Fact] - public void VerifyAndConvertToModernFormat_AddsNoDeliveryChannels_WhenOldDeliveryChannelEmulationDisabled() + public void VerifyAndConvertToModernFormat_AddsNoDeliveryChannels_WhenOldDeliveryChannelPropertiesDisabled_ForImage() { // Arrange var hydraImage = new Image() @@ -127,6 +127,103 @@ public void VerifyAndConvertToModernFormat_AddsNoDeliveryChannels_WhenOldDeliver convertedImage.DeliveryChannels.Should().BeNullOrEmpty(); } + [Theory] + [InlineData("fast-higher")] + [InlineData("https://api.dlc.services/imageOptimisationPolicies/fast-higher")] + public void VerifyAndConvertToModernFormat_AddsNoDeliveryChannels_WhenOldDeliveryChannelPropertiesDisabled_AndImageOptimisationPolicyValid_ForImage( + string imageOptimisationPolicy) + { + // Arrange + var hydraImage = new Image() + { + Family = AssetFamily.Image, + Origin = "something.jpg", + ImageOptimisationPolicy = imageOptimisationPolicy + }; + + // Act + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, false); + + // Assert + convertedImage.DeliveryChannels.Should().BeNullOrEmpty(); + } + + [Fact] + public void VerifyAndConvertToModernFormat_AddsNoDeliveryChannels_WhenOldDeliveryChannelPropertiesDisabled_ForVideo() + { + // Arrange + var hydraImage = new Image() + { + Family = AssetFamily.Timebased, + Origin = "something.mp4", + }; + + // Act + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, false); + + // Assert + convertedImage.DeliveryChannels.Should().BeNullOrEmpty(); + } + + [Theory] + [InlineData("video-max")] + [InlineData("https://api.dlc.services/imageOptimisationPolicies/video-max")] + public void VerifyAndConvertToModernFormat_AddsNoDeliveryChannels_WhenOldDeliveryChannelPropertiesDisabled_AndImageOptimisationPolicyValid_ForVideo( + string imageOptimisationPolicy) + { + // Arrange + var hydraImage = new Image() + { + Family = AssetFamily.Timebased, + Origin = "something.mp4", + ImageOptimisationPolicy = imageOptimisationPolicy + }; + + // Act + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, false); + + // Assert + convertedImage.DeliveryChannels.Should().BeNullOrEmpty(); + } + + [Fact] + public void VerifyAndConvertToModernFormat_AddsNoDeliveryChannels_WhenOldDeliveryChannelPropertiesDisabled_ForAudio() + { + // Arrange + var hydraImage = new Image() + { + Family = AssetFamily.Timebased, + Origin = "something.mp3", + }; + + // Act + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, false); + + // Assert + convertedImage.DeliveryChannels.Should().BeNullOrEmpty(); + } + + [Theory] + [InlineData("audio-max")] + [InlineData("https://api.dlc.services/imageOptimisationPolicies/audio-max")] + public void VerifyAndConvertToModernFormat_AddsNoDeliveryChannels_WhenOldDeliveryChannelPropertiesDisabled_AndImageOptimisationPolicyValid_ForAudio( + string imageOptimisationPolicy) + { + // Arrange + var hydraImage = new Image() + { + Family = AssetFamily.Timebased, + Origin = "something.mp3", + ImageOptimisationPolicy = imageOptimisationPolicy + }; + + // Act + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, false); + + // Assert + convertedImage.DeliveryChannels.Should().BeNullOrEmpty(); + } + [Fact] public void VerifyAndConvertToModernFormat_AddsDeliveryChannels_WhenNotSet_ForImage() { From 1b014888e953efa88edebb1bd201238548cdff46 Mon Sep 17 00:00:00 2001 From: griffri Date: Fri, 31 May 2024 15:31:28 +0100 Subject: [PATCH 12/30] Allow assets to be updated without specifying any delivery channels if legacy is enabled --- .../API.Tests/Integration/ModifyAssetTests.cs | 49 +++++++++++++++++++ ...etWithOldDeliveryChannelPropertiesTests.cs | 2 - .../Features/Image/Ingest/AssetProcessor.cs | 3 +- 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs b/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs index 09d44bd57..e19d7dbdc 100644 --- a/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs +++ b/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs @@ -594,6 +594,51 @@ public async Task Put_NewImageAsset_CreatesAsset_WhenInferringOfMediaTypeNotPoss x.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ThumbsDefault); } + [Fact] + public async Task Put_Existing_Asset_UpdatesAsset_IfIncomingDeliveryChannelsNull_AndLegacyEnabled() + { + const int customer = 325665; + const int space = 2; + var assetId = new AssetId(customer, space, nameof(Put_Existing_Asset_UpdatesAsset_IfIncomingDeliveryChannelsNull_AndLegacyEnabled)); + + await dbContext.Customers.AddTestCustomer(customer); + await dbContext.Spaces.AddTestSpace(customer, space); + + var expectedDeliveryChannels = new List() + { + new() + { + Channel = AssetDeliveryChannels.File, + DeliveryChannelPolicyId = KnownDeliveryChannelPolicies.FileNone + } + }; + + var testAsset = await dbContext.Images.AddTestAsset(assetId, customer: customer, space: space, + imageDeliveryChannels: expectedDeliveryChannels); + + await dbContext.SaveChangesAsync(); + + var hydraImageBody = @"{ + ""string1"": ""my-string"" + }"; + + A.CallTo(() => + EngineClient.SynchronousIngest( + A.That.Matches(r => r.Id == assetId), + A._)) + .Returns(HttpStatusCode.OK); + + // Act + var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); + var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + + // Assert + response.StatusCode.Should().Be(HttpStatusCode.OK); + await dbContext.Entry(testAsset.Entity).ReloadAsync(); + testAsset.Entity.Reference1.Should().Be("my-string"); + testAsset.Entity.ImageDeliveryChannels.Should().BeEquivalentTo(expectedDeliveryChannels); // Should be unchanged + } + [Theory] [InlineData("audio/mp3", AssetFamily.Timebased)] [InlineData("video/mp4", AssetFamily.Timebased)] @@ -1029,6 +1074,8 @@ public async Task Put_Existing_Asset_Returns400_IfDeliveryChannelsNull() // assert response.StatusCode.Should().Be(HttpStatusCode.BadRequest); + var body = await response.Content.ReadAsStringAsync(); + body.Should().Contain("Delivery channels are required when updating an existing Asset via PUT"); } [Fact] @@ -1052,6 +1099,8 @@ public async Task Put_Existing_Asset_Returns400_IfDeliveryChannelsEmpty() // assert response.StatusCode.Should().Be(HttpStatusCode.BadRequest); + var body = await response.Content.ReadAsStringAsync(); + body.Should().Contain("Delivery channels are required when updating an existing Asset via PUT"); } [Fact] diff --git a/src/protagonist/API.Tests/Integration/ModifyAssetWithOldDeliveryChannelPropertiesTests.cs b/src/protagonist/API.Tests/Integration/ModifyAssetWithOldDeliveryChannelPropertiesTests.cs index 8074c7819..54b1fa06a 100644 --- a/src/protagonist/API.Tests/Integration/ModifyAssetWithOldDeliveryChannelPropertiesTests.cs +++ b/src/protagonist/API.Tests/Integration/ModifyAssetWithOldDeliveryChannelPropertiesTests.cs @@ -93,8 +93,6 @@ public async Task Put_NewImageAsset_WithThumbnailPolicy_Creates_Asset_WhenLegacy var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); // assert - var test = response.Content.ReadAsStringAsync(); - response.StatusCode.Should().Be(HttpStatusCode.Created); var asset = dbContext.Images.Include(i => i.ImageDeliveryChannels) diff --git a/src/protagonist/API/Features/Image/Ingest/AssetProcessor.cs b/src/protagonist/API/Features/Image/Ingest/AssetProcessor.cs index e832730e1..fe80d1c71 100644 --- a/src/protagonist/API/Features/Image/Ingest/AssetProcessor.cs +++ b/src/protagonist/API/Features/Image/Ingest/AssetProcessor.cs @@ -93,7 +93,8 @@ public async Task Process(AssetBeforeProcessing assetBeforeP counts.CustomerStorage.NumberOfStoredImages++; } - else if (assetBeforeProcessing.DeliveryChannelsBeforeProcessing.IsNullOrEmpty() && alwaysReingest) + else if (assetBeforeProcessing.DeliveryChannelsBeforeProcessing.IsNullOrEmpty() && alwaysReingest + && !settings.LegacyModeEnabledForSpace(assetBeforeProcessing.Asset.Customer, assetBeforeProcessing.Asset.Space)) { return new ProcessAssetResult { From 2dfa939c62c271e30697ce56120d59462ca69caf Mon Sep 17 00:00:00 2001 From: griffri Date: Fri, 31 May 2024 16:21:50 +0100 Subject: [PATCH 13/30] Add customer queue tests for legacy payloads using IOP/TP --- ...ueWithOldDeliveryChannelPropertiesTests.cs | 233 ++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100644 src/protagonist/API.Tests/Integration/CustomerQueueWithOldDeliveryChannelPropertiesTests.cs diff --git a/src/protagonist/API.Tests/Integration/CustomerQueueWithOldDeliveryChannelPropertiesTests.cs b/src/protagonist/API.Tests/Integration/CustomerQueueWithOldDeliveryChannelPropertiesTests.cs new file mode 100644 index 000000000..4711209d8 --- /dev/null +++ b/src/protagonist/API.Tests/Integration/CustomerQueueWithOldDeliveryChannelPropertiesTests.cs @@ -0,0 +1,233 @@ +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Text; +using API.Tests.Integration.Infrastructure; +using DLCS.Model.Assets; +using DLCS.Model.Policies; +using DLCS.Repository; +using DLCS.Repository.Messaging; +using FakeItEasy; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Test.Helpers.Integration; +using Test.Helpers.Integration.Infrastructure; + +namespace API.Tests.Integration; + +[Trait("Category", "Integration")] +[Collection(CollectionDefinitions.DatabaseCollection.CollectionName)] +public class CustomerQueueWithOldDeliveryChannelPropertiesTests : IClassFixture> +{ + private readonly DlcsContext dbContext; + private readonly HttpClient httpClient; + private static readonly IEngineClient EngineClient = A.Fake(); + + public CustomerQueueWithOldDeliveryChannelPropertiesTests(DlcsDatabaseFixture dbFixture, + ProtagonistAppFactory factory) + { + dbContext = dbFixture.DbContext; + httpClient = factory + .WithConnectionString(dbFixture.ConnectionString) + .WithTestServices(services => + { + services.AddScoped(_ => EngineClient); + services.AddAuthentication("API-Test") + .AddScheme( + "API-Test", _ => { }); + }) + .WithConfigValue("EmulateOldDeliveryChannelProperties", "true") + .CreateClient(new WebApplicationFactoryClientOptions + { + AllowAutoRedirect = false + }); + } + + [Fact] + public async Task Post_CreateBatch_201_IfImageOptimisationPolicySetForImage_AndLegacyEnabled() + { + const int customerId = 325665; + const int space = 201; + await dbContext.Customers.AddTestCustomer(customerId); + await dbContext.Spaces.AddTestSpace(customerId, space); + await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customerId); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customerId); + await dbContext.CustomerStorages.AddTestCustomerStorage(customerId); + await dbContext.SaveChangesAsync(); + + // Arrange + var hydraImageBody = @"{ + ""@context"": ""http://www.w3.org/ns/hydra/context.jsonld"", + ""@type"": ""Collection"", + ""member"": [ + { + ""@id"": ""https://test/customers/325665/spaces/201/images/one"", + ""origin"": ""https://example.org/my-image.png"", + ""imageOptimisationPolicy"": ""fast-higher"", + ""space"": 201, + }, + ] + }"; + + var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); + var path = $"/customers/{customerId}/queue"; + + // Act + var response = await httpClient.AsCustomer(customerId).PostAsync(path, content); + + // Assert + response.StatusCode.Should().Be(HttpStatusCode.Created); + + var image = dbContext.Images + .Include(a => a.ImageDeliveryChannels!) + .ThenInclude(dc => dc.DeliveryChannelPolicy) + .Single(i => i.Customer == customerId && i.Space == space); + + image.ImageDeliveryChannels!.Should().Satisfy( + dc => dc.Channel == AssetDeliveryChannels.Image && + dc.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ImageDefault, + dc => dc.Channel == AssetDeliveryChannels.Thumbnails && + dc.DeliveryChannelPolicy.Name == "default"); + } + + [Fact] + public async Task Post_CreateBatch_201_IfThumbnailPolicySetForImage_AndLegacyEnabled() + { + const int customerId = 325665; + const int space = 201; + await dbContext.Customers.AddTestCustomer(customerId); + await dbContext.Spaces.AddTestSpace(customerId, space); + await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customerId); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customerId); + await dbContext.CustomerStorages.AddTestCustomerStorage(customerId); + await dbContext.SaveChangesAsync(); + + // Arrange + var hydraImageBody = @"{ + ""@context"": ""http://www.w3.org/ns/hydra/context.jsonld"", + ""@type"": ""Collection"", + ""member"": [ + { + ""@id"": ""https://test/customers/325665/spaces/201/images/one"", + ""origin"": ""https://example.org/my-image.png"", + ""thumbnailPolicy"": ""default"", + ""space"": 201, + }, + ] + }"; + + var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); + var path = $"/customers/{customerId}/queue"; + + // Act + var response = await httpClient.AsCustomer(customerId).PostAsync(path, content); + + // Assert + response.StatusCode.Should().Be(HttpStatusCode.Created); + + var image = dbContext.Images + .Include(a => a.ImageDeliveryChannels!) + .ThenInclude(dc => dc.DeliveryChannelPolicy) + .Single(i => i.Customer == customerId && i.Space == space); + + image.ImageDeliveryChannels!.Should().Satisfy( + dc => dc.Channel == AssetDeliveryChannels.Image && + dc.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ImageDefault, + dc => dc.Channel == AssetDeliveryChannels.Thumbnails && + dc.DeliveryChannelPolicy.Name == "default"); + } + + [Fact] + public async Task Post_CreateBatch_201_IfImageOptimisationPolicySetForVideo_AndLegacyEnabled() + { + const int customerId = 325665; + const int space = 201; + await dbContext.Customers.AddTestCustomer(customerId); + await dbContext.Spaces.AddTestSpace(customerId, space); + await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customerId); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customerId); + await dbContext.CustomerStorages.AddTestCustomerStorage(customerId); + await dbContext.SaveChangesAsync(); + + // Arrange + var hydraImageBody = @"{ + ""@context"": ""http://www.w3.org/ns/hydra/context.jsonld"", + ""@type"": ""Collection"", + ""member"": [ + { + ""@id"": ""https://test/customers/325665/spaces/201/images/one"", + ""family"": ""T"", + ""origin"": ""https://example.org/my-video.mp4"", + ""imageOptimisationPolicy"": ""video-max"", + ""space"": 201, + }, + ] + }"; + + var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); + var path = $"/customers/{customerId}/queue"; + + // Act + var response = await httpClient.AsCustomer(customerId).PostAsync(path, content); + + // Assert + response.StatusCode.Should().Be(HttpStatusCode.Created); + + var image = dbContext.Images + .Include(a => a.ImageDeliveryChannels!) + .ThenInclude(dc => dc.DeliveryChannelPolicy) + .Single(i => i.Customer == customerId && i.Space == space); + + image.ImageDeliveryChannels!.Should().Satisfy( + dc => dc.Channel == AssetDeliveryChannels.Timebased && + dc.DeliveryChannelPolicy.Name == "default-video"); + } + + [Fact] + public async Task Post_CreateBatch_201_IfImageOptimisationPolicySetForAudio_AndLegacyEnabled() + { + const int customerId = 325665; + const int space = 201; + await dbContext.Customers.AddTestCustomer(customerId); + await dbContext.Spaces.AddTestSpace(customerId, space); + await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customerId); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customerId); + await dbContext.CustomerStorages.AddTestCustomerStorage(customerId); + await dbContext.SaveChangesAsync(); + + // Arrange + var hydraImageBody = @"{ + ""@context"": ""http://www.w3.org/ns/hydra/context.jsonld"", + ""@type"": ""Collection"", + ""member"": [ + { + ""@id"": ""https://test/customers/325665/spaces/201/images/one"", + ""family"": ""T"", + ""origin"": ""https://example.org/my-audio.mp3"", + ""imageOptimisationPolicy"": ""audio-max"", + ""space"": 201, + }, + ] + }"; + + var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); + var path = $"/customers/{customerId}/queue"; + + // Act + var response = await httpClient.AsCustomer(customerId).PostAsync(path, content); + + // Assert + response.StatusCode.Should().Be(HttpStatusCode.Created); + + var image = dbContext.Images + .Include(a => a.ImageDeliveryChannels!) + .ThenInclude(dc => dc.DeliveryChannelPolicy) + .Single(i => i.Customer == customerId && i.Space == space); + + image.ImageDeliveryChannels!.Should().Satisfy( + dc => dc.Channel == AssetDeliveryChannels.Timebased && + dc.DeliveryChannelPolicy.Name == "default-audio"); + } +} \ No newline at end of file From 8d9b8f180c6c129b99932180a276dec1384e1809 Mon Sep 17 00:00:00 2001 From: griffri Date: Fri, 31 May 2024 16:59:15 +0100 Subject: [PATCH 14/30] Reject bad ImageOptimisationPolicies and ThumbnailPolicies in LegacyModeConverter --- .../API/Converters/LegacyModeConverter.cs | 91 +++++++++++++------ 1 file changed, 61 insertions(+), 30 deletions(-) diff --git a/src/protagonist/API/Converters/LegacyModeConverter.cs b/src/protagonist/API/Converters/LegacyModeConverter.cs index 8f05adf77..28bbdac1f 100644 --- a/src/protagonist/API/Converters/LegacyModeConverter.cs +++ b/src/protagonist/API/Converters/LegacyModeConverter.cs @@ -1,4 +1,5 @@ -using DLCS.Core; +using API.Exceptions; +using DLCS.Core; using DLCS.Core.Collections; using DLCS.HydraModel; using DLCS.Model.Assets; @@ -57,57 +58,88 @@ public static T VerifyAndConvertToModernFormat(T image, bool emulateOldDelive public static DeliveryChannel[]? GetDeliveryChannelsForLegacyAsset(T image) where T : Image { - var thumbnailPolicy = image.ThumbnailPolicy.GetLastPathElement() ?? image.ThumbnailPolicy; var imageOptimisationPolicy = image.ImageOptimisationPolicy.GetLastPathElement() ?? image.ImageOptimisationPolicy; - + var thumbnailPolicy = image.ThumbnailPolicy.GetLastPathElement() ?? image.ThumbnailPolicy; + if (image.Family == AssetFamily.Image) { + string? imageChannelPolicy = null; + if (!imageOptimisationPolicy.IsNullOrEmpty()) + { + if (imageOptimisationPolicy == "fast-higher") + { + imageChannelPolicy = "default"; + } + else + { + throw new APIException($"'{imageOptimisationPolicy}' is not a valid imageOptimisationPolicy") + { + StatusCode = 400 + }; + } + } + + string? thumbsChannelPolicy = null; + if (!thumbnailPolicy.IsNullOrEmpty()) + { + if (thumbnailPolicy == "default") + { + thumbsChannelPolicy = "default"; + } + else + { + throw new APIException($"'{thumbnailPolicy}' is not a valid thumbnailPolicy") + { + StatusCode = 400 + }; + } + } + return new DeliveryChannel[] { new() { Channel = AssetDeliveryChannels.Image, - Policy = imageOptimisationPolicy == "fast-higher" - ? "default" - : null + Policy = imageChannelPolicy }, new() { Channel = AssetDeliveryChannels.Thumbnails, - Policy = thumbnailPolicy == "default" - ? "default" - : null + Policy = thumbsChannelPolicy }, }; } + if (image.Family == AssetFamily.Timebased) { - if(MIMEHelper.IsVideo(image.MediaType)) + string? avChannelPolicy = null; + if (!imageOptimisationPolicy.IsNullOrEmpty()) { - return new DeliveryChannel[] + if (imageOptimisationPolicy == "video-max") + { + avChannelPolicy = "default-video"; + } + else if (imageOptimisationPolicy == "audio-max") + { + avChannelPolicy = "default-audio"; + } + else { - new() + throw new APIException($"'{avChannelPolicy}' is not a valid imageOptimisationPolicy for a timebased asset") { - Channel = AssetDeliveryChannels.Timebased, - Policy = imageOptimisationPolicy == "video-max" - ? "default-video" - : null - } - }; + StatusCode = 400 + }; + } } - if (MIMEHelper.IsAudio(image.MediaType)) + + return new DeliveryChannel[] { - return new DeliveryChannel[] + new() { - new() - { - Channel = AssetDeliveryChannels.Timebased, - Policy = imageOptimisationPolicy == "audio-max" - ? "default-audio" - : null - } - }; - } + Channel = AssetDeliveryChannels.Timebased, + Policy = avChannelPolicy + } + }; } if (image.Family == AssetFamily.File) { @@ -123,5 +155,4 @@ public static T VerifyAndConvertToModernFormat(T image, bool emulateOldDelive return Array.Empty(); } - } \ No newline at end of file From 9301f6e31200829e481deafcdd125d8099b70def Mon Sep 17 00:00:00 2001 From: griffri Date: Fri, 31 May 2024 17:39:26 +0100 Subject: [PATCH 15/30] Add tests for legacy assets provided with an invalid IOP/TP --- ...etWithOldDeliveryChannelPropertiesTests.cs | 156 +++++++++++++++--- .../API/Converters/LegacyModeConverter.cs | 6 +- .../API/Features/Image/ImageController.cs | 14 +- 3 files changed, 148 insertions(+), 28 deletions(-) diff --git a/src/protagonist/API.Tests/Integration/ModifyAssetWithOldDeliveryChannelPropertiesTests.cs b/src/protagonist/API.Tests/Integration/ModifyAssetWithOldDeliveryChannelPropertiesTests.cs index 54b1fa06a..c5d0e08db 100644 --- a/src/protagonist/API.Tests/Integration/ModifyAssetWithOldDeliveryChannelPropertiesTests.cs +++ b/src/protagonist/API.Tests/Integration/ModifyAssetWithOldDeliveryChannelPropertiesTests.cs @@ -29,7 +29,6 @@ public class ModifyAssetWithOldDeliveryChannelPropertiesTests : IClassFixture(); - private readonly IAmazonS3 amazonS3; private static readonly IEngineClient EngineClient = A.Fake(); public ModifyAssetWithOldDeliveryChannelPropertiesTests( @@ -37,7 +36,6 @@ public ModifyAssetWithOldDeliveryChannelPropertiesTests( ProtagonistAppFactory factory) { var dbFixture = storageFixture.DbFixture; - amazonS3 = storageFixture.LocalStackFixture.AWSS3ClientFactory(); dbContext = dbFixture.DbContext; @@ -62,14 +60,13 @@ public ModifyAssetWithOldDeliveryChannelPropertiesTests( } [Theory] - [InlineData("default")] - [InlineData("https://api.dlc.services/thumbnailPolicies/default")] - public async Task Put_NewImageAsset_WithThumbnailPolicy_Creates_Asset_WhenLegacyEnabled(string thumbnailPolicy) + [InlineData("fast-higher")] + [InlineData("https://api.dlc.services/imageOptimisationPolicies/fast-higher")] + public async Task Put_NewImageAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled(string imageOptimisationPolicy) { const int customer = 325665; const int space = 2; - var assetId = new AssetId(customer, space, nameof(Put_NewImageAsset_WithThumbnailPolicy_Creates_Asset_WhenLegacyEnabled)); - + var assetId = new AssetId(customer, space, nameof(Put_NewImageAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled)); await dbContext.Customers.AddTestCustomer(customer); await dbContext.Spaces.AddTestSpace(customer, space); await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); @@ -77,9 +74,8 @@ public async Task Put_NewImageAsset_WithThumbnailPolicy_Creates_Asset_WhenLegacy await dbContext.SaveChangesAsync(); var hydraImageBody = $@"{{ - ""@type"": ""Image"", ""origin"": ""https://example.org/{assetId.Asset}.tiff"", - ""thumbnailPolicy"": ""{thumbnailPolicy}"" + ""imageOptimisationPolicy"" : ""{imageOptimisationPolicy}"" }}"; A.CallTo(() => @@ -100,23 +96,52 @@ public async Task Put_NewImageAsset_WithThumbnailPolicy_Creates_Asset_WhenLegacy asset.Id.Should().Be(assetId); asset.MediaType.Should().Be("image/tiff"); asset.Family.Should().Be(AssetFamily.Image); - asset.ThumbnailPolicy.Should().Be("default"); - asset.ImageOptimisationPolicy.Should().BeEmpty(); + asset.ImageOptimisationPolicy.Should().Be("fast-higher"); + asset.ThumbnailPolicy.Should().BeEmpty(); asset.ImageDeliveryChannels.Count.Should().Be(2); asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == "iiif-img" && dc.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ImageDefault); asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == "thumbs" && - dc.DeliveryChannelPolicy.Name == "default"); + dc.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ThumbsDefault); } + + [Fact] + public async Task Put_NewImageAsset_WithImageOptimisationPolicy_Returns400_IfInvalid_AndLegacyEnabled() + { + const int customer = 325665; + const int space = 2; + var assetId = new AssetId(customer, space, nameof(Put_NewImageAsset_WithImageOptimisationPolicy_Returns400_IfInvalid_AndLegacyEnabled)); + await dbContext.Customers.AddTestCustomer(customer); + await dbContext.Spaces.AddTestSpace(customer, space); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); + await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); + await dbContext.SaveChangesAsync(); + var hydraImageBody = $@"{{ + ""origin"": ""https://example.org/{assetId.Asset}.tiff"", + ""imageOptimisationPolicy"" : ""foo"" + }}"; + + // act + var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); + var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + + // assert + response.StatusCode.Should().Be(HttpStatusCode.BadRequest); + + var body = await response.Content.ReadAsStringAsync(); + body.Should().Contain("'foo' is not a valid imageOptimisationPolicy for an image"); + } + [Theory] - [InlineData("fast-higher")] - [InlineData("https://api.dlc.services/imageOptimisationPolicies/fast-higher")] - public async Task Put_NewImageAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled(string imageOptimisationPolicy) + [InlineData("default")] + [InlineData("https://api.dlc.services/thumbnailPolicies/default")] + public async Task Put_NewImageAsset_WithThumbnailPolicy_Creates_Asset_WhenLegacyEnabled(string thumbnailPolicy) { const int customer = 325665; const int space = 2; - var assetId = new AssetId(customer, space, nameof(Put_NewImageAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled)); + var assetId = new AssetId(customer, space, nameof(Put_NewImageAsset_WithThumbnailPolicy_Creates_Asset_WhenLegacyEnabled)); + await dbContext.Customers.AddTestCustomer(customer); await dbContext.Spaces.AddTestSpace(customer, space); await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); @@ -124,8 +149,9 @@ public async Task Put_NewImageAsset_WithImageOptimisationPolicy_Creates_Asset_Wh await dbContext.SaveChangesAsync(); var hydraImageBody = $@"{{ + ""@type"": ""Image"", ""origin"": ""https://example.org/{assetId.Asset}.tiff"", - ""imageOptimisationPolicy"" : ""{imageOptimisationPolicy}"" + ""thumbnailPolicy"": ""{thumbnailPolicy}"" }}"; A.CallTo(() => @@ -146,13 +172,41 @@ public async Task Put_NewImageAsset_WithImageOptimisationPolicy_Creates_Asset_Wh asset.Id.Should().Be(assetId); asset.MediaType.Should().Be("image/tiff"); asset.Family.Should().Be(AssetFamily.Image); - asset.ImageOptimisationPolicy.Should().Be("fast-higher"); - asset.ThumbnailPolicy.Should().BeEmpty(); + asset.ThumbnailPolicy.Should().Be("default"); + asset.ImageOptimisationPolicy.Should().BeEmpty(); asset.ImageDeliveryChannels.Count.Should().Be(2); asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == "iiif-img" && dc.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ImageDefault); asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == "thumbs" && - dc.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ThumbsDefault); + dc.DeliveryChannelPolicy.Name == "default"); + } + + [Fact] + public async Task Put_NewImageAsset_WithThumbnailPolicy_Returns400_IfInvalid_AndLegacyEnabled() + { + const int customer = 325665; + const int space = 2; + var assetId = new AssetId(customer, space, nameof(Put_NewImageAsset_WithImageOptimisationPolicy_Returns400_IfInvalid_AndLegacyEnabled)); + await dbContext.Customers.AddTestCustomer(customer); + await dbContext.Spaces.AddTestSpace(customer, space); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); + await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); + await dbContext.SaveChangesAsync(); + + var hydraImageBody = $@"{{ + ""origin"": ""https://example.org/{assetId.Asset}.tiff"", + ""thumbnailPolicy"" : ""foo"" + }}"; + + // act + var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); + var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + + // assert + response.StatusCode.Should().Be(HttpStatusCode.BadRequest); + + var body = await response.Content.ReadAsStringAsync(); + body.Should().Contain("'foo' is not a valid thumbnailPolicy for an image"); } [Theory] @@ -162,7 +216,7 @@ public async Task Put_NewVideoAsset_WithImageOptimisationPolicy_Creates_Asset_Wh { const int customer = 325665; const int space = 2; - var assetId = new AssetId(customer, space, nameof(Put_NewImageAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled)); + var assetId = new AssetId(customer, space, nameof(Put_NewVideoAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled)); await dbContext.Customers.AddTestCustomer(customer); await dbContext.Spaces.AddTestSpace(customer, space); await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); @@ -200,6 +254,35 @@ public async Task Put_NewVideoAsset_WithImageOptimisationPolicy_Creates_Asset_Wh dc.DeliveryChannelPolicy.Name == "default-video"); } + [Fact] + public async Task Put_NewVideoAsset_WithImageOptimisationPolicy_Returns400_IfInvalid_AndLegacyEnabled() + { + const int customer = 325665; + const int space = 2; + var assetId = new AssetId(customer, space, nameof(Put_NewVideoAsset_WithImageOptimisationPolicy_Returns400_IfInvalid_AndLegacyEnabled)); + await dbContext.Customers.AddTestCustomer(customer); + await dbContext.Spaces.AddTestSpace(customer, space); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); + await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); + await dbContext.SaveChangesAsync(); + + var hydraImageBody = $@"{{ + ""family"": ""T"", + ""origin"": ""https://example.org/{assetId.Asset}.mp4"", + ""imageOptimisationPolicy"" : ""foo"" + }}"; + + // act + var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); + var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + + // assert + response.StatusCode.Should().Be(HttpStatusCode.BadRequest); + + var body = await response.Content.ReadAsStringAsync(); + body.Should().Contain("'foo' is not a valid imageOptimisationPolicy for a timebased asset"); + } + [Theory] [InlineData("audio-max")] [InlineData("https://api.dlc.services/imageOptimisationPolicy/audio-max")] @@ -207,7 +290,7 @@ public async Task Put_NewAudioAsset_WithImageOptimisationPolicy_Creates_Asset_Wh { const int customer = 325665; const int space = 2; - var assetId = new AssetId(customer, space, nameof(Put_NewImageAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled)); + var assetId = new AssetId(customer, space, nameof(Put_NewAudioAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled)); await dbContext.Customers.AddTestCustomer(customer); await dbContext.Spaces.AddTestSpace(customer, space); await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); @@ -244,4 +327,33 @@ public async Task Put_NewAudioAsset_WithImageOptimisationPolicy_Creates_Asset_Wh asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == "iiif-av" && dc.DeliveryChannelPolicy.Name == "default-audio"); } + + [Fact] + public async Task Put_NewAudioAsset_WithImageOptimisationPolicy_Returns400_IfInvalid_AndLegacyEnabled() + { + const int customer = 325665; + const int space = 2; + var assetId = new AssetId(customer, space, nameof(Put_NewAudioAsset_WithImageOptimisationPolicy_Returns400_IfInvalid_AndLegacyEnabled)); + await dbContext.Customers.AddTestCustomer(customer); + await dbContext.Spaces.AddTestSpace(customer, space); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); + await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); + await dbContext.SaveChangesAsync(); + + var hydraImageBody = $@"{{ + ""family"": ""T"", + ""origin"": ""https://example.org/{assetId.Asset}.mp3"", + ""imageOptimisationPolicy"" : ""foo"" + }}"; + + // act + var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); + var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + + // assert + response.StatusCode.Should().Be(HttpStatusCode.BadRequest); + + var body = await response.Content.ReadAsStringAsync(); + body.Should().Contain("'foo' is not a valid imageOptimisationPolicy for a timebased asset"); + } } \ No newline at end of file diff --git a/src/protagonist/API/Converters/LegacyModeConverter.cs b/src/protagonist/API/Converters/LegacyModeConverter.cs index 28bbdac1f..d148f7116 100644 --- a/src/protagonist/API/Converters/LegacyModeConverter.cs +++ b/src/protagonist/API/Converters/LegacyModeConverter.cs @@ -72,7 +72,7 @@ public static T VerifyAndConvertToModernFormat(T image, bool emulateOldDelive } else { - throw new APIException($"'{imageOptimisationPolicy}' is not a valid imageOptimisationPolicy") + throw new APIException($"'{imageOptimisationPolicy}' is not a valid imageOptimisationPolicy for an image") { StatusCode = 400 }; @@ -88,7 +88,7 @@ public static T VerifyAndConvertToModernFormat(T image, bool emulateOldDelive } else { - throw new APIException($"'{thumbnailPolicy}' is not a valid thumbnailPolicy") + throw new APIException($"'{thumbnailPolicy}' is not a valid thumbnailPolicy for an image") { StatusCode = 400 }; @@ -125,7 +125,7 @@ public static T VerifyAndConvertToModernFormat(T image, bool emulateOldDelive } else { - throw new APIException($"'{avChannelPolicy}' is not a valid imageOptimisationPolicy for a timebased asset") + throw new APIException($"'{imageOptimisationPolicy}' is not a valid imageOptimisationPolicy for a timebased asset") { StatusCode = 400 }; diff --git a/src/protagonist/API/Features/Image/ImageController.cs b/src/protagonist/API/Features/Image/ImageController.cs index be67e31cd..c0810b87b 100644 --- a/src/protagonist/API/Features/Image/ImageController.cs +++ b/src/protagonist/API/Features/Image/ImageController.cs @@ -1,6 +1,6 @@ using System.Net; using API.Converters; -using API.Features.DeliveryChannels.Converters; +using API.Exceptions; using API.Features.Image.Requests; using API.Features.Image.Validation; using API.Infrastructure; @@ -97,8 +97,16 @@ public async Task PutImage( { if (Settings.LegacyModeEnabledForSpace(customerId, spaceId)) { - hydraAsset = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraAsset, - Settings.EmulateOldDeliveryChannelProperties); + try + { + hydraAsset = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraAsset, + Settings.EmulateOldDeliveryChannelProperties); + } + catch (APIException apiEx) + { + return this.HydraProblem(apiEx.Message, null, + (int?)HttpStatusCode.BadRequest, "Failed to convert legacy asset"); + } } if (hydraAsset.ModelId == null) From ff72ef811481aaba8d27e868116671b14bdae990 Mon Sep 17 00:00:00 2001 From: griffri Date: Mon, 3 Jun 2024 08:53:57 +0100 Subject: [PATCH 16/30] Add tests for LegacyModeConverter errors Clean up DB when setting up CustomerQueueWithOldDeliveryChannelPropertiesTests --- .../Converters/LegacyModeConverterTests.cs | 65 ++++++++++++++++++- ...ueWithOldDeliveryChannelPropertiesTests.cs | 2 + .../API/Converters/LegacyModeConverter.cs | 1 + 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/src/protagonist/API.Tests/Converters/LegacyModeConverterTests.cs b/src/protagonist/API.Tests/Converters/LegacyModeConverterTests.cs index 74769fd35..935b0405d 100644 --- a/src/protagonist/API.Tests/Converters/LegacyModeConverterTests.cs +++ b/src/protagonist/API.Tests/Converters/LegacyModeConverterTests.cs @@ -1,4 +1,6 @@ -using API.Converters; +using System; +using API.Converters; +using API.Exceptions; using DLCS.HydraModel; using DLCS.Model.Assets; using AssetFamily = DLCS.HydraModel.AssetFamily; @@ -442,4 +444,65 @@ public void VerifyAndConvertToModernFormat_AddsTimebasedDeliveryChannelWithPolic dc => dc.Channel == AssetDeliveryChannels.Timebased && dc.Policy == "default-audio"); } + + [Fact] + public void VerifyAndConvertToModernFormat_Fails_WhenInvalidImageOptimisationPolicySpecified_ForImageAsset() + { + // Arrange + var hydraImage = new Image() + { + Origin = "something.tiff", + ImageOptimisationPolicy = "not-a-policy" + }; + + // Act + Action action = () => + LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, true); + + // Assert + action.Should() + .ThrowExactly() + .WithMessage($"'not-a-policy' is not a valid imageOptimisationPolicy for an image"); + } + + [Fact] + public void VerifyAndConvertToModernFormat_Fails_WhenInvalidThumbnailPolicySpecified_ForImageAsset() + { + // Arrange + var hydraImage = new Image() + { + Origin = "something.tiff", + ThumbnailPolicy = "not-a-policy" + }; + + // Act + Action action = () => + LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, true); + + // Assert + action.Should() + .ThrowExactly() + .WithMessage($"'not-a-policy' is not a valid thumbnailPolicy for an image"); + } + + [Fact] + public void VerifyAndConvertToModernFormat_Fails_WhenImageOptimisationPolicySpecified_ForTimebasedAsset() + { + // Arrange + var hydraImage = new Image() + { + Family = AssetFamily.Timebased, + Origin = "something.mp4", + ImageOptimisationPolicy= "not-a-policy" + }; + + // Act + Action action = () => + LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, true); + + // Assert + action.Should() + .ThrowExactly() + .WithMessage($"'not-a-policy' is not a valid imageOptimisationPolicy for a timebased asset"); + } } \ No newline at end of file diff --git a/src/protagonist/API.Tests/Integration/CustomerQueueWithOldDeliveryChannelPropertiesTests.cs b/src/protagonist/API.Tests/Integration/CustomerQueueWithOldDeliveryChannelPropertiesTests.cs index 4711209d8..adb96dea5 100644 --- a/src/protagonist/API.Tests/Integration/CustomerQueueWithOldDeliveryChannelPropertiesTests.cs +++ b/src/protagonist/API.Tests/Integration/CustomerQueueWithOldDeliveryChannelPropertiesTests.cs @@ -43,6 +43,8 @@ public CustomerQueueWithOldDeliveryChannelPropertiesTests(DlcsDatabaseFixture db { AllowAutoRedirect = false }); + + dbFixture.CleanUp(); } [Fact] diff --git a/src/protagonist/API/Converters/LegacyModeConverter.cs b/src/protagonist/API/Converters/LegacyModeConverter.cs index d148f7116..66c361446 100644 --- a/src/protagonist/API/Converters/LegacyModeConverter.cs +++ b/src/protagonist/API/Converters/LegacyModeConverter.cs @@ -58,6 +58,7 @@ public static T VerifyAndConvertToModernFormat(T image, bool emulateOldDelive public static DeliveryChannel[]? GetDeliveryChannelsForLegacyAsset(T image) where T : Image { + // Retrieve the name, if it is a path to a DLCS IOP/TP policy resource var imageOptimisationPolicy = image.ImageOptimisationPolicy.GetLastPathElement() ?? image.ImageOptimisationPolicy; var thumbnailPolicy = image.ThumbnailPolicy.GetLastPathElement() ?? image.ThumbnailPolicy; From c5066140e662e68317035782e0cc11bc84943c31 Mon Sep 17 00:00:00 2001 From: griffri Date: Mon, 3 Jun 2024 11:04:40 +0100 Subject: [PATCH 17/30] Add test for file asset creation --- ...etWithOldDeliveryChannelPropertiesTests.cs | 56 +++++++++++++++++-- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/src/protagonist/API.Tests/Integration/ModifyAssetWithOldDeliveryChannelPropertiesTests.cs b/src/protagonist/API.Tests/Integration/ModifyAssetWithOldDeliveryChannelPropertiesTests.cs index c5d0e08db..b9254b1c6 100644 --- a/src/protagonist/API.Tests/Integration/ModifyAssetWithOldDeliveryChannelPropertiesTests.cs +++ b/src/protagonist/API.Tests/Integration/ModifyAssetWithOldDeliveryChannelPropertiesTests.cs @@ -99,9 +99,9 @@ public async Task Put_NewImageAsset_WithImageOptimisationPolicy_Creates_Asset_Wh asset.ImageOptimisationPolicy.Should().Be("fast-higher"); asset.ThumbnailPolicy.Should().BeEmpty(); asset.ImageDeliveryChannels.Count.Should().Be(2); - asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == "iiif-img" && + asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == AssetDeliveryChannels.Image && dc.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ImageDefault); - asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == "thumbs" && + asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == AssetDeliveryChannels.Thumbnails && dc.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ThumbsDefault); } @@ -175,9 +175,9 @@ public async Task Put_NewImageAsset_WithThumbnailPolicy_Creates_Asset_WhenLegacy asset.ThumbnailPolicy.Should().Be("default"); asset.ImageOptimisationPolicy.Should().BeEmpty(); asset.ImageDeliveryChannels.Count.Should().Be(2); - asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == "iiif-img" && + asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == AssetDeliveryChannels.Image && dc.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ImageDefault); - asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == "thumbs" && + asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == AssetDeliveryChannels.Thumbnails && dc.DeliveryChannelPolicy.Name == "default"); } @@ -250,7 +250,7 @@ public async Task Put_NewVideoAsset_WithImageOptimisationPolicy_Creates_Asset_Wh asset.ImageOptimisationPolicy.Should().Be(imageOptimisationPolicy); asset.ThumbnailPolicy.Should().BeEmpty(); asset.ImageDeliveryChannels.Count.Should().Be(1); - asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == "iiif-av" && + asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == AssetDeliveryChannels.Timebased && dc.DeliveryChannelPolicy.Name == "default-video"); } @@ -324,7 +324,7 @@ public async Task Put_NewAudioAsset_WithImageOptimisationPolicy_Creates_Asset_Wh asset.ImageOptimisationPolicy.Should().Be(imageOptimisationPolicy); asset.ThumbnailPolicy.Should().BeEmpty(); asset.ImageDeliveryChannels.Count.Should().Be(1); - asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == "iiif-av" && + asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == AssetDeliveryChannels.Timebased && dc.DeliveryChannelPolicy.Name == "default-audio"); } @@ -356,4 +356,48 @@ public async Task Put_NewAudioAsset_WithImageOptimisationPolicy_Returns400_IfInv var body = await response.Content.ReadAsStringAsync(); body.Should().Contain("'foo' is not a valid imageOptimisationPolicy for a timebased asset"); } + + [Fact] + public async Task Put_NewFileAsset_Creates_Asset_WhenLegacyEnabled() + { + const int customer = 325665; + const int space = 2; + var assetId = new AssetId(customer, space, nameof(Put_NewImageAsset_WithThumbnailPolicy_Creates_Asset_WhenLegacyEnabled)); + + await dbContext.Customers.AddTestCustomer(customer); + await dbContext.Spaces.AddTestSpace(customer, space); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); + await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); + await dbContext.SaveChangesAsync(); + + var hydraImageBody = $@"{{ + ""@type"": ""Image"", + ""family"": ""F"", + ""origin"": ""https://example.org/{assetId.Asset}.pdf"", + }}"; + + A.CallTo(() => + EngineClient.SynchronousIngest( + A.That.Matches(r => r.Id == assetId), + A._)) + .Returns(HttpStatusCode.OK); + + // act + var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); + var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + + // assert + response.StatusCode.Should().Be(HttpStatusCode.Created); + + var asset = dbContext.Images.Include(i => i.ImageDeliveryChannels) + .ThenInclude(i => i.DeliveryChannelPolicy).Single(i => i.Id == assetId); + asset.Id.Should().Be(assetId); + asset.MediaType.Should().Be("application/pdf"); + asset.Family.Should().Be(AssetFamily.File); + asset.ThumbnailPolicy.Should().BeEmpty(); + asset.ImageOptimisationPolicy.Should().BeEmpty(); + asset.ImageDeliveryChannels.Count.Should().Be(1); + asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == AssetDeliveryChannels.File && + dc.DeliveryChannelPolicy.Name == "none"); + } } \ No newline at end of file From 8b525eb31731042bdb827f94e494c5869aa98485 Mon Sep 17 00:00:00 2001 From: griffri Date: Mon, 3 Jun 2024 13:06:14 +0100 Subject: [PATCH 18/30] Remove EmulateOldDeliveryChannelProperties setting Merge `WithOldDeliveryChannelProperties` tests with main test files --- .../Converters/LegacyModeConverterTests.cs | 154 +------ .../Validation/HydraImageValidatorTests.cs | 34 +- .../Validation/QueuePostValidatorTests.cs | 21 +- .../Integration/CustomerQueueTests.cs | 196 ++++++++- ...ueWithOldDeliveryChannelPropertiesTests.cs | 235 ---------- .../API.Tests/Integration/ModifyAssetTests.cs | 349 ++++++++++++++- ...etWithOldDeliveryChannelPropertiesTests.cs | 403 ------------------ .../API/Converters/LegacyModeConverter.cs | 18 +- .../API/Features/Image/ImageController.cs | 3 +- .../Image/Validation/HydraImageValidator.cs | 14 +- .../Queues/CustomerQueueController.cs | 3 +- .../Queues/Validation/QueuePostValidator.cs | 12 +- src/protagonist/API/Settings/ApiSettings.cs | 6 - 13 files changed, 584 insertions(+), 864 deletions(-) delete mode 100644 src/protagonist/API.Tests/Integration/CustomerQueueWithOldDeliveryChannelPropertiesTests.cs delete mode 100644 src/protagonist/API.Tests/Integration/ModifyAssetWithOldDeliveryChannelPropertiesTests.cs diff --git a/src/protagonist/API.Tests/Converters/LegacyModeConverterTests.cs b/src/protagonist/API.Tests/Converters/LegacyModeConverterTests.cs index 935b0405d..8e9b66330 100644 --- a/src/protagonist/API.Tests/Converters/LegacyModeConverterTests.cs +++ b/src/protagonist/API.Tests/Converters/LegacyModeConverterTests.cs @@ -16,7 +16,7 @@ public void VerifyAndConvertToModernFormat_ChangesNothing_WithNewFormat() var hydraImage = new Image{ MediaType = "type", MaxUnauthorised = 5, Family = AssetFamily.File}; // Act - var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, false); + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage); // Assert convertedImage.MediaType.Should().Be(hydraImage.MediaType); @@ -31,7 +31,7 @@ public void VerifyAndConvertToModernFormat_SetsMediaType_WithNotSet() var hydraImage = new Image{ MaxUnauthorised = 5, Family = AssetFamily.File}; // Act - var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, false); + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage); // Assert convertedImage.MediaType.Should().Be("image/unknown"); @@ -46,7 +46,7 @@ public void VerifyAndConvertToModernFormat_InferMediaType_WhenOriginSet() var hydraImage = new Image{ Origin = "something.jpg",MaxUnauthorised = 5, Family = AssetFamily.File}; // Act - var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage,false); + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage); // Assert convertedImage.MediaType.Should().Be("image/jpeg"); @@ -61,7 +61,7 @@ public void VerifyAndConvertToModernFormat_SetMaxUnauthorised_WhenSetToOldFormat var hydraImage = new Image{ Origin = "something.jpg",MaxUnauthorised = 0, Family = AssetFamily.File}; // Act - var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, false); + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage); // Assert convertedImage.MediaType.Should().Be("image/jpeg"); @@ -76,7 +76,7 @@ public void VerifyAndConvertToModernFormat_SetFamily_WhenNotSet() var hydraImage = new Image{ Origin = "something.jpg"}; // Act - var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, false); + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage); // Assert convertedImage.MediaType.Should().Be("image/jpeg"); @@ -91,7 +91,7 @@ public void VerifyAndConvertToModernFormat_MaxUnauthorisedUnchanged_WhenRolesSet var hydraImage = new Image{ Origin = "something.jpg", Roles = new []{ "some role" }}; // Act - var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, false); + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage); // Assert convertedImage.MediaType.Should().Be("image/jpeg"); @@ -106,125 +106,11 @@ public void VerifyAndConvertToModernFormat_ModelIdSet_WhenNoModelId() var hydraImage = new Image{ Id = "https://test/someId", MediaType = "something"}; // Act - var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, false); + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage); // Assert convertedImage.ModelId.Should().Be("someId"); } - - [Fact] - public void VerifyAndConvertToModernFormat_AddsNoDeliveryChannels_WhenOldDeliveryChannelPropertiesDisabled_ForImage() - { - // Arrange - var hydraImage = new Image() - { - Family = AssetFamily.Image, - Origin = "something.jpg", - }; - - // Act - var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, false); - - // Assert - convertedImage.DeliveryChannels.Should().BeNullOrEmpty(); - } - - [Theory] - [InlineData("fast-higher")] - [InlineData("https://api.dlc.services/imageOptimisationPolicies/fast-higher")] - public void VerifyAndConvertToModernFormat_AddsNoDeliveryChannels_WhenOldDeliveryChannelPropertiesDisabled_AndImageOptimisationPolicyValid_ForImage( - string imageOptimisationPolicy) - { - // Arrange - var hydraImage = new Image() - { - Family = AssetFamily.Image, - Origin = "something.jpg", - ImageOptimisationPolicy = imageOptimisationPolicy - }; - - // Act - var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, false); - - // Assert - convertedImage.DeliveryChannels.Should().BeNullOrEmpty(); - } - - [Fact] - public void VerifyAndConvertToModernFormat_AddsNoDeliveryChannels_WhenOldDeliveryChannelPropertiesDisabled_ForVideo() - { - // Arrange - var hydraImage = new Image() - { - Family = AssetFamily.Timebased, - Origin = "something.mp4", - }; - - // Act - var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, false); - - // Assert - convertedImage.DeliveryChannels.Should().BeNullOrEmpty(); - } - - [Theory] - [InlineData("video-max")] - [InlineData("https://api.dlc.services/imageOptimisationPolicies/video-max")] - public void VerifyAndConvertToModernFormat_AddsNoDeliveryChannels_WhenOldDeliveryChannelPropertiesDisabled_AndImageOptimisationPolicyValid_ForVideo( - string imageOptimisationPolicy) - { - // Arrange - var hydraImage = new Image() - { - Family = AssetFamily.Timebased, - Origin = "something.mp4", - ImageOptimisationPolicy = imageOptimisationPolicy - }; - - // Act - var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, false); - - // Assert - convertedImage.DeliveryChannels.Should().BeNullOrEmpty(); - } - - [Fact] - public void VerifyAndConvertToModernFormat_AddsNoDeliveryChannels_WhenOldDeliveryChannelPropertiesDisabled_ForAudio() - { - // Arrange - var hydraImage = new Image() - { - Family = AssetFamily.Timebased, - Origin = "something.mp3", - }; - - // Act - var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, false); - - // Assert - convertedImage.DeliveryChannels.Should().BeNullOrEmpty(); - } - - [Theory] - [InlineData("audio-max")] - [InlineData("https://api.dlc.services/imageOptimisationPolicies/audio-max")] - public void VerifyAndConvertToModernFormat_AddsNoDeliveryChannels_WhenOldDeliveryChannelPropertiesDisabled_AndImageOptimisationPolicyValid_ForAudio( - string imageOptimisationPolicy) - { - // Arrange - var hydraImage = new Image() - { - Family = AssetFamily.Timebased, - Origin = "something.mp3", - ImageOptimisationPolicy = imageOptimisationPolicy - }; - - // Act - var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, false); - - // Assert - convertedImage.DeliveryChannels.Should().BeNullOrEmpty(); - } [Fact] public void VerifyAndConvertToModernFormat_AddsDeliveryChannels_WhenNotSet_ForImage() @@ -237,7 +123,7 @@ public void VerifyAndConvertToModernFormat_AddsDeliveryChannels_WhenNotSet_ForIm }; // Act - var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, true); + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage); // Assert convertedImage.DeliveryChannels.Should().Satisfy( @@ -258,7 +144,7 @@ public void VerifyAndConvertToModernFormat_AddsDeliveryChannels_WhenNotSet_ForVi }; // Act - var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, true); + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage); // Assert convertedImage.DeliveryChannels.Should().Satisfy( @@ -277,7 +163,7 @@ public void VerifyAndConvertToModernFormat_AddsDeliveryChannels_WhenNotSet_ForAu }; // Act - var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, true); + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage); // Assert convertedImage.DeliveryChannels.Should().Satisfy( @@ -296,7 +182,7 @@ public void VerifyAndConvertToModernFormat_AddsDeliveryChannels_WhenNotSet_ForFi }; // Act - var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, true); + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage); // Assert convertedImage.DeliveryChannels.Should().Satisfy( @@ -317,7 +203,7 @@ public void VerifyAndConvertToModernFormat_TreatsAsImage_ForNonImagesWithoutFami }; // Act - var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, true); + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage); // Assert convertedImage.DeliveryChannels.Should().Satisfy( @@ -339,7 +225,7 @@ public void VerifyAndConvertToModernFormat_AddsImageDeliveryChannelsWithPolicies }; // Act - var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, true); + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage); // Assert convertedImage.DeliveryChannels.Should().Satisfy( @@ -363,7 +249,7 @@ public void VerifyAndConvertToModernFormat_AddsImageDeliveryChannelsWithPolicies }; // Act - var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, true); + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage); // Assert convertedImage.DeliveryChannels.Should().Satisfy( @@ -389,7 +275,7 @@ public void VerifyAndConvertToModernFormat_AddsImageDeliveryChannelsWithPolicies }; // Act - var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, true); + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage); // Assert convertedImage.DeliveryChannels.Should().Satisfy( @@ -414,7 +300,7 @@ public void VerifyAndConvertToModernFormat_AddsTimebasedDeliveryChannelWithPolic }; // Act - var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, true); + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage); // Assert convertedImage.DeliveryChannels.Should().Satisfy( @@ -437,7 +323,7 @@ public void VerifyAndConvertToModernFormat_AddsTimebasedDeliveryChannelWithPolic }; // Act - var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, true); + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage); // Assert convertedImage.DeliveryChannels.Should().Satisfy( @@ -457,7 +343,7 @@ public void VerifyAndConvertToModernFormat_Fails_WhenInvalidImageOptimisationPol // Act Action action = () => - LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, true); + LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage); // Assert action.Should() @@ -477,7 +363,7 @@ public void VerifyAndConvertToModernFormat_Fails_WhenInvalidThumbnailPolicySpeci // Act Action action = () => - LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, true); + LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage); // Assert action.Should() @@ -498,7 +384,7 @@ public void VerifyAndConvertToModernFormat_Fails_WhenImageOptimisationPolicySpec // Act Action action = () => - LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage, true); + LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage); // Assert action.Should() diff --git a/src/protagonist/API.Tests/Features/Images/Validation/HydraImageValidatorTests.cs b/src/protagonist/API.Tests/Features/Images/Validation/HydraImageValidatorTests.cs index 7c09d77cd..0fb554efc 100644 --- a/src/protagonist/API.Tests/Features/Images/Validation/HydraImageValidatorTests.cs +++ b/src/protagonist/API.Tests/Features/Images/Validation/HydraImageValidatorTests.cs @@ -9,16 +9,14 @@ namespace API.Tests.Features.Images.Validation; public class HydraImageValidatorTests { - public HydraImageValidator GetSut(bool emulateOldDeliveryChannelProperties = false) + public HydraImageValidator GetSut() { var apiSettings = new ApiSettings() { - RestrictedAssetIdCharacterString = "\\ ", - EmulateOldDeliveryChannelProperties = emulateOldDeliveryChannelProperties + RestrictedAssetIdCharacterString = "\\ " }; return new HydraImageValidator(Options.Create(apiSettings)); } - [Theory] [InlineData(null)] @@ -230,7 +228,7 @@ public void DeliveryChannel_ValidationError_WhenEmpty_OnPatch() } [Fact] - public void ImageOptimisationPolicy_ValidationError_WhenOldDeliveryChannelEmulationDisabled() + public void ImageOptimisationPolicy_ValidationError() { var sut = GetSut(); var model = new Image @@ -242,7 +240,7 @@ public void ImageOptimisationPolicy_ValidationError_WhenOldDeliveryChannelEmulat } [Fact] - public void ThumbnailPolicy_ValidationError_WhenOldDeliveryChannelEmulationDisabled() + public void ThumbnailPolicy_ValidationError() { var sut = GetSut(); var model = new Image @@ -252,28 +250,4 @@ public void ThumbnailPolicy_ValidationError_WhenOldDeliveryChannelEmulationDisab var result = sut.TestValidate(model); result.ShouldHaveValidationErrorFor(a => a.ThumbnailPolicy); } - - [Fact] - public void ImageOptimisationPolicy_NoValidationError_WhenOldDeliveryChannelEmulationEnabled() - { - var sut = GetSut(true); - var model = new Image - { - ImageOptimisationPolicy = "some-iop-policy" - }; - var result = sut.TestValidate(model); - result.ShouldNotHaveValidationErrorFor(a => a.ImageOptimisationPolicy); - } - - [Fact] - public void ThumbnailPolicy_NoValidationError_WhenOldDeliveryChannelEmulationEnabled() - { - var sut = GetSut(true); - var model = new Image - { - ThumbnailPolicy = "some-tp-policy" - }; - var result = sut.TestValidate(model); - result.ShouldNotHaveValidationErrorFor(a => a.ThumbnailPolicy); - } } \ No newline at end of file diff --git a/src/protagonist/API.Tests/Features/Queues/Validation/QueuePostValidatorTests.cs b/src/protagonist/API.Tests/Features/Queues/Validation/QueuePostValidatorTests.cs index d7c800aaa..e4711cfb9 100644 --- a/src/protagonist/API.Tests/Features/Queues/Validation/QueuePostValidatorTests.cs +++ b/src/protagonist/API.Tests/Features/Queues/Validation/QueuePostValidatorTests.cs @@ -10,11 +10,10 @@ namespace API.Tests.Features.Queues.Validation; public class QueuePostValidatorTests { - private QueuePostValidator GetSut(bool emulateOldDeliveryChannelProperties = false) + private QueuePostValidator GetSut() { var apiSettings = new ApiSettings { - EmulateOldDeliveryChannelProperties = emulateOldDeliveryChannelProperties, MaxBatchSize = 4 }; @@ -206,22 +205,4 @@ public void Member_ThumbnailPolicy_Provided() var result = sut.TestValidate(model); result.ShouldHaveValidationErrorFor("Members[0].ThumbnailPolicy"); } - - [Fact] - public void Member_ImageOptimisationPolicy_Allowed_WhenOldDeliveryChannelEmulationEnabled() - { - var sut = GetSut(true); - var model = new HydraCollection { Members = new[] { new Image { ImageOptimisationPolicy = "my-policy" } } }; - var result = sut.TestValidate(model); - result.ShouldNotHaveValidationErrorFor("Members[0].ImageOptimisationPolicy"); - } - - [Fact] - public void Member_ThumbnailPolicy_Allowed_WhenOldDeliveryChannelEmulationEnabled() - { - var sut = GetSut(true); - var model = new HydraCollection { Members = new[] { new Image { ThumbnailPolicy = "my-policy" } } }; - var result = sut.TestValidate(model); - result.ShouldNotHaveValidationErrorFor("Members[0].ThumbnailPolicy"); - } } \ No newline at end of file diff --git a/src/protagonist/API.Tests/Integration/CustomerQueueTests.cs b/src/protagonist/API.Tests/Integration/CustomerQueueTests.cs index 8a66746c8..a0c2cc16f 100644 --- a/src/protagonist/API.Tests/Integration/CustomerQueueTests.cs +++ b/src/protagonist/API.Tests/Integration/CustomerQueueTests.cs @@ -10,6 +10,7 @@ using API.Tests.Integration.Infrastructure; using DLCS.Core.Types; using DLCS.Model.Assets; +using DLCS.Model.Policies; using DLCS.Repository; using DLCS.Repository.Messaging; using FakeItEasy; @@ -535,6 +536,7 @@ public async Task Post_CreateBatch_201_IfLegacyModeEnabled() await dbContext.Customers.AddTestCustomer(customerId); await dbContext.Spaces.AddTestSpace(customerId, 2); await dbContext.CustomerStorages.AddTestCustomerStorage(customerId); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customerId); await dbContext.SaveChangesAsync(); // Arrange @@ -544,8 +546,9 @@ public async Task Post_CreateBatch_201_IfLegacyModeEnabled() ""member"": [ { ""id"": ""one"", + ""family"": ""T"", ""origin"": ""https://example.org/vid.mp4"", - ""space"": 2, + ""space"": 2 } ] }"; @@ -555,7 +558,7 @@ public async Task Post_CreateBatch_201_IfLegacyModeEnabled() // Act var response = await httpClient.AsCustomer(customerId).PostAsync(path, content); - + // Assert // status code correct response.StatusCode.Should().Be(HttpStatusCode.Created); @@ -569,6 +572,7 @@ public async Task Post_CreateBatch_201_IfLegacyModeEnabledWithAtIdFieldSet() await dbContext.Customers.AddTestCustomer(customerId); await dbContext.Spaces.AddTestSpace(customerId, space); await dbContext.CustomerStorages.AddTestCustomerStorage(customerId); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customerId); await dbContext.SaveChangesAsync(); // Arrange @@ -578,6 +582,7 @@ public async Task Post_CreateBatch_201_IfLegacyModeEnabledWithAtIdFieldSet() ""member"": [ { ""@id"": ""https://test/customers/15/spaces/200/images/one"", + ""family"": ""T"", ""origin"": ""https://example.org/vid.mp4"", ""space"": 200, } @@ -967,6 +972,7 @@ public async Task Post_CreatePriorityBatch_201_IfLegacyModeEnabled() await dbContext.Customers.AddTestCustomer(customerId); await dbContext.Spaces.AddTestSpace(customerId, 5); await dbContext.CustomerStorages.AddTestCustomerStorage(customerId); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customerId); await dbContext.SaveChangesAsync(); // Arrange @@ -1260,4 +1266,190 @@ public async Task Post_TestBatch_DoesNotChangeBatchFinished_IfImagesFoundAndAllF dbBatch.Finished.Should().BeCloseTo(finished, TimeSpan.FromMinutes((1))); dbBatch.Count.Should().Be(3); } + + [Fact] + public async Task Post_CreateBatch_201_IfImageOptimisationPolicySetForImage_AndLegacyEnabled() + { + const int customerId = 325665; + const int space = 201; + await dbContext.Customers.AddTestCustomer(customerId); + await dbContext.Spaces.AddTestSpace(customerId, space); + await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customerId); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customerId); + await dbContext.CustomerStorages.AddTestCustomerStorage(customerId); + await dbContext.SaveChangesAsync(); + + // Arrange + var hydraImageBody = @"{ + ""@context"": ""http://www.w3.org/ns/hydra/context.jsonld"", + ""@type"": ""Collection"", + ""member"": [ + { + ""@id"": ""https://test/customers/325665/spaces/201/images/one"", + ""origin"": ""https://example.org/my-image.png"", + ""imageOptimisationPolicy"": ""fast-higher"", + ""space"": 201, + }, + ] + }"; + + var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); + var path = $"/customers/{customerId}/queue"; + + // Act + var response = await httpClient.AsCustomer(customerId).PostAsync(path, content); + + // Assert + response.StatusCode.Should().Be(HttpStatusCode.Created); + + var image = dbContext.Images + .Include(a => a.ImageDeliveryChannels!) + .ThenInclude(dc => dc.DeliveryChannelPolicy) + .Single(i => i.Customer == customerId && i.Space == space); + + image.ImageDeliveryChannels!.Should().Satisfy( + dc => dc.Channel == AssetDeliveryChannels.Image && + dc.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ImageDefault, + dc => dc.Channel == AssetDeliveryChannels.Thumbnails && + dc.DeliveryChannelPolicy.Name == "default"); + } + + [Fact] + public async Task Post_CreateBatch_201_IfThumbnailPolicySetForImage_AndLegacyEnabled() + { + const int customerId = 325665; + const int space = 201; + await dbContext.Customers.AddTestCustomer(customerId); + await dbContext.Spaces.AddTestSpace(customerId, space); + await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customerId); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customerId); + await dbContext.CustomerStorages.AddTestCustomerStorage(customerId); + await dbContext.SaveChangesAsync(); + + // Arrange + var hydraImageBody = @"{ + ""@context"": ""http://www.w3.org/ns/hydra/context.jsonld"", + ""@type"": ""Collection"", + ""member"": [ + { + ""@id"": ""https://test/customers/325665/spaces/201/images/one"", + ""origin"": ""https://example.org/my-image.png"", + ""thumbnailPolicy"": ""default"", + ""space"": 201, + }, + ] + }"; + + var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); + var path = $"/customers/{customerId}/queue"; + + // Act + var response = await httpClient.AsCustomer(customerId).PostAsync(path, content); + + // Assert + response.StatusCode.Should().Be(HttpStatusCode.Created); + + var image = dbContext.Images + .Include(a => a.ImageDeliveryChannels!) + .ThenInclude(dc => dc.DeliveryChannelPolicy) + .Single(i => i.Customer == customerId && i.Space == space); + + image.ImageDeliveryChannels!.Should().Satisfy( + dc => dc.Channel == AssetDeliveryChannels.Image && + dc.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ImageDefault, + dc => dc.Channel == AssetDeliveryChannels.Thumbnails && + dc.DeliveryChannelPolicy.Name == "default"); + } + + [Fact] + public async Task Post_CreateBatch_201_IfImageOptimisationPolicySetForVideo_AndLegacyEnabled() + { + const int customerId = 325665; + const int space = 201; + await dbContext.Customers.AddTestCustomer(customerId); + await dbContext.Spaces.AddTestSpace(customerId, space); + await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customerId); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customerId); + await dbContext.CustomerStorages.AddTestCustomerStorage(customerId); + await dbContext.SaveChangesAsync(); + + // Arrange + var hydraImageBody = @"{ + ""@context"": ""http://www.w3.org/ns/hydra/context.jsonld"", + ""@type"": ""Collection"", + ""member"": [ + { + ""@id"": ""https://test/customers/325665/spaces/201/images/one"", + ""family"": ""T"", + ""origin"": ""https://example.org/my-video.mp4"", + ""imageOptimisationPolicy"": ""video-max"", + ""space"": 201, + }, + ] + }"; + + var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); + var path = $"/customers/{customerId}/queue"; + + // Act + var response = await httpClient.AsCustomer(customerId).PostAsync(path, content); + + // Assert + response.StatusCode.Should().Be(HttpStatusCode.Created); + + var image = dbContext.Images + .Include(a => a.ImageDeliveryChannels!) + .ThenInclude(dc => dc.DeliveryChannelPolicy) + .Single(i => i.Customer == customerId && i.Space == space); + + image.ImageDeliveryChannels!.Should().Satisfy( + dc => dc.Channel == AssetDeliveryChannels.Timebased && + dc.DeliveryChannelPolicy.Name == "default-video"); + } + + [Fact] + public async Task Post_CreateBatch_201_IfImageOptimisationPolicySetForAudio_AndLegacyEnabled() + { + const int customerId = 325665; + const int space = 201; + await dbContext.Customers.AddTestCustomer(customerId); + await dbContext.Spaces.AddTestSpace(customerId, space); + await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customerId); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customerId); + await dbContext.CustomerStorages.AddTestCustomerStorage(customerId); + await dbContext.SaveChangesAsync(); + + // Arrange + var hydraImageBody = @"{ + ""@context"": ""http://www.w3.org/ns/hydra/context.jsonld"", + ""@type"": ""Collection"", + ""member"": [ + { + ""@id"": ""https://test/customers/325665/spaces/201/images/one"", + ""family"": ""T"", + ""origin"": ""https://example.org/my-audio.mp3"", + ""imageOptimisationPolicy"": ""audio-max"", + ""space"": 201, + }, + ] + }"; + + var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); + var path = $"/customers/{customerId}/queue"; + + // Act + var response = await httpClient.AsCustomer(customerId).PostAsync(path, content); + + // Assert + response.StatusCode.Should().Be(HttpStatusCode.Created); + + var image = dbContext.Images + .Include(a => a.ImageDeliveryChannels!) + .ThenInclude(dc => dc.DeliveryChannelPolicy) + .Single(i => i.Customer == customerId && i.Space == space); + + image.ImageDeliveryChannels!.Should().Satisfy( + dc => dc.Channel == AssetDeliveryChannels.Timebased && + dc.DeliveryChannelPolicy.Name == "default-audio"); + } } \ No newline at end of file diff --git a/src/protagonist/API.Tests/Integration/CustomerQueueWithOldDeliveryChannelPropertiesTests.cs b/src/protagonist/API.Tests/Integration/CustomerQueueWithOldDeliveryChannelPropertiesTests.cs deleted file mode 100644 index adb96dea5..000000000 --- a/src/protagonist/API.Tests/Integration/CustomerQueueWithOldDeliveryChannelPropertiesTests.cs +++ /dev/null @@ -1,235 +0,0 @@ -using System.Linq; -using System.Net; -using System.Net.Http; -using System.Text; -using API.Tests.Integration.Infrastructure; -using DLCS.Model.Assets; -using DLCS.Model.Policies; -using DLCS.Repository; -using DLCS.Repository.Messaging; -using FakeItEasy; -using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Mvc.Testing; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Test.Helpers.Integration; -using Test.Helpers.Integration.Infrastructure; - -namespace API.Tests.Integration; - -[Trait("Category", "Integration")] -[Collection(CollectionDefinitions.DatabaseCollection.CollectionName)] -public class CustomerQueueWithOldDeliveryChannelPropertiesTests : IClassFixture> -{ - private readonly DlcsContext dbContext; - private readonly HttpClient httpClient; - private static readonly IEngineClient EngineClient = A.Fake(); - - public CustomerQueueWithOldDeliveryChannelPropertiesTests(DlcsDatabaseFixture dbFixture, - ProtagonistAppFactory factory) - { - dbContext = dbFixture.DbContext; - httpClient = factory - .WithConnectionString(dbFixture.ConnectionString) - .WithTestServices(services => - { - services.AddScoped(_ => EngineClient); - services.AddAuthentication("API-Test") - .AddScheme( - "API-Test", _ => { }); - }) - .WithConfigValue("EmulateOldDeliveryChannelProperties", "true") - .CreateClient(new WebApplicationFactoryClientOptions - { - AllowAutoRedirect = false - }); - - dbFixture.CleanUp(); - } - - [Fact] - public async Task Post_CreateBatch_201_IfImageOptimisationPolicySetForImage_AndLegacyEnabled() - { - const int customerId = 325665; - const int space = 201; - await dbContext.Customers.AddTestCustomer(customerId); - await dbContext.Spaces.AddTestSpace(customerId, space); - await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customerId); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customerId); - await dbContext.CustomerStorages.AddTestCustomerStorage(customerId); - await dbContext.SaveChangesAsync(); - - // Arrange - var hydraImageBody = @"{ - ""@context"": ""http://www.w3.org/ns/hydra/context.jsonld"", - ""@type"": ""Collection"", - ""member"": [ - { - ""@id"": ""https://test/customers/325665/spaces/201/images/one"", - ""origin"": ""https://example.org/my-image.png"", - ""imageOptimisationPolicy"": ""fast-higher"", - ""space"": 201, - }, - ] - }"; - - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var path = $"/customers/{customerId}/queue"; - - // Act - var response = await httpClient.AsCustomer(customerId).PostAsync(path, content); - - // Assert - response.StatusCode.Should().Be(HttpStatusCode.Created); - - var image = dbContext.Images - .Include(a => a.ImageDeliveryChannels!) - .ThenInclude(dc => dc.DeliveryChannelPolicy) - .Single(i => i.Customer == customerId && i.Space == space); - - image.ImageDeliveryChannels!.Should().Satisfy( - dc => dc.Channel == AssetDeliveryChannels.Image && - dc.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ImageDefault, - dc => dc.Channel == AssetDeliveryChannels.Thumbnails && - dc.DeliveryChannelPolicy.Name == "default"); - } - - [Fact] - public async Task Post_CreateBatch_201_IfThumbnailPolicySetForImage_AndLegacyEnabled() - { - const int customerId = 325665; - const int space = 201; - await dbContext.Customers.AddTestCustomer(customerId); - await dbContext.Spaces.AddTestSpace(customerId, space); - await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customerId); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customerId); - await dbContext.CustomerStorages.AddTestCustomerStorage(customerId); - await dbContext.SaveChangesAsync(); - - // Arrange - var hydraImageBody = @"{ - ""@context"": ""http://www.w3.org/ns/hydra/context.jsonld"", - ""@type"": ""Collection"", - ""member"": [ - { - ""@id"": ""https://test/customers/325665/spaces/201/images/one"", - ""origin"": ""https://example.org/my-image.png"", - ""thumbnailPolicy"": ""default"", - ""space"": 201, - }, - ] - }"; - - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var path = $"/customers/{customerId}/queue"; - - // Act - var response = await httpClient.AsCustomer(customerId).PostAsync(path, content); - - // Assert - response.StatusCode.Should().Be(HttpStatusCode.Created); - - var image = dbContext.Images - .Include(a => a.ImageDeliveryChannels!) - .ThenInclude(dc => dc.DeliveryChannelPolicy) - .Single(i => i.Customer == customerId && i.Space == space); - - image.ImageDeliveryChannels!.Should().Satisfy( - dc => dc.Channel == AssetDeliveryChannels.Image && - dc.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ImageDefault, - dc => dc.Channel == AssetDeliveryChannels.Thumbnails && - dc.DeliveryChannelPolicy.Name == "default"); - } - - [Fact] - public async Task Post_CreateBatch_201_IfImageOptimisationPolicySetForVideo_AndLegacyEnabled() - { - const int customerId = 325665; - const int space = 201; - await dbContext.Customers.AddTestCustomer(customerId); - await dbContext.Spaces.AddTestSpace(customerId, space); - await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customerId); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customerId); - await dbContext.CustomerStorages.AddTestCustomerStorage(customerId); - await dbContext.SaveChangesAsync(); - - // Arrange - var hydraImageBody = @"{ - ""@context"": ""http://www.w3.org/ns/hydra/context.jsonld"", - ""@type"": ""Collection"", - ""member"": [ - { - ""@id"": ""https://test/customers/325665/spaces/201/images/one"", - ""family"": ""T"", - ""origin"": ""https://example.org/my-video.mp4"", - ""imageOptimisationPolicy"": ""video-max"", - ""space"": 201, - }, - ] - }"; - - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var path = $"/customers/{customerId}/queue"; - - // Act - var response = await httpClient.AsCustomer(customerId).PostAsync(path, content); - - // Assert - response.StatusCode.Should().Be(HttpStatusCode.Created); - - var image = dbContext.Images - .Include(a => a.ImageDeliveryChannels!) - .ThenInclude(dc => dc.DeliveryChannelPolicy) - .Single(i => i.Customer == customerId && i.Space == space); - - image.ImageDeliveryChannels!.Should().Satisfy( - dc => dc.Channel == AssetDeliveryChannels.Timebased && - dc.DeliveryChannelPolicy.Name == "default-video"); - } - - [Fact] - public async Task Post_CreateBatch_201_IfImageOptimisationPolicySetForAudio_AndLegacyEnabled() - { - const int customerId = 325665; - const int space = 201; - await dbContext.Customers.AddTestCustomer(customerId); - await dbContext.Spaces.AddTestSpace(customerId, space); - await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customerId); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customerId); - await dbContext.CustomerStorages.AddTestCustomerStorage(customerId); - await dbContext.SaveChangesAsync(); - - // Arrange - var hydraImageBody = @"{ - ""@context"": ""http://www.w3.org/ns/hydra/context.jsonld"", - ""@type"": ""Collection"", - ""member"": [ - { - ""@id"": ""https://test/customers/325665/spaces/201/images/one"", - ""family"": ""T"", - ""origin"": ""https://example.org/my-audio.mp3"", - ""imageOptimisationPolicy"": ""audio-max"", - ""space"": 201, - }, - ] - }"; - - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var path = $"/customers/{customerId}/queue"; - - // Act - var response = await httpClient.AsCustomer(customerId).PostAsync(path, content); - - // Assert - response.StatusCode.Should().Be(HttpStatusCode.Created); - - var image = dbContext.Images - .Include(a => a.ImageDeliveryChannels!) - .ThenInclude(dc => dc.DeliveryChannelPolicy) - .Single(i => i.Customer == customerId && i.Space == space); - - image.ImageDeliveryChannels!.Should().Satisfy( - dc => dc.Channel == AssetDeliveryChannels.Timebased && - dc.DeliveryChannelPolicy.Name == "default-audio"); - } -} \ No newline at end of file diff --git a/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs b/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs index e19d7dbdc..ecb0b0628 100644 --- a/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs +++ b/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs @@ -989,7 +989,7 @@ public async Task Put_Asset_Fails_When_ThumbnailPolicy_Is_Provided() response.StatusCode.Should().Be(HttpStatusCode.BadRequest); var body = await response.Content.ReadAsStringAsync(); - body.Should().Contain("'ThumbnailPolicy' is disabled"); + body.Should().Contain("'ThumbnailPolicy' can only be specified when legacy mode is enabled"); } [Fact] @@ -1014,7 +1014,7 @@ public async Task Put_Asset_Fails_When_ImageOptimisationPolicy_Is_Provided() response.StatusCode.Should().Be(HttpStatusCode.BadRequest); var body = await response.Content.ReadAsStringAsync(); - body.Should().Contain("'ImageOptimisationPolicy' is disabled"); + body.Should().Contain("'ImageOptimisationPolicy' can only be specified when legacy mode is enabled"); } [Fact] @@ -1263,7 +1263,348 @@ await dbContext.CustomerStorages.AddAsync(new DLCS.Model.Storage.CustomerStorage // assert response.StatusCode.Should().Be(HttpStatusCode.InsufficientStorage); } + [Theory] + [InlineData("fast-higher")] + [InlineData("https://api.dlc.services/imageOptimisationPolicies/fast-higher")] + public async Task Put_NewImageAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled(string imageOptimisationPolicy) + { + const int customer = 325665; + const int space = 2; + var assetId = new AssetId(customer, space, nameof(Put_NewImageAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled)); + await dbContext.Customers.AddTestCustomer(customer); + await dbContext.Spaces.AddTestSpace(customer, space); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); + await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); + await dbContext.SaveChangesAsync(); + + var hydraImageBody = $@"{{ + ""origin"": ""https://example.org/{assetId.Asset}.tiff"", + ""imageOptimisationPolicy"" : ""{imageOptimisationPolicy}"" + }}"; + + A.CallTo(() => + EngineClient.SynchronousIngest( + A.That.Matches(r => r.Id == assetId), + A._)) + .Returns(HttpStatusCode.OK); + + // act + var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); + var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + + // assert + response.StatusCode.Should().Be(HttpStatusCode.Created); + + var asset = dbContext.Images.Include(i => i.ImageDeliveryChannels) + .ThenInclude(i => i.DeliveryChannelPolicy).Single(i => i.Id == assetId); + asset.Id.Should().Be(assetId); + asset.MediaType.Should().Be("image/tiff"); + asset.Family.Should().Be(AssetFamily.Image); + asset.ImageOptimisationPolicy.Should().BeEmpty(); + asset.ThumbnailPolicy.Should().BeEmpty(); + asset.ImageDeliveryChannels.Count.Should().Be(2); + asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == AssetDeliveryChannels.Image && + dc.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ImageDefault); + asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == AssetDeliveryChannels.Thumbnails && + dc.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ThumbsDefault); + } + + [Fact] + public async Task Put_NewImageAsset_WithImageOptimisationPolicy_Returns400_IfInvalid_AndLegacyEnabled() + { + const int customer = 325665; + const int space = 2; + var assetId = new AssetId(customer, space, nameof(Put_NewImageAsset_WithImageOptimisationPolicy_Returns400_IfInvalid_AndLegacyEnabled)); + await dbContext.Customers.AddTestCustomer(customer); + await dbContext.Spaces.AddTestSpace(customer, space); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); + await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); + await dbContext.SaveChangesAsync(); + + var hydraImageBody = $@"{{ + ""origin"": ""https://example.org/{assetId.Asset}.tiff"", + ""imageOptimisationPolicy"" : ""foo"" + }}"; + + // act + var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); + var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + + // assert + response.StatusCode.Should().Be(HttpStatusCode.BadRequest); + + var body = await response.Content.ReadAsStringAsync(); + body.Should().Contain("'foo' is not a valid imageOptimisationPolicy for an image"); + } + + [Theory] + [InlineData("default")] + [InlineData("https://api.dlc.services/thumbnailPolicies/default")] + public async Task Put_NewImageAsset_WithThumbnailPolicy_Creates_Asset_WhenLegacyEnabled(string thumbnailPolicy) + { + const int customer = 325665; + const int space = 2; + var assetId = new AssetId(customer, space, nameof(Put_NewImageAsset_WithThumbnailPolicy_Creates_Asset_WhenLegacyEnabled)); + + await dbContext.Customers.AddTestCustomer(customer); + await dbContext.Spaces.AddTestSpace(customer, space); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); + await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); + await dbContext.SaveChangesAsync(); + + var hydraImageBody = $@"{{ + ""@type"": ""Image"", + ""origin"": ""https://example.org/{assetId.Asset}.tiff"", + ""thumbnailPolicy"": ""{thumbnailPolicy}"" + }}"; + + A.CallTo(() => + EngineClient.SynchronousIngest( + A.That.Matches(r => r.Id == assetId), + A._)) + .Returns(HttpStatusCode.OK); + + // act + var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); + var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + + // assert + response.StatusCode.Should().Be(HttpStatusCode.Created); + + var asset = dbContext.Images.Include(i => i.ImageDeliveryChannels) + .ThenInclude(i => i.DeliveryChannelPolicy).Single(i => i.Id == assetId); + asset.Id.Should().Be(assetId); + asset.MediaType.Should().Be("image/tiff"); + asset.Family.Should().Be(AssetFamily.Image); + asset.ImageOptimisationPolicy.Should().BeEmpty(); + asset.ThumbnailPolicy.Should().BeEmpty(); + asset.ImageDeliveryChannels.Count.Should().Be(2); + asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == AssetDeliveryChannels.Image && + dc.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ImageDefault); + asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == AssetDeliveryChannels.Thumbnails && + dc.DeliveryChannelPolicy.Name == "default"); + } + + [Fact] + public async Task Put_NewImageAsset_WithThumbnailPolicy_Returns400_IfInvalid_AndLegacyEnabled() + { + const int customer = 325665; + const int space = 2; + var assetId = new AssetId(customer, space, nameof(Put_NewImageAsset_WithImageOptimisationPolicy_Returns400_IfInvalid_AndLegacyEnabled)); + await dbContext.Customers.AddTestCustomer(customer); + await dbContext.Spaces.AddTestSpace(customer, space); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); + await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); + await dbContext.SaveChangesAsync(); + + var hydraImageBody = $@"{{ + ""origin"": ""https://example.org/{assetId.Asset}.tiff"", + ""thumbnailPolicy"" : ""foo"" + }}"; + + // act + var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); + var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + + // assert + response.StatusCode.Should().Be(HttpStatusCode.BadRequest); + + var body = await response.Content.ReadAsStringAsync(); + body.Should().Contain("'foo' is not a valid thumbnailPolicy for an image"); + } + + [Theory] + [InlineData("video-max")] + [InlineData("https://api.dlc.services/imageOptimisationPolicy/video-max")] + public async Task Put_NewVideoAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled(string imageOptimisationPolicy) + { + const int customer = 325665; + const int space = 2; + var assetId = new AssetId(customer, space, nameof(Put_NewVideoAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled)); + await dbContext.Customers.AddTestCustomer(customer); + await dbContext.Spaces.AddTestSpace(customer, space); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); + await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); + await dbContext.SaveChangesAsync(); + + var hydraImageBody = $@"{{ + ""family"": ""T"", + ""origin"": ""https://example.org/{assetId.Asset}.mp4"", + ""imageOptimisationPolicy"" : ""{imageOptimisationPolicy}"" + }}"; + + A.CallTo(() => + EngineClient.AsynchronousIngest( + A.That.Matches(r => r.Id == assetId), + A._)) + .Returns(true); + + // act + var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); + var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + + // assert + response.StatusCode.Should().Be(HttpStatusCode.Created); + + var asset = dbContext.Images.Include(i => i.ImageDeliveryChannels) + .ThenInclude(i => i.DeliveryChannelPolicy).Single(i => i.Id == assetId); + asset.Id.Should().Be(assetId); + asset.MediaType.Should().Be("video/mp4"); + asset.Family.Should().Be(AssetFamily.Timebased); + asset.ImageOptimisationPolicy.Should().BeEmpty(); + asset.ThumbnailPolicy.Should().BeEmpty(); + asset.ImageDeliveryChannels.Count.Should().Be(1); + asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == AssetDeliveryChannels.Timebased && + dc.DeliveryChannelPolicy.Name == "default-video"); + } + + [Fact] + public async Task Put_NewVideoAsset_WithImageOptimisationPolicy_Returns400_IfInvalid_AndLegacyEnabled() + { + const int customer = 325665; + const int space = 2; + var assetId = new AssetId(customer, space, nameof(Put_NewVideoAsset_WithImageOptimisationPolicy_Returns400_IfInvalid_AndLegacyEnabled)); + await dbContext.Customers.AddTestCustomer(customer); + await dbContext.Spaces.AddTestSpace(customer, space); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); + await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); + await dbContext.SaveChangesAsync(); + + var hydraImageBody = $@"{{ + ""family"": ""T"", + ""origin"": ""https://example.org/{assetId.Asset}.mp4"", + ""imageOptimisationPolicy"" : ""foo"" + }}"; + + // act + var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); + var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + + // assert + response.StatusCode.Should().Be(HttpStatusCode.BadRequest); + + var body = await response.Content.ReadAsStringAsync(); + body.Should().Contain("'foo' is not a valid imageOptimisationPolicy for a timebased asset"); + } + + [Theory] + [InlineData("audio-max")] + [InlineData("https://api.dlc.services/imageOptimisationPolicy/audio-max")] + public async Task Put_NewAudioAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled(string imageOptimisationPolicy) + { + const int customer = 325665; + const int space = 2; + var assetId = new AssetId(customer, space, nameof(Put_NewAudioAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled)); + await dbContext.Customers.AddTestCustomer(customer); + await dbContext.Spaces.AddTestSpace(customer, space); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); + await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); + await dbContext.SaveChangesAsync(); + + var hydraImageBody = $@"{{ + ""family"": ""T"", + ""origin"": ""https://example.org/{assetId.Asset}.mp3"", + ""imageOptimisationPolicy"" : ""{imageOptimisationPolicy}"" + }}"; + + A.CallTo(() => + EngineClient.AsynchronousIngest( + A.That.Matches(r => r.Id == assetId), + A._)) + .Returns(true); + // act + var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); + var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + + // assert + response.StatusCode.Should().Be(HttpStatusCode.Created); + + var asset = dbContext.Images.Include(i => i.ImageDeliveryChannels) + .ThenInclude(i => i.DeliveryChannelPolicy).Single(i => i.Id == assetId); + asset.Id.Should().Be(assetId); + asset.MediaType.Should().Be("audio/mp3"); + asset.Family.Should().Be(AssetFamily.Timebased); + asset.ImageOptimisationPolicy.Should().BeEmpty(); + asset.ThumbnailPolicy.Should().BeEmpty(); + asset.ImageDeliveryChannels.Count.Should().Be(1); + asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == AssetDeliveryChannels.Timebased && + dc.DeliveryChannelPolicy.Name == "default-audio"); + } + + [Fact] + public async Task Put_NewAudioAsset_WithImageOptimisationPolicy_Returns400_IfInvalid_AndLegacyEnabled() + { + const int customer = 325665; + const int space = 2; + var assetId = new AssetId(customer, space, nameof(Put_NewAudioAsset_WithImageOptimisationPolicy_Returns400_IfInvalid_AndLegacyEnabled)); + await dbContext.Customers.AddTestCustomer(customer); + await dbContext.Spaces.AddTestSpace(customer, space); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); + await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); + await dbContext.SaveChangesAsync(); + + var hydraImageBody = $@"{{ + ""family"": ""T"", + ""origin"": ""https://example.org/{assetId.Asset}.mp3"", + ""imageOptimisationPolicy"" : ""foo"" + }}"; + + // act + var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); + var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + + // assert + response.StatusCode.Should().Be(HttpStatusCode.BadRequest); + + var body = await response.Content.ReadAsStringAsync(); + body.Should().Contain("'foo' is not a valid imageOptimisationPolicy for a timebased asset"); + } + + [Fact] + public async Task Put_NewFileAsset_Creates_Asset_WhenLegacyEnabled() + { + const int customer = 325665; + const int space = 2; + var assetId = new AssetId(customer, space, nameof(Put_NewImageAsset_WithThumbnailPolicy_Creates_Asset_WhenLegacyEnabled)); + + await dbContext.Customers.AddTestCustomer(customer); + await dbContext.Spaces.AddTestSpace(customer, space); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); + await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); + await dbContext.SaveChangesAsync(); + + var hydraImageBody = $@"{{ + ""@type"": ""Image"", + ""family"": ""F"", + ""origin"": ""https://example.org/{assetId.Asset}.pdf"", + }}"; + + A.CallTo(() => + EngineClient.SynchronousIngest( + A.That.Matches(r => r.Id == assetId), + A._)) + .Returns(HttpStatusCode.OK); + + // act + var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); + var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + + // assert + response.StatusCode.Should().Be(HttpStatusCode.Created); + + var asset = dbContext.Images.Include(i => i.ImageDeliveryChannels) + .ThenInclude(i => i.DeliveryChannelPolicy).Single(i => i.Id == assetId); + asset.Id.Should().Be(assetId); + asset.MediaType.Should().Be("application/pdf"); + asset.Family.Should().Be(AssetFamily.File); + asset.ThumbnailPolicy.Should().BeEmpty(); + asset.ImageOptimisationPolicy.Should().BeEmpty(); + asset.ImageDeliveryChannels.Count.Should().Be(1); + asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == AssetDeliveryChannels.File && + dc.DeliveryChannelPolicy.Name == "none"); + } + [Theory] [InlineData(AssetFamily.Image)] [InlineData(AssetFamily.Timebased)] @@ -1533,7 +1874,7 @@ public async Task Patch_Asset_Fails_When_ThumbnailPolicy_Is_Provided() response.StatusCode.Should().Be(HttpStatusCode.BadRequest); var body = await response.Content.ReadAsStringAsync(); - body.Should().Contain("'ThumbnailPolicy' is disabled"); + body.Should().Contain("'ThumbnailPolicy' can only be specified when legacy mode is enabled"); } [Fact] @@ -1553,7 +1894,7 @@ public async Task Patch_Asset_Fails_When_ImageOptimisationPolicy_Is_Provided() response.StatusCode.Should().Be(HttpStatusCode.BadRequest); var body = await response.Content.ReadAsStringAsync(); - body.Should().Contain("'ImageOptimisationPolicy' is disabled"); + body.Should().Contain("'ImageOptimisationPolicy' can only be specified when legacy mode is enabled"); } [Fact] diff --git a/src/protagonist/API.Tests/Integration/ModifyAssetWithOldDeliveryChannelPropertiesTests.cs b/src/protagonist/API.Tests/Integration/ModifyAssetWithOldDeliveryChannelPropertiesTests.cs deleted file mode 100644 index b9254b1c6..000000000 --- a/src/protagonist/API.Tests/Integration/ModifyAssetWithOldDeliveryChannelPropertiesTests.cs +++ /dev/null @@ -1,403 +0,0 @@ -using System.Linq; -using System.Net; -using System.Net.Http; -using System.Text; -using System.Threading; -using Amazon.S3; -using API.Infrastructure.Messaging; -using API.Tests.Integration.Infrastructure; -using DLCS.Core.Types; -using DLCS.Model.Assets; -using DLCS.Model.Policies; -using DLCS.Repository; -using DLCS.Repository.Messaging; -using FakeItEasy; -using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Mvc.Testing; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Test.Helpers.Integration; -using Test.Helpers.Integration.Infrastructure; -using AssetFamily = DLCS.Model.Assets.AssetFamily; - -namespace API.Tests.Integration; - -[Trait("Category", "Integration")] -[Collection(StorageCollection.CollectionName)] -public class ModifyAssetWithOldDeliveryChannelPropertiesTests : IClassFixture> -{ - private readonly DlcsContext dbContext; - private readonly HttpClient httpClient; - private static readonly IAssetNotificationSender NotificationSender = A.Fake(); - private static readonly IEngineClient EngineClient = A.Fake(); - - public ModifyAssetWithOldDeliveryChannelPropertiesTests( - StorageFixture storageFixture, - ProtagonistAppFactory factory) - { - var dbFixture = storageFixture.DbFixture; - - dbContext = dbFixture.DbContext; - - httpClient = factory - .WithConnectionString(dbFixture.ConnectionString) - .WithLocalStack(storageFixture.LocalStackFixture) - .WithTestServices(services => - { - services.AddSingleton(_ => NotificationSender); - services.AddScoped(_ => EngineClient); - services.AddAuthentication("API-Test") - .AddScheme( - "API-Test", _ => { }); - }) - .WithConfigValue("EmulateOldDeliveryChannelProperties", "true") - .CreateClient(new WebApplicationFactoryClientOptions - { - AllowAutoRedirect = false - }); - - dbFixture.CleanUp(); - } - - [Theory] - [InlineData("fast-higher")] - [InlineData("https://api.dlc.services/imageOptimisationPolicies/fast-higher")] - public async Task Put_NewImageAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled(string imageOptimisationPolicy) - { - const int customer = 325665; - const int space = 2; - var assetId = new AssetId(customer, space, nameof(Put_NewImageAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled)); - await dbContext.Customers.AddTestCustomer(customer); - await dbContext.Spaces.AddTestSpace(customer, space); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); - await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); - await dbContext.SaveChangesAsync(); - - var hydraImageBody = $@"{{ - ""origin"": ""https://example.org/{assetId.Asset}.tiff"", - ""imageOptimisationPolicy"" : ""{imageOptimisationPolicy}"" - }}"; - - A.CallTo(() => - EngineClient.SynchronousIngest( - A.That.Matches(r => r.Id == assetId), - A._)) - .Returns(HttpStatusCode.OK); - - // act - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); - - // assert - response.StatusCode.Should().Be(HttpStatusCode.Created); - - var asset = dbContext.Images.Include(i => i.ImageDeliveryChannels) - .ThenInclude(i => i.DeliveryChannelPolicy).Single(i => i.Id == assetId); - asset.Id.Should().Be(assetId); - asset.MediaType.Should().Be("image/tiff"); - asset.Family.Should().Be(AssetFamily.Image); - asset.ImageOptimisationPolicy.Should().Be("fast-higher"); - asset.ThumbnailPolicy.Should().BeEmpty(); - asset.ImageDeliveryChannels.Count.Should().Be(2); - asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == AssetDeliveryChannels.Image && - dc.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ImageDefault); - asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == AssetDeliveryChannels.Thumbnails && - dc.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ThumbsDefault); - } - - [Fact] - public async Task Put_NewImageAsset_WithImageOptimisationPolicy_Returns400_IfInvalid_AndLegacyEnabled() - { - const int customer = 325665; - const int space = 2; - var assetId = new AssetId(customer, space, nameof(Put_NewImageAsset_WithImageOptimisationPolicy_Returns400_IfInvalid_AndLegacyEnabled)); - await dbContext.Customers.AddTestCustomer(customer); - await dbContext.Spaces.AddTestSpace(customer, space); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); - await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); - await dbContext.SaveChangesAsync(); - - var hydraImageBody = $@"{{ - ""origin"": ""https://example.org/{assetId.Asset}.tiff"", - ""imageOptimisationPolicy"" : ""foo"" - }}"; - - // act - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); - - // assert - response.StatusCode.Should().Be(HttpStatusCode.BadRequest); - - var body = await response.Content.ReadAsStringAsync(); - body.Should().Contain("'foo' is not a valid imageOptimisationPolicy for an image"); - } - - [Theory] - [InlineData("default")] - [InlineData("https://api.dlc.services/thumbnailPolicies/default")] - public async Task Put_NewImageAsset_WithThumbnailPolicy_Creates_Asset_WhenLegacyEnabled(string thumbnailPolicy) - { - const int customer = 325665; - const int space = 2; - var assetId = new AssetId(customer, space, nameof(Put_NewImageAsset_WithThumbnailPolicy_Creates_Asset_WhenLegacyEnabled)); - - await dbContext.Customers.AddTestCustomer(customer); - await dbContext.Spaces.AddTestSpace(customer, space); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); - await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); - await dbContext.SaveChangesAsync(); - - var hydraImageBody = $@"{{ - ""@type"": ""Image"", - ""origin"": ""https://example.org/{assetId.Asset}.tiff"", - ""thumbnailPolicy"": ""{thumbnailPolicy}"" - }}"; - - A.CallTo(() => - EngineClient.SynchronousIngest( - A.That.Matches(r => r.Id == assetId), - A._)) - .Returns(HttpStatusCode.OK); - - // act - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); - - // assert - response.StatusCode.Should().Be(HttpStatusCode.Created); - - var asset = dbContext.Images.Include(i => i.ImageDeliveryChannels) - .ThenInclude(i => i.DeliveryChannelPolicy).Single(i => i.Id == assetId); - asset.Id.Should().Be(assetId); - asset.MediaType.Should().Be("image/tiff"); - asset.Family.Should().Be(AssetFamily.Image); - asset.ThumbnailPolicy.Should().Be("default"); - asset.ImageOptimisationPolicy.Should().BeEmpty(); - asset.ImageDeliveryChannels.Count.Should().Be(2); - asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == AssetDeliveryChannels.Image && - dc.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ImageDefault); - asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == AssetDeliveryChannels.Thumbnails && - dc.DeliveryChannelPolicy.Name == "default"); - } - - [Fact] - public async Task Put_NewImageAsset_WithThumbnailPolicy_Returns400_IfInvalid_AndLegacyEnabled() - { - const int customer = 325665; - const int space = 2; - var assetId = new AssetId(customer, space, nameof(Put_NewImageAsset_WithImageOptimisationPolicy_Returns400_IfInvalid_AndLegacyEnabled)); - await dbContext.Customers.AddTestCustomer(customer); - await dbContext.Spaces.AddTestSpace(customer, space); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); - await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); - await dbContext.SaveChangesAsync(); - - var hydraImageBody = $@"{{ - ""origin"": ""https://example.org/{assetId.Asset}.tiff"", - ""thumbnailPolicy"" : ""foo"" - }}"; - - // act - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); - - // assert - response.StatusCode.Should().Be(HttpStatusCode.BadRequest); - - var body = await response.Content.ReadAsStringAsync(); - body.Should().Contain("'foo' is not a valid thumbnailPolicy for an image"); - } - - [Theory] - [InlineData("video-max")] - [InlineData("https://api.dlc.services/imageOptimisationPolicy/video-max")] - public async Task Put_NewVideoAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled(string imageOptimisationPolicy) - { - const int customer = 325665; - const int space = 2; - var assetId = new AssetId(customer, space, nameof(Put_NewVideoAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled)); - await dbContext.Customers.AddTestCustomer(customer); - await dbContext.Spaces.AddTestSpace(customer, space); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); - await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); - await dbContext.SaveChangesAsync(); - - var hydraImageBody = $@"{{ - ""family"": ""T"", - ""origin"": ""https://example.org/{assetId.Asset}.mp4"", - ""imageOptimisationPolicy"" : ""{imageOptimisationPolicy}"" - }}"; - - A.CallTo(() => - EngineClient.AsynchronousIngest( - A.That.Matches(r => r.Id == assetId), - A._)) - .Returns(true); - - // act - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); - - // assert - response.StatusCode.Should().Be(HttpStatusCode.Created); - - var asset = dbContext.Images.Include(i => i.ImageDeliveryChannels) - .ThenInclude(i => i.DeliveryChannelPolicy).Single(i => i.Id == assetId); - asset.Id.Should().Be(assetId); - asset.MediaType.Should().Be("video/mp4"); - asset.Family.Should().Be(AssetFamily.Timebased); - asset.ImageOptimisationPolicy.Should().Be(imageOptimisationPolicy); - asset.ThumbnailPolicy.Should().BeEmpty(); - asset.ImageDeliveryChannels.Count.Should().Be(1); - asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == AssetDeliveryChannels.Timebased && - dc.DeliveryChannelPolicy.Name == "default-video"); - } - - [Fact] - public async Task Put_NewVideoAsset_WithImageOptimisationPolicy_Returns400_IfInvalid_AndLegacyEnabled() - { - const int customer = 325665; - const int space = 2; - var assetId = new AssetId(customer, space, nameof(Put_NewVideoAsset_WithImageOptimisationPolicy_Returns400_IfInvalid_AndLegacyEnabled)); - await dbContext.Customers.AddTestCustomer(customer); - await dbContext.Spaces.AddTestSpace(customer, space); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); - await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); - await dbContext.SaveChangesAsync(); - - var hydraImageBody = $@"{{ - ""family"": ""T"", - ""origin"": ""https://example.org/{assetId.Asset}.mp4"", - ""imageOptimisationPolicy"" : ""foo"" - }}"; - - // act - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); - - // assert - response.StatusCode.Should().Be(HttpStatusCode.BadRequest); - - var body = await response.Content.ReadAsStringAsync(); - body.Should().Contain("'foo' is not a valid imageOptimisationPolicy for a timebased asset"); - } - - [Theory] - [InlineData("audio-max")] - [InlineData("https://api.dlc.services/imageOptimisationPolicy/audio-max")] - public async Task Put_NewAudioAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled(string imageOptimisationPolicy) - { - const int customer = 325665; - const int space = 2; - var assetId = new AssetId(customer, space, nameof(Put_NewAudioAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled)); - await dbContext.Customers.AddTestCustomer(customer); - await dbContext.Spaces.AddTestSpace(customer, space); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); - await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); - await dbContext.SaveChangesAsync(); - - var hydraImageBody = $@"{{ - ""family"": ""T"", - ""origin"": ""https://example.org/{assetId.Asset}.mp3"", - ""imageOptimisationPolicy"" : ""{imageOptimisationPolicy}"" - }}"; - - A.CallTo(() => - EngineClient.AsynchronousIngest( - A.That.Matches(r => r.Id == assetId), - A._)) - .Returns(true); - - // act - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); - - // assert - response.StatusCode.Should().Be(HttpStatusCode.Created); - - var asset = dbContext.Images.Include(i => i.ImageDeliveryChannels) - .ThenInclude(i => i.DeliveryChannelPolicy).Single(i => i.Id == assetId); - asset.Id.Should().Be(assetId); - asset.MediaType.Should().Be("audio/mp3"); - asset.Family.Should().Be(AssetFamily.Timebased); - asset.ImageOptimisationPolicy.Should().Be(imageOptimisationPolicy); - asset.ThumbnailPolicy.Should().BeEmpty(); - asset.ImageDeliveryChannels.Count.Should().Be(1); - asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == AssetDeliveryChannels.Timebased && - dc.DeliveryChannelPolicy.Name == "default-audio"); - } - - [Fact] - public async Task Put_NewAudioAsset_WithImageOptimisationPolicy_Returns400_IfInvalid_AndLegacyEnabled() - { - const int customer = 325665; - const int space = 2; - var assetId = new AssetId(customer, space, nameof(Put_NewAudioAsset_WithImageOptimisationPolicy_Returns400_IfInvalid_AndLegacyEnabled)); - await dbContext.Customers.AddTestCustomer(customer); - await dbContext.Spaces.AddTestSpace(customer, space); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); - await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); - await dbContext.SaveChangesAsync(); - - var hydraImageBody = $@"{{ - ""family"": ""T"", - ""origin"": ""https://example.org/{assetId.Asset}.mp3"", - ""imageOptimisationPolicy"" : ""foo"" - }}"; - - // act - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); - - // assert - response.StatusCode.Should().Be(HttpStatusCode.BadRequest); - - var body = await response.Content.ReadAsStringAsync(); - body.Should().Contain("'foo' is not a valid imageOptimisationPolicy for a timebased asset"); - } - - [Fact] - public async Task Put_NewFileAsset_Creates_Asset_WhenLegacyEnabled() - { - const int customer = 325665; - const int space = 2; - var assetId = new AssetId(customer, space, nameof(Put_NewImageAsset_WithThumbnailPolicy_Creates_Asset_WhenLegacyEnabled)); - - await dbContext.Customers.AddTestCustomer(customer); - await dbContext.Spaces.AddTestSpace(customer, space); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); - await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); - await dbContext.SaveChangesAsync(); - - var hydraImageBody = $@"{{ - ""@type"": ""Image"", - ""family"": ""F"", - ""origin"": ""https://example.org/{assetId.Asset}.pdf"", - }}"; - - A.CallTo(() => - EngineClient.SynchronousIngest( - A.That.Matches(r => r.Id == assetId), - A._)) - .Returns(HttpStatusCode.OK); - - // act - var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); - - // assert - response.StatusCode.Should().Be(HttpStatusCode.Created); - - var asset = dbContext.Images.Include(i => i.ImageDeliveryChannels) - .ThenInclude(i => i.DeliveryChannelPolicy).Single(i => i.Id == assetId); - asset.Id.Should().Be(assetId); - asset.MediaType.Should().Be("application/pdf"); - asset.Family.Should().Be(AssetFamily.File); - asset.ThumbnailPolicy.Should().BeEmpty(); - asset.ImageOptimisationPolicy.Should().BeEmpty(); - asset.ImageDeliveryChannels.Count.Should().Be(1); - asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == AssetDeliveryChannels.File && - dc.DeliveryChannelPolicy.Name == "none"); - } -} \ No newline at end of file diff --git a/src/protagonist/API/Converters/LegacyModeConverter.cs b/src/protagonist/API/Converters/LegacyModeConverter.cs index 66c361446..d07049bcd 100644 --- a/src/protagonist/API/Converters/LegacyModeConverter.cs +++ b/src/protagonist/API/Converters/LegacyModeConverter.cs @@ -19,10 +19,9 @@ public static class LegacyModeConverter /// Converts from legacy format to new format /// /// The image to convert - /// Whether old thumbnailPolicy/imageOptimisationPolicy fields /// should be emulated and translated into delivery channels /// A converted image - public static T VerifyAndConvertToModernFormat(T image, bool emulateOldDeliveryChannelProperties) + public static T VerifyAndConvertToModernFormat(T image) where T : Image { if (image.MediaType.IsNullOrEmpty()) @@ -46,12 +45,13 @@ public static T VerifyAndConvertToModernFormat(T image, bool emulateOldDelive { image.MaxUnauthorised = -1; } - - if (emulateOldDeliveryChannelProperties) - { - image.DeliveryChannels = GetDeliveryChannelsForLegacyAsset(image); - } - + + image.DeliveryChannels = GetDeliveryChannelsForLegacyAsset(image); + + // Clear IOP and TP after we've matched them to the appropriate delivery channels + image.ImageOptimisationPolicy = null; + image.ThumbnailPolicy = null; + return image; } @@ -153,7 +153,7 @@ public static T VerifyAndConvertToModernFormat(T image, bool emulateOldDelive } }; } - + return Array.Empty(); } } \ No newline at end of file diff --git a/src/protagonist/API/Features/Image/ImageController.cs b/src/protagonist/API/Features/Image/ImageController.cs index c0810b87b..812811434 100644 --- a/src/protagonist/API/Features/Image/ImageController.cs +++ b/src/protagonist/API/Features/Image/ImageController.cs @@ -99,8 +99,7 @@ public async Task PutImage( { try { - hydraAsset = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraAsset, - Settings.EmulateOldDeliveryChannelProperties); + hydraAsset = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraAsset); } catch (APIException apiEx) { diff --git a/src/protagonist/API/Features/Image/Validation/HydraImageValidator.cs b/src/protagonist/API/Features/Image/Validation/HydraImageValidator.cs index 379210282..6e1445375 100644 --- a/src/protagonist/API/Features/Image/Validation/HydraImageValidator.cs +++ b/src/protagonist/API/Features/Image/Validation/HydraImageValidator.cs @@ -31,15 +31,11 @@ public HydraImageValidator(IOptions apiSettings) When(a => !a.DeliveryChannels.IsNullOrEmpty(), ImageDeliveryChannelDependantValidation); // Legacy policy fields - RuleFor(a => a.ImageOptimisationPolicy) - .Null() - .When(_ => !apiSettings.Value.EmulateOldDeliveryChannelProperties) - .WithMessage("'ImageOptimisationPolicy' is disabled"); - - RuleFor(a => a.ThumbnailPolicy) - .Null() - .When(_ => !apiSettings.Value.EmulateOldDeliveryChannelProperties) - .WithMessage("'ThumbnailPolicy' is disabled"); + RuleFor(a => a.ImageOptimisationPolicy).Null() + .WithMessage("'ImageOptimisationPolicy' can only be specified when legacy mode is enabled"); + + RuleFor(a => a.ThumbnailPolicy).Null() + .WithMessage("'ThumbnailPolicy' can only be specified when legacy mode is enabled"); // System edited fields RuleFor(a => a.Width).Empty().WithMessage("Should not include width"); diff --git a/src/protagonist/API/Features/Queues/CustomerQueueController.cs b/src/protagonist/API/Features/Queues/CustomerQueueController.cs index e31776a2d..a6625b973 100644 --- a/src/protagonist/API/Features/Queues/CustomerQueueController.cs +++ b/src/protagonist/API/Features/Queues/CustomerQueueController.cs @@ -371,8 +371,7 @@ private void UpdateMembers(int customerId, IList? members { if (Settings.LegacyModeEnabledForSpace(customerId, members[i].Space)) { - members[i] = LegacyModeConverter.VerifyAndConvertToModernFormat(members[i], - Settings.EmulateOldDeliveryChannelProperties); + members[i] = LegacyModeConverter.VerifyAndConvertToModernFormat(members[i]); } } } diff --git a/src/protagonist/API/Features/Queues/Validation/QueuePostValidator.cs b/src/protagonist/API/Features/Queues/Validation/QueuePostValidator.cs index 8126f998b..e2d6ed360 100644 --- a/src/protagonist/API/Features/Queues/Validation/QueuePostValidator.cs +++ b/src/protagonist/API/Features/Queues/Validation/QueuePostValidator.cs @@ -40,15 +40,11 @@ public QueuePostValidator(IOptions apiSettings) members.RuleFor(a => a.ModelId).NotEmpty().WithMessage("Asset Id cannot be empty"); members.RuleFor(a => a.Space).NotEmpty().WithMessage("Space cannot be empty"); - members.RuleFor(a => a.ImageOptimisationPolicy) - .Null() - .When(_ => !apiSettings.Value.EmulateOldDeliveryChannelProperties) - .WithMessage("'ImageOptimisationPolicy' is disabled"); + members.RuleFor(a => a.ImageOptimisationPolicy).Null() + .WithMessage("'ImageOptimisationPolicy' can only be specified when legacy mode is enabled"); - members.RuleFor(a => a.ThumbnailPolicy) - .Null() - .When(_ => !apiSettings.Value.EmulateOldDeliveryChannelProperties) - .WithMessage("'ThumbnailPolicy' is disabled"); + members.RuleFor(a => a.ThumbnailPolicy).Null() + .WithMessage("'ThumbnailPolicy' can only be specified when legacy mode is enabled"); }); } } \ No newline at end of file diff --git a/src/protagonist/API/Settings/ApiSettings.cs b/src/protagonist/API/Settings/ApiSettings.cs index 45f4e67a9..65d1d0c23 100644 --- a/src/protagonist/API/Settings/ApiSettings.cs +++ b/src/protagonist/API/Settings/ApiSettings.cs @@ -99,10 +99,4 @@ public string RestrictedAssetIdCharacterString restrictedAssetIdCharacters = restrictedAssetIdCharacterString.ToCharArray(); } } - - /// - /// Whether old delivery channel properties (e.g imageOptimisationPolicy, thumbnailPolicy) - /// on legacy payloads are supported and translated into the new format - /// - public bool EmulateOldDeliveryChannelProperties { get; set; } } \ No newline at end of file From 6c6f3edeb6e115cce27038ae80e7e7ffabf54612 Mon Sep 17 00:00:00 2001 From: griffri Date: Tue, 4 Jun 2024 11:44:54 +0100 Subject: [PATCH 19/30] Add tests for updating existing assets in legacy mode, require origin in legacy payloads --- .../API.Tests/Integration/ModifyAssetTests.cs | 214 +++++++++++++++++- .../API/Converters/LegacyModeConverter.cs | 14 +- .../Integration/DatabaseTestDataPopulation.cs | 3 +- 3 files changed, 217 insertions(+), 14 deletions(-) diff --git a/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs b/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs index ecb0b0628..1d2aa00fd 100644 --- a/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs +++ b/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs @@ -265,7 +265,7 @@ public async Task Put_NewImageAsset_Creates_AssetWithSpecifiedDeliveryChannels() asset.ImageDeliveryChannels.Should().ContainSingle(x => x.Channel == "thumbs"); } - [Fact] + [Fact] public async Task Put_NewImageAsset_Creates_Asset_WhileIgnoringCustomDefaultDeliveryChannel() { var customerAndSpace = await CreateCustomerAndSpace(); @@ -603,7 +603,8 @@ public async Task Put_Existing_Asset_UpdatesAsset_IfIncomingDeliveryChannelsNull await dbContext.Customers.AddTestCustomer(customer); await dbContext.Spaces.AddTestSpace(customer, space); - + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); + var expectedDeliveryChannels = new List() { new() @@ -614,13 +615,14 @@ public async Task Put_Existing_Asset_UpdatesAsset_IfIncomingDeliveryChannelsNull }; var testAsset = await dbContext.Images.AddTestAsset(assetId, customer: customer, space: space, - imageDeliveryChannels: expectedDeliveryChannels); + origin: $"https://example.org/{assetId.Asset}.tiff", imageDeliveryChannels: expectedDeliveryChannels); await dbContext.SaveChangesAsync(); - var hydraImageBody = @"{ + var hydraImageBody = $@"{{ + ""origin"": ""https://example.org/{assetId.Asset}.tiff"", ""string1"": ""my-string"" - }"; + }}"; A.CallTo(() => EngineClient.SynchronousIngest( @@ -631,7 +633,7 @@ public async Task Put_Existing_Asset_UpdatesAsset_IfIncomingDeliveryChannelsNull // Act var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); - + // Assert response.StatusCode.Should().Be(HttpStatusCode.OK); await dbContext.Entry(testAsset.Entity).ReloadAsync(); @@ -1163,7 +1165,7 @@ public async Task Put_Existing_Asset_AllowsUpdatingDeliveryChannel() i => i.Channel == AssetDeliveryChannels.File); } - [Fact] + [Fact] public async Task Put_Existing_Asset_AllowsSettingDeliveryChannelsToNone() { // Arrange @@ -1263,7 +1265,8 @@ await dbContext.CustomerStorages.AddAsync(new DLCS.Model.Storage.CustomerStorage // assert response.StatusCode.Should().Be(HttpStatusCode.InsufficientStorage); } - [Theory] + + [Theory] [InlineData("fast-higher")] [InlineData("https://api.dlc.services/imageOptimisationPolicies/fast-higher")] public async Task Put_NewImageAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled(string imageOptimisationPolicy) @@ -1337,6 +1340,56 @@ public async Task Put_NewImageAsset_WithImageOptimisationPolicy_Returns400_IfInv body.Should().Contain("'foo' is not a valid imageOptimisationPolicy for an image"); } + [Theory] + [InlineData("fast-higher")] + [InlineData("https://api.dlc.services/imageOptimisationPolicies/fast-higher")] + public async Task Put_ExistingImageAsset_WithImageOptimisationPolicy_AddsDeliveryChannelsToAsset_WhenLegacyEnabled(string imageOptimisationPolicy) + { + const int customer = 325665; + const int space = 2; + var assetId = new AssetId(customer, space, nameof(Put_ExistingImageAsset_WithImageOptimisationPolicy_AddsDeliveryChannelsToAsset_WhenLegacyEnabled)); + + await dbContext.Customers.AddTestCustomer(customer); + await dbContext.Spaces.AddTestSpace(customer, space); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); + await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); + await dbContext.Images.AddTestAsset(assetId, customer: customer, space: space, + family: AssetFamily.Image, origin: "https://images.org/image.tiff", mediaType: "image/tiff", + imageOptimisationPolicy: string.Empty, thumbnailPolicy: string.Empty); + await dbContext.SaveChangesAsync(); + + var hydraImageBody = $@"{{ + ""origin"": ""https://images.org/{assetId.Asset}.tiff"", + ""imageOptimisationPolicy"" : ""{imageOptimisationPolicy}"", + }}"; + + A.CallTo(() => + EngineClient.SynchronousIngest( + A.That.Matches(r => r.Id == assetId), + A._)) + .Returns(HttpStatusCode.OK); + + // act + var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); + var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + + // assert + response.StatusCode.Should().Be(HttpStatusCode.OK); + + var asset = dbContext.Images.Include(i => i.ImageDeliveryChannels) + .ThenInclude(i => i.DeliveryChannelPolicy).Single(i => i.Id == assetId); + + asset.MediaType.Should().Be("image/tiff"); + asset.Family.Should().Be(AssetFamily.Image); + asset.ImageOptimisationPolicy.Should().BeEmpty(); + asset.ThumbnailPolicy.Should().BeEmpty(); + asset.ImageDeliveryChannels.Count.Should().Be(2); + asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == AssetDeliveryChannels.Image && + dc.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ImageDefault); + asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == AssetDeliveryChannels.Thumbnails && + dc.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ThumbsDefault); + } + [Theory] [InlineData("default")] [InlineData("https://api.dlc.services/thumbnailPolicies/default")] @@ -1413,6 +1466,55 @@ public async Task Put_NewImageAsset_WithThumbnailPolicy_Returns400_IfInvalid_And body.Should().Contain("'foo' is not a valid thumbnailPolicy for an image"); } + [Theory] + [InlineData("default")] + [InlineData("https://api.dlc.services/thumbnailPolicies/default")] + public async Task Put_ExistingImageAsset_WithThumbnailPolicy_AddsDeliveryChannelsToAsset_WhenLegacyEnabled(string thumbnailPolicy) + { + const int customer = 325665; + const int space = 2; + var assetId = new AssetId(customer, space, nameof(Put_ExistingImageAsset_WithThumbnailPolicy_AddsDeliveryChannelsToAsset_WhenLegacyEnabled)); + + await dbContext.Customers.AddTestCustomer(customer); + await dbContext.Spaces.AddTestSpace(customer, space); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); + await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); + await dbContext.Images.AddTestAsset(assetId, customer: customer, space: space, + family: AssetFamily.Image, origin: "https://images.org/image.tiff", mediaType: "image/tiff", + imageOptimisationPolicy: string.Empty, thumbnailPolicy: string.Empty); + await dbContext.SaveChangesAsync(); + + var hydraImageBody = $@"{{ + ""origin"": ""https://images.org/{assetId.Asset}.tiff"", + ""thumbnailPolicy"" : ""{thumbnailPolicy}"", + }}"; + + A.CallTo(() => + EngineClient.SynchronousIngest( + A.That.Matches(r => r.Id == assetId), + A._)) + .Returns(HttpStatusCode.OK); + + // act + var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); + var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + + // assert + response.StatusCode.Should().Be(HttpStatusCode.OK); + + var asset = dbContext.Images.Include(i => i.ImageDeliveryChannels) + .ThenInclude(i => i.DeliveryChannelPolicy).Single(i => i.Id == assetId); + asset.MediaType.Should().Be("image/tiff"); + asset.Family.Should().Be(AssetFamily.Image); + asset.ImageOptimisationPolicy.Should().BeEmpty(); + asset.ThumbnailPolicy.Should().BeEmpty(); + asset.ImageDeliveryChannels.Count.Should().Be(2); + asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == AssetDeliveryChannels.Image && + dc.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ImageDefault); + asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == AssetDeliveryChannels.Thumbnails && + dc.DeliveryChannelPolicy.Name == "default"); + } + [Theory] [InlineData("video-max")] [InlineData("https://api.dlc.services/imageOptimisationPolicy/video-max")] @@ -1487,6 +1589,54 @@ public async Task Put_NewVideoAsset_WithImageOptimisationPolicy_Returns400_IfInv body.Should().Contain("'foo' is not a valid imageOptimisationPolicy for a timebased asset"); } + [Theory] + [InlineData("video-max")] + [InlineData("https://api.dlc.services/imageOptimisationPolicies/video-max")] + public async Task Put_ExistingVideoAsset_WithImageOptimisationPolicy_AddsDeliveryChannelsToAsset_WhenLegacyEnabled(string imageOptimisationPolicy) + { + const int customer = 325665; + const int space = 2; + var assetId = new AssetId(customer, space, nameof(Put_ExistingVideoAsset_WithImageOptimisationPolicy_AddsDeliveryChannelsToAsset_WhenLegacyEnabled)); + + await dbContext.Customers.AddTestCustomer(customer); + await dbContext.Spaces.AddTestSpace(customer, space); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); + await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); + await dbContext.Images.AddTestAsset(assetId, customer: customer, space: space, + family: AssetFamily.Timebased, origin: "https://images.org/image.mp4", mediaType: "video/mp4", + imageOptimisationPolicy: string.Empty, thumbnailPolicy: string.Empty); + await dbContext.SaveChangesAsync(); + + var hydraImageBody = $@"{{ + ""family"": ""T"", + ""origin"": ""https://images.org/{assetId.Asset}.mp4"", + ""thumbnailPolicy"" : ""{imageOptimisationPolicy}"", + }}"; + + A.CallTo(() => + EngineClient.AsynchronousIngest( + A.That.Matches(r => r.Id == assetId), + A._)) + .Returns(true); + + // act + var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); + var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + + // assert + response.StatusCode.Should().Be(HttpStatusCode.OK); + + var asset = dbContext.Images.Include(i => i.ImageDeliveryChannels) + .ThenInclude(i => i.DeliveryChannelPolicy).Single(i => i.Id == assetId); + asset.MediaType.Should().Be("video/mp4"); + asset.Family.Should().Be(AssetFamily.Timebased); + asset.ImageOptimisationPolicy.Should().BeEmpty(); + asset.ThumbnailPolicy.Should().BeEmpty(); + asset.ImageDeliveryChannels.Count.Should().Be(1); + asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == AssetDeliveryChannels.Timebased && + dc.DeliveryChannelPolicy.Name == "default-video"); + } + [Theory] [InlineData("audio-max")] [InlineData("https://api.dlc.services/imageOptimisationPolicy/audio-max")] @@ -1561,6 +1711,54 @@ public async Task Put_NewAudioAsset_WithImageOptimisationPolicy_Returns400_IfInv body.Should().Contain("'foo' is not a valid imageOptimisationPolicy for a timebased asset"); } + [Theory] + [InlineData("audio-max")] + [InlineData("https://api.dlc.services/imageOptimisationPolicies/audio-max")] + public async Task Put_ExistingAudioAsset_WithImageOptimisationPolicy_AddsDeliveryChannelsToAsset_WhenLegacyEnabled(string imageOptimisationPolicy) + { + const int customer = 325665; + const int space = 2; + var assetId = new AssetId(customer, space, nameof(Put_ExistingAudioAsset_WithImageOptimisationPolicy_AddsDeliveryChannelsToAsset_WhenLegacyEnabled)); + + await dbContext.Customers.AddTestCustomer(customer); + await dbContext.Spaces.AddTestSpace(customer, space); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); + await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); + await dbContext.Images.AddTestAsset(assetId, customer: customer, space: space, + family: AssetFamily.Timebased, origin: "https://images.org/image.mp3", mediaType: "audio/mp3", + imageOptimisationPolicy: string.Empty, thumbnailPolicy: string.Empty); + await dbContext.SaveChangesAsync(); + + var hydraImageBody = $@"{{ + ""family"": ""T"", + ""origin"": ""https://images.org/{assetId.Asset}.mp3"", + ""thumbnailPolicy"" : ""{imageOptimisationPolicy}"", + }}"; + + A.CallTo(() => + EngineClient.AsynchronousIngest( + A.That.Matches(r => r.Id == assetId), + A._)) + .Returns(true); + + // act + var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); + var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + + // assert + response.StatusCode.Should().Be(HttpStatusCode.OK); + + var asset = dbContext.Images.Include(i => i.ImageDeliveryChannels) + .ThenInclude(i => i.DeliveryChannelPolicy).Single(i => i.Id == assetId); + asset.MediaType.Should().Be("audio/mp3"); + asset.Family.Should().Be(AssetFamily.Timebased); + asset.ImageOptimisationPolicy.Should().BeEmpty(); + asset.ThumbnailPolicy.Should().BeEmpty(); + asset.ImageDeliveryChannels.Count.Should().Be(1); + asset.ImageDeliveryChannels.Should().ContainSingle(dc => dc.Channel == AssetDeliveryChannels.Timebased && + dc.DeliveryChannelPolicy.Name == "default-audio"); + } + [Fact] public async Task Put_NewFileAsset_Creates_Asset_WhenLegacyEnabled() { diff --git a/src/protagonist/API/Converters/LegacyModeConverter.cs b/src/protagonist/API/Converters/LegacyModeConverter.cs index d07049bcd..dc96f1061 100644 --- a/src/protagonist/API/Converters/LegacyModeConverter.cs +++ b/src/protagonist/API/Converters/LegacyModeConverter.cs @@ -24,16 +24,20 @@ public static class LegacyModeConverter public static T VerifyAndConvertToModernFormat(T image) where T : Image { + if (image.Origin is null) + { + throw new APIException($"An origin is required when legacy mode is enabled") + { + StatusCode = 400 + }; + } + if (image.MediaType.IsNullOrEmpty()) { var contentType = image.Origin?.Split('.').Last() ?? string.Empty; image.MediaType = MIMEHelper.GetContentTypeForExtension(contentType) ?? DefaultMediaType; - - if (image.Origin is not null && image.Family is null) - { - image.Family = AssetFamily.Image; - } + image.Family ??= AssetFamily.Image; } if (image.ModelId is null && image.Id is not null) diff --git a/src/protagonist/Test.Helpers/Integration/DatabaseTestDataPopulation.cs b/src/protagonist/Test.Helpers/Integration/DatabaseTestDataPopulation.cs index 75c5da816..b0ac5dd49 100644 --- a/src/protagonist/Test.Helpers/Integration/DatabaseTestDataPopulation.cs +++ b/src/protagonist/Test.Helpers/Integration/DatabaseTestDataPopulation.cs @@ -45,6 +45,7 @@ public static ValueTask> AddTestAsset(this DbSet asset bool ingesting = false, string error = "", string imageOptimisationPolicy = "", + string thumbnailPolicy = "default", DateTime? finished = null, List imageDeliveryChannels = null) { @@ -52,7 +53,7 @@ public static ValueTask> AddTestAsset(this DbSet asset { Created = DateTime.UtcNow, Customer = customer, Space = space, Id = id, Origin = origin, Width = width, Height = height, Roles = roles, Family = family, MediaType = mediaType, - ThumbnailPolicy = "default", MaxUnauthorised = maxUnauthorised, + ThumbnailPolicy = thumbnailPolicy, MaxUnauthorised = maxUnauthorised, Reference1 = ref1, Reference2 = ref2, Reference3 = ref3, NumberReference1 = num1, NumberReference2 = num2, NumberReference3 = num3, NotForDelivery = notForDelivery, Tags = "", PreservedUri = "", Error = error, From 45059322a39c259cc1f34a49b3fde911e12a14f9 Mon Sep 17 00:00:00 2001 From: griffri Date: Tue, 4 Jun 2024 11:54:25 +0100 Subject: [PATCH 20/30] Add Fails_WhenOriginNotSpecified test --- .../Converters/LegacyModeConverterTests.cs | 28 +++++++++++++++++-- .../API/Converters/LegacyModeConverter.cs | 2 +- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/protagonist/API.Tests/Converters/LegacyModeConverterTests.cs b/src/protagonist/API.Tests/Converters/LegacyModeConverterTests.cs index 8e9b66330..821e8ea2b 100644 --- a/src/protagonist/API.Tests/Converters/LegacyModeConverterTests.cs +++ b/src/protagonist/API.Tests/Converters/LegacyModeConverterTests.cs @@ -13,7 +13,8 @@ public class LegacyModeConverterTests public void VerifyAndConvertToModernFormat_ChangesNothing_WithNewFormat() { // Arrange - var hydraImage = new Image{ MediaType = "type", MaxUnauthorised = 5, Family = AssetFamily.File}; + var hydraImage = new Image{ MediaType = "type", Origin = "https://example.org/my-asset", + MaxUnauthorised = 5, Family = AssetFamily.File }; // Act var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage); @@ -24,11 +25,31 @@ public void VerifyAndConvertToModernFormat_ChangesNothing_WithNewFormat() convertedImage.Family.Should().Be(hydraImage.Family); } + [Fact] + public void VerifyAndConvertToModernFormat_Fails_WhenOriginNotSpecified() + { + // Arrange + var hydraImage = new Image() + { + Family = AssetFamily.Timebased + }; + + // Act + Action action = () => + LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage); + + // Assert + action.Should() + .ThrowExactly() + .WithMessage("An origin is required when legacy mode is enabled"); + } + [Fact] public void VerifyAndConvertToModernFormat_SetsMediaType_WithNotSet() { // Arrange - var hydraImage = new Image{ MaxUnauthorised = 5, Family = AssetFamily.File}; + var hydraImage = new Image{ MaxUnauthorised = 5, Family = AssetFamily.File, + Origin = "https://example.org/my-asset"}; // Act var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage); @@ -103,7 +124,8 @@ public void VerifyAndConvertToModernFormat_MaxUnauthorisedUnchanged_WhenRolesSet public void VerifyAndConvertToModernFormat_ModelIdSet_WhenNoModelId() { // Arrange - var hydraImage = new Image{ Id = "https://test/someId", MediaType = "something"}; + var hydraImage = new Image{ Id = "https://test/someId", MediaType = "something", + Origin = "https://example.org/my-asset" }; // Act var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage); diff --git a/src/protagonist/API/Converters/LegacyModeConverter.cs b/src/protagonist/API/Converters/LegacyModeConverter.cs index dc96f1061..c39d319d4 100644 --- a/src/protagonist/API/Converters/LegacyModeConverter.cs +++ b/src/protagonist/API/Converters/LegacyModeConverter.cs @@ -26,7 +26,7 @@ public static T VerifyAndConvertToModernFormat(T image) { if (image.Origin is null) { - throw new APIException($"An origin is required when legacy mode is enabled") + throw new APIException("An origin is required when legacy mode is enabled") { StatusCode = 400 }; From be67187d563a24312d819e8e6938b3e1d613c58e Mon Sep 17 00:00:00 2001 From: griffri Date: Tue, 4 Jun 2024 15:07:54 +0100 Subject: [PATCH 21/30] Handle LegacyModeConverter errors in CustomerQueueController --- .../API/Features/Queues/CustomerQueueController.cs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/protagonist/API/Features/Queues/CustomerQueueController.cs b/src/protagonist/API/Features/Queues/CustomerQueueController.cs index a6625b973..9fbb183e8 100644 --- a/src/protagonist/API/Features/Queues/CustomerQueueController.cs +++ b/src/protagonist/API/Features/Queues/CustomerQueueController.cs @@ -1,13 +1,13 @@ using System.Collections.Generic; +using System.Net; using API.Converters; -using API.Features.DeliveryChannels.Converters; +using API.Exceptions; using API.Features.Image; using API.Features.Queues.Converters; using API.Features.Queues.Requests; using API.Features.Queues.Validation; using API.Infrastructure; using API.Settings; -using DLCS.Core.Collections; using DLCS.Core.Strings; using DLCS.HydraModel; using DLCS.Model.Assets; @@ -328,7 +328,15 @@ public async Task GetRecentBatches([FromRoute] int customerId, Ca private async Task CreateBatchInternal(int customerId, HydraCollection images, QueuePostValidator validator, string queueName, CancellationToken cancellationToken) { - UpdateMembers(customerId, images.Members); + try + { + UpdateMembers(customerId, images.Members); + } + catch (APIException apiEx) + { + return this.HydraProblem(apiEx.Message, null, + (int?)HttpStatusCode.BadRequest, "Failed to convert legacy asset"); + } var validationResult = await validator.ValidateAsync(images, cancellationToken); if (!validationResult.IsValid) From f1873fcfaf1589063918bb1d08e3a64524b52cd4 Mon Sep 17 00:00:00 2001 From: griffri Date: Tue, 4 Jun 2024 16:30:44 +0100 Subject: [PATCH 22/30] Use GetAssetId() to generate asset ID for legacy IOP/TP tests --- .../API.Tests/Integration/ModifyAssetTests.cs | 31 +++++++++---------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs b/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs index 1d2aa00fd..9b6070588 100644 --- a/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs +++ b/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs @@ -599,7 +599,7 @@ public async Task Put_Existing_Asset_UpdatesAsset_IfIncomingDeliveryChannelsNull { const int customer = 325665; const int space = 2; - var assetId = new AssetId(customer, space, nameof(Put_Existing_Asset_UpdatesAsset_IfIncomingDeliveryChannelsNull_AndLegacyEnabled)); + var assetId = AssetIdGenerator.GetAssetId(customer, space); await dbContext.Customers.AddTestCustomer(customer); await dbContext.Spaces.AddTestSpace(customer, space); @@ -1273,7 +1273,7 @@ public async Task Put_NewImageAsset_WithImageOptimisationPolicy_Creates_Asset_Wh { const int customer = 325665; const int space = 2; - var assetId = new AssetId(customer, space, nameof(Put_NewImageAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled)); + var assetId = AssetIdGenerator.GetAssetId(customer, space); await dbContext.Customers.AddTestCustomer(customer); await dbContext.Spaces.AddTestSpace(customer, space); await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); @@ -1317,7 +1317,7 @@ public async Task Put_NewImageAsset_WithImageOptimisationPolicy_Returns400_IfInv { const int customer = 325665; const int space = 2; - var assetId = new AssetId(customer, space, nameof(Put_NewImageAsset_WithImageOptimisationPolicy_Returns400_IfInvalid_AndLegacyEnabled)); + var assetId = AssetIdGenerator.GetAssetId(customer, space); await dbContext.Customers.AddTestCustomer(customer); await dbContext.Spaces.AddTestSpace(customer, space); await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); @@ -1347,7 +1347,7 @@ public async Task Put_ExistingImageAsset_WithImageOptimisationPolicy_AddsDeliver { const int customer = 325665; const int space = 2; - var assetId = new AssetId(customer, space, nameof(Put_ExistingImageAsset_WithImageOptimisationPolicy_AddsDeliveryChannelsToAsset_WhenLegacyEnabled)); + var assetId = AssetIdGenerator.GetAssetId(customer, space); await dbContext.Customers.AddTestCustomer(customer); await dbContext.Spaces.AddTestSpace(customer, space); @@ -1397,7 +1397,7 @@ public async Task Put_NewImageAsset_WithThumbnailPolicy_Creates_Asset_WhenLegacy { const int customer = 325665; const int space = 2; - var assetId = new AssetId(customer, space, nameof(Put_NewImageAsset_WithThumbnailPolicy_Creates_Asset_WhenLegacyEnabled)); + var assetId = AssetIdGenerator.GetAssetId(customer, space); await dbContext.Customers.AddTestCustomer(customer); await dbContext.Spaces.AddTestSpace(customer, space); @@ -1443,7 +1443,7 @@ public async Task Put_NewImageAsset_WithThumbnailPolicy_Returns400_IfInvalid_And { const int customer = 325665; const int space = 2; - var assetId = new AssetId(customer, space, nameof(Put_NewImageAsset_WithImageOptimisationPolicy_Returns400_IfInvalid_AndLegacyEnabled)); + var assetId = AssetIdGenerator.GetAssetId(customer, space); await dbContext.Customers.AddTestCustomer(customer); await dbContext.Spaces.AddTestSpace(customer, space); await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); @@ -1473,7 +1473,7 @@ public async Task Put_ExistingImageAsset_WithThumbnailPolicy_AddsDeliveryChannel { const int customer = 325665; const int space = 2; - var assetId = new AssetId(customer, space, nameof(Put_ExistingImageAsset_WithThumbnailPolicy_AddsDeliveryChannelsToAsset_WhenLegacyEnabled)); + var assetId = AssetIdGenerator.GetAssetId(customer, space); await dbContext.Customers.AddTestCustomer(customer); await dbContext.Spaces.AddTestSpace(customer, space); @@ -1522,7 +1522,7 @@ public async Task Put_NewVideoAsset_WithImageOptimisationPolicy_Creates_Asset_Wh { const int customer = 325665; const int space = 2; - var assetId = new AssetId(customer, space, nameof(Put_NewVideoAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled)); + var assetId = AssetIdGenerator.GetAssetId(customer, space); await dbContext.Customers.AddTestCustomer(customer); await dbContext.Spaces.AddTestSpace(customer, space); await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); @@ -1565,7 +1565,7 @@ public async Task Put_NewVideoAsset_WithImageOptimisationPolicy_Returns400_IfInv { const int customer = 325665; const int space = 2; - var assetId = new AssetId(customer, space, nameof(Put_NewVideoAsset_WithImageOptimisationPolicy_Returns400_IfInvalid_AndLegacyEnabled)); + var assetId = AssetIdGenerator.GetAssetId(customer, space); await dbContext.Customers.AddTestCustomer(customer); await dbContext.Spaces.AddTestSpace(customer, space); await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); @@ -1596,8 +1596,7 @@ public async Task Put_ExistingVideoAsset_WithImageOptimisationPolicy_AddsDeliver { const int customer = 325665; const int space = 2; - var assetId = new AssetId(customer, space, nameof(Put_ExistingVideoAsset_WithImageOptimisationPolicy_AddsDeliveryChannelsToAsset_WhenLegacyEnabled)); - + var assetId = AssetIdGenerator.GetAssetId(customer, space); await dbContext.Customers.AddTestCustomer(customer); await dbContext.Spaces.AddTestSpace(customer, space); await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); @@ -1644,7 +1643,7 @@ public async Task Put_NewAudioAsset_WithImageOptimisationPolicy_Creates_Asset_Wh { const int customer = 325665; const int space = 2; - var assetId = new AssetId(customer, space, nameof(Put_NewAudioAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled)); + var assetId = AssetIdGenerator.GetAssetId(customer, space); await dbContext.Customers.AddTestCustomer(customer); await dbContext.Spaces.AddTestSpace(customer, space); await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); @@ -1687,7 +1686,7 @@ public async Task Put_NewAudioAsset_WithImageOptimisationPolicy_Returns400_IfInv { const int customer = 325665; const int space = 2; - var assetId = new AssetId(customer, space, nameof(Put_NewAudioAsset_WithImageOptimisationPolicy_Returns400_IfInvalid_AndLegacyEnabled)); + var assetId = AssetIdGenerator.GetAssetId(customer, space); await dbContext.Customers.AddTestCustomer(customer); await dbContext.Spaces.AddTestSpace(customer, space); await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); @@ -1718,8 +1717,7 @@ public async Task Put_ExistingAudioAsset_WithImageOptimisationPolicy_AddsDeliver { const int customer = 325665; const int space = 2; - var assetId = new AssetId(customer, space, nameof(Put_ExistingAudioAsset_WithImageOptimisationPolicy_AddsDeliveryChannelsToAsset_WhenLegacyEnabled)); - + var assetId = AssetIdGenerator.GetAssetId(customer, space); await dbContext.Customers.AddTestCustomer(customer); await dbContext.Spaces.AddTestSpace(customer, space); await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); @@ -1764,8 +1762,7 @@ public async Task Put_NewFileAsset_Creates_Asset_WhenLegacyEnabled() { const int customer = 325665; const int space = 2; - var assetId = new AssetId(customer, space, nameof(Put_NewImageAsset_WithThumbnailPolicy_Creates_Asset_WhenLegacyEnabled)); - + var assetId = AssetIdGenerator.GetAssetId(customer, space); await dbContext.Customers.AddTestCustomer(customer); await dbContext.Spaces.AddTestSpace(customer, space); await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); From d99ee63680189040323e3c54b69e91947da29521 Mon Sep 17 00:00:00 2001 From: griffri Date: Tue, 4 Jun 2024 17:21:24 +0100 Subject: [PATCH 23/30] Remove redundant legacy mode check --- src/protagonist/API/Features/Image/Ingest/AssetProcessor.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/protagonist/API/Features/Image/Ingest/AssetProcessor.cs b/src/protagonist/API/Features/Image/Ingest/AssetProcessor.cs index fe80d1c71..e832730e1 100644 --- a/src/protagonist/API/Features/Image/Ingest/AssetProcessor.cs +++ b/src/protagonist/API/Features/Image/Ingest/AssetProcessor.cs @@ -93,8 +93,7 @@ public async Task Process(AssetBeforeProcessing assetBeforeP counts.CustomerStorage.NumberOfStoredImages++; } - else if (assetBeforeProcessing.DeliveryChannelsBeforeProcessing.IsNullOrEmpty() && alwaysReingest - && !settings.LegacyModeEnabledForSpace(assetBeforeProcessing.Asset.Customer, assetBeforeProcessing.Asset.Space)) + else if (assetBeforeProcessing.DeliveryChannelsBeforeProcessing.IsNullOrEmpty() && alwaysReingest) { return new ProcessAssetResult { From c13e9d270c75f596c58633922219c0b6be32c9d7 Mon Sep 17 00:00:00 2001 From: griffri Date: Tue, 4 Jun 2024 17:58:13 +0100 Subject: [PATCH 24/30] Reword IOP/TP rejection messages --- src/protagonist/API.Tests/Integration/ModifyAssetTests.cs | 8 ++++---- .../API/Features/Image/Validation/HydraImageValidator.cs | 4 ++-- .../API/Features/Queues/Validation/QueuePostValidator.cs | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs b/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs index 9b6070588..1b4a4658e 100644 --- a/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs +++ b/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs @@ -991,7 +991,7 @@ public async Task Put_Asset_Fails_When_ThumbnailPolicy_Is_Provided() response.StatusCode.Should().Be(HttpStatusCode.BadRequest); var body = await response.Content.ReadAsStringAsync(); - body.Should().Contain("'ThumbnailPolicy' can only be specified when legacy mode is enabled"); + body.Should().Contain("'thumbnailPolicy' is deprecated. Use 'deliveryChannels' instead."); } [Fact] @@ -1016,7 +1016,7 @@ public async Task Put_Asset_Fails_When_ImageOptimisationPolicy_Is_Provided() response.StatusCode.Should().Be(HttpStatusCode.BadRequest); var body = await response.Content.ReadAsStringAsync(); - body.Should().Contain("'ImageOptimisationPolicy' can only be specified when legacy mode is enabled"); + body.Should().Contain("'imageOptimisationPolicy' is deprecated. Use 'deliveryChannels' instead."); } [Fact] @@ -2069,7 +2069,7 @@ public async Task Patch_Asset_Fails_When_ThumbnailPolicy_Is_Provided() response.StatusCode.Should().Be(HttpStatusCode.BadRequest); var body = await response.Content.ReadAsStringAsync(); - body.Should().Contain("'ThumbnailPolicy' can only be specified when legacy mode is enabled"); + body.Should().Contain("'thumbnailPolicy' is deprecated. Use 'deliveryChannels' instead."); } [Fact] @@ -2089,7 +2089,7 @@ public async Task Patch_Asset_Fails_When_ImageOptimisationPolicy_Is_Provided() response.StatusCode.Should().Be(HttpStatusCode.BadRequest); var body = await response.Content.ReadAsStringAsync(); - body.Should().Contain("'ImageOptimisationPolicy' can only be specified when legacy mode is enabled"); + body.Should().Contain("'imageOptimisationPolicy' is deprecated. Use 'deliveryChannels' instead."); } [Fact] diff --git a/src/protagonist/API/Features/Image/Validation/HydraImageValidator.cs b/src/protagonist/API/Features/Image/Validation/HydraImageValidator.cs index 6e1445375..d3b167d9c 100644 --- a/src/protagonist/API/Features/Image/Validation/HydraImageValidator.cs +++ b/src/protagonist/API/Features/Image/Validation/HydraImageValidator.cs @@ -32,10 +32,10 @@ public HydraImageValidator(IOptions apiSettings) // Legacy policy fields RuleFor(a => a.ImageOptimisationPolicy).Null() - .WithMessage("'ImageOptimisationPolicy' can only be specified when legacy mode is enabled"); + .WithMessage("'imageOptimisationPolicy' is deprecated. Use 'deliveryChannels' instead."); RuleFor(a => a.ThumbnailPolicy).Null() - .WithMessage("'ThumbnailPolicy' can only be specified when legacy mode is enabled"); + .WithMessage("'thumbnailPolicy' is deprecated. Use 'deliveryChannels' instead."); // System edited fields RuleFor(a => a.Width).Empty().WithMessage("Should not include width"); diff --git a/src/protagonist/API/Features/Queues/Validation/QueuePostValidator.cs b/src/protagonist/API/Features/Queues/Validation/QueuePostValidator.cs index e2d6ed360..e4eec7624 100644 --- a/src/protagonist/API/Features/Queues/Validation/QueuePostValidator.cs +++ b/src/protagonist/API/Features/Queues/Validation/QueuePostValidator.cs @@ -41,10 +41,10 @@ public QueuePostValidator(IOptions apiSettings) members.RuleFor(a => a.Space).NotEmpty().WithMessage("Space cannot be empty"); members.RuleFor(a => a.ImageOptimisationPolicy).Null() - .WithMessage("'ImageOptimisationPolicy' can only be specified when legacy mode is enabled"); + .WithMessage("'imageOptimisationPolicy' is deprecated. Use 'deliveryChannels' instead."); members.RuleFor(a => a.ThumbnailPolicy).Null() - .WithMessage("'ThumbnailPolicy' can only be specified when legacy mode is enabled"); + .WithMessage("'thumbnailPolicy' is deprecated. Use 'deliveryChannels' instead."); }); } } \ No newline at end of file From 2fb94ae2eaad1cca556ecb10a3057aa230b364ea Mon Sep 17 00:00:00 2001 From: griffri Date: Wed, 5 Jun 2024 10:07:06 +0100 Subject: [PATCH 25/30] Return status code from thrown exception --- src/protagonist/API/Features/Image/ImageController.cs | 2 +- src/protagonist/API/Features/Queues/CustomerQueueController.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/protagonist/API/Features/Image/ImageController.cs b/src/protagonist/API/Features/Image/ImageController.cs index 812811434..c02698183 100644 --- a/src/protagonist/API/Features/Image/ImageController.cs +++ b/src/protagonist/API/Features/Image/ImageController.cs @@ -104,7 +104,7 @@ public async Task PutImage( catch (APIException apiEx) { return this.HydraProblem(apiEx.Message, null, - (int?)HttpStatusCode.BadRequest, "Failed to convert legacy asset"); + apiEx.StatusCode, "Failed to convert legacy asset"); } } diff --git a/src/protagonist/API/Features/Queues/CustomerQueueController.cs b/src/protagonist/API/Features/Queues/CustomerQueueController.cs index 9fbb183e8..dda627229 100644 --- a/src/protagonist/API/Features/Queues/CustomerQueueController.cs +++ b/src/protagonist/API/Features/Queues/CustomerQueueController.cs @@ -335,7 +335,7 @@ private async Task CreateBatchInternal(int customerId, HydraColle catch (APIException apiEx) { return this.HydraProblem(apiEx.Message, null, - (int?)HttpStatusCode.BadRequest, "Failed to convert legacy asset"); + apiEx.StatusCode, "Failed to convert legacy asset"); } var validationResult = await validator.ValidateAsync(images, cancellationToken); From e5549888e15b9f601577df0cf6856dddc6ec77bb Mon Sep 17 00:00:00 2001 From: Donald Gray Date: Wed, 5 Jun 2024 12:43:51 +0100 Subject: [PATCH 26/30] Remove duplicated checks in QueuePostValidator --- .../Images/Validation/HydraImageValidatorTests.cs | 3 +-- .../API/Features/Image/Validation/HydraImageValidator.cs | 6 ++---- .../API/Features/Queues/Validation/QueuePostValidator.cs | 8 +------- 3 files changed, 4 insertions(+), 13 deletions(-) diff --git a/src/protagonist/API.Tests/Features/Images/Validation/HydraImageValidatorTests.cs b/src/protagonist/API.Tests/Features/Images/Validation/HydraImageValidatorTests.cs index 0fb554efc..b6f993aea 100644 --- a/src/protagonist/API.Tests/Features/Images/Validation/HydraImageValidatorTests.cs +++ b/src/protagonist/API.Tests/Features/Images/Validation/HydraImageValidatorTests.cs @@ -3,7 +3,6 @@ using API.Settings; using DLCS.HydraModel; using FluentValidation.TestHelper; -using Microsoft.Extensions.Options; namespace API.Tests.Features.Images.Validation; @@ -15,7 +14,7 @@ public HydraImageValidator GetSut() { RestrictedAssetIdCharacterString = "\\ " }; - return new HydraImageValidator(Options.Create(apiSettings)); + return new HydraImageValidator(); } [Theory] diff --git a/src/protagonist/API/Features/Image/Validation/HydraImageValidator.cs b/src/protagonist/API/Features/Image/Validation/HydraImageValidator.cs index d3b167d9c..5df47af64 100644 --- a/src/protagonist/API/Features/Image/Validation/HydraImageValidator.cs +++ b/src/protagonist/API/Features/Image/Validation/HydraImageValidator.cs @@ -1,10 +1,8 @@ -using API.Settings; -using DLCS.Core; +using DLCS.Core; using DLCS.Core.Collections; using DLCS.Model.Assets; using DLCS.Model.Policies; using FluentValidation; -using Microsoft.Extensions.Options; namespace API.Features.Image.Validation; @@ -13,7 +11,7 @@ namespace API.Features.Image.Validation; /// public class HydraImageValidator : AbstractValidator { - public HydraImageValidator(IOptions apiSettings) + public HydraImageValidator() { RuleSet("patch", () => { diff --git a/src/protagonist/API/Features/Queues/Validation/QueuePostValidator.cs b/src/protagonist/API/Features/Queues/Validation/QueuePostValidator.cs index e4eec7624..07c567d99 100644 --- a/src/protagonist/API/Features/Queues/Validation/QueuePostValidator.cs +++ b/src/protagonist/API/Features/Queues/Validation/QueuePostValidator.cs @@ -30,7 +30,7 @@ public QueuePostValidator(IOptions apiSettings) .Must(m => (m?.Length ?? 0) <= maxBatch) .WithMessage($"Maximum assets in single batch is {maxBatch}"); - RuleForEach(c => c.Members).SetValidator(new HydraImageValidator(apiSettings), + RuleForEach(c => c.Members).SetValidator(new HydraImageValidator(), "default", "create"); // In addition to above validation, batched updates must have ModelId + Space as this can't be taken from @@ -39,12 +39,6 @@ public QueuePostValidator(IOptions apiSettings) { members.RuleFor(a => a.ModelId).NotEmpty().WithMessage("Asset Id cannot be empty"); members.RuleFor(a => a.Space).NotEmpty().WithMessage("Space cannot be empty"); - - members.RuleFor(a => a.ImageOptimisationPolicy).Null() - .WithMessage("'imageOptimisationPolicy' is deprecated. Use 'deliveryChannels' instead."); - - members.RuleFor(a => a.ThumbnailPolicy).Null() - .WithMessage("'thumbnailPolicy' is deprecated. Use 'deliveryChannels' instead."); }); } } \ No newline at end of file From 68e2f0086c04952c492c77bad7094736922e69c6 Mon Sep 17 00:00:00 2001 From: Donald Gray Date: Wed, 5 Jun 2024 12:44:51 +0100 Subject: [PATCH 27/30] Improve LegacyModeConverter handling Use BadRequestException, better handling of mediaTypes and allow tp and iop to be provided without the value --- .../API/Converters/LegacyModeConverter.cs | 51 ++++++++++--------- .../Features/Image/Ingest/AssetProcessor.cs | 1 - .../DLCS.Hydra.Tests/JsonLd/HydraJsonTests.cs | 2 - 3 files changed, 26 insertions(+), 28 deletions(-) diff --git a/src/protagonist/API/Converters/LegacyModeConverter.cs b/src/protagonist/API/Converters/LegacyModeConverter.cs index c39d319d4..2542d0047 100644 --- a/src/protagonist/API/Converters/LegacyModeConverter.cs +++ b/src/protagonist/API/Converters/LegacyModeConverter.cs @@ -18,24 +18,20 @@ public static class LegacyModeConverter /// /// Converts from legacy format to new format /// - /// The image to convert - /// should be emulated and translated into delivery channels + /// The image to convert should be emulated and translated into delivery channels /// A converted image public static T VerifyAndConvertToModernFormat(T image) where T : Image { - if (image.Origin is null) + if (image.Origin.IsNullOrEmpty()) { - throw new APIException("An origin is required when legacy mode is enabled") - { - StatusCode = 400 - }; + throw new BadRequestException("An origin is required when legacy mode is enabled"); } if (image.MediaType.IsNullOrEmpty()) { var contentType = image.Origin?.Split('.').Last() ?? string.Empty; - + image.MediaType = MIMEHelper.GetContentTypeForExtension(contentType) ?? DefaultMediaType; image.Family ??= AssetFamily.Image; } @@ -59,14 +55,15 @@ public static T VerifyAndConvertToModernFormat(T image) return image; } - public static DeliveryChannel[]? GetDeliveryChannelsForLegacyAsset(T image) + private static DeliveryChannel[] GetDeliveryChannelsForLegacyAsset(T image) where T : Image { // Retrieve the name, if it is a path to a DLCS IOP/TP policy resource - var imageOptimisationPolicy = image.ImageOptimisationPolicy.GetLastPathElement() ?? image.ImageOptimisationPolicy; - var thumbnailPolicy = image.ThumbnailPolicy.GetLastPathElement() ?? image.ThumbnailPolicy; - - if (image.Family == AssetFamily.Image) + var imageOptimisationPolicy = GetPolicyValue(image.ImageOptimisationPolicy, "imageOptimisationPolicies/"); + var thumbnailPolicy = GetPolicyValue(image.ThumbnailPolicy, "thumbnailPolicies/"); + + // If IOP/TP specified, try to map given value. Else fallback to configured defaults (by returning null policy) + if (image.Family == AssetFamily.Image || (image.Family == null && MIMEHelper.IsImage(image.MediaType))) { string? imageChannelPolicy = null; if (!imageOptimisationPolicy.IsNullOrEmpty()) @@ -77,10 +74,7 @@ public static T VerifyAndConvertToModernFormat(T image) } else { - throw new APIException($"'{imageOptimisationPolicy}' is not a valid imageOptimisationPolicy for an image") - { - StatusCode = 400 - }; + throw new BadRequestException($"'{imageOptimisationPolicy}' is not a valid imageOptimisationPolicy for an image"); } } @@ -93,10 +87,7 @@ public static T VerifyAndConvertToModernFormat(T image) } else { - throw new APIException($"'{thumbnailPolicy}' is not a valid thumbnailPolicy for an image") - { - StatusCode = 400 - }; + throw new BadRequestException($"'{thumbnailPolicy}' is not a valid thumbnailPolicy for an image"); } } @@ -130,10 +121,8 @@ public static T VerifyAndConvertToModernFormat(T image) } else { - throw new APIException($"'{imageOptimisationPolicy}' is not a valid imageOptimisationPolicy for a timebased asset") - { - StatusCode = 400 - }; + throw new BadRequestException( + $"'{imageOptimisationPolicy}' is not a valid imageOptimisationPolicy for a timebased asset"); } } @@ -160,4 +149,16 @@ public static T VerifyAndConvertToModernFormat(T image) return Array.Empty(); } + + private static string? GetPolicyValue(string? policyValue, string pathSlug) + { + if (string.IsNullOrEmpty(policyValue)) return policyValue; + + var candidate = policyValue.GetLastPathElement(pathSlug); + if (!string.IsNullOrEmpty(candidate)) return candidate; + + // This catches sending payloads that only contain the initial slug, without a value + // e.g. https://dlcs.io/thumbnailPolicies/ + return policyValue.EndsWith(pathSlug) ? null : policyValue; + } } \ No newline at end of file diff --git a/src/protagonist/API/Features/Image/Ingest/AssetProcessor.cs b/src/protagonist/API/Features/Image/Ingest/AssetProcessor.cs index e832730e1..e5d5a0305 100644 --- a/src/protagonist/API/Features/Image/Ingest/AssetProcessor.cs +++ b/src/protagonist/API/Features/Image/Ingest/AssetProcessor.cs @@ -44,7 +44,6 @@ public AssetProcessor( /// /// Optional delegate for modifying asset prior to saving /// Current cancellation token - /// Whether the request is for the priority queue or not public async Task Process(AssetBeforeProcessing assetBeforeProcessing, bool mustExist, bool alwaysReingest, bool isBatchUpdate, Func? requiresReingestPreSave = null, CancellationToken cancellationToken = default) diff --git a/src/protagonist/DLCS.Hydra.Tests/JsonLd/HydraJsonTests.cs b/src/protagonist/DLCS.Hydra.Tests/JsonLd/HydraJsonTests.cs index ab2ec83a8..b9e01f859 100644 --- a/src/protagonist/DLCS.Hydra.Tests/JsonLd/HydraJsonTests.cs +++ b/src/protagonist/DLCS.Hydra.Tests/JsonLd/HydraJsonTests.cs @@ -16,7 +16,6 @@ public void HydraClass_Has_HydraType() operation.Type.Should().Be("hydra:Operation"); } - [Theory] [InlineData(false, null)] [InlineData(true, HydraContext)] @@ -29,7 +28,6 @@ public void HydraClass_Has_HydraContext(bool requireContext, string? expectedCon operation.Context.Should().Be(expectedContext); } - [Fact] public void HydraContext_Not_Overwritten() { From f1a0569dcad3218054dec8f48e820798a3b9c4e1 Mon Sep 17 00:00:00 2001 From: Donald Gray Date: Wed, 5 Jun 2024 12:56:02 +0100 Subject: [PATCH 28/30] Fix tests for legacyModeConverter --- .../Converters/LegacyModeConverterTests.cs | 52 +++++++++++++++---- .../API.Tests/Integration/ModifyAssetTests.cs | 4 +- 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/src/protagonist/API.Tests/Converters/LegacyModeConverterTests.cs b/src/protagonist/API.Tests/Converters/LegacyModeConverterTests.cs index 821e8ea2b..0f8ad5a3a 100644 --- a/src/protagonist/API.Tests/Converters/LegacyModeConverterTests.cs +++ b/src/protagonist/API.Tests/Converters/LegacyModeConverterTests.cs @@ -40,8 +40,9 @@ public void VerifyAndConvertToModernFormat_Fails_WhenOriginNotSpecified() // Assert action.Should() - .ThrowExactly() - .WithMessage("An origin is required when legacy mode is enabled"); + .Throw() + .WithMessage("An origin is required when legacy mode is enabled") + .And.StatusCode.Should().Be(400); } [Fact] @@ -154,6 +155,32 @@ public void VerifyAndConvertToModernFormat_AddsDeliveryChannels_WhenNotSet_ForIm dc => dc.Channel == AssetDeliveryChannels.Thumbnails && dc.Policy == null); } + + [Theory] + [InlineData("", "")] + [InlineData(null, null)] + [InlineData("http://dlc.io/imageOptimisationPolicies/", "http://dlc.io/thumbnailPolicies/")] + public void VerifyAndConvertToModernFormat_AddsDeliveryChannels_WhenProvidedWithoutPolicy_ForImage(string iop, string tp) + { + // Arrange + var hydraImage = new Image() + { + Family = AssetFamily.Image, + Origin = "something.jpg", + ImageOptimisationPolicy = iop, + ThumbnailPolicy = tp + }; + + // Act + var convertedImage = LegacyModeConverter.VerifyAndConvertToModernFormat(hydraImage); + + // Assert + convertedImage.DeliveryChannels.Should().Satisfy( + dc => dc.Channel == AssetDeliveryChannels.Image && + dc.Policy == null, + dc => dc.Channel == AssetDeliveryChannels.Thumbnails && + dc.Policy == null); + } [Fact] public void VerifyAndConvertToModernFormat_AddsDeliveryChannels_WhenNotSet_ForVideo() @@ -309,7 +336,7 @@ public void VerifyAndConvertToModernFormat_AddsImageDeliveryChannelsWithPolicies [Theory] [InlineData("video-max")] - [InlineData("https://api.dlc.services/imageOptimisationPolicy/video-max")] + [InlineData("https://api.dlc.services/imageOptimisationPolicies/video-max")] public void VerifyAndConvertToModernFormat_AddsTimebasedDeliveryChannelWithPolicy_WhenVideoMaxSpecified( string imageOptimisationPolicy) { @@ -332,7 +359,7 @@ public void VerifyAndConvertToModernFormat_AddsTimebasedDeliveryChannelWithPolic [Theory] [InlineData("audio-max")] - [InlineData("https://api.dlc.services/imageOptimisationPolicy/audio-max")] + [InlineData("https://api.dlc.services/imageOptimisationPolicies/audio-max")] public void VerifyAndConvertToModernFormat_AddsTimebasedDeliveryChannelWithPolicy_WhenAudioMaxSpecified( string imageOptimisationPolicy) { @@ -369,8 +396,9 @@ public void VerifyAndConvertToModernFormat_Fails_WhenInvalidImageOptimisationPol // Assert action.Should() - .ThrowExactly() - .WithMessage($"'not-a-policy' is not a valid imageOptimisationPolicy for an image"); + .Throw() + .WithMessage($"'not-a-policy' is not a valid imageOptimisationPolicy for an image") + .And.StatusCode.Should().Be(400); } [Fact] @@ -389,8 +417,9 @@ public void VerifyAndConvertToModernFormat_Fails_WhenInvalidThumbnailPolicySpeci // Assert action.Should() - .ThrowExactly() - .WithMessage($"'not-a-policy' is not a valid thumbnailPolicy for an image"); + .Throw() + .WithMessage($"'not-a-policy' is not a valid thumbnailPolicy for an image") + .And.StatusCode.Should().Be(400); } [Fact] @@ -410,7 +439,8 @@ public void VerifyAndConvertToModernFormat_Fails_WhenImageOptimisationPolicySpec // Assert action.Should() - .ThrowExactly() - .WithMessage($"'not-a-policy' is not a valid imageOptimisationPolicy for a timebased asset"); + .Throw() + .WithMessage($"'not-a-policy' is not a valid imageOptimisationPolicy for a timebased asset") + .And.StatusCode.Should().Be(400); } -} \ No newline at end of file +} diff --git a/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs b/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs index 1b4a4658e..f055b42f5 100644 --- a/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs +++ b/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs @@ -1517,7 +1517,7 @@ await dbContext.Images.AddTestAsset(assetId, customer: customer, space: space, [Theory] [InlineData("video-max")] - [InlineData("https://api.dlc.services/imageOptimisationPolicy/video-max")] + [InlineData("https://api.dlc.services/imageOptimisationPolicies/video-max")] public async Task Put_NewVideoAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled(string imageOptimisationPolicy) { const int customer = 325665; @@ -1638,7 +1638,7 @@ await dbContext.Images.AddTestAsset(assetId, customer: customer, space: space, [Theory] [InlineData("audio-max")] - [InlineData("https://api.dlc.services/imageOptimisationPolicy/audio-max")] + [InlineData("https://api.dlc.services/imageOptimisationPolicies/audio-max")] public async Task Put_NewAudioAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled(string imageOptimisationPolicy) { const int customer = 325665; From 3e511e95b516a4b3cfd7a6bf4a975df3ff90a00c Mon Sep 17 00:00:00 2001 From: Donald Gray Date: Mon, 10 Jun 2024 12:49:39 +0100 Subject: [PATCH 29/30] Simplify LegacyCustomer test setup Introduce helper method to create customer + spaces. Use constants when using Legacy and prefer default Customer 99 where possible --- .../Integration/CustomerQueueTests.cs | 303 ++++++------------ .../API.Tests/Integration/ModifyAssetTests.cs | 198 +++--------- .../API.Tests/LegacyModeHelpers.cs | 26 ++ .../API.Tests/appsettings.Testing.json | 6 +- 4 files changed, 180 insertions(+), 353 deletions(-) create mode 100644 src/protagonist/API.Tests/LegacyModeHelpers.cs diff --git a/src/protagonist/API.Tests/Integration/CustomerQueueTests.cs b/src/protagonist/API.Tests/Integration/CustomerQueueTests.cs index a0c2cc16f..a0e50f472 100644 --- a/src/protagonist/API.Tests/Integration/CustomerQueueTests.cs +++ b/src/protagonist/API.Tests/Integration/CustomerQueueTests.cs @@ -87,6 +87,7 @@ public CustomerQueueTests(DlcsDatabaseFixture dbFixture, ProtagonistAppFactory a.Customer == customerId && a.Space == space); + var assetInDatabase = dbContext.Images.Where(a => a.Customer == LegacyModeHelpers.LegacyCustomer && a.Space == LegacyModeHelpers.LegacySpace); assetInDatabase.Count().Should().Be(1); assetInDatabase.ToList()[0].Id.Asset.Should().Be("one"); } @@ -606,13 +592,6 @@ public async Task Post_CreateBatch_201_IfLegacyModeEnabledWithAtIdFieldSet() [Fact] public async Task Post_CreateBatch_400_WithIdEmptyString() { - const int customerId = 15; - const int space = 3; - await dbContext.Customers.AddTestCustomer(customerId); - await dbContext.Spaces.AddTestSpace(customerId, space); - await dbContext.CustomerStorages.AddTestCustomerStorage(customerId); - await dbContext.SaveChangesAsync(); - // Arrange var hydraImageBody = @"{ ""@context"": ""http://www.w3.org/ns/hydra/context.jsonld"", @@ -627,10 +606,10 @@ public async Task Post_CreateBatch_400_WithIdEmptyString() }"; var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var path = $"/customers/{customerId}/queue"; + var path = $"/customers/{LegacyModeHelpers.LegacyCustomer}/queue"; // Act - var response = await httpClient.AsCustomer(customerId).PostAsync(path, content); + var response = await httpClient.AsCustomer(LegacyModeHelpers.LegacyCustomer).PostAsync(path, content); // Assert response.StatusCode.Should().Be(HttpStatusCode.BadRequest); @@ -639,13 +618,6 @@ public async Task Post_CreateBatch_400_WithIdEmptyString() [Fact] public async Task Post_CreateBatch_201_WithMixtureOfIdSet() { - const int customerId = 15; - const int space = 4; - await dbContext.Customers.AddTestCustomer(customerId); - await dbContext.Spaces.AddTestSpace(customerId, space); - await dbContext.CustomerStorages.AddTestCustomerStorage(customerId); - await dbContext.SaveChangesAsync(); - // Arrange var hydraImageBody = @"{ ""@context"": ""http://www.w3.org/ns/hydra/context.jsonld"", @@ -653,21 +625,21 @@ public async Task Post_CreateBatch_201_WithMixtureOfIdSet() ""member"": [ { ""origin"": ""https://example.org/vid.mp4"", - ""space"": 4, + ""space"": 1, ""family"": ""T"", ""mediaType"": ""video/mp4"" }, { ""id"": """", ""origin"": ""https://example.org/vid.mp4"", - ""space"": 4, + ""space"": 1, ""family"": ""T"", ""mediaType"": ""video/mp4"" }, { ""id"": ""someId"", ""origin"": ""https://example.org/vid.mp4"", - ""space"": 4, + ""space"": 1, ""family"": ""T"", ""mediaType"": ""video/mp4"" } @@ -675,15 +647,16 @@ public async Task Post_CreateBatch_201_WithMixtureOfIdSet() }"; var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var path = $"/customers/{customerId}/queue"; + const string path = "/customers/99/queue"; // Act - var response = await httpClient.AsCustomer(customerId).PostAsync(path, content); + var response = await httpClient.AsCustomer(99).PostAsync(path, content); // Assert response.StatusCode.Should().Be(HttpStatusCode.Created); - var assetInDatabase = dbContext.Images.Where(a => a.Customer == customerId && a.Space == space); + var model = await response.ReadAsHydraResponseAsync(); + var assetInDatabase = dbContext.Images.Where(a => a.Batch == model.Id.GetLastPathElementAsInt()); assetInDatabase.Count().Should().Be(3); Guid.TryParse(assetInDatabase.ToList()[0].Id.Asset, out _).Should().BeTrue(); Guid.TryParse(assetInDatabase.ToList()[1].Id.Asset, out _).Should().BeTrue(); @@ -693,13 +666,6 @@ public async Task Post_CreateBatch_201_WithMixtureOfIdSet() [Fact] public async Task Post_CreateBatch_400_WithInvalidIdsSet() { - const int customerId = 15; - const int space = 4; - await dbContext.Customers.AddTestCustomer(customerId); - await dbContext.Spaces.AddTestSpace(customerId, space); - await dbContext.CustomerStorages.AddTestCustomerStorage(customerId); - await dbContext.SaveChangesAsync(); - // Arrange var hydraImageBody = @"{ ""@context"": ""http://www.w3.org/ns/hydra/context.jsonld"", @@ -708,14 +674,14 @@ public async Task Post_CreateBatch_400_WithInvalidIdsSet() { ""id"": ""some\id"", ""origin"": ""https://example.org/vid.mp4"", - ""space"": 4, + ""space"": 1, ""family"": ""T"", ""mediaType"": ""video/mp4"" }, { ""id"": ""some Id"", ""origin"": ""https://example.org/vid.mp4"", - ""space"": 4, + ""space"": 1, ""family"": ""T"", ""mediaType"": ""video/mp4"" } @@ -723,10 +689,10 @@ public async Task Post_CreateBatch_400_WithInvalidIdsSet() }"; var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var path = $"/customers/{customerId}/queue"; + const string path = "/customers/99/queue"; // Act - var response = await httpClient.AsCustomer(customerId).PostAsync(path, content); + var response = await httpClient.AsCustomer(99).PostAsync(path, content); // Assert response.StatusCode.Should().Be(HttpStatusCode.BadRequest); @@ -751,7 +717,7 @@ public async Task Post_CreateBatch_400_IfSpaceNotFound() }"; var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var path = "/customers/99/queue"; + const string path = "/customers/99/queue"; // Act var response = await httpClient.AsCustomer(99).PostAsync(path, content); @@ -761,73 +727,65 @@ public async Task Post_CreateBatch_400_IfSpaceNotFound() response.StatusCode.Should().Be(HttpStatusCode.BadRequest); } - [Fact] - public async Task Post_CreateBatch_400_IfThumbnailPolicySet() + [Theory] + [InlineData("I")] + [InlineData("T")] + [InlineData("F")] + public async Task Post_CreateBatch_400_IfThumbnailPolicySet(string family) { - const int customerId = 15; - const int space = 4; - await dbContext.Customers.AddTestCustomer(customerId); - await dbContext.Spaces.AddTestSpace(customerId, space); - await dbContext.CustomerStorages.AddTestCustomerStorage(customerId); - await dbContext.SaveChangesAsync(); - // Arrange - var hydraImageBody = @"{ + var hydraImageBody = $@"{{ ""@context"": ""http://www.w3.org/ns/hydra/context.jsonld"", ""@type"": ""Collection"", ""member"": [ - { + {{ ""id"": ""one"", ""origin"": ""https://example.org/vid.mp4"", - ""space"": 4, - ""family"": ""T"", + ""space"": 1, + ""family"": ""{family}"", ""thumbnailPolicy"": ""some-thumbnail-policy"" ""mediaType"": ""video/mp4"" - } + }} ] - }"; + }}"; var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var path = $"/customers/{customerId}/queue"; + const string path = "/customers/99/queue"; // Act - var response = await httpClient.AsCustomer(customerId).PostAsync(path, content); + var response = await httpClient.AsCustomer(99).PostAsync(path, content); // Assert response.StatusCode.Should().Be(HttpStatusCode.BadRequest); } - [Fact] - public async Task Post_CreateBatch_400_IfImageOptimisationPolicySet() - { - const int customerId = 15; - const int space = 4; - await dbContext.Customers.AddTestCustomer(customerId); - await dbContext.Spaces.AddTestSpace(customerId, space); - await dbContext.CustomerStorages.AddTestCustomerStorage(customerId); - await dbContext.SaveChangesAsync(); - + [Theory] + [InlineData("I")] + [InlineData("T")] + [InlineData("F")] + public async Task Post_CreateBatch_400_IfImageOptimisationPolicySet(string family) + { // Arrange - var hydraImageBody = @"{ + var hydraImageBody = $@"{{ ""@context"": ""http://www.w3.org/ns/hydra/context.jsonld"", ""@type"": ""Collection"", ""member"": [ - { + {{ ""id"": ""one"", ""origin"": ""https://example.org/vid.mp4"", - ""space"": 4, - ""family"": ""T"", - ""thumbnailPolicy"": ""some-thumbnail-policy"" + ""space"": 1, + ""family"": ""{family}"", + ""imageOptimisationPolicy"": ""some-thumbnail-policy"" ""mediaType"": ""video/mp4"" - } + }} ] - }"; + }}"; var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var path = $"/customers/{customerId}/queue"; + const string path = "/customers/99/queue"; // Act - var response = await httpClient.AsCustomer(customerId).PostAsync(path, content); + var response = await httpClient.AsCustomer(99).PostAsync(path, content); // Assert response.StatusCode.Should().Be(HttpStatusCode.BadRequest); @@ -968,31 +926,24 @@ public async Task Post_CreatePriorityBatch_400_IfNonImage() [Fact] public async Task Post_CreatePriorityBatch_201_IfLegacyModeEnabled() { - const int customerId = 15; - await dbContext.Customers.AddTestCustomer(customerId); - await dbContext.Spaces.AddTestSpace(customerId, 5); - await dbContext.CustomerStorages.AddTestCustomerStorage(customerId); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customerId); - await dbContext.SaveChangesAsync(); - // Arrange - var hydraImageBody = @"{ + var hydraImageBody = $@"{{ ""@context"": ""http://www.w3.org/ns/hydra/context.jsonld"", ""@type"": ""Collection"", ""member"": [ - { + {{ ""id"": ""one"", ""origin"": ""https://example.org/stuff.jpg"", - ""space"": 5, - } + ""space"": {LegacyModeHelpers.LegacySpace}, + }} ] -}"; +}}"; var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var path = $"/customers/{customerId}/queue/priority"; + var path = $"/customers/{LegacyModeHelpers.LegacyCustomer}/queue/priority"; // Act - var response = await httpClient.AsCustomer(customerId).PostAsync(path, content); + var response = await httpClient.AsCustomer(LegacyModeHelpers.LegacyCustomer).PostAsync(path, content); // Assert // status code correct @@ -1002,13 +953,6 @@ public async Task Post_CreatePriorityBatch_201_IfLegacyModeEnabled() [Fact] public async Task Post_CreatePriorityBatch_201_WithMixtureOfIdSet() { - const int customerId = 15; - const int space = 4; - await dbContext.Customers.AddTestCustomer(customerId); - await dbContext.Spaces.AddTestSpace(customerId, space); - await dbContext.CustomerStorages.AddTestCustomerStorage(customerId); - await dbContext.SaveChangesAsync(); - // Arrange var hydraImageBody = @"{ ""@context"": ""http://www.w3.org/ns/hydra/context.jsonld"", @@ -1016,21 +960,21 @@ public async Task Post_CreatePriorityBatch_201_WithMixtureOfIdSet() ""member"": [ { ""origin"": ""https://example.org/stuff.jpg"", - ""space"": 4, + ""space"": 1, ""family"": ""I"", ""mediaType"": ""image/jpeg"" }, { ""id"": """", ""origin"": ""https://example.org/stuff.jpg"", - ""space"": 4, + ""space"": 1, ""family"": ""I"", ""mediaType"": ""image/jpeg"" }, { ""id"": ""someId"", ""origin"": ""https://example.org/stuff.jpg"", - ""space"": 4, + ""space"": 1, ""family"": ""I"", ""mediaType"": ""image/jpeg"" } @@ -1038,15 +982,16 @@ public async Task Post_CreatePriorityBatch_201_WithMixtureOfIdSet() }"; var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var path = $"/customers/{customerId}/queue/priority"; + const string path = "/customers/99/queue/priority"; // Act - var response = await httpClient.AsCustomer(customerId).PostAsync(path, content); + var response = await httpClient.AsCustomer(99).PostAsync(path, content); // Assert response.StatusCode.Should().Be(HttpStatusCode.Created); - var assetInDatabase = dbContext.Images.Where(a => a.Customer == customerId && a.Space == space); + var model = await response.ReadAsHydraResponseAsync(); + var assetInDatabase = dbContext.Images.Where(a => a.Batch == model.Id.GetLastPathElementAsInt()); assetInDatabase.Count().Should().Be(3); Guid.TryParse(assetInDatabase.ToList()[0].Id.Asset, out _).Should().BeTrue(); Guid.TryParse(assetInDatabase.ToList()[1].Id.Asset, out _).Should().BeTrue(); @@ -1270,34 +1215,25 @@ public async Task Post_TestBatch_DoesNotChangeBatchFinished_IfImagesFoundAndAllF [Fact] public async Task Post_CreateBatch_201_IfImageOptimisationPolicySetForImage_AndLegacyEnabled() { - const int customerId = 325665; - const int space = 201; - await dbContext.Customers.AddTestCustomer(customerId); - await dbContext.Spaces.AddTestSpace(customerId, space); - await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customerId); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customerId); - await dbContext.CustomerStorages.AddTestCustomerStorage(customerId); - await dbContext.SaveChangesAsync(); - // Arrange - var hydraImageBody = @"{ + var hydraImageBody = $@"{{ ""@context"": ""http://www.w3.org/ns/hydra/context.jsonld"", ""@type"": ""Collection"", ""member"": [ - { - ""@id"": ""https://test/customers/325665/spaces/201/images/one"", + {{ + ""@id"": ""https://test/customers/{LegacyModeHelpers.LegacyCustomer}/spaces/{LegacyModeHelpers.LegacySpace}/images/one"", ""origin"": ""https://example.org/my-image.png"", ""imageOptimisationPolicy"": ""fast-higher"", ""space"": 201, - }, + }}, ] - }"; + }}"; var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var path = $"/customers/{customerId}/queue"; + var path = $"/customers/{LegacyModeHelpers.LegacyCustomer}/queue"; // Act - var response = await httpClient.AsCustomer(customerId).PostAsync(path, content); + var response = await httpClient.AsCustomer(LegacyModeHelpers.LegacyCustomer).PostAsync(path, content); // Assert response.StatusCode.Should().Be(HttpStatusCode.Created); @@ -1305,7 +1241,7 @@ public async Task Post_CreateBatch_201_IfImageOptimisationPolicySetForImage_AndL var image = dbContext.Images .Include(a => a.ImageDeliveryChannels!) .ThenInclude(dc => dc.DeliveryChannelPolicy) - .Single(i => i.Customer == customerId && i.Space == space); + .Single(i => i.Customer == LegacyModeHelpers.LegacyCustomer && i.Space == LegacyModeHelpers.LegacySpace); image.ImageDeliveryChannels!.Should().Satisfy( dc => dc.Channel == AssetDeliveryChannels.Image && @@ -1317,34 +1253,25 @@ public async Task Post_CreateBatch_201_IfImageOptimisationPolicySetForImage_AndL [Fact] public async Task Post_CreateBatch_201_IfThumbnailPolicySetForImage_AndLegacyEnabled() { - const int customerId = 325665; - const int space = 201; - await dbContext.Customers.AddTestCustomer(customerId); - await dbContext.Spaces.AddTestSpace(customerId, space); - await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customerId); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customerId); - await dbContext.CustomerStorages.AddTestCustomerStorage(customerId); - await dbContext.SaveChangesAsync(); - // Arrange - var hydraImageBody = @"{ + var hydraImageBody = $@"{{ ""@context"": ""http://www.w3.org/ns/hydra/context.jsonld"", ""@type"": ""Collection"", ""member"": [ - { - ""@id"": ""https://test/customers/325665/spaces/201/images/one"", + {{ + ""@id"": ""https://test/customers/{LegacyModeHelpers.LegacyCustomer}/spaces/{LegacyModeHelpers.LegacySpace}/images/one"", ""origin"": ""https://example.org/my-image.png"", ""thumbnailPolicy"": ""default"", - ""space"": 201, - }, + ""space"": {LegacyModeHelpers.LegacySpace}, + }}, ] - }"; + }}"; var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var path = $"/customers/{customerId}/queue"; + var path = $"/customers/{LegacyModeHelpers.LegacyCustomer}/queue"; // Act - var response = await httpClient.AsCustomer(customerId).PostAsync(path, content); + var response = await httpClient.AsCustomer(LegacyModeHelpers.LegacyCustomer).PostAsync(path, content); // Assert response.StatusCode.Should().Be(HttpStatusCode.Created); @@ -1352,7 +1279,7 @@ public async Task Post_CreateBatch_201_IfThumbnailPolicySetForImage_AndLegacyEna var image = dbContext.Images .Include(a => a.ImageDeliveryChannels!) .ThenInclude(dc => dc.DeliveryChannelPolicy) - .Single(i => i.Customer == customerId && i.Space == space); + .Single(i => i.Customer == LegacyModeHelpers.LegacyCustomer && i.Space == LegacyModeHelpers.LegacySpace); image.ImageDeliveryChannels!.Should().Satisfy( dc => dc.Channel == AssetDeliveryChannels.Image && @@ -1364,35 +1291,26 @@ public async Task Post_CreateBatch_201_IfThumbnailPolicySetForImage_AndLegacyEna [Fact] public async Task Post_CreateBatch_201_IfImageOptimisationPolicySetForVideo_AndLegacyEnabled() { - const int customerId = 325665; - const int space = 201; - await dbContext.Customers.AddTestCustomer(customerId); - await dbContext.Spaces.AddTestSpace(customerId, space); - await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customerId); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customerId); - await dbContext.CustomerStorages.AddTestCustomerStorage(customerId); - await dbContext.SaveChangesAsync(); - // Arrange - var hydraImageBody = @"{ + var hydraImageBody = $@"{{ ""@context"": ""http://www.w3.org/ns/hydra/context.jsonld"", ""@type"": ""Collection"", ""member"": [ - { - ""@id"": ""https://test/customers/325665/spaces/201/images/one"", + {{ + ""@id"": ""https://test/customers/{LegacyModeHelpers.LegacyCustomer}/spaces/{LegacyModeHelpers.LegacySpace}/images/one"", ""family"": ""T"", ""origin"": ""https://example.org/my-video.mp4"", ""imageOptimisationPolicy"": ""video-max"", ""space"": 201, - }, + }}, ] - }"; + }}"; var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var path = $"/customers/{customerId}/queue"; + var path = $"/customers/{LegacyModeHelpers.LegacyCustomer}/queue"; // Act - var response = await httpClient.AsCustomer(customerId).PostAsync(path, content); + var response = await httpClient.AsCustomer(LegacyModeHelpers.LegacyCustomer).PostAsync(path, content); // Assert response.StatusCode.Should().Be(HttpStatusCode.Created); @@ -1400,7 +1318,7 @@ public async Task Post_CreateBatch_201_IfImageOptimisationPolicySetForVideo_AndL var image = dbContext.Images .Include(a => a.ImageDeliveryChannels!) .ThenInclude(dc => dc.DeliveryChannelPolicy) - .Single(i => i.Customer == customerId && i.Space == space); + .Single(i => i.Customer == LegacyModeHelpers.LegacyCustomer && i.Space == LegacyModeHelpers.LegacySpace); image.ImageDeliveryChannels!.Should().Satisfy( dc => dc.Channel == AssetDeliveryChannels.Timebased && @@ -1410,35 +1328,26 @@ public async Task Post_CreateBatch_201_IfImageOptimisationPolicySetForVideo_AndL [Fact] public async Task Post_CreateBatch_201_IfImageOptimisationPolicySetForAudio_AndLegacyEnabled() { - const int customerId = 325665; - const int space = 201; - await dbContext.Customers.AddTestCustomer(customerId); - await dbContext.Spaces.AddTestSpace(customerId, space); - await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customerId); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customerId); - await dbContext.CustomerStorages.AddTestCustomerStorage(customerId); - await dbContext.SaveChangesAsync(); - // Arrange - var hydraImageBody = @"{ + var hydraImageBody = $@"{{ ""@context"": ""http://www.w3.org/ns/hydra/context.jsonld"", ""@type"": ""Collection"", ""member"": [ - { - ""@id"": ""https://test/customers/325665/spaces/201/images/one"", + {{ + ""@id"": ""https://test/customers/{LegacyModeHelpers.LegacyCustomer}/spaces/{LegacyModeHelpers.LegacySpace}/images/one"", ""family"": ""T"", ""origin"": ""https://example.org/my-audio.mp3"", ""imageOptimisationPolicy"": ""audio-max"", ""space"": 201, - }, + }}, ] - }"; + }}"; var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var path = $"/customers/{customerId}/queue"; + var path = $"/customers/{LegacyModeHelpers.LegacyCustomer}/queue"; // Act - var response = await httpClient.AsCustomer(customerId).PostAsync(path, content); + var response = await httpClient.AsCustomer(LegacyModeHelpers.LegacyCustomer).PostAsync(path, content); // Assert response.StatusCode.Should().Be(HttpStatusCode.Created); @@ -1446,7 +1355,7 @@ public async Task Post_CreateBatch_201_IfImageOptimisationPolicySetForAudio_AndL var image = dbContext.Images .Include(a => a.ImageDeliveryChannels!) .ThenInclude(dc => dc.DeliveryChannelPolicy) - .Single(i => i.Customer == customerId && i.Space == space); + .Single(i => i.Customer == LegacyModeHelpers.LegacyCustomer && i.Space == LegacyModeHelpers.LegacySpace); image.ImageDeliveryChannels!.Should().Satisfy( dc => dc.Channel == AssetDeliveryChannels.Timebased && diff --git a/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs b/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs index f055b42f5..827b49472 100644 --- a/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs +++ b/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs @@ -42,7 +42,7 @@ public class ModifyAssetTests : IClassFixture> private static readonly IAssetNotificationSender NotificationSender = A.Fake(); private readonly IAmazonS3 amazonS3; private static readonly IEngineClient EngineClient = A.Fake(); - + public ModifyAssetTests( StorageFixture storageFixture, ProtagonistAppFactory factory) @@ -69,6 +69,8 @@ public ModifyAssetTests( }); dbFixture.CleanUp(); + + LegacyModeHelpers.SetupLegacyCustomer(dbContext).Wait(); } [Fact] @@ -266,10 +268,12 @@ public async Task Put_NewImageAsset_Creates_AssetWithSpecifiedDeliveryChannels() } [Fact] - public async Task Put_NewImageAsset_Creates_Asset_WhileIgnoringCustomDefaultDeliveryChannel() + public async Task Put_NewImageAsset_CreatesAsset_WhileIgnoringDefaultDeliveryChannelForDifferentSpace() { var customerAndSpace = await CreateCustomerAndSpace(); + // Create a new policy and DefaultDeliveryChannel for a space that isn't the one used. Meaning we fallback to + // the system defaultDeliveryChannel var newPolicy = await dbContext.DeliveryChannelPolicies.AddAsync(new DLCS.Model.Policies.DeliveryChannelPolicy() { Created = DateTime.UtcNow, @@ -279,9 +283,8 @@ public async Task Put_NewImageAsset_Creates_Asset_WhileIgnoringCustomDefaultDeli Name = "space-specific-image", Channel = "iiif-img", Customer = customerAndSpace.customer, - Id = 260 + Id = 9988 }); - await dbContext.DefaultDeliveryChannels.AddAsync(new DLCS.Model.DeliveryChannels.DefaultDeliveryChannel { Space = customerAndSpace.space + 1, @@ -292,7 +295,7 @@ await dbContext.DefaultDeliveryChannels.AddAsync(new DLCS.Model.DeliveryChannels await dbContext.SaveChangesAsync(); - var assetId = new AssetId(customerAndSpace.customer, customerAndSpace.space, nameof(Put_NewImageAsset_Creates_Asset)); + var assetId = AssetIdGenerator.GetAssetId(customerAndSpace.customer, customerAndSpace.space); var hydraImageBody = $@"{{ ""@type"": ""Image"", ""origin"": ""https://example.org/{assetId.Asset}.tiff"", @@ -317,7 +320,8 @@ await dbContext.DefaultDeliveryChannels.AddAsync(new DLCS.Model.DeliveryChannels asset.MaxUnauthorised.Should().Be(-1); asset.ImageDeliveryChannels.Count.Should().Be(2); asset.ImageDeliveryChannels.Should().ContainSingle(x => x.Channel == "iiif-img" && - x.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ImageDefault); + x.DeliveryChannelPolicyId == KnownDeliveryChannelPolicies.ImageDefault, + "Default DeliveryChannelPolicyId used as new DefaultDeliveryChannel is for a different space"); asset.ImageDeliveryChannels.Should().ContainSingle(x => x.Channel == "thumbs"); } @@ -520,13 +524,7 @@ public async Task Put_NewImageAsset_FailsToCreateAsset_WhenMatchingDefaultDelive [Fact] public async Task Put_NewImageAsset_CreatesAsset_WhenMediaTypeAndFamilyNotSetWithLegacyEnabled() { - const int customer = 325665; - const int space = 2; - var assetId = new AssetId(customer, space, nameof(Put_NewImageAsset_CreatesAsset_WhenMediaTypeAndFamilyNotSetWithLegacyEnabled)); - await dbContext.Customers.AddTestCustomer(customer); - await dbContext.Spaces.AddTestSpace(customer, space); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); - await dbContext.SaveChangesAsync(); + var assetId = AssetIdGenerator.GetAssetId(LegacyModeHelpers.LegacyCustomer, LegacyModeHelpers.LegacySpace); var hydraImageBody = $@"{{ ""@type"": ""Image"", @@ -540,7 +538,7 @@ public async Task Put_NewImageAsset_CreatesAsset_WhenMediaTypeAndFamilyNotSetWit // act var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + var response = await httpClient.AsCustomer(LegacyModeHelpers.LegacyCustomer).PutAsync(assetId.ToApiResourcePath(), content); // assert response.StatusCode.Should().Be(HttpStatusCode.Created); @@ -558,13 +556,7 @@ public async Task Put_NewImageAsset_CreatesAsset_WhenMediaTypeAndFamilyNotSetWit [Fact] public async Task Put_NewImageAsset_CreatesAsset_WhenInferringOfMediaTypeNotPossibleWithLegacyEnabled() { - const int customer = 325665; - const int space = 2; - var assetId = new AssetId(customer, space, nameof(Put_NewImageAsset_CreatesAsset_WhenInferringOfMediaTypeNotPossibleWithLegacyEnabled)); - await dbContext.Customers.AddTestCustomer(customer); - await dbContext.Spaces.AddTestSpace(customer, space); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); - await dbContext.SaveChangesAsync(); + var assetId = AssetIdGenerator.GetAssetId(LegacyModeHelpers.LegacyCustomer, LegacyModeHelpers.LegacySpace); var hydraImageBody = $@"{{ ""@type"": ""Image"", @@ -578,7 +570,7 @@ public async Task Put_NewImageAsset_CreatesAsset_WhenInferringOfMediaTypeNotPoss // act var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + var response = await httpClient.AsCustomer(LegacyModeHelpers.LegacyCustomer).PutAsync(assetId.ToApiResourcePath(), content); // assert response.StatusCode.Should().Be(HttpStatusCode.Created); @@ -597,13 +589,7 @@ public async Task Put_NewImageAsset_CreatesAsset_WhenInferringOfMediaTypeNotPoss [Fact] public async Task Put_Existing_Asset_UpdatesAsset_IfIncomingDeliveryChannelsNull_AndLegacyEnabled() { - const int customer = 325665; - const int space = 2; - var assetId = AssetIdGenerator.GetAssetId(customer, space); - - await dbContext.Customers.AddTestCustomer(customer); - await dbContext.Spaces.AddTestSpace(customer, space); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); + var assetId = AssetIdGenerator.GetAssetId(LegacyModeHelpers.LegacyCustomer, LegacyModeHelpers.LegacySpace); var expectedDeliveryChannels = new List() { @@ -614,7 +600,7 @@ public async Task Put_Existing_Asset_UpdatesAsset_IfIncomingDeliveryChannelsNull } }; - var testAsset = await dbContext.Images.AddTestAsset(assetId, customer: customer, space: space, + var testAsset = await dbContext.Images.AddTestAsset(assetId, customer: LegacyModeHelpers.LegacyCustomer, space: LegacyModeHelpers.LegacySpace, origin: $"https://example.org/{assetId.Asset}.tiff", imageDeliveryChannels: expectedDeliveryChannels); await dbContext.SaveChangesAsync(); @@ -632,7 +618,7 @@ public async Task Put_Existing_Asset_UpdatesAsset_IfIncomingDeliveryChannelsNull // Act var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + var response = await httpClient.AsCustomer(LegacyModeHelpers.LegacyCustomer).PutAsync(assetId.ToApiResourcePath(), content); // Assert response.StatusCode.Should().Be(HttpStatusCode.OK); @@ -1271,14 +1257,7 @@ await dbContext.CustomerStorages.AddAsync(new DLCS.Model.Storage.CustomerStorage [InlineData("https://api.dlc.services/imageOptimisationPolicies/fast-higher")] public async Task Put_NewImageAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled(string imageOptimisationPolicy) { - const int customer = 325665; - const int space = 2; - var assetId = AssetIdGenerator.GetAssetId(customer, space); - await dbContext.Customers.AddTestCustomer(customer); - await dbContext.Spaces.AddTestSpace(customer, space); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); - await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); - await dbContext.SaveChangesAsync(); + var assetId = AssetIdGenerator.GetAssetId(LegacyModeHelpers.LegacyCustomer, LegacyModeHelpers.LegacySpace); var hydraImageBody = $@"{{ ""origin"": ""https://example.org/{assetId.Asset}.tiff"", @@ -1293,7 +1272,7 @@ public async Task Put_NewImageAsset_WithImageOptimisationPolicy_Creates_Asset_Wh // act var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + var response = await httpClient.AsCustomer(LegacyModeHelpers.LegacyCustomer).PutAsync(assetId.ToApiResourcePath(), content); // assert response.StatusCode.Should().Be(HttpStatusCode.Created); @@ -1315,14 +1294,7 @@ public async Task Put_NewImageAsset_WithImageOptimisationPolicy_Creates_Asset_Wh [Fact] public async Task Put_NewImageAsset_WithImageOptimisationPolicy_Returns400_IfInvalid_AndLegacyEnabled() { - const int customer = 325665; - const int space = 2; - var assetId = AssetIdGenerator.GetAssetId(customer, space); - await dbContext.Customers.AddTestCustomer(customer); - await dbContext.Spaces.AddTestSpace(customer, space); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); - await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); - await dbContext.SaveChangesAsync(); + var assetId = AssetIdGenerator.GetAssetId(LegacyModeHelpers.LegacyCustomer, LegacyModeHelpers.LegacySpace); var hydraImageBody = $@"{{ ""origin"": ""https://example.org/{assetId.Asset}.tiff"", @@ -1331,7 +1303,7 @@ public async Task Put_NewImageAsset_WithImageOptimisationPolicy_Returns400_IfInv // act var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + var response = await httpClient.AsCustomer(LegacyModeHelpers.LegacyCustomer).PutAsync(assetId.ToApiResourcePath(), content); // assert response.StatusCode.Should().Be(HttpStatusCode.BadRequest); @@ -1345,15 +1317,8 @@ public async Task Put_NewImageAsset_WithImageOptimisationPolicy_Returns400_IfInv [InlineData("https://api.dlc.services/imageOptimisationPolicies/fast-higher")] public async Task Put_ExistingImageAsset_WithImageOptimisationPolicy_AddsDeliveryChannelsToAsset_WhenLegacyEnabled(string imageOptimisationPolicy) { - const int customer = 325665; - const int space = 2; - var assetId = AssetIdGenerator.GetAssetId(customer, space); - - await dbContext.Customers.AddTestCustomer(customer); - await dbContext.Spaces.AddTestSpace(customer, space); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); - await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); - await dbContext.Images.AddTestAsset(assetId, customer: customer, space: space, + var assetId = AssetIdGenerator.GetAssetId(LegacyModeHelpers.LegacyCustomer, LegacyModeHelpers.LegacySpace); + await dbContext.Images.AddTestAsset(assetId, customer: LegacyModeHelpers.LegacyCustomer, space: LegacyModeHelpers.LegacySpace, family: AssetFamily.Image, origin: "https://images.org/image.tiff", mediaType: "image/tiff", imageOptimisationPolicy: string.Empty, thumbnailPolicy: string.Empty); await dbContext.SaveChangesAsync(); @@ -1371,7 +1336,7 @@ await dbContext.Images.AddTestAsset(assetId, customer: customer, space: space, // act var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + var response = await httpClient.AsCustomer(LegacyModeHelpers.LegacyCustomer).PutAsync(assetId.ToApiResourcePath(), content); // assert response.StatusCode.Should().Be(HttpStatusCode.OK); @@ -1395,15 +1360,7 @@ await dbContext.Images.AddTestAsset(assetId, customer: customer, space: space, [InlineData("https://api.dlc.services/thumbnailPolicies/default")] public async Task Put_NewImageAsset_WithThumbnailPolicy_Creates_Asset_WhenLegacyEnabled(string thumbnailPolicy) { - const int customer = 325665; - const int space = 2; - var assetId = AssetIdGenerator.GetAssetId(customer, space); - - await dbContext.Customers.AddTestCustomer(customer); - await dbContext.Spaces.AddTestSpace(customer, space); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); - await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); - await dbContext.SaveChangesAsync(); + var assetId = AssetIdGenerator.GetAssetId(LegacyModeHelpers.LegacyCustomer, LegacyModeHelpers.LegacySpace); var hydraImageBody = $@"{{ ""@type"": ""Image"", @@ -1419,7 +1376,7 @@ public async Task Put_NewImageAsset_WithThumbnailPolicy_Creates_Asset_WhenLegacy // act var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + var response = await httpClient.AsCustomer(LegacyModeHelpers.LegacyCustomer).PutAsync(assetId.ToApiResourcePath(), content); // assert response.StatusCode.Should().Be(HttpStatusCode.Created); @@ -1441,14 +1398,7 @@ public async Task Put_NewImageAsset_WithThumbnailPolicy_Creates_Asset_WhenLegacy [Fact] public async Task Put_NewImageAsset_WithThumbnailPolicy_Returns400_IfInvalid_AndLegacyEnabled() { - const int customer = 325665; - const int space = 2; - var assetId = AssetIdGenerator.GetAssetId(customer, space); - await dbContext.Customers.AddTestCustomer(customer); - await dbContext.Spaces.AddTestSpace(customer, space); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); - await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); - await dbContext.SaveChangesAsync(); + var assetId = AssetIdGenerator.GetAssetId(LegacyModeHelpers.LegacyCustomer, LegacyModeHelpers.LegacySpace); var hydraImageBody = $@"{{ ""origin"": ""https://example.org/{assetId.Asset}.tiff"", @@ -1457,7 +1407,7 @@ public async Task Put_NewImageAsset_WithThumbnailPolicy_Returns400_IfInvalid_And // act var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + var response = await httpClient.AsCustomer(LegacyModeHelpers.LegacyCustomer).PutAsync(assetId.ToApiResourcePath(), content); // assert response.StatusCode.Should().Be(HttpStatusCode.BadRequest); @@ -1471,15 +1421,8 @@ public async Task Put_NewImageAsset_WithThumbnailPolicy_Returns400_IfInvalid_And [InlineData("https://api.dlc.services/thumbnailPolicies/default")] public async Task Put_ExistingImageAsset_WithThumbnailPolicy_AddsDeliveryChannelsToAsset_WhenLegacyEnabled(string thumbnailPolicy) { - const int customer = 325665; - const int space = 2; - var assetId = AssetIdGenerator.GetAssetId(customer, space); - - await dbContext.Customers.AddTestCustomer(customer); - await dbContext.Spaces.AddTestSpace(customer, space); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); - await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); - await dbContext.Images.AddTestAsset(assetId, customer: customer, space: space, + var assetId = AssetIdGenerator.GetAssetId(LegacyModeHelpers.LegacyCustomer, LegacyModeHelpers.LegacySpace); + await dbContext.Images.AddTestAsset(assetId, customer: LegacyModeHelpers.LegacyCustomer, space: LegacyModeHelpers.LegacySpace, family: AssetFamily.Image, origin: "https://images.org/image.tiff", mediaType: "image/tiff", imageOptimisationPolicy: string.Empty, thumbnailPolicy: string.Empty); await dbContext.SaveChangesAsync(); @@ -1497,7 +1440,7 @@ await dbContext.Images.AddTestAsset(assetId, customer: customer, space: space, // act var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + var response = await httpClient.AsCustomer(LegacyModeHelpers.LegacyCustomer).PutAsync(assetId.ToApiResourcePath(), content); // assert response.StatusCode.Should().Be(HttpStatusCode.OK); @@ -1520,14 +1463,7 @@ await dbContext.Images.AddTestAsset(assetId, customer: customer, space: space, [InlineData("https://api.dlc.services/imageOptimisationPolicies/video-max")] public async Task Put_NewVideoAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled(string imageOptimisationPolicy) { - const int customer = 325665; - const int space = 2; - var assetId = AssetIdGenerator.GetAssetId(customer, space); - await dbContext.Customers.AddTestCustomer(customer); - await dbContext.Spaces.AddTestSpace(customer, space); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); - await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); - await dbContext.SaveChangesAsync(); + var assetId = AssetIdGenerator.GetAssetId(LegacyModeHelpers.LegacyCustomer, LegacyModeHelpers.LegacySpace); var hydraImageBody = $@"{{ ""family"": ""T"", @@ -1543,7 +1479,7 @@ public async Task Put_NewVideoAsset_WithImageOptimisationPolicy_Creates_Asset_Wh // act var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + var response = await httpClient.AsCustomer(LegacyModeHelpers.LegacyCustomer).PutAsync(assetId.ToApiResourcePath(), content); // assert response.StatusCode.Should().Be(HttpStatusCode.Created); @@ -1563,14 +1499,7 @@ public async Task Put_NewVideoAsset_WithImageOptimisationPolicy_Creates_Asset_Wh [Fact] public async Task Put_NewVideoAsset_WithImageOptimisationPolicy_Returns400_IfInvalid_AndLegacyEnabled() { - const int customer = 325665; - const int space = 2; - var assetId = AssetIdGenerator.GetAssetId(customer, space); - await dbContext.Customers.AddTestCustomer(customer); - await dbContext.Spaces.AddTestSpace(customer, space); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); - await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); - await dbContext.SaveChangesAsync(); + var assetId = AssetIdGenerator.GetAssetId(LegacyModeHelpers.LegacyCustomer, LegacyModeHelpers.LegacySpace); var hydraImageBody = $@"{{ ""family"": ""T"", @@ -1580,7 +1509,7 @@ public async Task Put_NewVideoAsset_WithImageOptimisationPolicy_Returns400_IfInv // act var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + var response = await httpClient.AsCustomer(LegacyModeHelpers.LegacyCustomer).PutAsync(assetId.ToApiResourcePath(), content); // assert response.StatusCode.Should().Be(HttpStatusCode.BadRequest); @@ -1594,14 +1523,8 @@ public async Task Put_NewVideoAsset_WithImageOptimisationPolicy_Returns400_IfInv [InlineData("https://api.dlc.services/imageOptimisationPolicies/video-max")] public async Task Put_ExistingVideoAsset_WithImageOptimisationPolicy_AddsDeliveryChannelsToAsset_WhenLegacyEnabled(string imageOptimisationPolicy) { - const int customer = 325665; - const int space = 2; - var assetId = AssetIdGenerator.GetAssetId(customer, space); - await dbContext.Customers.AddTestCustomer(customer); - await dbContext.Spaces.AddTestSpace(customer, space); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); - await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); - await dbContext.Images.AddTestAsset(assetId, customer: customer, space: space, + var assetId = AssetIdGenerator.GetAssetId(LegacyModeHelpers.LegacyCustomer, LegacyModeHelpers.LegacySpace); + await dbContext.Images.AddTestAsset(assetId, customer: LegacyModeHelpers.LegacyCustomer, space: LegacyModeHelpers.LegacySpace, family: AssetFamily.Timebased, origin: "https://images.org/image.mp4", mediaType: "video/mp4", imageOptimisationPolicy: string.Empty, thumbnailPolicy: string.Empty); await dbContext.SaveChangesAsync(); @@ -1620,7 +1543,7 @@ await dbContext.Images.AddTestAsset(assetId, customer: customer, space: space, // act var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + var response = await httpClient.AsCustomer(LegacyModeHelpers.LegacyCustomer).PutAsync(assetId.ToApiResourcePath(), content); // assert response.StatusCode.Should().Be(HttpStatusCode.OK); @@ -1641,14 +1564,7 @@ await dbContext.Images.AddTestAsset(assetId, customer: customer, space: space, [InlineData("https://api.dlc.services/imageOptimisationPolicies/audio-max")] public async Task Put_NewAudioAsset_WithImageOptimisationPolicy_Creates_Asset_WhenLegacyEnabled(string imageOptimisationPolicy) { - const int customer = 325665; - const int space = 2; - var assetId = AssetIdGenerator.GetAssetId(customer, space); - await dbContext.Customers.AddTestCustomer(customer); - await dbContext.Spaces.AddTestSpace(customer, space); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); - await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); - await dbContext.SaveChangesAsync(); + var assetId = AssetIdGenerator.GetAssetId(LegacyModeHelpers.LegacyCustomer, LegacyModeHelpers.LegacySpace); var hydraImageBody = $@"{{ ""family"": ""T"", @@ -1664,7 +1580,7 @@ public async Task Put_NewAudioAsset_WithImageOptimisationPolicy_Creates_Asset_Wh // act var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + var response = await httpClient.AsCustomer(LegacyModeHelpers.LegacyCustomer).PutAsync(assetId.ToApiResourcePath(), content); // assert response.StatusCode.Should().Be(HttpStatusCode.Created); @@ -1684,14 +1600,7 @@ public async Task Put_NewAudioAsset_WithImageOptimisationPolicy_Creates_Asset_Wh [Fact] public async Task Put_NewAudioAsset_WithImageOptimisationPolicy_Returns400_IfInvalid_AndLegacyEnabled() { - const int customer = 325665; - const int space = 2; - var assetId = AssetIdGenerator.GetAssetId(customer, space); - await dbContext.Customers.AddTestCustomer(customer); - await dbContext.Spaces.AddTestSpace(customer, space); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); - await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); - await dbContext.SaveChangesAsync(); + var assetId = AssetIdGenerator.GetAssetId(LegacyModeHelpers.LegacyCustomer, LegacyModeHelpers.LegacySpace); var hydraImageBody = $@"{{ ""family"": ""T"", @@ -1701,7 +1610,7 @@ public async Task Put_NewAudioAsset_WithImageOptimisationPolicy_Returns400_IfInv // act var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + var response = await httpClient.AsCustomer(LegacyModeHelpers.LegacyCustomer).PutAsync(assetId.ToApiResourcePath(), content); // assert response.StatusCode.Should().Be(HttpStatusCode.BadRequest); @@ -1715,14 +1624,8 @@ public async Task Put_NewAudioAsset_WithImageOptimisationPolicy_Returns400_IfInv [InlineData("https://api.dlc.services/imageOptimisationPolicies/audio-max")] public async Task Put_ExistingAudioAsset_WithImageOptimisationPolicy_AddsDeliveryChannelsToAsset_WhenLegacyEnabled(string imageOptimisationPolicy) { - const int customer = 325665; - const int space = 2; - var assetId = AssetIdGenerator.GetAssetId(customer, space); - await dbContext.Customers.AddTestCustomer(customer); - await dbContext.Spaces.AddTestSpace(customer, space); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); - await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); - await dbContext.Images.AddTestAsset(assetId, customer: customer, space: space, + var assetId = AssetIdGenerator.GetAssetId(LegacyModeHelpers.LegacyCustomer, LegacyModeHelpers.LegacySpace); + await dbContext.Images.AddTestAsset(assetId, customer: LegacyModeHelpers.LegacyCustomer, space: LegacyModeHelpers.LegacySpace, family: AssetFamily.Timebased, origin: "https://images.org/image.mp3", mediaType: "audio/mp3", imageOptimisationPolicy: string.Empty, thumbnailPolicy: string.Empty); await dbContext.SaveChangesAsync(); @@ -1741,7 +1644,7 @@ await dbContext.Images.AddTestAsset(assetId, customer: customer, space: space, // act var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + var response = await httpClient.AsCustomer(LegacyModeHelpers.LegacyCustomer).PutAsync(assetId.ToApiResourcePath(), content); // assert response.StatusCode.Should().Be(HttpStatusCode.OK); @@ -1760,14 +1663,7 @@ await dbContext.Images.AddTestAsset(assetId, customer: customer, space: space, [Fact] public async Task Put_NewFileAsset_Creates_Asset_WhenLegacyEnabled() { - const int customer = 325665; - const int space = 2; - var assetId = AssetIdGenerator.GetAssetId(customer, space); - await dbContext.Customers.AddTestCustomer(customer); - await dbContext.Spaces.AddTestSpace(customer, space); - await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(customer); - await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(customer); - await dbContext.SaveChangesAsync(); + var assetId = AssetIdGenerator.GetAssetId(LegacyModeHelpers.LegacyCustomer, LegacyModeHelpers.LegacySpace); var hydraImageBody = $@"{{ ""@type"": ""Image"", @@ -1783,7 +1679,7 @@ public async Task Put_NewFileAsset_Creates_Asset_WhenLegacyEnabled() // act var content = new StringContent(hydraImageBody, Encoding.UTF8, "application/json"); - var response = await httpClient.AsCustomer(customer).PutAsync(assetId.ToApiResourcePath(), content); + var response = await httpClient.AsCustomer(LegacyModeHelpers.LegacyCustomer).PutAsync(assetId.ToApiResourcePath(), content); // assert response.StatusCode.Should().Be(HttpStatusCode.Created); diff --git a/src/protagonist/API.Tests/LegacyModeHelpers.cs b/src/protagonist/API.Tests/LegacyModeHelpers.cs new file mode 100644 index 000000000..ff0e6b5f6 --- /dev/null +++ b/src/protagonist/API.Tests/LegacyModeHelpers.cs @@ -0,0 +1,26 @@ +using DLCS.Repository; +using Test.Helpers.Integration; + +namespace API.Tests; + +/// +/// Helper methods and constants for working with LegacyMode. LegacyCustomer + Space are configured as such via +/// appsettings.Testing.json +/// +public class LegacyModeHelpers +{ + public const int LegacyCustomer = 325665; + public const int LegacySpace = 201; + public const int NonLegacySpace = 4; + + public static async Task SetupLegacyCustomer(DlcsContext dbContext, int space = LegacySpace) + { + await dbContext.Customers.AddTestCustomer(LegacyCustomer); + await dbContext.Spaces.AddTestSpace(LegacyCustomer, space); + await dbContext.Spaces.AddTestSpace(LegacyCustomer, NonLegacySpace); + await dbContext.CustomerStorages.AddTestCustomerStorage(LegacyCustomer); + await dbContext.DefaultDeliveryChannels.AddTestDefaultDeliveryChannels(LegacyCustomer); + await dbContext.DeliveryChannelPolicies.AddTestDeliveryChannelPolicies(LegacyCustomer); + await dbContext.SaveChangesAsync(); + } +} \ No newline at end of file diff --git a/src/protagonist/API.Tests/appsettings.Testing.json b/src/protagonist/API.Tests/appsettings.Testing.json index b0ed2586b..8c359a931 100644 --- a/src/protagonist/API.Tests/appsettings.Testing.json +++ b/src/protagonist/API.Tests/appsettings.Testing.json @@ -22,13 +22,9 @@ "PageSize": 100, "ApiSalt": "this-is-a-salt", "CustomerOverrides": { - "15": { - "LegacySupport": true, - "NovelSpaces": ["1","4"] - }, "325665": { "LegacySupport": true, - "NovelSpaces": ["1","4"] + "NovelSpaces": ["4"] } }, "RestrictedAssetIdCharacterString": "\\ " From 9e07cd0d996d4598572b878fb5b886de06e37aab Mon Sep 17 00:00:00 2001 From: Donald Gray Date: Wed, 12 Jun 2024 14:05:21 +0100 Subject: [PATCH 30/30] Reword error message in test This will enable us to merge develop into main, where error message has been renamed --- src/protagonist/API.Tests/Integration/ModifyAssetTests.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs b/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs index 827b49472..3f095041f 100644 --- a/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs +++ b/src/protagonist/API.Tests/Integration/ModifyAssetTests.cs @@ -1045,7 +1045,7 @@ public async Task Put_Existing_Asset_ClearsError_AndMarksAsIngesting() [Fact] public async Task Put_Existing_Asset_Returns400_IfDeliveryChannelsNull() { - var assetId = new AssetId(99, 1, nameof(Put_Existing_Asset_Returns400_IfDeliveryChannelsNull)); + var assetId = AssetIdGenerator.GetAssetId(); await dbContext.Images.AddTestAsset(assetId); await dbContext.SaveChangesAsync(); @@ -1063,13 +1063,13 @@ public async Task Put_Existing_Asset_Returns400_IfDeliveryChannelsNull() // assert response.StatusCode.Should().Be(HttpStatusCode.BadRequest); var body = await response.Content.ReadAsStringAsync(); - body.Should().Contain("Delivery channels are required when updating an existing Asset via PUT"); + body.Should().Contain("Delivery channels are required when updating an existing Asset"); } [Fact] public async Task Put_Existing_Asset_Returns400_IfDeliveryChannelsEmpty() { - var assetId = new AssetId(99, 1, nameof(Put_Existing_Asset_Returns400_IfDeliveryChannelsEmpty)); + var assetId = AssetIdGenerator.GetAssetId(); await dbContext.Images.AddTestAsset(assetId); await dbContext.SaveChangesAsync(); @@ -1088,7 +1088,7 @@ public async Task Put_Existing_Asset_Returns400_IfDeliveryChannelsEmpty() // assert response.StatusCode.Should().Be(HttpStatusCode.BadRequest); var body = await response.Content.ReadAsStringAsync(); - body.Should().Contain("Delivery channels are required when updating an existing Asset via PUT"); + body.Should().Contain("Delivery channels are required when updating an existing Asset"); } [Fact]