From 7ba7c906b40d86445a89a6e888f49e3d6558ed62 Mon Sep 17 00:00:00 2001 From: Donald Gray Date: Thu, 12 May 2022 11:46:21 +0100 Subject: [PATCH] Allow canvas to have items that target itself --- .../IIIF.Tests/Presentation/V3/CanvasTests.cs | 72 ++++++++++++++++++- .../IIIF/Serialisation/IIIFSerialiserX.cs | 1 + 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/src/IIIF/IIIF.Tests/Presentation/V3/CanvasTests.cs b/src/IIIF/IIIF.Tests/Presentation/V3/CanvasTests.cs index 1d47c57..2b7e4e9 100644 --- a/src/IIIF/IIIF.Tests/Presentation/V3/CanvasTests.cs +++ b/src/IIIF/IIIF.Tests/Presentation/V3/CanvasTests.cs @@ -2,6 +2,7 @@ using FluentAssertions; using IIIF.Presentation.V3; using IIIF.Presentation.V3.Annotation; +using IIIF.Presentation.V3.Content; using IIIF.Presentation.V3.Strings; using IIIF.Serialisation; using Xunit; @@ -85,7 +86,7 @@ public void SerialiseTargetAsId_True_RendersIdAsTarget() [Fact] public void SerialiseTargetAsId_False_RendersFullCanvasAsTarget() { - var targetIsIdOnlyCanvas = new Canvas + var targetIsFullCanvas = new Canvas { Id = "https://test.example.com/canvas/full", Width = 1000, @@ -102,7 +103,7 @@ public void SerialiseTargetAsId_False_RendersFullCanvasAsTarget() Id = "https://test.example.com/canvas/referencing/page", Items = new List { - new PaintingAnnotation { Target = targetIsIdOnlyCanvas, } + new PaintingAnnotation { Target = targetIsFullCanvas, } } } } @@ -113,7 +114,7 @@ public void SerialiseTargetAsId_False_RendersFullCanvasAsTarget() Context = "http://iiif.io/api/presentation/3/context.json", Id = "https://test.example.com/manifest", Label = new LanguageMap("en", "Test string"), - Items = new List { targetIsIdOnlyCanvas, referencingCanvas } + Items = new List { targetIsFullCanvas, referencingCanvas } }; var serialisedManifest = manifest.AsJson().Replace("\r\n", "\n"); @@ -157,5 +158,70 @@ public void SerialiseTargetAsId_False_RendersFullCanvasAsTarget() serialisedManifest.Should().BeEquivalentTo(expected); } + + [Fact] + public void CanSelfReferenceCanvas() + { + var canvas = new Canvas + { + Id = "https://test.example.com/canvas/target-id-only", + SerialiseTargetAsId = true + }; + + canvas.Items = new List + { + new() + { + Id = "https://test.example.com/canvas/referencing/page", + Items = new List + { + new PaintingAnnotation + { + Id = "https://test.example.com/canvas/referencing/page/anno", + Target = canvas, + } + } + } + }; + + var manifest = new Manifest + { + Context = "http://iiif.io/api/presentation/3/context.json", + Id = "https://test.example.com/manifest", + Label = new LanguageMap("en", "Test string"), + Items = new List { canvas } + }; + + var serialisedManifest = manifest.AsJson().Replace("\r\n", "\n"); + + const string expected = @"{ + ""@context"": ""http://iiif.io/api/presentation/3/context.json"", + ""id"": ""https://test.example.com/manifest"", + ""type"": ""Manifest"", + ""label"": {""en"":[""Test string""]}, + ""items"": [ + { + ""id"": ""https://test.example.com/canvas/target-id-only"", + ""type"": ""Canvas"", + ""items"": [ + { + ""id"": ""https://test.example.com/canvas/referencing/page"", + ""type"": ""AnnotationPage"", + ""items"": [ + { + ""id"": ""https://test.example.com/canvas/referencing/page/anno"", + ""type"": ""Annotation"", + ""motivation"": ""painting"", + ""target"": ""https://test.example.com/canvas/target-id-only"" + } + ] + } + ] + } + ] +}"; + + serialisedManifest.Should().BeEquivalentTo(expected); + } } } \ No newline at end of file diff --git a/src/IIIF/IIIF/Serialisation/IIIFSerialiserX.cs b/src/IIIF/IIIF/Serialisation/IIIFSerialiserX.cs index 54e5eb2..305be23 100644 --- a/src/IIIF/IIIF/Serialisation/IIIFSerialiserX.cs +++ b/src/IIIF/IIIF/Serialisation/IIIFSerialiserX.cs @@ -14,6 +14,7 @@ public static class IIIFSerialiserX NullValueHandling = NullValueHandling.Ignore, ContractResolver = new PrettyIIIFContractResolver(), Formatting = Formatting.Indented, + ReferenceLoopHandling = ReferenceLoopHandling.Serialize, Converters = new List { new SizeConverter(), new StringArrayConverter(), new ServiceReferenceConverter(),