mirror of
https://github.com/encounter/JSONAPI.git
synced 2026-03-30 11:18:38 -07:00
Allow omitting relationships if all are optional
When all relationships are optional, the `relationships` key is also optional and not required in the structure. I'm not super happy with importing Foundation and creating new objects any time a key is missing, but ultimately none of my attempts at conditional generics worked out for me.
This commit is contained in:
@@ -5,6 +5,8 @@
|
||||
// Created by Mathew Polzin on 7/24/18.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// A JSON API structure within an ResourceObject that contains
|
||||
/// named properties of types `ToOneRelationship` and
|
||||
/// `ToManyRelationship`.
|
||||
@@ -582,7 +584,6 @@ public extension ResourceObject {
|
||||
}
|
||||
|
||||
init(from decoder: Decoder) throws {
|
||||
|
||||
let container = try decoder.container(keyedBy: ResourceObjectCodingKeys.self)
|
||||
|
||||
let type = try container.decode(String.self, forKey: .type)
|
||||
@@ -597,7 +598,9 @@ public extension ResourceObject {
|
||||
attributes = try (NoAttributes() as? Description.Attributes) ??
|
||||
container.decode(Description.Attributes.self, forKey: .attributes)
|
||||
|
||||
relationships = try (NoRelationships() as? Description.Relationships) ?? container.decode(Description.Relationships.self, forKey: .relationships)
|
||||
relationships = try (NoRelationships() as? Description.Relationships)
|
||||
?? container.decodeIfPresent(Description.Relationships.self, forKey: .relationships)
|
||||
?? JSONDecoder().decode(Description.Relationships.self, from: "{}".data(using: .utf8)!)
|
||||
|
||||
meta = try (NoMetadata() as? MetaType) ?? container.decode(MetaType.self, forKey: .meta)
|
||||
|
||||
|
||||
@@ -403,6 +403,16 @@ extension EntityTests {
|
||||
data: entity_optional_nullable_nulled_relationship)
|
||||
}
|
||||
|
||||
func test_optionalNullableRelationshipOmitted() {
|
||||
let entity = decoded(type: TestEntity12.self,
|
||||
data: entity_all_relationships_optional_and_omitted)
|
||||
|
||||
XCTAssertNil(entity ~> \.optionalOne)
|
||||
XCTAssertNil(entity ~> \.optionalNullableOne)
|
||||
XCTAssertNil(entity ~> \.optionalMany)
|
||||
XCTAssertNoThrow(try TestEntity12.check(entity))
|
||||
}
|
||||
|
||||
func test_nullableRelationshipIsNull() {
|
||||
let entity = decoded(type: TestEntity9.self,
|
||||
data: entity_nulled_relationship)
|
||||
@@ -806,6 +816,28 @@ extension EntityTests {
|
||||
|
||||
typealias TestEntity11 = BasicEntity<TestEntityType11>
|
||||
|
||||
enum TestEntityType12: ResourceObjectDescription {
|
||||
public static var jsonType: String { return "twelfth_test_entities" }
|
||||
|
||||
typealias Attributes = NoAttributes
|
||||
|
||||
public struct Relationships: JSONAPI.Relationships {
|
||||
public init() {
|
||||
optionalOne = nil
|
||||
optionalNullableOne = nil
|
||||
optionalMany = nil
|
||||
}
|
||||
|
||||
let optionalOne: ToOneRelationship<TestEntity1, NoMetadata, NoLinks>?
|
||||
|
||||
let optionalNullableOne: ToOneRelationship<TestEntity1?, NoMetadata, NoLinks>?
|
||||
|
||||
let optionalMany: ToManyRelationship<TestEntity1, NoMetadata, NoLinks>?
|
||||
}
|
||||
}
|
||||
|
||||
typealias TestEntity12 = BasicEntity<TestEntityType12>
|
||||
|
||||
enum UnidentifiedTestEntityType: ResourceObjectDescription {
|
||||
public static var jsonType: String { return "unidentified_test_entities" }
|
||||
|
||||
|
||||
@@ -383,6 +383,16 @@ let entity_valid_validated_attribute = """
|
||||
}
|
||||
""".data(using: .utf8)!
|
||||
|
||||
let entity_all_relationships_optional_and_omitted = """
|
||||
{
|
||||
"id": "1",
|
||||
"type": "twelfth_test_entities",
|
||||
"attributes": {
|
||||
"number": 10
|
||||
}
|
||||
}
|
||||
""".data(using: .utf8)!
|
||||
|
||||
let entity_unidentified = """
|
||||
{
|
||||
"type": "unidentified_test_entities",
|
||||
|
||||
Reference in New Issue
Block a user