Added tests and fix to ensure RawDataContainer includes all data#1565
Conversation
fb12779 to
74be49e
Compare
f9fb2d6 to
56a12b6
Compare
74be49e to
db27ce0
Compare
56a12b6 to
2301693
Compare
RawDataContainerRawDataContainer
RawDataContainerRawDataContainer includes all data
2301693 to
af2b181
Compare
db27ce0 to
6242220
Compare
af2b181 to
9e0a81e
Compare
6242220 to
d36135d
Compare
38b6f32 to
d9f8c16
Compare
a243e5e to
093d620
Compare
d9f8c16 to
49198cf
Compare
093d620 to
8e41b91
Compare
49198cf to
b466521
Compare
There was a problem hiding this comment.
This logs an error and simply returns empty data. We wouldn't want to make the entire structure fail to decode because of this.
There was a problem hiding this comment.
This is the new way of making CustomerInfoResponse: Hashable only look at subscriber :)
There was a problem hiding this comment.
nice!! Perhaps we could add that as a comment here?
There was a problem hiding this comment.
Oh yeah, I removed the comment from the previous implementation but that would be good here.
There was a problem hiding this comment.
I think this is pretty elegant 🤓
There was a problem hiding this comment.
yeah, the syntax for this is :chefskiss:
There was a problem hiding this comment.
This is the only downside, but it's not too bad. We must manually implement this method. But reusing decodeRawData() it's pretty clean.
8e41b91 to
181958f
Compare
7951bed to
09605aa
Compare
There was a problem hiding this comment.
nice!! Perhaps we could add that as a comment here?
There was a problem hiding this comment.
yeah, the syntax for this is :chefskiss:
### Depends on: - #1537 - #1540 - #1541 - #1543 - #1546 - #1547 - #1550 - #1551, - #1565 ### Changes - Removed all custom deserialization code thanks to #1537, #1541, and #1543. - The format of the customer info response is now very concise and only in one place (`CustomerInfoResponse`) instead of being passed through dictionaries and magic strings everywhere. - `CustomerInfo` was combining the dictionaries inside of `"subscriptions"` and `"non_subscriptions"`, despite them having different formats. This is now made explicit through type conversions between the two, (see `CustomerInfoResponse.allTransactionsByProductId`). - Removed all custom `CustomerInfo` errors since deserialization is automatic, and the underlying `Error` information will be provided thanks to `ErrorUtils.logDecodingError`. - `CustomerInfo` deserialization always wraps errors into `ErrorCode.customerInfoError`, which is now also covered in a new test. - Added a new snapshot test that covers `CustomerInfo` serialization by storing the result in a JSON file. ### Other changes: - `CustomerInfo` equality is now automatic through the `CustomerInfoResponse` `Equatable` conformance. - Simplified `schemaVersion` handling - All tests still use `CustomerInfo(data: [String: Any])`, but that method is only visible for tests now, and it uses the underlying `Decodable` implementation (see `CustomerInfo+TestExtensions.swift`). - Added extra tests for `CustomerInfoResponse` that use a fixture `CustomerInfo.json`, which is easier to maintain than having JSON in code. - `RawDataContainer` implementation is changed in #1565. ### TODO: - [x] Fix all tests - [x] Update `RawValueContainer` - [x] Consider recovering `CustomerInfoError` - [x] Look at all previously logged errors - [x] Finish `CustomerInfoResponseTests` - [x] Handle all TODOs - [x] Make `RawDataContainer` actually store all the original data: #1565
Follow up to #1496. Depends on #1567 and #1568. The solution implemented in #1496 was very simple, but [as pointed out by @joshdholtz](#1496 (comment)), it was only encoding the data that was formally decoded by the `struct`s. We had no test coverage for this, so it went unnoticed. The new solution adds a new field: ```swift @IgnoreEncodable var rawData: [String: Any] ``` Which, together with a new helper method `decodeRawData()`, allows storing all the data to be used by `CustomerInfo`'s `RawDataContainer` implementation. Unfortunately, despite many attempts, I realized that this can't be abstracted into a property wrapper, because a `KeyedDecodingContainer` can't access the parent `Decoder`. That's why the `CustomerInfoResponse` and `CustomerInfoResponse.Entitlement` must manually call this method.
09605aa to
7e630a3
Compare
Follow up to #1496. Depends on
#1567, #1568, #1604.The solution implemented in #1496 was very simple, but as pointed out by @joshdholtz, it was only encoding the data that was formally decoded by the
structs.We had no test coverage for this, so it went unnoticed.
The new solution adds a new field:
Which, together with a new helper method
decodeRawData(), allows storing all the data to be used byCustomerInfo'sRawDataContainerimplementation.Unfortunately, despite many attempts, I realized that this can't be abstracted into a property wrapper, because a
KeyedDecodingContainercan't access the parentDecoder.That's why the
CustomerInfoResponseandCustomerInfoResponse.Entitlementmust manually call this method.