//-----------------------------------------------------------------------
// <copyright file="DbPersistTests.cs" company="lanedirt">
// Copyright (c) lanedirt. All rights reserved.
// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
// </copyright>
//-----------------------------------------------------------------------

namespace AliasVault.E2ETests.Tests.Client.Shard2;

using Microsoft.EntityFrameworkCore;

/// <summary>
/// End-to-end tests for the client database persistence.
/// </summary>
[TestFixture]
[Category("ClientTests")]
[NonParallelizable]
public class DbPersistTests : ClientPlaywrightTest
{
    /// <summary>
    /// Test if a created credential is still present after a hard page refresh which causes
    /// the database to be loaded fresh from the remote server. This is to ensure that the
    /// database is correctly persisted and then loaded from the server.
    /// </summary>
    /// <returns>Async task.</returns>
    [Test]
    [Order(1)]
    public async Task DbPersistCredentialTest()
    {
        var serviceNameBefore = "Credential service before";
        await CreateCredentialEntry(new Dictionary<string, string>
        {
            { "service-name", serviceNameBefore },
        });

        // Check that the service name is present in the content.
        var pageContent = await Page.TextContentAsync("body");
        Assert.That(pageContent, Does.Contain(serviceNameBefore), "Created credential service name does not appear on login page.");

        // Refresh page so the database gets dropped then unlock the vault again which will refetch the database from the server.
        await RefreshPageAndUnlockVault();

        // Wait for the credentials page to load again.
        await WaitForUrlAsync("credentials/**", serviceNameBefore);

        // Check if the service name is still present in the content.
        pageContent = await Page.TextContentAsync("body");
        Assert.That(pageContent, Does.Contain(serviceNameBefore), "Created credential service name does not appear on login page after hard page reload. Check if the database is correctly persisted and then loaded from the server.");
    }

    /// <summary>
    /// Test if the vault revision number is incremented when a new version of the vault is saved to the server.
    /// </summary>
    /// <returns>Async task.</returns>
    [Test]
    [Order(2)]
    public async Task VaultRevisionNumberIncrementTest()
    {
        // Assert that the vault revision number is 1 in the server database.
        // Note: for this we expect the previous test to have run first and created a first credential.
        var firstUpdateVault = await ApiDbContext.Vaults.OrderByDescending(x => x.UpdatedAt).FirstAsync();
        Assert.That(firstUpdateVault.RevisionNumber, Is.EqualTo(1), "Vault revision number is not at 1 after creating the first credential in a new vault.");

        // Create a new credential which will trigger a vault save to the server.
        await CreateCredentialEntry();

        // Assert that the vault revision number is now 2 in the server database.
        var secondUpdateVault = await ApiDbContext.Vaults.OrderByDescending(x => x.UpdatedAt).FirstAsync();
        Assert.That(secondUpdateVault.RevisionNumber, Is.EqualTo(2), "Vault revision number is not 2 after the second credential save.");
    }
}
