Skip to content

Commit 634478d

Browse files
committed
Tests and fixes for ToastArguments
1 parent bf2139d commit 634478d

File tree

4 files changed

+652
-20
lines changed

4 files changed

+652
-20
lines changed

Microsoft.Toolkit.Uwp.Notifications/Toasts/ToastArguments.cs

Lines changed: 57 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
namespace Microsoft.Toolkit.Uwp.Notifications
77
{
88
/// <summary>
9-
/// A portable string serializer/deserializer for .NET.
9+
/// A class that supports serializing simple key/value pairs into a format that's friendly for being used within toast notifications. The serialized format is similar to a query string, however optimized for being placed within an XML property (uses semicolons instead of ampersands since those don't need to be XML-escaped, doesn't url-encode all special characters since not being used within a URL, etc).
1010
/// </summary>
1111
public sealed class ToastArguments : IEnumerable<KeyValuePair<string, string>>
1212
{
@@ -66,16 +66,14 @@ public bool TryGetValue(string key, out string value)
6666
return _dictionary.TryGetValue(key, out value);
6767
}
6868

69+
#if !WINRT
6970
/// <summary>
7071
/// Attempts to get the value of the specified key. If no key exists, returns false.
7172
/// </summary>
7273
/// <typeparam name="T">The enum to parse.</typeparam>
7374
/// <param name="key">The key to find.</param>
7475
/// <param name="value">The key's value will be written here if found.</param>
7576
/// <returns>True if found the key and set the value, otherwise false.</returns>
76-
#if WINRT
77-
[return: System.Runtime.InteropServices.WindowsRuntime.ReturnValueName("found")]
78-
#endif
7977
public bool TryGetValue<T>(string key, out T value)
8078
where T : struct, Enum
8179
{
@@ -87,6 +85,7 @@ public bool TryGetValue<T>(string key, out T value)
8785
value = default(T);
8886
return false;
8987
}
88+
#endif
9089

9190
/// <summary>
9291
/// Gets the value of the specified key, or throws <see cref="KeyNotFoundException"/> if key didn't exist.
@@ -138,6 +137,16 @@ public float GetFloat(string key)
138137
return float.Parse(Get(key));
139138
}
140139

140+
/// <summary>
141+
/// Gets the value of the specified key, or throws <see cref="KeyNotFoundException"/> if key didn't exist.
142+
/// </summary>
143+
/// <param name="key">The key to get.</param>
144+
/// <returns>The value of the key.</returns>
145+
public byte GetByte(string key)
146+
{
147+
return byte.Parse(Get(key));
148+
}
149+
141150
/// <summary>
142151
/// Gets the value of the specified key, or throws <see cref="KeyNotFoundException"/> if key didn't exist.
143152
/// </summary>
@@ -148,6 +157,7 @@ public bool GetBool(string key)
148157
return Get(key) == "1" ? true : false;
149158
}
150159

160+
#if !WINRT
151161
/// <summary>
152162
/// Gets the value of the specified key, or throws <see cref="KeyNotFoundException"/> if key didn't exist.
153163
/// </summary>
@@ -164,6 +174,7 @@ public T GetEnum<T>(string key)
164174

165175
throw new KeyNotFoundException();
166176
}
177+
#endif
167178

168179
/// <summary>
169180
/// Gets the number of key/value pairs contained in the toast arguments.
@@ -203,14 +214,20 @@ public void Add(string key, string value)
203214
/// Sets a key. If there is an existing key, it is replaced.
204215
/// </summary>
205216
/// <param name="key">The key.</param>
206-
public void Set(string key)
217+
/// <returns>The current <see cref="ToastArguments"/> object.</returns>
218+
#if WINRT
219+
[return: System.Runtime.InteropServices.WindowsRuntime.ReturnValueName("toastArguments")]
220+
#endif
221+
public ToastArguments Set(string key)
207222
{
208223
if (key == null)
209224
{
210225
throw new ArgumentNullException(nameof(key));
211226
}
212227

213228
_dictionary[key] = null;
229+
230+
return this;
214231
}
215232

216233
/// <summary>
@@ -219,6 +236,10 @@ public void Set(string key)
219236
/// <param name="key">The key.</param>
220237
/// <param name="value">The optional value of the key.</param>
221238
/// <returns>The current <see cref="ToastArguments"/> object.</returns>
239+
#if WINRT
240+
[Windows.Foundation.Metadata.DefaultOverload]
241+
[return: System.Runtime.InteropServices.WindowsRuntime.ReturnValueName("toastArguments")]
242+
#endif
222243
public ToastArguments Set(string key, string value)
223244
{
224245
if (key == null)
@@ -237,6 +258,9 @@ public ToastArguments Set(string key, string value)
237258
/// <param name="key">The key.</param>
238259
/// <param name="value">The value of the key.</param>
239260
/// <returns>The current <see cref="ToastArguments"/> object.</returns>
261+
#if WINRT
262+
[return: System.Runtime.InteropServices.WindowsRuntime.ReturnValueName("toastArguments")]
263+
#endif
240264
public ToastArguments Set(string key, int value)
241265
{
242266
return SetHelper(key, value);
@@ -248,6 +272,9 @@ public ToastArguments Set(string key, int value)
248272
/// <param name="key">The key.</param>
249273
/// <param name="value">The value of the key.</param>
250274
/// <returns>The current <see cref="ToastArguments"/> object.</returns>
275+
#if WINRT
276+
[return: System.Runtime.InteropServices.WindowsRuntime.ReturnValueName("toastArguments")]
277+
#endif
251278
public ToastArguments Set(string key, double value)
252279
{
253280
return SetHelper(key, value);
@@ -259,6 +286,9 @@ public ToastArguments Set(string key, double value)
259286
/// <param name="key">The key.</param>
260287
/// <param name="value">The value of the key.</param>
261288
/// <returns>The current <see cref="ToastArguments"/> object.</returns>
289+
#if WINRT
290+
[return: System.Runtime.InteropServices.WindowsRuntime.ReturnValueName("toastArguments")]
291+
#endif
262292
public ToastArguments Set(string key, float value)
263293
{
264294
return SetHelper(key, value);
@@ -270,11 +300,15 @@ public ToastArguments Set(string key, float value)
270300
/// <param name="key">The key.</param>
271301
/// <param name="value">The value of the key.</param>
272302
/// <returns>The current <see cref="ToastArguments"/> object.</returns>
303+
#if WINRT
304+
[return: System.Runtime.InteropServices.WindowsRuntime.ReturnValueName("toastArguments")]
305+
#endif
273306
public ToastArguments Set(string key, bool value)
274307
{
275308
return Set(key, value ? "1" : "0"); // Encode as 1 or 0 to save string space
276309
}
277310

311+
#if !WINRT
278312
/// <summary>
279313
/// Sets a key and value. If there is an existing key, it is replaced.
280314
/// </summary>
@@ -285,6 +319,7 @@ public ToastArguments Set(string key, Enum value)
285319
{
286320
return Set(key, (int)(object)value);
287321
}
322+
#endif
288323

289324
private ToastArguments SetHelper(string key, object value)
290325
{
@@ -347,18 +382,20 @@ public bool Remove(string key)
347382
return _dictionary.Remove(key);
348383
}
349384

350-
private static string UrlEncode(string str)
385+
private static string Encode(string str)
351386
{
352-
return Uri.EscapeDataString(str)
353-
354-
// It incorrectly encodes spaces as %20, should use +
355-
.Replace("%20", "+");
387+
return str
388+
.Replace("%", "%25")
389+
.Replace(";", "%3B")
390+
.Replace("=", "%3D");
356391
}
357392

358-
private static string UrlDecode(string str)
393+
private static string Decode(string str)
359394
{
360-
// Doesn't handle decoding the +, so we manually do that
361-
return Uri.UnescapeDataString(str.Replace('+', ' '));
395+
return str
396+
.Replace("%25", "%")
397+
.Replace("%3B", ";")
398+
.Replace("%3D", "=");
362399
}
363400

364401
/// <summary>
@@ -373,7 +410,7 @@ public static ToastArguments Parse(string toastArgumentsStr)
373410
return new ToastArguments();
374411
}
375412

376-
string[] pairs = toastArgumentsStr.Split('&');
413+
string[] pairs = toastArgumentsStr.Split(';');
377414

378415
ToastArguments answer = new ToastArguments();
379416

@@ -386,13 +423,13 @@ public static ToastArguments Parse(string toastArgumentsStr)
386423

387424
if (indexOfEquals == -1)
388425
{
389-
name = UrlDecode(pair);
426+
name = Decode(pair);
390427
value = null;
391428
}
392429
else
393430
{
394-
name = UrlDecode(pair.Substring(0, indexOfEquals));
395-
value = UrlDecode(pair.Substring(indexOfEquals + 1));
431+
name = Decode(pair.Substring(0, indexOfEquals));
432+
value = Decode(pair.Substring(indexOfEquals + 1));
396433
}
397434

398435
answer.Add(name, value);
@@ -407,13 +444,13 @@ public static ToastArguments Parse(string toastArgumentsStr)
407444
/// <returns>A string that can be used within a toast notification.</returns>
408445
public sealed override string ToString()
409446
{
410-
return string.Join("&", this.Select(pair =>
447+
return string.Join(";", this.Select(pair =>
411448

412449
// Key
413-
UrlEncode(pair.Key) +
450+
Encode(pair.Key) +
414451

415452
// Write value if not null
416-
((pair.Value == null) ? string.Empty : ("=" + UrlEncode(pair.Value)))));
453+
((pair.Value == null) ? string.Empty : ("=" + Encode(pair.Value)))));
417454
}
418455

419456
/// <summary>

0 commit comments

Comments
 (0)