Skip to content

Commit

Permalink
Merge branch 'db-spb'
Browse files Browse the repository at this point in the history
  • Loading branch information
dlidstrom committed Mar 17, 2022
2 parents 82121f3 + a9960cc commit cbcc8ba
Show file tree
Hide file tree
Showing 41 changed files with 573 additions and 100 deletions.
36 changes: 28 additions & 8 deletions Snittlistan.Test/ApiControllers/Infrastructure/InMemoryContext.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
using System.Collections;
#nullable enable

using System.Collections;
using System.Collections.ObjectModel;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq.Expressions;
using System.Reflection;
using Snittlistan.Web.Infrastructure.Database;

#nullable enable

namespace Snittlistan.Test.ApiControllers.Infrastructure;

public sealed class InMemoryDbSet<T> : IDbSet<T>, IDbAsyncEnumerable<T> where T : class
{
private readonly IdGenerator _generator;
Expand Down Expand Up @@ -106,19 +107,34 @@ public InMemoryContext()
IdGenerator generator = new();
PublishedTasks = new InMemoryDbSet<PublishedTask>(generator);
Tenants = new InMemoryDbSet<Tenant>(generator);
Teams = new InMemoryDbSet<Bits_Team>(generator);
Hallar = new InMemoryDbSet<Bits_Hall>(generator);
Team = new InMemoryDbSet<Bits_Team>(generator);
HallRef = new InMemoryDbSet<Bits_HallRef>(generator);
Hall = new InMemoryDbSet<Bits_Hall>(generator);
RosterMails = new InMemoryDbSet<RosterMail>(generator);
ChangeLogs = new InMemoryDbSet<ChangeLog>(generator);
KeyValueProperties = new InMemoryDbSet<KeyValueProperty>(generator);
SentEmails = new InMemoryDbSet<SentEmail>(generator);
Match = new InMemoryDbSet<Bits_Match>(generator);
TeamRef = new InMemoryDbSet<Bits_TeamRef>(generator);
OilProfile = new InMemoryDbSet<Bits_OilProfile>(generator);
VMatchHeadInfo = new InMemoryDbSet<Bits_VMatchHeadInfo>(generator);
}

public IDbSet<PublishedTask> PublishedTasks { get; }

public IDbSet<Bits_Team> Teams { get; }
public IDbSet<Bits_Team> Team { get; }

public IDbSet<Bits_HallRef> HallRef { get; }

public IDbSet<Bits_Hall> Hall { get; }

public IDbSet<Bits_Match> Match { get; }

public IDbSet<Bits_Hall> Hallar { get; }
public IDbSet<Bits_TeamRef> TeamRef { get; }

public IDbSet<Bits_OilProfile> OilProfile { get; }

public IDbSet<Bits_VMatchHeadInfo> VMatchHeadInfo { get; }

public IDbSet<Tenant> Tenants { get; }

Expand All @@ -130,7 +146,7 @@ public InMemoryContext()

public IDbSet<SentEmail> SentEmails { get; }

public DbChangeTracker ChangeTracker => throw new NotImplementedException();
public DbChangeTracker ChangeTracker { get; } = null!;

public int SaveChanges()
{
Expand All @@ -141,4 +157,8 @@ public Task<int> SaveChangesAsync()
{
return Task.FromResult(0);
}

public void Dispose()
{
}
}
7 changes: 6 additions & 1 deletion Snittlistan.Test/Domain/MatchResult_MatchCommentary.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#nullable enable

using Castle.Core.Logging;
using EventStoreLite;
using Moq;
using NUnit.Framework;
Expand Down Expand Up @@ -168,13 +169,16 @@ await Transact(async session =>
session,
eventStoreSession,
Databases,
new(() => Databases),
Container.Resolve<MsmqFactory>(),
Container.Resolve<EventStore>(),
CurrentTenant,
Container.Resolve<IEmailService>(),
Mock.Of<IBitsClient>(MockBehavior.Strict));
Mock.Of<IBitsClient>(MockBehavior.Strict),
NullLogger.Instance);
CommandExecutor commandExecutor = new(
compositionRoot,
Databases,
compositionRoot.CorrelationId,
null,
string.Empty);
Expand All @@ -184,6 +188,7 @@ await Transact(async session =>
};
HandlerContext<RegisterMatchCommandHandler.Command> context = new(
compositionRoot,
Databases,
command,
new("hostname", "favicon", "appleTouchIcon", "appleTouchIconSize", "webAppTitle", -1, "teamFullName"),
Guid.NewGuid(),
Expand Down
6 changes: 3 additions & 3 deletions Snittlistan.Web/Areas/V1/Controllers/SearchController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public JsonResult TeamsQuickSearch(string term)
}

var query =
from team in CompositionRoot.Databases.Bits.Teams
from team in CompositionRoot.Databases.Bits.Team
where team.TeamAlias.StartsWith(term)
orderby team.TeamAlias
select new
Expand All @@ -35,14 +35,14 @@ public JsonResult LocationsQuickSearch(string term)
}

var query =
from hall in CompositionRoot.Databases.Bits.Hallar
from hall in CompositionRoot.Databases.Bits.Hall
where hall.HallName.StartsWith(term)
orderby hall.HallName
select new
{
label = hall.HallName
};

return Json(term, JsonRequestBehavior.AllowGet);
return Json(query, JsonRequestBehavior.AllowGet);
}
}
22 changes: 20 additions & 2 deletions Snittlistan.Web/Areas/V2/Controllers/AdminTasksController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using Snittlistan.Web.Infrastructure.Indexes;
using Snittlistan.Web.Models;
using Snittlistan.Web.Services;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Web;
using System.Web.Mvc;
Expand Down Expand Up @@ -271,23 +272,40 @@ await CompositionRoot.Databases.Snittlistan.KeyValueProperties.SingleOrDefaultAs
public async Task<ActionResult> Features(TenantFeaturesViewModel vm)
{
UpdateFeaturesCommandHandler.Command command = new(
vm.RosterMailEnabled);
vm.RosterMailEnabled,
vm.RosterMailDelayMinutes);
await ExecuteCommand(command);

return RedirectToAction("Index");
}

public class TenantFeaturesViewModel
public class TenantFeaturesViewModel : IValidatableObject
{
public TenantFeaturesViewModel(TenantFeatures tenantFeatures)
{
RosterMailEnabled = tenantFeatures.RosterMailEnabled;
RosterMailDelayMinutes = tenantFeatures.RosterMailDelayMinutes;
}

public TenantFeaturesViewModel()
{
}

public bool RosterMailEnabled { get; set; }

public int RosterMailDelayMinutes { get; set; }

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (RosterMailDelayMinutes < 1)
{
yield return new("Must be at least 1", new[] { nameof(RosterMailDelayMinutes) });
}

if (RosterMailDelayMinutes > 60)
{
yield return new("Must be at most 60", new[] { nameof(RosterMailDelayMinutes) });
}
}
}
}
80 changes: 52 additions & 28 deletions Snittlistan.Web/Areas/V2/Controllers/Api/TaskController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,32 +56,40 @@ public async Task<IHttpActionResult> Post(TaskRequest request)
$"throttled due to unhandled exception (allowance = {cacheItem.Allowance:N2})");
}

// check for published task
PublishedTask? publishedTask =
await CompositionRoot.Databases.Snittlistan.PublishedTasks.SingleOrDefaultAsync(
x => x.MessageId == request.MessageId);
if (publishedTask is null)
{
return BadRequest($"No published task found with message id {request.MessageId}");
}

if (publishedTask.HandledDate.HasValue)
{
return Ok($"task with message id {publishedTask.MessageId} already handled");
}

IDisposable scope = NLog.NestedDiagnosticsLogicalContext.Push(taskObject.BusinessKey);
try
{
using IDisposable scope = NLog.NestedDiagnosticsLogicalContext.Push(taskObject.BusinessKey);
Logger.Info("Begin");
bool handled = await HandleMessage(
taskObject,
request.CorrelationId ?? default,
request.MessageId ?? default);
if (handled)
Logger.Info("begin");
IHttpActionResult result = await Transact<IHttpActionResult>(async databases =>
{
publishedTask.MarkHandled(DateTime.Now);
}
// check for published task
PublishedTask? publishedTask =
await databases.Snittlistan.PublishedTasks.SingleOrDefaultAsync(
x => x.MessageId == request.MessageId);
if (publishedTask is null)
{
return BadRequest($"no published task found with message id {request.MessageId}");
}
if (publishedTask.HandledDate.HasValue)
{
return Ok($"task with message id {publishedTask.MessageId} already handled");
}
bool handled = await HandleMessage(
taskObject,
request.CorrelationId ?? default,
request.MessageId ?? default,
databases);
if (handled)
{
publishedTask.MarkHandled(DateTime.Now);
}
return Ok();
});

return result;
}
catch (Exception ex)
{
Expand All @@ -94,29 +102,30 @@ await CompositionRoot.Databases.Snittlistan.PublishedTasks.SingleOrDefaultAsync(
}
finally
{
Logger.Info("End");
Logger.Info("end");
scope.Dispose();
}

return Ok();
}

private async Task<bool> HandleMessage(
TaskBase taskObject,
Guid correlationId,
Guid causationId)
Guid causationId,
Databases databases)
{
Type handlerType = typeof(ITaskHandler<>).MakeGenericType(taskObject.GetType());

MethodInfo handleMethod = handlerType.GetMethod(nameof(ITaskHandler<TaskBase>.Handle));
TaskPublisher taskPublisher = new(
CompositionRoot.CurrentTenant,
CompositionRoot.Databases,
databases,
CompositionRoot.MsmqFactory,
correlationId,
causationId);
IHandlerContext handlerContext = (IHandlerContext)Activator.CreateInstance(
typeof(HandlerContext<>).MakeGenericType(taskObject.GetType()),
CompositionRoot,
databases,
taskObject,
CompositionRoot.CurrentTenant,
correlationId,
Expand Down Expand Up @@ -147,6 +156,21 @@ private async Task<bool> HandleMessage(

return true;
}

private async Task<TResult> Transact<TResult>(Func<Databases, Task<TResult>> func)
{
using Databases databases = CompositionRoot.DatabasesFactory.Create();
TResult result = await func.Invoke(databases);
int changesSaved = databases.Snittlistan.SaveChanges();
if (changesSaved > 0)
{
Logger.InfoFormat(
"saved {changesSaved} to database",
changesSaved);
}

return result;
}
}

public class TaskRequest
Expand Down
9 changes: 4 additions & 5 deletions Snittlistan.Web/Areas/V2/Controllers/RosterController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ public ActionResult Print(
}

[Authorize(Roles = WebsiteRoles.Uk.UkTasks)]
public async Task<ActionResult> EditPlayers(string rosterId)
public ActionResult EditPlayers(string rosterId)
{
Roster roster = CompositionRoot.DocumentSession
.Include<Roster>(r => r.Players)
Expand All @@ -392,7 +392,6 @@ public async Task<ActionResult> EditPlayers(string rosterId)
.Where(p => p.PlayerStatus == Player.Status.Active)
.ToList();

TenantFeatures? features = await CompositionRoot.GetFeatures();
EditRosterPlayersViewModel vm = new()
{
RosterViewModel = CompositionRoot.DocumentSession.LoadRosterViewModel(roster),
Expand All @@ -407,7 +406,7 @@ public async Task<ActionResult> EditPlayers(string rosterId, RosterPlayersViewMo
{
if (ModelState.IsValid == false)
{
return await EditPlayers(rosterId);
return EditPlayers(rosterId);
}

Roster roster = CompositionRoot.DocumentSession.Load<Roster>(rosterId);
Expand Down Expand Up @@ -488,8 +487,8 @@ public async Task<ActionResult> EditPlayers(string rosterId, RosterPlayersViewMo
break;
}

TenantFeatures? features = await CompositionRoot.GetFeatures();
if ((features?.RosterMailEnabled ?? false) == false)
TenantFeatures features = await CompositionRoot.GetFeatures();
if (features.RosterMailEnabled == false)
{
Logger.Info("RosterMailEnabled evaluated to false");
break;
Expand Down
9 changes: 9 additions & 0 deletions Snittlistan.Web/Areas/V2/Views/AdminTasks/Features.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@
</span>
</div>
</div>
<div class="control-group">
@Html.LabelFor(x => x.RosterMailDelayMinutes, new { @class = "control-label" })
<div class="controls">
@Html.TextBoxFor(x => x.RosterMailDelayMinutes)
<span class="help-block">
Antal minuter att vänta innan laguttagningarna skickas ut per mail, efter en uppdatering.
</span>
</div>
</div>
<div class="control-group">
<div class="controls">
<button class="btn btn-primary btn-large" type="submit">Spara</button>
Expand Down
Loading

0 comments on commit cbcc8ba

Please sign in to comment.