From 4e197d1346de6e85af46cb9075549c9b21d1689e Mon Sep 17 00:00:00 2001 From: Di Wu Date: Tue, 12 Dec 2023 12:30:57 -0800 Subject: [PATCH] fix(datastore): configure json encoder with sorted key --- .../Categories/DataStore/Model/Internal/Model+Codable.swift | 6 +++++- .../Model/Internal/Schema/ModelValueConverter.swift | 4 +++- .../Models/SQLModelValueConverterTests.swift | 2 +- .../ProcessMutationErrorFromCloudOperationTests.swift | 2 +- AmplifyTests/CoreTests/Model+CodableTests.swift | 4 ++-- 5 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Amplify/Categories/DataStore/Model/Internal/Model+Codable.swift b/Amplify/Categories/DataStore/Model/Internal/Model+Codable.swift index 1fd055d95b..a91253a2ec 100644 --- a/Amplify/Categories/DataStore/Model/Internal/Model+Codable.swift +++ b/Amplify/Categories/DataStore/Model/Internal/Model+Codable.swift @@ -71,13 +71,17 @@ extension Model where Self: Codable { /// application making any change to these `public` types should be backward compatible, otherwise it will be a /// breaking change. public func toJSON(encoder: JSONEncoder? = nil) throws -> String { - let resolvedEncoder: JSONEncoder + var resolvedEncoder: JSONEncoder if let encoder = encoder { resolvedEncoder = encoder } else { resolvedEncoder = JSONEncoder(dateEncodingStrategy: ModelDateFormatting.encodingStrategy) } + if isKnownUniquelyReferenced(&resolvedEncoder) { + resolvedEncoder.outputFormatting = .sortedKeys + } + let data = try resolvedEncoder.encode(self) guard let json = String(data: data, encoding: .utf8) else { throw DataStoreError.decodingError( diff --git a/Amplify/Categories/DataStore/Model/Internal/Schema/ModelValueConverter.swift b/Amplify/Categories/DataStore/Model/Internal/Schema/ModelValueConverter.swift index e2ad3fb0f6..de961101ec 100644 --- a/Amplify/Categories/DataStore/Model/Internal/Schema/ModelValueConverter.swift +++ b/Amplify/Categories/DataStore/Model/Internal/Schema/ModelValueConverter.swift @@ -44,7 +44,9 @@ extension ModelValueConverter { } static var jsonEncoder: JSONEncoder { - JSONEncoder(dateEncodingStrategy: ModelDateFormatting.encodingStrategy) + let encoder = JSONEncoder(dateEncodingStrategy: ModelDateFormatting.encodingStrategy) + encoder.outputFormatting = .sortedKeys + return encoder } /// - Warning: Although this has `public` access, it is intended for internal & codegen use and should not be used diff --git a/AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginTests/Models/SQLModelValueConverterTests.swift b/AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginTests/Models/SQLModelValueConverterTests.swift index b4aba9e6d6..619265b00e 100644 --- a/AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginTests/Models/SQLModelValueConverterTests.swift +++ b/AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginTests/Models/SQLModelValueConverterTests.swift @@ -52,7 +52,7 @@ class SQLModelValueConverterTests: BaseDataStoreTests { /// - bool must be `Int` (1 or 0) /// - the remaining types should not change func testModelWithEveryTypeConversionToBindings() { - let nonModelJSON = "{\"someString\":\"string\",\"someEnum\":\"foo\"}" + let nonModelJSON = "{\"someEnum\":\"foo\",\"someString\":\"string\"}" let example = exampleModel // convert model to SQLite Bindings diff --git a/AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginTests/Sync/MutationQueue/ProcessMutationErrorFromCloudOperationTests.swift b/AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginTests/Sync/MutationQueue/ProcessMutationErrorFromCloudOperationTests.swift index 53204467b3..6733402a35 100644 --- a/AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginTests/Sync/MutationQueue/ProcessMutationErrorFromCloudOperationTests.swift +++ b/AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginTests/Sync/MutationQueue/ProcessMutationErrorFromCloudOperationTests.swift @@ -26,7 +26,7 @@ class ProcessMutationErrorFromCloudOperationTests: XCTestCase { var localPost = Post(title: "localTitle", content: "localContent", createdAt: .now()) let queue = OperationQueue() let reconciliationQueue = MockReconciliationQueue() - + override func setUp() { tryOrFail { try setUpWithAPI() diff --git a/AmplifyTests/CoreTests/Model+CodableTests.swift b/AmplifyTests/CoreTests/Model+CodableTests.swift index 5096ddca87..b933d2552f 100644 --- a/AmplifyTests/CoreTests/Model+CodableTests.swift +++ b/AmplifyTests/CoreTests/Model+CodableTests.swift @@ -11,11 +11,11 @@ import AmplifyTestCommon class ModelCodableTests: XCTestCase { let postJSONWithFractionalSeconds = """ - {"id":"post-1","title":"title","content":"content","comments":[],"createdAt":"1970-01-12T13:46:40.123Z"} + {"comments":[],"content":"content","createdAt":"1970-01-12T13:46:40.123Z","id":"post-1","title":"title"} """ let postJSONWithoutFractionalSeconds = """ - {"id":"post-1","title":"title","content":"content","comments":[],"createdAt":"1970-01-12T13:46:40Z"} + {"comments":[],"content":"content","createdAt":"1970-01-12T13:46:40Z","id":"post-1","title":"title"} """ override func setUp() {