Skip to content

Commit af22d1e

Browse files
fix(client): handling of null value type
refactor(internal): share get/set logic
1 parent fc3c17b commit af22d1e

File tree

314 files changed

+17427
-111814
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

314 files changed

+17427
-111814
lines changed
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
using System.Collections.Generic;
2+
using System.Text.Json;
3+
using Orb.Core;
4+
using Orb.Exceptions;
5+
6+
namespace Orb.Tests.Core;
7+
8+
public class ModelBaseTest
9+
{
10+
[Fact]
11+
public void GetNotNullClass_WhenPresent_Works()
12+
{
13+
var dictionary = new Dictionary<string, JsonElement>();
14+
ModelBase.Set(dictionary, "key", "value");
15+
16+
var value = ModelBase.GetNotNullClass<string>(dictionary, "key");
17+
18+
Assert.Equal("value", value);
19+
}
20+
21+
[Fact]
22+
public void GetNotNullClass_WhenAbsent_Throws()
23+
{
24+
var dictionary = new Dictionary<string, JsonElement>();
25+
26+
var exception = Assert.Throws<OrbInvalidDataException>(() =>
27+
ModelBase.GetNotNullClass<string>(dictionary, "key")
28+
);
29+
30+
Assert.Equal("'key' cannot be absent", exception.Message);
31+
}
32+
33+
[Fact]
34+
public void GetNotNullClass_WhenNull_Throws()
35+
{
36+
var dictionary = new Dictionary<string, JsonElement>();
37+
ModelBase.Set<string?>(dictionary, "key", null);
38+
39+
var exception = Assert.Throws<OrbInvalidDataException>(() =>
40+
ModelBase.GetNotNullClass<string>(dictionary, "key")
41+
);
42+
43+
Assert.Equal("'key' cannot be null", exception.Message);
44+
}
45+
46+
[Fact]
47+
public void GetNotNullClass_WhenMismatchedType_Throws()
48+
{
49+
var dictionary = new Dictionary<string, JsonElement>();
50+
ModelBase.Set(dictionary, "key", 42);
51+
52+
var exception = Assert.Throws<OrbInvalidDataException>(() =>
53+
ModelBase.GetNotNullClass<string>(dictionary, "key")
54+
);
55+
56+
Assert.Equal("'key' must be of type System.String", exception.Message);
57+
}
58+
59+
[Fact]
60+
public void GetNotNullStruct_WhenPresent_Works()
61+
{
62+
var dictionary = new Dictionary<string, JsonElement>();
63+
ModelBase.Set(dictionary, "key", 42);
64+
65+
var value = ModelBase.GetNotNullStruct<int>(dictionary, "key");
66+
67+
Assert.Equal(42, value);
68+
}
69+
70+
[Fact]
71+
public void GetNotNullStruct_WhenAbsent_Throws()
72+
{
73+
var dictionary = new Dictionary<string, JsonElement>();
74+
75+
var exception = Assert.Throws<OrbInvalidDataException>(() =>
76+
ModelBase.GetNotNullStruct<int>(dictionary, "key")
77+
);
78+
79+
Assert.Equal("'key' cannot be absent", exception.Message);
80+
}
81+
82+
[Fact]
83+
public void GetNotNullStruct_WhenNull_Throws()
84+
{
85+
var dictionary = new Dictionary<string, JsonElement>();
86+
ModelBase.Set<int?>(dictionary, "key", null);
87+
88+
var exception = Assert.Throws<OrbInvalidDataException>(() =>
89+
ModelBase.GetNotNullStruct<int>(dictionary, "key")
90+
);
91+
92+
Assert.Equal("'key' cannot be null", exception.Message);
93+
}
94+
95+
[Fact]
96+
public void GetNotNullStruct_WhenMismatchedType_Throws()
97+
{
98+
var dictionary = new Dictionary<string, JsonElement>();
99+
ModelBase.Set(dictionary, "key", "value");
100+
101+
var exception = Assert.Throws<OrbInvalidDataException>(() =>
102+
ModelBase.GetNotNullStruct<int>(dictionary, "key")
103+
);
104+
105+
Assert.Equal("'key' must be of type System.Int32", exception.Message);
106+
}
107+
108+
[Fact]
109+
public void GetNullableClass_WhenPresent_Works()
110+
{
111+
var dictionary = new Dictionary<string, JsonElement>();
112+
ModelBase.Set(dictionary, "key", "value");
113+
114+
var value = ModelBase.GetNullableClass<string>(dictionary, "key");
115+
116+
Assert.Equal("value", value);
117+
}
118+
119+
[Fact]
120+
public void GetNullableClass_WhenAbsent_ReturnsNull()
121+
{
122+
var dictionary = new Dictionary<string, JsonElement>();
123+
124+
var value = ModelBase.GetNullableClass<string>(dictionary, "key");
125+
126+
Assert.Null(value);
127+
}
128+
129+
[Fact]
130+
public void GetNullableClass_WhenNull_ReturnsNull()
131+
{
132+
var dictionary = new Dictionary<string, JsonElement>();
133+
ModelBase.Set<string?>(dictionary, "key", null);
134+
135+
var value = ModelBase.GetNullableClass<string>(dictionary, "key");
136+
137+
Assert.Null(value);
138+
}
139+
140+
[Fact]
141+
public void GetNullableClass_WhenMismatchedType_Throws()
142+
{
143+
var dictionary = new Dictionary<string, JsonElement>();
144+
ModelBase.Set(dictionary, "key", 42);
145+
146+
var exception = Assert.Throws<OrbInvalidDataException>(() =>
147+
ModelBase.GetNullableClass<string>(dictionary, "key")
148+
);
149+
150+
Assert.Equal("'key' must be of type System.String", exception.Message);
151+
}
152+
153+
[Fact]
154+
public void GetNullableStruct_WhenPresent_Works()
155+
{
156+
var dictionary = new Dictionary<string, JsonElement>();
157+
ModelBase.Set(dictionary, "key", 42);
158+
159+
var value = ModelBase.GetNullableStruct<int>(dictionary, "key");
160+
161+
Assert.Equal(42, value);
162+
}
163+
164+
[Fact]
165+
public void GetNullableStruct_WhenAbsent_ReturnsNull()
166+
{
167+
var dictionary = new Dictionary<string, JsonElement>();
168+
169+
var value = ModelBase.GetNullableStruct<int>(dictionary, "key");
170+
171+
Assert.Null(value);
172+
}
173+
174+
[Fact]
175+
public void GetNullableStruct_WhenNull_ReturnsNull()
176+
{
177+
var dictionary = new Dictionary<string, JsonElement>();
178+
ModelBase.Set<int?>(dictionary, "key", null);
179+
180+
var value = ModelBase.GetNullableStruct<int>(dictionary, "key");
181+
182+
Assert.Null(value);
183+
}
184+
185+
[Fact]
186+
public void GetNullableStruct_WhenMismatchedType_Throws()
187+
{
188+
var dictionary = new Dictionary<string, JsonElement>();
189+
ModelBase.Set(dictionary, "key", "value");
190+
191+
var exception = Assert.Throws<OrbInvalidDataException>(() =>
192+
ModelBase.GetNullableStruct<int>(dictionary, "key")
193+
);
194+
195+
Assert.Equal("'key' must be of type System.Int32", exception.Message);
196+
}
197+
}

src/Orb/Core/ModelBase.cs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Collections.Generic;
22
using System.Text.Json;
3+
using Orb.Exceptions;
34
using Orb.Models.Beta;
45
using Orb.Models.CreditNotes;
56
using Orb.Models.Customers;
@@ -861,6 +862,97 @@ public IReadOnlyDictionary<string, JsonElement> RawData
861862
WriteIndented = true,
862863
};
863864

865+
internal static void Set<T>(IDictionary<string, JsonElement> dictionary, string key, T value)
866+
{
867+
dictionary[key] = JsonSerializer.SerializeToElement(value, SerializerOptions);
868+
}
869+
870+
internal static T GetNotNullClass<T>(
871+
IReadOnlyDictionary<string, JsonElement> dictionary,
872+
string key
873+
)
874+
where T : class
875+
{
876+
if (!dictionary.TryGetValue(key, out JsonElement element))
877+
{
878+
throw new OrbInvalidDataException($"'{key}' cannot be absent");
879+
}
880+
881+
try
882+
{
883+
return JsonSerializer.Deserialize<T>(element, SerializerOptions)
884+
?? throw new OrbInvalidDataException($"'{key}' cannot be null");
885+
}
886+
catch (JsonException e)
887+
{
888+
throw new OrbInvalidDataException($"'{key}' must be of type {typeof(T).FullName}", e);
889+
}
890+
}
891+
892+
internal static T GetNotNullStruct<T>(
893+
IReadOnlyDictionary<string, JsonElement> dictionary,
894+
string key
895+
)
896+
where T : struct
897+
{
898+
if (!dictionary.TryGetValue(key, out JsonElement element))
899+
{
900+
throw new OrbInvalidDataException($"'{key}' cannot be absent");
901+
}
902+
903+
try
904+
{
905+
return JsonSerializer.Deserialize<T?>(element, SerializerOptions)
906+
?? throw new OrbInvalidDataException($"'{key}' cannot be null");
907+
}
908+
catch (JsonException e)
909+
{
910+
throw new OrbInvalidDataException($"'{key}' must be of type {typeof(T).FullName}", e);
911+
}
912+
}
913+
914+
internal static T? GetNullableClass<T>(
915+
IReadOnlyDictionary<string, JsonElement> dictionary,
916+
string key
917+
)
918+
where T : class
919+
{
920+
if (!dictionary.TryGetValue(key, out JsonElement element))
921+
{
922+
return null;
923+
}
924+
925+
try
926+
{
927+
return JsonSerializer.Deserialize<T?>(element, SerializerOptions);
928+
}
929+
catch (JsonException e)
930+
{
931+
throw new OrbInvalidDataException($"'{key}' must be of type {typeof(T).FullName}", e);
932+
}
933+
}
934+
935+
internal static T? GetNullableStruct<T>(
936+
IReadOnlyDictionary<string, JsonElement> dictionary,
937+
string key
938+
)
939+
where T : struct
940+
{
941+
if (!dictionary.TryGetValue(key, out JsonElement element))
942+
{
943+
return null;
944+
}
945+
946+
try
947+
{
948+
return JsonSerializer.Deserialize<T?>(element, SerializerOptions);
949+
}
950+
catch (JsonException e)
951+
{
952+
throw new OrbInvalidDataException($"'{key}' must be of type {typeof(T).FullName}", e);
953+
}
954+
}
955+
864956
public sealed override string? ToString()
865957
{
866958
return JsonSerializer.Serialize(this.RawData, _toStringSerializerOptions);

0 commit comments

Comments
 (0)