public SalesOrdersControllerSystemTest(WebApplicationFactory <TC3.Startup> factory)
        {
            // The WebApplicationFactory allows true E2E testing spinning up the application in memory
            // and allowing HttpClient calls agains the HTTP interface. Without any adjustments this
            // runs the application as configured in the project folder (appsettings, Startup class, etc.)

            string currentDir = Directory.GetCurrentDirectory();
            string configPath = Path.Combine(currentDir, appConfigFile);

            this.factory = factory.WithWebHostBuilder(builder => {
                // Part 1: override the appsettings in the configuration. A system test is an E2E
                // "plumbing" test. We don't want to spin up the application with the live database,
                // so a test-appsettings file can be injected to override those settings. In this
                // example an external database is used, but it could be replaced by an in-memory
                // database as the intergration test example used.

                builder.ConfigureAppConfiguration((context, conf) => {
                    conf.AddJsonFile(configPath);
                });

                // There are two options in system testing for the database. In general a system
                // test will be an E2# integration test: check individual operations to make sure
                // everything works from beginning to end. In order to effectively test
                // operations database changes need to be rolled back, but that becomes a problem
                // when .NET core injects a new DbContext into each request (scoped) and we don't
                // know what it is! Some net articles advocate channging the Startup class to use
                // a singleton DbContext instead, but that fails on two counts: you don't want to
                // do a "plumbing" test with a different Startup, tests could "pass" because of
                // differences in the versions. And, tests running in parallel may share the same
                // context, leading to false negatives!
                //
                // Each test runs in it's own instance of this test suite class, and each test has
                // its own web application instance in memory, so the solution is to instaniate a
                // DbContext in each test class instance and inject it into the configuration for
                // that specific web application instance :)

                IConfigurationRoot configurationRoot = new ConfigurationBuilder()
                                                       .SetBasePath(Directory.GetCurrentDirectory())
                                                       .AddJsonFile(appConfigFile, optional: true)
                                                       .Build();

                var options = new DbContextOptionsBuilder <TC3Context>()
                              .UseSqlite(configurationRoot.GetConnectionString("DefaultConnection"))
                              .EnableSensitiveDataLogging()
                              .Options;

                dbContext = new TC3Context(options);

                builder.ConfigureServices(services => {
                    // Inject our DbContext for the configuration for this application instance.
                    // This is the same place that you would inject third-party mocks, such as
                    // credit-card authorization.

                    services.AddSingleton <TC3Context>(dbContext);
                });
            });
        }
        private void GivenSalesOrderControllerWithInMemoryDatabase()
        {
            // Follow this method into the factory to see how it sets up the in-memory database.

            InMemoryDatabaseFactory       factory = new InMemoryDatabaseFactory();
            DbContextOptions <TC3Context> options = new DbContextOptionsBuilder <TC3Context>().UseSqlite(factory.Instance.Connection).Options;

            dbContext = new TC3Context(options);
            dbContext.Database.EnsureCreated();

            salesOrdersService = new SalesOrdersService(dbContext);
            controller         = new SalesOrdersController(salesOrdersService);
        }
 public SalesOrdersService(TC3Context tc3Context)
 {
     this.dbContext = tc3Context;
 }
 public SalesOrderManager(ICardValidator cardValidator, IMerchantServicesAuthorizer authorizer, TC3Context dbContext)
 {
     this.cardValidator = cardValidator;
     this.authorizer    = authorizer;
     this.dbContext     = dbContext;
 }