// Subclasses can access this method, private would mean only this class. protected IntegrationTest(ITestOutputHelper output) { _output = output; // The configuration we use for integration testing has Caching and Mailing disabled (flags set to false) - we do not test these aspects here for now. // These mutations tested to work in .NET Core 3.1 var builder = new ConfigurationBuilder().AddUserSecrets <IntegrationTest>(); Configuration = builder.Build(); var appFactory = new WebApplicationFactory <Startup>() .WithWebHostBuilder(builder => { builder.ConfigureServices(services => { // Remove certain injected services (from the Startup.cs) in order to mutate and reinject. foreach (Type t in new Type[] { typeof(DbContextOptions <AppDbContext>), typeof(PgSqlSettings), typeof(RedisSettings), typeof(MailSettings), typeof(JwtSettings), typeof(IConnectionMultiplexer), typeof(ICacheService), typeof(ConnectionMultiplexer), typeof(RedisCacheService) }) { services.RemoveAll(t); //var descriptor = services.SingleOrDefault(d => d.ServiceType == t); //if (descriptor != null) //{ // services.Remove(descriptor); //} } // Reinject the settings with the new configuration (these mutations tested to work in .NET Core 3.1) var settings = ConfigurationInstaller.BindSettings(Configuration, services, disableAll: true); ConfigurationInstaller.InstallServicesFromSettings(settings, services); _output.WriteLine(JsonConvert.SerializeObject(settings)); // Construct a throwaway database with it. _throwawayDatabase = ThrowawayDatabase.Create(settings.PgSqlSettings.Username, settings.PgSqlSettings.Password, settings.PgSqlSettings.Host); services.AddDbContext <AppDbContext>(options => options.UseNpgsql(_throwawayDatabase.ConnectionString)); }); }); _serviceProvider = appFactory.Services; TestClient = appFactory.CreateClient(); }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddControllers().AddNewtonsoftJson(s => { s.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); }); var settings = ConfigurationInstaller.BindSettings(Configuration, services); services.AddDbContext <AppDbContext>(options => options.UseNpgsql(Configuration.GetConnectionString("PgDbMain"))); services.AddIdentity <ApplicationUser, IdentityRole>() .AddEntityFrameworkStores <AppDbContext>() .AddDefaultTokenProviders(); services.AddSingleton(ConfigurationInstaller.AssembleMapperConfiguration().CreateMapper()); services.AddScoped <IAuthService, AuthService>(); services.AddScoped <IMailService, MailService>(); services.AddHostedService <QueuedHostedService>(); services.AddSingleton <IBackgroundTaskQueue, BackgroundTaskQueue>(); services.AddScoped <IUpdateService, UpdateService>(); services.AddScoped <IResourceService, ResourceService>(); ConfigurationInstaller.InstallServicesFromSettings(settings, services); services.Configure <IdentityOptions>(options => { options.User.RequireUniqueEmail = true; options.Password.RequireDigit = true; options.Password.RequireLowercase = true; options.Password.RequireNonAlphanumeric = false; options.Password.RequireUppercase = false; options.Password.RequiredLength = 8; options.Password.RequiredUniqueChars = 1; options.SignIn.RequireConfirmedEmail = true; }); var tokenValidationParameters = new TokenValidationParameters() { ValidateIssuer = true, ValidateAudience = true, ValidateIssuerSigningKey = true, ValidIssuer = settings.JwtSettings.Issuer, ValidAudience = settings.JwtSettings.Audience, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(settings.JwtSettings.SigningKey)) }; services.AddSingleton(tokenValidationParameters); services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.SaveToken = true; options.RequireHttpsMetadata = false; options.TokenValidationParameters = tokenValidationParameters; }); services.AddAuthorization(options => { options.AddPolicy(AdminOnlyPolicy, policy => { policy.RequireClaim(SeniorityClaimKey, Admin); policy.RequireClaim(IsInitalSetClaimKey, true.ToString()); }); options.AddPolicy(ContractorOrAbovePolicy, policy => { policy.RequireClaim(SeniorityClaimKey, Admin, Contractor); policy.RequireClaim(IsInitalSetClaimKey, true.ToString()); }); options.AddPolicy(ManagerOrAbovePolicy, policy => { policy.RequireClaim(SeniorityClaimKey, Admin, Contractor, Manager); policy.RequireClaim(IsInitalSetClaimKey, true.ToString()); }); options.AddPolicy(SupervisorOrAbovePolicy, policy => { policy.RequireClaim(SeniorityClaimKey, Admin, Contractor, Manager, Supervisor); policy.RequireClaim(IsInitalSetClaimKey, true.ToString()); }); options.AddPolicy(WorkerOrAbovePolicy, policy => { policy.RequireClaim(SeniorityClaimKey, Admin, Contractor, Manager, Supervisor, Worker); policy.RequireClaim(IsInitalSetClaimKey, true.ToString()); }); }); services.AddSwaggerGen(c => { c.AddSecurityDefinition(JwtBearerDefaults.AuthenticationScheme, new OpenApiSecurityScheme { Description = "", Name = "Authorization", In = ParameterLocation.Header, Type = SecuritySchemeType.ApiKey, Scheme = JwtBearerDefaults.AuthenticationScheme }); c.AddSecurityRequirement(new OpenApiSecurityRequirement() { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = JwtBearerDefaults.AuthenticationScheme }, Scheme = "oauth2", Name = JwtBearerDefaults.AuthenticationScheme, In = ParameterLocation.Header, }, new List <string>() } }); c.OperationFilter <AppendAuthorizeToSummaryOperationFilter>(); }); }