I am trying to supply an ApplicationUser to my mocked ApplicationUserManager. When I try and add roles I notice that Roles is a read-only property. Not sure the best way to implement in my test.
[TestMethod]
public void AccountPerission_PermissionScope()
{
//Arrange
IRolePermissionSvc roleService = GetRoleService();
IUserPermissionSvc userService = GetUserService();
AccountController controller = new AccountController(
_applicationUserManager.Object,
null,
_staffTypeSvc.Object,
_militaryBaseSvc.Object,
_positionTitleSvc.Object,
userService,
roleService
);
var appUser = new ApplicationUser()
{
FirstName = "test",
LastName = "tester",
Id = "02dfeb89-9b80-4884-b694-862adf38f09d",
Roles = new List<ApplicationRoles> { new ApplicationRole { Id = "1" } } // This doesn't work.
};
//Act
_applicationUserManager.Setup(x => x.FindByIdAsync(It.IsAny<string>())).Returns(Task.FromResult<ApplicationUser>(appUser));
Task<PartialViewResult> result = controller.AjaxResetUserPermission(appUser.Id, 1);
//Assert
Assert.IsNotNull(result);
}
While Roles is a read-only property, it is virtual which means that it can be overridden in a derived class. So you can either create a class derived from ApplicationUser
public class MockApplicationUser : ApplicationUser {
private readonly ICollection<ApplicationRoles> roles
public MockedApplicationUser(List<ApplicationRoles> roles) : base() {
this.roles = roles;
}
public override ICollection<ApplicationRoles> Roles {
get { return roles; }
}
}
and use that in the test
var appUser = new MockApplicationUser(new List<ApplicationRoles> { new ApplicationRole { Id = "1" } })
{
FirstName = "test",
LastName = "tester",
Id = "02dfeb89-9b80-4884-b694-862adf38f09d"
};
or mock the ApplicationUser and setup the Roles property
var roles = new List<ApplicationRoles> { new ApplicationRole { Id = "1" } };
var appUserMock = new Mock<ApplicationUser>();
appUserMock.SetupAllProperties();
appUserMock.Setup(m => m.Roles).Returns(roles);
var appUser = appUserMock.Object;
appUser.FirstName = "test";
appUser.LastName = "tester";
appUser.Id = "02dfeb89-9b80-4884-b694-862adf38f09d";
As an aside, the test method can also be made async
[TestMethod]
public async Task AccountPerission_PermissionScope() {
//Arrange
//..code removed for brevity
_applicationUserManager
.Setup(x => x.FindByIdAsync(It.IsAny<string>()))
.ReturnsAsync(appUser);
//Act
var result = await controller.AjaxResetUserPermission(appUser.Id, 1);
//Assert
Assert.IsNotNull(result);
}
Related
Till .net5 I've been Seeding data using the following in startup.cs file:
SeedData.Seed(_userManager, _roleManager);
And then in a seperate file SeedData.cs, the following code:
public static class SeedData
{
public static void Seed(UserManager<IdentityUser> userManager, RoleManager<IdentityRole> roleManager)
{
SeedRoles(roleManager);
SeedUsers(userManager);
}
private static void SeedUsers(UserManager<IdentityUser> userManager)
{
if(userManager.FindByNameAsync("admin#localhost.com").Result == null)
{
var user = new IdentityUser
{
UserName = "admin#localhost.com",
Email = "admin#localhost.com"
};
var result = userManager.CreateAsync(user, "P#ssword1").Result;
if(result.Succeeded)
{
userManager.AddToRoleAsync(user, "Administrator").Wait();
}
}
}
private static void SeedRoles(RoleManager<IdentityRole> roleManager)
{
if(!roleManager.RoleExistsAsync("Administrator").Result)
{
var role = new IdentityRole
{
Name = "Administrator",
};
var result = roleManager.CreateAsync(role).Result;
}
if(!roleManager.RoleExistsAsync("Employee").Result)
{
var role = new IdentityRole
{
Name = "Employee",
};
var result = roleManager.CreateAsync(role).Result;
}
}
}
Now, how do i do the same with .net6, since it has only program.cs file?
This is what I personally do:
I make an extension to IApplicationBuilder:
public static class ApplicationBuilderExtensions
{
public static async Task<IApplicationBuilder> PrepareDatabase(this IApplicationBuilder app)
{
using var scopedServices = app.ApplicationServices.CreateScope();
var serviceProvider = scopedServices.ServiceProvider;
var data = serviceProvider.GetRequiredService<NeonatologyDbContext>();
data.Database.Migrate();
await SeedAdministratorAsync(serviceProvider);
await SeedDoctorAsync(data, serviceProvider);
return app;
}
Here are the seedings:
private static async Task SeedDoctorAsync(NeonatologyDbContext data, IServiceProvider serviceProvider)
{
if (data.Doctors.Any())
{
return;
}
var userManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();
var roleManager = serviceProvider.GetRequiredService<RoleManager<ApplicationRole>>();
var identityRole = new ApplicationRole()
{
Name = DoctorRoleName
};
await roleManager.CreateAsync(identityRole);
var city = await data.Cities.Where(x => x.Name == "Плевен").FirstOrDefaultAsync();
var doctor = new ApplicationUser()
{
Email = DoctorEmail,
UserName = DoctorEmail,
EmailConfirmed = true,
Doctor = new Doctor
{
FirstName = DoctorFirstName,
LastName = DoctorLastName,
PhoneNumber = DoctorPhone,
Address = Address,
Age = DoctorAge,
Biography = Biography,
CityId = city.Id,
City = city,
YearsOfExperience = YearsOfExperience,
Email = DoctorEmail
}
};
await userManager.CreateAsync(doctor, DoctorPassword);
await userManager.AddToRoleAsync(doctor, identityRole.Name);
doctor.Doctor.UserId = doctor.Id;
doctor.Doctor.Image = new Image()
{
RemoteImageUrl = "SomeURL"
};
await data.SaveChangesAsync();
}
private static async Task SeedAdministratorAsync(IServiceProvider serviceProvider)
{
var userManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();
var roleManager = serviceProvider.GetRequiredService<RoleManager<ApplicationRole>>();
if (await roleManager.RoleExistsAsync(AdministratorRoleName))
{
return;
}
var identityRole = new ApplicationRole()
{
Name = AdministratorRoleName
};
await roleManager.CreateAsync(identityRole);
const string adminEmail = AdministratorEmail;
const string adminPassword = AdministratorPassword;
var adminUser = new ApplicationUser()
{
Email = adminEmail,
UserName = adminEmail,
EmailConfirmed = true
};
if (await userManager.IsInRoleAsync(adminUser, identityRole.Name))
{
return;
}
await userManager.CreateAsync(adminUser, adminPassword);
await userManager.AddToRoleAsync(adminUser, identityRole.Name);
}
And in the Program.cs I have:
app.PrepareDatabase()
.GetAwaiter()
.GetResult();
The following snippet works for me and seeds the data upon initialization of the application.
I want to make unit tests in my app. I use NUNIT, and the following libraries :
Autofac.Extras.Moq
AutoFixture
I followed this samples but it doesn't work :
http://makanda.io/unit-testing-xamarin-forms-view-model/
Mock a method of class under test with Moq & AutoMock
Here is my test :
private Fixture _fixture;
[SetUp]
public void Setup()
{
_fixture = new Fixture();
}
[Test]
public void Login_Success()
{
using (var mock = AutoMock.GetLoose())
{
var infosLogin = _fixture.Create<LoginRequest>();
var loginResponse = _fixture.Create<LoginResponse>();
var userService = mock.Mock<IUserService>();
userService
.Setup(user => user.Login(infosLogin))
.Returns(Task.FromResult(loginResponse));
var viewModel = new MainPageViewModel(new ContentPage(), userService.Object);
viewModel.Login = infosLogin.Username;
viewModel.Password = infosLogin.Password;
viewModel.LoginCommand.Execute(null);
}
}
My view
public MainPage()
{
InitializeComponent();
BindingContext = new MainPageViewModel(this, new UserServiceImpl());
}
My ViewModel
public MainPageViewModel(Page page, IUserService userService)
{
_page = page;
_userService = userService;
Login = "";
Password = "";
}
public Command LoginCommand
{
get
{
return new Command(async () =>
{
Console.WriteLine("step 1...");
if (!string.IsNullOrEmpty(Login) && !string.IsNullOrEmpty(Password))
{
Console.WriteLine("step 2...");
var infos = new LoginRequest() { Username = "Wyllis", Password = "test" };
LoginResponse response = await _userService.Login(infos);
Console.WriteLine("step 3...");
Console.WriteLine(response);
Age = response.Age; // Got error : Object reference not set to an instance of an object
}
});
}
}
LoginResponse model
public class LoginResponse
{
public string Username { get; set; }
public string Age { get; set; }
}
Age = response.Age;, I Got error : Object reference not set to an instance of an object, can you explain what is wrong ?
I found the solution, new LoginRequest(...) from my viewmodel and my tests are same BUT the hashcode (memory address) is different, so my test fail because my param is not the same object with the same memory than viewmodel
here is my new test and my view model
ViewModel
public Command LoginCommand
{
get
{
return new Command(async () =>
{
if (!string.IsNullOrEmpty(Login) && !string.IsNullOrEmpty(Password))
{
var infos = new LoginRequest() { Username = Login, Password = Password };
LoginResponse response = await _userService.Login(infos);
Age = response.Age;
}
});
}
}
Test
private Mock<IUserService> _userService;
private MainPageViewModel _viewModel;
private Fixture _fixture;
[SetUp]
public void Setup()
{
using (var mock = AutoMock.GetLoose())
{
_userService = mock.Mock<IUserService>();
}
_fixture = new Fixture();
}
private MainPageViewModel CreateInstance()
{
return new MainPageViewModel(_userService.Object);
}
[Test]
public void Test_Constructor()
{
using (var mock = AutoMock.GetLoose())
{
var viewModel = mock.Create<MainPageViewModel>();
viewModel.Login.Equals("");
viewModel.Password.Equals("");
}
}
[Test]
public void Login_Success()
{
var user = _fixture.Create<LoginResponse>();
_viewModel = CreateInstance();
_viewModel.Login = "test";
_viewModel.Password = "test";
_userService
.Setup(s => s.Login(It.IsAny<LoginRequest>()))
.Returns(Task.FromResult(user))
.Verifiable();
_viewModel.LoginCommand.Execute(null);
_userService.Verify();
Assert.AreEqual(_viewModel.Age, user.Age);
}
How I can add test cookie to request so I can test my code from Unit test. Consider a code like this:
public ActionResult Dashboard()
{
if (Request.Cookies["usercookie"] == null)
{
return RedirectToAction("Index");
}
return View();
}
I mock everything, but I don't know how I can add something to cookie so this line Request.Cookies["usercookie"] not return null. As now it is null and returning me this error:
{"Object reference not set to an instance of an object."}
This is one of my unit test methods:
[TestMethod]
[TestCategory("Unit")]
public void Login_ShouldValidateUserAndLoginSuccessfully()
{
using (var kernel = new NSubstituteMockingKernel())
{
// Setup the dependency incjection
kernel.Load(new EntityFrameworkTestingNSubstituteModule());
// Create test request data
var request = new LogInRequest { UserName = "test", Password = "test" };
var fakeResponseHandler = new FakeResponseHandler();
fakeResponseHandler.AddFakeResponse(new Uri("http://localhost/test"), new HttpResponseMessage(HttpStatusCode.OK));
ConfigurationManager.AppSettings["SearchApiBaseUrl"] = "http://test/internal";
var server = new HttpServer(new HttpConfiguration(), fakeResponseHandler);
var httpClient = new HttpClient(server);
var fakeCookieManager = new FakeCookieManager();
var authenticationService = Substitute.For<IAuthenticationService>();
var newUser = Fake.GetNewUser(1);
var newUserClaim = Fake.GetNewUserClaim(1, newUser.Id, "http://test/identity/claims/loans");
authenticationService.GetUserByEmailPasswordAsync(request.UserName, request.Password).Returns(newUser);
authenticationService.GetUserClaimByEmailAndPasswordAsync(request.UserName, request.Password).Returns(newUserClaim);
var controller = new HomeController(httpClient, fakeCookieManager, null, authenticationService);
Fake.SetFakeAuthenticatedControllerContext(controller);
controller.HttpContext.Session["ReturnUrl"] = "/search";
var result = controller.Login(request);
Assert.IsNotNull(result);
}
}
This is a class in Fake for Httpcontext:
public static HttpContextBase InitialiseFakeHttpContext(string url = "")
{
var HttpContextSub = Substitute.For<HttpContextBase>();
var RequestSub = Substitute.For<HttpRequestBase>();
var ResponseSub = Substitute.For<HttpResponseBase>();
var serverUtilitySub = Substitute.For<HttpServerUtilityBase>();
var itemsSub = Substitute.For<IDictionary>();
HttpContextSub.Request.Returns(RequestSub);
HttpContextSub.Response.Returns(ResponseSub);
HttpContextSub.Server.Returns(serverUtilitySub);
var cookie = Substitute.For<HttpResponseBase>();
HttpContextSub.Response.Returns(cookie);
return HttpContextSub;
}
Here is an example unit test where a cookie is set on the request.
Used NSubstitute framework to mock the http context and then setup the request cookies property. Applied the mocked http context to the controller context to simulate a request.
[TestClass]
public class MyControllerTests {
[TestMethod]
public void Request_Cookies_Should_Not_Be_Null() {
//Arrange
var cookies = new HttpCookieCollection();
cookies.Add(new HttpCookie("usercookie"));
var mockHttpContext = Substitute.For<HttpContextBase>();
mockHttpContext.Request.Cookies.Returns(cookies);
var sut = new MyController();
sut.ControllerContext = new ControllerContext {
Controller = sut,
HttpContext = mockHttpContext
};
//Act
var result = sut.Dashboard() as ViewResult;
//Assert
Assert.IsNotNull(result);
}
public class MyController : Controller {
public ActionResult Dashboard() {
if (Request.Cookies["usercookie"] == null) {
return RedirectToAction("Index");
}
return View();
}
}
}
Update:
Here is an updated version of the test using a manually created mocked HttpContext.
[TestClass]
public class MyControllerTests {
[TestMethod]
public void Request_Cookies_Should_Not_Be_Null() {
//Arrange
var cookies = new HttpCookieCollection();
cookies.Add(new HttpCookie("usercookie"));
var mockHttpContext = new MockHttpContext(cookies);
var sut = new MyController();
sut.ControllerContext = new ControllerContext {
Controller = sut,
HttpContext = mockHttpContext
};
//Act
var result = sut.Dashboard() as ViewResult;
//Assert
Assert.IsNotNull(result);
}
public class MyController : Controller {
public ActionResult Dashboard() {
if (Request.Cookies["usercookie"] == null) {
return RedirectToAction("Index");
}
return View();
}
}
private class MockHttpContext : HttpContextBase {
private readonly MockRequest request;
public MockHttpContext(HttpCookieCollection cookies) {
this.request = new MockRequest(cookies);
}
public override HttpRequestBase Request {
get {
return request;
}
}
public class MockRequest : HttpRequestBase {
private readonly HttpCookieCollection cookies;
public MockRequest(HttpCookieCollection cookies) {
this.cookies = cookies;
}
public override HttpCookieCollection Cookies {
get {
return cookies;
}
}
}
}
}
This is the same thing using MOQ framework
MockContext class used to mock the HTTP context
public class MockContext
{
public Mock<RequestContext> RoutingRequestContext { get; private set; }
public Mock<HttpContextBase> Http { get; private set; }
public Mock<HttpServerUtilityBase> Server { get; private set; }
public Mock<HttpResponseBase> Response { get; private set; }
public Mock<HttpRequestBase> Request { get; private set; }
public Mock<HttpSessionStateBase> Session { get; private set; }
public Mock<ActionExecutingContext> ActionExecuting { get; private set; }
public HttpCookieCollection Cookies { get; private set; }
public MockContext()
{
this.RoutingRequestContext = new Mock<RequestContext>(MockBehavior.Loose);
this.ActionExecuting = new Mock<ActionExecutingContext>(MockBehavior.Loose);
this.Http = new Mock<HttpContextBase>(MockBehavior.Loose);
this.Server = new Mock<HttpServerUtilityBase>(MockBehavior.Loose);
this.Response = new Mock<HttpResponseBase>(MockBehavior.Loose);
this.Request = new Mock<HttpRequestBase>(MockBehavior.Loose);
this.Session = new Mock<HttpSessionStateBase>(MockBehavior.Loose);
this.Cookies = new HttpCookieCollection();
this.RoutingRequestContext.SetupGet (c => c.HttpContext).Returns(this.Http.Object);
this.ActionExecuting.SetupGet (c => c.HttpContext).Returns(this.Http.Object);
this.Http.SetupGet (c => c.Request).Returns(this.Request.Object);
this.Http.SetupGet (c => c.Response).Returns(this.Response.Object);
this.Http.SetupGet (c => c.Server).Returns(this.Server.Object);
this.Http.SetupGet (c => c.Session).Returns(this.Session.Object);
this.Request.Setup (c => c.Cookies).Returns(Cookies);
}
}
and this is the test case
public void IndexTest()
{
// arrange
MockContext mockContext = new MockContext();
#region creating cookie
HttpCookie cookie = new HttpCookie(Constant.COOKIE_ADMIN_USER_INFO,
Config.DefaultCountryID.ToString());
cookie.Values.Add(Constant.COOKIE_ADMIN_VALUE_COUNTRY_ID,
Config.DefaultCountryID.ToString());
cookie.Values.Add(Constant.COOKIE_ADMIN_VALUE_LANGUAGE_ID,
Config.DefaultLanguageID.ToString());
mockContext.Cookies.Add(cookie);
#endregion
#region Creating controller
ControllerContext controllerContex = new ControllerContext()
{
HttpContext = mockContext.Http.Object
};
HomeController controller = new HomeController()
{
ControllerContext = controllerContex
};
#endregion
// act
var output = (ViewResult)controller.Index();
var result = output.ViewData;
// assert
result.ShouldNotBeNull();
}
How do you seed users, roles and app specific entities? It appears as though the IdentityModel targets its own Context?
internal sealed class Configuration : DbMigrationsConfiguration<Project.Models.SchoolContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
protected override void Seed(Project.Models.SchoolContext context)
{
// Seed the Entities
// context.People.AddOrUpdate(
// p => p.FullName,
// new Person { FullName = "Andrew Peters" }
// );
//
}
}
vs.
protected override void Seed(Project.Models.ApplicationDbContext context)
{
if (!context.Roles.Any(r => r.Name == "AppAdmin"))
{
var store = new RoleStore<IdentityRole>(context);
var manager = new RoleManager<IdentityRole>(store);
var role = new IdentityRole { Name = "AppAdmin" };
manager.Create(role);
}
if (!context.Users.Any(u => u.UserName == "founder"))
{
var store = new UserStore<ApplicationUser>(context);
var manager = new UserManager<ApplicationUser>(store);
var user = new ApplicationUser {UserName = "founder"};
manager.Create(user, "ChangeItAsap!");
manager.AddToRole(user.Id, "AppAdmin");
}
}
I don't seed from the migration, instead use the context db initializer. My context derives from IdentityDbContext so I use this method to seed users and roles:
Call an initializer from ctor:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
private readonly IHttpContextBaseWrapper _httpContextBaseWrapper;
static ApplicationDbContext()
{
// Set the database intializer which is run once during application start
// This seeds the database with admin user credentials and admin role
Database.SetInitializer(new ApplicationDbInitializer());
}
...
Then my seed code:
public class ApplicationDbInitializer : CreateDatabaseIfNotExists<ApplicationDbContext>
{
protected override void Seed(ApplicationDbContext context)
{
InitializeIdentityForEF(context);
base.Seed(context);
}
public static void InitializeIdentityForEF(ApplicationDbContext db)
{
if (!db.Users.Any())
{
var roleStore = new RoleStore<IdentityRole>(db);
var roleManager = new RoleManager<IdentityRole>(roleStore);
var userStore = new UserStore<ApplicationUser>(db);
var userManager = new UserManager<ApplicationUser>(userStore);
// Add missing roles
var role = roleManager.FindByName("Admin");
if (role == null)
{
role = new IdentityRole("Admin");
roleManager.Create(role);
}
// Create test users
var user = userManager.FindByName("admin");
if (user == null)
{
var newUser = new ApplicationUser()
{
UserName = "admin",
FirstName = "Admin",
LastName = "User",
Email = "xxx#xxx.net",
PhoneNumber = "5551234567",
MustChangePassword = false
};
userManager.Create(newUser, "Password1");
userManager.SetLockoutEnabled(newUser.Id, false);
userManager.AddToRole(newUser.Id, "Admin");
}
...
have this (model builder) code on our DbContext.cs
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<IdentityUserLogin>().HasKey<string>(l => l.UserId);
modelBuilder.Entity<IdentityRole>().HasKey<string>(r => r.Id);
modelBuilder.Entity<IdentityUserRole>().HasKey(r => new { r.RoleId, r.UserId });
modelBuilder.Entity<ApplicationUser>().ToTable("ApplicationUser");
Everything works fine except for Authorization/User Roles.
After checking all tables I noticed that IdentityUserRoles table creates 4 columns: RoleId, UserId, IdentityRole_Id and ApplicationUser_Id.
I found out that, IdentityRole_Id and ApplicationUser_Id [Foreign Keys] are mapped or used instead of the RoleId and UserId [Primary Keys]. Unfortunately, identity (Id's) data were inserted in RoleId/UserId column and IdenityRole_Id/ApplicationUser_Id are NULL by default.
Please help.
My Code:
public class RqDbContext : DbContext
{
private const string ConnectionString = "RqDbContext";
public RqDbContext() : base(ConnectionString)
{
}
public static RqDbContext Create()
{
return new RqDbContext();
}
// ----------------------------------------------------------------------
// Data Tables
// ----------------------------------------------------------------------
public DbSet<Quote> Quotes { get; set; }
public DbSet<Booking> Bookings { get; set; }
public DbSet<CompanyAccount> CompanyAccounts { get; set; }
// ----------------------------------------------------------------------
// Security
// ----------------------------------------------------------------------
public DbSet<ApplicationUserExtend> ApplicationUserExtends { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<IdentityUserLogin>().HasKey<string>(l => l.UserId);
modelBuilder.Entity<IdentityRole>().HasKey<string>(r => r.Id);
modelBuilder.Entity<IdentityUserRole>().HasKey(r => new { r.RoleId, r.UserId });
modelBuilder.Entity<ApplicationUser>().ToTable("ApplicationUser");
}
}
public partial class ApplicationUser : IdentityUser
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
//custom+
public virtual ApplicationUserExtend Extend { get; set; }
}
public class ApplicationUserExtend
{
public ApplicationUserExtend()
{
}
[Key]
[Display(Name="Id")]
[XmlAttribute]
public int Id { get; set; }
[Display(Name="Account Id")]
[XmlAttribute]
public int AccountId { get; set; }
[Display(Name="Active Account Id")]
[XmlAttribute]
public int ActiveAccountId { get; set; }
}
public class RqInitializer : System.Data.Entity.DropCreateDatabaseAlways<RqDbContext>
{
protected override void Seed(RqDbContext context)
{
var testData = ReadTestData();
AddIdentityRoles(context, testData);
AddUsers(context, testData);
MvcUtil.SaveChanges(context);
}
private void AddUsers(RqDbContext context, TestDataDo testData)
{
var userStore = new UserStore<ApplicationUser>(context);
var userManager = new UserManager<ApplicationUser>(userStore);
//Roles.Enabled("user","member");
var userIndex = 0;
foreach (var applicationUser in testData.ApplicationUsers)
{
var user = new ApplicationUser
{
UserName = applicationUser.UserName,
Email = applicationUser.Email,
PhoneNumber = applicationUser.PhoneNumber
};
if (userIndex > testData.ApplicationUserExtends.Count)
{
throw new Exception("Make sure you the number of rows in ApplicationUserExtends, matches the number of rows in Users");
}
user.Extend = new ApplicationUserExtend
{
AccountId = testData.ApplicationUserExtends[userIndex++].AccountId
};
userManager.Create(user, applicationUser.Password);
//set User Role
userManager.AddToRole(user.Id, applicationUser.Role);
//context.Users.Add(user);
}
context.SaveChanges();
}
private void AddIdentityRoles(RqDbContext context, TestDataDo testData)
{
var roleStore = new RoleStore<IdentityRole>(context);
var roleManager = new RoleManager<IdentityRole>(roleStore);
foreach (var role in testData.IdentityRoles)
{
var identity = new IdentityRole(role.Name);
roleManager.Create(identity);
}
context.SaveChanges();
}
public static TestDataDo ReadTestData()
{
var xml = GetResource("Rq.Web.App_Specification.Rq-TestData.xml");
return XmlUtil.SerializeFromString<TestDataDo>(xml);
}
private static string GetResource(string file)
{
var assembly = Assembly.GetExecutingAssembly();
return ResourceUtil.GetAsString(assembly, file);
}
}
// Configure the application user manager used in this application. UserManager is defined in ASP.NET Identity and is used by the application.
public class ApplicationUserManager : UserManager<ApplicationUser>
{
public ApplicationUserManager(IUserStore<ApplicationUser> store)
: base(store)
{
}
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<RqDbContext>()));
// Configure validation logic for usernames
manager.UserValidator = new UserValidator<ApplicationUser>(manager)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
// Configure validation logic for passwords
manager.PasswordValidator = new PasswordValidator
{
RequiredLength = 6,
RequireNonLetterOrDigit = true,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true,
};
// Configure user lockout defaults
manager.UserLockoutEnabledByDefault = true;
manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
manager.MaxFailedAccessAttemptsBeforeLockout = 5;
// Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user
// You can write your own provider and plug it in here.
manager.RegisterTwoFactorProvider("Phone Code", new PhoneNumberTokenProvider<ApplicationUser>
{
MessageFormat = "Your security code is {0}"
});
manager.RegisterTwoFactorProvider("Email Code", new EmailTokenProvider<ApplicationUser>
{
Subject = "Security Code",
BodyFormat = "Your security code is {0}"
});
manager.EmailService = new EmailService();
manager.SmsService = new SmsService();
var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)
{
manager.UserTokenProvider =
new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
}
return manager;
}
}
// Configure the application sign-in manager which is used in this application.
public class ApplicationSignInManager : SignInManager<ApplicationUser, string>
{
public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager)
: base(userManager, authenticationManager)
{
}
public override Task<ClaimsIdentity> CreateUserIdentityAsync(ApplicationUser user)
{
return user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager);
}
public static ApplicationSignInManager Create(IdentityFactoryOptions<ApplicationSignInManager> options, IOwinContext context)
{
return new ApplicationSignInManager(context.GetUserManager<ApplicationUserManager>(), context.Authentication);
}
}
The code below will fix IdentityUserRoles table Foreign Keys issue.
var user = modelBuilder.Entity<TUser>()
.ToTable("AspNetUsers");
user.HasMany(u => u.Roles).WithRequired().HasForeignKey(ur => ur.UserId);
user.HasMany(u => u.Claims).WithRequired().HasForeignKey(uc => uc.UserId);
user.HasMany(u => u.Logins).WithRequired().HasForeignKey(ul => ul.UserId);
user.Property(u => u.UserName).IsRequired();
modelBuilder.Entity<TUserRole>()
.HasKey(r => new { r.UserId, r.RoleId })
.ToTable("AspNetUserRoles");
modelBuilder.Entity<TUserLogin>()
.HasKey(l => new { l.UserId, l.LoginProvider, l.ProviderKey})
.ToTable("AspNetUserLogins");
modelBuilder.Entity<TUserClaim>()
.ToTable("AspNetUserClaims");
var role = modelBuilder.Entity<TRole>()
.ToTable("AspNetRoles");
role.Property(r => r.Name).IsRequired();
role.HasMany(r => r.Users).WithRequired().HasForeignKey(ur => ur.RoleId);
I found my answer here. Create ASP.NET Identity tables using SQL script!