From 5cb694776f51e6dc46596da1eac52f3ed1d3829d Mon Sep 17 00:00:00 2001 From: Lewis Westbury Date: Sat, 8 Feb 2025 21:23:43 +0000 Subject: [PATCH] Support a JSON environment config key --- .../ATConnectionTests.cs | 4 +- .../ConsoleConnectionTests.cs | 5 +- Presence.Posting.Lib.Tests/CredentialTests.cs | 3 +- .../EnvironmentConfigReaderTests.cs | 119 ++++++++++++++++++ ...nfigTests.cs => IntegrationConfigTests.cs} | 8 +- .../EnvironmentConfigReader.cs | 24 ++-- .../Config/JsonConfigReader.cs | 13 ++ .../Connections/AT/ATAccount.cs | 3 +- .../Connections/AT/ATConnection.cs | 5 +- .../Connections/AbstractNetworkAccount.cs | 9 +- .../Connections/ConnectionFactory.cs | 8 +- .../Connections/Console/ConsoleAccount.cs | 3 +- .../Connections/Console/ConsoleConnection.cs | 1 + .../Connections/INetworkAccount.cs | 3 +- Presence.Posting.Lib/Constants/ConfigKeys.cs | 8 ++ .../NetworkCredentialType.cs | 2 +- Presence.Posting.Lib/DTO/ThreadPostSummary.cs | 1 - .../Helpers/DictionaryExtension.cs | 6 +- 18 files changed, 191 insertions(+), 34 deletions(-) create mode 100644 Presence.Posting.Lib.Tests/EnvironmentConfigReaderTests.cs rename Presence.Posting.Lib.Tests/{ConfigTests.cs => IntegrationConfigTests.cs} (88%) rename Presence.Posting.Lib/{Connections => Config}/EnvironmentConfigReader.cs (60%) create mode 100644 Presence.Posting.Lib/Config/JsonConfigReader.cs create mode 100644 Presence.Posting.Lib/Constants/ConfigKeys.cs rename Presence.Posting.Lib/{Connections => Constants}/NetworkCredentialType.cs (69%) diff --git a/Presence.Posting.Lib.Tests/ATConnectionTests.cs b/Presence.Posting.Lib.Tests/ATConnectionTests.cs index 3694e3a..97b831a 100644 --- a/Presence.Posting.Lib.Tests/ATConnectionTests.cs +++ b/Presence.Posting.Lib.Tests/ATConnectionTests.cs @@ -1,8 +1,10 @@ using System.Text; using FishyFlip.Lexicon.App.Bsky.Embed; using FishyFlip.Lexicon.App.Bsky.Feed; +using Presence.Posting.Lib.Config; using Presence.Posting.Lib.Connections; using Presence.Posting.Lib.Connections.AT; +using Presence.Posting.Lib.Constants; using Presence.SocialFormat.Lib.Networks; using Presence.SocialFormat.Lib.Post; @@ -126,7 +128,7 @@ public async Task ATConnection_Posts_WithLinkAndTagFacets() [TestCategory("Unit")] public async Task ATConnection_IdentifiesFacets() { - var connection = new ATConnection(new ATAccount("TEST1", new Dictionary())); + var connection = new ATConnection(new ATAccount("TEST1", new Dictionary())); var post = new CommonPost(0, ATThreadComposer.AT_POST_RENDER_RULES) { Message = diff --git a/Presence.Posting.Lib.Tests/ConsoleConnectionTests.cs b/Presence.Posting.Lib.Tests/ConsoleConnectionTests.cs index 601fc6b..08e1ef3 100644 --- a/Presence.Posting.Lib.Tests/ConsoleConnectionTests.cs +++ b/Presence.Posting.Lib.Tests/ConsoleConnectionTests.cs @@ -1,5 +1,6 @@ using Presence.Posting.Lib.Connections; using Presence.Posting.Lib.Connections.Console; +using Presence.Posting.Lib.Constants; namespace Presence.Posting.Lib.Tests; @@ -10,7 +11,7 @@ public class ConsoleConnectionTests [TestMethod] public async Task ConsoleConnection_Connects_WithSingleCredential() { - var connection = new ConsoleConnection(new ConsoleAccount("TEST", new Dictionary() { { NetworkCredentialType.PrintPrefix, "TEST> " } })); + var connection = new ConsoleConnection(new ConsoleAccount("TEST", new Dictionary() { { NetworkCredentialType.PrintPrefix, "TEST> " } })); var ok = await connection.ConnectAsync(); Assert.IsTrue(ok); } @@ -18,7 +19,7 @@ public async Task ConsoleConnection_Connects_WithSingleCredential() [TestMethod] public async Task ConnectionFactory_Creates_ConsoleConnection() { - var connection = ConnectionFactory.CreateConsole("TEST", new Dictionary() { { NetworkCredentialType.PrintPrefix, "TEST> " } }); + var connection = ConnectionFactory.CreateConsole("TEST", new Dictionary() { { NetworkCredentialType.PrintPrefix, "TEST> " } }); Assert.IsNotNull(connection); await connection.ConnectAsync(); Assert.IsTrue(connection.Connected); diff --git a/Presence.Posting.Lib.Tests/CredentialTests.cs b/Presence.Posting.Lib.Tests/CredentialTests.cs index 326668c..65a4290 100644 --- a/Presence.Posting.Lib.Tests/CredentialTests.cs +++ b/Presence.Posting.Lib.Tests/CredentialTests.cs @@ -1,4 +1,5 @@ using Presence.Posting.Lib.Connections; +using Presence.Posting.Lib.Constants; namespace Presence.Posting.Lib.Tests; @@ -9,7 +10,7 @@ public class CredentialTests [TestMethod] public void ATAccount_Validates() { - var account = new ATAccount("TEST", new Dictionary + var account = new ATAccount("TEST", new Dictionary { }); var (valid, errors) = account.Validate(); diff --git a/Presence.Posting.Lib.Tests/EnvironmentConfigReaderTests.cs b/Presence.Posting.Lib.Tests/EnvironmentConfigReaderTests.cs new file mode 100644 index 0000000..3adbc36 --- /dev/null +++ b/Presence.Posting.Lib.Tests/EnvironmentConfigReaderTests.cs @@ -0,0 +1,119 @@ +using System.Collections; +using System.Text.Json; +using Presence.Posting.Lib.Config; +using Presence.Posting.Lib.Constants; +using Presence.SocialFormat.Lib.Networks; + +namespace Presence.Posting.Lib.Tests; + +[TestClass] +public class EnvironmentConfigReaderTests +{ + + [TestMethod] + [TestCategory("Unit")] + public void EnvironmentConfigReader_ExtractsIgnoringCase_MultipleAccounts() + { + var environments = new List() + { + new Dictionary() + { + { ConfigKeys.ACCOUNTS_ENV_KEY, "TEST0,TEST1" }, + { "TEST0_CONSOLE_PRINTPREFIX", "printprefix:test0" }, + { "TEST1_AT_ACCOUNTNAME", "account:test1" }, + { "TEST1_AT_APPPASSWORD", "password:test1" } + }, + new Dictionary() + { + { ConfigKeys.ACCOUNTS_ENV_KEY, "TEST0,TEST1" }, + { "TEST0_console_printprefix", "printprefix:test0" }, + { "TEST1_at_accountname", "account:test1" }, + { "TEST1_at_apppassword", "password:test1" } + } + }; + + foreach (var env in environments) + { + var reader = new EnvironmentConfigReader(env); + Assert.AreEqual(2, reader.Count); + Assert.IsTrue(reader.ContainsKey("TEST0")); + Assert.IsTrue(reader.ContainsKey("TEST1")); + Assert.AreEqual("printprefix:test0", reader["TEST0"][SocialNetwork.Console][NetworkCredentialType.PrintPrefix]); + Assert.AreEqual("account:test1", reader["TEST1"][SocialNetwork.AT][NetworkCredentialType.AccountName]); + Assert.AreEqual("password:test1", reader["TEST1"][SocialNetwork.AT][NetworkCredentialType.AppPassword]); + } + } + + [TestMethod] + [TestCategory("Unit")] + public void EnvironmentConfigReader_ExtractsOnly_AccountsInTheAccountsVariable() + { + var env = new Dictionary() + { + { ConfigKeys.ACCOUNTS_ENV_KEY, "TEST0,TEST1" }, + { "TEST0_CONSOLE_PRINTPREFIX", "printprefix:test0" }, + { "TEST1_AT_ACCOUNTNAME", "account:test1" }, + { "TEST1_AT_APPPASSWORD", "password:test1" }, + { "TEST2_AT_ACCOUNTNAME", "account:test2" }, + { "TEST2_AT_APPPASSWORD", "password:test2" }, + }; + var reader = new EnvironmentConfigReader(env); + Assert.AreEqual(2, reader.Count); + Assert.IsTrue(reader.ContainsKey("TEST0")); + Assert.IsTrue(reader.ContainsKey("TEST1")); + Assert.IsFalse(reader.ContainsKey("TEST2")); + } + + [TestMethod] + [TestCategory("Unit")] + public void EnvironmentConfigReader_CanExtract_JsonConfiguration() + { + var env = new Dictionary() + { + { ConfigKeys.JSON_DATA_ENV_KEY, @" + { + ""PRESENCE_ACCOUNTS"": ""TEST0,TEST1"", + ""TEST0_CONSOLE_PRINTPREFIX"": ""printprefix:test0"", + ""TEST1_AT_ACCOUNTNAME"": ""account:test1"", + ""TEST1_AT_APPPASSWORD"": ""password:test1"" + }" } + }; + var reader = new EnvironmentConfigReader(env); + Assert.AreEqual(2, reader.Count, JsonSerializer.Serialize(reader)); + Assert.IsTrue(reader.ContainsKey("TEST0")); + Assert.IsTrue(reader.ContainsKey("TEST1")); + Assert.AreEqual("printprefix:test0", reader["TEST0"][SocialNetwork.Console][NetworkCredentialType.PrintPrefix]); + Assert.AreEqual("account:test1", reader["TEST1"][SocialNetwork.AT][NetworkCredentialType.AccountName]); + Assert.AreEqual("password:test1", reader["TEST1"][SocialNetwork.AT][NetworkCredentialType.AppPassword]); + } + + [TestMethod] + [TestCategory("Unit")] + public void EnvironmentConfigReader_JsonConfiguration_Supersedes_OtherKeys() + { + var env = new Dictionary() + { + { + ConfigKeys.JSON_DATA_ENV_KEY, @" + { + ""PRESENCE_ACCOUNTS"": ""TEST0,TEST1"", + ""TEST0_CONSOLE_PRINTPREFIX"": ""json:printprefix:test0"", + ""TEST1_AT_ACCOUNTNAME"": ""json:account:test1"", + ""TEST1_AT_APPPASSWORD"": ""json:password:test1"" + }" + }, + { "PRESENCE_ACCOUNTS", "TEST0" }, + { "TEST0_CONSOLE_PRINTPREFIX", "ignored:printprefix:test0" }, + { "TEST1_AT_ACCOUNTNAME", "ignored:account:test1" }, + { "TEST1_AT_APPPASSWORD", "ignored:password:test1" } + }; + var reader = new EnvironmentConfigReader(env); + Assert.AreEqual(2, reader.Count, JsonSerializer.Serialize(reader)); + Assert.IsTrue(reader.ContainsKey("TEST0")); + Assert.IsTrue(reader.ContainsKey("TEST1")); + Assert.AreEqual("json:printprefix:test0", reader["TEST0"][SocialNetwork.Console][NetworkCredentialType.PrintPrefix]); + Assert.AreEqual("json:account:test1", reader["TEST1"][SocialNetwork.AT][NetworkCredentialType.AccountName]); + Assert.AreEqual("json:password:test1", reader["TEST1"][SocialNetwork.AT][NetworkCredentialType.AppPassword]); + } + +} \ No newline at end of file diff --git a/Presence.Posting.Lib.Tests/ConfigTests.cs b/Presence.Posting.Lib.Tests/IntegrationConfigTests.cs similarity index 88% rename from Presence.Posting.Lib.Tests/ConfigTests.cs rename to Presence.Posting.Lib.Tests/IntegrationConfigTests.cs index c84c96b..5564b87 100644 --- a/Presence.Posting.Lib.Tests/ConfigTests.cs +++ b/Presence.Posting.Lib.Tests/IntegrationConfigTests.cs @@ -1,13 +1,14 @@ -using Presence.Posting.Lib.Connections; +using Presence.Posting.Lib.Config; +using Presence.Posting.Lib.Constants; using Presence.SocialFormat.Lib.Networks; namespace Presence.Posting.Lib.Tests; [TestClass] -[TestCategory("Integration")] -public class ConfigTests +public class IntegrationConfigTests { [TestMethod] + [TestCategory("Integration")] public void ConfigPresent() { var env = Environment.GetEnvironmentVariables(); @@ -26,5 +27,4 @@ public void ConfigPresent() Assert.IsTrue(environment["TEST1"][SocialNetwork.AT].ContainsKey(NetworkCredentialType.AccountName)); Assert.IsTrue(environment["TEST1"][SocialNetwork.AT].ContainsKey(NetworkCredentialType.AppPassword)); } - } \ No newline at end of file diff --git a/Presence.Posting.Lib/Connections/EnvironmentConfigReader.cs b/Presence.Posting.Lib/Config/EnvironmentConfigReader.cs similarity index 60% rename from Presence.Posting.Lib/Connections/EnvironmentConfigReader.cs rename to Presence.Posting.Lib/Config/EnvironmentConfigReader.cs index 7989fee..5fd162c 100644 --- a/Presence.Posting.Lib/Connections/EnvironmentConfigReader.cs +++ b/Presence.Posting.Lib/Config/EnvironmentConfigReader.cs @@ -1,18 +1,24 @@ using System.Collections; +using Presence.Posting.Lib.Constants; using Presence.Posting.Lib.Helpers; using Presence.SocialFormat.Lib.Networks; -namespace Presence.Posting.Lib.Connections; +namespace Presence.Posting.Lib.Config; -public class EnvironmentConfigReader : Dictionary>> +public class EnvironmentConfigReader : Dictionary>> { - public const string ACCOUNTS_ENV_KEY = "PRESENCE_ACCOUNTS"; - public EnvironmentConfigReader(IDictionary env) { - // extract account prefixes - var strings = env.ToStringDictionary(); - var prefixes = strings[ACCOUNTS_ENV_KEY].Split(','); + // If the JSON data key is present use that in preference to other environment variables. + // Otherwise, convert the the environment dictionary to a simple string dictionary. + var strings = (env.Contains(ConfigKeys.JSON_DATA_ENV_KEY) + ? JsonConfigReader.ReadJsonConfig(env[ConfigKeys.JSON_DATA_ENV_KEY] as string) + : null) ?? env.ToStringDictionary(); + + // extract prefixes + var prefixes = strings.ContainsKey(ConfigKeys.ACCOUNTS_ENV_KEY) && !string.IsNullOrWhiteSpace(strings[ConfigKeys.ACCOUNTS_ENV_KEY]) + ? strings[ConfigKeys.ACCOUNTS_ENV_KEY]!.Split(',') + : throw new ArgumentException($"Please provide a comma separated list of account prefixes in config key: {ConfigKeys.ACCOUNTS_ENV_KEY}"); // extract credentials per network per prefix var credentials = prefixes @@ -37,9 +43,9 @@ public EnvironmentConfigReader(IDictionary env) } } - private Dictionary ExtractCredentials(string prefix, SocialNetwork network, IDictionary env) + private Dictionary ExtractCredentials(string prefix, SocialNetwork network, IDictionary env) => env - .ToDictionary(kv => kv.Key.Trim(), kv => kv.Value.Trim()) + .ToDictionary(kv => kv.Key.Trim(), kv => kv.Value?.Trim()) .Where(kv => kv.Key.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) .ToDictionary(kv => kv.Key.Substring(prefix.Length).Trim('_'), kv => kv.Value) .Where(kv => kv.Key.StartsWith(network.ToString(), StringComparison.OrdinalIgnoreCase)) diff --git a/Presence.Posting.Lib/Config/JsonConfigReader.cs b/Presence.Posting.Lib/Config/JsonConfigReader.cs new file mode 100644 index 0000000..ad3f127 --- /dev/null +++ b/Presence.Posting.Lib/Config/JsonConfigReader.cs @@ -0,0 +1,13 @@ +using System.Text.Json; + +namespace Presence.Posting.Lib.Config; + +public class JsonConfigReader +{ + public static IDictionary? ReadJsonConfig(string? json) => + string.IsNullOrWhiteSpace(json) + ? null + : JsonSerializer.Deserialize>(json); + // ?.Where(kv => !string.IsNullOrWhiteSpace(kv.Value)) + // .ToDictionary(kv => kv.Key, kv => kv.Value!); +} \ No newline at end of file diff --git a/Presence.Posting.Lib/Connections/AT/ATAccount.cs b/Presence.Posting.Lib/Connections/AT/ATAccount.cs index f7d82c0..f3c4c76 100644 --- a/Presence.Posting.Lib/Connections/AT/ATAccount.cs +++ b/Presence.Posting.Lib/Connections/AT/ATAccount.cs @@ -1,10 +1,11 @@ +using Presence.Posting.Lib.Constants; using Presence.SocialFormat.Lib.Networks; namespace Presence.Posting.Lib.Connections; public class ATAccount : AbstractNetworkAccount { - public ATAccount(string prefix, IDictionary credentials) : base(prefix, credentials) + public ATAccount(string prefix, IDictionary credentials) : base(prefix, credentials) { } diff --git a/Presence.Posting.Lib/Connections/AT/ATConnection.cs b/Presence.Posting.Lib/Connections/AT/ATConnection.cs index c19c8ac..57536d7 100644 --- a/Presence.Posting.Lib/Connections/AT/ATConnection.cs +++ b/Presence.Posting.Lib/Connections/AT/ATConnection.cs @@ -9,6 +9,7 @@ using FishyFlip.Lexicon.Com.Atproto.Repo; using FishyFlip.Models; using FishyFlip.Tools; +using Presence.Posting.Lib.Constants; using Presence.SocialFormat.Lib.Helpers; using Presence.SocialFormat.Lib.Post; @@ -56,8 +57,8 @@ protected override async Task ConnectImplementationAsync(INetworkAccount c await RateLimitAsync(); var (session, error) = await Protocol.AuthenticateWithPasswordResultAsync( - credentials![NetworkCredentialType.AccountName], - credentials![NetworkCredentialType.AppPassword]); + credentials![NetworkCredentialType.AccountName]!, + credentials![NetworkCredentialType.AppPassword]!); if (error != null) { diff --git a/Presence.Posting.Lib/Connections/AbstractNetworkAccount.cs b/Presence.Posting.Lib/Connections/AbstractNetworkAccount.cs index 14f6f62..b183beb 100644 --- a/Presence.Posting.Lib/Connections/AbstractNetworkAccount.cs +++ b/Presence.Posting.Lib/Connections/AbstractNetworkAccount.cs @@ -1,13 +1,14 @@ +using Presence.Posting.Lib.Constants; using Presence.SocialFormat.Lib.Networks; namespace Presence.Posting.Lib.Connections; -public abstract class AbstractNetworkAccount : Dictionary, INetworkAccount +public abstract class AbstractNetworkAccount : Dictionary, INetworkAccount { - protected AbstractNetworkAccount(string accountPrefix, IDictionary? credentials = null) + protected AbstractNetworkAccount(string accountPrefix, IDictionary? credentials = null) { AccountPrefix = accountPrefix; - SetCredentials(credentials ?? new Dictionary()); + SetCredentials(credentials ?? new Dictionary()); } public string AccountPrefix { get; init; } @@ -25,7 +26,7 @@ protected AbstractNetworkAccount(string accountPrefix, IDictionary credentials) + private void SetCredentials(IDictionary credentials) { foreach (var (key, value) in credentials) { diff --git a/Presence.Posting.Lib/Connections/ConnectionFactory.cs b/Presence.Posting.Lib/Connections/ConnectionFactory.cs index e878e33..6e76b82 100644 --- a/Presence.Posting.Lib/Connections/ConnectionFactory.cs +++ b/Presence.Posting.Lib/Connections/ConnectionFactory.cs @@ -1,6 +1,8 @@ using System.Collections; +using Presence.Posting.Lib.Config; using Presence.Posting.Lib.Connections.AT; using Presence.Posting.Lib.Connections.Console; +using Presence.Posting.Lib.Constants; using Presence.SocialFormat.Lib.Networks; namespace Presence.Posting.Lib.Connections; @@ -13,7 +15,7 @@ public static IEnumerable CreateConnections(IDictionary env) return environment.Keys.SelectMany((prefix) => environment[prefix].Keys.Select((network) => CreateConnection(prefix, network, environment[prefix][network]))); } - public static INetworkConnection CreateConnection(string prefix, SocialNetwork network, IDictionary credentials) + public static INetworkConnection CreateConnection(string prefix, SocialNetwork network, IDictionary credentials) { return network switch { @@ -23,9 +25,9 @@ public static INetworkConnection CreateConnection(string prefix, SocialNetwork n }; } - public static ConsoleConnection CreateConsole(string prefix, IDictionary credentials) + public static ConsoleConnection CreateConsole(string prefix, IDictionary credentials) => new ConsoleConnection(new ConsoleAccount(prefix, credentials)); - public static ATConnection CreateAT(string prefix, IDictionary credentials) + public static ATConnection CreateAT(string prefix, IDictionary credentials) => new ATConnection(new ATAccount(prefix, credentials)); } \ No newline at end of file diff --git a/Presence.Posting.Lib/Connections/Console/ConsoleAccount.cs b/Presence.Posting.Lib/Connections/Console/ConsoleAccount.cs index a1b246c..b05f197 100644 --- a/Presence.Posting.Lib/Connections/Console/ConsoleAccount.cs +++ b/Presence.Posting.Lib/Connections/Console/ConsoleAccount.cs @@ -1,11 +1,12 @@ using Presence.Posting.Lib.Connections; +using Presence.Posting.Lib.Constants; using Presence.SocialFormat.Lib.Networks; namespace Presence.Posting.Lib; public class ConsoleAccount : AbstractNetworkAccount { - public ConsoleAccount(string accountPrefix, IDictionary? credentials = null) : base(accountPrefix, credentials) + public ConsoleAccount(string accountPrefix, IDictionary? credentials = null) : base(accountPrefix, credentials) { } diff --git a/Presence.Posting.Lib/Connections/Console/ConsoleConnection.cs b/Presence.Posting.Lib/Connections/Console/ConsoleConnection.cs index cd62fc1..e571fe6 100644 --- a/Presence.Posting.Lib/Connections/Console/ConsoleConnection.cs +++ b/Presence.Posting.Lib/Connections/Console/ConsoleConnection.cs @@ -1,4 +1,5 @@ using System.Diagnostics.CodeAnalysis; +using Presence.Posting.Lib.Constants; using Presence.SocialFormat.Lib.Post; namespace Presence.Posting.Lib.Connections.Console; diff --git a/Presence.Posting.Lib/Connections/INetworkAccount.cs b/Presence.Posting.Lib/Connections/INetworkAccount.cs index a90f7e9..1f96746 100644 --- a/Presence.Posting.Lib/Connections/INetworkAccount.cs +++ b/Presence.Posting.Lib/Connections/INetworkAccount.cs @@ -1,8 +1,9 @@ +using Presence.Posting.Lib.Constants; using Presence.SocialFormat.Lib.Networks; namespace Presence.Posting.Lib.Connections; -public interface INetworkAccount : IDictionary +public interface INetworkAccount : IDictionary { public SocialNetwork SocialNetwork { get; } public string AccountPrefix { get; } diff --git a/Presence.Posting.Lib/Constants/ConfigKeys.cs b/Presence.Posting.Lib/Constants/ConfigKeys.cs new file mode 100644 index 0000000..84d2a76 --- /dev/null +++ b/Presence.Posting.Lib/Constants/ConfigKeys.cs @@ -0,0 +1,8 @@ +namespace Presence.Posting.Lib.Constants; + +public static class ConfigKeys +{ + public const string JSON_DATA_ENV_KEY = "PRESENCE_CONFIG_JSON"; + public const string ACCOUNTS_ENV_KEY = "PRESENCE_ACCOUNTS"; + +} \ No newline at end of file diff --git a/Presence.Posting.Lib/Connections/NetworkCredentialType.cs b/Presence.Posting.Lib/Constants/NetworkCredentialType.cs similarity index 69% rename from Presence.Posting.Lib/Connections/NetworkCredentialType.cs rename to Presence.Posting.Lib/Constants/NetworkCredentialType.cs index 558e257..4c01f0b 100644 --- a/Presence.Posting.Lib/Connections/NetworkCredentialType.cs +++ b/Presence.Posting.Lib/Constants/NetworkCredentialType.cs @@ -1,4 +1,4 @@ -namespace Presence.Posting.Lib.Connections; +namespace Presence.Posting.Lib.Constants; public enum NetworkCredentialType { diff --git a/Presence.Posting.Lib/DTO/ThreadPostSummary.cs b/Presence.Posting.Lib/DTO/ThreadPostSummary.cs index 44a7c8d..860d5bc 100644 --- a/Presence.Posting.Lib/DTO/ThreadPostSummary.cs +++ b/Presence.Posting.Lib/DTO/ThreadPostSummary.cs @@ -1,5 +1,4 @@ using System.Text.Json.Serialization; -using Presence.Posting.Lib.Connections; using Presence.SocialFormat.Lib.Networks; namespace Presence.Posting.Lib.DTO; diff --git a/Presence.Posting.Lib/Helpers/DictionaryExtension.cs b/Presence.Posting.Lib/Helpers/DictionaryExtension.cs index e82e902..04af324 100644 --- a/Presence.Posting.Lib/Helpers/DictionaryExtension.cs +++ b/Presence.Posting.Lib/Helpers/DictionaryExtension.cs @@ -4,8 +4,8 @@ namespace Presence.Posting.Lib.Helpers; public static class DictionaryExtension { - public static IDictionary ToStringDictionary(this IDictionary dict) - => dict is IDictionary strings + public static IDictionary ToStringDictionary(this IDictionary dict) + => dict is IDictionary strings ? strings - : dict.Cast().ToDictionary(kv => (string)kv.Key, kv => (string)kv.Value!); + : dict.Cast().ToDictionary(kv => (string)kv.Key, kv => (string?)kv.Value); } \ No newline at end of file