59 lines
4.3 KiB
C#
59 lines
4.3 KiB
C#
using VoiceCat.Interop;
|
|||
|
|
using VoiceCat.Server.Data;
|
||
|
|
using Voicecat.V1;
|
||
|
|
using static VoiceCat.Tests.ServerTests;
|
||
|
|
using Client = VoiceCat.Interop.VoiceCatClient;
|
||
|
|
|
||
|
|
namespace VoiceCat.Tests;
|
||
|
|
|
||
|
|
public class WindowsManagedClientTests
|
||
|
|
{
|
||
|
|
private static async Task Until(Client client, Func<bool> predicate)
|
||
|
|
{
|
||
|
|
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(10));
|
||
|
|
do { client.PumpEvents(); if (predicate()) return; await Task.Delay(10, timeout.Token); } while (true);
|
||
|
|
}
|
||
|
|
private static async Task Login(Client client, ServerFixture fixture, bool admin = false)
|
||
|
|
{
|
||
|
|
client.EventReceived += e => { if (e.Type == VcEventType.ServerIdentity) client.ConfirmServerIdentity(true); };
|
||
|
|
Assert.Equal(VcResult.Ok, client.Connect("127.0.0.1", (ushort)fixture.Server.EndPoint.Port));
|
||
|
|
if (admin) client.AuthenticateUser("Admin", "secret"); else client.AuthenticateGuest("Guest");
|
||
|
|
await Until(client, () => client.ListUsers().Count > 0);
|
||
|
|
}
|
||
|
|
[Fact]
|
||
|
|
public async Task ShippedWindowsFacadeChatsExchangesPcmAndKeepsCaptureIdsAcrossChannelMoves()
|
||
|
|
{
|
||
|
|
await using var fixture = new ServerFixture();
|
||
|
|
using (var accounts = new AccountStore(Path.Combine(fixture.Directory, "voicecat.db"))) await accounts.CreateAccountAsync("Admin", "secret", true);
|
||
|
|
using var alice = new Client("Alice", "test", tofuStorePath: Path.Combine(fixture.Directory, "alice.pins"));
|
||
|
|
using var bob = new Client("Bob", "test", tofuStorePath: Path.Combine(fixture.Directory, "bob.pins"));
|
||
|
|
await Login(alice, fixture, true); await Login(bob, fixture);
|
||
|
|
Assert.True(alice.GetPermissions().IsAdmin);
|
||
|
|
string? body = null; bob.EventReceived += e => { if (e.Type == VcEventType.TextMessage) body = e.Text; };
|
||
|
|
Assert.Equal(VcResult.Ok, alice.SendText(VcTextScope.Channel, 1, "Managed Windows chat"));
|
||
|
|
await Until(bob, () => body is not null); Assert.Equal("Managed Windows chat", body);
|
||
|
|
Assert.Equal(VcResult.Ok, alice.JoinVoice()); Assert.Equal(VcResult.Ok, bob.JoinVoice());
|
||
|
|
alice.SetInputMode(VcInputMode.AlwaysOn); bob.SetInputMode(VcInputMode.AlwaysOn);
|
||
|
|
var a = alice.StartStreamExternalFeed(VcStreamKind.Mic, "Mic"); var b = bob.StartStreamExternalFeed(VcStreamKind.Mic, "Mic");
|
||
|
|
Assert.Equal(VcResult.Ok, a.Result); Assert.Equal(VcResult.Ok, b.Result);
|
||
|
|
await Until(bob, () => bob.ManagedClient.Users.Any(u => u.Streams.Count > 0 && u.Id != bob.ManagedClient.Authentication!.Self.Id));
|
||
|
|
long aliceEnergy = 0, bobEnergy = 0;
|
||
|
|
alice.ManagedClient.Audio.MixedPcm += pcm => { long sum = 0; foreach (short sample in pcm) sum += Math.Abs((int)sample); Interlocked.Add(ref aliceEnergy, sum); };
|
||
|
|
bob.ManagedClient.Audio.MixedPcm += pcm => { long sum = 0; foreach (short sample in pcm) sum += Math.Abs((int)sample); Interlocked.Add(ref bobEnergy, sum); };
|
||
|
|
short[] tone = Enumerable.Range(0, 960).Select(i => (short)(8000 * Math.Sin(i * Math.PI * 880 / 48000))).ToArray();
|
||
|
|
for (int i = 0; i < 40; i++) { alice.StreamFeedPcm(a.StreamId, tone, 960, 1); bob.StreamFeedPcm(b.StreamId, tone, 960, 1); alice.PumpEvents(); bob.PumpEvents(); await Task.Delay(20); }
|
||
|
|
Assert.True(Interlocked.Read(ref aliceEnergy) > 100000); Assert.True(Interlocked.Read(ref bobEnergy) > 100000);
|
||
|
|
uint oldId = alice.ManagedClient.LocalStreams.Single().StreamId;
|
||
|
|
await alice.ManagedClient.RequestAsync(new() { CreateChannel = new() { Channel = new() { Name = "Stereo", ParentId = 1, Audio = AudioEngineTests.Stream(20, true).Audio } } });
|
||
|
|
await Until(alice, () => alice.ListChannels().Any(c => c.Name == "Stereo"));
|
||
|
|
uint channel = alice.ListChannels().Single(c => c.Name == "Stereo").Id;
|
||
|
|
Assert.Equal(VcResult.Ok, alice.JoinChannel(channel));
|
||
|
|
await Until(alice, () => alice.ManagedClient.LocalStreams.Any(s => s.StreamId != oldId));
|
||
|
|
Assert.Equal(a.StreamId, Assert.Single(alice.ListUserStreams(alice.ManagedClient.Authentication!.Self.Id)).StreamId);
|
||
|
|
Assert.True(alice.GetStreamAudioConfig(alice.ManagedClient.Authentication!.Self.Id, a.StreamId).Config!.Stereo);
|
||
|
|
Assert.Equal(VcResult.Ok, alice.StreamFeedPcm(a.StreamId, tone, 960, 1));
|
||
|
|
Assert.Equal(VcResult.Ok, alice.StopStream(a.StreamId));
|
||
|
|
Assert.Empty(alice.ManagedClient.LocalStreams);
|
||
|
|
}
|
||
|
|
}
|