Libation 4.0 prep: in process of migrating to new settings files
This commit is contained in:
parent
8391e43b03
commit
643ae09b2b
162
InternalUtilities/Accounts.cs
Normal file
162
InternalUtilities/Accounts.cs
Normal file
@ -0,0 +1,162 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using AudibleApi;
|
||||
using AudibleApi.Authorization;
|
||||
using Dinah.Core;
|
||||
using Dinah.Core.IO;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace InternalUtilities
|
||||
{
|
||||
public class AccountsPersister : JsonFilePersister<Accounts>
|
||||
{
|
||||
/// <summary>Alias for Target </summary>
|
||||
public Accounts Accounts => Target;
|
||||
|
||||
/// <summary>uses path. create file if doesn't yet exist</summary>
|
||||
public AccountsPersister(Accounts target, string path, string jsonPath = null)
|
||||
: base(target, path, jsonPath) { }
|
||||
|
||||
/// <summary>load from existing file</summary>
|
||||
public AccountsPersister(string path, string jsonPath = null)
|
||||
: base(path, jsonPath) { }
|
||||
|
||||
protected override JsonSerializerSettings GetSerializerSettings()
|
||||
=> Identity.GetJsonSerializerSettings();
|
||||
}
|
||||
public class Accounts : Updatable
|
||||
{
|
||||
public event EventHandler Updated;
|
||||
private void update(object sender = null, EventArgs e = null)
|
||||
=> Updated?.Invoke(this, new EventArgs());
|
||||
|
||||
public Accounts() { }
|
||||
|
||||
// for some reason this will make the json instantiator use _accountsSettings_json.set()
|
||||
[JsonConstructor]
|
||||
protected Accounts(List<Account> accounts) { }
|
||||
|
||||
#region AccountsSettings
|
||||
private List<Account> _accountsSettings_backing = new List<Account>();
|
||||
[JsonProperty(PropertyName = "AccountsSettings")]
|
||||
private List<Account> _accountsSettings_json
|
||||
{
|
||||
get => _accountsSettings_backing;
|
||||
// 'set' is only used by json deser
|
||||
set
|
||||
{
|
||||
_accountsSettings_backing = value;
|
||||
|
||||
if (_accountsSettings_backing is null)
|
||||
return;
|
||||
|
||||
foreach (var acct in _accountsSettings_backing)
|
||||
acct.Updated += update;
|
||||
|
||||
update();
|
||||
}
|
||||
}
|
||||
[JsonIgnore]
|
||||
public IReadOnlyList<Account> AccountsSettings => _accountsSettings_json.AsReadOnly();
|
||||
#endregion
|
||||
|
||||
public static Accounts FromJson(string json)
|
||||
=> JsonConvert.DeserializeObject<Accounts>(json, Identity.GetJsonSerializerSettings());
|
||||
|
||||
public string ToJson(Formatting formatting = Formatting.Indented)
|
||||
=> JsonConvert.SerializeObject(this, formatting, Identity.GetJsonSerializerSettings());
|
||||
|
||||
public void UNITTEST_Seed(Account account)
|
||||
{
|
||||
_accountsSettings_backing.Add(account);
|
||||
update();
|
||||
}
|
||||
|
||||
// replace UNITTEST_Seed
|
||||
|
||||
// when creating Account object (get, update, insert), subscribe to it's update. including all new ones on initial load
|
||||
// removing: unsubscribe
|
||||
|
||||
// IEnumerable<Account> GetAllAccounts
|
||||
|
||||
// void UpsertAccount (id, locale)
|
||||
// if not exists
|
||||
// create account w/null identity
|
||||
// save in file
|
||||
// return Account?
|
||||
// return bool/enum of whether is newly created?
|
||||
|
||||
// how to persist edits to [Account] obj?
|
||||
// account name, decryptkey, id tokens, ...
|
||||
// persistence happens in [Accounts], not [Account]. an [Account] accidentally created directly shouldn't mess up expected workflow ???
|
||||
}
|
||||
public class Account : Updatable
|
||||
{
|
||||
public event EventHandler Updated;
|
||||
private void update(object sender = null, EventArgs e = null)
|
||||
=> Updated?.Invoke(this, new EventArgs());
|
||||
|
||||
// canonical. immutable. email or phone number
|
||||
public string AccountId { get; }
|
||||
|
||||
// user-friendly, non-canonical name. mutable
|
||||
private string _accountName;
|
||||
public string AccountName
|
||||
{
|
||||
get => _accountName;
|
||||
set
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
return;
|
||||
var v = value.Trim();
|
||||
if (v == _accountName)
|
||||
return;
|
||||
_accountName = v;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
private string _decryptKey = "";
|
||||
public string DecryptKey
|
||||
{
|
||||
get => _decryptKey;
|
||||
set
|
||||
{
|
||||
var v = (value ?? "").Trim();
|
||||
if (v == _decryptKey)
|
||||
return;
|
||||
_decryptKey = v;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
private Identity _identity;
|
||||
public Identity IdentityTokens
|
||||
{
|
||||
get => _identity;
|
||||
set
|
||||
{
|
||||
if (_identity is null && value is null)
|
||||
return;
|
||||
|
||||
if (_identity != null)
|
||||
_identity.Updated -= update;
|
||||
|
||||
if (value != null)
|
||||
value.Updated += update;
|
||||
|
||||
_identity = value;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public Locale Locale => IdentityTokens?.Locale;
|
||||
|
||||
public Account(string accountId)
|
||||
{
|
||||
ArgumentValidator.EnsureNotNullOrWhiteSpace(accountId, nameof(accountId));
|
||||
AccountId = accountId.Trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -12,11 +12,11 @@ namespace InternalUtilities
|
||||
{
|
||||
public static class AudibleApiActions
|
||||
{
|
||||
public static async Task<Api> GetApiAsyncLegacy30(ILoginCallback loginCallback = null)
|
||||
public static async Task<Api> GetApiAsyncLegacy30Async()
|
||||
{
|
||||
Localization.SetLocale(Configuration.Instance.LocaleCountryCode);
|
||||
|
||||
return await EzApiCreator.GetApiAsync(AudibleApiStorage.AccountsSettingsFileLegacy30, null, loginCallback);
|
||||
return await EzApiCreator.GetApiAsync(AudibleApiStorage.AccountsSettingsFileLegacy30);
|
||||
}
|
||||
|
||||
/// <summary>USE THIS from within Libation. It wraps the call with correct JSONPath</summary>
|
||||
|
||||
@ -14,6 +14,15 @@ namespace InternalUtilities
|
||||
|
||||
public static string AccountsSettingsFile => Path.Combine(Configuration.Instance.LibationFiles, "AccountsSettings.json");
|
||||
|
||||
public static void EnsureAccountsSettingsFileExists()
|
||||
{
|
||||
if (File.Exists(AccountsSettingsFile))
|
||||
return;
|
||||
|
||||
// saves. BEWARE: this will overwrite an existing file
|
||||
_ = new AccountsPersister(new Accounts(), AccountsSettingsFile);
|
||||
}
|
||||
|
||||
// TEMP
|
||||
public static string GetJsonPath() => null;
|
||||
|
||||
|
||||
@ -82,6 +82,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WindowsDesktopUtilities", "
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibationLauncher", "LibationLauncher\LibationLauncher.csproj", "{F3B04A3A-20C8-4582-A54A-715AF6A5D859}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "0 Libation Tests", "0 Libation Tests", "{67E66E82-5532-4440-AFB3-9FB1DF9DEF53}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InternalUtilities.Tests", "_Tests\InternalUtilities.Tests\InternalUtilities.Tests.csproj", "{8447C956-B03E-4F59-9DD4-877793B849D9}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -200,6 +204,10 @@ Global
|
||||
{F3B04A3A-20C8-4582-A54A-715AF6A5D859}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F3B04A3A-20C8-4582-A54A-715AF6A5D859}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F3B04A3A-20C8-4582-A54A-715AF6A5D859}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8447C956-B03E-4F59-9DD4-877793B849D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8447C956-B03E-4F59-9DD4-877793B849D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8447C956-B03E-4F59-9DD4-877793B849D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8447C956-B03E-4F59-9DD4-877793B849D9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@ -233,6 +241,7 @@ Global
|
||||
{059CE32C-9AD6-45E9-A166-790DFFB0B730} = {43E3ACB3-E0BC-4370-8DBB-E3720C8C8FD1}
|
||||
{E7EFD64D-6630-4426-B09C-B6862A92E3FD} = {F0CBB7A7-D3FB-41FF-8F47-CF3F6A592249}
|
||||
{F3B04A3A-20C8-4582-A54A-715AF6A5D859} = {8679CAC8-9164-4007-BDD2-F004810EDA14}
|
||||
{8447C956-B03E-4F59-9DD4-877793B849D9} = {67E66E82-5532-4440-AFB3-9FB1DF9DEF53}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {615E00ED-BAEF-4E8E-A92A-9B82D87942A9}
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
<!-- <PublishSingleFile>true</PublishSingleFile> -->
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
|
||||
<Version>3.1.12.95</Version>
|
||||
<Version>3.1.12.120</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@ -24,7 +24,7 @@ namespace LibationLauncher
|
||||
|
||||
createSettings();
|
||||
|
||||
ensureIdentityFile();
|
||||
AudibleApiStorage.EnsureAccountsSettingsFileExists();
|
||||
migrateIdentityFile();
|
||||
updateSettingsFile();
|
||||
|
||||
@ -82,18 +82,6 @@ namespace LibationLauncher
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
private static void ensureIdentityFile()
|
||||
{
|
||||
if (File.Exists(AudibleApiStorage.AccountsSettingsFile))
|
||||
return;
|
||||
|
||||
var jObj = new JObject {
|
||||
{ "AccountsSettings", new JArray() }
|
||||
};
|
||||
var contents = jObj.ToString(Formatting.Indented);
|
||||
File.WriteAllText(AudibleApiStorage.AccountsSettingsFile, contents);
|
||||
}
|
||||
|
||||
private static void migrateIdentityFile()
|
||||
{
|
||||
if (!File.Exists(AudibleApiStorage.AccountsSettingsFileLegacy30))
|
||||
@ -102,8 +90,9 @@ namespace LibationLauncher
|
||||
try
|
||||
{
|
||||
//
|
||||
// for all in here: read directly from json file => JObject. A lot of this is legacy; don't rely on applicable POCOs
|
||||
// in here: read directly from json file => JObject. A lot of this is legacy; don't rely on applicable POCOs
|
||||
//
|
||||
|
||||
var legacyContents = File.ReadAllText(AudibleApiStorage.AccountsSettingsFileLegacy30);
|
||||
var legacyJObj = JObject.Parse(legacyContents);
|
||||
|
||||
@ -127,6 +116,11 @@ namespace LibationLauncher
|
||||
}
|
||||
}
|
||||
|
||||
// create new account stub in new file
|
||||
var api = AudibleApiActions.GetApiAsyncLegacy30Async().GetAwaiter().GetResult();
|
||||
var email = api.GetEmailAsync().GetAwaiter().GetResult();
|
||||
var locale = api.GetLocaleAsync(AudibleApi.CustomerOptions.All).GetAwaiter().GetResult();
|
||||
|
||||
// more to do?
|
||||
|
||||
}
|
||||
|
||||
451
_Tests/InternalUtilities.Tests/AccountTests.cs
Normal file
451
_Tests/InternalUtilities.Tests/AccountTests.cs
Normal file
@ -0,0 +1,451 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AudibleApi;
|
||||
using AudibleApi.Authorization;
|
||||
using Dinah.Core;
|
||||
using FluentAssertions;
|
||||
using InternalUtilities;
|
||||
using Microsoft.VisualStudio.TestPlatform.Common.Filtering;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using Moq.Protected;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using TestAudibleApiCommon;
|
||||
using TestCommon;
|
||||
using static AuthorizationShared.Shared;
|
||||
using static AuthorizationShared.Shared.AccessTokenTemporality;
|
||||
using static TestAudibleApiCommon.ComputedTestValues;
|
||||
|
||||
namespace AccountsTests
|
||||
{
|
||||
[TestClass]
|
||||
public class FromJson
|
||||
{
|
||||
[TestMethod]
|
||||
public void _0_accounts()
|
||||
{
|
||||
var json = @"
|
||||
{
|
||||
""AccountsSettings"": []
|
||||
}
|
||||
".Trim();
|
||||
var accounts = Accounts.FromJson(json);
|
||||
accounts.AccountsSettings.Count.Should().Be(0);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void _1_account_new()
|
||||
{
|
||||
var json = @"
|
||||
{
|
||||
""AccountsSettings"": [
|
||||
{
|
||||
""AccountId"": ""cng"",
|
||||
""AccountName"": ""my main login"",
|
||||
""DecryptKey"": ""asdfasdf"",
|
||||
""IdentityTokens"": null
|
||||
}
|
||||
]
|
||||
}
|
||||
".Trim();
|
||||
var accounts = Accounts.FromJson(json);
|
||||
accounts.AccountsSettings.Count.Should().Be(1);
|
||||
accounts.AccountsSettings[0].AccountId.Should().Be("cng");
|
||||
accounts.AccountsSettings[0].IdentityTokens.Should().BeNull();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void _1_account_populated()
|
||||
{
|
||||
var id = GetIdentityJson(Future);
|
||||
|
||||
var json = $@"
|
||||
{{
|
||||
""AccountsSettings"": [
|
||||
{{
|
||||
""AccountId"": ""cng"",
|
||||
""AccountName"": ""my main login"",
|
||||
""DecryptKey"": ""asdfasdf"",
|
||||
""IdentityTokens"": {id}
|
||||
}}
|
||||
]
|
||||
}}
|
||||
".Trim();
|
||||
var accounts = Accounts.FromJson(json);
|
||||
accounts.AccountsSettings.Count.Should().Be(1);
|
||||
accounts.AccountsSettings[0].AccountId.Should().Be("cng");
|
||||
accounts.AccountsSettings[0].IdentityTokens.Should().NotBeNull();
|
||||
accounts.AccountsSettings[0].IdentityTokens.ExistingAccessToken.TokenValue.Should().Be(AccessTokenValue);
|
||||
}
|
||||
}
|
||||
|
||||
[TestClass]
|
||||
public class ToJson
|
||||
{
|
||||
[TestMethod]
|
||||
public void serialize()
|
||||
{
|
||||
var id = JsonConvert.SerializeObject(Identity.Empty, Identity.GetJsonSerializerSettings());
|
||||
var jsonIn = $@"
|
||||
{{
|
||||
""AccountsSettings"": [
|
||||
{{
|
||||
""AccountId"": ""cng"",
|
||||
""AccountName"": ""my main login"",
|
||||
""DecryptKey"": ""asdfasdf"",
|
||||
""IdentityTokens"": {id}
|
||||
}}
|
||||
]
|
||||
}}
|
||||
".Trim();
|
||||
var accounts = Accounts.FromJson(jsonIn);
|
||||
|
||||
var jsonOut = accounts.ToJson();
|
||||
jsonOut.Should().Be(@"
|
||||
{
|
||||
""AccountsSettings"": [
|
||||
{
|
||||
""AccountId"": ""cng"",
|
||||
""AccountName"": ""my main login"",
|
||||
""DecryptKey"": ""asdfasdf"",
|
||||
""IdentityTokens"": {
|
||||
""LocaleName"": ""[empty]"",
|
||||
""ExistingAccessToken"": {
|
||||
""TokenValue"": ""Atna|"",
|
||||
""Expires"": ""9999-12-31T23:59:59.9999999""
|
||||
},
|
||||
""PrivateKey"": null,
|
||||
""AdpToken"": null,
|
||||
""RefreshToken"": null,
|
||||
""Cookies"": []
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
".Trim());
|
||||
}
|
||||
}
|
||||
|
||||
public class AccountsPersisterTestBase
|
||||
{
|
||||
protected string TestFile;
|
||||
|
||||
protected void WriteToTestFile(string contents)
|
||||
=> File.WriteAllText(TestFile, contents);
|
||||
|
||||
[TestInitialize]
|
||||
public void TestInit()
|
||||
=> TestFile = Guid.NewGuid() + ".txt";
|
||||
|
||||
[TestCleanup]
|
||||
public void TestCleanup()
|
||||
{
|
||||
if (File.Exists(TestFile))
|
||||
File.Delete(TestFile);
|
||||
}
|
||||
}
|
||||
|
||||
[TestClass]
|
||||
public class ctor : AccountsPersisterTestBase
|
||||
{
|
||||
[TestMethod]
|
||||
public void create_file()
|
||||
{
|
||||
File.Exists(TestFile).Should().BeFalse();
|
||||
var accounts = new Accounts();
|
||||
_ = new AccountsPersister(accounts, TestFile);
|
||||
File.Exists(TestFile).Should().BeTrue();
|
||||
File.ReadAllText(TestFile).Should().Be(@"
|
||||
{
|
||||
""AccountsSettings"": []
|
||||
}
|
||||
".Trim());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void overwrite_existing_file()
|
||||
{
|
||||
File.Exists(TestFile).Should().BeFalse();
|
||||
WriteToTestFile("foo");
|
||||
File.Exists(TestFile).Should().BeTrue();
|
||||
|
||||
var accounts = new Accounts();
|
||||
_ = new AccountsPersister(accounts, TestFile);
|
||||
File.Exists(TestFile).Should().BeTrue();
|
||||
File.ReadAllText(TestFile).Should().Be(@"
|
||||
{
|
||||
""AccountsSettings"": []
|
||||
}
|
||||
".Trim());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void save_multiple_children()
|
||||
{
|
||||
var accounts = new Accounts();
|
||||
accounts.UNITTEST_Seed(new Account("a0") { AccountName = "n0" });
|
||||
accounts.UNITTEST_Seed(new Account("a1") { AccountName = "n1" });
|
||||
|
||||
// dispose to cease auto-updates
|
||||
using (var p = new AccountsPersister(accounts, TestFile)) { }
|
||||
|
||||
var persister = new AccountsPersister(TestFile);
|
||||
persister.Accounts.AccountsSettings.Count.Should().Be(2);
|
||||
persister.Accounts.AccountsSettings[1].AccountName.Should().Be("n1");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void save_with_identity()
|
||||
{
|
||||
var usLocale = Localization.Locales.Single(l => l.Name == "us");
|
||||
var id = new Identity(usLocale);
|
||||
var idJson = JsonConvert.SerializeObject(id, Identity.GetJsonSerializerSettings());
|
||||
|
||||
var accounts = new Accounts();
|
||||
accounts.UNITTEST_Seed(new Account("a0") { AccountName = "n0", IdentityTokens = id });
|
||||
|
||||
// dispose to cease auto-updates
|
||||
using (var p = new AccountsPersister(accounts, TestFile)) { }
|
||||
|
||||
var persister = new AccountsPersister(TestFile);
|
||||
var acct = persister.Accounts.AccountsSettings[0];
|
||||
acct.AccountName.Should().Be("n0");
|
||||
acct.Locale.CountryCode.Should().Be("us");
|
||||
}
|
||||
}
|
||||
|
||||
[TestClass]
|
||||
public class save : AccountsPersisterTestBase
|
||||
{
|
||||
// add/save account after file creation
|
||||
[TestMethod]
|
||||
public void save_1_account()
|
||||
{
|
||||
// create initial file
|
||||
using (var p = new AccountsPersister(new Accounts(), TestFile)) { }
|
||||
|
||||
// load file. create account
|
||||
using (var p = new AccountsPersister(TestFile))
|
||||
{
|
||||
var localeIn = Localization.Locales.Single(l => l.Name == "us");
|
||||
var idIn = new Identity(localeIn);
|
||||
var acctIn = new Account("a0") { AccountName = "n0", IdentityTokens = idIn };
|
||||
|
||||
p.Accounts.UNITTEST_Seed(acctIn);
|
||||
}
|
||||
|
||||
// re-load file. ensure account still exists
|
||||
using (var p = new AccountsPersister(TestFile))
|
||||
{
|
||||
p.Accounts.AccountsSettings.Count.Should().Be(1);
|
||||
var acct0 = p.Accounts.AccountsSettings[0];
|
||||
acct0.AccountName.Should().Be("n0");
|
||||
acct0.Locale.CountryCode.Should().Be("us");
|
||||
}
|
||||
}
|
||||
|
||||
// add/save mult accounts after file creation
|
||||
// separately create 2 accounts. ensure both still exist in the end
|
||||
[TestMethod]
|
||||
public void save_2_accounts()
|
||||
{
|
||||
// create initial file
|
||||
using (var p = new AccountsPersister(new Accounts(), TestFile)) { }
|
||||
|
||||
// load file. create account 0
|
||||
using (var p = new AccountsPersister(TestFile))
|
||||
{
|
||||
var localeIn = Localization.Locales.Single(l => l.Name == "us");
|
||||
var idIn = new Identity(localeIn);
|
||||
var acctIn = new Account("a0") { AccountName = "n0", IdentityTokens = idIn };
|
||||
|
||||
p.Accounts.UNITTEST_Seed(acctIn);
|
||||
}
|
||||
|
||||
// re-load file. ensure account still exists
|
||||
using (var p = new AccountsPersister(TestFile))
|
||||
{
|
||||
p.Accounts.AccountsSettings.Count.Should().Be(1);
|
||||
|
||||
var acct0 = p.Accounts.AccountsSettings[0];
|
||||
acct0.AccountName.Should().Be("n0");
|
||||
acct0.Locale.CountryCode.Should().Be("us");
|
||||
}
|
||||
|
||||
// load file. create account 1
|
||||
using (var p = new AccountsPersister(TestFile))
|
||||
{
|
||||
var localeIn = Localization.Locales.Single(l => l.Name == "uk");
|
||||
var idIn = new Identity(localeIn);
|
||||
var acctIn = new Account("a1") { AccountName = "n1", IdentityTokens = idIn };
|
||||
|
||||
p.Accounts.UNITTEST_Seed(acctIn);
|
||||
}
|
||||
|
||||
// re-load file. ensure both accounts still exist
|
||||
using (var p = new AccountsPersister(TestFile))
|
||||
{
|
||||
p.Accounts.AccountsSettings.Count.Should().Be(2);
|
||||
|
||||
var acct0 = p.Accounts.AccountsSettings[0];
|
||||
acct0.AccountName.Should().Be("n0");
|
||||
acct0.Locale.CountryCode.Should().Be("us");
|
||||
|
||||
var acct1 = p.Accounts.AccountsSettings[1];
|
||||
acct1.AccountName.Should().Be("n1");
|
||||
acct1.Locale.CountryCode.Should().Be("uk");
|
||||
}
|
||||
}
|
||||
|
||||
// update Account property. must be non-destructive to all other data
|
||||
[TestMethod]
|
||||
public void update_Account_field()
|
||||
{
|
||||
// create initial file
|
||||
using (var p = new AccountsPersister(new Accounts(), TestFile)) { }
|
||||
|
||||
// load file. create 2 accounts
|
||||
using (var p = new AccountsPersister(TestFile))
|
||||
{
|
||||
var locale1 = Localization.Locales.Single(l => l.Name == "us");
|
||||
var id1 = new Identity(locale1);
|
||||
var acct1 = new Account("a0") { AccountName = "n0", IdentityTokens = id1 };
|
||||
p.Accounts.UNITTEST_Seed(acct1);
|
||||
|
||||
var locale2 = Localization.Locales.Single(l => l.Name == "uk");
|
||||
var id2 = new Identity(locale2);
|
||||
var acct2 = new Account("a1") { AccountName = "n1", IdentityTokens = id2 };
|
||||
|
||||
p.Accounts.UNITTEST_Seed(acct2);
|
||||
}
|
||||
|
||||
// update AccountName on existing file
|
||||
using (var p = new AccountsPersister(TestFile))
|
||||
{
|
||||
var acct0 = p.Accounts.AccountsSettings[0];
|
||||
acct0.AccountName = "new";
|
||||
}
|
||||
|
||||
// re-load file. ensure both accounts still exist
|
||||
using (var p = new AccountsPersister(TestFile))
|
||||
{
|
||||
p.Accounts.AccountsSettings.Count.Should().Be(2);
|
||||
|
||||
var acct0 = p.Accounts.AccountsSettings[0];
|
||||
// new
|
||||
acct0.AccountName.Should().Be("new");
|
||||
|
||||
// still here
|
||||
acct0.Locale.CountryCode.Should().Be("us");
|
||||
var acct1 = p.Accounts.AccountsSettings[1];
|
||||
acct1.AccountName.Should().Be("n1");
|
||||
acct1.Locale.CountryCode.Should().Be("uk");
|
||||
}
|
||||
}
|
||||
|
||||
// update identity. must be non-destructive to all other data
|
||||
[TestMethod]
|
||||
public void replace_identity()
|
||||
{
|
||||
// create initial file
|
||||
using (var p = new AccountsPersister(new Accounts(), TestFile)) { }
|
||||
|
||||
// load file. create 2 accounts
|
||||
using (var p = new AccountsPersister(TestFile))
|
||||
{
|
||||
var locale1 = Localization.Locales.Single(l => l.Name == "us");
|
||||
var id1 = new Identity(locale1);
|
||||
var acct1 = new Account("a0") { AccountName = "n0", IdentityTokens = id1 };
|
||||
p.Accounts.UNITTEST_Seed(acct1);
|
||||
|
||||
var locale2 = Localization.Locales.Single(l => l.Name == "uk");
|
||||
var id2 = new Identity(locale2);
|
||||
var acct2 = new Account("a1") { AccountName = "n1", IdentityTokens = id2 };
|
||||
|
||||
p.Accounts.UNITTEST_Seed(acct2);
|
||||
}
|
||||
|
||||
// update identity on existing file
|
||||
using (var p = new AccountsPersister(TestFile))
|
||||
{
|
||||
var locale = Localization.Locales.Single(l => l.Name == "uk");
|
||||
var id = new Identity(locale);
|
||||
|
||||
var acct0 = p.Accounts.AccountsSettings[0];
|
||||
acct0.IdentityTokens = id;
|
||||
}
|
||||
|
||||
// re-load file. ensure both accounts still exist
|
||||
using (var p = new AccountsPersister(TestFile))
|
||||
{
|
||||
p.Accounts.AccountsSettings.Count.Should().Be(2);
|
||||
|
||||
var acct0 = p.Accounts.AccountsSettings[0];
|
||||
// new
|
||||
acct0.Locale.CountryCode.Should().Be("uk");
|
||||
|
||||
// still here
|
||||
acct0.AccountName.Should().Be("n0");
|
||||
var acct1 = p.Accounts.AccountsSettings[1];
|
||||
acct1.AccountName.Should().Be("n1");
|
||||
acct1.Locale.CountryCode.Should().Be("uk");
|
||||
}
|
||||
}
|
||||
|
||||
// multi-level subscribe => update
|
||||
// edit field of existing identity. must be non-destructive to all other data
|
||||
[TestMethod]
|
||||
public void update_identity_field()
|
||||
{
|
||||
// create initial file
|
||||
using (var p = new AccountsPersister(new Accounts(), TestFile)) { }
|
||||
|
||||
// load file. create 2 accounts
|
||||
using (var p = new AccountsPersister(TestFile))
|
||||
{
|
||||
var locale1 = Localization.Locales.Single(l => l.Name == "us");
|
||||
var id1 = new Identity(locale1);
|
||||
var acct1 = new Account("a0") { AccountName = "n0", IdentityTokens = id1 };
|
||||
p.Accounts.UNITTEST_Seed(acct1);
|
||||
|
||||
var locale2 = Localization.Locales.Single(l => l.Name == "uk");
|
||||
var id2 = new Identity(locale2);
|
||||
var acct2 = new Account("a1") { AccountName = "n1", IdentityTokens = id2 };
|
||||
|
||||
p.Accounts.UNITTEST_Seed(acct2);
|
||||
}
|
||||
|
||||
// update identity on existing file
|
||||
using (var p = new AccountsPersister(TestFile))
|
||||
{
|
||||
p.Accounts.AccountsSettings[0]
|
||||
.IdentityTokens
|
||||
.Update(new AccessToken("Atna|_NEW_", DateTime.Now.AddDays(1)));
|
||||
}
|
||||
|
||||
// re-load file. ensure both accounts still exist
|
||||
using (var p = new AccountsPersister(TestFile))
|
||||
{
|
||||
p.Accounts.AccountsSettings.Count.Should().Be(2);
|
||||
|
||||
var acct0 = p.Accounts.AccountsSettings[0];
|
||||
// new
|
||||
acct0.IdentityTokens.ExistingAccessToken.TokenValue.Should().Be("Atna|_NEW_");
|
||||
|
||||
// still here
|
||||
acct0.AccountName.Should().Be("n0");
|
||||
acct0.Locale.CountryCode.Should().Be("us");
|
||||
var acct1 = p.Accounts.AccountsSettings[1];
|
||||
acct1.AccountName.Should().Be("n1");
|
||||
acct1.Locale.CountryCode.Should().Be("uk");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.0" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="2.1.2" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="2.1.2" />
|
||||
<PackageReference Include="coverlet.collector" Version="1.3.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\audible api\AudibleApi\_Tests\AudibleApi.Tests\AudibleApi.Tests.csproj" />
|
||||
<ProjectReference Include="..\..\..\Dinah.Core\_Tests\TestCommon\TestCommon.csproj" />
|
||||
<ProjectReference Include="..\..\InternalUtilities\InternalUtilities.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
Loading…
x
Reference in New Issue
Block a user