Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
177 changes: 177 additions & 0 deletions src/PackageUploader.UI.Test/ViewModel/Msixvc2UploadViewModelTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using Microsoft.Extensions.Logging;
using Moq;
using PackageUploader.ClientApi;
using PackageUploader.UI.Providers;
using PackageUploader.UI.Utility;
using PackageUploader.UI.View;
using PackageUploader.UI.ViewModel;

namespace PackageUploader.UI.Test.ViewModel;

[TestClass]
public class Msixvc2UploadViewModelTest
{
private Mock<IWindowService> _mockWindowService;
private Mock<IPackageUploaderService> _mockUploaderService;
private Mock<ILogger<Msixvc2UploadViewModel>> _mockLogger;
private ErrorModelProvider _errorModelProvider;
private PathConfigurationProvider _pathConfigurationProvider;
private PackageModelProvider _packageModelProvider;

private Msixvc2UploadViewModel _viewModel;

[TestInitialize]
public void Setup()
{
_mockWindowService = new Mock<IWindowService>();
_mockUploaderService = new Mock<IPackageUploaderService>();
_mockLogger = new Mock<ILogger<Msixvc2UploadViewModel>>();
_errorModelProvider = new ErrorModelProvider();
_pathConfigurationProvider = new PathConfigurationProvider();
_packageModelProvider = new PackageModelProvider();

_viewModel = new Msixvc2UploadViewModel(
_mockWindowService.Object,
_mockUploaderService.Object,
_mockLogger.Object,
_errorModelProvider,
_pathConfigurationProvider,
_packageModelProvider
);
}

#region Constructor & Property initialization

[TestMethod]
public void Constructor_InitializesProperties()
{
Assert.AreEqual(string.Empty, _viewModel.ContentPath);
Assert.IsNotNull(_viewModel.UploadPackageCommand);
Assert.IsNotNull(_viewModel.CancelButtonCommand);
Assert.IsNotNull(_viewModel.BrowseContentPathCommand);
}

#endregion

#region BuildUploadArguments Tests

[TestMethod]
public void BuildUploadArguments_WithBranch()
{
_viewModel.ContentPath = @"C:\game\content";
_viewModel.BranchOrFlightDisplayName = "Branch: Main";
_viewModel.MarketGroupName = "default";
_viewModel.BigId = "9ABC123DEF456";

string args = _viewModel.BuildUploadArguments();

Assert.IsTrue(args.StartsWith("upload /d \"C:\\game\\content\" /msixvc2"));
Assert.IsTrue(args.Contains("/branch \"Main\""));
Assert.IsFalse(args.Contains("/flight"));
Assert.IsTrue(args.Contains("/market \"default\""));
Assert.IsTrue(args.Contains("/storeid \"9ABC123DEF456\""));
Assert.IsTrue(args.Contains("/auth CacheableBrowser"));
}

[TestMethod]
public void BuildUploadArguments_WithFlight()
{
_viewModel.ContentPath = @"C:\game\content";
_viewModel.BranchOrFlightDisplayName = "Flight: TestFlight";
_viewModel.MarketGroupName = "default";
_viewModel.BigId = "None";

string args = _viewModel.BuildUploadArguments();

Assert.IsTrue(args.Contains("/flight \"TestFlight\""));
Assert.IsFalse(args.Contains("/branch"));
Assert.IsFalse(args.Contains("/storeid"));
}

[TestMethod]
public void BuildUploadArguments_NoStoreId_NotIncluded()
{
_viewModel.ContentPath = @"C:\game\content";
_viewModel.BranchOrFlightDisplayName = "Branch: Dev";
_viewModel.MarketGroupName = "default";
_viewModel.BigId = string.Empty;

string args = _viewModel.BuildUploadArguments();

Assert.IsFalse(args.Contains("/storeid"));
}
#endregion

#region CanUpload (via UploadPackageCommand.CanExecute) Tests

[TestMethod]
public void CanUpload_ReturnsFalse_WhenContentPathEmpty()
{
_viewModel.ContentPath = string.Empty;

Assert.IsFalse(_viewModel.UploadPackageCommand.CanExecute(null));
}

[TestMethod]
public void CanUpload_ReturnsFalse_WhenNoBranchSelected()
{
_viewModel.BranchOrFlightDisplayName = string.Empty;

Assert.IsFalse(_viewModel.UploadPackageCommand.CanExecute(null));
}

[TestMethod]
public void CanUpload_ReturnsFalse_WhenNoMarketSelected()
{
_viewModel.MarketGroupName = string.Empty;

Assert.IsFalse(_viewModel.UploadPackageCommand.CanExecute(null));
}

[TestMethod]
public void CanUpload_ReturnsFalse_WhenLoadingBranches()
{
_viewModel.IsLoadingBranchesAndFlights = true;

Assert.IsFalse(_viewModel.UploadPackageCommand.CanExecute(null));
}

[TestMethod]
public void CanUpload_ReturnsFalse_WhenLoadingMarkets()
{
_viewModel.IsLoadingMarkets = true;

Assert.IsFalse(_viewModel.UploadPackageCommand.CanExecute(null));
}

[TestMethod]
public void CanUpload_ReturnsFalse_WhenContentPathHasError()
{
_viewModel.ContentPathError = "Some error";

Assert.IsFalse(_viewModel.UploadPackageCommand.CanExecute(null));
}
#endregion

#region Error Handling Tests

[TestMethod]
public void CancelButton_NavigatesToMainPage()
{
_viewModel.CancelButtonCommand.Execute(null);

_mockWindowService.Verify(x => x.NavigateTo(typeof(MainPageView)), Times.Once);
}

[TestMethod]
public void ErrorModelProvider_ReceivesCorrectValues_OnError()
{
// Verify the error model provider is the one we injected
Assert.IsNotNull(_errorModelProvider);
Assert.AreEqual(string.Empty, _errorModelProvider.Error.MainMessage);
}
#endregion
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,20 @@ public void Setup()
// Setup mock package
_mockPackage = new PackageModel
{
PackageFilePath = Path.GetTempFileName(),
Version = "1.0.0.0",
BigId = "12345678",
PackageType = "Xbox Game Package",
PackageType = "PC",
BranchId = "branch-123",
PackagePreviewImage = new BitmapImage()
PackagePreviewImage = new BitmapImage(),
PackageName = "Test Game",
Destination = "Branch: main",
Market = "default",
PackageIdentityName = "Publisher.TestGame",
FolderSize = "1.04 GB",
UploadSize = "1.001 GB"
};

_packageModelProvider.Package = _mockPackage;


// Setup App.GetLogFilePath for log tests
typeof(App).GetField("_logFilePath", BindingFlags.NonPublic | BindingFlags.Static)?.SetValue(null, @"C:\test\logs\app.log");

Expand All @@ -72,26 +75,71 @@ public void Constructor_InitializesCommands()
}

[TestMethod]
public void OnAppearing_LoadsPackageInformation()
public void OnAppearing_LoadsAllPreviewFields()
{
// Arrange
var packagePath = _mockPackage.PackageFilePath;
var fileInfo = new FileInfo(packagePath);
var mockFileLength = 1024 * 1024 * 10; // 10 MB

// Use reflection to set private field values if necessary for file info
SetFileInfoLength(fileInfo, mockFileLength);

// Act
_viewModel.OnAppearing();

// Assert
Assert.AreEqual(_mockPackage.PackagePreviewImage, _viewModel.PackagePreviewImage);
Assert.AreEqual(_mockPackage.Version, _viewModel.VersionNum);
Assert.AreEqual(_mockPackage.BigId, _viewModel.StoreId);
Assert.AreEqual(Path.GetFileName(packagePath), _viewModel.PackageFileName);
Assert.AreEqual("0 B", _viewModel.PackageSize); // temp file is empty
Assert.AreEqual(_mockPackage.PackageType, _viewModel.PackageType);
Assert.AreEqual("Test Game", _viewModel.ProductName);
Assert.AreEqual("Branch: main", _viewModel.Destination);
Assert.AreEqual("default", _viewModel.Market);
Assert.AreEqual("Publisher.TestGame", _viewModel.PackageIdentityName);
Assert.AreEqual("12345678", _viewModel.StoreId);
Assert.AreEqual("1.04 GB", _viewModel.FolderSize);
Assert.AreEqual("PC", _viewModel.PackageType);
Assert.IsTrue(_viewModel.HasUploadSize);
Assert.AreEqual("1.001 GB", _viewModel.UploadSize);
}

[TestMethod]
public void OnAppearing_WithoutUploadSize_HidesUploadSize()
{
// Arrange
_mockPackage.UploadSize = string.Empty;

// Act
_viewModel.OnAppearing();

// Assert
Assert.IsFalse(_viewModel.HasUploadSize);
}

[TestMethod]
public void OnAppearing_WithoutPackageName_FallsBackToFileName()
{
// Arrange - legacy path with file but no package name
string tempFile = Path.GetTempFileName();
try
{
_mockPackage.PackageName = string.Empty;
_mockPackage.PackageFilePath = tempFile;

// Act
_viewModel.OnAppearing();

// Assert
Assert.AreEqual(Path.GetFileName(tempFile), _viewModel.ProductName);
}
finally
{
File.Delete(tempFile);
}
}

[TestMethod]
public void OnAppearing_WithNoNameOrFile_ShowsFallbackText()
{
// Arrange
_mockPackage.PackageName = string.Empty;
_mockPackage.PackageFilePath = string.Empty;

// Act
_viewModel.OnAppearing();

// Assert
Assert.AreEqual("Loose content upload", _viewModel.ProductName);
}

[TestMethod]
Expand Down Expand Up @@ -149,76 +197,9 @@ public void OnViewInPartnerCenter_OpensBrowserWithCorrectUrl()
Times.Once);
}

[TestMethod]
public void TranslateFileSize_FormatsCorrectly()
{
// Arrange & Act - Use reflection to call private static method
string bytesResult = InvokePrivateStaticMethod<string>(
typeof(UploadingFinishedViewModel), "TranslateFileSize", 500L);

string kbResult = InvokePrivateStaticMethod<string>(
typeof(UploadingFinishedViewModel), "TranslateFileSize", 1500L);

string mbResult = InvokePrivateStaticMethod<string>(
typeof(UploadingFinishedViewModel), "TranslateFileSize", 1500 * 1024L);

string gbResult = InvokePrivateStaticMethod<string>(
typeof(UploadingFinishedViewModel), "TranslateFileSize", 1500 * 1024 * 1024L);

// Assert
Assert.AreEqual("500 B", bytesResult);
Assert.AreEqual("1 KB", kbResult);
Assert.AreEqual("1 MB", mbResult);
Assert.AreEqual("1.46 GB", gbResult);
}

[TestCleanup]
public void Cleanup()
{
// Delete temp file
if (File.Exists(_mockPackage.PackageFilePath))
{
File.Delete(_mockPackage.PackageFilePath);
}
}

#region Helper Methods

private static void SetStaticProperty(Type type, string propertyName, object value)
{
var propertyInfo = type.GetProperty(
propertyName,
BindingFlags.Public | BindingFlags.Static);

if (propertyInfo != null && propertyInfo.CanWrite)
{
propertyInfo.SetValue(null, value);
}
}

private static void SetFileInfoLength(FileInfo fileInfo, long length)
{
// This is a hack for testing purposes since FileInfo length is read-only
// In real tests, you'd use a file system abstraction instead
var fieldInfo = typeof(FileInfo).GetField(
"length",
BindingFlags.NonPublic | BindingFlags.Instance);

if (fieldInfo != null)
{
fieldInfo.SetValue(fileInfo, length);
}
}

private static T InvokePrivateStaticMethod<T>(Type type, string methodName, params object[] parameters)
{
var method = type.GetMethod(
methodName,
BindingFlags.NonPublic | BindingFlags.Static);

return (T)method?.Invoke(null, parameters);
}

#endregion
}
}
4 changes: 4 additions & 0 deletions src/PackageUploader.UI/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ public App()
services.AddSingleton<PackageUploadingViewModel>();
services.AddSingleton<UploadingFinishedViewModel>();
services.AddSingleton<ErrorScreenViewModel>();
services.AddSingleton<Msixvc2UploadViewModel>();
services.AddSingleton<Msixvc2UploadingViewModel>();

// Register Views
services.AddTransient<MainPageView>();
Expand All @@ -74,6 +76,8 @@ public App()
services.AddTransient<PackageUploadingView>();
services.AddTransient<UploadingFinishedView>();
services.AddTransient<ErrorPageView>();
services.AddTransient<Msixvc2UploadView>();
services.AddTransient<Msixvc2UploadingView>();

// Register the main window
services.AddSingleton<MainWindow>();
Expand Down
Loading
Loading