I want to make a test that access my page that need Admin role to access it. This is my page: (Model)
[Authorize(Roles = "Admin")]
public class AddModel : PageModel
{
private readonly ILinkRepository _linkRepository;
[BindProperty]
public AddLink AddLinkRequest { get; set; }
public AddModel(ILinkRepository linkRepository)
{
_linkRepository = linkRepository;
}
public void OnGet()
{
ViewData["Title"] = "Ajouter un lien";
}
public async Task<IActionResult> OnPost()
{
...
return RedirectToPage("/Admin/Links/List");
}
}
The view is this:
@page
@model as_quebec.Pages.Admin.Links.AddModel
@{
}
<div class="bg-secondary bg-opacity-10 py-2 mb-5">
<div class="container">
<h1 id="title">Ajouter un lien</h1>
</div>
</div>
<div>
...
</div>
So here is my test that doesn't pass (I get 302 Redirect to my Login page (it is like the user isn't connected) instead of 200):
public class AddTest
{
private ILinkRepository _linkRepository;
private ITempDataDictionary _temp;
private WebApplicationFactory<Program> _factory;
[OneTimeSetUp]
public async Task SetUp()
{
_linkRepository = Substitute.For<ILinkRepository>();
_temp = Substitute.For<ITempDataDictionary>();
_factory = new WebApplicationFactory<Program>();
}
[Test]
public async Task GivenPage_WhenDisplayingPage_ThenElementsAreDisplaying()
{
// Arrange
var client = _factory.WithWebHostBuilder(builder =>
{
builder.ConfigureTestServices(services =>
{
services.AddAuthentication(defaultScheme: "TestScheme")
.AddScheme<AuthenticationSchemeOptions, TestAuthHandler>(
"TestScheme", options => { });
});
})
.CreateClient(new WebApplicationFactoryClientOptions
{
AllowAutoRedirect = false,
});
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue(scheme: "TestScheme");
//Act
var response = await client.GetAsync("/admin/links/add");
// Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
}
}
Here is the TestAuthHandler.cs:
public class TestAuthHandler : AuthenticationHandler<AuthenticationSchemeOptions>
{
public TestAuthHandler(IOptionsMonitor<AuthenticationSchemeOptions> options,
ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock)
: base(options, logger, encoder, clock)
{
}
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
{
var claims = new[] {
new Claim(ClaimTypes.Name, "Test user"),
new Claim(ClaimTypes.Role, "Admin")
};
var identity = new ClaimsIdentity(claims, "Test");
var principal = new ClaimsPrincipal(identity);
var ticket = new AuthenticationTicket(principal, "TestScheme");
var result = AuthenticateResult.Success(ticket);
return Task.FromResult(result);
}
}
Here is my Program.cs:
var builder = WebApplication.CreateBuilder(args);
// Load environment variable
DotNetEnv.Env.Load();
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddControllers();
builder.Services.AddDbContext<ASQuebecDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("ASQuebecDbConnectionString"))
);
builder.Services.AddDbContext<AuthDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("AuthenticationDbConnectionString"))
);
builder.Services.AddIdentity<IdentityUser, IdentityRole>()
.AddEntityFrameworkStores<AuthDbContext>();
builder.Services.Configure<IdentityOptions>(options =>
{
// Default setting password
options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
options.Password.RequireNonAlphanumeric = true;
options.Password.RequireUppercase = true;
options.Password.RequiredLength = 6;
options.Password.RequiredUniqueChars = 1;
});
builder.Services.ConfigureApplicationCookie(
options =>
{
options.LoginPath = "/Login";
options.AccessDeniedPath = "/AccessDenied";
}
);
builder.Services.AddScoped<ITextPostRepository, TextPostRepository>();
builder.Services.AddScoped<ILinkRepository, LinkRepository>();
builder.Services.AddScoped<IImageRepository, ImageRepositoryCloudinary>();
builder.Services.AddScoped<ITagRepository, TagRepository>();
builder.Services.AddScoped<ITagManagementRepository, TagManagementRepository>();
builder.Services.AddScoped<ITextPostLikeRepository, TextPostLikeRepository>();
builder.Services.AddScoped<ITextPostCommentRepository, TextPostCommentRepository>();
builder.Services.AddScoped<IUserRepository, UserRepository>();
builder.Services.AddScoped<IEmailManager, EmailManager>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.MapControllers();
app.Run();
public partial class Program { }
// </snippet_all>
I'm using AngleSharp and NUnit v. 3.13.3, so what should I do for accessing the page /admin/links/add in order to test the rendering and etc...