File tree Expand file tree Collapse file tree
kotlin/embedded-checkout-protocol/src/test/java/com/shopify/ucp/embedded/checkout
swift/Tests/EmbeddedCheckoutProtocolTests Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1+ package com.shopify.ucp.embedded.checkout
2+
3+ import kotlinx.serialization.json.Json
4+ import kotlinx.serialization.json.jsonObject
5+ import kotlinx.serialization.json.jsonPrimitive
6+ import org.assertj.core.api.Assertions.assertThat
7+ import org.junit.Test
8+
9+ class ExtensionPreservationTest {
10+
11+ private val json = Json { ignoreUnknownKeys = true }
12+
13+ @Test
14+ fun `preserves unknown extension keys on Signals` () {
15+ val wire = """ {"dev.ucp.buyer_ip":"203.0.113.7","com.example.device_id":"abc-123"}"""
16+
17+ val signals = json.decodeFromString(Signals .serializer(), wire)
18+ val reEncoded = json.parseToJsonElement(json.encodeToString(Signals .serializer(), signals)).jsonObject
19+
20+ assertThat(reEncoded[" dev.ucp.buyer_ip" ]?.jsonPrimitive?.content).isEqualTo(" 203.0.113.7" )
21+ assertThat(reEncoded[" com.example.device_id" ]?.jsonPrimitive?.content).isEqualTo(" abc-123" )
22+ }
23+
24+ @Test
25+ fun `preserves unknown extension keys on Checkout` () {
26+ val wire = """
27+ {
28+ "id": "checkout-123",
29+ "currency": "USD",
30+ "line_items": [],
31+ "links": [],
32+ "status": "incomplete",
33+ "totals": [],
34+ "ucp": {"payment_handlers": {}, "version": "2026-04-08"},
35+ "com.example.foo": "bar"
36+ }
37+ """ .trimIndent()
38+
39+ val checkout = json.decodeFromString(Checkout .serializer(), wire)
40+ val reEncoded = json.parseToJsonElement(json.encodeToString(Checkout .serializer(), checkout)).jsonObject
41+
42+ assertThat(reEncoded[" com.example.foo" ]?.jsonPrimitive?.content).isEqualTo(" bar" )
43+ }
44+ }
Original file line number Diff line number Diff line change @@ -153,6 +153,38 @@ struct ModelDecodingTests {
153153 #expect( colorScheme == [ . light, . dark] )
154154 #expect( config. delegate == [ " window.open " ] )
155155 }
156+
157+ @Test func preservesUnknownExtensionKeysOnSignals( ) throws {
158+ let json = """
159+ { " dev.ucp.buyer_ip " : " 203.0.113.7 " , " com.example.device_id " : " abc-123 " }
160+ """
161+ let signals = try JSONDecoder ( ) . decode ( Signals . self, from: Data ( json. utf8) )
162+ let reEncoded = try JSONEncoder ( ) . encode ( signals)
163+ let object = try #require( try JSONSerialization . jsonObject ( with: reEncoded) as? [ String : Any ] )
164+
165+ #expect( object [ " dev.ucp.buyer_ip " ] as? String == " 203.0.113.7 " )
166+ #expect( object [ " com.example.device_id " ] as? String == " abc-123 " )
167+ }
168+
169+ @Test func preservesUnknownExtensionKeysOnCheckout( ) throws {
170+ let json = """
171+ {
172+ " id " : " checkout-123 " ,
173+ " currency " : " USD " ,
174+ " line_items " : [],
175+ " links " : [],
176+ " status " : " incomplete " ,
177+ " totals " : [],
178+ " ucp " : { " payment_handlers " : {}, " version " : " 2026-04-08 " },
179+ " com.example.foo " : " bar "
180+ }
181+ """
182+ let checkout = try JSONDecoder ( ) . decode ( Checkout . self, from: Data ( json. utf8) )
183+ let reEncoded = try JSONEncoder ( ) . encode ( checkout)
184+ let object = try #require( try JSONSerialization . jsonObject ( with: reEncoded) as? [ String : Any ] )
185+
186+ #expect( object [ " com.example.foo " ] as? String == " bar " )
187+ }
156188}
157189
158190private func fixtureString( _ name: String ) throws -> String {
Original file line number Diff line number Diff line change 1+ import { expect , test } from 'vitest' ;
2+
3+ import { Convert } from '../src/generated/Models' ;
4+
5+ test ( 'preserves unknown top-level and nested extension keys through Convert round-trip' , ( ) => {
6+ const wire = {
7+ id : 'checkout-123' ,
8+ currency : 'USD' ,
9+ line_items : [ ] ,
10+ links : [ ] ,
11+ status : 'incomplete' ,
12+ totals : [ ] ,
13+ ucp : { payment_handlers : { } , version : '2026-04-08' } ,
14+ signals : {
15+ 'dev.ucp.buyer_ip' : '203.0.113.7' ,
16+ 'com.example.device_id' : 'abc-123' ,
17+ } ,
18+ 'com.example.foo' : 'bar' ,
19+ } ;
20+
21+ const checkout = Convert . toCheckout ( JSON . stringify ( wire ) ) ;
22+ const roundTripped = JSON . parse ( Convert . checkoutToJson ( checkout ) ) ;
23+
24+ expect ( roundTripped [ 'com.example.foo' ] ) . toBe ( 'bar' ) ;
25+ expect ( roundTripped . signals [ 'dev.ucp.buyer_ip' ] ) . toBe ( '203.0.113.7' ) ;
26+ expect ( roundTripped . signals [ 'com.example.device_id' ] ) . toBe ( 'abc-123' ) ;
27+ } ) ;
You can’t perform that action at this time.
0 commit comments