### Bootstrap AlbaHost with WebApplicationFactory Source: https://github.com/jasperfx/alba/blob/master/docs/guide/gettingstarted.md This example demonstrates how to initialize AlbaHost using `AlbaHost.For`, which leverages `WebApplicationFactory`. It allows for custom service configuration during testing. ```csharp await using var host = await AlbaHost.For(x => { x.ConfigureServices((context, services) => { services.AddSingleton(); }); }); ``` -------------------------------- ### NUnit Application Setup with AlbaHost Source: https://github.com/jasperfx/alba/blob/master/docs/guide/nunit.md Initialize and dispose of AlbaHost once for NUnit test fixtures. This setup ensures the host is created before any tests run and cleaned up afterwards. ```csharp [SetUpFixture] public class Application { [OneTimeSetUp] public async Task Init() { Host = await AlbaHost.For(); } public static IAlbaHost Host { get; private set; } // Make sure that NUnit will shut down the AlbaHost when // all the projects are finished [OneTimeTearDown] public void Teardown() { Host.Dispose(); } } ``` -------------------------------- ### Bootstrap AlbaHost with a Stub Extension Source: https://github.com/jasperfx/alba/blob/master/docs/guide/extensions.md Initialize an AlbaHost by passing an array of extensions. This example demonstrates using an `AuthenticationStub` extension to stub out authentication with specific claims and a name. ```csharp // This is a Alba extension that can "stub" out authentication var securityStub = new AuthenticationStub() .With("foo", "bar") .With(JwtRegisteredClaimNames.Email, "guy@company.com") .WithName("jeremy"); // We're calling your real web service's configuration theHost = await AlbaHost.For(securityStub); ``` -------------------------------- ### Run a Basic Scenario Source: https://github.com/jasperfx/alba/blob/master/docs/guide/gettingstarted.md Execute a simple GET request and assert the response content and status code. Alba manages the host lifetime automatically. ```cs await using var host = await AlbaHost.For(); // This runs an HTTP request and makes an assertion // about the expected content of the response await host.Scenario(_ => { _.Get.Url("/"); _.ContentShouldBe("Hello World!"); _.StatusCodeShouldBeOk(); }); ``` -------------------------------- ### Define an Alba Extension Interface Source: https://github.com/jasperfx/alba/blob/master/docs/guide/extensions.md Models an extension to an AlbaHost. Implement `IDisposable` and `IAsyncDisposable`. The `Start` method is called after the application is started, providing access to the DI container. The `Configure` method allows altering the `IHostBuilder` before the application starts. ```csharp /// /// Models an extension to an AlbaHost /// public interface IAlbaExtension : IDisposable, IAsyncDisposable { /// /// Called during the initialization of an AlbaHost after the application is started, /// so the application DI container is available. Useful for registering setup or teardown /// actions on an AlbaHOst /// /// /// Task Start(IAlbaHost host); /// /// Allow an extension to alter the application's /// IHostBuilder prior to starting the application /// /// /// IHostBuilder Configure(IHostBuilder builder); } ``` -------------------------------- ### Specify URL Directly for HTTP Methods Source: https://github.com/jasperfx/alba/blob/master/docs/scenarios/urls.md Use this method to directly specify the URL for GET, PUT, POST, DELETE, and HEAD requests within an Alba scenario. No special setup is required beyond the standard AlbaHost. ```cs public async Task specify_url(AlbaHost system) { await system.Scenario(_ => { // Directly specify the Url against a given // HTTP method _.Get.Url("/"); _.Put.Url("/"); _.Post.Url("/"); _.Delete.Url("/"); _.Head.Url("/"); }); } ``` -------------------------------- ### TUnit Alba Test Class with Scenario Source: https://github.com/jasperfx/alba/blob/master/docs/guide/tunit.md Inherit from a base class that provides access to the `IAlbaHost` and use `ClassDataSource` to share the `AlbaBootstrap` instance across tests. This example demonstrates a basic scenario test. ```csharp public abstract class AlbaTestBase(AlbaBootstrap albaBootstrap) { protected IAlbaHost Host => albaBootstrap.Host; } [ClassDataSource(Shared = SharedType.PerTestSession)] public class MyTestClass(AlbaBootstrap albaBootstrap) : AlbaTestBase(albaBootstrap) { [Test] public async Task happy_path() { await Host.Scenario(_ => { _.Get.Url("/fake/okay"); _.StatusCodeShouldBeOk(); }); } } ``` -------------------------------- ### Minimal Web API Example Source: https://github.com/jasperfx/alba/blob/master/docs/guide/gettingstarted.md This snippet shows a basic ASP.NET Core application using the Minimal API approach. It defines endpoints for a simple greeting, error throwing, JSON handling, and argument retrieval. ```csharp var builder = WebApplication.CreateBuilder(args); // Add services to the container. var app = builder.Build(); // Configure the HTTP request pipeline. app.UseHttpsRedirection(); app.MapGet("", () => "Hello World!"); app.MapGet("/blowup", context => throw new Exception("Boo!")); app.MapPost("/json", (MyEntity entity) => entity); app.MapGet("/args", () => Results.Ok(args)); app.Run(); public record MyEntity(Guid Id, string MyValue); ``` -------------------------------- ### Implement Integration Test Fixture Source: https://github.com/jasperfx/alba/blob/master/docs/guide/xunit.md This concrete test fixture inherits from ScenarioContext and demonstrates a basic integration test using the injected IAlbaHost. It performs a GET request and asserts a 200 OK status code. ```csharp public class sample_integration_fixture : ScenarioContext { public sample_integration_fixture(WebAppFixture fixture) : base(fixture) { } [Fact] public Task happy_path() { return Host.Scenario(_ => { _.Get.Url("/fake/okay"); _.StatusCodeShouldBeOk(); }); } } ``` -------------------------------- ### Define xUnit Collection Fixture Source: https://github.com/jasperfx/alba/blob/master/docs/guide/xunit.md This class defines a collection fixture named 'scenarios' and specifies that it uses WebAppFixture for setup. This is a marker class to group tests that share the same fixture. ```csharp [CollectionDefinition("scenarios")] public class ScenarioCollection : ICollectionFixture { } ``` -------------------------------- ### Create Base Class for Scenario Tests Source: https://github.com/jasperfx/alba/blob/master/docs/guide/xunit.md This abstract base class provides a common setup for test fixtures that utilize the 'scenarios' collection. It injects the IAlbaHost from the WebAppFixture into derived classes. ```csharp [Collection("scenarios")] public abstract class ScenarioContext { protected ScenarioContext(WebAppFixture fixture) { Host = fixture.AlbaHost; } public IAlbaHost Host { get; } } ``` -------------------------------- ### Test GET request with Alba Source: https://github.com/jasperfx/alba/blob/master/docs/scenarios/writingscenarios.md Tests a GET endpoint by issuing a request to the '/math/add/{one}/{two}' URL and verifying the 'Answer' property of the JSON response. ```cs [Fact] public async Task get_happy_path() { await using var system = await AlbaHost.For(); // Issue a request, and check the results var result = await system.GetAsJson("/math/add/3/4"); result.Answer.ShouldBe(7); } ``` -------------------------------- ### Shorthand for Reading JSON Response Source: https://github.com/jasperfx/alba/blob/master/docs/scenarios/json.md Use the `host.GetAsJson()` shorthand for a more concise way to make a GET request and deserialize the JSON response directly into a specified type. ```cs public async Task read_json_shorthand(IAlbaHost host) { var output = await host.GetAsJson("/output"); // do assertions against the Output model } ``` -------------------------------- ### Use Custom Assertion in a Scenario Source: https://github.com/jasperfx/alba/blob/master/docs/scenarios/assertions.md Demonstrates how to use the ContentShouldContain extension method within a scenario to verify the response body content. This example sets up a handler and then asserts the expected text. ```csharp [Fact] public Task using_scenario_with_ContentShouldContain_declaration_happy_path() { router.Handlers["/one"] = c => { c.Response.Write("**just the marker**"); return Task.CompletedTask; }; return host.Scenario(x => { x.Get.Url("/one"); x.ContentShouldContain("just the marker"); }); } ``` -------------------------------- ### Read Response Body as Text Source: https://github.com/jasperfx/alba/blob/master/docs/scenarios/text.md Use ReadAsTextAsync() to get the response body as a string. This is useful for asserting against the raw text content of a response. ```csharp public async Task read_text(IAlbaHost host) { var result = await host.Scenario(_ => { _.Get.Url("/output"); }); // This deserializes the response body to the // designated Output type var outputString = await result.ReadAsTextAsync(); // do assertions against the Output string } ``` -------------------------------- ### Setup Alba Host with JwtSecurityStub Source: https://github.com/jasperfx/alba/blob/master/docs/guide/security.md Use JwtSecurityStub to automatically add a valid JWT token string to the Authorization header. This stubs out JWT bearer token authentication and disables calls to validate tokens with a real Open Id Connect server. ```cs var jwtSecurityStub = new JwtSecurityStub() .With("foo", "bar") .With(JwtRegisteredClaimNames.Email, "guy@company.com"); // We're calling your real web service's configuration theHost = await AlbaHost.For(jwtSecurityStub); ``` -------------------------------- ### Implement a Body Contains Assertion Source: https://github.com/jasperfx/alba/blob/master/docs/scenarios/assertions.md An example implementation of IScenarioAssertion that checks if the response body contains specific text. It reads the body and adds a failure message if the text is not found. ```csharp internal sealed class BodyContainsAssertion : IScenarioAssertion { public string Text { get; set; } public BodyContainsAssertion(string text) { Text = text; } public void Assert(Scenario scenario, AssertionContext context) { // Context has this useful extension to read the body as a string. // This will bake the body contents into the exception message to make debugging easier. var body = context.ReadBodyAsString(); if (!body.Contains(Text)) { // Add the failure message to the exception. This exception only // gets thrown if there are failures. context.AddFailure($"Expected text '{Text}' was not found in the response body"); } } } ``` -------------------------------- ### Fluent Interface Bootstrapping with StartAlbaAsync Source: https://github.com/jasperfx/alba/blob/master/docs/guide/bootstrapping.md Use Alba's extension method StartAlbaAsync on IHostBuilder for a fluent interface style to bootstrap an AlbaHost. Asynchronous methods are recommended when applicable. ```csharp await using var host = await Program .CreateHostBuilder(Array.Empty()) .StartAlbaAsync(); /* Just as a sample, I'll run a scenario against a "hello, world" application's root url */ await host.Scenario(s => { s.Get.Url("/"); s.ContentShouldBe("Hello, World!"); }); ``` -------------------------------- ### Perform Snapshot Test with Alba and Verify Source: https://github.com/jasperfx/alba/blob/master/docs/guide/snapshot.md This snippet demonstrates how to use Alba to set up a host, define a scenario with a POST request, and then pass the scenario to Verify for snapshotting. Ensure Verify and Verify.AspNetCore are initialized in your test project. ```csharp await using var host = await AlbaHost.For(); var scenario = await host.Scenario(s => { s.Post.Json(new MyEntity(Guid.NewGuid(), "SomeValue")).ToUrl("/json"); }); await Verify(scenario); ``` -------------------------------- ### TUnit Alba Bootstrap Class Source: https://github.com/jasperfx/alba/blob/master/docs/guide/tunit.md Implement `IAsyncInitializer` and `IAsyncDisposable` to manage the `IAlbaHost` lifecycle. This class is responsible for creating and disposing of the Alba host. ```csharp public sealed class AlbaBootstrap : IAsyncInitializer, IAsyncDisposable { public IAlbaHost Host { get; private set; } = null!; public async Task InitializeAsync() { Host = await AlbaHost.For(); } public async ValueTask DisposeAsync() { await Host.DisposeAsync(); } } ``` -------------------------------- ### Basic xUnit Test with Alba Source: https://github.com/jasperfx/alba/blob/master/docs/guide/xunit.md Use this for simple tests where application startup is fast. Ensure your test method is async Task and dispose of the AlbaHost. ```cs [Fact] public async Task should_say_hello_world() { // Alba will automatically manage the lifetime of the underlying host await using var host = await AlbaHost.For(); // This runs an HTTP request and makes an assertion // about the expected content of the response await host.Scenario(_ => { _.Get.Url("/"); _.ContentShouldBe("Hello World!"); _.StatusCodeShouldBeOk(); }); } ``` -------------------------------- ### Bootstrap AlbaHost with IHostBuilder Directly Source: https://github.com/jasperfx/alba/blob/master/docs/guide/bootstrapping.md Initialize an AlbaHost by directly using the definition of your IHostBuilder. This is useful for bootstrapping ASP.NET Core Startup.cs-style applications. ```csharp /* Bootstrap your application just as your real application does */ var hostBuilder = Program.CreateHostBuilder(Array.Empty()); await using var host = new AlbaHost(hostBuilder); /* Just as a sample, I'll run a scenario against a "hello, world" application's root url */ await host.Scenario(s => { s.Get.Url("/"); s.ContentShouldBe("Hello, World!"); }); ``` -------------------------------- ### Run Scenario and Assert Response Entity Source: https://github.com/jasperfx/alba/blob/master/docs/guide/gettingstarted.md Execute a POST request with JSON data, assert the status code, and then read and assert properties from the JSON response. ```cs await using var host = await AlbaHost.For(); var guid = Guid.NewGuid(); var res = await host.Scenario(_ => { _.Post.Json(new MyEntity(guid, "SomeValue")).ToUrl("/json"); _.StatusCodeShouldBeOk(); }); var json = await res.ReadAsJsonAsync(); Assert.Equal(guid, json.Id); ``` -------------------------------- ### Check HTTP Status Codes in Alba Scenarios Source: https://github.com/jasperfx/alba/blob/master/docs/scenarios/statuscode.md Demonstrates how to assert specific status codes, the default OK status, or ignore status code checks within an Alba scenario. ```cs public async Task check_the_status(IAlbaHost system) { await system.Scenario(_ => { // Shorthand for saying that the StatusCode should be 200 _.StatusCodeShouldBeOk(); // Or a specific status code _.StatusCodeShouldBe(403); // Ignore the status code altogether _.IgnoreStatusCode(); }); } ``` -------------------------------- ### Configure Test Host with Overrides Source: https://github.com/jasperfx/alba/blob/master/docs/guide/gettingstarted.md Customize the `AlbaHost` by overriding the hosting environment, configuring services, and registering test-specific implementations like mocked services. ```cs var stubbedWebService = new StubbedWebService(); await using var host = await AlbaHost.For(x => { // override the environment if you need to x.UseEnvironment("Testing"); // override service registrations or internal options if you need to x.ConfigureServices(s => { s.AddSingleton(stubbedWebService); s.PostConfigure(o => o.SerializerSettings.TypeNameHandling = TypeNameHandling.All); }); }); host.BeforeEach(httpContext => { // do some data setup or clean up before every single test }) .AfterEach(httpContext => { // do any kind of cleanup after each scenario completes }); ``` -------------------------------- ### xUnit Class Fixture for AlbaHost Source: https://github.com/jasperfx/alba/blob/master/docs/guide/xunit.md Implement IAsyncLifetime to manage the AlbaHost lifecycle for sharing across tests. Configure application services within the builder lambda. ```cs public class WebAppFixture : IAsyncLifetime { public IAlbaHost AlbaHost = null!; public async ValueTask InitializeAsync() { AlbaHost = await Alba.AlbaHost.For(builder => { // Configure all the things }); } public async ValueTask DisposeAsync() { await AlbaHost.DisposeAsync(); } } ``` -------------------------------- ### Synchronous and Asynchronous Before/After Actions Source: https://github.com/jasperfx/alba/blob/master/docs/scenarios/setup.md Use BeforeEach and AfterEach for synchronous operations, and BeforeEachAsync and AfterEachAsync for asynchronous operations. These actions modify the HttpContext before or after each scenario/HTTP request. ```cs // Synchronously system.BeforeEach(context => { // Modify the HttpContext immediately before each // Scenario()/HTTP request is executed context.Request.Headers.Append("trace", "something"); }); system.AfterEach(context => { // perform an action immediately after the scenario/HTTP request // is executed }); // Asynchronously system.BeforeEachAsync(context => { // do something asynchronous here return Task.CompletedTask; }); system.AfterEachAsync(context => { // do something asynchronous here return Task.CompletedTask; }); ``` -------------------------------- ### Configure OIDC Client Credentials Flow Source: https://github.com/jasperfx/alba/blob/master/docs/guide/security.md Use this extension for OIDC Client Credentials workflow. Ensure ClientId, ClientSecret, and Scope are configured in your OIDC server. ```csharp oidc = new OpenConnectClientCredentials { // These three properties are mandatory, // and // would refer to matching configuration in your // OIDC server ClientId = Config.ClientId, ClientSecret = Config.ClientSecret, Scope = Config.ApiScope }; theHost = await AlbaHost.For(x => { x.ConfigureServices((ctx, collection) => collection.Configure(JwtBearerDefaults.AuthenticationScheme, options => { options.Authority = _fixture.IdentityServer.BaseAddress.ToString(); options.BackchannelHttpHandler = _fixture.IdentityServer.CreateHandler(); options.RequireHttpsMetadata = false; })); }, oidc); ``` -------------------------------- ### Using xUnit Class Fixture with AlbaHost Source: https://github.com/jasperfx/alba/blob/master/docs/guide/xunit.md Reference the shared AlbaHost from your xUnit test class by implementing IClassFixture and injecting the fixture in the constructor. ```cs public class ContractTestWithAlba : IClassFixture { public ContractTestWithAlba(WebAppFixture app) { _host = app.AlbaHost; } private readonly IAlbaHost _host; } ``` -------------------------------- ### Using Content Negotiation Helpers in Alba Source: https://github.com/jasperfx/alba/blob/master/docs/scenarios/headers.md Alba offers specific helpers for common content negotiation headers like `Accepts`, `Etag`, and `ContentType`. These simplify setting standard headers for requests. ```cs await system.Scenario(_ => { // Set the accepts header on the request _.Get.Url("/").Accepts("text/plain"); // Specify the etag header value _.Get.Url("/").Etag("12345"); // Set the content-type header on the request _.Post.Url("/").ContentType("text/json"); // This is a superset of the code above that // will set the content-type header as well _.Post.Json(new InputModel()).ToUrl("/"); }); ``` -------------------------------- ### Bootstrap Alba Host with AuthenticationStub Source: https://github.com/jasperfx/alba/blob/master/docs/guide/security.md Use AuthenticationStub to automatically authenticate every request and build a ClaimsPrincipal. This is useful for stubbing out all possible authentication in ASP.NET Core. ```cs var securityStub = new AuthenticationStub() .With("foo", "bar") .With(JwtRegisteredClaimNames.Email, "guy@company.com") .WithName("jeremy"); // We're calling your real web service's configuration theHost = await AlbaHost.For(securityStub); ``` -------------------------------- ### NUnit Scenario Test with Reused AlbaHost Source: https://github.com/jasperfx/alba/blob/master/docs/guide/nunit.md Reference the static AlbaHost within NUnit tests to execute scenarios. This allows tests to utilize the pre-initialized host for making requests and asserting responses. ```csharp public class sample_integration_fixture { [Test] public async Task happy_path() { await Application.Host.Scenario(_ => { _.Get.Url("/fake/okay"); _.StatusCodeShouldBeOk(); }); } } ``` -------------------------------- ### Write Multipart Form Data with File Uploads Source: https://github.com/jasperfx/alba/blob/master/docs/scenarios/formdata.md Use this extension to send `MultipartFormDataContent`, which is commonly used for file uploads. Remember to manually set the media type for stream content. ```cs public async Task write_multipart_form_data(IAlbaHost system) { // Read our file into a stream await using var imageFile = File.OpenRead("TestImage.jpg"); // Extract the name from the path var imageFileName = Path.GetFileName(imageFile.Name); // Create the stream content using var content = new StreamContent(imageFile); // Remember to manually set the media type as it won't be done automatically content.Headers.ContentType = new MediaTypeHeaderValue(MediaTypeNames.Image.Jpeg); // Create the MultiPartForm content & add the file using var formData = new MultipartFormDataContent(); formData.Add(content, "files", imageFileName); // If you have other content in the form object, you can add it as well! formData.Add(new StringContent("My additional metadata"), "metadata"); var result = await system.Scenario(_ => { // This extension will write the content to the request // body and set the required headers _.Post.MultipartFormData(formData).ToUrl("/api/files/upload"); _.StatusCodeShouldBeOk(); }); } ``` -------------------------------- ### Post JSON and Receive JSON Response Source: https://github.com/jasperfx/alba/blob/master/docs/scenarios/json.md The `system.PostJson(request, url).Receive()` helper simplifies posting a JSON request and expecting a JSON response, directly deserializing the result into the specified type. ```cs [Fact] public async Task post_and_expect_response() { await using var system = await AlbaHost.For(); var request = new OperationRequest { Type = OperationType.Multiply, One = 3, Two = 4 }; var result = await system.PostJson(request, "/math") .Receive(); result.Answer.ShouldBe(12); result.Method.ShouldBe("POST"); } ``` -------------------------------- ### Send XML in Request Body Source: https://github.com/jasperfx/alba/blob/master/docs/scenarios/xml.md Use the .Xml() extension method to serialize an object to XML and set the appropriate HTTP headers for the request body. This is useful for testing XML APIs. ```cs public async Task send_xml(IAlbaHost host) { await host.Scenario(_ => { // This serializes the Input object to xml, // writes it to the HttpRequest.Body, and sets // the accepts & content-type header values to // application/xml _.Post .Xml(new Input {Name = "Max", Age = 13}) .ToUrl("/person"); // OR, if url lookup is enabled, this is an equivalent: _.Post.Xml(new Input {Name = "Max", Age = 13}); }); } ``` -------------------------------- ### Setting Request Headers with Alba Source: https://github.com/jasperfx/alba/blob/master/docs/scenarios/headers.md Use the `WithRequestHeader` method within a scenario to set custom request headers. This is useful for simulating specific client configurations. ```cs await system.Scenario(_ => { _.WithRequestHeader("foo", "bar"); }); ``` -------------------------------- ### Send JSON to a Minimal API Endpoint Source: https://github.com/jasperfx/alba/blob/master/docs/scenarios/json.md When testing systems with mixed Minimal API and MVC usage, specify `JsonStyle.MinimalApi` to ensure correct JSON serialization compliant with Minimal API conventions. ```cs public async Task send_json_minimal_api(IAlbaHost host) { await host.Scenario(_ => { // In a system that has mixed Minimal API and MVC usage, // you may need to help Alba know if the route being tested // should use Minimal API or MVC Core compliant JSON testing _.Post .Json(new Input {Name = "Max", Age = 13}, JsonStyle.MinimalApi) .ToUrl("/person"); }); } ``` -------------------------------- ### Create an Extension Method for Content Assertion Source: https://github.com/jasperfx/alba/blob/master/docs/scenarios/assertions.md This extension method applies the BodyContainsAssertion to a scenario. It provides a convenient way to assert that the response content contains specific text. ```csharp /// /// Assert that the Http response contains the designated text /// /// /// /// public static Scenario ContentShouldContain(this Scenario scenario, string text) { return scenario.AssertThat(new BodyContainsAssertion(text)); } ``` -------------------------------- ### Define MathController and Operation Types Source: https://github.com/jasperfx/alba/blob/master/docs/scenarios/writingscenarios.md Defines the necessary C# enums and classes for a sample MathController, including OperationType, OperationRequest, and OperationResult. ```cs public enum OperationType { Add, Subtract, Multiply, Divide } public class OperationRequest { public OperationType Type { get; set; } public int One { get; set; } public int Two { get; set; } } public class OperationResult { public int Answer { get; set; } public string Method { get; set; } } [ApiController] [Route("[controller]")] public class MathController : Controller { [HttpGet("add/{one}/{two}")] public OperationResult Add(int one, int two) { return new OperationResult { Answer = one + two }; } [HttpPut] public OperationResult Put([FromBody]OperationRequest request) { switch (request.Type) { case OperationType.Add: return new OperationResult{Answer = request.One + request.Two, Method = "PUT"}; case OperationType.Multiply: return new OperationResult{Answer = request.One * request.Two, Method = "PUT"}; case OperationType.Subtract: return new OperationResult{Answer = request.One - request.Two, Method = "PUT"}; default: throw new ArgumentOutOfRangeException(nameof(request.Type)); } } [HttpPost] public OperationResult Post([FromBody]OperationRequest request) { switch (request.Type) { case OperationType.Add: return new OperationResult{Answer = request.One + request.Two, Method = "POST"}; case OperationType.Multiply: return new OperationResult{Answer = request.One * request.Two, Method = "POST"}; case OperationType.Subtract: return new OperationResult{Answer = request.One - request.Two, Method = "POST"}; default: throw new ArgumentOutOfRangeException(nameof(request.Type)); } } } ``` -------------------------------- ### Send JSON to an Endpoint Source: https://github.com/jasperfx/alba/blob/master/docs/scenarios/json.md Use the `.Json()` method to serialize an object to JSON and send it as the request body. This also sets the 'Accept' and 'Content-Type' headers to 'application/json'. ```cs public async Task send_json(IAlbaHost host) { await host.Scenario(_ => { // This serializes the Input object to json, // writes it to the HttpRequest.Body, and sets // the accepts & content-type header values to // application/json _.Post .Json(new Input {Name = "Max", Age = 13}) .ToUrl("/person"); }); } ``` -------------------------------- ### Override Application Configuration with ConfigurationOverride Source: https://github.com/jasperfx/alba/blob/master/docs/guide/extensions.md Utilize the `ConfigurationOverride` extension to modify application configuration values, such as a Postgres connection string. This is a workaround for limitations in the ASP.NET Core test host. ```csharp var configValues = new Dictionary() { { "ConnectionStrings:Postgres", "MyOverriddenValue" } }; var host = await AlbaHost.For(builder => { builder.ConfigureServices(c => { // services config }); }, ConfigurationOverride.Create(configValues)); ``` -------------------------------- ### Override a Specific Authentication Scheme Source: https://github.com/jasperfx/alba/blob/master/docs/guide/security.md Use `AuthenticationStub` with a scheme name to replace only that specific authentication scheme instead of all schemes. ```cs var securityStub = new AuthenticationStub("custom") .With("foo", "bar") .With(JwtRegisteredClaimNames.Email, "guy@company.com") .WithName("jeremy"); await using var host = await AlbaHost.For(securityStub); ``` -------------------------------- ### Specify Specific Claims for a Scenario Source: https://github.com/jasperfx/alba/blob/master/docs/guide/security.md Modify claims for a single scenario using WithClaim() and RemoveClaim(). This allows testing with different claims than the baseline defined on the AuthenticationStub. ```cs [Fact] public async Task can_modify_claims_per_scenario() { var input = new Numbers { Values = new[] {2, 3, 4} }; var response = await theHost.Scenario(x => { // This is a custom claim that would only be used for the // JWT token in this individual test x.WithClaim(new Claim("color", "green")); x.RemoveClaim("foo"); x.Post.Json(input).ToUrl("/math"); x.StatusCodeShouldBeOk(); }); var principal = response.Context.User; principal.ShouldNotBeNull(); principal.Claims.Single(x => x.Type == "color") .Value.ShouldBe("green"); principal.Claims.Any(x => x.Type.Equals("foo")).ShouldBeFalse(); } ``` -------------------------------- ### Bind Form Data from an Object Source: https://github.com/jasperfx/alba/blob/master/docs/scenarios/formdata.md This overload attempts to use an object and its properties to populate the form data. Note that it only adds first-level properties; for deeper accessors, use the dictionary approach. ```cs [Fact] public async Task can_bind_to_form_data() { await using var system = await AlbaHost.For(); var input = new InputModel { One = "one", Two = "two", Three = "three" }; await system.Scenario(_ => { _.Post.FormData(input) .ToUrl("/gateway/insert"); }); GatewayController.LastInput.ShouldNotBeNull(); GatewayController.LastInput.One.ShouldBe("one"); GatewayController.LastInput.Two.ShouldBe("two"); GatewayController.LastInput.Three.ShouldBe("three"); } ``` -------------------------------- ### Write Standard Form Data with Dictionary Source: https://github.com/jasperfx/alba/blob/master/docs/scenarios/formdata.md Use this method to write dictionary values to the HTTP request as form data. It automatically sets the content-length and content-type headers to application/x-www-form-urlencoded. ```cs public async Task write_form_data(IAlbaHost system) { var form1 = new Dictionary { ["a"] = "what?", ["b"] = "now?", ["c"] = "really?" }; await system.Scenario(_ => { // This writes the dictionary values to the HTTP // request as form data, and sets the content-length // header as well as setting the content-type // header to application/x-www-form-urlencoded _.WriteFormData(form1); }); } ``` -------------------------------- ### Asserting Redirect Responses Source: https://github.com/jasperfx/alba/blob/master/docs/scenarios/redirects.md Use RedirectShouldBe and RedirectPermanentShouldBe assertions to verify redirect URLs. These assertions are part of the Scenario method in Alba. ```cs public async Task asserting_redirects(IAlbaHost system) { await system.Scenario(_ => { // should redirect to the url _.RedirectShouldBe("/redirect"); // should redirect permanently to the url _.RedirectPermanentShouldBe("/redirect"); }); } ``` -------------------------------- ### Define a Custom Scenario Assertion Interface Source: https://github.com/jasperfx/alba/blob/master/docs/scenarios/assertions.md Implement this interface to create your own assertion logic for scenarios. The Assert method is called during scenario execution. ```csharp public interface IScenarioAssertion { void Assert(Scenario scenario, AssertionContext context); } ``` -------------------------------- ### Configure OIDC Resource Owner Password Grant Source: https://github.com/jasperfx/alba/blob/master/docs/guide/security.md Use this extension for OIDC Resource Owner Password Grant workflow. All properties like ClientId, ClientSecret, UserName, and Password are mandatory. ```csharp oidc = new OpenConnectUserPassword { // All of these properties are mandatory ClientId = Config.ClientId, ClientSecret = Config.ClientSecret, UserName = "alice", Password = "alice" }; theHost = await AlbaHost.For(x => { x.ConfigureServices((ctx, collection) => collection.Configure(JwtBearerDefaults.AuthenticationScheme, options => { options.Authority = _fixture.IdentityServer.BaseAddress.ToString(); options.BackchannelHttpHandler = _fixture.IdentityServer.CreateHandler(); options.RequireHttpsMetadata = false; })); }, oidc); ``` -------------------------------- ### Send Plain Text in Request Source: https://github.com/jasperfx/alba/blob/master/docs/scenarios/text.md Use the Post.Text() method to send plain text content in an HTTP request. This automatically sets the Content-Length and Content-Type headers. ```csharp public async Task send_text(IAlbaHost host) { await host.Scenario(_ => { _.Post.Text("some text").ToUrl("/textdata"); }); } ``` -------------------------------- ### Asserting on Response Headers with Alba Source: https://github.com/jasperfx/alba/blob/master/docs/scenarios/headers.md Alba provides declarative assertions for response headers, including checking for single values, absence of values, presence of any values, specific values, and regex matching. Use `Header()` for custom headers and `ContentTypeShouldBe()` for the content type. ```cs await system.Scenario(_ => { // Assert that there is one and only one value equal to "150" _.Header(HeaderNames.ContentLength).SingleValueShouldEqual("150"); // Assert that there is no value for this response header _.Header(HeaderNames.Connection).ShouldNotBeWritten(); // Only write one value for this header _.Header(HeaderNames.SetCookie).ShouldHaveOneNonNullValue(); // Assert that the header has any values _.Header(HeaderNames.ETag).ShouldHaveValues(); // Assert that the header has the given values _.Header(HeaderNames.WWWAuthenticate).ShouldHaveValues("NTLM", "Negotiate"); // Assert that the header matches a regular expression _.Header(HeaderNames.Location).SingleValueShouldMatch(new Regex(@"^/items/\d*$")); // Check the content-type header _.ContentTypeShouldBe("text/json"); }); ``` -------------------------------- ### Access Raw Response Objects in Scenario Source: https://github.com/jasperfx/alba/blob/master/docs/guide/gettingstarted.md Execute a scenario and gain direct access to the raw `HttpContext` and `Response.Body` stream for custom assertions. Alba rewinds the response body stream automatically. ```cs var response = await host.Scenario(_ => { _.Get.Url("/"); _.StatusCodeShouldBeOk(); }); // you can go straight at the HttpContext & do assertions directly on the responseStream Stream responseStream = response.Context.Response.Body; ``` -------------------------------- ### Assert on Response Text Content Source: https://github.com/jasperfx/alba/blob/master/docs/scenarios/text.md Alba offers operations like ContentShouldBe, ContentShouldContain, and ContentShouldNotContain to assert specific text content in the response body. ```csharp public async Task assert_on_content(IAlbaHost host) { await host.Scenario(_ => { _.ContentShouldBe("exactly this"); _.ContentShouldContain("some snippet"); _.ContentShouldNotContain("some warning"); }); } ``` -------------------------------- ### Override User Credentials in Scenario Source: https://github.com/jasperfx/alba/blob/master/docs/guide/security.md Override the default user credentials for a specific scenario using the UserAndPasswordIs extension method. This is useful for testing different user contexts within the same test suite. ```csharp [Fact] public async Task post_to_a_secured_endpoint_with_jwt_with_overridden_user_and_password() { // Building the input body var input = new Numbers { Values = new[] {2, 3, 4} }; var response = await theHost.Scenario(x => { // Alba deals with Json serialization for us x.Post.Json(input).ToUrl("/math"); // Override the user credentials for just this scenario x.UserAndPasswordIs("bob", "bob"); // Enforce that the HTTP Status Code is 200 Ok x.StatusCodeShouldBeOk(); }); var output = response.ReadAsJson(); output.Sum.ShouldBe(9); output.Product.ShouldBe(24); var user = response.Context.User; user.FindFirst("name").Value.ShouldBe("Bob Smith"); } ``` -------------------------------- ### Read JSON Response Body Source: https://github.com/jasperfx/alba/blob/master/docs/scenarios/json.md Deserialize the response body into a strongly-typed object using `result.ReadAsJsonAsync()` after making a request within a `Scenario`. ```cs public async Task read_json(IAlbaHost host) { var result = await host.Scenario(_ => { _.Get.Url("/output"); }); // This deserializes the response body to the // designated Output type var output = result.ReadAsJsonAsync(); // do assertions against the Output model } ``` -------------------------------- ### Read XML from Response Body Source: https://github.com/jasperfx/alba/blob/master/docs/scenarios/xml.md Utilize the ReadAsXml() or ReadAsXmlAsync() methods on the HttpResponseBody to deserialize XML content from an HTTP response. This allows for assertions on the received XML data. ```cs public async Task read_xml(IAlbaHost host) { var result = await host.Scenario(_ => { _.Get.Url("/output"); }); // This deserializes the response body to the // designated Output type var output = result.ReadAsXml(); // do assertions against the Output model // OR, if you just want the XmlDocument itself: XmlDocument document = await result.ReadAsXmlAsync(); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.