mirror of
https://github.com/aliasvault/aliasvault.git
synced 2026-04-03 14:33:50 -04:00
Update tests (#1742)
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
@if (_errors.Any())
|
||||
{
|
||||
@foreach (var error in _errors)
|
||||
{
|
||||
<AlertMessageError Message="@error" />
|
||||
}
|
||||
<div class="messages-container">
|
||||
@foreach (var error in _errors)
|
||||
{
|
||||
<AlertMessageError Message="@error" />
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
@code {
|
||||
|
||||
@@ -40,6 +40,7 @@ public sealed class DbService : IDisposable
|
||||
private readonly ILogger<DbService> _logger;
|
||||
private readonly GlobalNotificationService _globalNotificationService;
|
||||
private readonly IStringLocalizer _sharedLocalizer;
|
||||
private readonly CancellationTokenSource _backgroundSyncCts = new();
|
||||
private SettingsService _settingsService = new();
|
||||
private SqliteConnection? _sqlConnection;
|
||||
private AliasClientDbContext _dbContext;
|
||||
@@ -210,44 +211,79 @@ public sealed class DbService : IDisposable
|
||||
// Set state to indicate background sync is pending
|
||||
_state.UpdateState(DbServiceState.DatabaseStatus.BackgroundSyncPending);
|
||||
|
||||
// Capture cancellation token for this background operation
|
||||
var cancellationToken = _backgroundSyncCts.Token;
|
||||
|
||||
// Fire and forget the background save operation
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
_ = Task.Run(
|
||||
async () =>
|
||||
{
|
||||
// Prune expired items from trash before saving.
|
||||
await PruneExpiredTrashItemsAsync();
|
||||
|
||||
// Make sure a public/private RSA encryption key exists before saving the database.
|
||||
await GetOrCreateEncryptionKeyAsync();
|
||||
|
||||
var encryptedBase64String = await GetEncryptedDatabaseBase64String();
|
||||
|
||||
// Update state to show we're actively syncing
|
||||
_state.UpdateState(DbServiceState.DatabaseStatus.SavingToServer);
|
||||
|
||||
// Save to webapi.
|
||||
var success = await SaveToServerAsync(encryptedBase64String);
|
||||
if (success)
|
||||
try
|
||||
{
|
||||
_logger.LogInformation("Database successfully saved to server (background sync).");
|
||||
if (cancellationToken.IsCancellationRequested || _disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Prune expired items from trash before saving.
|
||||
await PruneExpiredTrashItemsAsync();
|
||||
|
||||
if (cancellationToken.IsCancellationRequested || _disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure a public/private RSA encryption key exists before saving the database.
|
||||
await GetOrCreateEncryptionKeyAsync();
|
||||
|
||||
if (cancellationToken.IsCancellationRequested || _disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var encryptedBase64String = await GetEncryptedDatabaseBase64String();
|
||||
|
||||
if (cancellationToken.IsCancellationRequested || _disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Update state to show we're actively syncing
|
||||
_state.UpdateState(DbServiceState.DatabaseStatus.SavingToServer);
|
||||
|
||||
// Save to webapi.
|
||||
var success = await SaveToServerAsync(encryptedBase64String);
|
||||
if (success)
|
||||
{
|
||||
_logger.LogInformation("Database successfully saved to server (background sync).");
|
||||
_state.UpdateState(DbServiceState.DatabaseStatus.Ready);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogWarning("Background sync to server failed.");
|
||||
_globalNotificationService.AddErrorMessage(
|
||||
"Failed to sync changes to server. Your changes are saved locally and will be synced on next refresh.");
|
||||
_state.UpdateState(DbServiceState.DatabaseStatus.Ready);
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// Background sync was cancelled (e.g., during logout), this is expected
|
||||
_logger.LogDebug("Background database sync was cancelled.");
|
||||
}
|
||||
catch (Exception ex) when (_disposed || cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
// Service was disposed during sync, silently ignore
|
||||
_logger.LogDebug(ex, "Background database sync aborted due to disposal.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error during background database sync.");
|
||||
_globalNotificationService.AddErrorMessage(_sharedLocalizer["ErrorUnknown"]);
|
||||
_state.UpdateState(DbServiceState.DatabaseStatus.Ready);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogWarning("Background sync to server failed.");
|
||||
_globalNotificationService.AddErrorMessage(
|
||||
"Failed to sync changes to server. Your changes are saved locally and will be synced on next refresh.");
|
||||
_state.UpdateState(DbServiceState.DatabaseStatus.Ready);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error during background database sync.");
|
||||
_globalNotificationService.AddErrorMessage(_sharedLocalizer["ErrorUnknown"]);
|
||||
_state.UpdateState(DbServiceState.DatabaseStatus.Ready);
|
||||
}
|
||||
});
|
||||
},
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1127,6 +1163,9 @@ public sealed class DbService : IDisposable
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
// Cancel any pending background sync operations first
|
||||
_backgroundSyncCts.Cancel();
|
||||
_backgroundSyncCts.Dispose();
|
||||
_sqlConnection?.Dispose();
|
||||
}
|
||||
|
||||
|
||||
@@ -42,16 +42,16 @@ public class TwoFactorAuthBase : ClientPlaywrightTest
|
||||
// Press the confirm disable button as well.
|
||||
await confirmButton.ClickAsync();
|
||||
|
||||
// Check if the success message is displayed.
|
||||
// Check if the success message is displayed
|
||||
var expectedMessage = "Two-factor authentication is now successfully disabled.";
|
||||
var successMessageLocator = Page.Locator($"div[role='alert']:has-text('{expectedMessage}')");
|
||||
var successMessageLocator = Page.Locator($".messages-container div[role='alert']:has-text('{expectedMessage}')");
|
||||
await successMessageLocator.WaitForAsync(new LocatorWaitForOptions
|
||||
{
|
||||
State = WaitForSelectorState.Visible,
|
||||
Timeout = 5000,
|
||||
});
|
||||
|
||||
var message = await Page.TextContentAsync("div[role='alert']");
|
||||
var message = await successMessageLocator.TextContentAsync();
|
||||
Assert.That(message, Does.Contain("Two-factor authentication is now successfully disabled."), "No two-factor auth disable success message displayed.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,14 +27,14 @@ public class TwoFactorAuthTests : TwoFactorAuthBase
|
||||
await DisableTwoFactorIfEnabled();
|
||||
var (totpCode, _) = await EnableTwoFactor();
|
||||
|
||||
// Check if the success message is displayed.
|
||||
var successMessage = Page.Locator("div[role='alert']");
|
||||
// Check if the success message is displayed (target the app notification area, not the error UI in index.html).
|
||||
var successMessage = Page.Locator(".messages-container div[role='alert']");
|
||||
await successMessage.WaitForAsync(new LocatorWaitForOptions
|
||||
{
|
||||
State = WaitForSelectorState.Visible,
|
||||
Timeout = 5000,
|
||||
});
|
||||
var message = await Page.TextContentAsync("div[role='alert']");
|
||||
var message = await successMessage.TextContentAsync();
|
||||
Assert.That(message, Does.Contain("Two-factor authentication is now successfully enabled."), "No success message displayed.");
|
||||
|
||||
await Logout();
|
||||
|
||||
@@ -160,7 +160,8 @@ public class AuthTests : ClientPlaywrightTest
|
||||
await deleteButton.ClickAsync();
|
||||
|
||||
// Check for error message about wrong username
|
||||
var warning = await Page.TextContentAsync("div[role='alert']");
|
||||
var warningLocator = Page.Locator(".messages-container div[role='alert']");
|
||||
var warning = await warningLocator.TextContentAsync();
|
||||
Assert.That(warning, Does.Contain("The username you entered does not match your current username"), "No warning shown when attempting to delete account with wrong username.");
|
||||
|
||||
// Try with correct username
|
||||
@@ -178,7 +179,7 @@ public class AuthTests : ClientPlaywrightTest
|
||||
await confirmButton.ClickAsync();
|
||||
|
||||
// Check for error message about wrong password
|
||||
warning = await Page.TextContentAsync("div[role='alert']");
|
||||
warning = await warningLocator.TextContentAsync();
|
||||
Assert.That(warning, Does.Contain("The provided password does not match"), "No warning shown when attempting to delete account with wrong password.");
|
||||
|
||||
// Fill in correct password
|
||||
@@ -201,7 +202,7 @@ public class AuthTests : ClientPlaywrightTest
|
||||
var loginButton = await WaitForAndGetElement("button[type='submit']");
|
||||
await loginButton.ClickAsync();
|
||||
|
||||
warning = await Page.TextContentAsync("div[role='alert']");
|
||||
warning = await warningLocator.TextContentAsync();
|
||||
Assert.That(warning, Does.Contain("Invalid username or password"), "No error shown when attempting to login with deleted account.");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user