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
74 changes: 52 additions & 22 deletions PhoneAssistant.Model.Tests/Repositories/PhonesRepositoryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,28 +113,6 @@ public async Task Exists_ShouldReturnTrue_WhenPhoneDoesExistAsync()
await Assert.That(actual).IsTrue();
}

[Test]
public async Task GetPhonebyUser_should_only_return_lastest_In_Stock_phone()
{
Phone[] phones = [
new Phone() { Imei = "1" , AssetTag = "Tag A1", Model = "", Condition = "N", OEM = Manufacturer.Nokia, Status = "In Repair", NewUser = "new user"},
new Phone() { Imei = "2" , AssetTag = "Tag B2", Model = "", Condition = "N", OEM = Manufacturer.Samsung, Status = "Production", NewUser = "new user"},
new Phone() { Imei = "3" , AssetTag = "Tag C3", Model = "", Condition = "N", OEM = Manufacturer.Nokia, Status = "Production", NewUser = "new user"},
new Phone() { Imei = "4" , AssetTag = "Tag D4", Model = "", Condition = "N", OEM = Manufacturer.Other, Status = "Decommissioned", NewUser = "new user"},
new Phone() { Imei = "5" , AssetTag = "Tag E5", Model = "", Condition = "N", OEM = Manufacturer.Apple, Status = "Disposed", NewUser = "new user"}
];
for (int i = 0; i < phones.Length; i++)
{
await _repository.CreateAsync(phones[i]);
await Task.Delay(1100); // Ensure LastUpdate will be different on updated record
}

var actual = await _repository.GetPhonebyUser("new user");

await Assert.That(actual).IsNotNull();
await Assert.That(actual.Imei).IsEqualTo("3");
}

[Test]
public async Task UpdateAsync_WithNullPhone_ThrowsException()
{
Expand Down Expand Up @@ -298,4 +276,56 @@ public async Task UpdateStatusAsync_WithStatusChange_Succeeds()
await Assert.That(actual).IsNotNull();
await Assert.That(actual!.Status).IsEqualTo(ApplicationConstants.StatusDisposed);
}

[Test]
public async Task UserHasProductionPhone_should_return_false_when_no_Production_phone_found()
{
Phone[] phones = [
new Phone() { Imei = "1" , AssetTag = "Tag A1", Model = "", Condition = "N", OEM = Manufacturer.Nokia, Status = "In Repair", NewUser = "new user"},
new Phone() { Imei = "2" , AssetTag = "Tag B2", Model = "", Condition = "N", OEM = Manufacturer.Samsung, Status = "Decommissioned", NewUser = "new user"},
new Phone() { Imei = "3" , AssetTag = "Tag C3", Model = "", Condition = "N", OEM = Manufacturer.Nokia, Status = "Disposed", NewUser = "new user"},
new Phone() { Imei = "4" , AssetTag = "Tag D4", Model = "", Condition = "N", OEM = Manufacturer.Other, Status = "Decommissioned", NewUser = "new user"},
new Phone() { Imei = "5" , AssetTag = "Tag E5", Model = "", Condition = "N", OEM = Manufacturer.Apple, Status = "Disposed", NewUser = "new user"}
];
_helper.DbContext.Phones.AddRange(phones);
_helper.DbContext.SaveChanges();

bool actual = await _repository.UserHasProductionPhone("new user");

await Assert.That(actual).IsFalse();
}

[Test]
public async Task UserHasProductionPhone_should_return_true_when_Production_phone_found()
{
Phone[] phones = [
new Phone() { Imei = "1" , AssetTag = "Tag A1", Model = "", Condition = "N", OEM = Manufacturer.Nokia, Status = "In Repair", NewUser = "new user"},
new Phone() { Imei = "2" , AssetTag = "Tag B2", Model = "", Condition = "N", OEM = Manufacturer.Samsung, Status = "Production", NewUser = "new user"},
new Phone() { Imei = "3" , AssetTag = "Tag C3", Model = "", Condition = "N", OEM = Manufacturer.Nokia, Status = "Production", NewUser = "new user"},
new Phone() { Imei = "4" , AssetTag = "Tag D4", Model = "", Condition = "N", OEM = Manufacturer.Other, Status = "Decommissioned", NewUser = "new user"},
new Phone() { Imei = "5" , AssetTag = "Tag E5", Model = "", Condition = "N", OEM = Manufacturer.Apple, Status = "Disposed", NewUser = "new user"}
];
_helper.DbContext.Phones.AddRange(phones);
_helper.DbContext.SaveChanges();

bool actual = await _repository.UserHasProductionPhone("new user");

await Assert.That(actual).IsTrue();
}

[Test]
[Arguments("new user")]
[Arguments("New user")]
[Arguments("New User")]
[Arguments("NEW USER")]
public async Task UserHasProductionPhone_is_case_insensitive(string newUser)
{
Phone phone = new() { Imei = "1", AssetTag = "Tag A1", Model = "", Condition = "N", OEM = Manufacturer.Samsung, Status = "Production", NewUser = "NEW USER" };
await _helper.DbContext.Phones.AddAsync(phone);
_helper.DbContext.SaveChanges();

bool actual = await _repository.UserHasProductionPhone(newUser);

await Assert.That(actual).IsTrue();
}
}
1 change: 1 addition & 0 deletions PhoneAssistant.Model/Repositories/IPhonesRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public interface IPhonesRepository
Task<IEnumerable<Phone>> GetActivePhonesAsync();
Task<IEnumerable<Phone>> GetAllPhonesAsync();
Task<Phone?> GetPhoneAsync(string imei);
Task<bool> UserHasProductionPhone(string user);
Task<bool> PhoneNumberExistsAsync(string phoneNumber);
Task<Result> UpdateAsync(Phone phone);
Task UpdateStatusAsync(string imei, string status);
Expand Down
7 changes: 2 additions & 5 deletions PhoneAssistant.Model/Repositories/PhonesRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,9 @@ public async Task<IEnumerable<Phone>> GetAllPhonesAsync()
return await dbContext.Phones.FindAsync(imei);
}

public async Task<Phone?> GetPhonebyUser(string user)
public async Task<bool> UserHasProductionPhone(string user)
{
return await dbContext.Phones.Where(p => p.NewUser == user)
.Where(p => p.Status == "Production")
.OrderByDescending(p => p.LastUpdate)
.FirstOrDefaultAsync();
return await dbContext.Phones.AnyAsync(p => EF.Functions.Collate(p.NewUser, "NOCASE") == user && p.Status == "Production");
}

public async Task<bool> PhoneNumberExistsAsync(string phoneNumber)
Expand Down
117 changes: 68 additions & 49 deletions PhoneAssistant.Tests/Features/Phones/PhonesItemViewModelTests.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
using Moq;
using CommunityToolkit.Mvvm.Messaging;
using Moq;
using Moq.AutoMock;

using PhoneAssistant.Model;
using PhoneAssistant.WPF.Features.Phones;
using PhoneAssistant.Tests.Shared;

namespace PhoneAssistant.Tests.Features.Phones;

Expand All @@ -27,7 +28,7 @@ public sealed class PhonesItemViewModelTests
SerialNumber = "sn",
};

private readonly AutoMocker _mocker = new AutoMocker();
private readonly AutoMocker _mocker = new();
private readonly PhonesItemViewModel _vm;
private readonly Mock<IPhonesRepository> _repository;

Expand All @@ -41,38 +42,22 @@ public PhonesItemViewModelTests()
}

[Test]
[Arguments("phone number", "sim number", "In Stock")]
[Arguments(null, "sim number", "In Stock")]
[Arguments("phone number", null, "In Stock")]
[Arguments(null, null, "In Stock")]
[Arguments("phone number", "sim number", "Production")]
[Arguments(null, "sim number", "Production")]
[Arguments("phone number", null, "Production")]
[Arguments(null, null, "Production")]
public async Task PhonePropertySet_SetsBoundProperties(string? phoneNumber, string? simNumber, string status)
[Arguments("In Stock", null, null, false)]
[Arguments("In Repair", null, null, false)]
[Arguments("Production", null, null, false)]
[Arguments("Production", 123, null, false)]
[Arguments("Production", null, "new user", false)]
[Arguments("Production", 123, "new user", true)]
public async Task CreateEmailCommand_CanExecuteAsync(string status, int? sr, string? newUser, bool canExecute)
{
_phone.PhoneNumber = phoneNumber;
_phone.SimNumber = simNumber;
_phone.Status = status;
_phone.Ticket = sr;
_phone.NewUser = newUser;
var vm = _mocker.CreateInstance<PhonesItemViewModel>();

await Assert.That(vm.AssetTag).IsEqualTo(_phone.AssetTag);
await Assert.That(vm.Esim).IsEqualTo(_phone.Esim ?? false);
await Assert.That(vm.FormerUser).IsEqualTo(_phone.FormerUser);
await Assert.That(vm.Imei).IsEqualTo(_phone.Imei);
await Assert.That(vm.Model).IsEqualTo(_phone.Model);
await Assert.That(vm.NewUser).IsEqualTo(_phone.NewUser);
await Assert.That(vm.NorR).IsEqualTo(_phone.Condition);
await Assert.That(vm.Notes).IsEqualTo(_phone.Notes);
await Assert.That(vm.OEM).IsEqualTo(_phone.OEM);
await Assert.That(vm.PhoneNumber).IsEqualTo(_phone.PhoneNumber ?? string.Empty);
await Assert.That(vm.SerialNumber).IsEqualTo(_phone.SerialNumber ?? string.Empty);
await Assert.That(vm.SimNumber).IsEqualTo(_phone.SimNumber ?? string.Empty);
await Assert.That(vm.SR).IsEqualTo(_phone.Ticket.ToString());
await Assert.That(vm.Status).IsEqualTo(_phone.Status);
await Assert.That(vm.CreateEmailCommand.CanExecute(null)).IsEqualTo(canExecute);
}

#region Update
[Test]
public async Task OnAssetTagChanged_CallsUpdateAsync_WithChangedValueAsync()
{
Expand Down Expand Up @@ -125,9 +110,31 @@ public async Task OnNewUserChanged_CallsUpdateAsync_WithChangedValueAsync(string
_repository.Verify(r => r.UpdateAsync(_phone), Times.Once);
await Assert.That(_phone.NewUser).IsEqualTo(expected);
await Assert.That(_vm.LastUpdate).IsEqualTo(_phone.LastUpdate);
}

[Test]
public async Task OnNewUserChanged_should_not_send_ProductionPhoneWarning_when_NewUser_has_no_Production_phone()
{
_repository.Setup(r => r.UserHasProductionPhone("phoneuser")).ReturnsAsync(false);
var messenger = _mocker.GetMock<IMessenger>();

_vm.NewUser = "phoneuser";

messenger.Verify(m => m.Send(It.IsAny<ProductionPhoneWarning>(), It.IsAny<IsAnyToken>()), Times.Never);
}

[Test]
public async Task OnNewUserChanged_should_send_ProductionPhoneWarning_when_NewUser_has_no_Production_phone()
{
_repository.Setup(r => r.UserHasProductionPhone("phoneuser")).ReturnsAsync(true);
var messenger = _mocker.GetMock<IMessenger>();

_vm.NewUser = "phoneuser";

messenger.Verify(m => m.Send(It.IsAny<ProductionPhoneWarning>(), It.IsAny<IsAnyToken>()), Times.Once);
}


[Test]
public async Task OnNorRChanged_CallsUpdateAsync_WithChangedValueAsync()
{
Expand Down Expand Up @@ -298,9 +305,39 @@ public async Task OnStatusChanged_ShouldSetTicketToDefault_WhenDecommissionedAsy

await Assert.That(_vm.SR).IsEqualTo("987654");
}
#endregion

[Test]
[Arguments("phone number", "sim number", "In Stock")]
[Arguments(null, "sim number", "In Stock")]
[Arguments("phone number", null, "In Stock")]
[Arguments(null, null, "In Stock")]
[Arguments("phone number", "sim number", "Production")]
[Arguments(null, "sim number", "Production")]
[Arguments("phone number", null, "Production")]
[Arguments(null, null, "Production")]
public async Task PhonePropertySet_SetsBoundProperties(string? phoneNumber, string? simNumber, string status)
{
_phone.PhoneNumber = phoneNumber;
_phone.SimNumber = simNumber;
_phone.Status = status;
var vm = _mocker.CreateInstance<PhonesItemViewModel>();

await Assert.That(vm.AssetTag).IsEqualTo(_phone.AssetTag);
await Assert.That(vm.Esim).IsEqualTo(_phone.Esim ?? false);
await Assert.That(vm.FormerUser).IsEqualTo(_phone.FormerUser);
await Assert.That(vm.Imei).IsEqualTo(_phone.Imei);
await Assert.That(vm.Model).IsEqualTo(_phone.Model);
await Assert.That(vm.NewUser).IsEqualTo(_phone.NewUser);
await Assert.That(vm.NorR).IsEqualTo(_phone.Condition);
await Assert.That(vm.Notes).IsEqualTo(_phone.Notes);
await Assert.That(vm.OEM).IsEqualTo(_phone.OEM);
await Assert.That(vm.PhoneNumber).IsEqualTo(_phone.PhoneNumber ?? string.Empty);
await Assert.That(vm.SerialNumber).IsEqualTo(_phone.SerialNumber ?? string.Empty);
await Assert.That(vm.SimNumber).IsEqualTo(_phone.SimNumber ?? string.Empty);
await Assert.That(vm.SR).IsEqualTo(_phone.Ticket.ToString());
await Assert.That(vm.Status).IsEqualTo(_phone.Status);
}

#region RemoveSim
[Test]
public async Task RemoveSim_SetsBoundPropertiesAsync()
{
Expand Down Expand Up @@ -334,22 +371,4 @@ public async Task RemoveSimCommand_SetsCanExecute_FalseAsync()

await Assert.That(_vm.RemoveSimCommand.CanExecute(null)).IsFalse();
}
#endregion

[Test]
[Arguments("In Stock", null, null, false)]
[Arguments("In Repair", null, null, false)]
[Arguments("Production", null, null, false)]
[Arguments("Production", 123, null, false)]
[Arguments("Production", null, "new user", false)]
[Arguments("Production", 123, "new user", true)]
public async Task CreateEmailCommand_CanExecuteAsync(string status, int? sr, string? newUser, bool canExecute)
{
_phone.Status = status;
_phone.Ticket = sr;
_phone.NewUser = newUser;
var vm = _mocker.CreateInstance<PhonesItemViewModel>();

await Assert.That(vm.CreateEmailCommand.CanExecute(null)).IsEqualTo(canExecute);
}
}
17 changes: 14 additions & 3 deletions PhoneAssistant.Tests/Features/Phones/PhonesMainViewModelTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ public sealed class PhonesMainViewModelTests
[Test]
public async Task ChangingFilterAssetTag_ChangesFilterViewAsync()
{
List<Phone> phones = new List<Phone>() {
List<Phone> phones = [
new Phone() { Imei = "1" , AssetTag = "Tag A1", Model = "", Condition = "", OEM = Manufacturer.Apple, Status = ""},
new Phone() { Imei = "2" , AssetTag = "Tag Bb2", Model = "", Condition = "", OEM = Manufacturer.Apple, Status = ""},
new Phone() {Imei = "3", AssetTag = "Tag Ccc3", Model = "", Condition = "", OEM = Manufacturer.Apple, Status = ""}
};
];
PhonesMainViewModel vm = ViewModelMockSetup(phones);
await vm.LoadAsync();
ICollectionView view = CollectionViewSource.GetDefaultView(vm.PhoneItems);
Expand Down Expand Up @@ -328,7 +328,7 @@ public async Task LoadAsync_should_call_GetAllPhones_when_IncludeDisposals_true(
}

[Test]
public async Task Receive_ShouldAddPhoneAsync()
public async Task Receive_Phone_should_add_phone_to_PhoneItems()
{
AutoMocker mocker = new();
PhonesMainViewModel vm = mocker.CreateInstance<PhonesMainViewModel>();
Expand All @@ -338,6 +338,17 @@ public async Task Receive_ShouldAddPhoneAsync()
await Assert.That(vm.PhoneItems.Any()).IsTrue();
}

[Test]
public async Task Receive_ProductionPhoneWarning_should_make_warning_visible()
{
AutoMocker mocker = new();
PhonesMainViewModel vm = mocker.CreateInstance<PhonesMainViewModel>();

vm.Receive(new ProductionPhoneWarning("message"));

await Assert.That(vm.ProductionPhoneWarning).IsEqualTo(Visibility.Visible);
}

[Test]
public async Task SelectedPhone_should_leave_ConcurrentUpdateWarning_as_collapsed_when_ConcurrentChange_false()
{
Expand Down
15 changes: 10 additions & 5 deletions PhoneAssistant.WPF/Features/Phones/PhonesItemViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using CommunityToolkit.Mvvm.ComponentModel;
using System.Windows;

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;

using PhoneAssistant.Model;
using PhoneAssistant.WPF.Shared;

Expand Down Expand Up @@ -121,17 +124,16 @@ async partial void OnNewUserChanged(string value)
if (string.IsNullOrEmpty(value))
{
if (_phone.NewUser is null)
{
return;
}
else
{
_phone.NewUser = null;
}
}
else
{
_phone.NewUser = value;

if (await _repository.UserHasProductionPhone(value))
_messenger.Send(new ProductionPhoneWarning("User has phone in production"));
}

await UpdatePhone();
Expand Down Expand Up @@ -291,6 +293,9 @@ async partial void OnStatusChanged(string value)

_phone.Status = value;

//if (await _repository.UserHasProductionPhone(value))
// _messenger.Send(new ProductionPhoneWarning("User has phone in production"));

await UpdatePhone();
}

Expand Down
Loading
Loading