From d69ee73ffff6a9e3870d1dedd723ba9085116312 Mon Sep 17 00:00:00 2001 From: Chris Sainty Date: Sun, 1 Jan 2023 14:29:28 +0000 Subject: [PATCH] Updated features to match local storage package --- Directory.Build.props | 4 +- README.md | 37 +- ...zored.SessionStorage.TestExtensions.csproj | 8 +- .../InMemoryStorageProvider.cs | 47 +- .../Blazored.SessionStorage.csproj | 18 +- .../BrowserStorageProvider.cs | 344 +++++++++++++-- .../ChangedEventArgs.cs | 15 +- .../ChangingEventArgs.cs | 13 +- .../BrowserStorageDisabledException.cs | 18 + .../ISessionStorageService.cs | 144 +++--- .../IStorageProvider.cs | 39 +- .../ISyncSessionStorageService.cs | 126 +++--- .../JsonConverters/TimespanJsonConverter.cs | 49 +-- .../Serialization/IJsonSerializer.cs | 11 +- .../Serialization/SystemTextJsonSerializer.cs | 35 +- .../ServiceCollectionExtensions.cs | 66 ++- .../SessionStorageService.cs | 412 +++++++++--------- .../StorageOptions/LocalStorageOptions.cs | 9 - .../StorageOptions/SessionStorageOptions.cs | 8 + .../SessionStorageServiceTests/Clear.cs | 73 ++-- .../SessionStorageServiceTests/ClearAsync.cs | 73 ++-- .../SessionStorageServiceTests/ContainsKey.cs | 73 ++-- .../ContainsKeyAsync.cs | 73 ++-- .../SessionStorageServiceTests/GetItem.cs | 151 ++++--- .../GetItemAsString.cs | 109 +++-- .../GetItemAsStringAsync.cs | 109 +++-- .../GetItemAsync.cs | 151 ++++--- .../SessionStorageServiceTests/Key.cs | 81 ++-- .../SessionStorageServiceTests/KeyAsync.cs | 81 ++-- .../SessionStorageServiceTests/Keys.cs | 153 +++++++ .../SessionStorageServiceTests/Length.cs | 77 ++-- .../SessionStorageServiceTests/LengthAsync.cs | 77 ++-- .../SessionStorageServiceTests/RemoveItem.cs | 93 ++-- .../RemoveItemAsync.cs | 93 ++-- .../SessionStorageServiceTests/SetItem.cs | 411 +++++++++-------- .../SetItemAsString.cs | 353 ++++++++------- .../SetItemAsStringAsync.cs | 353 ++++++++------- .../SetItemAsync.cs | 411 +++++++++-------- .../TestAssets/TestObject.cs | 23 +- 39 files changed, 2486 insertions(+), 1935 deletions(-) create mode 100644 src/Blazored.SessionStorage/Exceptions/BrowserStorageDisabledException.cs delete mode 100644 src/Blazored.SessionStorage/StorageOptions/LocalStorageOptions.cs create mode 100644 src/Blazored.SessionStorage/StorageOptions/SessionStorageOptions.cs create mode 100644 tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/Keys.cs diff --git a/Directory.Build.props b/Directory.Build.props index 28acef2..8f1e9e9 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -2,8 +2,8 @@ - 3.1.14 - 5.0.5 + 6.0.12 + 7.0.1 \ No newline at end of file diff --git a/README.md b/README.md index 703cebf..3d1e274 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ builder.Services.AddBlazoredSessionStorage(config => { ``` ### SetItem[Async] method now serializes string values -Prior to v2 we bypassed the serialization of string values as it seemed a pointless as string can be stored directly. However, this led to some edge cases where nullable strings were being saved as the string `"null"`. Then when retrieved, instead of being null the value was `"null"`. By serializing strings this issue is taken care of. +Prior to v2 we bypassed the serialization of string values as it seemed pointless as string can be stored directly. However, this led to some edge cases where nullable strings were being saved as the string `"null"`. Then when retrieved, instead of being null the value was `"null"`. By serializing strings this issue is taken care of. For those who wish to save raw string values, a new method `SetValueAsString[Async]` is available. This will save a string value without attempting to serialize it and will throw an exception if a null string is attempted to be saved. ## Installing @@ -42,7 +42,7 @@ You can also install via the .NET CLI with the following command: dotnet add package Blazored.SessionStorage ``` -If you're using Visual Studio you can also install via the built in NuGet package manager. +If you're using Jetbrains Rider or Visual Studio you can also install via the built in NuGet package manager. ## Setup @@ -69,6 +69,17 @@ public static async Task Main(string[] args) } ``` +### Registering services as Singleton - Blazor WebAssembly **ONLY** +99% of developers will want to register Blazored SessionStorage using the method described above. However, in some very specific scenarios, +developers may have a need to register services as Singleton as apposed to Scoped. This is possible by using the following method: + +```csharp +builder.Services.AddBlazoredSessionStorageAsSingleton(); +``` + +**This method will not work with Blazor Server applications as Blazor's JS interop services are registered as Scoped and cannot be injected into Singletons.** + + ## Usage (Blazor WebAssembly) To use Blazored.SessionStorage in Blazor WebAssembly, inject the `ISessionStorageService` per the example below. @@ -128,9 +139,11 @@ The APIs available are: - GetItemAsync() - GetItemAsStringAsync() - RemoveItemAsync() + - RemoveItemsAsync() - ClearAsync() - LengthAsync() - KeyAsync() + - KeysAsync() - ContainKeyAsync() - synchronous via `ISyncSessionStorageService` (Synchronous methods are **only** available in Blazor WebAssembly): @@ -139,9 +152,11 @@ The APIs available are: - GetItem() - GetItemAsString() - RemoveItem() + - RemovesItem() - Clear() - Length() - Key() + - Keys() - ContainKey() **Note:** Blazored.SessionStorage methods will handle the serialisation and de-serialisation of the data for you, the exception is the `GetItemAsString[Async]` method which will return the raw string value from session storage. @@ -178,6 +193,24 @@ You can find an example of this in the Blazor Server sample project. The standar ## Testing with bUnit This library provides test extensions for use with the [bUnit testing library](https://bunit.dev/). Using these test extensions will provide an in memory implementation which mimics session storage allowing more realistic testing of your components. +### Installing + +To install the package add the following line to you csproj file replacing x.x.x with the latest version number (found at the top of this file): + +``` + +``` + +You can also install via the .NET CLI with the following command: + +``` +dotnet add package Blazored.SessionStorage.TestExtensions +``` + +If you're using Jetbrains Rider or Visual Studio you can also install via the built in NuGet package manager. + +### Usage example + Below is an example test which uses these extensions. You can find an example project which shows this code in action in the samples folder. ```c# diff --git a/src/Blazored.SessionStorage.TestExtensions/Blazored.SessionStorage.TestExtensions.csproj b/src/Blazored.SessionStorage.TestExtensions/Blazored.SessionStorage.TestExtensions.csproj index f75b71b..40800be 100644 --- a/src/Blazored.SessionStorage.TestExtensions/Blazored.SessionStorage.TestExtensions.csproj +++ b/src/Blazored.SessionStorage.TestExtensions/Blazored.SessionStorage.TestExtensions.csproj @@ -1,7 +1,7 @@  - netstandard2.1;net7.0 + net6.0;net7.0 Chris Sainty @@ -26,12 +26,16 @@ Blazored.SessionStorage.snk + + + + - + diff --git a/src/Blazored.SessionStorage.TestExtensions/InMemoryStorageProvider.cs b/src/Blazored.SessionStorage.TestExtensions/InMemoryStorageProvider.cs index 268d1e3..36615c0 100644 --- a/src/Blazored.SessionStorage.TestExtensions/InMemoryStorageProvider.cs +++ b/src/Blazored.SessionStorage.TestExtensions/InMemoryStorageProvider.cs @@ -7,12 +7,12 @@ namespace Blazored.SessionStorage.TestExtensions { internal class InMemoryStorageProvider : IStorageProvider { - private readonly Dictionary _dataStore = new Dictionary(); + private readonly Dictionary _dataStore = new(); public void Clear() => _dataStore.Clear(); - public ValueTask ClearAsync(CancellationToken? cancellationToken = null) + public ValueTask ClearAsync(CancellationToken cancellationToken = default) { _dataStore.Clear(); return new ValueTask(Task.CompletedTask); @@ -21,35 +21,56 @@ public ValueTask ClearAsync(CancellationToken? cancellationToken = null) public bool ContainKey(string key) => _dataStore.ContainsKey(key); - public ValueTask ContainKeyAsync(string key, CancellationToken? cancellationToken = null) - => new ValueTask(ContainKey(key)); + public ValueTask ContainKeyAsync(string key, CancellationToken cancellationToken = default) + => new(ContainKey(key)); public string GetItem(string key) - => _dataStore.ContainsKey(key) ? _dataStore[key] : default; + => _dataStore.TryGetValue(key, out var value) ? value : default; - public ValueTask GetItemAsync(string key, CancellationToken? cancellationToken = null) - => new ValueTask(GetItem(key)); + public ValueTask GetItemAsync(string key, CancellationToken cancellationToken = default) + => new(GetItem(key)); public string Key(int index) => index > _dataStore.Count - 1 ? default : _dataStore.ElementAt(index).Key; - public ValueTask KeyAsync(int index, CancellationToken? cancellationToken = null) - => new ValueTask(Key(index)); + public IEnumerable Keys() + => _dataStore.Keys.ToList(); + + public ValueTask KeyAsync(int index, CancellationToken cancellationToken = default) + => new(Key(index)); + + public ValueTask> KeysAsync(CancellationToken cancellationToken = default) + => new(_dataStore.Keys.ToList()); public int Length() => _dataStore.Count; - public ValueTask LengthAsync(CancellationToken? cancellationToken = null) - => new ValueTask(Length()); + public ValueTask LengthAsync(CancellationToken cancellationToken = default) + => new(Length()); public void RemoveItem(string key) => _dataStore.Remove(key); - public ValueTask RemoveItemAsync(string key, CancellationToken? cancellationToken = null) + public ValueTask RemoveItemAsync(string key, CancellationToken cancellationToken = default) { RemoveItem(key); return new ValueTask(Task.CompletedTask); } + + public void RemoveItems(IEnumerable keys) + { + foreach (var key in keys) + { + _dataStore.Remove(key); + } + } + + public ValueTask RemoveItemsAsync(IEnumerable keys, CancellationToken cancellationToken = default) + { + RemoveItems(keys); + + return new ValueTask(Task.CompletedTask); + } public void SetItem(string key, string data) { @@ -63,7 +84,7 @@ public void SetItem(string key, string data) } } - public ValueTask SetItemAsync(string key, string data, CancellationToken? cancellationToken = null) + public ValueTask SetItemAsync(string key, string data, CancellationToken cancellationToken = default) { SetItem(key, data); return new ValueTask(Task.CompletedTask); diff --git a/src/Blazored.SessionStorage/Blazored.SessionStorage.csproj b/src/Blazored.SessionStorage/Blazored.SessionStorage.csproj index 2ff8b60..07ebd5d 100644 --- a/src/Blazored.SessionStorage/Blazored.SessionStorage.csproj +++ b/src/Blazored.SessionStorage/Blazored.SessionStorage.csproj @@ -1,7 +1,7 @@  - netstandard2.1;net7.0 + net6.0;net7.0 Chris Sainty @@ -26,20 +26,16 @@ Blazored.SessionStorage.snk - - 3.0 - - - + - - + + - + - + @@ -62,4 +58,4 @@ - + \ No newline at end of file diff --git a/src/Blazored.SessionStorage/BrowserStorageProvider.cs b/src/Blazored.SessionStorage/BrowserStorageProvider.cs index 6c1e398..883c4bb 100644 --- a/src/Blazored.SessionStorage/BrowserStorageProvider.cs +++ b/src/Blazored.SessionStorage/BrowserStorageProvider.cs @@ -1,88 +1,352 @@ using Microsoft.JSInterop; using System; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using Blazored.SessionStorage.Exceptions; -namespace Blazored.SessionStorage +namespace Blazored.SessionStorage; + +internal class BrowserStorageProvider : IStorageProvider { - internal class BrowserStorageProvider : IStorageProvider + private const string StorageNotAvailableMessage = "Unable to access the browser storage. This is most likely due to the browser settings."; + + private readonly IJSRuntime _jSRuntime; + private readonly IJSInProcessRuntime _jSInProcessRuntime; + + public BrowserStorageProvider(IJSRuntime jSRuntime) + { + _jSRuntime = jSRuntime; + _jSInProcessRuntime = jSRuntime as IJSInProcessRuntime; + } + + public async ValueTask ClearAsync(CancellationToken cancellationToken = default) + { + try + { + await _jSRuntime.InvokeVoidAsync("sessionStorage.clear", cancellationToken); + } + catch (Exception exception) + { + if (IsStorageDisabledException(exception)) + { + throw new BrowserStorageDisabledException(StorageNotAvailableMessage, exception); + } + + throw; + } + } + + public async ValueTask GetItemAsync(string key, CancellationToken cancellationToken = default) + { + try + { + return await _jSRuntime.InvokeAsync("sessionStorage.getItem", cancellationToken, key); + } + catch (Exception exception) + { + if (IsStorageDisabledException(exception)) + { + throw new BrowserStorageDisabledException(StorageNotAvailableMessage, exception); + } + + throw; + } + } + + public async ValueTask KeyAsync(int index, CancellationToken cancellationToken = default) + { + try + { + return await _jSRuntime.InvokeAsync("sessionStorage.key", cancellationToken, index); + } + catch (Exception exception) + { + if (IsStorageDisabledException(exception)) + { + throw new BrowserStorageDisabledException(StorageNotAvailableMessage, exception); + } + + throw; + } + } + + public async ValueTask> KeysAsync(CancellationToken cancellationToken = default) { - private readonly IJSRuntime _jSRuntime; - private readonly IJSInProcessRuntime _jSInProcessRuntime; + try + { + return await _jSRuntime.InvokeAsync>("eval", cancellationToken, "Object.keys(sessionStorage)"); + } + catch (Exception exception) + { + if (IsStorageDisabledException(exception)) + { + throw new BrowserStorageDisabledException(StorageNotAvailableMessage, exception); + } + + throw; + } + } - public BrowserStorageProvider(IJSRuntime jSRuntime) + public async ValueTask ContainKeyAsync(string key, CancellationToken cancellationToken = default) + { + try { - _jSRuntime = jSRuntime; - _jSInProcessRuntime = jSRuntime as IJSInProcessRuntime; + return await _jSRuntime.InvokeAsync("sessionStorage.hasOwnProperty", cancellationToken, key); } + catch (Exception exception) + { + if (IsStorageDisabledException(exception)) + { + throw new BrowserStorageDisabledException(StorageNotAvailableMessage, exception); + } - public ValueTask ClearAsync(CancellationToken? cancellationToken = null) - => _jSRuntime.InvokeVoidAsync("sessionStorage.clear", cancellationToken ?? CancellationToken.None); + throw; + } + } - public ValueTask GetItemAsync(string key, CancellationToken? cancellationToken = null) - => _jSRuntime.InvokeAsync("sessionStorage.getItem", cancellationToken ?? CancellationToken.None, key); + public async ValueTask LengthAsync(CancellationToken cancellationToken = default) + { + try + { + return await _jSRuntime.InvokeAsync("eval", cancellationToken, "sessionStorage.length"); + } + catch (Exception exception) + { + if (IsStorageDisabledException(exception)) + { + throw new BrowserStorageDisabledException(StorageNotAvailableMessage, exception); + } - public ValueTask KeyAsync(int index, CancellationToken? cancellationToken = null) - => _jSRuntime.InvokeAsync("sessionStorage.key", cancellationToken ?? CancellationToken.None, index); + throw; + } + } - public ValueTask ContainKeyAsync(string key, CancellationToken? cancellationToken = null) - => _jSRuntime.InvokeAsync("sessionStorage.hasOwnProperty", cancellationToken ?? CancellationToken.None, key); + public async ValueTask RemoveItemAsync(string key, CancellationToken cancellationToken = default) + { + try + { + await _jSRuntime.InvokeVoidAsync("sessionStorage.removeItem", cancellationToken, key); + } + catch (Exception exception) + { + if (IsStorageDisabledException(exception)) + { + throw new BrowserStorageDisabledException(StorageNotAvailableMessage, exception); + } - public ValueTask LengthAsync(CancellationToken? cancellationToken = null) - => _jSRuntime.InvokeAsync("eval", cancellationToken ?? CancellationToken.None, "sessionStorage.length"); + throw; + } + } - public ValueTask RemoveItemAsync(string key, CancellationToken? cancellationToken = null) - => _jSRuntime.InvokeVoidAsync("sessionStorage.removeItem", cancellationToken ?? CancellationToken.None, key); + public async ValueTask RemoveItemsAsync(IEnumerable keys, CancellationToken cancellationToken = default) + { + try + { + foreach (var key in keys) + { + await _jSRuntime.InvokeVoidAsync("sessionStorage.removeItem", cancellationToken, key); + } + } + catch (Exception exception) + { + if (IsStorageDisabledException(exception)) + { + throw new BrowserStorageDisabledException(StorageNotAvailableMessage, exception); + } - public ValueTask SetItemAsync(string key, string data, CancellationToken? cancellationToken = null) - => _jSRuntime.InvokeVoidAsync("sessionStorage.setItem", cancellationToken ?? CancellationToken.None, key, data); + throw; + } + } - public void Clear() + public async ValueTask SetItemAsync(string key, string data, CancellationToken cancellationToken = default) + { + try + { + await _jSRuntime.InvokeVoidAsync("sessionStorage.setItem", cancellationToken, key, data); + } + catch (Exception exception) + { + if (IsStorageDisabledException(exception)) + { + throw new BrowserStorageDisabledException(StorageNotAvailableMessage, exception); + } + + throw; + } + } + + public void Clear() + { + CheckForInProcessRuntime(); + try { - CheckForInProcessRuntime(); _jSInProcessRuntime.InvokeVoid("sessionStorage.clear"); } + catch (Exception exception) + { + if (IsStorageDisabledException(exception)) + { + throw new BrowserStorageDisabledException(StorageNotAvailableMessage, exception); + } + + throw; + } + } - public string GetItem(string key) + public string GetItem(string key) + { + CheckForInProcessRuntime(); + try { - CheckForInProcessRuntime(); return _jSInProcessRuntime.Invoke("sessionStorage.getItem", key); } + catch (Exception exception) + { + if (IsStorageDisabledException(exception)) + { + throw new BrowserStorageDisabledException(StorageNotAvailableMessage, exception); + } - public string Key(int index) + throw; + } + } + + public string Key(int index) + { + CheckForInProcessRuntime(); + try { - CheckForInProcessRuntime(); return _jSInProcessRuntime.Invoke("sessionStorage.key", index); } + catch (Exception exception) + { + if (IsStorageDisabledException(exception)) + { + throw new BrowserStorageDisabledException(StorageNotAvailableMessage, exception); + } - public bool ContainKey(string key) + throw; + } + } + + public IEnumerable Keys() + { + CheckForInProcessRuntime(); + try + { + return _jSInProcessRuntime.Invoke>("eval", "Object.keys(sessionStorage)"); + } + catch (Exception exception) + { + if (IsStorageDisabledException(exception)) + { + throw new BrowserStorageDisabledException(StorageNotAvailableMessage, exception); + } + + throw; + } + } + + public bool ContainKey(string key) + { + CheckForInProcessRuntime(); + try { - CheckForInProcessRuntime(); return _jSInProcessRuntime.Invoke("sessionStorage.hasOwnProperty", key); } + catch (Exception exception) + { + if (IsStorageDisabledException(exception)) + { + throw new BrowserStorageDisabledException(StorageNotAvailableMessage, exception); + } - public int Length() + throw; + } + } + + public int Length() + { + CheckForInProcessRuntime(); + try { - CheckForInProcessRuntime(); return _jSInProcessRuntime.Invoke("eval", "sessionStorage.length"); } + catch (Exception exception) + { + if (IsStorageDisabledException(exception)) + { + throw new BrowserStorageDisabledException(StorageNotAvailableMessage, exception); + } + + throw; + } + } + + public void RemoveItem(string key) + { + CheckForInProcessRuntime(); + try + { + _jSInProcessRuntime.InvokeVoid("sessionStorage.removeItem", key); + } + catch (Exception exception) + { + if (IsStorageDisabledException(exception)) + { + throw new BrowserStorageDisabledException(StorageNotAvailableMessage, exception); + } - public void RemoveItem(string key) + throw; + } + } + + public void RemoveItems(IEnumerable keys) + { + CheckForInProcessRuntime(); + try { - CheckForInProcessRuntime(); - _jSInProcessRuntime.InvokeVoidAsync("sessionStorage.removeItem", key); + foreach (var key in keys) + { + _jSInProcessRuntime.InvokeVoid("sessionStorage.removeItem", key); + } + } + catch (Exception exception) + { + if (IsStorageDisabledException(exception)) + { + throw new BrowserStorageDisabledException(StorageNotAvailableMessage, exception); + } + + throw; } + } - public void SetItem(string key, string data) + public void SetItem(string key, string data) + { + CheckForInProcessRuntime(); + try { - CheckForInProcessRuntime(); _jSInProcessRuntime.InvokeVoid("sessionStorage.setItem", key, data); } - - private void CheckForInProcessRuntime() + catch (Exception exception) { - if (_jSInProcessRuntime == null) - throw new InvalidOperationException("IJSInProcessRuntime not available"); + if (IsStorageDisabledException(exception)) + { + throw new BrowserStorageDisabledException(StorageNotAvailableMessage, exception); + } + + throw; } } + + private void CheckForInProcessRuntime() + { + if (_jSInProcessRuntime == null) + throw new InvalidOperationException("IJSInProcessRuntime not available"); + } + + private static bool IsStorageDisabledException(Exception exception) + => exception.Message.Contains("Failed to read the 'sessionStorage' property from 'Window'"); } diff --git a/src/Blazored.SessionStorage/ChangedEventArgs.cs b/src/Blazored.SessionStorage/ChangedEventArgs.cs index fae2781..f20fba4 100644 --- a/src/Blazored.SessionStorage/ChangedEventArgs.cs +++ b/src/Blazored.SessionStorage/ChangedEventArgs.cs @@ -1,12 +1,11 @@ using System.Diagnostics.CodeAnalysis; -namespace Blazored.SessionStorage +namespace Blazored.SessionStorage; + +[ExcludeFromCodeCoverage] +public class ChangedEventArgs { - [ExcludeFromCodeCoverage] - public class ChangedEventArgs - { - public string Key { get; set; } - public object OldValue { get; set; } - public object NewValue { get; set; } - } + public string Key { get; set; } + public object OldValue { get; set; } + public object NewValue { get; set; } } \ No newline at end of file diff --git a/src/Blazored.SessionStorage/ChangingEventArgs.cs b/src/Blazored.SessionStorage/ChangingEventArgs.cs index 047a3e3..032c9e4 100644 --- a/src/Blazored.SessionStorage/ChangingEventArgs.cs +++ b/src/Blazored.SessionStorage/ChangingEventArgs.cs @@ -1,11 +1,10 @@ using System; using System.Diagnostics.CodeAnalysis; -namespace Blazored.SessionStorage +namespace Blazored.SessionStorage; + +[ExcludeFromCodeCoverage] +public class ChangingEventArgs : ChangedEventArgs { - [ExcludeFromCodeCoverage] - public class ChangingEventArgs : ChangedEventArgs - { - public bool Cancel { get; set; } - } -} + public bool Cancel { get; set; } +} \ No newline at end of file diff --git a/src/Blazored.SessionStorage/Exceptions/BrowserStorageDisabledException.cs b/src/Blazored.SessionStorage/Exceptions/BrowserStorageDisabledException.cs new file mode 100644 index 0000000..212a658 --- /dev/null +++ b/src/Blazored.SessionStorage/Exceptions/BrowserStorageDisabledException.cs @@ -0,0 +1,18 @@ +using System; + +namespace Blazored.SessionStorage.Exceptions; + +public class BrowserStorageDisabledException : Exception +{ + public BrowserStorageDisabledException() + { + } + + public BrowserStorageDisabledException(string message) : base(message) + { + } + + public BrowserStorageDisabledException(string message, Exception inner) : base(message, inner) + { + } +} diff --git a/src/Blazored.SessionStorage/ISessionStorageService.cs b/src/Blazored.SessionStorage/ISessionStorageService.cs index c61c98c..e35d989 100644 --- a/src/Blazored.SessionStorage/ISessionStorageService.cs +++ b/src/Blazored.SessionStorage/ISessionStorageService.cs @@ -1,75 +1,99 @@ using System; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using Microsoft.JSInterop; -namespace Blazored.SessionStorage +namespace Blazored.SessionStorage; + +public interface ISessionStorageService { - public interface ISessionStorageService - { - /// - /// Clears all data from session storage. - /// - /// A representing the completion of the operation. - ValueTask ClearAsync(CancellationToken? cancellationToken = null); + /// + /// Clears all data from session storage. + /// + /// A representing the completion of the operation. + ValueTask ClearAsync(CancellationToken cancellationToken = default); - /// - /// Retrieve the specified data from session storage and deseralise it to the specfied type. - /// - /// A value specifying the name of the session storage slot to use - /// A representing the completion of the operation. - ValueTask GetItemAsync(string key, CancellationToken? cancellationToken = null); + /// + /// Retrieve the specified data from session storage and deseralise it to the specfied type. + /// + /// A value specifying the name of the session storage slot to use + /// A cancellation token to signal the cancellation of the operation. Specifying this parameter will override any default cancellations such as due to timeouts () from being applied. + /// A representing the completion of the operation. + ValueTask GetItemAsync(string key, CancellationToken cancellationToken = default); - /// - /// Retrieve the specified data from session storage as a . - /// - /// A value specifying the name of the storage slot to use - /// A representing the completion of the operation. - ValueTask GetItemAsStringAsync(string key, CancellationToken? cancellationToken = null); + /// + /// Retrieve the specified data from session storage as a . + /// + /// A value specifying the name of the storage slot to use + /// A cancellation token to signal the cancellation of the operation. Specifying this parameter will override any default cancellations such as due to timeouts () from being applied. + /// A representing the completion of the operation. + ValueTask GetItemAsStringAsync(string key, CancellationToken cancellationToken = default); - /// - /// Return the name of the key at the specified . - /// - /// - /// A representing the completion of the operation. - ValueTask KeyAsync(int index, CancellationToken? cancellationToken = null); + /// + /// Return the name of the key at the specified . + /// + /// + /// A cancellation token to signal the cancellation of the operation. Specifying this parameter will override any default cancellations such as due to timeouts () from being applied. + /// A representing the completion of the operation. + ValueTask KeyAsync(int index, CancellationToken cancellationToken = default); + + /// + /// Returns a collection of strings representing the names of the keys in the Session storage. + /// + /// A cancellation token to signal the cancellation of the operation. Specifying this parameter will override any default cancellations such as due to timeouts () from being applied. + /// A representing the completion of the operation. + ValueTask> KeysAsync(CancellationToken cancellationToken = default); - /// - /// Checks if the exists in session storage, but does not check its value. - /// - /// A value specifying the name of the storage slot to use - /// A representing the completion of the operation. - ValueTask ContainKeyAsync(string key, CancellationToken? cancellationToken = null); + /// + /// Checks if the exists in session storage, but does not check its value. + /// + /// A value specifying the name of the storage slot to use + /// A cancellation token to signal the cancellation of the operation. Specifying this parameter will override any default cancellations such as due to timeouts () from being applied. + /// A representing the completion of the operation. + ValueTask ContainKeyAsync(string key, CancellationToken cancellationToken = default); - /// - /// The number of items stored in session storage. - /// - /// A representing the completion of the operation. - ValueTask LengthAsync(CancellationToken? cancellationToken = null); + /// + /// The number of items stored in session storage. + /// + /// A cancellation token to signal the cancellation of the operation. Specifying this parameter will override any default cancellations such as due to timeouts () from being applied. + /// A representing the completion of the operation. + ValueTask LengthAsync(CancellationToken cancellationToken = default); - /// - /// Remove the data with the specified . - /// - /// A value specifying the name of the storage slot to use - /// A representing the completion of the operation. - ValueTask RemoveItemAsync(string key, CancellationToken? cancellationToken = null); + /// + /// Remove the data with the specified . + /// + /// A value specifying the name of the storage slot to use + /// A cancellation token to signal the cancellation of the operation. Specifying this parameter will override any default cancellations such as due to timeouts () from being applied. + /// A representing the completion of the operation. + ValueTask RemoveItemAsync(string key, CancellationToken cancellationToken = default); + + /// + /// Removes a collection of . + /// + /// A IEnumerable collection of strings specifying the name of the storage slot to remove + /// A cancellation token to signal the cancellation of the operation. Specifying this parameter will override any default cancellations such as due to timeouts () from being applied. + /// A representing the completion of the operation. + ValueTask RemoveItemsAsync(IEnumerable keys, CancellationToken cancellationToken = default); - /// - /// Sets or updates the in session storage with the specified . - /// - /// A value specifying the name of the storage slot to use - /// The data to be saved - /// A representing the completion of the operation. - ValueTask SetItemAsync(string key, T data, CancellationToken? cancellationToken = null); + /// + /// Sets or updates the in session storage with the specified . + /// + /// A value specifying the name of the storage slot to use + /// The data to be saved + /// A cancellation token to signal the cancellation of the operation. Specifying this parameter will override any default cancellations such as due to timeouts () from being applied. + /// A representing the completion of the operation. + ValueTask SetItemAsync(string key, T data, CancellationToken cancellationToken = default); - /// - /// Sets or updates the in session storage with the specified . Does not serialize the value before storing. - /// - /// A value specifying the name of the storage slot to use - /// The string to be saved - /// - ValueTask SetItemAsStringAsync(string key, string data, CancellationToken? cancellationToken = null); + /// + /// Sets or updates the in session storage with the specified . Does not serialize the value before storing. + /// + /// A value specifying the name of the storage slot to use + /// The string to be saved + /// A cancellation token to signal the cancellation of the operation. Specifying this parameter will override any default cancellations such as due to timeouts () from being applied. + /// A representing the completion of the operation. + ValueTask SetItemAsStringAsync(string key, string data, CancellationToken cancellationToken = default); - event EventHandler Changing; - event EventHandler Changed; - } + event EventHandler Changing; + event EventHandler Changed; } diff --git a/src/Blazored.SessionStorage/IStorageProvider.cs b/src/Blazored.SessionStorage/IStorageProvider.cs index df476de..0bd2c7f 100644 --- a/src/Blazored.SessionStorage/IStorageProvider.cs +++ b/src/Blazored.SessionStorage/IStorageProvider.cs @@ -1,23 +1,26 @@ +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; -namespace Blazored.SessionStorage +namespace Blazored.SessionStorage; + +internal interface IStorageProvider { - internal interface IStorageProvider - { - void Clear(); - ValueTask ClearAsync(CancellationToken? cancellationToken = null); - bool ContainKey(string key); - ValueTask ContainKeyAsync(string key, CancellationToken? cancellationToken = null); - string GetItem(string key); - ValueTask GetItemAsync(string key, CancellationToken? cancellationToken = null); - string Key(int index); - ValueTask KeyAsync(int index, CancellationToken? cancellationToken = null); - int Length(); - ValueTask LengthAsync(CancellationToken? cancellationToken = null); - void RemoveItem(string key); - ValueTask RemoveItemAsync(string key, CancellationToken? cancellationToken = null); - void SetItem(string key, string data); - ValueTask SetItemAsync(string key, string data, CancellationToken? cancellationToken = null); - } + void Clear(); + ValueTask ClearAsync(CancellationToken cancellationToken = default); + bool ContainKey(string key); + ValueTask ContainKeyAsync(string key, CancellationToken cancellationToken = default); + string GetItem(string key); + ValueTask GetItemAsync(string key, CancellationToken cancellationToken = default); + string Key(int index); + ValueTask KeyAsync(int index, CancellationToken cancellationToken = default); + IEnumerable Keys(); + ValueTask> KeysAsync(CancellationToken cancellationToken = default); + int Length(); + ValueTask LengthAsync(CancellationToken cancellationToken = default); + void RemoveItem(string key); + ValueTask RemoveItemAsync(string key, CancellationToken cancellationToken = default); + ValueTask RemoveItemsAsync(IEnumerable keys, CancellationToken cancellationToken = default); + void SetItem(string key, string data); + ValueTask SetItemAsync(string key, string data, CancellationToken cancellationToken = default); } diff --git a/src/Blazored.SessionStorage/ISyncSessionStorageService.cs b/src/Blazored.SessionStorage/ISyncSessionStorageService.cs index 0017e89..d972a1a 100644 --- a/src/Blazored.SessionStorage/ISyncSessionStorageService.cs +++ b/src/Blazored.SessionStorage/ISyncSessionStorageService.cs @@ -1,70 +1,82 @@ using System; +using System.Collections.Generic; -namespace Blazored.SessionStorage +namespace Blazored.SessionStorage; + +public interface ISyncSessionStorageService { - public interface ISyncSessionStorageService - { - /// - /// Clears all data from session storage. - /// - void Clear(); + /// + /// Clears all data from session storage. + /// + void Clear(); - /// - /// Retrieve the specified data from session storage as a . - /// - /// A value specifying the name of the session storage slot to use - /// The data from the specified as a - T GetItem(string key); + /// + /// Retrieve the specified data from session storage as a . + /// + /// A value specifying the name of the session storage slot to use + /// The data from the specified as a + T GetItem(string key); - /// - /// Retrieve the specified data from session storage as a . - /// - /// A value specifying the name of the storage slot to use - /// The data associated with the specified as a - string GetItemAsString(string key); + /// + /// Retrieve the specified data from session storage as a . + /// + /// A value specifying the name of the storage slot to use + /// The data associated with the specified as a + string GetItemAsString(string key); - /// - /// Return the name of the key at the specified . - /// - /// - /// The name of the key at the specified - string Key(int index); + /// + /// Return the name of the key at the specified . + /// + /// + /// The name of the key at the specified + string Key(int index); + + /// + /// Get the keys of all items stored in session storage. + /// + /// The keys of all items stored in session storage + IEnumerable Keys(); - /// - /// Checks if the exists in session storage, but does not check its value. - /// - /// A value specifying the name of the storage slot to use - /// Boolean indicating if the specified exists - bool ContainKey(string key); + /// + /// Checks if the exists in session storage, but does not check its value. + /// + /// A value specifying the name of the storage slot to use + /// Boolean indicating if the specified exists + bool ContainKey(string key); - /// - /// The number of items stored in session storage. - /// - /// The number of items stored in session storage - int Length(); + /// + /// The number of items stored in session storage. + /// + /// The number of items stored in session storage + int Length(); - /// - /// Remove the data with the specified . - /// - /// A value specifying the name of the storage slot to use - void RemoveItem(string key); + /// + /// Remove the data with the specified . + /// + /// A value specifying the name of the storage slot to use + void RemoveItem(string key); + + /// + /// Removes a collection of . + /// + /// A IEnumerable collection of strings specifying the name of the storage slot to remove + void RemoveItems(IEnumerable keys); - /// - /// Sets or updates the in session storage with the specified . - /// - /// A value specifying the name of the storage slot to use - /// The data to be saved - void SetItem(string key, T data); + /// + /// Sets or updates the in session storage with the specified . + /// + /// A value specifying the name of the storage slot to use + /// The data to be saved + void SetItem(string key, T data); - /// - /// Sets or updates the in session storage with the specified . Does not serialize the value before storing. - /// - /// A value specifying the name of the storage slot to use - /// The string to be saved - /// - void SetItemAsString(string key, string data); + /// + /// Sets or updates the in session storage with the specified . Does not serialize the value before storing. + /// + /// A value specifying the name of the storage slot to use + /// The string to be saved + /// + void SetItemAsString(string key, string data); - event EventHandler Changing; - event EventHandler Changed; - } + event EventHandler Changing; + event EventHandler Changed; } diff --git a/src/Blazored.SessionStorage/JsonConverters/TimespanJsonConverter.cs b/src/Blazored.SessionStorage/JsonConverters/TimespanJsonConverter.cs index b67e0a8..2a81538 100644 --- a/src/Blazored.SessionStorage/JsonConverters/TimespanJsonConverter.cs +++ b/src/Blazored.SessionStorage/JsonConverters/TimespanJsonConverter.cs @@ -5,39 +5,38 @@ using System.Text.Json.Serialization; using System.Text.RegularExpressions; -namespace Blazored.SessionStorage.JsonConverters +namespace Blazored.SessionStorage.JsonConverters; + +/// +/// The new Json.NET doesn't support Timespan at this time +/// https://github.com/dotnet/corefx/issues/38641 +/// +public class TimespanJsonConverter : JsonConverter { /// - /// The new Json.NET doesn't support Timespan at this time - /// https://github.com/dotnet/corefx/issues/38641 + /// Format: Days.Hours:Minutes:Seconds:Milliseconds /// - public class TimespanJsonConverter : JsonConverter - { - /// - /// Format: Days.Hours:Minutes:Seconds:Milliseconds - /// - public const string TimeSpanFormatString = @"d\.hh\:mm\:ss\:FFF"; + public const string TimeSpanFormatString = @"d\.hh\:mm\:ss\:FFF"; - public override TimeSpan Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override TimeSpan Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + var s = reader.GetString(); + if (string.IsNullOrWhiteSpace(s)) { - var s = reader.GetString(); - if (string.IsNullOrWhiteSpace(s)) - { - return TimeSpan.Zero; - } - - if (!TimeSpan.TryParseExact(s, TimeSpanFormatString, null, out var parsedTimeSpan)) - { - throw new FormatException($"Input timespan is not in an expected format : expected {Regex.Unescape(TimeSpanFormatString)}. Please retrieve this key as a string and parse manually."); - } - - return parsedTimeSpan; + return TimeSpan.Zero; } - public override void Write(Utf8JsonWriter writer, TimeSpan value, JsonSerializerOptions options) + if (!TimeSpan.TryParseExact(s, TimeSpanFormatString, null, out var parsedTimeSpan)) { - var timespanFormatted = $"{value.ToString(TimeSpanFormatString)}"; - writer.WriteStringValue(timespanFormatted); + throw new FormatException($"Input timespan is not in an expected format : expected {Regex.Unescape(TimeSpanFormatString)}. Please retrieve this key as a string and parse manually."); } + + return parsedTimeSpan; + } + + public override void Write(Utf8JsonWriter writer, TimeSpan value, JsonSerializerOptions options) + { + var timespanFormatted = $"{value.ToString(TimeSpanFormatString)}"; + writer.WriteStringValue(timespanFormatted); } } diff --git a/src/Blazored.SessionStorage/Serialization/IJsonSerializer.cs b/src/Blazored.SessionStorage/Serialization/IJsonSerializer.cs index 9bccf18..e1a99c5 100644 --- a/src/Blazored.SessionStorage/Serialization/IJsonSerializer.cs +++ b/src/Blazored.SessionStorage/Serialization/IJsonSerializer.cs @@ -1,8 +1,7 @@ -namespace Blazored.SessionStorage.Serialization +namespace Blazored.SessionStorage.Serialization; + +public interface IJsonSerializer { - public interface IJsonSerializer - { - string Serialize(T obj); - T Deserialize(string text); - } + string Serialize(T obj); + T Deserialize(string text); } diff --git a/src/Blazored.SessionStorage/Serialization/SystemTextJsonSerializer.cs b/src/Blazored.SessionStorage/Serialization/SystemTextJsonSerializer.cs index 5ce56c0..a4b893f 100644 --- a/src/Blazored.SessionStorage/Serialization/SystemTextJsonSerializer.cs +++ b/src/Blazored.SessionStorage/Serialization/SystemTextJsonSerializer.cs @@ -2,26 +2,25 @@ using Microsoft.Extensions.Options; using System.Text.Json; -namespace Blazored.SessionStorage.Serialization +namespace Blazored.SessionStorage.Serialization; + +internal class SystemTextJsonSerializer : IJsonSerializer { - internal class SystemTextJsonSerializer : IJsonSerializer - { - private readonly JsonSerializerOptions _options; + private readonly JsonSerializerOptions _options; - public SystemTextJsonSerializer(IOptions options) - { - _options = options.Value.JsonSerializerOptions; - } + public SystemTextJsonSerializer(IOptions options) + { + _options = options.Value.JsonSerializerOptions; + } - public SystemTextJsonSerializer(SessionStorageOptions sessionStorageOptions) - { - _options = sessionStorageOptions.JsonSerializerOptions; - } + public SystemTextJsonSerializer(SessionStorageOptions sessionStorageOptions) + { + _options = sessionStorageOptions.JsonSerializerOptions; + } - public T Deserialize(string data) - => JsonSerializer.Deserialize(data, _options); + public T Deserialize(string data) + => JsonSerializer.Deserialize(data, _options); - public string Serialize(T data) - => JsonSerializer.Serialize(data, _options); - } -} + public string Serialize(T data) + => JsonSerializer.Serialize(data, _options); +} \ No newline at end of file diff --git a/src/Blazored.SessionStorage/ServiceCollectionExtensions.cs b/src/Blazored.SessionStorage/ServiceCollectionExtensions.cs index 9b1e2bf..795a92c 100644 --- a/src/Blazored.SessionStorage/ServiceCollectionExtensions.cs +++ b/src/Blazored.SessionStorage/ServiceCollectionExtensions.cs @@ -5,26 +5,54 @@ using Blazored.SessionStorage.StorageOptions; using Microsoft.Extensions.DependencyInjection; -namespace Blazored.SessionStorage +namespace Blazored.SessionStorage; + +[ExcludeFromCodeCoverage] +public static class ServiceCollectionExtensions { - [ExcludeFromCodeCoverage] - public static class ServiceCollectionExtensions - { - public static IServiceCollection AddBlazoredSessionStorage(this IServiceCollection services) - => AddBlazoredSessionStorage(services, null); + public static IServiceCollection AddBlazoredSessionStorage(this IServiceCollection services) + => AddBlazoredSessionStorage(services, null); - public static IServiceCollection AddBlazoredSessionStorage(this IServiceCollection services, Action configure) - { - return services - .AddScoped() - .AddScoped() - .AddScoped() - .AddScoped() - .Configure(configureOptions => - { - configure?.Invoke(configureOptions); - configureOptions.JsonSerializerOptions.Converters.Add(new TimespanJsonConverter()); - }); - } + public static IServiceCollection AddBlazoredSessionStorage(this IServiceCollection services, Action configure) + { + return services + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .Configure(configureOptions => + { + configure?.Invoke(configureOptions); + configureOptions.JsonSerializerOptions.Converters.Add(new TimespanJsonConverter()); + }); + } + + /// + /// Registers the Blazored SessionStorage services as singletons. This should only be used in Blazor WebAssembly applications. + /// Using this in Blazor Server applications will cause unexpected and potentially dangerous behaviour. + /// + /// + public static IServiceCollection AddBlazoredSessionStorageAsSingleton(this IServiceCollection services) + => AddBlazoredSessionStorageAsSingleton(services, null); + + /// + /// Registers the Blazored SessionStorage services as singletons. This should only be used in Blazor WebAssembly applications. + /// Using this in Blazor Server applications will cause unexpected and potentially dangerous behaviour. + /// + /// + /// + /// + public static IServiceCollection AddBlazoredSessionStorageAsSingleton(this IServiceCollection services, Action configure) + { + return services + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .Configure(configureOptions => + { + configure?.Invoke(configureOptions); + configureOptions.JsonSerializerOptions.Converters.Add(new TimespanJsonConverter()); + }); } } diff --git a/src/Blazored.SessionStorage/SessionStorageService.cs b/src/Blazored.SessionStorage/SessionStorageService.cs index d020994..c9b429d 100644 --- a/src/Blazored.SessionStorage/SessionStorageService.cs +++ b/src/Blazored.SessionStorage/SessionStorageService.cs @@ -1,269 +1,289 @@ using System; +using System.Collections.Generic; using System.Text.Json; using System.Threading; using System.Threading.Tasks; using Blazored.SessionStorage.Serialization; -namespace Blazored.SessionStorage +namespace Blazored.SessionStorage; + +internal class SessionStorageService : ISessionStorageService, ISyncSessionStorageService { - internal class SessionStorageService : ISessionStorageService, ISyncSessionStorageService + private readonly IStorageProvider _storageProvider; + private readonly IJsonSerializer _serializer; + + public SessionStorageService(IStorageProvider storageProvider, IJsonSerializer serializer) { - private readonly IStorageProvider _storageProvider; - private readonly IJsonSerializer _serializer; + _storageProvider = storageProvider; + _serializer = serializer; + } - public SessionStorageService(IStorageProvider storageProvider, IJsonSerializer serializer) - { - _storageProvider = storageProvider; - _serializer = serializer; - } + public ValueTask RemoveItemsAsync(IEnumerable keys, CancellationToken cancellationToken = default) + => _storageProvider.RemoveItemsAsync(keys, cancellationToken); - public async ValueTask SetItemAsync(string key, T data, CancellationToken? cancellationToken = null) - { - if (string.IsNullOrWhiteSpace(key)) - throw new ArgumentNullException(nameof(key)); + public async ValueTask SetItemAsync(string key, T data, CancellationToken cancellationToken = default) + { + if (string.IsNullOrWhiteSpace(key)) + throw new ArgumentNullException(nameof(key)); - var e = await RaiseOnChangingAsync(key, data).ConfigureAwait(false); + var e = await RaiseOnChangingAsync(key, data).ConfigureAwait(false); - if (e.Cancel) - return; + if (e.Cancel) + return; - var serialisedData = _serializer.Serialize(data); - await _storageProvider.SetItemAsync(key, serialisedData, cancellationToken).ConfigureAwait(false); + var serialisedData = _serializer.Serialize(data); + await _storageProvider.SetItemAsync(key, serialisedData, cancellationToken).ConfigureAwait(false); - RaiseOnChanged(key, e.OldValue, data); - } + RaiseOnChanged(key, e.OldValue, data); + } - public async ValueTask SetItemAsStringAsync(string key, string data, CancellationToken? cancellationToken = null) - { - if (string.IsNullOrWhiteSpace(key)) - throw new ArgumentNullException(nameof(key)); + public async ValueTask SetItemAsStringAsync(string key, string data, CancellationToken cancellationToken = default) + { + if (string.IsNullOrWhiteSpace(key)) + throw new ArgumentNullException(nameof(key)); - if (data is null) - throw new ArgumentNullException(nameof(data)); + if (data is null) + throw new ArgumentNullException(nameof(data)); - var e = await RaiseOnChangingAsync(key, data).ConfigureAwait(false); + var e = await RaiseOnChangingAsync(key, data).ConfigureAwait(false); - if (e.Cancel) - return; + if (e.Cancel) + return; - await _storageProvider.SetItemAsync(key, data, cancellationToken).ConfigureAwait(false); + await _storageProvider.SetItemAsync(key, data, cancellationToken).ConfigureAwait(false); - RaiseOnChanged(key, e.OldValue, data); - } + RaiseOnChanged(key, e.OldValue, data); + } + + public async ValueTask GetItemAsync(string key, CancellationToken cancellationToken = default) + { + if (string.IsNullOrWhiteSpace(key)) + throw new ArgumentNullException(nameof(key)); - public async ValueTask GetItemAsync(string key, CancellationToken? cancellationToken = null) + var serialisedData = await _storageProvider.GetItemAsync(key, cancellationToken).ConfigureAwait(false); + + if (string.IsNullOrWhiteSpace(serialisedData)) + return default; + + try { - if (string.IsNullOrWhiteSpace(key)) - throw new ArgumentNullException(nameof(key)); - - var serialisedData = await _storageProvider.GetItemAsync(key, cancellationToken).ConfigureAwait(false); - - if (string.IsNullOrWhiteSpace(serialisedData)) - return default; - - try - { - return _serializer.Deserialize(serialisedData); - } - catch (JsonException e) when (e.Path == "$" && typeof(T) == typeof(string)) - { - // For backward compatibility return the plain string. - // On the next save a correct value will be stored and this Exception will not happen again, for this 'key' - return (T)(object)serialisedData; - } + return _serializer.Deserialize(serialisedData); } - - public ValueTask GetItemAsStringAsync(string key, CancellationToken? cancellationToken = null) + catch (JsonException e) when (e.Path == "$" && typeof(T) == typeof(string)) { - if (string.IsNullOrWhiteSpace(key)) - throw new ArgumentNullException(nameof(key)); - - return _storageProvider.GetItemAsync(key, cancellationToken); + // For backward compatibility return the plain string. + // On the next save a correct value will be stored and this Exception will not happen again, for this 'key' + return (T)(object)serialisedData; } + } - public ValueTask RemoveItemAsync(string key, CancellationToken? cancellationToken = null) - { - if (string.IsNullOrWhiteSpace(key)) - throw new ArgumentNullException(nameof(key)); + public ValueTask GetItemAsStringAsync(string key, CancellationToken cancellationToken = default) + { + if (string.IsNullOrWhiteSpace(key)) + throw new ArgumentNullException(nameof(key)); - return _storageProvider.RemoveItemAsync(key, cancellationToken); - } + return _storageProvider.GetItemAsync(key, cancellationToken); + } - public ValueTask ClearAsync(CancellationToken? cancellationToken = null) - => _storageProvider.ClearAsync(cancellationToken); + public ValueTask RemoveItemAsync(string key, CancellationToken cancellationToken = default) + { + if (string.IsNullOrWhiteSpace(key)) + throw new ArgumentNullException(nameof(key)); - public ValueTask LengthAsync(CancellationToken? cancellationToken = null) - => _storageProvider.LengthAsync(cancellationToken); + return _storageProvider.RemoveItemAsync(key, cancellationToken); + } - public ValueTask KeyAsync(int index, CancellationToken? cancellationToken = null) - => _storageProvider.KeyAsync(index, cancellationToken); + public ValueTask ClearAsync(CancellationToken cancellationToken = default) + => _storageProvider.ClearAsync(cancellationToken); - public ValueTask ContainKeyAsync(string key, CancellationToken? cancellationToken = null) - => _storageProvider.ContainKeyAsync(key, cancellationToken); + public ValueTask LengthAsync(CancellationToken cancellationToken = default) + => _storageProvider.LengthAsync(cancellationToken); - public void SetItem(string key, T data) - { - if (string.IsNullOrWhiteSpace(key)) - throw new ArgumentNullException(nameof(key)); + public ValueTask KeyAsync(int index, CancellationToken cancellationToken = default) + => _storageProvider.KeyAsync(index, cancellationToken); - var e = RaiseOnChangingSync(key, data); + public ValueTask> KeysAsync(CancellationToken cancellationToken = default) + => _storageProvider.KeysAsync(cancellationToken); - if (e.Cancel) - return; + public ValueTask ContainKeyAsync(string key, CancellationToken cancellationToken = default) + => _storageProvider.ContainKeyAsync(key, cancellationToken); - var serialisedData = _serializer.Serialize(data); - _storageProvider.SetItem(key, serialisedData); + public void SetItem(string key, T data) + { + if (string.IsNullOrWhiteSpace(key)) + throw new ArgumentNullException(nameof(key)); - RaiseOnChanged(key, e.OldValue, data); - } + var e = RaiseOnChangingSync(key, data); - public void SetItemAsString(string key, string data) - { - if (string.IsNullOrWhiteSpace(key)) - throw new ArgumentNullException(nameof(key)); + if (e.Cancel) + return; - if (data is null) - throw new ArgumentNullException(nameof(data)); + var serialisedData = _serializer.Serialize(data); + _storageProvider.SetItem(key, serialisedData); - var e = RaiseOnChangingSync(key, data); + RaiseOnChanged(key, e.OldValue, data); + } - if (e.Cancel) - return; + public void SetItemAsString(string key, string data) + { + if (string.IsNullOrWhiteSpace(key)) + throw new ArgumentNullException(nameof(key)); - _storageProvider.SetItem(key, data); + if (data is null) + throw new ArgumentNullException(nameof(data)); - RaiseOnChanged(key, e.OldValue, data); - } + var e = RaiseOnChangingSync(key, data); + + if (e.Cancel) + return; + + _storageProvider.SetItem(key, data); + + RaiseOnChanged(key, e.OldValue, data); + } + + public T GetItem(string key) + { + if (string.IsNullOrWhiteSpace(key)) + throw new ArgumentNullException(nameof(key)); - public T GetItem(string key) + var serialisedData = _storageProvider.GetItem(key); + + if (string.IsNullOrWhiteSpace(serialisedData)) + return default; + + try { - if (string.IsNullOrWhiteSpace(key)) - throw new ArgumentNullException(nameof(key)); - - var serialisedData = _storageProvider.GetItem(key); - - if (string.IsNullOrWhiteSpace(serialisedData)) - return default; - - try - { - return _serializer.Deserialize(serialisedData); - } - catch (JsonException e) when (e.Path == "$" && typeof(T) == typeof(string)) - { - // For backward compatibility return the plain string. - // On the next save a correct value will be stored and this Exception will not happen again, for this 'key' - return (T)(object)serialisedData; - } + return _serializer.Deserialize(serialisedData); } - - public string GetItemAsString(string key) + catch (JsonException e) when (e.Path == "$" && typeof(T) == typeof(string)) { - if (string.IsNullOrWhiteSpace(key)) - throw new ArgumentNullException(nameof(key)); - - return _storageProvider.GetItem(key); + // For backward compatibility return the plain string. + // On the next save a correct value will be stored and this Exception will not happen again, for this 'key' + return (T)(object)serialisedData; } + } - public void RemoveItem(string key) - { - if (string.IsNullOrWhiteSpace(key)) - throw new ArgumentNullException(nameof(key)); + public string GetItemAsString(string key) + { + if (string.IsNullOrWhiteSpace(key)) + throw new ArgumentNullException(nameof(key)); + return _storageProvider.GetItem(key); + } + + public void RemoveItem(string key) + { + if (string.IsNullOrWhiteSpace(key)) + throw new ArgumentNullException(nameof(key)); + + _storageProvider.RemoveItem(key); + } + + public void RemoveItems(IEnumerable keys) + { + if (keys == null) + throw new ArgumentNullException(nameof(keys)); + + foreach (var key in keys) + { _storageProvider.RemoveItem(key); } + } - public void Clear() - => _storageProvider.Clear(); + public void Clear() + => _storageProvider.Clear(); - public int Length() - => _storageProvider.Length(); + public int Length() + => _storageProvider.Length(); - public string Key(int index) - => _storageProvider.Key(index); + public string Key(int index) + => _storageProvider.Key(index); + + public IEnumerable Keys() + => _storageProvider.Keys(); - public bool ContainKey(string key) - => _storageProvider.ContainKey(key); + public bool ContainKey(string key) + => _storageProvider.ContainKey(key); - public event EventHandler Changing; - private async Task RaiseOnChangingAsync(string key, object data) + public event EventHandler Changing; + private async Task RaiseOnChangingAsync(string key, object data) + { + var e = new ChangingEventArgs { - var e = new ChangingEventArgs - { - Key = key, - OldValue = await GetItemInternalAsync(key).ConfigureAwait(false), - NewValue = data - }; + Key = key, + OldValue = await GetItemInternalAsync(key).ConfigureAwait(false), + NewValue = data + }; - Changing?.Invoke(this, e); + Changing?.Invoke(this, e); - return e; - } + return e; + } - private ChangingEventArgs RaiseOnChangingSync(string key, object data) + private ChangingEventArgs RaiseOnChangingSync(string key, object data) + { + var e = new ChangingEventArgs { - var e = new ChangingEventArgs - { - Key = key, - OldValue = GetItemInternal(key), - NewValue = data - }; + Key = key, + OldValue = GetItemInternal(key), + NewValue = data + }; - Changing?.Invoke(this, e); + Changing?.Invoke(this, e); - return e; - } + return e; + } + + private async Task GetItemInternalAsync(string key) + { + if (string.IsNullOrEmpty(key)) + throw new ArgumentNullException(nameof(key)); - private async Task GetItemInternalAsync(string key) + var serialisedData = await _storageProvider.GetItemAsync(key).ConfigureAwait(false); + + if (string.IsNullOrWhiteSpace(serialisedData)) + return default; + try { - if (string.IsNullOrEmpty(key)) - throw new ArgumentNullException(nameof(key)); - - var serialisedData = await _storageProvider.GetItemAsync(key).ConfigureAwait(false); - - if (string.IsNullOrWhiteSpace(serialisedData)) - return default; - try - { - return _serializer.Deserialize(serialisedData); - } - catch (JsonException) - { - return (T)(object)serialisedData; - } + return _serializer.Deserialize(serialisedData); } - - private object GetItemInternal(string key) + catch (JsonException) { - if (string.IsNullOrEmpty(key)) - throw new ArgumentNullException(nameof(key)); - - var serialisedData = _storageProvider.GetItem(key); - - if (string.IsNullOrWhiteSpace(serialisedData)) - return default; - - try - { - return _serializer.Deserialize(serialisedData); - } - catch (JsonException) - { - return serialisedData; - } + return (T)(object)serialisedData; } + } + + private object GetItemInternal(string key) + { + if (string.IsNullOrEmpty(key)) + throw new ArgumentNullException(nameof(key)); - public event EventHandler Changed; - private void RaiseOnChanged(string key, object oldValue, object data) + var serialisedData = _storageProvider.GetItem(key); + + if (string.IsNullOrWhiteSpace(serialisedData)) + return default; + + try { - var e = new ChangedEventArgs - { - Key = key, - OldValue = oldValue, - NewValue = data - }; - - Changed?.Invoke(this, e); + return _serializer.Deserialize(serialisedData); } + catch (JsonException) + { + return serialisedData; + } + } + + public event EventHandler Changed; + private void RaiseOnChanged(string key, object oldValue, object data) + { + var e = new ChangedEventArgs + { + Key = key, + OldValue = oldValue, + NewValue = data + }; + + Changed?.Invoke(this, e); } } diff --git a/src/Blazored.SessionStorage/StorageOptions/LocalStorageOptions.cs b/src/Blazored.SessionStorage/StorageOptions/LocalStorageOptions.cs deleted file mode 100644 index 509f1f0..0000000 --- a/src/Blazored.SessionStorage/StorageOptions/LocalStorageOptions.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Text.Json; - -namespace Blazored.SessionStorage.StorageOptions -{ - public class SessionStorageOptions - { - public JsonSerializerOptions JsonSerializerOptions { get; } = new JsonSerializerOptions(); - } -} diff --git a/src/Blazored.SessionStorage/StorageOptions/SessionStorageOptions.cs b/src/Blazored.SessionStorage/StorageOptions/SessionStorageOptions.cs new file mode 100644 index 0000000..2156750 --- /dev/null +++ b/src/Blazored.SessionStorage/StorageOptions/SessionStorageOptions.cs @@ -0,0 +1,8 @@ +using System.Text.Json; + +namespace Blazored.SessionStorage.StorageOptions; + +public class SessionStorageOptions +{ + public JsonSerializerOptions JsonSerializerOptions { get; } = new(); +} diff --git a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/Clear.cs b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/Clear.cs index a7c8331..4b68577 100644 --- a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/Clear.cs +++ b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/Clear.cs @@ -8,49 +8,48 @@ using Moq; using Xunit; -namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests +namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests; + +public class Clear { - public class Clear - { - private readonly SessionStorageService _sut; - private readonly IStorageProvider _storageProvider; + private readonly SessionStorageService _sut; + private readonly IStorageProvider _storageProvider; - public Clear() - { - var mockOptions = new Mock>(); - var jsonOptions = new JsonSerializerOptions(); - jsonOptions.Converters.Add(new TimespanJsonConverter()); - mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); - IJsonSerializer serializer = new SystemTextJsonSerializer(mockOptions.Object); - _storageProvider = new InMemoryStorageProvider(); - _sut = new SessionStorageService(_storageProvider, serializer); - } + public Clear() + { + var mockOptions = new Mock>(); + var jsonOptions = new JsonSerializerOptions(); + jsonOptions.Converters.Add(new TimespanJsonConverter()); + mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); + IJsonSerializer serializer = new SystemTextJsonSerializer(mockOptions.Object); + _storageProvider = new InMemoryStorageProvider(); + _sut = new SessionStorageService(_storageProvider, serializer); + } - [Fact] - public void ClearsAnyItemsInTheStore() - { - // Arrange - var item1 = new TestObject(1, "Jane Smith"); - var item2 = new TestObject(2, "John Smith"); + [Fact] + public void ClearsAnyItemsInTheStore() + { + // Arrange + var item1 = new TestObject(1, "Jane Smith"); + var item2 = new TestObject(2, "John Smith"); - _sut.SetItem("Item1", item1); - _sut.SetItem("Item2", item2); + _sut.SetItem("Item1", item1); + _sut.SetItem("Item2", item2); - // Act - _sut.Clear(); + // Act + _sut.Clear(); - // Assert - Assert.Equal(0, _storageProvider.Length()); - } + // Assert + Assert.Equal(0, _storageProvider.Length()); + } - [Fact] - public void DoesNothingWhenStoreIsEmpty() - { - // Act - _sut.Clear(); + [Fact] + public void DoesNothingWhenStoreIsEmpty() + { + // Act + _sut.Clear(); - // Assert - Assert.Equal(0, _storageProvider.Length()); - } + // Assert + Assert.Equal(0, _storageProvider.Length()); } -} +} \ No newline at end of file diff --git a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/ClearAsync.cs b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/ClearAsync.cs index 69a71e4..3c39ac9 100644 --- a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/ClearAsync.cs +++ b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/ClearAsync.cs @@ -9,49 +9,48 @@ using Moq; using Xunit; -namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests +namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests; + +public class ClearAsync { - public class ClearAsync - { - private readonly SessionStorageService _sut; - private readonly IStorageProvider _storageProvider; + private readonly SessionStorageService _sut; + private readonly IStorageProvider _storageProvider; - public ClearAsync() - { - var mockOptions = new Mock>(); - var jsonOptions = new JsonSerializerOptions(); - jsonOptions.Converters.Add(new TimespanJsonConverter()); - mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); - IJsonSerializer serializer = new SystemTextJsonSerializer(mockOptions.Object); - _storageProvider = new InMemoryStorageProvider(); - _sut = new SessionStorageService(_storageProvider, serializer); - } + public ClearAsync() + { + var mockOptions = new Mock>(); + var jsonOptions = new JsonSerializerOptions(); + jsonOptions.Converters.Add(new TimespanJsonConverter()); + mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); + IJsonSerializer serializer = new SystemTextJsonSerializer(mockOptions.Object); + _storageProvider = new InMemoryStorageProvider(); + _sut = new SessionStorageService(_storageProvider, serializer); + } - [Fact] - public async Task ClearsAnyItemsInTheStore() - { - // Arrange - var item1 = new TestObject(1, "Jane Smith"); - var item2 = new TestObject(2, "John Smith"); + [Fact] + public async Task ClearsAnyItemsInTheStore() + { + // Arrange + var item1 = new TestObject(1, "Jane Smith"); + var item2 = new TestObject(2, "John Smith"); - await _sut.SetItemAsync("Item1", item1); - await _sut.SetItemAsync("Item2", item2); + await _sut.SetItemAsync("Item1", item1); + await _sut.SetItemAsync("Item2", item2); - // Act - await _sut.ClearAsync(); + // Act + await _sut.ClearAsync(); - // Assert - Assert.Equal(0, await _storageProvider.LengthAsync()); - } + // Assert + Assert.Equal(0, await _storageProvider.LengthAsync()); + } - [Fact] - public async Task DoesNothingWhenItemDoesNotExistInStore() - { - // Act - await _sut.ClearAsync(); + [Fact] + public async Task DoesNothingWhenItemDoesNotExistInStore() + { + // Act + await _sut.ClearAsync(); - // Assert - Assert.Equal(0, await _storageProvider.LengthAsync()); - } + // Assert + Assert.Equal(0, await _storageProvider.LengthAsync()); } -} +} \ No newline at end of file diff --git a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/ContainsKey.cs b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/ContainsKey.cs index b09f482..81b67ab 100644 --- a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/ContainsKey.cs +++ b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/ContainsKey.cs @@ -8,49 +8,48 @@ using Moq; using Xunit; -namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests +namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests; + +public class ContainsKey { - public class ContainsKey - { - private readonly SessionStorageService _sut; + private readonly SessionStorageService _sut; - public ContainsKey() - { - var mockOptions = new Mock>(); - var jsonOptions = new JsonSerializerOptions(); - jsonOptions.Converters.Add(new TimespanJsonConverter()); - mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); - IJsonSerializer serializer = new SystemTextJsonSerializer(mockOptions.Object); - IStorageProvider storageProvider = new InMemoryStorageProvider(); - _sut = new SessionStorageService(storageProvider, serializer); - } + public ContainsKey() + { + var mockOptions = new Mock>(); + var jsonOptions = new JsonSerializerOptions(); + jsonOptions.Converters.Add(new TimespanJsonConverter()); + mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); + IJsonSerializer serializer = new SystemTextJsonSerializer(mockOptions.Object); + IStorageProvider storageProvider = new InMemoryStorageProvider(); + _sut = new SessionStorageService(storageProvider, serializer); + } - [Fact] - public void ReturnsTrue_When_KeyExistsInStore() - { - // Arrange - const string key = "TestKey"; - var item1 = new TestObject(1, "Jane Smith"); - _sut.SetItem(key, item1); + [Fact] + public void ReturnsTrue_When_KeyExistsInStore() + { + // Arrange + const string key = "TestKey"; + var item1 = new TestObject(1, "Jane Smith"); + _sut.SetItem(key, item1); - // Act - var containsKey = _sut.ContainKey(key); + // Act + var containsKey = _sut.ContainKey(key); - // Assert - Assert.True(containsKey); - } + // Assert + Assert.True(containsKey); + } - [Fact] - public void ReturnsFalse_When_KeyDoesNotExistsInStore() - { - // Arrange - const string key = "TestKey"; + [Fact] + public void ReturnsFalse_When_KeyDoesNotExistsInStore() + { + // Arrange + const string key = "TestKey"; - // Act - var containsKey = _sut.ContainKey(key); + // Act + var containsKey = _sut.ContainKey(key); - // Assert - Assert.False(containsKey); - } + // Assert + Assert.False(containsKey); } -} +} \ No newline at end of file diff --git a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/ContainsKeyAsync.cs b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/ContainsKeyAsync.cs index c2a9cc4..74c65de 100644 --- a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/ContainsKeyAsync.cs +++ b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/ContainsKeyAsync.cs @@ -9,49 +9,48 @@ using Moq; using Xunit; -namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests +namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests; + +public class ContainsKeyAsync { - public class ContainsKeyAsync - { - private readonly SessionStorageService _sut; + private readonly SessionStorageService _sut; - public ContainsKeyAsync() - { - var mockOptions = new Mock>(); - var jsonOptions = new JsonSerializerOptions(); - jsonOptions.Converters.Add(new TimespanJsonConverter()); - mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); - IJsonSerializer serializer = new SystemTextJsonSerializer(mockOptions.Object); - IStorageProvider storageProvider = new InMemoryStorageProvider(); - _sut = new SessionStorageService(storageProvider, serializer); - } + public ContainsKeyAsync() + { + var mockOptions = new Mock>(); + var jsonOptions = new JsonSerializerOptions(); + jsonOptions.Converters.Add(new TimespanJsonConverter()); + mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); + IJsonSerializer serializer = new SystemTextJsonSerializer(mockOptions.Object); + IStorageProvider storageProvider = new InMemoryStorageProvider(); + _sut = new SessionStorageService(storageProvider, serializer); + } - [Fact] - public async Task ReturnsTrue_When_KeyExistsInStore() - { - // Arrange - const string key = "TestKey"; - var item1 = new TestObject(1, "Jane Smith"); - await _sut.SetItemAsync(key, item1); + [Fact] + public async Task ReturnsTrue_When_KeyExistsInStore() + { + // Arrange + const string key = "TestKey"; + var item1 = new TestObject(1, "Jane Smith"); + await _sut.SetItemAsync(key, item1); - // Act - var containsKey = await _sut.ContainKeyAsync(key); + // Act + var containsKey = await _sut.ContainKeyAsync(key); - // Assert - Assert.True(containsKey); - } + // Assert + Assert.True(containsKey); + } - [Fact] - public async Task ReturnsFalse_When_KeyDoesNotExistsInStore() - { - // Arrange - const string key = "TestKey"; + [Fact] + public async Task ReturnsFalse_When_KeyDoesNotExistsInStore() + { + // Arrange + const string key = "TestKey"; - // Act - var containsKey = await _sut.ContainKeyAsync(key); + // Act + var containsKey = await _sut.ContainKeyAsync(key); - // Assert - Assert.False(containsKey); - } + // Assert + Assert.False(containsKey); } -} +} \ No newline at end of file diff --git a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/GetItem.cs b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/GetItem.cs index 6052294..ee957a0 100644 --- a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/GetItem.cs +++ b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/GetItem.cs @@ -9,97 +9,96 @@ using Moq; using Xunit; -namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests +namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests; + +public class GetItem { - public class GetItem - { - private readonly SessionStorageService _sut; - private readonly IStorageProvider _storageProvider; - private readonly IJsonSerializer _serializer; + private readonly SessionStorageService _sut; + private readonly IStorageProvider _storageProvider; + private readonly IJsonSerializer _serializer; - private const string Key = "testKey"; + private const string Key = "testKey"; - public GetItem() - { - var mockOptions = new Mock>(); - var jsonOptions = new JsonSerializerOptions(); - jsonOptions.Converters.Add(new TimespanJsonConverter()); - mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); - _serializer = new SystemTextJsonSerializer(mockOptions.Object); - _storageProvider = new InMemoryStorageProvider(); - _sut = new SessionStorageService(_storageProvider, _serializer); - } + public GetItem() + { + var mockOptions = new Mock>(); + var jsonOptions = new JsonSerializerOptions(); + jsonOptions.Converters.Add(new TimespanJsonConverter()); + mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); + _serializer = new SystemTextJsonSerializer(mockOptions.Object); + _storageProvider = new InMemoryStorageProvider(); + _sut = new SessionStorageService(_storageProvider, _serializer); + } - [Theory] - [InlineData("")] - [InlineData(" ")] - [InlineData(null)] - public void ThrowsArgumentNullException_When_KeyIsInvalid(string key) - { - // arrange / act - var action = new Action(() => _sut.GetItem(key)); + [Theory] + [InlineData("")] + [InlineData(" ")] + [InlineData(null)] + public void ThrowsArgumentNullException_When_KeyIsInvalid(string key) + { + // arrange / act + var action = new Action(() => _sut.GetItem(key)); - // assert - Assert.Throws(action); - } + // assert + Assert.Throws(action); + } - [Theory] - [InlineData("Item1", "stringTest")] - [InlineData("Item2", 11)] - [InlineData("Item3", 11.11)] - public void ReturnsDeserializedDataFromStore(string key, T data) - { - // Arrange - _sut.SetItem(key, data); + [Theory] + [InlineData("Item1", "stringTest")] + [InlineData("Item2", 11)] + [InlineData("Item3", 11.11)] + public void ReturnsDeserializedDataFromStore(string key, T data) + { + // Arrange + _sut.SetItem(key, data); - // Act - var result = _sut.GetItem(key); + // Act + var result = _sut.GetItem(key); - // Assert - Assert.Equal(data, result); - } + // Assert + Assert.Equal(data, result); + } - [Fact] - public void ReturnsComplexObjectFromStore() - { - // Arrange - var objectToSave = new TestObject(2, "Jane Smith"); - _sut.SetItem(Key, objectToSave); + [Fact] + public void ReturnsComplexObjectFromStore() + { + // Arrange + var objectToSave = new TestObject(2, "Jane Smith"); + _sut.SetItem(Key, objectToSave); - // Act - var result = _sut.GetItem(Key); + // Act + var result = _sut.GetItem(Key); - // Assert - Assert.Equal(objectToSave.Id, result.Id); - Assert.Equal(objectToSave.Name, result.Name); - } + // Assert + Assert.Equal(objectToSave.Id, result.Id); + Assert.Equal(objectToSave.Name, result.Name); + } - [Fact] - public void ReturnsNullFromStore_When_NullValueSaved() - { - // Arrange - var valueToSave = (string)null; - _sut.SetItem(Key, valueToSave); + [Fact] + public void ReturnsNullFromStore_When_NullValueSaved() + { + // Arrange + var valueToSave = (string)null; + _sut.SetItem(Key, valueToSave); - // Act - var result = _sut.GetItem(Key); + // Act + var result = _sut.GetItem(Key); - // Assert - Assert.Null(result); - } + // Assert + Assert.Null(result); + } - [Fact] - public void ReturnsStringFromStore_When_JsonExceptionIsThrown() - { - // Arrange - var jsonData = "[{ id: 5, name: \"Jane Smith\"}]"; - _storageProvider.SetItem(Key, jsonData); + [Fact] + public void ReturnsStringFromStore_When_JsonExceptionIsThrown() + { + // Arrange + var jsonData = "[{ id: 5, name: \"Jane Smith\"}]"; + _storageProvider.SetItem(Key, jsonData); - // Act - var result = _sut.GetItem(Key); + // Act + var result = _sut.GetItem(Key); - // Assert - Assert.Equal(jsonData, result); - } + // Assert + Assert.Equal(jsonData, result); } -} +} \ No newline at end of file diff --git a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/GetItemAsString.cs b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/GetItemAsString.cs index 253ed78..92f985a 100644 --- a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/GetItemAsString.cs +++ b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/GetItemAsString.cs @@ -9,70 +9,69 @@ using Moq; using Xunit; -namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests +namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests; + +public class GetItemAsString { - public class GetItemAsString - { - private readonly SessionStorageService _sut; - private readonly IStorageProvider _storageProvider; - private readonly IJsonSerializer _serializer; + private readonly SessionStorageService _sut; + private readonly IStorageProvider _storageProvider; + private readonly IJsonSerializer _serializer; - private const string Key = "testKey"; + private const string Key = "testKey"; - public GetItemAsString() - { - var mockOptions = new Mock>(); - var jsonOptions = new JsonSerializerOptions(); - jsonOptions.Converters.Add(new TimespanJsonConverter()); - mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); - _serializer = new SystemTextJsonSerializer(mockOptions.Object); - _storageProvider = new InMemoryStorageProvider(); - _sut = new SessionStorageService(_storageProvider, _serializer); - } + public GetItemAsString() + { + var mockOptions = new Mock>(); + var jsonOptions = new JsonSerializerOptions(); + jsonOptions.Converters.Add(new TimespanJsonConverter()); + mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); + _serializer = new SystemTextJsonSerializer(mockOptions.Object); + _storageProvider = new InMemoryStorageProvider(); + _sut = new SessionStorageService(_storageProvider, _serializer); + } - [Theory] - [InlineData("")] - [InlineData(" ")] - [InlineData(null)] - public void ThrowsArgumentNullException_When_KeyIsInvalid(string key) - { - // arrange / act - var action = new Action(() => _sut.GetItemAsString(key)); + [Theory] + [InlineData("")] + [InlineData(" ")] + [InlineData(null)] + public void ThrowsArgumentNullException_When_KeyIsInvalid(string key) + { + // arrange / act + var action = new Action(() => _sut.GetItemAsString(key)); - // assert - Assert.Throws(action); - } + // assert + Assert.Throws(action); + } - [Theory] - [InlineData("Item1", "stringTest")] - [InlineData("Item2", 11)] - [InlineData("Item3", 11.11)] - public void ReturnsDeserializedDataFromStore(string key, T data) - { - // Arrange - _sut.SetItem(key, data); + [Theory] + [InlineData("Item1", "stringTest")] + [InlineData("Item2", 11)] + [InlineData("Item3", 11.11)] + public void ReturnsDeserializedDataFromStore(string key, T data) + { + // Arrange + _sut.SetItem(key, data); - // Act - var result = _sut.GetItemAsString(key); + // Act + var result = _sut.GetItemAsString(key); - // Assert - var serializedData = _serializer.Serialize(data); - Assert.Equal(serializedData, result); - } + // Assert + var serializedData = _serializer.Serialize(data); + Assert.Equal(serializedData, result); + } - [Fact] - public void ReturnsComplexObjectFromStore() - { - // Arrange - var objectToSave = new TestObject(2, "Jane Smith"); - _sut.SetItem(Key, objectToSave); + [Fact] + public void ReturnsComplexObjectFromStore() + { + // Arrange + var objectToSave = new TestObject(2, "Jane Smith"); + _sut.SetItem(Key, objectToSave); - // Act - var result = _sut.GetItemAsString(Key); + // Act + var result = _sut.GetItemAsString(Key); - // Assert - var serializedData = _serializer.Serialize(objectToSave); - Assert.Equal(serializedData, result); - } + // Assert + var serializedData = _serializer.Serialize(objectToSave); + Assert.Equal(serializedData, result); } -} +} \ No newline at end of file diff --git a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/GetItemAsStringAsync.cs b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/GetItemAsStringAsync.cs index 9a7b3d7..a3dedb7 100644 --- a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/GetItemAsStringAsync.cs +++ b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/GetItemAsStringAsync.cs @@ -10,70 +10,69 @@ using Moq; using Xunit; -namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests +namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests; + +public class GetItemAsStringAsync { - public class GetItemAsStringAsync - { - private readonly SessionStorageService _sut; - private readonly IStorageProvider _storageProvider; - private readonly IJsonSerializer _serializer; + private readonly SessionStorageService _sut; + private readonly IStorageProvider _storageProvider; + private readonly IJsonSerializer _serializer; - private const string Key = "testKey"; + private const string Key = "testKey"; - public GetItemAsStringAsync() - { - var mockOptions = new Mock>(); - var jsonOptions = new JsonSerializerOptions(); - jsonOptions.Converters.Add(new TimespanJsonConverter()); - mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); - _serializer = new SystemTextJsonSerializer(mockOptions.Object); - _storageProvider = new InMemoryStorageProvider(); - _sut = new SessionStorageService(_storageProvider, _serializer); - } + public GetItemAsStringAsync() + { + var mockOptions = new Mock>(); + var jsonOptions = new JsonSerializerOptions(); + jsonOptions.Converters.Add(new TimespanJsonConverter()); + mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); + _serializer = new SystemTextJsonSerializer(mockOptions.Object); + _storageProvider = new InMemoryStorageProvider(); + _sut = new SessionStorageService(_storageProvider, _serializer); + } - [Theory] - [InlineData("")] - [InlineData(" ")] - [InlineData(null)] - public void ThrowsArgumentNullException_When_KeyIsInvalid(string key) - { - // arrange / act - var action = new Func(async () => await _sut.GetItemAsStringAsync(key)); + [Theory] + [InlineData("")] + [InlineData(" ")] + [InlineData(null)] + public void ThrowsArgumentNullException_When_KeyIsInvalid(string key) + { + // arrange / act + var action = new Func(async () => await _sut.GetItemAsStringAsync(key)); - // assert - Assert.ThrowsAsync(action); - } + // assert + Assert.ThrowsAsync(action); + } - [Theory] - [InlineData("Item1", "stringTest")] - [InlineData("Item2", 11)] - [InlineData("Item3", 11.11)] - public async Task ReturnsDeserializedDataFromStore(string key, T data) - { - // Arrange - await _sut.SetItemAsync(key, data); + [Theory] + [InlineData("Item1", "stringTest")] + [InlineData("Item2", 11)] + [InlineData("Item3", 11.11)] + public async Task ReturnsDeserializedDataFromStore(string key, T data) + { + // Arrange + await _sut.SetItemAsync(key, data); - // Act - var result = await _sut.GetItemAsStringAsync(key); + // Act + var result = await _sut.GetItemAsStringAsync(key); - // Assert - var serializedData = _serializer.Serialize(data); - Assert.Equal(serializedData, result); - } + // Assert + var serializedData = _serializer.Serialize(data); + Assert.Equal(serializedData, result); + } - [Fact] - public async Task ReturnsComplexObjectFromStore() - { - // Arrange - var objectToSave = new TestObject(2, "Jane Smith"); - await _sut.SetItemAsync(Key, objectToSave); + [Fact] + public async Task ReturnsComplexObjectFromStore() + { + // Arrange + var objectToSave = new TestObject(2, "Jane Smith"); + await _sut.SetItemAsync(Key, objectToSave); - // Act - var result = await _sut.GetItemAsStringAsync(Key); + // Act + var result = await _sut.GetItemAsStringAsync(Key); - // Assert - var serializedData = _serializer.Serialize(objectToSave); - Assert.Equal(serializedData, result); - } + // Assert + var serializedData = _serializer.Serialize(objectToSave); + Assert.Equal(serializedData, result); } -} +} \ No newline at end of file diff --git a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/GetItemAsync.cs b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/GetItemAsync.cs index cba032e..67de73f 100644 --- a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/GetItemAsync.cs +++ b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/GetItemAsync.cs @@ -10,97 +10,96 @@ using Moq; using Xunit; -namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests +namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests; + +public class GetItemAsync { - public class GetItemAsync - { - private readonly SessionStorageService _sut; - private readonly IStorageProvider _storageProvider; - private readonly IJsonSerializer _serializer; + private readonly SessionStorageService _sut; + private readonly IStorageProvider _storageProvider; + private readonly IJsonSerializer _serializer; - private const string Key = "testKey"; + private const string Key = "testKey"; - public GetItemAsync() - { - var mockOptions = new Mock>(); - var jsonOptions = new JsonSerializerOptions(); - jsonOptions.Converters.Add(new TimespanJsonConverter()); - mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); - _serializer = new SystemTextJsonSerializer(mockOptions.Object); - _storageProvider = new InMemoryStorageProvider(); - _sut = new SessionStorageService(_storageProvider, _serializer); - } + public GetItemAsync() + { + var mockOptions = new Mock>(); + var jsonOptions = new JsonSerializerOptions(); + jsonOptions.Converters.Add(new TimespanJsonConverter()); + mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); + _serializer = new SystemTextJsonSerializer(mockOptions.Object); + _storageProvider = new InMemoryStorageProvider(); + _sut = new SessionStorageService(_storageProvider, _serializer); + } - [Theory] - [InlineData("")] - [InlineData(" ")] - [InlineData(null)] - public void ThrowsArgumentNullException_When_KeyIsInvalid(string key) - { - // arrange / act - var action = new Func(async () => await _sut.GetItemAsync(key)); + [Theory] + [InlineData("")] + [InlineData(" ")] + [InlineData(null)] + public void ThrowsArgumentNullException_When_KeyIsInvalid(string key) + { + // arrange / act + var action = new Func(async () => await _sut.GetItemAsync(key)); - // assert - Assert.ThrowsAsync(action); - } + // assert + Assert.ThrowsAsync(action); + } - [Theory] - [InlineData("Item1", "stringTest")] - [InlineData("Item2", 11)] - [InlineData("Item3", 11.11)] - public async Task ReturnsDeserializedDataFromStore(string key, T data) - { - // Arrange - await _sut.SetItemAsync(key, data); + [Theory] + [InlineData("Item1", "stringTest")] + [InlineData("Item2", 11)] + [InlineData("Item3", 11.11)] + public async Task ReturnsDeserializedDataFromStore(string key, T data) + { + // Arrange + await _sut.SetItemAsync(key, data); - // Act - var result = await _sut.GetItemAsync(key); + // Act + var result = await _sut.GetItemAsync(key); - // Assert - Assert.Equal(data, result); - } + // Assert + Assert.Equal(data, result); + } - [Fact] - public async Task ReturnsComplexObjectFromStore() - { - // Arrange - var objectToSave = new TestObject(2, "Jane Smith"); - await _sut.SetItemAsync(Key, objectToSave); + [Fact] + public async Task ReturnsComplexObjectFromStore() + { + // Arrange + var objectToSave = new TestObject(2, "Jane Smith"); + await _sut.SetItemAsync(Key, objectToSave); - // Act - var result = await _sut.GetItemAsync(Key); + // Act + var result = await _sut.GetItemAsync(Key); - // Assert - Assert.Equal(objectToSave.Id, result.Id); - Assert.Equal(objectToSave.Name, result.Name); - } + // Assert + Assert.Equal(objectToSave.Id, result.Id); + Assert.Equal(objectToSave.Name, result.Name); + } - [Fact] - public async Task ReturnsNullFromStore_When_NullValueSaved() - { - // Arrange - var valueToSave = (string)null; - await _sut.SetItemAsync(Key, valueToSave); + [Fact] + public async Task ReturnsNullFromStore_When_NullValueSaved() + { + // Arrange + var valueToSave = (string)null; + await _sut.SetItemAsync(Key, valueToSave); - // Act - var result = await _sut.GetItemAsync(Key); + // Act + var result = await _sut.GetItemAsync(Key); - // Assert - Assert.Null(result); - } + // Assert + Assert.Null(result); + } - [Fact] - public async Task ReturnsStringFromStore_When_JsonExceptionIsThrown() - { - // Arrange - var valueToSave = "[{ id: 5, name: \"Jane Smith\"}]"; - await _storageProvider.SetItemAsync(Key, valueToSave); + [Fact] + public async Task ReturnsStringFromStore_When_JsonExceptionIsThrown() + { + // Arrange + var valueToSave = "[{ id: 5, name: \"Jane Smith\"}]"; + await _storageProvider.SetItemAsync(Key, valueToSave); - // Act - var result = await _sut.GetItemAsync(Key); + // Act + var result = await _sut.GetItemAsync(Key); - // Assert - Assert.Equal(valueToSave, result); - } + // Assert + Assert.Equal(valueToSave, result); } -} +} \ No newline at end of file diff --git a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/Key.cs b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/Key.cs index 5082df1..ac8cba3 100644 --- a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/Key.cs +++ b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/Key.cs @@ -8,55 +8,54 @@ using Moq; using Xunit; -namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests +namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests; + +public class Key { - public class Key - { - private readonly SessionStorageService _sut; + private readonly SessionStorageService _sut; - public Key() - { - var mockOptions = new Mock>(); - var jsonOptions = new JsonSerializerOptions(); - jsonOptions.Converters.Add(new TimespanJsonConverter()); - mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); - IJsonSerializer serializer = new SystemTextJsonSerializer(mockOptions.Object); - IStorageProvider storageProvider = new InMemoryStorageProvider(); - _sut = new SessionStorageService(storageProvider, serializer); - } + public Key() + { + var mockOptions = new Mock>(); + var jsonOptions = new JsonSerializerOptions(); + jsonOptions.Converters.Add(new TimespanJsonConverter()); + mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); + IJsonSerializer serializer = new SystemTextJsonSerializer(mockOptions.Object); + IStorageProvider storageProvider = new InMemoryStorageProvider(); + _sut = new SessionStorageService(storageProvider, serializer); + } - [Fact] - public void ReturnsNameOfKeyAtIndex_When_KeyExistsInStore() - { - // Arrange - const string key1 = "TestKey1"; - const string key2 = "TestKey2"; + [Fact] + public void ReturnsNameOfKeyAtIndex_When_KeyExistsInStore() + { + // Arrange + const string key1 = "TestKey1"; + const string key2 = "TestKey2"; - var item1 = new TestObject(1, "Jane Smith"); - var item2 = new TestObject(2, "John Smith"); + var item1 = new TestObject(1, "Jane Smith"); + var item2 = new TestObject(2, "John Smith"); - _sut.SetItem(key1, item1); - _sut.SetItem(key2, item2); + _sut.SetItem(key1, item1); + _sut.SetItem(key2, item2); - // Act - var keyName = _sut.Key(1); + // Act + var keyName = _sut.Key(1); - // Assert - Assert.Equal(key2, keyName); - } + // Assert + Assert.Equal(key2, keyName); + } - [Fact] - public void ReturnsNull_When_KeyDoesNotExistInStore() - { - // Arrange - var item1 = new TestObject(1, "Jane Smith"); - _sut.SetItem("TestKey1", item1); + [Fact] + public void ReturnsNull_When_KeyDoesNotExistInStore() + { + // Arrange + var item1 = new TestObject(1, "Jane Smith"); + _sut.SetItem("TestKey1", item1); - // Act - var keyName = _sut.Key(1); + // Act + var keyName = _sut.Key(1); - // Assert - Assert.Null(keyName); - } + // Assert + Assert.Null(keyName); } -} +} \ No newline at end of file diff --git a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/KeyAsync.cs b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/KeyAsync.cs index 86dec29..0ec8a92 100644 --- a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/KeyAsync.cs +++ b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/KeyAsync.cs @@ -9,55 +9,54 @@ using Moq; using Xunit; -namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests +namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests; + +public class KeyAsync { - public class KeyAsync - { - private readonly SessionStorageService _sut; + private readonly SessionStorageService _sut; - public KeyAsync() - { - var mockOptions = new Mock>(); - var jsonOptions = new JsonSerializerOptions(); - jsonOptions.Converters.Add(new TimespanJsonConverter()); - mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); - IJsonSerializer serializer = new SystemTextJsonSerializer(mockOptions.Object); - IStorageProvider storageProvider = new InMemoryStorageProvider(); - _sut = new SessionStorageService(storageProvider, serializer); - } + public KeyAsync() + { + var mockOptions = new Mock>(); + var jsonOptions = new JsonSerializerOptions(); + jsonOptions.Converters.Add(new TimespanJsonConverter()); + mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); + IJsonSerializer serializer = new SystemTextJsonSerializer(mockOptions.Object); + IStorageProvider storageProvider = new InMemoryStorageProvider(); + _sut = new SessionStorageService(storageProvider, serializer); + } - [Fact] - public async Task ReturnsNameOfKeyAtIndex_When_KeyExistsInStore() - { - // Arrange - const string key1 = "TestKey1"; - const string key2 = "TestKey2"; + [Fact] + public async Task ReturnsNameOfKeyAtIndex_When_KeyExistsInStore() + { + // Arrange + const string key1 = "TestKey1"; + const string key2 = "TestKey2"; - var item1 = new TestObject(1, "Jane Smith"); - var item2 = new TestObject(2, "John Smith"); + var item1 = new TestObject(1, "Jane Smith"); + var item2 = new TestObject(2, "John Smith"); - await _sut.SetItemAsync(key1, item1); - await _sut.SetItemAsync(key2, item2); + await _sut.SetItemAsync(key1, item1); + await _sut.SetItemAsync(key2, item2); - // Act - var keyName = await _sut.KeyAsync(1); + // Act + var keyName = await _sut.KeyAsync(1); - // Assert - Assert.Equal(key2, keyName); - } + // Assert + Assert.Equal(key2, keyName); + } - [Fact] - public async Task ReturnsNull_When_KeyDoesNotExistInStore() - { - // Arrange - var item1 = new TestObject(1, "Jane Smith"); - await _sut.SetItemAsync("TestKey1", item1); + [Fact] + public async Task ReturnsNull_When_KeyDoesNotExistInStore() + { + // Arrange + var item1 = new TestObject(1, "Jane Smith"); + await _sut.SetItemAsync("TestKey1", item1); - // Act - var keyName = await _sut.KeyAsync(1); + // Act + var keyName = await _sut.KeyAsync(1); - // Assert - Assert.Null(keyName); - } + // Assert + Assert.Null(keyName); } -} +} \ No newline at end of file diff --git a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/Keys.cs b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/Keys.cs new file mode 100644 index 0000000..d243c19 --- /dev/null +++ b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/Keys.cs @@ -0,0 +1,153 @@ +using System.Linq; +using System.Text.Json; +using Blazored.SessionStorage.JsonConverters; +using Blazored.SessionStorage.Serialization; +using Blazored.SessionStorage.StorageOptions; +using Blazored.SessionStorage.TestExtensions; +using Blazored.SessionStorage.Tests.TestAssets; +using Microsoft.Extensions.Options; +using Moq; +using Xunit; + +namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests; + +public class Keys + { + private readonly SessionStorageService _sut; + + public Keys() + { + var mockOptions = new Mock>(); + var jsonOptions = new JsonSerializerOptions(); + jsonOptions.Converters.Add(new TimespanJsonConverter()); + mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); + IJsonSerializer serializer = new SystemTextJsonSerializer(mockOptions.Object); + IStorageProvider storageProvider = new InMemoryStorageProvider(); + + _sut = new SessionStorageService(storageProvider, serializer); + } + + [Fact] + public void ReturnsKeysAsync() + { + // Arrange + const string key1 = "TestKey1"; + const string key2 = "TestKey2"; + _sut.Clear(); + + var item1 = new TestObject(1, "Jane Smith"); + var item2 = new TestObject(2, "John Smith"); + + _sut.SetItem(key1, item1); + _sut.SetItem(key2, item2); + + // Act + var keyNames = _sut.KeysAsync().Result.ToList(); + + // Assert + Assert.Collection(keyNames, + item => Assert.Equal(key1, item), + item => Assert.Equal(key2, item)); + } + + [Fact] + public void ReturnsKeys() + { + // Arrange + const string key1 = "TestKey1"; + const string key2 = "TestKey2"; + _sut.Clear(); + + var item1 = new TestObject(1, "Jane Smith"); + var item2 = new TestObject(2, "John Smith"); + + _sut.SetItem(key1, item1); + _sut.SetItem(key2, item2); + + // Act + var keyNames = _sut.Keys().ToList(); + + // Assert + Assert.Collection(keyNames, + item => Assert.Equal(key1, item), + item => Assert.Equal(key2, item)); + } + + [Fact] + public void ReturnsEmptyWhenCollectionEmptyAsync() + { + // Arrange + _sut.Clear(); + + // Act + var keyNames = _sut.KeysAsync().Result; + + // Assert + Assert.Empty(keyNames); + } + + [Fact] + public void ReturnsEmptyWhenCollectionEmpty() + { + // Arrange + _sut.Clear(); + + // Act + var keyNames = _sut.Keys(); + + // Assert + Assert.Empty(keyNames); + } + + [Fact] + public void RemoveKeysAsync() + { + // Arrange + const string key1 = "TestKey1"; + const string key2 = "TestKey2"; + const string key3 = "TestKey3"; + _sut.Clear(); + + var item1 = new TestObject(1, "Jane Smith"); + var item2 = new TestObject(2, "John Smith"); + var item3 = new TestObject(3, "Jade Smith"); + + _sut.SetItem(key1, item1); + _sut.SetItem(key2, item2); + _sut.SetItem(key3, item3); + + // Act + var keyNames = new[] { key1, key2 }; + _sut.RemoveItemsAsync(keyNames).AsTask().Wait(); + + // Assert + Assert.Equal(1, _sut.Length()); + Assert.NotNull(_sut.GetItem(key3)); + } + + [Fact] + public void RemoveKeys() + { + // Arrange + const string key1 = "TestKey1"; + const string key2 = "TestKey2"; + const string key3 = "TestKey3"; + _sut.Clear(); + + var item1 = new TestObject(1, "Jane Smith"); + var item2 = new TestObject(2, "John Smith"); + var item3 = new TestObject(3, "Jade Smith"); + + _sut.SetItem(key1, item1); + _sut.SetItem(key2, item2); + _sut.SetItem(key3, item3); + + // Act + var keyNames = new[] { key1, key2 }; + _sut.RemoveItems(keyNames); + + // Assert + Assert.Equal(1, _sut.Length()); + Assert.NotNull(_sut.GetItem(key3)); + } + } diff --git a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/Length.cs b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/Length.cs index 94d189d..aaecf4e 100644 --- a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/Length.cs +++ b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/Length.cs @@ -8,48 +8,47 @@ using Moq; using Xunit; -namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests +namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests; + +public class Length { - public class Length + private readonly SessionStorageService _sut; + + public Length() + { + var mockOptions = new Mock>(); + var jsonOptions = new JsonSerializerOptions(); + jsonOptions.Converters.Add(new TimespanJsonConverter()); + mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); + IJsonSerializer serializer = new SystemTextJsonSerializer(mockOptions.Object); + IStorageProvider storageProvider = new InMemoryStorageProvider(); + _sut = new SessionStorageService(storageProvider, serializer); + } + + [Fact] + public void ReturnsZeroWhenStoreIsEmpty() + { + // Act + var itemCount = _sut.Length(); + + // Assert + Assert.Equal(0, itemCount); + } + + [Fact] + public void ReturnsNumberOfItemsInStore() { - private readonly SessionStorageService _sut; - - public Length() - { - var mockOptions = new Mock>(); - var jsonOptions = new JsonSerializerOptions(); - jsonOptions.Converters.Add(new TimespanJsonConverter()); - mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); - IJsonSerializer serializer = new SystemTextJsonSerializer(mockOptions.Object); - IStorageProvider storageProvider = new InMemoryStorageProvider(); - _sut = new SessionStorageService(storageProvider, serializer); - } - - [Fact] - public void ReturnsZeroWhenStoreIsEmpty() - { - // Act - var itemCount = _sut.Length(); - - // Assert - Assert.Equal(0, itemCount); - } - - [Fact] - public void ReturnsNumberOfItemsInStore() - { - // Arrange - var item1 = new TestObject(1, "Jane Smith"); - var item2 = new TestObject(2, "John Smith"); + // Arrange + var item1 = new TestObject(1, "Jane Smith"); + var item2 = new TestObject(2, "John Smith"); - _sut.SetItem("Item1", item1); - _sut.SetItem("Item2", item2); + _sut.SetItem("Item1", item1); + _sut.SetItem("Item2", item2); - // Act - var itemCount = _sut.Length(); + // Act + var itemCount = _sut.Length(); - // Assert - Assert.Equal(2, itemCount); - } + // Assert + Assert.Equal(2, itemCount); } -} +} \ No newline at end of file diff --git a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/LengthAsync.cs b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/LengthAsync.cs index 6cc547e..700780d 100644 --- a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/LengthAsync.cs +++ b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/LengthAsync.cs @@ -9,48 +9,47 @@ using Moq; using Xunit; -namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests +namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests; + +public class LengthAsync { - public class LengthAsync + private readonly SessionStorageService _sut; + + public LengthAsync() + { + var mockOptions = new Mock>(); + var jsonOptions = new JsonSerializerOptions(); + jsonOptions.Converters.Add(new TimespanJsonConverter()); + mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); + IJsonSerializer serializer = new SystemTextJsonSerializer(mockOptions.Object); + IStorageProvider storageProvider = new InMemoryStorageProvider(); + _sut = new SessionStorageService(storageProvider, serializer); + } + + [Fact] + public async Task ReturnsZeroWhenStoreIsEmpty() + { + // Act + var itemCount = await _sut.LengthAsync(); + + // Assert + Assert.Equal(0, itemCount); + } + + [Fact] + public async Task ReturnsNumberOfItemsInStore() { - private readonly SessionStorageService _sut; - - public LengthAsync() - { - var mockOptions = new Mock>(); - var jsonOptions = new JsonSerializerOptions(); - jsonOptions.Converters.Add(new TimespanJsonConverter()); - mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); - IJsonSerializer serializer = new SystemTextJsonSerializer(mockOptions.Object); - IStorageProvider storageProvider = new InMemoryStorageProvider(); - _sut = new SessionStorageService(storageProvider, serializer); - } - - [Fact] - public async Task ReturnsZeroWhenStoreIsEmpty() - { - // Act - var itemCount = await _sut.LengthAsync(); - - // Assert - Assert.Equal(0, itemCount); - } - - [Fact] - public async Task ReturnsNumberOfItemsInStore() - { - // Arrange - var item1 = new TestObject(1, "Jane Smith"); - var item2 = new TestObject(2, "John Smith"); + // Arrange + var item1 = new TestObject(1, "Jane Smith"); + var item2 = new TestObject(2, "John Smith"); - await _sut.SetItemAsync("Item1", item1); - await _sut.SetItemAsync("Item2", item2); + await _sut.SetItemAsync("Item1", item1); + await _sut.SetItemAsync("Item2", item2); - // Act - var itemCount = await _sut.LengthAsync(); + // Act + var itemCount = await _sut.LengthAsync(); - // Assert - Assert.Equal(2, itemCount); - } + // Assert + Assert.Equal(2, itemCount); } -} +} \ No newline at end of file diff --git a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/RemoveItem.cs b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/RemoveItem.cs index bc088d4..1433b44 100644 --- a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/RemoveItem.cs +++ b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/RemoveItem.cs @@ -9,61 +9,60 @@ using Moq; using Xunit; -namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests +namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests; + +public class RemoveItem { - public class RemoveItem - { - private readonly SessionStorageService _sut; - private readonly IStorageProvider _storageProvider; + private readonly SessionStorageService _sut; + private readonly IStorageProvider _storageProvider; - private const string Key = "testKey"; + private const string Key = "testKey"; - public RemoveItem() - { - var mockOptions = new Mock>(); - var jsonOptions = new JsonSerializerOptions(); - jsonOptions.Converters.Add(new TimespanJsonConverter()); - mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); - IJsonSerializer serializer = new SystemTextJsonSerializer(mockOptions.Object); - _storageProvider = new InMemoryStorageProvider(); - _sut = new SessionStorageService(_storageProvider, serializer); - } + public RemoveItem() + { + var mockOptions = new Mock>(); + var jsonOptions = new JsonSerializerOptions(); + jsonOptions.Converters.Add(new TimespanJsonConverter()); + mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); + IJsonSerializer serializer = new SystemTextJsonSerializer(mockOptions.Object); + _storageProvider = new InMemoryStorageProvider(); + _sut = new SessionStorageService(_storageProvider, serializer); + } - [Theory] - [InlineData("")] - [InlineData(" ")] - [InlineData(null)] - public void ThrowsArgumentNullException_When_KeyIsInvalid(string key) - { - // arrange / act - var action = new Action(() => _sut.RemoveItem(key)); + [Theory] + [InlineData("")] + [InlineData(" ")] + [InlineData(null)] + public void ThrowsArgumentNullException_When_KeyIsInvalid(string key) + { + // arrange / act + var action = new Action(() => _sut.RemoveItem(key)); - // assert - Assert.Throws(action); - } + // assert + Assert.Throws(action); + } - [Fact] - public void RemovesItemFromStoreIfExists() - { - // Arrange - var data = new TestObject(2, "Jane Smith"); - _sut.SetItem(Key, data); + [Fact] + public void RemovesItemFromStoreIfExists() + { + // Arrange + var data = new TestObject(2, "Jane Smith"); + _sut.SetItem(Key, data); - // Act - _sut.RemoveItem(Key); + // Act + _sut.RemoveItem(Key); - // Assert - Assert.Equal(0, _storageProvider.Length()); - } + // Assert + Assert.Equal(0, _storageProvider.Length()); + } - [Fact] - public void DoesNothingWhenItemDoesNotExistInStore() - { - // Act - _sut.RemoveItem(Key); + [Fact] + public void DoesNothingWhenItemDoesNotExistInStore() + { + // Act + _sut.RemoveItem(Key); - // Assert - Assert.Equal(0, _storageProvider.Length()); - } + // Assert + Assert.Equal(0, _storageProvider.Length()); } -} +} \ No newline at end of file diff --git a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/RemoveItemAsync.cs b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/RemoveItemAsync.cs index 56f27c4..cd138ee 100644 --- a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/RemoveItemAsync.cs +++ b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/RemoveItemAsync.cs @@ -10,61 +10,60 @@ using Moq; using Xunit; -namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests +namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests; + +public class RemoveItemAsync { - public class RemoveItemAsync - { - private readonly SessionStorageService _sut; - private readonly IStorageProvider _storageProvider; + private readonly SessionStorageService _sut; + private readonly IStorageProvider _storageProvider; - private const string Key = "testKey"; + private const string Key = "testKey"; - public RemoveItemAsync() - { - var mockOptions = new Mock>(); - var jsonOptions = new JsonSerializerOptions(); - jsonOptions.Converters.Add(new TimespanJsonConverter()); - mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); - IJsonSerializer serializer = new SystemTextJsonSerializer(mockOptions.Object); - _storageProvider = new InMemoryStorageProvider(); - _sut = new SessionStorageService(_storageProvider, serializer); - } + public RemoveItemAsync() + { + var mockOptions = new Mock>(); + var jsonOptions = new JsonSerializerOptions(); + jsonOptions.Converters.Add(new TimespanJsonConverter()); + mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); + IJsonSerializer serializer = new SystemTextJsonSerializer(mockOptions.Object); + _storageProvider = new InMemoryStorageProvider(); + _sut = new SessionStorageService(_storageProvider, serializer); + } - [Theory] - [InlineData("")] - [InlineData(" ")] - [InlineData(null)] - public void ThrowsArgumentNullException_When_KeyIsInvalid(string key) - { - // arrange / act - var action = new Func(async () => await _sut.RemoveItemAsync(key)); + [Theory] + [InlineData("")] + [InlineData(" ")] + [InlineData(null)] + public void ThrowsArgumentNullException_When_KeyIsInvalid(string key) + { + // arrange / act + var action = new Func(async () => await _sut.RemoveItemAsync(key)); - // assert - Assert.ThrowsAsync(action); - } + // assert + Assert.ThrowsAsync(action); + } - [Fact] - public async Task RemovesItemFromStoreIfExists() - { - // Arrange - var data = new TestObject(2, "Jane Smith"); - await _sut.SetItemAsync(Key, data); + [Fact] + public async Task RemovesItemFromStoreIfExists() + { + // Arrange + var data = new TestObject(2, "Jane Smith"); + await _sut.SetItemAsync(Key, data); - // Act - await _sut.RemoveItemAsync(Key); + // Act + await _sut.RemoveItemAsync(Key); - // Assert - Assert.Equal(0, await _storageProvider.LengthAsync()); - } + // Assert + Assert.Equal(0, await _storageProvider.LengthAsync()); + } - [Fact] - public async Task DoesNothingWhenItemDoesNotExistInStore() - { - // Act - await _sut.RemoveItemAsync(Key); + [Fact] + public async Task DoesNothingWhenItemDoesNotExistInStore() + { + // Act + await _sut.RemoveItemAsync(Key); - // Assert - Assert.Equal(0, await _storageProvider.LengthAsync()); - } + // Assert + Assert.Equal(0, await _storageProvider.LengthAsync()); } -} +} \ No newline at end of file diff --git a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/SetItem.cs b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/SetItem.cs index f722851..48c3f92 100644 --- a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/SetItem.cs +++ b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/SetItem.cs @@ -9,226 +9,225 @@ using Moq; using Xunit; -namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests +namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests; + +public class SetItem { - public class SetItem + private readonly SessionStorageService _sut; + private readonly IStorageProvider _storageProvider; + private readonly IJsonSerializer _serializer; + + private const string Key = "testKey"; + + public SetItem() + { + var mockOptions = new Mock>(); + var jsonOptions = new JsonSerializerOptions(); + jsonOptions.Converters.Add(new TimespanJsonConverter()); + mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); + _serializer = new SystemTextJsonSerializer(mockOptions.Object); + _storageProvider = new InMemoryStorageProvider(); + _sut = new SessionStorageService(_storageProvider, _serializer); + } + + [Theory] + [InlineData("")] + [InlineData(" ")] + [InlineData(null)] + public void ThrowsArgumentNullException_When_KeyIsInvalid(string key) { - private readonly SessionStorageService _sut; - private readonly IStorageProvider _storageProvider; - private readonly IJsonSerializer _serializer; - - private const string Key = "testKey"; - - public SetItem() - { - var mockOptions = new Mock>(); - var jsonOptions = new JsonSerializerOptions(); - jsonOptions.Converters.Add(new TimespanJsonConverter()); - mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); - _serializer = new SystemTextJsonSerializer(mockOptions.Object); - _storageProvider = new InMemoryStorageProvider(); - _sut = new SessionStorageService(_storageProvider, _serializer); - } - - [Theory] - [InlineData("")] - [InlineData(" ")] - [InlineData(null)] - public void ThrowsArgumentNullException_When_KeyIsInvalid(string key) - { - // arrange / act - const string data = "Data"; - var action = new Action(() => _sut.SetItem(key, data)); - - // assert - Assert.Throws(action); - } - - [Fact] - public void RaisesOnChangingEvent_When_SavingNewData() - { - // arrange - var onChangingCalled = false; - _sut.Changing += (_, _) => onChangingCalled = true; - - // act - _sut.SetItem("Key", "Data"); - - // assert - Assert.True(onChangingCalled); - } + // arrange / act + const string data = "Data"; + var action = new Action(() => _sut.SetItem(key, data)); + + // assert + Assert.Throws(action); + } + + [Fact] + public void RaisesOnChangingEvent_When_SavingNewData() + { + // arrange + var onChangingCalled = false; + _sut.Changing += (_, _) => onChangingCalled = true; + + // act + _sut.SetItem("Key", "Data"); + + // assert + Assert.True(onChangingCalled); + } - [Fact] - public void OnChangingEventContainsEmptyOldValue_When_SavingData() - { - // arrange - var oldValue = ""; - _sut.Changing += (_, args) => oldValue = args.OldValue?.ToString(); - - // act - _sut.SetItem("Key", "Data"); - - // assert - Assert.Equal(default, oldValue); - } + [Fact] + public void OnChangingEventContainsEmptyOldValue_When_SavingData() + { + // arrange + var oldValue = ""; + _sut.Changing += (_, args) => oldValue = args.OldValue?.ToString(); + + // act + _sut.SetItem("Key", "Data"); + + // assert + Assert.Equal(default, oldValue); + } - [Fact] - public void OnChangingEventContainsNewValue_When_SavingNewData() - { - // arrange - const string data = "Data"; - var newValue = ""; - _sut.Changing += (_, args) => newValue = args.NewValue.ToString(); - - // act - _sut.SetItemAsync("Key", data); - - // assert - Assert.Equal(data, newValue); - } + [Fact] + public void OnChangingEventContainsNewValue_When_SavingNewData() + { + // arrange + const string data = "Data"; + var newValue = ""; + _sut.Changing += (_, args) => newValue = args.NewValue.ToString(); + + // act + _sut.SetItemAsync("Key", data); + + // assert + Assert.Equal(data, newValue); + } - [Fact] - public void OnChangingEventIsCancelled_When_SettingCancelToTrue_When_SavingNewData() - { - // arrange - _sut.Changing += (_, args) => args.Cancel = true; - - // act - _sut.SetItem("Key", "Data"); - - // assert - Assert.Equal(0, _storageProvider.Length()); - } + [Fact] + public void OnChangingEventIsCancelled_When_SettingCancelToTrue_When_SavingNewData() + { + // arrange + _sut.Changing += (_, args) => args.Cancel = true; + + // act + _sut.SetItem("Key", "Data"); + + // assert + Assert.Equal(0, _storageProvider.Length()); + } - [Theory] - [InlineData("stringTest")] - [InlineData(11)] - [InlineData(11.11)] - public void SavesDataAsJsonToStore(T valueToSave) - { - // Act - _sut.SetItem(Key, valueToSave); - - // Assert - var serializedValue = _storageProvider.GetItem(Key); - var valueFromStore = _serializer.Deserialize(serializedValue); - - Assert.Equal(1, _storageProvider.Length()); - Assert.Equal(valueToSave, valueFromStore); - } - - [Fact] - public void SavesComplexObjectAsJsonToStore() - { - // Arrange - var objectToSave = new TestObject(2, "Jane Smith"); - - // Act - _sut.SetItem(Key, objectToSave); - - // Assert - var serializedObject = _storageProvider.GetItem(Key); - var objectFromStore = _serializer.Deserialize(serializedObject); - - Assert.Equal(1, _storageProvider.Length()); - Assert.Equal(objectToSave.Id, objectFromStore.Id); - Assert.Equal(objectToSave.Name, objectFromStore.Name); - } + [Theory] + [InlineData("stringTest")] + [InlineData(11)] + [InlineData(11.11)] + public void SavesDataAsJsonToStore(T valueToSave) + { + // Act + _sut.SetItem(Key, valueToSave); + + // Assert + var serializedValue = _storageProvider.GetItem(Key); + var valueFromStore = _serializer.Deserialize(serializedValue); + + Assert.Equal(1, _storageProvider.Length()); + Assert.Equal(valueToSave, valueFromStore); + } + + [Fact] + public void SavesComplexObjectAsJsonToStore() + { + // Arrange + var objectToSave = new TestObject(2, "Jane Smith"); + + // Act + _sut.SetItem(Key, objectToSave); + + // Assert + var serializedObject = _storageProvider.GetItem(Key); + var objectFromStore = _serializer.Deserialize(serializedObject); + + Assert.Equal(1, _storageProvider.Length()); + Assert.Equal(objectToSave.Id, objectFromStore.Id); + Assert.Equal(objectToSave.Name, objectFromStore.Name); + } - [Fact] - public void SavesNullIntoStore_When_NullValueProvided() - { - // Arrange - var valueToSave = (string)null; - - // Act - _sut.SetItem(Key, valueToSave); - - // Assert - var serializedValue = _storageProvider.GetItem(Key); - var valueFromStore = _serializer.Deserialize(serializedValue); - - Assert.Equal(1, _storageProvider.Length()); - Assert.Null(valueFromStore); - } + [Fact] + public void SavesNullIntoStore_When_NullValueProvided() + { + // Arrange + var valueToSave = (string)null; + + // Act + _sut.SetItem(Key, valueToSave); + + // Assert + var serializedValue = _storageProvider.GetItem(Key); + var valueFromStore = _serializer.Deserialize(serializedValue); + + Assert.Equal(1, _storageProvider.Length()); + Assert.Null(valueFromStore); + } - [Fact] - public void OverwriteExistingValueInStore_When_UsingTheSameKey() - { - // Arrange - const string existingValue = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiYWRtaW4iLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOiJBZG1pbmlzdHJhdG9yIiwiZXhwIjoxNTg1NjYwNzEyLCJpc3MiOiJDb2RlUmVkQm9va2luZy5TZXJ2ZXIiLCJhdWQiOiJDb2RlUmVkQm9va2luZy5DbGllbnRzIn0.JhK1M1H7NLCFexujJYCDjTn9La0HloGYADMHXGCFksU"; - const string newValue = "6QLE0LL7iw7tHPAwold31qUENt3lVTUZxDGqeXQFx38="; + [Fact] + public void OverwriteExistingValueInStore_When_UsingTheSameKey() + { + // Arrange + const string existingValue = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiYWRtaW4iLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOiJBZG1pbmlzdHJhdG9yIiwiZXhwIjoxNTg1NjYwNzEyLCJpc3MiOiJDb2RlUmVkQm9va2luZy5TZXJ2ZXIiLCJhdWQiOiJDb2RlUmVkQm9va2luZy5DbGllbnRzIn0.JhK1M1H7NLCFexujJYCDjTn9La0HloGYADMHXGCFksU"; + const string newValue = "6QLE0LL7iw7tHPAwold31qUENt3lVTUZxDGqeXQFx38="; - var serializedValue = _serializer.Serialize(existingValue); - _storageProvider.SetItem(Key, serializedValue); + var serializedValue = _serializer.Serialize(existingValue); + _storageProvider.SetItem(Key, serializedValue); - // Act - _sut.SetItem(Key, newValue); + // Act + _sut.SetItem(Key, newValue); - // Assert - var serializedUpdatedValue = _storageProvider.GetItem(Key); - var updatedValue = _serializer.Deserialize(serializedUpdatedValue); + // Assert + var serializedUpdatedValue = _storageProvider.GetItem(Key); + var updatedValue = _serializer.Deserialize(serializedUpdatedValue); - Assert.Equal(newValue, updatedValue); - } + Assert.Equal(newValue, updatedValue); + } - [Fact] - public void RaisesOnChangedEvent_When_SavingData() - { - // arrange - var onChangedCalled = false; - _sut.Changed += (_, _) => onChangedCalled = true; - - // act - _sut.SetItem("Key", "Data"); - - // assert - Assert.True(onChangedCalled); - } + [Fact] + public void RaisesOnChangedEvent_When_SavingData() + { + // arrange + var onChangedCalled = false; + _sut.Changed += (_, _) => onChangedCalled = true; + + // act + _sut.SetItem("Key", "Data"); + + // assert + Assert.True(onChangedCalled); + } - [Fact] - public void OnChangedEventContainsEmptyOldValue_When_SavingNewData() - { - // arrange - var oldValue = ""; - _sut.Changed += (_, args) => oldValue = args.OldValue?.ToString(); - - // act - _sut.SetItem("Key", "Data"); - - // assert - Assert.Equal(default, oldValue); - } + [Fact] + public void OnChangedEventContainsEmptyOldValue_When_SavingNewData() + { + // arrange + var oldValue = ""; + _sut.Changed += (_, args) => oldValue = args.OldValue?.ToString(); + + // act + _sut.SetItem("Key", "Data"); + + // assert + Assert.Equal(default, oldValue); + } - [Fact] - public void OnChangedEventContainsNewValue_When_SavingNewData() - { - // arrange - const string data = "Data"; - var newValue = ""; - _sut.Changed += (_, args) => newValue = args.NewValue.ToString(); - - // act - _sut.SetItem("Key", data); - - // assert - Assert.Equal(data, newValue); - } + [Fact] + public void OnChangedEventContainsNewValue_When_SavingNewData() + { + // arrange + const string data = "Data"; + var newValue = ""; + _sut.Changed += (_, args) => newValue = args.NewValue.ToString(); + + // act + _sut.SetItem("Key", data); + + // assert + Assert.Equal(data, newValue); + } - [Fact] - public void OnChangedEventContainsOldValue_When_UpdatingExistingData() - { - // arrange - var existingValue = "Foo"; - _storageProvider.SetItem("Key", existingValue); - var oldValue = ""; - _sut.Changed += (_, args) => oldValue = args.OldValue?.ToString(); - - // act - _sut.SetItem("Key", "Data"); - - // assert - Assert.Equal(existingValue, oldValue); - } + [Fact] + public void OnChangedEventContainsOldValue_When_UpdatingExistingData() + { + // arrange + var existingValue = "Foo"; + _storageProvider.SetItem("Key", existingValue); + var oldValue = ""; + _sut.Changed += (_, args) => oldValue = args.OldValue?.ToString(); + + // act + _sut.SetItem("Key", "Data"); + + // assert + Assert.Equal(existingValue, oldValue); } -} +} \ No newline at end of file diff --git a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/SetItemAsString.cs b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/SetItemAsString.cs index 24ec2fd..913b043 100644 --- a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/SetItemAsString.cs +++ b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/SetItemAsString.cs @@ -8,197 +8,196 @@ using Moq; using Xunit; -namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests +namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests; + +public class SetItemAsString { - public class SetItemAsString + private readonly SessionStorageService _sut; + private readonly IStorageProvider _storageProvider; + private readonly IJsonSerializer _serializer; + + private const string Key = "testKey"; + + public SetItemAsString() { - private readonly SessionStorageService _sut; - private readonly IStorageProvider _storageProvider; - private readonly IJsonSerializer _serializer; - - private const string Key = "testKey"; - - public SetItemAsString() - { - var mockOptions = new Mock>(); - var jsonOptions = new JsonSerializerOptions(); - jsonOptions.Converters.Add(new TimespanJsonConverter()); - mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); - _serializer = new SystemTextJsonSerializer(mockOptions.Object); - _storageProvider = new InMemoryStorageProvider(); - _sut = new SessionStorageService(_storageProvider, _serializer); - } - - [Theory] - [InlineData("")] - [InlineData(" ")] - [InlineData(null)] - public void ThrowsArgumentNullException_When_KeyIsInvalid(string key) - { - // arrange / act - const string data = "Data"; - var action = new Action(() => _sut.SetItemAsString(key, data)); - - // assert - Assert.Throws(action); - } + var mockOptions = new Mock>(); + var jsonOptions = new JsonSerializerOptions(); + jsonOptions.Converters.Add(new TimespanJsonConverter()); + mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); + _serializer = new SystemTextJsonSerializer(mockOptions.Object); + _storageProvider = new InMemoryStorageProvider(); + _sut = new SessionStorageService(_storageProvider, _serializer); + } + + [Theory] + [InlineData("")] + [InlineData(" ")] + [InlineData(null)] + public void ThrowsArgumentNullException_When_KeyIsInvalid(string key) + { + // arrange / act + const string data = "Data"; + var action = new Action(() => _sut.SetItemAsString(key, data)); + + // assert + Assert.Throws(action); + } - [Fact] - public void ThrowsArgumentNullException_When_DataIsNull() - { - // arrange / act - var data = (string)null; - var action = new Action(() => _sut.SetItemAsString("MyValue", data)); - - // assert - Assert.Throws(action); - } - - [Fact] - public void RaisesOnChangingEvent_When_SavingNewData() - { - // arrange - var onChangingCalled = false; - _sut.Changing += (_, _) => onChangingCalled = true; - - // act - _sut.SetItemAsString("Key", "Data"); - - // assert - Assert.True(onChangingCalled); - } + [Fact] + public void ThrowsArgumentNullException_When_DataIsNull() + { + // arrange / act + var data = (string)null; + var action = new Action(() => _sut.SetItemAsString("MyValue", data)); + + // assert + Assert.Throws(action); + } + + [Fact] + public void RaisesOnChangingEvent_When_SavingNewData() + { + // arrange + var onChangingCalled = false; + _sut.Changing += (_, _) => onChangingCalled = true; + + // act + _sut.SetItemAsString("Key", "Data"); + + // assert + Assert.True(onChangingCalled); + } - [Fact] - public void OnChangingEventContainsEmptyOldValue_When_SavingData() - { - // arrange - var oldValue = ""; - _sut.Changing += (_, args) => oldValue = args.OldValue?.ToString(); - - // act - _sut.SetItemAsString("Key", "Data"); - - // assert - Assert.Equal(default, oldValue); - } + [Fact] + public void OnChangingEventContainsEmptyOldValue_When_SavingData() + { + // arrange + var oldValue = ""; + _sut.Changing += (_, args) => oldValue = args.OldValue?.ToString(); + + // act + _sut.SetItemAsString("Key", "Data"); + + // assert + Assert.Equal(default, oldValue); + } - [Fact] - public void OnChangingEventContainsNewValue_When_SavingNewData() - { - // arrange - const string data = "Data"; - var newValue = ""; - _sut.Changing += (_, args) => newValue = args.NewValue.ToString(); - - // act - _sut.SetItemAsString("Key", data); - - // assert - Assert.Equal(data, newValue); - } + [Fact] + public void OnChangingEventContainsNewValue_When_SavingNewData() + { + // arrange + const string data = "Data"; + var newValue = ""; + _sut.Changing += (_, args) => newValue = args.NewValue.ToString(); + + // act + _sut.SetItemAsString("Key", data); + + // assert + Assert.Equal(data, newValue); + } - [Fact] - public void OnChangingEventIsCancelled_When_SettingCancelToTrue_When_SavingNewData() - { - // arrange - _sut.Changing += (_, args) => args.Cancel = true; - - // act - _sut.SetItemAsString("Key", "Data"); - - // assert - Assert.Equal(0, _storageProvider.Length()); - } + [Fact] + public void OnChangingEventIsCancelled_When_SettingCancelToTrue_When_SavingNewData() + { + // arrange + _sut.Changing += (_, args) => args.Cancel = true; + + // act + _sut.SetItemAsString("Key", "Data"); + + // assert + Assert.Equal(0, _storageProvider.Length()); + } - [Fact] - public void SavesDataToStore() - { - // Act - var valueToSave = "StringValue"; - _sut.SetItemAsString(Key, valueToSave); - - // Assert - var valueFromStore = _storageProvider.GetItem(Key); - - Assert.Equal(1, _storageProvider.Length()); - Assert.Equal(valueToSave, valueFromStore); - } + [Fact] + public void SavesDataToStore() + { + // Act + var valueToSave = "StringValue"; + _sut.SetItemAsString(Key, valueToSave); + + // Assert + var valueFromStore = _storageProvider.GetItem(Key); + + Assert.Equal(1, _storageProvider.Length()); + Assert.Equal(valueToSave, valueFromStore); + } - [Fact] - public void OverwriteExistingValueInStore_When_UsingTheSameKey() - { - // Arrange - const string existingValue = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiYWRtaW4iLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOiJBZG1pbmlzdHJhdG9yIiwiZXhwIjoxNTg1NjYwNzEyLCJpc3MiOiJDb2RlUmVkQm9va2luZy5TZXJ2ZXIiLCJhdWQiOiJDb2RlUmVkQm9va2luZy5DbGllbnRzIn0.JhK1M1H7NLCFexujJYCDjTn9La0HloGYADMHXGCFksU"; - const string newValue = "6QLE0LL7iw7tHPAwold31qUENt3lVTUZxDGqeXQFx38="; + [Fact] + public void OverwriteExistingValueInStore_When_UsingTheSameKey() + { + // Arrange + const string existingValue = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiYWRtaW4iLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOiJBZG1pbmlzdHJhdG9yIiwiZXhwIjoxNTg1NjYwNzEyLCJpc3MiOiJDb2RlUmVkQm9va2luZy5TZXJ2ZXIiLCJhdWQiOiJDb2RlUmVkQm9va2luZy5DbGllbnRzIn0.JhK1M1H7NLCFexujJYCDjTn9La0HloGYADMHXGCFksU"; + const string newValue = "6QLE0LL7iw7tHPAwold31qUENt3lVTUZxDGqeXQFx38="; - _storageProvider.SetItem(Key, existingValue); + _storageProvider.SetItem(Key, existingValue); - // Act - _sut.SetItemAsString(Key, newValue); + // Act + _sut.SetItemAsString(Key, newValue); - // Assert - var updatedValue = _storageProvider.GetItem(Key); + // Assert + var updatedValue = _storageProvider.GetItem(Key); - Assert.Equal(newValue, updatedValue); - } + Assert.Equal(newValue, updatedValue); + } - [Fact] - public void RaisesOnChangedEvent_When_SavingData() - { - // arrange - var onChangedCalled = false; - _sut.Changed += (_, _) => onChangedCalled = true; - - // act - _sut.SetItemAsString("Key", "Data"); - - // assert - Assert.True(onChangedCalled); - } + [Fact] + public void RaisesOnChangedEvent_When_SavingData() + { + // arrange + var onChangedCalled = false; + _sut.Changed += (_, _) => onChangedCalled = true; + + // act + _sut.SetItemAsString("Key", "Data"); + + // assert + Assert.True(onChangedCalled); + } - [Fact] - public void OnChangedEventContainsEmptyOldValue_When_SavingNewData() - { - // arrange - var oldValue = ""; - _sut.Changed += (_, args) => oldValue = args.OldValue?.ToString(); - - // act - _sut.SetItemAsString("Key", "Data"); - - // assert - Assert.Equal(default, oldValue); - } + [Fact] + public void OnChangedEventContainsEmptyOldValue_When_SavingNewData() + { + // arrange + var oldValue = ""; + _sut.Changed += (_, args) => oldValue = args.OldValue?.ToString(); + + // act + _sut.SetItemAsString("Key", "Data"); + + // assert + Assert.Equal(default, oldValue); + } - [Fact] - public void OnChangedEventContainsNewValue_When_SavingNewData() - { - // arrange - const string data = "Data"; - var newValue = ""; - _sut.Changed += (_, args) => newValue = args.NewValue.ToString(); - - // act - _sut.SetItemAsString("Key", data); - - // assert - Assert.Equal(data, newValue); - } + [Fact] + public void OnChangedEventContainsNewValue_When_SavingNewData() + { + // arrange + const string data = "Data"; + var newValue = ""; + _sut.Changed += (_, args) => newValue = args.NewValue.ToString(); + + // act + _sut.SetItemAsString("Key", data); + + // assert + Assert.Equal(data, newValue); + } - [Fact] - public void OnChangedEventContainsOldValue_When_UpdatingExistingData() - { - // arrange - var existingValue = "Foo"; - _storageProvider.SetItem("Key", existingValue); - var oldValue = ""; - _sut.Changed += (_, args) => oldValue = args.OldValue?.ToString(); - - // act - _sut.SetItemAsString("Key", "Data"); - - // assert - Assert.Equal(existingValue, oldValue); - } + [Fact] + public void OnChangedEventContainsOldValue_When_UpdatingExistingData() + { + // arrange + var existingValue = "Foo"; + _storageProvider.SetItem("Key", existingValue); + var oldValue = ""; + _sut.Changed += (_, args) => oldValue = args.OldValue?.ToString(); + + // act + _sut.SetItemAsString("Key", "Data"); + + // assert + Assert.Equal(existingValue, oldValue); } -} +} \ No newline at end of file diff --git a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/SetItemAsStringAsync.cs b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/SetItemAsStringAsync.cs index 4a5d0a2..7857a1b 100644 --- a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/SetItemAsStringAsync.cs +++ b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/SetItemAsStringAsync.cs @@ -9,197 +9,196 @@ using Moq; using Xunit; -namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests +namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests; + +public class SetItemAsStringAsync { - public class SetItemAsStringAsync + private readonly SessionStorageService _sut; + private readonly IStorageProvider _storageProvider; + private readonly IJsonSerializer _serializer; + + private const string Key = "testKey"; + + public SetItemAsStringAsync() { - private readonly SessionStorageService _sut; - private readonly IStorageProvider _storageProvider; - private readonly IJsonSerializer _serializer; - - private const string Key = "testKey"; - - public SetItemAsStringAsync() - { - var mockOptions = new Mock>(); - var jsonOptions = new JsonSerializerOptions(); - jsonOptions.Converters.Add(new TimespanJsonConverter()); - mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); - _serializer = new SystemTextJsonSerializer(mockOptions.Object); - _storageProvider = new InMemoryStorageProvider(); - _sut = new SessionStorageService(_storageProvider, _serializer); - } - - [Theory] - [InlineData("")] - [InlineData(" ")] - [InlineData(null)] - public void ThrowsArgumentNullException_When_KeyIsInvalid(string key) - { - // arrange / act - const string data = "Data"; - var action = new Func(async () => await _sut.SetItemAsStringAsync(key, data)); - - // assert - Assert.ThrowsAsync(action); - } + var mockOptions = new Mock>(); + var jsonOptions = new JsonSerializerOptions(); + jsonOptions.Converters.Add(new TimespanJsonConverter()); + mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); + _serializer = new SystemTextJsonSerializer(mockOptions.Object); + _storageProvider = new InMemoryStorageProvider(); + _sut = new SessionStorageService(_storageProvider, _serializer); + } + + [Theory] + [InlineData("")] + [InlineData(" ")] + [InlineData(null)] + public void ThrowsArgumentNullException_When_KeyIsInvalid(string key) + { + // arrange / act + const string data = "Data"; + var action = new Func(async () => await _sut.SetItemAsStringAsync(key, data)); + + // assert + Assert.ThrowsAsync(action); + } - [Fact] - public void ThrowsArgumentNullException_When_DataIsNull() - { - // arrange / act - var data = (string)null; - var action = new Func(async () => await _sut.SetItemAsStringAsync("MyValue", data)); - - // assert - Assert.ThrowsAsync(action); - } - - [Fact] - public async Task RaisesOnChangingEvent_When_SavingNewData() - { - // arrange - var onChangingCalled = false; - _sut.Changing += (_, _) => onChangingCalled = true; - - // act - await _sut.SetItemAsStringAsync("Key", "Data"); - - // assert - Assert.True(onChangingCalled); - } + [Fact] + public void ThrowsArgumentNullException_When_DataIsNull() + { + // arrange / act + var data = (string)null; + var action = new Func(async () => await _sut.SetItemAsStringAsync("MyValue", data)); + + // assert + Assert.ThrowsAsync(action); + } + + [Fact] + public async Task RaisesOnChangingEvent_When_SavingNewData() + { + // arrange + var onChangingCalled = false; + _sut.Changing += (_, _) => onChangingCalled = true; + + // act + await _sut.SetItemAsStringAsync("Key", "Data"); + + // assert + Assert.True(onChangingCalled); + } - [Fact] - public async Task OnChangingEventContainsEmptyOldValue_When_SavingData() - { - // arrange - var oldValue = ""; - _sut.Changing += (_, args) => oldValue = args.OldValue?.ToString(); - - // act - await _sut.SetItemAsStringAsync("Key", "Data"); - - // assert - Assert.Equal(default, oldValue); - } + [Fact] + public async Task OnChangingEventContainsEmptyOldValue_When_SavingData() + { + // arrange + var oldValue = ""; + _sut.Changing += (_, args) => oldValue = args.OldValue?.ToString(); + + // act + await _sut.SetItemAsStringAsync("Key", "Data"); + + // assert + Assert.Equal(default, oldValue); + } - [Fact] - public async Task OnChangingEventContainsNewValue_When_SavingNewData() - { - // arrange - const string data = "Data"; - var newValue = ""; - _sut.Changing += (_, args) => newValue = args.NewValue.ToString(); - - // act - await _sut.SetItemAsStringAsync("Key", data); - - // assert - Assert.Equal(data, newValue); - } + [Fact] + public async Task OnChangingEventContainsNewValue_When_SavingNewData() + { + // arrange + const string data = "Data"; + var newValue = ""; + _sut.Changing += (_, args) => newValue = args.NewValue.ToString(); + + // act + await _sut.SetItemAsStringAsync("Key", data); + + // assert + Assert.Equal(data, newValue); + } - [Fact] - public async Task OnChangingEventIsCancelled_When_SettingCancelToTrue_When_SavingNewData() - { - // arrange - _sut.Changing += (_, args) => args.Cancel = true; - - // act - await _sut.SetItemAsStringAsync("Key", "Data"); - - // assert - Assert.Equal(0, _storageProvider.Length()); - } + [Fact] + public async Task OnChangingEventIsCancelled_When_SettingCancelToTrue_When_SavingNewData() + { + // arrange + _sut.Changing += (_, args) => args.Cancel = true; + + // act + await _sut.SetItemAsStringAsync("Key", "Data"); + + // assert + Assert.Equal(0, _storageProvider.Length()); + } - [Fact] - public async Task SavesDataToStore() - { - // Act - var valueToSave = "StringValue"; - await _sut.SetItemAsStringAsync(Key, valueToSave); - - // Assert - var valueFromStore = _storageProvider.GetItem(Key); - - Assert.Equal(1, _storageProvider.Length()); - Assert.Equal(valueToSave, valueFromStore); - } + [Fact] + public async Task SavesDataToStore() + { + // Act + var valueToSave = "StringValue"; + await _sut.SetItemAsStringAsync(Key, valueToSave); + + // Assert + var valueFromStore = _storageProvider.GetItem(Key); + + Assert.Equal(1, _storageProvider.Length()); + Assert.Equal(valueToSave, valueFromStore); + } - [Fact] - public async Task OverwriteExistingValueInStore_When_UsingTheSameKey() - { - // Arrange - const string existingValue = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiYWRtaW4iLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOiJBZG1pbmlzdHJhdG9yIiwiZXhwIjoxNTg1NjYwNzEyLCJpc3MiOiJDb2RlUmVkQm9va2luZy5TZXJ2ZXIiLCJhdWQiOiJDb2RlUmVkQm9va2luZy5DbGllbnRzIn0.JhK1M1H7NLCFexujJYCDjTn9La0HloGYADMHXGCFksU"; - const string newValue = "6QLE0LL7iw7tHPAwold31qUENt3lVTUZxDGqeXQFx38="; + [Fact] + public async Task OverwriteExistingValueInStore_When_UsingTheSameKey() + { + // Arrange + const string existingValue = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiYWRtaW4iLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOiJBZG1pbmlzdHJhdG9yIiwiZXhwIjoxNTg1NjYwNzEyLCJpc3MiOiJDb2RlUmVkQm9va2luZy5TZXJ2ZXIiLCJhdWQiOiJDb2RlUmVkQm9va2luZy5DbGllbnRzIn0.JhK1M1H7NLCFexujJYCDjTn9La0HloGYADMHXGCFksU"; + const string newValue = "6QLE0LL7iw7tHPAwold31qUENt3lVTUZxDGqeXQFx38="; - _storageProvider.SetItem(Key, existingValue); + _storageProvider.SetItem(Key, existingValue); - // Act - await _sut.SetItemAsStringAsync(Key, newValue); + // Act + await _sut.SetItemAsStringAsync(Key, newValue); - // Assert - var updatedValue = _storageProvider.GetItem(Key); + // Assert + var updatedValue = _storageProvider.GetItem(Key); - Assert.Equal(newValue, updatedValue); - } + Assert.Equal(newValue, updatedValue); + } - [Fact] - public async Task RaisesOnChangedEvent_When_SavingData() - { - // arrange - var onChangedCalled = false; - _sut.Changed += (_, _) => onChangedCalled = true; - - // act - await _sut.SetItemAsStringAsync("Key", "Data"); - - // assert - Assert.True(onChangedCalled); - } + [Fact] + public async Task RaisesOnChangedEvent_When_SavingData() + { + // arrange + var onChangedCalled = false; + _sut.Changed += (_, _) => onChangedCalled = true; + + // act + await _sut.SetItemAsStringAsync("Key", "Data"); + + // assert + Assert.True(onChangedCalled); + } - [Fact] - public async Task OnChangedEventContainsEmptyOldValue_When_SavingNewData() - { - // arrange - var oldValue = ""; - _sut.Changed += (_, args) => oldValue = args.OldValue?.ToString(); - - // act - await _sut.SetItemAsStringAsync("Key", "Data"); - - // assert - Assert.Equal(default, oldValue); - } + [Fact] + public async Task OnChangedEventContainsEmptyOldValue_When_SavingNewData() + { + // arrange + var oldValue = ""; + _sut.Changed += (_, args) => oldValue = args.OldValue?.ToString(); + + // act + await _sut.SetItemAsStringAsync("Key", "Data"); + + // assert + Assert.Equal(default, oldValue); + } - [Fact] - public async Task OnChangedEventContainsNewValue_When_SavingNewData() - { - // arrange - const string data = "Data"; - var newValue = ""; - _sut.Changed += (_, args) => newValue = args.NewValue.ToString(); - - // act - await _sut.SetItemAsStringAsync("Key", data); - - // assert - Assert.Equal(data, newValue); - } + [Fact] + public async Task OnChangedEventContainsNewValue_When_SavingNewData() + { + // arrange + const string data = "Data"; + var newValue = ""; + _sut.Changed += (_, args) => newValue = args.NewValue.ToString(); + + // act + await _sut.SetItemAsStringAsync("Key", data); + + // assert + Assert.Equal(data, newValue); + } - [Fact] - public async Task OnChangedEventContainsOldValue_When_UpdatingExistingData() - { - // arrange - var existingValue = "Foo"; - _storageProvider.SetItem("Key", existingValue); - var oldValue = ""; - _sut.Changed += (_, args) => oldValue = args.OldValue?.ToString(); - - // act - await _sut.SetItemAsStringAsync("Key", "Data"); - - // assert - Assert.Equal(existingValue, oldValue); - } + [Fact] + public async Task OnChangedEventContainsOldValue_When_UpdatingExistingData() + { + // arrange + var existingValue = "Foo"; + _storageProvider.SetItem("Key", existingValue); + var oldValue = ""; + _sut.Changed += (_, args) => oldValue = args.OldValue?.ToString(); + + // act + await _sut.SetItemAsStringAsync("Key", "Data"); + + // assert + Assert.Equal(existingValue, oldValue); } -} +} \ No newline at end of file diff --git a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/SetItemAsync.cs b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/SetItemAsync.cs index df49036..8aa1e49 100644 --- a/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/SetItemAsync.cs +++ b/tests/Blazored.SessionStorage.Tests/SessionStorageServiceTests/SetItemAsync.cs @@ -10,226 +10,225 @@ using Moq; using Xunit; -namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests +namespace Blazored.SessionStorage.Tests.SessionStorageServiceTests; + +public class SetItemAsync { - public class SetItemAsync + private readonly SessionStorageService _sut; + private readonly IStorageProvider _storageProvider; + private readonly IJsonSerializer _serializer; + + private const string Key = "testKey"; + + public SetItemAsync() + { + var mockOptions = new Mock>(); + var jsonOptions = new JsonSerializerOptions(); + jsonOptions.Converters.Add(new TimespanJsonConverter()); + mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); + _serializer = new SystemTextJsonSerializer(mockOptions.Object); + _storageProvider = new InMemoryStorageProvider(); + _sut = new SessionStorageService(_storageProvider, _serializer); + } + + [Theory] + [InlineData("")] + [InlineData(" ")] + [InlineData(null)] + public void ThrowsArgumentNullException_When_KeyIsInvalid(string key) { - private readonly SessionStorageService _sut; - private readonly IStorageProvider _storageProvider; - private readonly IJsonSerializer _serializer; - - private const string Key = "testKey"; - - public SetItemAsync() - { - var mockOptions = new Mock>(); - var jsonOptions = new JsonSerializerOptions(); - jsonOptions.Converters.Add(new TimespanJsonConverter()); - mockOptions.Setup(u => u.Value).Returns(new SessionStorageOptions()); - _serializer = new SystemTextJsonSerializer(mockOptions.Object); - _storageProvider = new InMemoryStorageProvider(); - _sut = new SessionStorageService(_storageProvider, _serializer); - } - - [Theory] - [InlineData("")] - [InlineData(" ")] - [InlineData(null)] - public void ThrowsArgumentNullException_When_KeyIsInvalid(string key) - { - // arrange / act - const string data = "Data"; - var action = new Func(async () => await _sut.SetItemAsync(key, data)); - - // assert - Assert.ThrowsAsync(action); - } - - [Fact] - public async Task RaisesOnChangingEvent_When_SavingNewData() - { - // arrange - var onChangingCalled = false; - _sut.Changing += (sender, args) => onChangingCalled = true; - - // act - await _sut.SetItemAsync("Key", "Data"); - - // assert - Assert.True(onChangingCalled); - } + // arrange / act + const string data = "Data"; + var action = new Func(async () => await _sut.SetItemAsync(key, data)); + + // assert + Assert.ThrowsAsync(action); + } + + [Fact] + public async Task RaisesOnChangingEvent_When_SavingNewData() + { + // arrange + var onChangingCalled = false; + _sut.Changing += (sender, args) => onChangingCalled = true; + + // act + await _sut.SetItemAsync("Key", "Data"); + + // assert + Assert.True(onChangingCalled); + } - [Fact] - public async Task OnChangingEventContainsEmptyOldValue_When_SavingData() - { - // arrange - var oldValue = ""; - _sut.Changing += (_, args) => oldValue = args.OldValue?.ToString(); - - // act - await _sut.SetItemAsync("Key", "Data"); - - // assert - Assert.Equal(default, oldValue); - } + [Fact] + public async Task OnChangingEventContainsEmptyOldValue_When_SavingData() + { + // arrange + var oldValue = ""; + _sut.Changing += (_, args) => oldValue = args.OldValue?.ToString(); + + // act + await _sut.SetItemAsync("Key", "Data"); + + // assert + Assert.Equal(default, oldValue); + } - [Fact] - public async Task OnChangingEventContainsNewValue_When_SavingNewData() - { - // arrange - const string data = "Data"; - var newValue = ""; - _sut.Changing += (_, args) => newValue = args.NewValue.ToString(); - - // act - await _sut.SetItemAsync("Key", data); - - // assert - Assert.Equal(data, newValue); - } + [Fact] + public async Task OnChangingEventContainsNewValue_When_SavingNewData() + { + // arrange + const string data = "Data"; + var newValue = ""; + _sut.Changing += (_, args) => newValue = args.NewValue.ToString(); + + // act + await _sut.SetItemAsync("Key", data); + + // assert + Assert.Equal(data, newValue); + } - [Fact] - public async Task OnChangingEventIsCancelled_When_SettingCancelToTrue_When_SavingNewData() - { - // arrange - _sut.Changing += (_, args) => args.Cancel = true; - - // act - await _sut.SetItemAsync("Key", "Data"); - - // assert - Assert.Equal(0, await _storageProvider.LengthAsync()); - } + [Fact] + public async Task OnChangingEventIsCancelled_When_SettingCancelToTrue_When_SavingNewData() + { + // arrange + _sut.Changing += (_, args) => args.Cancel = true; + + // act + await _sut.SetItemAsync("Key", "Data"); + + // assert + Assert.Equal(0, await _storageProvider.LengthAsync()); + } - [Theory] - [InlineData("stringTest")] - [InlineData(11)] - [InlineData(11.11)] - public async Task SavesDataAsJsonToStore(T valueToSave) - { - // Act - await _sut.SetItemAsync(Key, valueToSave); - - // Assert - var serializedValue = await _storageProvider.GetItemAsync(Key); - var valueFromStore = _serializer.Deserialize(serializedValue); - - Assert.Equal(1, await _storageProvider.LengthAsync()); - Assert.Equal(valueToSave, valueFromStore); - } - - [Fact] - public async Task SavesComplexObjectAsJsonToStore() - { - // Arrange - var objectToSave = new TestObject(2, "Jane Smith"); - - // Act - await _sut.SetItemAsync(Key, objectToSave); - - // Assert - var serializedObject = await _storageProvider.GetItemAsync(Key); - var objectFromStore = _serializer.Deserialize(serializedObject); - - Assert.Equal(1, await _storageProvider.LengthAsync()); - Assert.Equal(objectToSave.Id, objectFromStore.Id); - Assert.Equal(objectToSave.Name, objectFromStore.Name); - } + [Theory] + [InlineData("stringTest")] + [InlineData(11)] + [InlineData(11.11)] + public async Task SavesDataAsJsonToStore(T valueToSave) + { + // Act + await _sut.SetItemAsync(Key, valueToSave); + + // Assert + var serializedValue = await _storageProvider.GetItemAsync(Key); + var valueFromStore = _serializer.Deserialize(serializedValue); + + Assert.Equal(1, await _storageProvider.LengthAsync()); + Assert.Equal(valueToSave, valueFromStore); + } + + [Fact] + public async Task SavesComplexObjectAsJsonToStore() + { + // Arrange + var objectToSave = new TestObject(2, "Jane Smith"); + + // Act + await _sut.SetItemAsync(Key, objectToSave); + + // Assert + var serializedObject = await _storageProvider.GetItemAsync(Key); + var objectFromStore = _serializer.Deserialize(serializedObject); + + Assert.Equal(1, await _storageProvider.LengthAsync()); + Assert.Equal(objectToSave.Id, objectFromStore.Id); + Assert.Equal(objectToSave.Name, objectFromStore.Name); + } - [Fact] - public async Task SavesNullIntoStore_When_NullValueProvided() - { - // Arrange - var valueToSave = (string)null; - - // Act - await _sut.SetItemAsync(Key, valueToSave); - - // Assert - var serializedValue = await _storageProvider.GetItemAsync(Key); - var valueFromStore = _serializer.Deserialize(serializedValue); - - Assert.Equal(1, await _storageProvider.LengthAsync()); - Assert.Null(valueFromStore); - } + [Fact] + public async Task SavesNullIntoStore_When_NullValueProvided() + { + // Arrange + var valueToSave = (string)null; + + // Act + await _sut.SetItemAsync(Key, valueToSave); + + // Assert + var serializedValue = await _storageProvider.GetItemAsync(Key); + var valueFromStore = _serializer.Deserialize(serializedValue); + + Assert.Equal(1, await _storageProvider.LengthAsync()); + Assert.Null(valueFromStore); + } - [Fact] - public async Task OverwriteExistingValueInStore_When_UsingTheSameKey() - { - // Arrange - const string existingValue = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiYWRtaW4iLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOiJBZG1pbmlzdHJhdG9yIiwiZXhwIjoxNTg1NjYwNzEyLCJpc3MiOiJDb2RlUmVkQm9va2luZy5TZXJ2ZXIiLCJhdWQiOiJDb2RlUmVkQm9va2luZy5DbGllbnRzIn0.JhK1M1H7NLCFexujJYCDjTn9La0HloGYADMHXGCFksU"; - const string newValue = "6QLE0LL7iw7tHPAwold31qUENt3lVTUZxDGqeXQFx38="; + [Fact] + public async Task OverwriteExistingValueInStore_When_UsingTheSameKey() + { + // Arrange + const string existingValue = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiYWRtaW4iLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOiJBZG1pbmlzdHJhdG9yIiwiZXhwIjoxNTg1NjYwNzEyLCJpc3MiOiJDb2RlUmVkQm9va2luZy5TZXJ2ZXIiLCJhdWQiOiJDb2RlUmVkQm9va2luZy5DbGllbnRzIn0.JhK1M1H7NLCFexujJYCDjTn9La0HloGYADMHXGCFksU"; + const string newValue = "6QLE0LL7iw7tHPAwold31qUENt3lVTUZxDGqeXQFx38="; - var serializedValue = _serializer.Serialize(existingValue); - await _storageProvider.SetItemAsync(Key, serializedValue); + var serializedValue = _serializer.Serialize(existingValue); + await _storageProvider.SetItemAsync(Key, serializedValue); - // Act - await _sut.SetItemAsync(Key, newValue); + // Act + await _sut.SetItemAsync(Key, newValue); - // Assert - var serializedUpdatedValue = await _storageProvider.GetItemAsync(Key); - var updatedValue = _serializer.Deserialize(serializedUpdatedValue); + // Assert + var serializedUpdatedValue = await _storageProvider.GetItemAsync(Key); + var updatedValue = _serializer.Deserialize(serializedUpdatedValue); - Assert.Equal(newValue, updatedValue); - } + Assert.Equal(newValue, updatedValue); + } - [Fact] - public async Task RaisesOnChangedEvent_When_SavingData() - { - // arrange - var onChangedCalled = false; - _sut.Changed += (sender, args) => onChangedCalled = true; - - // act - await _sut.SetItemAsync("Key", "Data"); - - // assert - Assert.True(onChangedCalled); - } + [Fact] + public async Task RaisesOnChangedEvent_When_SavingData() + { + // arrange + var onChangedCalled = false; + _sut.Changed += (sender, args) => onChangedCalled = true; + + // act + await _sut.SetItemAsync("Key", "Data"); + + // assert + Assert.True(onChangedCalled); + } - [Fact] - public async Task OnChangedEventContainsEmptyOldValue_When_SavingNewData() - { - // arrange - var oldValue = ""; - _sut.Changed += (_, args) => oldValue = args.OldValue?.ToString(); - - // act - await _sut.SetItemAsync("Key", "Data"); - - // assert - Assert.Equal(default, oldValue); - } + [Fact] + public async Task OnChangedEventContainsEmptyOldValue_When_SavingNewData() + { + // arrange + var oldValue = ""; + _sut.Changed += (_, args) => oldValue = args.OldValue?.ToString(); + + // act + await _sut.SetItemAsync("Key", "Data"); + + // assert + Assert.Equal(default, oldValue); + } - [Fact] - public async Task OnChangedEventContainsNewValue_When_SavingNewData() - { - // arrange - const string data = "Data"; - var newValue = ""; - _sut.Changed += (_, args) => newValue = args.NewValue.ToString(); - - // act - await _sut.SetItemAsync("Key", data); - - // assert - Assert.Equal(data, newValue); - } + [Fact] + public async Task OnChangedEventContainsNewValue_When_SavingNewData() + { + // arrange + const string data = "Data"; + var newValue = ""; + _sut.Changed += (_, args) => newValue = args.NewValue.ToString(); + + // act + await _sut.SetItemAsync("Key", data); + + // assert + Assert.Equal(data, newValue); + } - [Fact] - public async Task OnChangedEventContainsOldValue_When_UpdatingExistingData() - { - // arrange - var existingValue = "Foo"; - await _storageProvider.SetItemAsync("Key", existingValue); - var oldValue = ""; - _sut.Changed += (_, args) => oldValue = args.OldValue?.ToString(); - - // act - await _sut.SetItemAsync("Key", "Data"); - - // assert - Assert.Equal(existingValue, oldValue); - } + [Fact] + public async Task OnChangedEventContainsOldValue_When_UpdatingExistingData() + { + // arrange + var existingValue = "Foo"; + await _storageProvider.SetItemAsync("Key", existingValue); + var oldValue = ""; + _sut.Changed += (_, args) => oldValue = args.OldValue?.ToString(); + + // act + await _sut.SetItemAsync("Key", "Data"); + + // assert + Assert.Equal(existingValue, oldValue); } -} +} \ No newline at end of file diff --git a/tests/Blazored.SessionStorage.Tests/TestAssets/TestObject.cs b/tests/Blazored.SessionStorage.Tests/TestAssets/TestObject.cs index 126a9f1..5ee381d 100644 --- a/tests/Blazored.SessionStorage.Tests/TestAssets/TestObject.cs +++ b/tests/Blazored.SessionStorage.Tests/TestAssets/TestObject.cs @@ -1,15 +1,14 @@ -namespace Blazored.SessionStorage.Tests.TestAssets +namespace Blazored.SessionStorage.Tests.TestAssets; + +public class TestObject { - public class TestObject - { - public int Id { get; set; } - public string Name { get; set; } + public int Id { get; set; } + public string Name { get; set; } - public TestObject() { } - public TestObject(int id, string name) - { - Id = id; - Name = name; - } + public TestObject() { } + public TestObject(int id, string name) + { + Id = id; + Name = name; } -} +} \ No newline at end of file