Skip to content

Commit

Permalink
Fix the initializer with DbContext to use admin rights.
Browse files Browse the repository at this point in the history
  • Loading branch information
GillesTourreau committed Aug 20, 2024
1 parent 2d998e0 commit 7efef4e
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 5 deletions.
19 changes: 15 additions & 4 deletions src/UnitTests.Databases.SqlServer/SqlServerDatabaseInitializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,21 +47,32 @@ IF SUSER_ID ('{connectionStringBuilder.UserID}') IS NULL
public SqlServerDatabase Initialize<TContext>(TContext context)
where TContext : DbContext
{
var connectionStringBuilder = new SqlConnectionStringBuilder(context.Database.GetDbConnection().ConnectionString);
var connectionString = context.Database.GetConnectionString();

var server = new SqlServer(context.Database.GetDbConnection().ConnectionString);
var connectionStringBuilder = new SqlConnectionStringBuilder(connectionString);

var server = new SqlServer(connectionString!);
var database = server.GetDatabase(connectionStringBuilder.InitialCatalog);

if (!this.isDeployed)
{
server.DeleteDatabase(connectionStringBuilder.InitialCatalog);

// Change the connection with administrator rights.
context.Database.SetConnectionString(database.AsAdministrator().ConnectionString);
context.Database.EnsureCreated();
context.Database.SetConnectionString(connectionString);

if (!string.IsNullOrWhiteSpace(connectionStringBuilder.UserID))
{
server.Master.ExecuteNonQuery($@"
IF SUSER_ID ('{connectionStringBuilder.UserID}') IS NULL
CREATE LOGIN [{connectionStringBuilder.UserID}] WITH PASSWORD = '{connectionStringBuilder.Password}'");
}

this.isDeployed = true;
}

var database = server.GetDatabase(connectionStringBuilder.InitialCatalog);

ClearAllData(database.AsAdministrator());

return database;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

namespace PosInformatique.UnitTests.Databases.SqlServer.Tests
{
using Microsoft.EntityFrameworkCore;

[Collection("PosInformatique.UnitTests.Databases.SqlServer.Tests")]
public class SqlServerDatabaseInitializerDbContextWithLoginTest : IClassFixture<SqlServerDatabaseInitializer>
{
Expand All @@ -15,7 +17,16 @@ public class SqlServerDatabaseInitializerDbContextWithLoginTest : IClassFixture<

public SqlServerDatabaseInitializerDbContextWithLoginTest(SqlServerDatabaseInitializer initializer)
{
this.database = initializer.Initialize("UnitTests.Databases.SqlServer.Tests.DacPac.dacpac", ConnectionString);
var optionsBuilder = new DbContextOptionsBuilder<DbContextTest>()
.UseSqlServer(ConnectionString);

using var context = new DbContextTest(optionsBuilder.Options);

this.database = initializer.Initialize(context);

this.database.AsAdministrator().ExecuteNonQuery("IF NOT EXISTS (SELECT 1 FROM [sys].[sysusers] WHERE name = 'ServiceAccountUser') CREATE USER [ServiceAccountUser] FOR LOGIN [ServiceAccountLogin]");
this.database.AsAdministrator().ExecuteNonQuery("GRANT CONNECT TO [ServiceAccountUser]");
this.database.AsAdministrator().ExecuteNonQuery("GRANT SELECT, INSERT ON [MyTable] TO [ServiceAccountUser]");

var table = this.database.ExecuteQuery("SELECT * FROM MyTable");

Expand Down Expand Up @@ -66,5 +77,36 @@ public void Test2()
// Insert a row which should not be use in other tests.
this.database.InsertInto("MyTable", new { Id = 99, Name = "Should not be here for the next unit test" });
}

private sealed class DbContextTest : DbContext
{
public DbContextTest(DbContextOptions<DbContextTest> options)
: base(options)
{
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Table>(t =>
{
t.ToTable("MyTable");

t.Property(t => t.Id)
.ValueGeneratedNever();

t.Property(t => t.Name)
.IsRequired()
.HasMaxLength(50)
.IsUnicode(false);
});
}
}

private sealed class Table
{
public int Id { get; set; }

public string Name { get; set; }
}
}
}

0 comments on commit 7efef4e

Please sign in to comment.