| File: MauiiOSValidationTests.cs | Web Access |
| Project: src\tests\Aspire.Hosting.Maui.Tests\Aspire.Hosting.Maui.Tests.csproj (Aspire.Hosting.Maui.Tests) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Aspire.Hosting.ApplicationModel; using Aspire.Hosting.Eventing; using Microsoft.Extensions.DependencyInjection; namespace Aspire.Hosting.Tests; /// <summary> /// Tests for iOS device/simulator ID cross-validation. /// When a GUID is passed to AddiOSDevice, or a non-GUID to AddiOSSimulator, /// BeforeResourceStartedEvent should throw with guidance to use the correct method. /// </summary> public class MauiiOSValidationTests(ITestOutputHelper outputHelper) { [Fact] public async Task AddiOSDevice_WithGuidDeviceId_ThrowsOnBeforeStart() { // A GUID looks like a simulator UDID, not a physical device UDID var simulatorLikeId = "E25BBE37-69BA-4720-B6FD-D54C97791E79"; using var workspace = TemporaryWorkspace.Create(outputHelper); var tempFile = Path.Combine(workspace.Path, "TempMauiProject.csproj"); File.WriteAllText(tempFile, MauiTestHelper.CreateProjectContent("net10.0-ios")); var appBuilder = DistributedApplication.CreateBuilder(); var maui = appBuilder.AddMauiProject("mauiapp", tempFile); var device = maui.AddiOSDevice("my-device", simulatorLikeId); await using var app = appBuilder.Build(); var exception = await Assert.ThrowsAsync<DistributedApplicationException>(async () => { await app.Services.GetRequiredService<IDistributedApplicationEventing>() .PublishAsync(new BeforeResourceStartedEvent(device.Resource, app.Services), CancellationToken.None); }); Assert.Contains("appears to be an iOS Simulator UDID", exception.Message); Assert.Contains("AddiOSSimulator", exception.Message); } [Fact] public async Task AddiOSSimulator_WithNonGuidSimulatorId_ThrowsOnBeforeStart() { // A non-GUID looks like a physical device UDID, not a simulator UDID var deviceLikeId = "00008030-001234567890123A"; using var workspace = TemporaryWorkspace.Create(outputHelper); var tempFile = Path.Combine(workspace.Path, "TempMauiProject.csproj"); File.WriteAllText(tempFile, MauiTestHelper.CreateProjectContent("net10.0-ios")); var appBuilder = DistributedApplication.CreateBuilder(); var maui = appBuilder.AddMauiProject("mauiapp", tempFile); var simulator = maui.AddiOSSimulator("my-simulator", deviceLikeId); await using var app = appBuilder.Build(); var exception = await Assert.ThrowsAsync<DistributedApplicationException>(async () => { await app.Services.GetRequiredService<IDistributedApplicationEventing>() .PublishAsync(new BeforeResourceStartedEvent(simulator.Resource, app.Services), CancellationToken.None); }); Assert.Contains("does not appear to be an iOS Simulator UDID", exception.Message); Assert.Contains("AddiOSDevice", exception.Message); } [Fact] public async Task AddiOSDevice_WithValidDeviceId_DoesNotThrowOnBeforeStart() { // A typical physical device UDID (non-GUID format) var validDeviceId = "00008030-001234567890123A"; using var workspace = TemporaryWorkspace.Create(outputHelper); var tempFile = Path.Combine(workspace.Path, "TempMauiProject.csproj"); File.WriteAllText(tempFile, MauiTestHelper.CreateProjectContent("net10.0-ios")); var appBuilder = DistributedApplication.CreateBuilder(); var maui = appBuilder.AddMauiProject("mauiapp", tempFile); var device = maui.AddiOSDevice("my-device", validDeviceId); await using var app = appBuilder.Build(); // Should not throw — this is a valid device UDID format await app.Services.GetRequiredService<IDistributedApplicationEventing>() .PublishAsync(new BeforeResourceStartedEvent(device.Resource, app.Services), CancellationToken.None); } [Fact] public async Task AddiOSSimulator_WithValidGuidSimulatorId_DoesNotThrowOnBeforeStart() { // A standard GUID format which is expected for simulator UDIDs var validSimulatorId = "E25BBE37-69BA-4720-B6FD-D54C97791E79"; using var workspace = TemporaryWorkspace.Create(outputHelper); var tempFile = Path.Combine(workspace.Path, "TempMauiProject.csproj"); File.WriteAllText(tempFile, MauiTestHelper.CreateProjectContent("net10.0-ios")); var appBuilder = DistributedApplication.CreateBuilder(); var maui = appBuilder.AddMauiProject("mauiapp", tempFile); var simulator = maui.AddiOSSimulator("my-simulator", validSimulatorId); await using var app = appBuilder.Build(); // Should not throw — this is a valid simulator UDID format await app.Services.GetRequiredService<IDistributedApplicationEventing>() .PublishAsync(new BeforeResourceStartedEvent(simulator.Resource, app.Services), CancellationToken.None); } [Fact] public async Task AddiOSDevice_WithNoDeviceId_DoesNotThrowOnBeforeStart() { using var workspace = TemporaryWorkspace.Create(outputHelper); var tempFile = Path.Combine(workspace.Path, "TempMauiProject.csproj"); File.WriteAllText(tempFile, MauiTestHelper.CreateProjectContent("net10.0-ios")); var appBuilder = DistributedApplication.CreateBuilder(); var maui = appBuilder.AddMauiProject("mauiapp", tempFile); var device = maui.AddiOSDevice(); await using var app = appBuilder.Build(); // No device ID validation when no ID is provided await app.Services.GetRequiredService<IDistributedApplicationEventing>() .PublishAsync(new BeforeResourceStartedEvent(device.Resource, app.Services), CancellationToken.None); } [Fact] public async Task AddiOSSimulator_WithNoSimulatorId_DoesNotThrowOnBeforeStart() { using var workspace = TemporaryWorkspace.Create(outputHelper); var tempFile = Path.Combine(workspace.Path, "TempMauiProject.csproj"); File.WriteAllText(tempFile, MauiTestHelper.CreateProjectContent("net10.0-ios")); var appBuilder = DistributedApplication.CreateBuilder(); var maui = appBuilder.AddMauiProject("mauiapp", tempFile); var simulator = maui.AddiOSSimulator(); await using var app = appBuilder.Build(); // No simulator ID validation when no ID is provided await app.Services.GetRequiredService<IDistributedApplicationEventing>() .PublishAsync(new BeforeResourceStartedEvent(simulator.Resource, app.Services), CancellationToken.None); } }