Skip to content

Commit

Permalink
Added unit testing for defaultAdminAccountService
Browse files Browse the repository at this point in the history
Includes refactoring based on the tests.

Some aditional methods are now public in the DefaultAdminAccountService to better allow for testing these.
  • Loading branch information
SimonFlapse authored and grilledham committed Aug 22, 2020
1 parent 5ab2b29 commit a11ae16
Show file tree
Hide file tree
Showing 3 changed files with 172 additions and 14 deletions.
26 changes: 14 additions & 12 deletions FactorioWebInterface/Services/DefaultAdminAccountService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ public DefaultAdminAccountService(UserManager<ApplicationUser> userManager, ILog
_fileSystem = fileSystem;
}

private enum AccountsNumbers
public enum AccountsNumbers
{
NoAccounts,
OnlyDefaultAccount,
NoRootAccount,
DefaultIsOnlyRootAccount,
MultipleAccounts
}
Expand All @@ -44,21 +44,22 @@ public async Task SetupDefaultUserAsync()
switch (await OnlyAccount())
{
case AccountsNumbers.DefaultIsOnlyRootAccount:
case AccountsNumbers.OnlyDefaultAccount:
_logger.LogInformation("{UserId} could not be created, another account already exists", Constants.DefaultAdminAccount);
return;
case AccountsNumbers.MultipleAccounts:
await ValidateOrClearDefaultUserAsync(id, true);
return;
case AccountsNumbers.NoAccounts:
break;
case AccountsNumbers.NoRootAccount:
break;
}

await CreateDefaultUserAsync(id);
}

//Suggestion: Perform count directly on database (Eg. using LINQ or SQL)
private async Task<AccountsNumbers> OnlyAccount()
public async Task<AccountsNumbers> OnlyAccount()
{

var rootUsers = await _userManager.GetUsersInRoleAsync(Constants.RootRole);
Expand All @@ -71,20 +72,21 @@ private async Task<AccountsNumbers> OnlyAccount()

var users = _userManager.Users;
int userCount = users.Count();
if (userCount == 1 && await ValidateDefaultUserAsync(users.First()))
{
return AccountsNumbers.OnlyDefaultAccount;
}

if (userCount > 0 && rootCount > 0)
{
return AccountsNumbers.MultipleAccounts;
}

return AccountsNumbers.NoAccounts;
if (userCount == 0)
{
return AccountsNumbers.NoAccounts;
}

return AccountsNumbers.NoRootAccount;
}

private async Task ValidateOrClearDefaultUserAsync(string id, bool force = false)
public async Task ValidateOrClearDefaultUserAsync(string id, bool force = false)
{
ApplicationUser userResult = await _userManager.FindByIdAsync(id);
if (await ValidateDefaultUserAsync(userResult) && !force)
Expand All @@ -105,7 +107,7 @@ private async Task ValidateOrClearDefaultUserAsync(string id, bool force = false
}
}

private async Task<bool> ValidateDefaultUserAsync(ApplicationUser user)
public async Task<bool> ValidateDefaultUserAsync(ApplicationUser user)
{
if (user == null || user.UserName != Constants.DefaultAdminName)
{
Expand Down Expand Up @@ -169,7 +171,7 @@ private async Task CreateDefaultUserAsync(string id)
_fileSystem.File.WriteAllText(path, $"{warningTag}\nThis account is unsecure. Please setup a personal account.\n{warningTag}\nUsername: {Constants.DefaultAdminName}\nPassword: {password}");
}

private void DeleteDefaultAccountFile()
public void DeleteDefaultAccountFile()
{
var path = GetDefaultAccountFilePath();
try
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ public static ServiceProvider MakeDefaultAdminAccountServiceProvider()
.AddSingleton(typeof(ILogger<>), typeof(TestLogger<>))
.AddSingleton<IFileSystem, MockFileSystem>()
.AddTransient<ApplicationDbContext>(_ => dbContextFactory.Create<ApplicationDbContext>())
.AddTransient<DefaultAdminAccountService>();
.AddTransient<DefaultAdminAccountService>()
.AddTransient<UserManager<ApplicationUser>>();
Startup.SetupIdentity(serviceCollection);

return serviceCollection.BuildServiceProvider();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.IO.Abstractions;
using System.IO.Abstractions.TestingHelpers;
using System.Linq;
Expand All @@ -20,6 +21,7 @@ public class SetupDefaultUserAsync : IDisposable
private readonly TestLogger<IDefaultAdminAccountService> logger;
private readonly MockFileSystem fileSystem;
private readonly RoleManager<IdentityRole> roleManager;
private readonly UserManager<ApplicationUser> userManager;
private readonly DefaultAdminAccountService defaultAdminAccountService;

public SetupDefaultUserAsync()
Expand All @@ -28,7 +30,9 @@ public SetupDefaultUserAsync()
logger = (TestLogger<IDefaultAdminAccountService>)serviceProvider.GetRequiredService<ILogger<IDefaultAdminAccountService>>();
fileSystem = (MockFileSystem)serviceProvider.GetRequiredService<IFileSystem>();
roleManager = serviceProvider.GetService<RoleManager<IdentityRole>>();
userManager = serviceProvider.GetService<UserManager<ApplicationUser>>();
defaultAdminAccountService = serviceProvider.GetRequiredService<DefaultAdminAccountService>();
DefaultAdminAccountServiceHelper.SetupRoles(roleManager);
}

public void Dispose()
Expand All @@ -40,7 +44,6 @@ public void Dispose()
public async Task CreatedSuccessfully()
{
// Arrange.
DefaultAdminAccountServiceHelper.SetupRoles(roleManager);
DefaultAdminAccountServiceHelper.SetupFileSystem(fileSystem);

// Act.
Expand All @@ -61,5 +64,157 @@ public async Task CreatedSuccessfully()

logger.AssertContainsLog(LogLevel.Warning, $"{Constants.DefaultAdminAccount} created. This action potential exposes your interface, creating a new account and restarting this web interface will disable the default admin account");
}

[Fact]
public async Task DefaultIsOnlyRootAccountTest()
{
// Arrange.
await CreatedSuccessfully();

// Act.
var result = await defaultAdminAccountService.OnlyAccount();

// Assert.
Assert.Equal(DefaultAdminAccountService.AccountsNumbers.DefaultIsOnlyRootAccount, result);
}

[Fact]
public async Task MultipleAccountsTest()
{
// Arrange.
await CreatedSuccessfully();
var user = new ApplicationUser()
{
Id = "testUser",
UserName = "Test User"
};
await userManager.CreateAsync(user, "testing1234");
await userManager.AddToRoleAsync(user, Constants.RootRole);

// Act.
var result = await defaultAdminAccountService.OnlyAccount();

// Assert.
Assert.Equal(DefaultAdminAccountService.AccountsNumbers.MultipleAccounts, result);
}

[Fact]
public async Task MultipleAccountsNoDefaultUserTest()
{
// Arrange.
var user = new ApplicationUser()
{
Id = "testRootUser",
UserName = "Test Root User"
};
await userManager.CreateAsync(user, "testing1234");
await userManager.AddToRoleAsync(user, Constants.RootRole);

user = new ApplicationUser()
{
Id = "testAdminUser",
UserName = "Test Admin User"
};
await userManager.CreateAsync(user, "testing1234");
await userManager.AddToRoleAsync(user, Constants.AdminRole);

// Act.
var result = await defaultAdminAccountService.OnlyAccount();

// Assert.
Assert.Equal(DefaultAdminAccountService.AccountsNumbers.MultipleAccounts, result);
}

[Fact]
public async Task NoAccountsTest()
{
// Arrange.

// Act.
var result = await defaultAdminAccountService.OnlyAccount();

// Assert.
Assert.Equal(DefaultAdminAccountService.AccountsNumbers.NoAccounts, result);
}

[Fact]
public async Task NoRootAccountTest()
{
// Arrange.
var user = new ApplicationUser()
{
Id = "testUser",
UserName = "Test User"
};
await userManager.CreateAsync(user, "testing1234");

// Act.
var result = await defaultAdminAccountService.OnlyAccount();

// Assert.
Assert.Equal(DefaultAdminAccountService.AccountsNumbers.NoRootAccount, result);
}

private async Task ValidateDefaultUser(ApplicationUser user, bool expected)
{
// Arrange.

// Act.
var result = await defaultAdminAccountService.ValidateDefaultUserAsync(user);

// Assert.
Assert.Equal(expected, result);
}

[Fact]
public async Task ValidateDefaultUserTest()
{
// Arrange.
await CreatedSuccessfully();
var validDefaultUser = await userManager.FindByIdAsync(Constants.DefaultAdminAccount);

var invalidDefaultUser = new ApplicationUser()
{
Id = "DefaultTestUser",
UserName = "Default Test User"
};
await userManager.CreateAsync(invalidDefaultUser, Guid.NewGuid().ToString());
await userManager.AddToRolesAsync(invalidDefaultUser, new string[] { Constants.AdminRole, Constants.RootRole });

var invalidPassword = new ApplicationUser()
{
Id = "DefaultTestUserPassword",
UserName = Constants.DefaultAdminName
};
await userManager.CreateAsync(invalidPassword);
await userManager.AddToRolesAsync(invalidPassword, new string[] { Constants.AdminRole, Constants.RootRole });

var invalidRole = new ApplicationUser()
{
Id = "DefaultTestUserRole",
UserName = Constants.DefaultAdminName
};
await userManager.CreateAsync(invalidRole, Guid.NewGuid().ToString());
await userManager.AddToRoleAsync(invalidRole, Constants.AdminRole);

// Act.
await ValidateDefaultUser(validDefaultUser, true);
await ValidateDefaultUser(invalidDefaultUser, false);
await ValidateDefaultUser(invalidPassword, false);
await ValidateDefaultUser(invalidRole, false);
}

[Fact]
public async Task DeleteDefaultAccountFileTest()
{
// Arrange.
await CreatedSuccessfully();

// Act.
defaultAdminAccountService.DeleteDefaultAccountFile();

// Assert.
Assert.False(fileSystem.File.Exists(DefaultAdminAccountServiceHelper.filePath));
}
}
}

0 comments on commit a11ae16

Please sign in to comment.