diff --git a/DLCS.Repository.Tests/Assets/ThumbReorganiserTests.cs b/DLCS.Repository.Tests/Assets/ThumbReorganiserTests.cs index f9f3902a3..6fee8683e 100644 --- a/DLCS.Repository.Tests/Assets/ThumbReorganiserTests.cs +++ b/DLCS.Repository.Tests/Assets/ThumbReorganiserTests.cs @@ -204,6 +204,64 @@ public async Task EnsureNewLayout_CreatesExpectedResources_MixedAuthAndOpen() "application/json")) .MustHaveHappened(); } + + [Fact] + public async Task EnsureNewLayout_CreatesExpectedResources_MixedAuthAndOpen_ImageSmallerThanThumbnail() + { + var rootKey = new ObjectInBucket {Bucket = "the-bucket", Key = "2/1/the-astronaut/"}; + A.CallTo(() => bucketReader.GetMatchingKeys(rootKey)) + .Returns(new[] + { + "2/1/the-astronaut/full/200,/0/default.jpg", + "2/1/the-astronaut/full/200,400/0/default.jpg", + "2/1/the-astronaut/full/100,/0/default.jpg", + "2/1/the-astronaut/full/100,200/0/default.jpg", + "2/1/the-astronaut/full/50,/0/default.jpg", + "2/1/the-astronaut/full/50,100/0/default.jpg" + }); + + A.CallTo(() => assetRepository.GetAsset(A._)) + .Returns(new Asset {Width = 300, Height = 600, ThumbnailPolicy = "TheBestOne", MaxUnauthorised = 350, Roles = "admin"}); + A.CallTo(() => thumbPolicyRepository.GetThumbnailPolicy("TheBestOne")) + .Returns(new ThumbnailPolicy {Sizes = "1024,400,200,100"}); + + // Act + var response = await sut.EnsureNewLayout(rootKey); + + // Assert + response.Should().Be(ReorganiseResult.Reorganised); + + // move jpg per thumbnail size + A.CallTo(() => + bucketReader.CopyWithinBucket("the-bucket", + "2/1/the-astronaut/low.jpg", + "2/1/the-astronaut/auth/600.jpg")) + .MustHaveHappened(); + A.CallTo(() => + bucketReader.CopyWithinBucket("the-bucket", + "2/1/the-astronaut/full/200,400/0/default.jpg", + "2/1/the-astronaut/auth/400.jpg")) + .MustHaveHappened(); + A.CallTo(() => + bucketReader.CopyWithinBucket("the-bucket", + "2/1/the-astronaut/full/100,200/0/default.jpg", + "2/1/the-astronaut/open/200.jpg")) + .MustHaveHappened(); + A.CallTo(() => + bucketReader.CopyWithinBucket("the-bucket", + "2/1/the-astronaut/full/50,100/0/default.jpg", + "2/1/the-astronaut/open/100.jpg")) + .MustHaveHappened(); + + // create sizes.json + const string expected = "{\"o\":[[100,200],[50,100]],\"a\":[[300,600],[200,400]]}"; + A.CallTo(() => + bucketReader.WriteToBucket( + A.That.Matches(o => + o.Bucket == "the-bucket" && o.Key == "2/1/the-astronaut/s.json"), expected, + "application/json")) + .MustHaveHappened(); + } [Fact] public async Task EnsureNewLayout_CreatesExpectedResources_HandlingRoundingDifference_Portrait() diff --git a/DLCS.Repository/Assets/ThumbReorganiser.cs b/DLCS.Repository/Assets/ThumbReorganiser.cs index c0ac4af3e..7f41b8c2c 100644 --- a/DLCS.Repository/Assets/ThumbReorganiser.cs +++ b/DLCS.Repository/Assets/ThumbReorganiser.cs @@ -90,7 +90,7 @@ public async Task EnsureNewLayout(ObjectInBucket rootKey) } // All the thumbnail jpgs will already exist and need copied up to root - await CreateThumbnails(rootKey, boundingSquares, thumbnailSizes, existingSizes); + await CreateThumbnails(rootKey, thumbnailSizes, existingSizes); // Create sizes json file last, as this dictates whether this process will be attempted again await CreateSizesJson(rootKey, thumbnailSizes); @@ -125,32 +125,34 @@ private static List GetExistingSizesList(ThumbnailSizes thumbnailSizes, st return existingSizes; } - private async Task CreateThumbnails(ObjectInBucket rootKey, List boundingSquares, - ThumbnailSizes thumbnailSizes, List existingSizes) + private async Task CreateThumbnails(ObjectInBucket rootKey, ThumbnailSizes thumbnailSizes, + List existingSizes) { var copyTasks = new List(thumbnailSizes.Count); - // low.jpg becomes the first in this list - var largestSize = boundingSquares[0]; + var openSizes = thumbnailSizes.Open.Select(wh => Size.FromArray(wh)).ToList(); + var authSizes = thumbnailSizes.Auth.Select(wh => Size.FromArray(wh)).ToList(); + var largestSize = openSizes.Concat(authSizes).Max(sz => sz.MaxDimension); + + // low.jpg becomes the largest sized thumb var largestSlug = thumbnailSizes.Auth.IsNullOrEmpty() ? thumbConsts.OpenSlug : thumbConsts.AuthorisedSlug; copyTasks.Add(bucketReader.CopyWithinBucket(rootKey.Bucket, $"{rootKey.Key}low.jpg", $"{rootKey.Key}{largestSlug}/{largestSize}.jpg")); - copyTasks.AddRange(ProcessThumbBatch(rootKey, thumbnailSizes.Auth, thumbConsts.AuthorisedSlug, largestSize, + copyTasks.AddRange(ProcessThumbBatch(rootKey, authSizes, thumbConsts.AuthorisedSlug, largestSize, existingSizes)); - copyTasks.AddRange(ProcessThumbBatch(rootKey, thumbnailSizes.Open, thumbConsts.OpenSlug, largestSize, + copyTasks.AddRange(ProcessThumbBatch(rootKey, openSizes, thumbConsts.OpenSlug, largestSize, existingSizes)); await Task.WhenAll(copyTasks); } - private IEnumerable ProcessThumbBatch(ObjectInBucket rootKey, IEnumerable thumbnailSizes, - string slug, int largestSize, List existingSizes) + private IEnumerable ProcessThumbBatch(ObjectInBucket rootKey, IEnumerable thumbnailSizes, + string slug, int largestSize, IReadOnlyCollection existingSizes) { - foreach (var wh in thumbnailSizes) + foreach (var currentSize in thumbnailSizes) { - var currentSize = Size.FromArray(wh); var maxDimension = currentSize.MaxDimension; if (maxDimension == largestSize) continue;