Skip to content

Commit

Permalink
Add link resolution for (new) RecursiveNode, e.g. for RichTextDo… (#276)
Browse files Browse the repository at this point in the history
Add link resolution for (new) RecursiveNode, e.g. for RichTextDocument
  • Loading branch information
Khaledgarbaya committed Jul 16, 2019
2 parents efa32f4 + 731e74e commit 8276d17
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 3 deletions.
2 changes: 2 additions & 0 deletions Sources/Contentful/Entry.swift
Expand Up @@ -90,6 +90,8 @@ public class Entry: LocalizableResource {
}
}
resolvedLocalizableFieldMap[localeCode] = resolvedLinks
case let recursiveNode as RecursiveNode:
recursiveNode.resolveLinks(against: includedEntries, and: includedAssets)
default:
continue
}
Expand Down
81 changes: 78 additions & 3 deletions Sources/Contentful/RichText.swift
Expand Up @@ -15,6 +15,25 @@ public protocol Node: Decodable {
var nodeType: NodeType { get }
}

public protocol RecursiveNode: Node {
var content: [Node] { get }
func resolveLinks(against includedEntries: [Entry]?, and includedAssets: [Asset]?)
}

private extension RecursiveNode {

func resolveLinksInChildNodes(against includedEntries: [Entry]?, and includedAssets: [Asset]?) {
self.content.forEach { node in
switch node {
case let recursiveNode as RecursiveNode:
recursiveNode.resolveLinks(against: includedEntries, and: includedAssets)
default:
break
}
}
}
}

/// The data describing the linked entry or asset for an `EmbeddedResouceNode`
public class ResourceLinkData: Decodable {

Expand Down Expand Up @@ -124,7 +143,7 @@ public enum NodeType: String, Decodable {
}

/// BlockNode is the base class for all nodes which are rendered as a block (as opposed to an inline node).
public class BlockNode: Node {
public class BlockNode: RecursiveNode {
public let nodeType: NodeType
public internal(set) var content: [Node]

Expand All @@ -137,10 +156,14 @@ public class BlockNode: Node {
self.nodeType = nodeType
self.content = content
}

public func resolveLinks(against includedEntries: [Entry]?, and includedAssets: [Asset]?) {
resolveLinksInChildNodes(against: includedEntries, and: includedAssets)
}
}

/// InlineNode is the base class for all nodes which are rendered as an inline string (as opposed to a block node).
public class InlineNode: Node {
public class InlineNode: RecursiveNode {
public let nodeType: NodeType
public internal(set) var content: [Node]

Expand All @@ -153,10 +176,14 @@ public class InlineNode: Node {
self.nodeType = nodeType
self.content = content
}

public func resolveLinks(against includedEntries: [Entry]?, and includedAssets: [Asset]?) {
resolveLinksInChildNodes(against: includedEntries, and: includedAssets)
}
}

/// The top level node which contains all other nodes.
public class RichTextDocument: Node {
public class RichTextDocument: RecursiveNode {
public let nodeType: NodeType
public internal(set) var content: [Node]

Expand All @@ -170,6 +197,10 @@ public class RichTextDocument: Node {
nodeType = try container.decode(NodeType.self, forKey: .nodeType)
content = try container.decodeContent(forKey: .content)
}

public func resolveLinks(against includedEntries: [Entry]?, and includedAssets: [Asset]?) {
resolveLinksInChildNodes(against: includedEntries, and: includedAssets)
}
}

/// A block of text, containing child `Text` nodes.
Expand Down Expand Up @@ -245,6 +276,28 @@ public class ResourceLinkBlock: BlockNode {
data = try container.decode(ResourceLinkData.self, forKey: .data)
try super.init(from: decoder)
}

public override func resolveLinks(against includedEntries: [Entry]?, and includedAssets: [Asset]?) {
switch data.target {
case .asset, .entry, .entryDecodable:
return
case let .unresolved(sys):
switch sys.linkType.lowercased() {
case "entry":
guard let linkedEntry = includedEntries?.first(where: { $0.sys.id == sys.id }) else {
return
}
data.target = Link.entry(linkedEntry)
case "asset":
guard let linkedAsset = includedAssets?.first(where: { $0.sys.id == sys.id }) else {
return
}
data.target = Link.asset(linkedAsset)
default:
return
}
}
}
}

/// A inline containing data for a linked entry or asset.
Expand All @@ -263,6 +316,28 @@ public class ResourceLinkInline: InlineNode {
data = try container.decode(ResourceLinkData.self, forKey: .data)
try super.init(from: decoder)
}

public override func resolveLinks(against includedEntries: [Entry]?, and includedAssets: [Asset]?) {
switch data.target {
case .asset, .entry, .entryDecodable:
return
case let .unresolved(sys):
switch sys.linkType.lowercased() {
case "entry":
guard let linkedEntry = includedEntries?.first(where: { $0.sys.id == sys.id }) else {
return
}
data.target = Link.entry(linkedEntry)
case "asset":
guard let linkedAsset = includedAssets?.first(where: { $0.sys.id == sys.id }) else {
return
}
data.target = Link.asset(linkedAsset)
default:
return
}
}
}
}

/// A node containing text with marks.
Expand Down
42 changes: 42 additions & 0 deletions Tests/ContentfulTests/DVRRecordings/RichTextNodeDecodingTests.json
Expand Up @@ -336,6 +336,48 @@
},
"recorded_at" : 1541494467.6026201
},
{
"request" : {
"method" : "GET",
"headers" : {
"X-Contentful-User-Agent" : "sdk contentful.swift\/4.0.1; platform Swift\/4.0; os iOS\/12.1.0;",
"Authorization" : "Bearer 1859a86ac82f679e8436af5ed5202bdb45f96b1deed3b5d1e20275698b5184c9"
},
"url" : "https:\/\/cdn.contentful.com\/spaces\/pzlh94jb0ghw\/environments\/master\/entries?fields.name=nested_included_entries"
},
"response" : {
"headers" : {
"Content-Encoding" : "gzip",
"Age" : "62",
"access-control-max-age" : "86400",
"x-timer" : "S1541494468.594509,VS0,VE0",
"access-control-expose-headers" : "Etag",
"x-cache" : "HIT",
"x-contentful-region" : "us-east-1",
"contentful-api" : "cda_cached",
"Date" : "Tue, 06 Nov 2018 08:54:27 GMT",
"access-control-allow-methods" : "GET,HEAD,OPTIONS",
"Server" : "Contentful",
"Vary" : "Accept-Encoding",
"Cache-Control" : "max-age=0",
"x-served-by" : "cache-bma1641-BMA",
"Accept-Ranges" : "bytes",
"Content-Length" : "1460",
"Access-Control-Allow-Origin" : "*",
"Content-Type" : "application\/vnd.contentful.delivery.v1+json",
"Via" : "1.1 varnish",
"access-control-allow-headers" : "Accept,Accept-Language,Authorization,Cache-Control,Content-Length,Content-Range,Content-Type,DNT,Destination,Expires,If-Match,If-Modified-Since,If-None-Match,Keep-Alive,Last-Modified,Origin,Pragma,Range,User-Agent,X-Http-Method-Override,X-Mx-ReqToken,X-Requested-With,X-Contentful-Version,X-Contentful-Content-Type,X-Contentful-Organization,X-Contentful-Skip-Transformation,X-Contentful-User-Agent,X-Contentful-Enable-Alpha-Feature",
"Etag" : "W\/\"18fa4c989a708dacb0192e5ec0f0b9ad\"",
"x-content-type-options" : "nosniff",
"x-contentful-request-id" : "231920a6600fd0de2a9dc73f2deea6d0",
"x-cache-hits" : "1"
},
"url" : "https:\/\/cdn.contentful.com\/spaces\/pzlh94jb0ghw\/environments\/master\/entries?fields.name=nested_included_entries",
"status" : 200,
"body" : "ewogICJzeXMiOiB7CiAgICAidHlwZSI6ICJBcnJheSIKICB9LAogICJ0b3RhbCI6IDEsCiAgInNraXAiOiAwLAogICJsaW1pdCI6IDEwMCwKICAiaXRlbXMiOiBbCiAgICB7CiAgICAgICJzeXMiOiB7CiAgICAgICAgInNwYWNlIjogewogICAgICAgICAgInN5cyI6IHsKICAgICAgICAgICAgInR5cGUiOiAiTGluayIsCiAgICAgICAgICAgICJsaW5rVHlwZSI6ICJTcGFjZSIsCiAgICAgICAgICAgICJpZCI6ICJwemxoOTRqYjBnaHciCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiaWQiOiAiM1JrUGhKaHFsMm13Q2tjeXVZMmFNcSIsCiAgICAgICAgInR5cGUiOiAiRW50cnkiLAogICAgICAgICJjcmVhdGVkQXQiOiAiMjAxOC0xMS0wMVQxMjoyODoxOS45NzJaIiwKICAgICAgICAidXBkYXRlZEF0IjogIjIwMTgtMTEtMDFUMTI6Mjg6MTkuOTcyWiIsCiAgICAgICAgImVudmlyb25tZW50IjogewogICAgICAgICAgInN5cyI6IHsKICAgICAgICAgICAgImlkIjogIm1hc3RlciIsCiAgICAgICAgICAgICJ0eXBlIjogIkxpbmsiLAogICAgICAgICAgICAibGlua1R5cGUiOiAiRW52aXJvbm1lbnQiCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAicmV2aXNpb24iOiAxLAogICAgICAgICJjb250ZW50VHlwZSI6IHsKICAgICAgICAgICJzeXMiOiB7CiAgICAgICAgICAgICJ0eXBlIjogIkxpbmsiLAogICAgICAgICAgICAibGlua1R5cGUiOiAiQ29udGVudFR5cGUiLAogICAgICAgICAgICAiaWQiOiAicmljaCIKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJsb2NhbGUiOiAiZW4tVVMiCiAgICAgIH0sCiAgICAgICJmaWVsZHMiOiB7CiAgICAgICAgIm5hbWUiOiAiaW5saW5lX2h5cGVybGlua19pbnRlZ3JhdGlvbiIsCiAgICAgICAgInJpY2giOiB7CiAgICAgICAgICAiZGF0YSI6IHt9LAogICAgICAgICAgImNvbnRlbnQiOiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAiZGF0YSI6IHt9LAogICAgICAgICAgICAgICJjb250ZW50IjogWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAiZGF0YSI6IHt9LAogICAgICAgICAgICAgICAgICAibWFya3MiOiBbXSwKICAgICAgICAgICAgICAgICAgInZhbHVlIjogIkFuIGVudHJ5IHdpdGggYW4gZW1iZWRkZWQgZW50cnkgdGhhdCBpdHNlbGYgaGFzIGFuIGVtYmVkZGVkIGVudHJ5OiIsCiAgICAgICAgICAgICAgICAgICJub2RlVHlwZSI6ICJ0ZXh0IgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgImRhdGEiOiB7CiAgICAgICAgICAgICAgICAgICAgInRhcmdldCI6IHsKICAgICAgICAgICAgICAgICAgICAgICJzeXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJpZCI6ICI0dmcxY1JGSHRLYUFnV1lhQUVVdTZLIiwKICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAiTGluayIsCiAgICAgICAgICAgICAgICAgICAgICAgICJsaW5rVHlwZSI6ICJFbnRyeSIKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICJjb250ZW50IjogW10sCiAgICAgICAgICAgICAgICAgICJub2RlVHlwZSI6ICJlbWJlZGRlZC1lbnRyeS1ibG9jayIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICJub2RlVHlwZSI6ICJwYXJhZ3JhcGgiCiAgICAgICAgICAgIH0KICAgICAgICAgIF0sCiAgICAgICAgICAibm9kZVR5cGUiOiAiZG9jdW1lbnQiCiAgICAgICAgfQogICAgICB9CiAgICB9CiAgXSwKICAiaW5jbHVkZXMiOiB7CiAgICAiRW50cnkiOiBbCiAgICAgIHsKICAgICAgICAic3lzIjogewogICAgICAgICAgInNwYWNlIjogewogICAgICAgICAgICAic3lzIjogewogICAgICAgICAgICAgICJ0eXBlIjogIkxpbmsiLAogICAgICAgICAgICAgICJsaW5rVHlwZSI6ICJTcGFjZSIsCiAgICAgICAgICAgICAgImlkIjogInB6bGg5NGpiMGdodyIKICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgICJpZCI6ICI0dmcxY1JGSHRLYUFnV1lhQUVVdTZLIiwKICAgICAgICAgICJ0eXBlIjogIkVudHJ5IiwKICAgICAgICAgICJjcmVhdGVkQXQiOiAiMjAxOC0xMC0xN1QxMzozMjozMC4yNTJaIiwKICAgICAgICAgICJ1cGRhdGVkQXQiOiAiMjAxOC0xMC0zMVQxMTowNDozMi40MzhaIiwKICAgICAgICAgICJlbnZpcm9ubWVudCI6IHsKICAgICAgICAgICAgInN5cyI6IHsKICAgICAgICAgICAgICAiaWQiOiAibWFzdGVyIiwKICAgICAgICAgICAgICAidHlwZSI6ICJMaW5rIiwKICAgICAgICAgICAgICAibGlua1R5cGUiOiAiRW52aXJvbm1lbnQiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICAicmV2aXNpb24iOiAyLAogICAgICAgICAgImNvbnRlbnRUeXBlIjogewogICAgICAgICAgICAic3lzIjogewogICAgICAgICAgICAgICJ0eXBlIjogIkxpbmsiLAogICAgICAgICAgICAgICJsaW5rVHlwZSI6ICJDb250ZW50VHlwZSIsCiAgICAgICAgICAgICAgImlkIjogInJpY2giCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICAibG9jYWxlIjogImVuLVVTIgogICAgICAgIH0sCiAgICAgICAgImZpZWxkcyI6IHsKICAgICAgICAgICJuYW1lIjogInNpbXBsZV9oZWFkbGluZV8xIiwKICAgICAgICAgICJsaW5rZWRFbnRyeSI6IHsKICAgICAgICAgICAgInN5cyI6IHsKICAgICAgICAgICAgICAidHlwZSI6ICJMaW5rIiwKICAgICAgICAgICAgICAibGlua1R5cGUiOiAiRW50cnkiLAogICAgICAgICAgICAgICJpZCI6ICJCdkJtMlNOVEVzNDB3VXd5b0kwUW8iCiAgICAgICAgICAgIH0KICAgICAgICAgIH0sCiAgICAgICAgICAicmljaCI6IHsKICAgICAgICAgICAgImRhdGEiOiB7fSwKICAgICAgICAgICAgImNvbnRlbnQiOiBbCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImRhdGEiOiB7fSwKICAgICAgICAgICAgICAgICJjb250ZW50IjogWwogICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgImRhdGEiOiB7fSwKICAgICAgICAgICAgICAgICAgICAibWFya3MiOiBbXSwKICAgICAgICAgICAgICAgICAgICAidmFsdWUiOiAiVGhpcyBpcyBzb21lIHNpbXBsZSB0ZXh0IiwKICAgICAgICAgICAgICAgICAgICAibm9kZVR5cGUiOiAidGV4dCIKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgICAgICJub2RlVHlwZSI6ICJoZWFkaW5nLTEiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAiZGF0YSI6IHt9LAogICAgICAgICAgICAgICAgImNvbnRlbnQiOiBbCiAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAiZGF0YSI6IHt9LAogICAgICAgICAgICAgICAgICAgICJtYXJrcyI6IFtdLAogICAgICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICIiLAogICAgICAgICAgICAgICAgICAgICJub2RlVHlwZSI6ICJ0ZXh0IgogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICAgIm5vZGVUeXBlIjogInBhcmFncmFwaCIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJub2RlVHlwZSI6ICJkb2N1bWVudCIKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0sCiAgICAgIHsKICAgICAgICAic3lzIjogewogICAgICAgICAgInNwYWNlIjogewogICAgICAgICAgICAic3lzIjogewogICAgICAgICAgICAgICJ0eXBlIjogIkxpbmsiLAogICAgICAgICAgICAgICJsaW5rVHlwZSI6ICJTcGFjZSIsCiAgICAgICAgICAgICAgImlkIjogInB6bGg5NGpiMGdodyIKICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgICJpZCI6ICJCdkJtMlNOVEVzNDB3VXd5b0kwUW8iLAogICAgICAgICAgInR5cGUiOiAiRW50cnkiLAogICAgICAgICAgImNyZWF0ZWRBdCI6ICIyMDE4LTEwLTE3VDEzOjI1OjU3LjkyNloiLAogICAgICAgICAgInVwZGF0ZWRBdCI6ICIyMDE4LTEwLTE3VDEzOjU3OjU0LjIxNFoiLAogICAgICAgICAgImVudmlyb25tZW50IjogewogICAgICAgICAgICAic3lzIjogewogICAgICAgICAgICAgICJpZCI6ICJtYXN0ZXIiLAogICAgICAgICAgICAgICJ0eXBlIjogIkxpbmsiLAogICAgICAgICAgICAgICJsaW5rVHlwZSI6ICJFbnZpcm9ubWVudCIKICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgICJyZXZpc2lvbiI6IDMsCiAgICAgICAgICAiY29udGVudFR5cGUiOiB7CiAgICAgICAgICAgICJzeXMiOiB7CiAgICAgICAgICAgICAgInR5cGUiOiAiTGluayIsCiAgICAgICAgICAgICAgImxpbmtUeXBlIjogIkNvbnRlbnRUeXBlIiwKICAgICAgICAgICAgICAiaWQiOiAicmljaCIKICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgICJsb2NhbGUiOiAiZW4tVVMiCiAgICAgICAgfSwKICAgICAgICAiZmllbGRzIjogewogICAgICAgICAgIm5hbWUiOiAiSGVsbG8gV29ybGQiLAogICAgICAgICAgInJpY2giOiB7CiAgICAgICAgICAgICJkYXRhIjoge30sCiAgICAgICAgICAgICJjb250ZW50IjogWwogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJkYXRhIjoge30sCiAgICAgICAgICAgICAgICAiY29udGVudCI6IFsKICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICJkYXRhIjoge30sCiAgICAgICAgICAgICAgICAgICAgIm1hcmtzIjogWwogICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJib2xkIgogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgICAgICAgInZhbHVlIjogIkhlbGxvIiwKICAgICAgICAgICAgICAgICAgICAibm9kZVR5cGUiOiAidGV4dCIKICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICJkYXRhIjoge30sCiAgICAgICAgICAgICAgICAgICAgIm1hcmtzIjogW10sCiAgICAgICAgICAgICAgICAgICAgInZhbHVlIjogIiAiLAogICAgICAgICAgICAgICAgICAgICJub2RlVHlwZSI6ICJ0ZXh0IgogICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgImRhdGEiOiB7fSwKICAgICAgICAgICAgICAgICAgICAibWFya3MiOiBbCiAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogIml0YWxpYyIKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICAgICAgICJ2YWx1ZSI6ICJXb3JsZCIsCiAgICAgICAgICAgICAgICAgICAgIm5vZGVUeXBlIjogInRleHQiCiAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAiZGF0YSI6IHt9LAogICAgICAgICAgICAgICAgICAgICJtYXJrcyI6IFsKICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgInR5cGUiOiAidW5kZXJsaW5lIgogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgICAgICAgInZhbHVlIjogIiEiLAogICAgICAgICAgICAgICAgICAgICJub2RlVHlwZSI6ICJ0ZXh0IgogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICAgIm5vZGVUeXBlIjogInBhcmFncmFwaCIKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJub2RlVHlwZSI6ICJkb2N1bWVudCIKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIF0KICB9Cn0="
},
"recorded_at" : 1541494467.6026201
},
{
"request" : {
"method" : "GET",
Expand Down
28 changes: 28 additions & 0 deletions Tests/ContentfulTests/RichTextTests.swift
Expand Up @@ -42,6 +42,11 @@ class RichTextNodeDecodingTests: XCTestCase {
spaceId: "pzlh94jb0ghw",
accessToken: "1859a86ac82f679e8436af5ed5202bdb45f96b1deed3b5d1e20275698b5184c9",
contentTypeClasses: [RichTextContentType.self])
static let clientWithoutContentTypeClasses = TestClientFactory.testClient(
withCassetteNamed: "RichTextNodeDecodingTests",
spaceId: "pzlh94jb0ghw",
accessToken: "1859a86ac82f679e8436af5ed5202bdb45f96b1deed3b5d1e20275698b5184c9"
)

override class func setUp() {
super.setUp()
Expand Down Expand Up @@ -437,4 +442,27 @@ class RichTextNodeDecodingTests: XCTestCase {
waitForExpectations(timeout: 10_000.0, handler: nil)
}

func testDecodingNestedEntriesInlinedInRichTextWithoutContentTypeClasses() {
let expectation = self.expectation(description: "")

RichTextNodeDecodingTests.clientWithoutContentTypeClasses.fetchArray(
of: Entry.self,
matching: .where(field: "name", .equals("nested_included_entries"))) { result in
switch result {
case .success(let arrayResponse):
let rootRichTextContentType = arrayResponse.items.first
let paragraph = (rootRichTextContentType?.fields["rich"] as! RichTextDocument).content.first as? Paragraph
let link = paragraph?.content[1] as? ResourceLinkBlock
let inlinedEntry = link?.data.target.entry

XCTAssertNotNil(inlinedEntry)
case .error(let error):
XCTFail("\(error)")
}
expectation.fulfill()
}
waitForExpectations(timeout: 10_000.0, handler: nil)
}


}

0 comments on commit 8276d17

Please sign in to comment.