@ -0,0 +1,120 @@ | |||
using Xunit; | |||
using Xamarin.Forms; | |||
using System; | |||
using System.Globalization; | |||
namespace eShopOnContainers.UnitTests | |||
{ | |||
public class EventToCommandBehaviorTests | |||
{ | |||
[Fact] | |||
public void InvalidEventNameShouldThrowArgumentExceptionText() | |||
{ | |||
var behavior = new MockEventToCommandBehavior | |||
{ | |||
EventName = "OnItemTapped" | |||
}; | |||
var listView = new ListView(); | |||
Assert.Throws<ArgumentException>(() => listView.Behaviors.Add(behavior)); | |||
} | |||
[Fact] | |||
public void CommandExecutedWhenEventFiresText() | |||
{ | |||
bool executedCommand = false; | |||
var behavior = new MockEventToCommandBehavior | |||
{ | |||
EventName = "ItemTapped", | |||
Command = new Command(() => | |||
{ | |||
executedCommand = true; | |||
}) | |||
}; | |||
var listView = new ListView(); | |||
listView.Behaviors.Add(behavior); | |||
behavior.RaiseEvent(listView, null); | |||
Assert.True(executedCommand); | |||
} | |||
[Fact] | |||
public void CommandCanExecuteTest() | |||
{ | |||
var behavior = new MockEventToCommandBehavior | |||
{ | |||
EventName = "ItemTapped", | |||
Command = new Command(() => Assert.True(false), () => false) | |||
}; | |||
var listView = new ListView(); | |||
listView.Behaviors.Add(behavior); | |||
behavior.RaiseEvent(listView, null); | |||
} | |||
[Fact] | |||
public void CommandCanExecuteWithParameterShouldNotExecuteTest() | |||
{ | |||
bool shouldExecute = false; | |||
var behavior = new MockEventToCommandBehavior | |||
{ | |||
EventName = "ItemTapped", | |||
CommandParameter = shouldExecute, | |||
Command = new Command<string>(o => Assert.True(false), o => o.Equals(true)) | |||
}; | |||
var listView = new ListView(); | |||
listView.Behaviors.Add(behavior); | |||
behavior.RaiseEvent(listView, null); | |||
} | |||
[Fact] | |||
public void CommandWithConverterTest() | |||
{ | |||
const string item = "ItemProperty"; | |||
bool executedCommand = false; | |||
var behavior = new MockEventToCommandBehavior | |||
{ | |||
EventName = "ItemTapped", | |||
EventArgsConverter = new ItemTappedEventArgsConverter(false), | |||
Command = new Command<string>(o => | |||
{ | |||
executedCommand = true; | |||
Assert.NotNull(o); | |||
Assert.Equal(item, o); | |||
}) | |||
}; | |||
var listView = new ListView(); | |||
listView.Behaviors.Add(behavior); | |||
behavior.RaiseEvent(listView, new ItemTappedEventArgs(listView, item)); | |||
Assert.True(executedCommand); | |||
} | |||
private class ItemTappedEventArgsConverter : IValueConverter | |||
{ | |||
private readonly bool _returnParameter; | |||
public bool HasConverted { get; private set; } | |||
public ItemTappedEventArgsConverter(bool returnParameter) | |||
{ | |||
_returnParameter = returnParameter; | |||
} | |||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) | |||
{ | |||
HasConverted = true; | |||
return _returnParameter ? parameter : (value as ItemTappedEventArgs)?.Item; | |||
} | |||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
} | |||
} | |||
} |
@ -1,27 +0,0 @@ | |||
using System; | |||
using System.Threading.Tasks; | |||
using Xunit; | |||
namespace eShopOnContainers.UnitTests | |||
{ | |||
public class DummyTests | |||
{ | |||
[Fact] | |||
public void ThisShouldPass_Sync() | |||
{ | |||
Assert.True(true); | |||
} | |||
[Fact] | |||
public async Task ThisShouldPass_Async() | |||
{ | |||
await Task.Run(() => { Assert.True(true); }); | |||
} | |||
[Fact] | |||
public async Task ThisShouldFail_Async() | |||
{ | |||
await Task.Run(() => { throw new Exception("Oops!"); }); | |||
} | |||
} | |||
} |
@ -0,0 +1,12 @@ | |||
using eShopOnContainers.Core.Behaviors; | |||
namespace eShopOnContainers.UnitTests | |||
{ | |||
public class MockEventToCommandBehavior : EventToCommandBehavior | |||
{ | |||
public void RaiseEvent(params object[] args) | |||
{ | |||
_handler.DynamicInvoke(args); | |||
} | |||
} | |||
} |
@ -0,0 +1,53 @@ | |||
using eShopOnContainers.Core.ViewModels.Base; | |||
using eShopOnContainers.Core.Validations; | |||
namespace eShopOnContainers.UnitTests | |||
{ | |||
public class MockViewModel : ViewModelBase | |||
{ | |||
private ValidatableObject<string> _forename; | |||
private ValidatableObject<string> _surname; | |||
public ValidatableObject<string> Forename | |||
{ | |||
get | |||
{ | |||
return _forename; | |||
} | |||
set | |||
{ | |||
_forename = value; | |||
RaisePropertyChanged(() => Forename); | |||
} | |||
} | |||
public ValidatableObject<string> Surname | |||
{ | |||
get | |||
{ | |||
return _surname; | |||
} | |||
set | |||
{ | |||
_surname = value; | |||
RaisePropertyChanged(() => Surname); | |||
} | |||
} | |||
public MockViewModel() | |||
{ | |||
_forename = new ValidatableObject<string>(); | |||
_surname = new ValidatableObject<string>(); | |||
_forename.Validations.Add(new IsNotNullOrEmptyRule<string> { ValidationMessage = "Forename is required." }); | |||
_surname.Validations.Add(new IsNotNullOrEmptyRule<string> { ValidationMessage = "Surname name is required." }); | |||
} | |||
public bool Validate() | |||
{ | |||
bool isValidForename = _forename.Validate(); | |||
bool isValidSurname = _surname.Validate(); | |||
return isValidForename && isValidSurname; | |||
} | |||
} | |||
} |
@ -0,0 +1,223 @@ | |||
using Xunit; | |||
using eShopOnContainers.Core.ViewModels; | |||
using eShopOnContainers.Core.ViewModels.Base; | |||
using eShopOnContainers.Core.Services.Catalog; | |||
using eShopOnContainers.Core.Models.Catalog; | |||
using System.Threading.Tasks; | |||
using System.Linq; | |||
namespace eShopOnContainers.UnitTests | |||
{ | |||
public class CatalogViewModelTests | |||
{ | |||
public CatalogViewModelTests() | |||
{ | |||
ViewModelLocator.RegisterDependencies(true); | |||
} | |||
[Fact] | |||
public void AddCatalogItemCommandIsNotNullTest() | |||
{ | |||
var catalogService = new CatalogMockService(); | |||
var catalogViewModel = new CatalogViewModel(catalogService); | |||
Assert.NotNull(catalogViewModel.AddCatalogItemCommand); | |||
} | |||
[Fact] | |||
public void FilterCommandIsNotNullTest() | |||
{ | |||
var catalogService = new CatalogMockService(); | |||
var catalogViewModel = new CatalogViewModel(catalogService); | |||
Assert.NotNull(catalogViewModel.FilterCommand); | |||
} | |||
[Fact] | |||
public void ClearFilterCommandIsNotNullTest() | |||
{ | |||
var catalogService = new CatalogMockService(); | |||
var catalogViewModel = new CatalogViewModel(catalogService); | |||
Assert.NotNull(catalogViewModel.ClearFilterCommand); | |||
} | |||
[Fact] | |||
public void ProductsPropertyIsNullWhenViewModelInstantiatedTest() | |||
{ | |||
var catalogService = new CatalogMockService(); | |||
var catalogViewModel = new CatalogViewModel(catalogService); | |||
Assert.Null(catalogViewModel.Products); | |||
} | |||
[Fact] | |||
public void BrandsPropertyuIsNullWhenViewModelInstantiatedTest() | |||
{ | |||
var catalogService = new CatalogMockService(); | |||
var catalogViewModel = new CatalogViewModel(catalogService); | |||
Assert.Null(catalogViewModel.Brands); | |||
} | |||
[Fact] | |||
public void BrandPropertyIsNullWhenViewModelInstantiatedTest() | |||
{ | |||
var catalogService = new CatalogMockService(); | |||
var catalogViewModel = new CatalogViewModel(catalogService); | |||
Assert.Null(catalogViewModel.Brand); | |||
} | |||
[Fact] | |||
public void TypesPropertyIsNullWhenViewModelInstantiatedTest() | |||
{ | |||
var catalogService = new CatalogMockService(); | |||
var catalogViewModel = new CatalogViewModel(catalogService); | |||
Assert.Null(catalogViewModel.Types); | |||
} | |||
[Fact] | |||
public void TypePropertyIsNullWhenViewModelInstantiatedTest() | |||
{ | |||
var catalogService = new CatalogMockService(); | |||
var catalogViewModel = new CatalogViewModel(catalogService); | |||
Assert.Null(catalogViewModel.Type); | |||
} | |||
[Fact] | |||
public void IsFilterPropertyIsFalseWhenViewModelInstantiatedTest() | |||
{ | |||
var catalogService = new CatalogMockService(); | |||
var catalogViewModel = new CatalogViewModel(catalogService); | |||
Assert.False(catalogViewModel.IsFilter); | |||
} | |||
[Fact] | |||
public async Task ProductsPropertyIsNotNullAfterViewModelInitializationTest() | |||
{ | |||
var catalogService = new CatalogMockService(); | |||
var catalogViewModel = new CatalogViewModel(catalogService); | |||
await catalogViewModel.InitializeAsync(null); | |||
Assert.NotNull(catalogViewModel.Products); | |||
} | |||
[Fact] | |||
public async Task BrandsPropertyIsNotNullAfterViewModelInitializationTest() | |||
{ | |||
var catalogService = new CatalogMockService(); | |||
var catalogViewModel = new CatalogViewModel(catalogService); | |||
await catalogViewModel.InitializeAsync(null); | |||
Assert.NotNull(catalogViewModel.Brands); | |||
} | |||
[Fact] | |||
public async Task TypesPropertyIsNotNullAfterViewModelInitializationTest() | |||
{ | |||
var catalogService = new CatalogMockService(); | |||
var catalogViewModel = new CatalogViewModel(catalogService); | |||
await catalogViewModel.InitializeAsync(null); | |||
Assert.NotNull(catalogViewModel.Types); | |||
} | |||
[Fact] | |||
public async Task SettingProductsPropertyShouldRaisePropertyChanged() | |||
{ | |||
bool invoked = false; | |||
var catalogService = new CatalogMockService(); | |||
var catalogViewModel = new CatalogViewModel(catalogService); | |||
catalogViewModel.PropertyChanged += (sender, e) => | |||
{ | |||
if (e.PropertyName.Equals("Products")) | |||
invoked = true; | |||
}; | |||
await catalogViewModel.InitializeAsync(null); | |||
Assert.True(invoked); | |||
} | |||
[Fact] | |||
public async Task SettingBrandsPropertyShouldRaisePropertyChanged() | |||
{ | |||
bool invoked = false; | |||
var catalogService = new CatalogMockService(); | |||
var catalogViewModel = new CatalogViewModel(catalogService); | |||
catalogViewModel.PropertyChanged += (sender, e) => | |||
{ | |||
if (e.PropertyName.Equals("Brands")) | |||
invoked = true; | |||
}; | |||
await catalogViewModel.InitializeAsync(null); | |||
Assert.True(invoked); | |||
} | |||
[Fact] | |||
public async Task SettingTypesPropertyShouldRaisePropertyChanged() | |||
{ | |||
bool invoked = false; | |||
var catalogService = new CatalogMockService(); | |||
var catalogViewModel = new CatalogViewModel(catalogService); | |||
catalogViewModel.PropertyChanged += (sender, e) => | |||
{ | |||
if (e.PropertyName.Equals("Types")) | |||
invoked = true; | |||
}; | |||
await catalogViewModel.InitializeAsync(null); | |||
Assert.True(invoked); | |||
} | |||
[Fact] | |||
public void AddCatalogItemCommandSendsAddProductMessageTest() | |||
{ | |||
bool messageReceived = false; | |||
var catalogService = new CatalogMockService(); | |||
var catalogViewModel = new CatalogViewModel(catalogService); | |||
Xamarin.Forms.MessagingCenter.Subscribe<CatalogViewModel, CatalogItem>(this, MessageKeys.AddProduct, (sender, arg) => | |||
{ | |||
messageReceived = true; | |||
}); | |||
catalogViewModel.AddCatalogItemCommand.Execute(null); | |||
Assert.True(messageReceived); | |||
} | |||
[Fact] | |||
public async Task FilterCommandSendsFilterMessageTest() | |||
{ | |||
bool messageReceived = false; | |||
var catalogService = new CatalogMockService(); | |||
var catalogViewModel = new CatalogViewModel(catalogService); | |||
await catalogViewModel.InitializeAsync(null); | |||
catalogViewModel.Brand = catalogViewModel.Brands.FirstOrDefault(); | |||
catalogViewModel.Type = catalogViewModel.Types.FirstOrDefault(); | |||
Xamarin.Forms.MessagingCenter.Subscribe<CatalogViewModel>(this, MessageKeys.Filter, (sender) => | |||
{ | |||
messageReceived = true; | |||
}); | |||
catalogViewModel.FilterCommand.Execute(null); | |||
Assert.True(messageReceived); | |||
} | |||
[Fact] | |||
public async Task ClearFilterCommandResetsPropertiesTest() | |||
{ | |||
var catalogService = new CatalogMockService(); | |||
var catalogViewModel = new CatalogViewModel(catalogService); | |||
await catalogViewModel.InitializeAsync(null); | |||
catalogViewModel.ClearFilterCommand.Execute(null); | |||
Assert.Null(catalogViewModel.Brand); | |||
Assert.Null(catalogViewModel.Type); | |||
Assert.NotNull(catalogViewModel.Products); | |||
} | |||
} | |||
} |
@ -0,0 +1,54 @@ | |||
using Xunit; | |||
using eShopOnContainers.Core.ViewModels; | |||
using eShopOnContainers.Core.ViewModels.Base; | |||
using eShopOnContainers.Core.Models.Navigation; | |||
using System.Threading.Tasks; | |||
namespace eShopOnContainers.UnitTests | |||
{ | |||
public class MainViewModelTests | |||
{ | |||
public MainViewModelTests() | |||
{ | |||
ViewModelLocator.RegisterDependencies(true); | |||
} | |||
[Fact] | |||
public void SettingsCommandIsNotNullWhenViewModelInstantiatedTest() | |||
{ | |||
var mainViewModel = new MainViewModel(); | |||
Assert.NotNull(mainViewModel.SettingsCommand); | |||
} | |||
[Fact] | |||
public async Task ViewModelInitializationSendsChangeTabMessageTest() | |||
{ | |||
bool messageReceived = false; | |||
var mainViewModel = new MainViewModel(); | |||
var tabParam = new TabParameter { TabIndex = 2 }; | |||
Xamarin.Forms.MessagingCenter.Subscribe<MainViewModel, int>(this, MessageKeys.ChangeTab, (sender, arg) => | |||
{ | |||
messageReceived = true; | |||
}); | |||
await mainViewModel.InitializeAsync(tabParam); | |||
Assert.True(messageReceived); | |||
} | |||
[Fact] | |||
public void IsBusyPropertyIsFalseWhenViewModelInstantiatedTest() | |||
{ | |||
var mainViewModel = new MainViewModel(); | |||
Assert.False(mainViewModel.IsBusy); | |||
} | |||
[Fact] | |||
public async Task IsBusyPropertyIsTrueAfterViewModelInitializationTest() | |||
{ | |||
var mainViewModel = new MainViewModel(); | |||
await mainViewModel.InitializeAsync(null); | |||
Assert.True(mainViewModel.IsBusy); | |||
} | |||
} | |||
} |
@ -0,0 +1,113 @@ | |||
using Xunit; | |||
using eShopOnContainers.Core.ViewModels.Base; | |||
namespace eShopOnContainers.UnitTests | |||
{ | |||
public class MockViewModelTests | |||
{ | |||
public MockViewModelTests() | |||
{ | |||
ViewModelLocator.RegisterDependencies(true); | |||
} | |||
[Fact] | |||
public void CheckValidationFailsWhenPropertiesAreEmptyTest() | |||
{ | |||
var mockViewModel = new MockViewModel(); | |||
bool isValid = mockViewModel.Validate(); | |||
Assert.False(isValid); | |||
Assert.Null(mockViewModel.Forename.Value); | |||
Assert.Null(mockViewModel.Surname.Value); | |||
Assert.False(mockViewModel.Forename.IsValid); | |||
Assert.False(mockViewModel.Surname.IsValid); | |||
Assert.NotEmpty(mockViewModel.Forename.Errors); | |||
Assert.NotEmpty(mockViewModel.Surname.Errors); | |||
} | |||
[Fact] | |||
public void CheckValidationFailsWhenOnlyForenameHasDataTest() | |||
{ | |||
var mockViewModel = new MockViewModel(); | |||
mockViewModel.Forename.Value = "John"; | |||
bool isValid = mockViewModel.Validate(); | |||
Assert.False(isValid); | |||
Assert.NotNull(mockViewModel.Forename.Value); | |||
Assert.Null(mockViewModel.Surname.Value); | |||
Assert.True(mockViewModel.Forename.IsValid); | |||
Assert.False(mockViewModel.Surname.IsValid); | |||
Assert.Empty(mockViewModel.Forename.Errors); | |||
Assert.NotEmpty(mockViewModel.Surname.Errors); | |||
} | |||
[Fact] | |||
public void CheckValidationPassesWhenOnlySurnameHasDataTest() | |||
{ | |||
var mockViewModel = new MockViewModel(); | |||
mockViewModel.Surname.Value = "Smith"; | |||
bool isValid = mockViewModel.Validate(); | |||
Assert.False(isValid); | |||
Assert.Null(mockViewModel.Forename.Value); | |||
Assert.NotNull(mockViewModel.Surname.Value); | |||
Assert.False(mockViewModel.Forename.IsValid); | |||
Assert.True(mockViewModel.Surname.IsValid); | |||
Assert.NotEmpty(mockViewModel.Forename.Errors); | |||
Assert.Empty(mockViewModel.Surname.Errors); | |||
} | |||
[Fact] | |||
public void CheckValidationPassesWhenBothPropertiesHaveDataTest() | |||
{ | |||
var mockViewModel = new MockViewModel(); | |||
mockViewModel.Forename.Value = "John"; | |||
mockViewModel.Surname.Value = "Smith"; | |||
bool isValid = mockViewModel.Validate(); | |||
Assert.True(isValid); | |||
Assert.NotNull(mockViewModel.Forename.Value); | |||
Assert.NotNull(mockViewModel.Surname.Value); | |||
Assert.True(mockViewModel.Forename.IsValid); | |||
Assert.True(mockViewModel.Surname.IsValid); | |||
Assert.Empty(mockViewModel.Forename.Errors); | |||
Assert.Empty(mockViewModel.Surname.Errors); | |||
} | |||
[Fact] | |||
public void SettingForenamePropertyShouldRaisePropertyChanged() | |||
{ | |||
bool invoked = false; | |||
var mockViewModel = new MockViewModel(); | |||
mockViewModel.Forename.PropertyChanged += (sender, e) => | |||
{ | |||
if (e.PropertyName.Equals("Value")) | |||
invoked = true; | |||
}; | |||
mockViewModel.Forename.Value = "John"; | |||
Assert.True(invoked); | |||
} | |||
[Fact] | |||
public void SettingSurnamePropertyShouldRaisePropertyChanged() | |||
{ | |||
bool invoked = false; | |||
var mockViewModel = new MockViewModel(); | |||
mockViewModel.Surname.PropertyChanged += (sender, e) => | |||
{ | |||
if (e.PropertyName.Equals("Value")) | |||
invoked = true; | |||
}; | |||
mockViewModel.Surname.Value = "Smith"; | |||
Assert.True(invoked); | |||
} | |||
} | |||
} |
@ -0,0 +1,55 @@ | |||
using Xunit; | |||
using eShopOnContainers.Core; | |||
using eShopOnContainers.Core.ViewModels; | |||
using eShopOnContainers.Core.ViewModels.Base; | |||
using eShopOnContainers.Core.Services.Order; | |||
using System.Threading.Tasks; | |||
namespace eShopOnContainers.UnitTests | |||
{ | |||
public class OrderViewModelTests | |||
{ | |||
public OrderViewModelTests() | |||
{ | |||
ViewModelLocator.RegisterDependencies(true); | |||
} | |||
[Fact] | |||
public void OrderPropertyIsNullWhenViewModelInstantiatedTest() | |||
{ | |||
var orderService = new OrderMockService(); | |||
var orderViewModel = new OrderDetailViewModel(orderService); | |||
Assert.Null(orderViewModel.Order); | |||
} | |||
[Fact] | |||
public async Task OrderPropertyIsNotNullAfterViewModelInitializationTest() | |||
{ | |||
var orderService = new OrderMockService(); | |||
var orderViewModel = new OrderDetailViewModel(orderService); | |||
var order = await orderService.GetOrderAsync(1, GlobalSetting.Instance.AuthToken); | |||
await orderViewModel.InitializeAsync(order); | |||
Assert.NotNull(orderViewModel.Order); | |||
} | |||
[Fact] | |||
public async Task SettingOrderPropertyShouldRaisePropertyChanged() | |||
{ | |||
bool invoked = false; | |||
var orderService = new OrderMockService(); | |||
var orderViewModel = new OrderDetailViewModel(orderService); | |||
orderViewModel.PropertyChanged += (sender, e) => | |||
{ | |||
if (e.PropertyName.Equals("Order")) | |||
invoked = true; | |||
}; | |||
var order = await orderService.GetOrderAsync(1, GlobalSetting.Instance.AuthToken); | |||
await orderViewModel.InitializeAsync(order); | |||
Assert.True(invoked); | |||
} | |||
} | |||
} |
@ -1,10 +1,11 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<packages> | |||
<package id="xunit" version="2.2.0-beta4-build3444" targetFramework="portable46-net451+win81" /> | |||
<package id="xunit.abstractions" version="2.0.1" targetFramework="portable46-net451+win81" /> | |||
<package id="xunit.assert" version="2.2.0-beta4-build3444" targetFramework="portable46-net451+win81" /> | |||
<package id="xunit.core" version="2.2.0-beta4-build3444" targetFramework="portable46-net451+win81" /> | |||
<package id="xunit.extensibility.core" version="2.2.0-beta4-build3444" targetFramework="portable46-net451+win81" /> | |||
<package id="xunit.extensibility.execution" version="2.2.0-beta4-build3444" targetFramework="portable46-net451+win81" /> | |||
<package id="xunit.runner.console" version="2.2.0-beta4-build3444" targetFramework="portable46-net451+win81" developmentDependency="true" /> | |||
<package id="Xamarin.Forms" version="2.3.4.231" targetFramework="portable46-net451+win81" /> | |||
<package id="xunit" version="2.2.0-beta4-build3444" targetFramework="portable-net451+win81" /> | |||
<package id="xunit.abstractions" version="2.0.1" targetFramework="portable-net451+win81" requireReinstallation="True" /> | |||
<package id="xunit.assert" version="2.2.0-beta4-build3444" targetFramework="portable-net451+win81" requireReinstallation="True" /> | |||
<package id="xunit.core" version="2.2.0-beta4-build3444" targetFramework="portable-net451+win81" requireReinstallation="True" /> | |||
<package id="xunit.extensibility.core" version="2.2.0-beta4-build3444" targetFramework="portable-net451+win81" requireReinstallation="True" /> | |||
<package id="xunit.extensibility.execution" version="2.2.0-beta4-build3444" targetFramework="portable-net451+win81" requireReinstallation="True" /> | |||
<package id="xunit.runner.console" version="2.2.0-beta4-build3444" targetFramework="portable-net451+win81" developmentDependency="true" /> | |||
</packages> |