Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
0b121e4
Add Bower package.json files and update .gitignore to ignore node_mod…
Dec 4, 2025
94f7513
Remove appsettings.Development.json from Git and ignore it
Dec 4, 2025
9e2c9f8
Add Daily Report link to navbar
Dec 9, 2025
8b28a1a
Add Daily Report link to navbar
Dec 9, 2025
d8fd487
Add new Daily Report view and backend
Dec 9, 2025
9cfa4c2
Refactor Daily.cshtml.cs into split methods (no logic changes)
Dec 10, 2025
1355b61
Add UnitTest project
Dec 10, 2025
c16012a
make the shifts of Saturday and Sunday 7:30 -- 7:30 instead of 12:00 …
Dec 10, 2025
05ac5c0
this commit has commented code that could show the timeline
Dec 11, 2025
d392c4d
Daily report no longer assigns hours after last forwarding state
Dec 11, 2025
8e35b10
replace Doordeweeks and Weekend with Storingsdienst
Dec 11, 2025
aa384aa
Normalize forwarding timestamps and duration rounding for accurate ha…
Dec 11, 2025
4551ace
make all the methods inside Handler in Daily.cshtml.cs internal to be…
Dec 12, 2025
f71054b
add HandlerTests.CreateWeekSlotsTests.cs
Dec 12, 2025
245d99e
add HandlerTests.RoundTimestampToNearestMinuteTests.cs
Dec 12, 2025
229df09
add HandlerTests.RoundToNearestMinuteTests.cs
Dec 12, 2025
a9f088a
make GetSlotsWithEndTime static so I can unit test it properly
Dec 12, 2025
e77a552
change the name of the classs RoundTimestampToNearestMinuteTests to R…
Dec 12, 2025
6f28ed6
change the name of the class RoundToNearestMinuteTests to RoundToNear…
Dec 12, 2025
55ba7cf
change the name of the class CreateWeekSlotsTests to CreateWeekSlots
Dec 12, 2025
0914fad
add HandlerTests.GetSlotsWithEndTime.cs
Dec 12, 2025
dea1d5c
Refactor GetResultStart so the parameter int dayOfWeek can be deleted
Dec 12, 2025
5782ef2
add HandlerTests.GetWeekSummaries.cs
Dec 12, 2025
caa216a
add // Arrange, // Act and // Assert for HandlerTests.RoundToNearestM…
Dec 12, 2025
26dddd1
add // Arrange, // Act and // Assert for HandlerTests.RoundTimestampT…
Dec 12, 2025
28ebce5
add HandlerTests.GetWeekSummaries.cs
Dec 12, 2025
dba7c40
make the method GetWeeks (inside Handle) static so I can unit test it
Dec 12, 2025
99bb4f1
rename test methods to PascalCase
Dec 12, 2025
486f650
delete unused method (Returns_Summaries_With_TotalValue_Sum) inside H…
Dec 12, 2025
1b2a708
replace Doordeweeks and Weekend with Storingsdienst
Dec 12, 2025
922c505
make all the comments in English
Dec 12, 2025
180a4eb
Translate the comments to English and remove useless comments
Dec 12, 2025
3d653c3
add HandlerTests.GetDaySummaries.cs
Dec 12, 2025
3ac2aaa
add HandlerTests.GetWeeks.cs
Dec 12, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,8 @@ packages/
lib/

.vs/

node_modules/
bower_components/

appsettings.Development.json
12 changes: 12 additions & 0 deletions SupportManager.Telegram/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"profiles": {
"SupportManager.Telegram": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:57506;http://localhost:57507"
}
}
}
93 changes: 93 additions & 0 deletions SupportManager.Web.Tests/HandlerTests.CreateWeekSlots.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
using Shouldly;
using Xunit;
using static SupportManager.Web.Areas.Teams.Pages.Report.DailyModel;

namespace SupportManager.Web.Tests
{
public partial class HandlerTests
{
public class CreateWeekSlots
{
[Fact]
public void Creates_Expected_Number_Of_Week_Slots()
{
// Act
var slots = Handler.CreateWeekSlots();

// Assert
slots.Count.ShouldBe(12);
}

[Fact]
public void First_Slot_Is_Monday_Kantooruren_At_07_30()
{
// Act
var slots = Handler.CreateWeekSlots();
var firstSlot = slots[0];

// Assert
firstSlot.GroupingKey.ShouldBe("Kantooruren");

var expectedStart = TimeSpan.FromDays(1).Add(TimeSpan.FromHours(7.5));

firstSlot.Start.ShouldBe(expectedStart);
}

[Fact]
public void Contains_Doordeweeks_Slot_At_16_30()
{
// Act
var slots = Handler.CreateWeekSlots();

var doordeweeksSlot = slots.First(s =>
s.GroupingKey == "Doordeweeks" &&
s.Start.Hours == 16 &&
s.Start.Minutes == 30);

// Assert
doordeweeksSlot.ShouldNotBeNull();
}

[Fact]
public void Contains_Three_Weekend_Slots()
{
// Act
var slots = Handler.CreateWeekSlots();

var weekendSlots = slots.Where(s => s.GroupingKey == "Weekend").ToList();

// Assert
weekendSlots.Count.ShouldBe(3);
}

[Fact]
public void Weekend_Starts_On_Friday_At_16_30()
{
// Act
var slots = Handler.CreateWeekSlots();

var weekendStart = slots.First(s => s.GroupingKey == "Weekend");

var expectedStart =TimeSpan.FromDays(5).Add(TimeSpan.FromHours(16.5));

// Assert
weekendStart.Start.ShouldBe(expectedStart);
}

[Fact]
public void Sunday_Weekend_Slot_Is_Normalized_To_Day_7()
{
// Act
var slots = Handler.CreateWeekSlots();

var sundaySlot = slots.Last(s =>
s.GroupingKey == "Weekend" &&
s.Start.Hours == 7 &&
s.Start.Minutes == 30);

// Assert
sundaySlot.Start.Days.ShouldBe(7);
}
}
}
}
149 changes: 149 additions & 0 deletions SupportManager.Web.Tests/HandlerTests.GetDaySummaries.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
using Shouldly;
using Xunit;
using static SupportManager.Web.Areas.Teams.Pages.Report.DailyModel;

namespace SupportManager.Web.Tests
{
public partial class HandlerTests
{
public class GetDaySummaries
{
[Fact]
public void Returns_One_Summary_Per_GroupingKey()
{
// Arrange
var startTime = DateTimeOffset.Now;

var day = new Result.Day
{
Slots =
[
new() { StartTime = startTime, EndTime = startTime.AddHours(1), GroupingKey = "A", Participations = [] },
new() { StartTime = startTime.AddHours(2), EndTime = startTime.AddHours(3), GroupingKey = "A", Participations = [] },
new() { StartTime = startTime.AddHours(4), EndTime = startTime.AddHours(5), GroupingKey = "B", Participations = [] },
]
};

// Act
var summaries = Handler.GetDaySummaries(day);

// Assert
summaries.Count.ShouldBe(2);
summaries.ShouldContain(s => s.GroupingKey == "A");
summaries.ShouldContain(s => s.GroupingKey == "B");
}

[Fact]
public void Sets_Duration_As_Sum_Of_Slot_Durations()
{
// Arrange
var startTime = DateTimeOffset.Now;

var day = new Result.Day
{
Slots =
[
new() { StartTime = startTime, EndTime = startTime.AddHours(2), GroupingKey = "A", Participations = [] },
new() { StartTime = startTime.AddHours(3), EndTime = startTime.AddHours(4), GroupingKey = "A", Participations = [] },
]
};

// Act
var summaries = Handler.GetDaySummaries(day);

// Assert
var summary = summaries.First(s => s.GroupingKey == "A");
summary.Duration.ShouldBe(TimeSpan.FromHours(3));
}

[Fact]
public void Aggregates_Participations_Per_User()
{
// Arrange
var startTime = DateTimeOffset.Now;

var day = new Result.Day
{
Slots =
[
new()
{
StartTime = startTime,
EndTime = startTime.AddHours(1),
GroupingKey = "A",
Participations =
[
new Result.Participation { UserName = "Miguel", Duration = TimeSpan.FromMinutes(10), FirstStart = startTime }
]
},
new()
{
StartTime = startTime.AddHours(2),
EndTime = startTime.AddHours(3),
GroupingKey = "A",
Participations =
[
new Result.Participation { UserName = "Miguel", Duration = TimeSpan.FromMinutes(20), FirstStart = startTime.AddHours(2) }
]
}
]
};

// Act
var summaries = Handler.GetDaySummaries(day);

// Assert
var summary = summaries.First(s => s.GroupingKey == "A");
summary.Participations.Count.ShouldBe(1);

var p = summary.Participations.First();
p.UserName.ShouldBe("Miguel");
p.Duration.ShouldBe(TimeSpan.FromMinutes(30));
}

[Fact]
public void Uses_Earliest_FirstStart_Per_User()
{
// Arrange
var startTime = DateTimeOffset.Now;
var later = startTime.AddHours(4);
var earlier = startTime.AddHours(1);

var day = new Result.Day
{
Slots =
[
new()
{
StartTime = startTime,
EndTime = startTime.AddHours(1),
GroupingKey = "A",
Participations =
[
new Result.Participation { UserName = "Miguel", Duration = TimeSpan.FromMinutes(10), FirstStart = later }
]
},
new()
{
StartTime = startTime.AddHours(2),
EndTime = startTime.AddHours(3),
GroupingKey = "A",
Participations =
[
new Result.Participation { UserName = "Miguel", Duration = TimeSpan.FromMinutes(20), FirstStart = earlier }
]
}
]
};

// Act
var summaries = Handler.GetDaySummaries(day);

// Assert
var summary = summaries.First(s => s.GroupingKey == "A");
var p = summary.Participations.First();
p.FirstStart.ShouldBe(earlier);
}
}
}
}
79 changes: 79 additions & 0 deletions SupportManager.Web.Tests/HandlerTests.GetSlotsWithEndTime.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using Shouldly;
using Xunit;
using static SupportManager.Web.Areas.Teams.Pages.Report.DailyModel;

namespace SupportManager.Web.Tests
{
public partial class HandlerTests
{
public class GetSlotsWithEndTime
{
[Fact]
public void Returns_One_Less_Slot_Than_Start_Times()
{
// Arrange
var week = new Result.Week();

var startTimes = new List<(Result.Week week, DateTime start, string groupingKey)>
{
(week, new DateTime(2025, 1, 1, 7, 30, 0), "A"),
(week, new DateTime(2025, 1, 1, 16, 30, 0), "B"),
(week, new DateTime(2025, 1, 2, 7, 30, 0), "C"),
};

// Act
var result = Handler.GetSlotsWithEndTime(startTimes).ToList();

// Assert
result.Count.ShouldBe(2);
}

[Fact]
public void Uses_Next_Start_Time_As_End_Time()
{
// Arrange
var week = new Result.Week();

var firstStart = new DateTime(2025, 1, 1, 7, 30, 0);

var secondStart = new DateTime(2025, 1, 1, 16, 30, 0);

var startTimes = new List<(Result.Week week, DateTime start, string groupingKey)>
{
(week, firstStart, "A"),
(week, secondStart, "B"),
};

// Act
var result = Handler.GetSlotsWithEndTime(startTimes).ToList();

var slot = result[0];

// Assert
slot.Item2.ShouldBe(firstStart);
slot.Item3.ShouldBe(secondStart);
}

[Fact]
public void Preserves_Grouping_Key_Of_Start_Slot()
{
// Arrange
var week = new Result.Week();

var startTimes = new List<(Result.Week week, DateTime start, string groupingKey)>
{
(week, new DateTime(2025, 1, 1, 7, 30, 0), "Kantooruren"),
(week, new DateTime(2025, 1, 1, 16, 30, 0), "Doordeweeks"),
};

// Act
var result = Handler.GetSlotsWithEndTime(startTimes).ToList();

var slot = result[0];

// Assert
slot.Item4.ShouldBe("Kantooruren");
}
}
}
}
Loading