using System;
using System.Data.Common;
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Hosting.Internal;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.OptionsModel;
using Yavsc.Lib;
using Yavsc.Services;
using Yavsc;
using Yavsc.Models;
using Xunit;
using Npgsql;
using test.Settings;
using Microsoft.Data.Entity;
using Microsoft.Data.Entity.Metadata.Conventions;
namespace test
{
[Trait("regression", "II")]
public class ServerSideFixture : IDisposable
{
SiteSettings _siteSetup;
ILogger _logger;
IApplication _app;
readonly EMailer _mailer;
readonly ILoggerFactory _loggerFactory;
IEmailSender _mailSender;
public static string ApiKey => "53f4d5da-93a9-4584-82f9-b8fdf243b002";
public ApplicationDbContext DbContext { get; private set; }
public SiteSettings SiteSetup
{
get
{
return _siteSetup;
}
set
{
_siteSetup = value;
}
}
///
/// initialized by Init
///
///
public static object TestingSetup { get; private set; }
public IEmailSender MailSender
{
get
{
return _mailSender;
}
set
{
_mailSender = value;
}
}
public IApplication App
{
get
{
return _app;
}
set
{
_app = value;
}
}
internal void UpgradeDb()
{
Microsoft.Data.Entity.Commands.Program.Main(
new string[] { "database", "update" });
}
public ILogger Logger
{
get
{
return _logger;
}
set
{
_logger = value;
}
}
bool dbCreated;
private readonly WebHostBuilder host;
private readonly IHostingEngine hostengnine;
void AssertNotNull(object obj, string msg)
{
if (obj == null)
throw new Exception(msg);
}
//
public ServerSideFixture()
{
host = new WebHostBuilder();
AssertNotNull(host, nameof(host));
hostengnine = host
.UseEnvironment("Development")
.UseServer("test")
.UseStartup()
.Build();
AssertNotNull(hostengnine, nameof(hostengnine));
App = hostengnine.Start();
AssertNotNull(App, nameof(App));
// hostengnine.ApplicationServices
_mailer = App.Services.GetService(typeof(EMailer)) as EMailer;
AssertNotNull(_mailer, nameof(_mailer));
MailSender = App.Services.GetService(typeof(IEmailSender)) as IEmailSender;
AssertNotNull(MailSender, nameof(MailSender));
_loggerFactory = App.Services.GetService(typeof(ILoggerFactory)) as ILoggerFactory;
AssertNotNull(_loggerFactory, nameof(_loggerFactory));
var siteSetup = App.Services.GetService(typeof(IOptions)) as IOptions;
AssertNotNull(siteSetup, nameof(siteSetup));
var testingSetup = App.Services.GetService(typeof(IOptions)) as IOptions;
DbContext = App.Services.GetService(typeof(ApplicationDbContext)) as ApplicationDbContext;
SiteSetup = siteSetup.Value;
TestingSetup = testingSetup.Value;
Logger = _loggerFactory.CreateLogger();
var builder = new DbConnectionStringBuilder
{
ConnectionString = Startup.Testing.ConnectionStrings.Default
};
ConventionSet conventions = new ConventionSet();
modelBuilder = new ModelBuilder(conventions);
ApplicationDbContext context = new ApplicationDbContext();
TestingDatabase = (string)builder["Database"];
Logger.LogInformation("ServerSideFixture created.");
}
private readonly ModelBuilder modelBuilder;
public string TestingDatabase { get; private set; }
public void CheckDbExistence()
{
using (
NpgsqlConnection cx = new NpgsqlConnection(Startup.Testing.ConnectionStrings.DatabaseCtor))
{
cx.Open();
_logger.LogInformation($"check db for TestingDatabase:{TestingDatabase}");
var command = cx.CreateCommand();
command.CommandText = $"SELECT 1 FROM pg_database WHERE datname='{TestingDatabase}';";
dbCreated = (command.ExecuteScalar()!=null);
_logger.LogInformation($"DbCreated:{dbCreated}");
cx.Close();
}
}
public bool EnsureTestDb()
{
if (!DbCreated)
{
using (NpgsqlConnection cx = new NpgsqlConnection(Startup.Testing.ConnectionStrings.DatabaseCtor))
{
_logger.LogInformation($"create database for TestingDatabase : {TestingDatabase}");
cx.Open();
var command = cx.CreateCommand();
using (NpgsqlConnection ownercx = new NpgsqlConnection(Startup.Testing.ConnectionStrings.Default))
command.CommandText = $"create database \"{TestingDatabase}\" OWNER \"{ownercx.UserName}\";";
_logger.LogInformation(command.CommandText);
command.ExecuteNonQuery();
}
dbCreated = true;
}
return dbCreated;
}
public void DropTestDb()
{
if (dbCreated)
DbContext.Database.EnsureDeleted();
dbCreated = false;
}
public void Dispose()
{
Logger.LogInformation("Disposing");
}
public bool DbCreated { get {
CheckDbExistence();
return dbCreated; } }
}
}