Skip to content

Commit

Permalink
chore: More efficient testing
Browse files Browse the repository at this point in the history
  • Loading branch information
svrooij committed Dec 8, 2023
1 parent 1a29cef commit e87a61e
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 50 deletions.
2 changes: 1 addition & 1 deletion src/Sonos.Cli/Commands/InfoCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,4 @@ public class InfoCommandOptions : BaseOptions
{
public SonosInfo Info { get; set; }
}
}
}
4 changes: 2 additions & 2 deletions src/Sonos.Cli/Commands/MusicCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ private static async Task RunLogin(MusicCommandOptions options, IHost host, Invo
if (musicClient.AuthenticationType == AuthenticationType.AppLink)
{
var appLinkResult = await musicClient.GetAppLinkAsync(token);
linkCode = appLinkResult.AuthorizeAccount.DeviceLink.LinkCode;
linkCode = appLinkResult!.AuthorizeAccount.DeviceLink.LinkCode;
Console.WriteLine("Go to {0}", appLinkResult.AuthorizeAccount.DeviceLink.RegistrationUrl);
if(appLinkResult.AuthorizeAccount.DeviceLink.ShowLinkCode == true)
{
Expand Down Expand Up @@ -155,4 +155,4 @@ public class MusicCommandOptions : BaseOptions
public bool? Json { get; set; }
public string? Input { get; set; }
}
}
}
5 changes: 5 additions & 0 deletions tests/Sonos.Base.Tests/FakeData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -426,4 +426,9 @@ internal class FakeData
</device>
</root>
";

public const string DevicePropertiesGetZoneInfo = "<SerialNumber>00-0E-58-64-AA-AA:A</SerialNumber><SoftwareVersion>57.19-46310</SoftwareVersion><DisplaySoftwareVersion>11.12</DisplaySoftwareVersion><HardwareVersion>1.16.4.1-2.0</HardwareVersion><IPAddress>192.168.1.10</IPAddress><MACAddress>00:0E:58:64:AA:AA</MACAddress><CopyrightInfo>© 2003-2023, Sonos, Inc. All rights reserved.</CopyrightInfo><ExtraInfo>OTP: 1.1.1(1-16-4-zp5s-0.5)</ExtraInfo><HTAudioIn>0</HTAudioIn><Flags>1</Flags>";

public const string DevicePropertiesGetZoneInfoMac = "00:0E:58:64:AA:AA";
public static string DevicePropertiesGetZoneInfoUuid() => $"RINCON_{DevicePropertiesGetZoneInfoMac.Replace(":","")}01400";
}
39 changes: 39 additions & 0 deletions tests/Sonos.Base.Tests/SonosDeviceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,5 +95,44 @@ public async Task GetDeviceDescriptionAsync_ParsesDeviceDescription(string xml,
Assert.NotNull(description);
Assert.Equal(name, description.device.friendlyName);
}

[Fact]
public async Task SwitchToLineInAsync_ExecutesCorrectCommands()
{
var mockedHandler = new Mock<HttpClientHandler>();
mockedHandler.MockDevicePropertiesGetZoneInfo();
mockedHandler.MockSonosRequest(nameof(Services.SonosService.AVTransport), nameof(Services.AVTransportService.SetAVTransportURI), $"<InstanceID>0</InstanceID><CurrentURI>x-rincon-stream:{FakeData.DevicePropertiesGetZoneInfoUuid()}</CurrentURI><CurrentURIMetaData />");
mockedHandler.MockSonosRequest(nameof(Services.SonosService.AVTransport), nameof(Services.AVTransportService.Play), "<InstanceID>0</InstanceID><Speed>1</Speed>");

var sonos = new SonosDevice(new SonosDeviceOptions(TestHelpers.DefaultUri, new StaticSonosServiceProvider(mockedHandler.Object)));
var result = await sonos.SwitchToLineInAsync();
Assert.True(result);
}

[Fact]
public async Task SwitchToQueueAsync_ExecutesCorrectCommands()
{
var mockedHandler = new Mock<HttpClientHandler>();
mockedHandler.MockDevicePropertiesGetZoneInfo();
mockedHandler.MockSonosRequest(nameof(Services.SonosService.AVTransport), nameof(Services.AVTransportService.SetAVTransportURI), $"<InstanceID>0</InstanceID><CurrentURI>x-rincon-queue:{FakeData.DevicePropertiesGetZoneInfoUuid()}#0</CurrentURI><CurrentURIMetaData />");
mockedHandler.MockSonosRequest(nameof(Services.SonosService.AVTransport), nameof(Services.AVTransportService.Play), "<InstanceID>0</InstanceID><Speed>1</Speed>");

var sonos = new SonosDevice(new SonosDeviceOptions(TestHelpers.DefaultUri, new StaticSonosServiceProvider(mockedHandler.Object)));
var result = await sonos.SwitchToQueueAsync();
Assert.True(result);
}

[Fact]
public async Task SwitchToTvAsync_ExecutesCorrectCommands()
{
var mockedHandler = new Mock<HttpClientHandler>();
mockedHandler.MockDevicePropertiesGetZoneInfo();
mockedHandler.MockSonosRequest(nameof(Services.SonosService.AVTransport), nameof(Services.AVTransportService.SetAVTransportURI), $"<InstanceID>0</InstanceID><CurrentURI>x-sonos-htastream:{FakeData.DevicePropertiesGetZoneInfoUuid()}:spdif</CurrentURI><CurrentURIMetaData />");
mockedHandler.MockSonosRequest(nameof(Services.SonosService.AVTransport), nameof(Services.AVTransportService.Play), "<InstanceID>0</InstanceID><Speed>1</Speed>");

var sonos = new SonosDevice(new SonosDeviceOptions(TestHelpers.DefaultUri, new StaticSonosServiceProvider(mockedHandler.Object)));
var result = await sonos.SwitchToTvAsync();
Assert.True(result);
}
}
}
59 changes: 12 additions & 47 deletions tests/Sonos.Base.Tests/TestHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public static Mock<HttpClientHandler> MockDeviceDescription(this Mock<HttpClient
return mock;
}

public static Mock<HttpClientHandler> MockDevicePropertiesGetZoneInfo(this Mock<HttpClientHandler> mock, string baseUrl = defaultUri) => mock.MockSonosRequest(nameof(Services.SonosService.DeviceProperties), nameof(Services.DevicePropertiesService.GetZoneInfo), null, FakeData.DevicePropertiesGetZoneInfo, baseUrl);

/// <summary>
/// Mock a specific request to sonos speakers.
/// </summary>
Expand Down Expand Up @@ -84,6 +86,11 @@ public static Mock<HttpClientHandler> MockSonosRequest(this Mock<HttpClientHandl

internal static bool VerifySonosRequest(this HttpRequestMessage message, string baseUrl, string service, string action, string? requestBody)
{
if (message.RequestUri != new Uri(new Uri(baseUrl), GetPathForService(service)) ||
!message.Headers.ContainsHeaderWithValue(SoapActionHeader, $"urn:schemas-upnp-org:service:{service}:1#{action}"))
{
return false;
}
// TODO: Verify body in tests
bool bodyChecked = false;
if (requestBody != null)
Expand All @@ -92,58 +99,16 @@ internal static bool VerifySonosRequest(this HttpRequestMessage message, string
{
var content = message.Content.ReadAsStringAsync().GetAwaiter().GetResult().RemoveXmlIndentation() ;
var expectedContent = string.Format(SoapRequestFormat, service, action, requestBody).RemoveXmlIndentation();
#if DEBUG
Assert.Equal(expectedContent, content);
#endif
//#if DEBUG
// Assert.Equal(expectedContent, content);
//#endif
bodyChecked = content.Equals(expectedContent);
}
}
return
message.RequestUri == new Uri(new Uri(baseUrl), GetPathForService(service)) &&
message.Headers.ContainsHeaderWithValue(SoapActionHeader, $"urn:schemas-upnp-org:service:{service}:1#{action}") &&
(requestBody == null || bodyChecked);
return requestBody == null || bodyChecked;
}

// public static Mock<HttpClientHandler> MockMusicServiceRequest(this Mock<HttpClientHandler> mock, string action, string? requestBody = null, string responseBody = "", string baseUrl = defaultUri)
// {
// string response = string.Format(MusicResponseFormat, action, responseBody);
// mock
// .Protected()
// .Setup<Task<HttpResponseMessage>>("SendAsync",
// ItExpr.Is<HttpRequestMessage>(m => m.VerifyMusicServiceRequest(baseUrl, action, requestBody)),
// ItExpr.IsAny<CancellationToken>()
// ).ReturnsAsync(new HttpResponseMessage
// {
// StatusCode = System.Net.HttpStatusCode.OK,
// Content = new StringContent(response)
// });

// return mock;
// }

// internal static bool VerifyMusicServiceRequest(this HttpRequestMessage message, string baseUrl, string action, string? requestBody)
// {
// // TODO: Verify body in tests
// bool bodyChecked = false;
// if (requestBody != null)
// {
// var streamContent = message.Content as StreamContent;

// if (streamContent != null)
// {
// var content = streamContent.ReadAsStringAsync().GetAwaiter().GetResult();
// var expectedContent = string.Format(MusicRequestFormat, action, requestBody);
// bodyChecked = content.Equals(expectedContent);
//#if DEBUG
// Assert.Equal(expectedContent, content);
//#endif
// }
// }
// return
// message.RequestUri == new Uri(baseUrl) &&
// message.Headers.ContainsHeaderWithValue(MusicActionHeader, $"http://www.sonos.com/Services/1.1#{action}") &&
// (requestBody == null || bodyChecked);
// }


internal static bool ContainsHeaderWithValue(this HttpRequestHeaders headers, string key, string value)
{
Expand Down

0 comments on commit e87a61e

Please sign in to comment.