Skip to content
This repository has been archived by the owner on Aug 28, 2022. It is now read-only.

refactor: decompose division #65

Merged
merged 14 commits into from
Nov 23, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
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
2 changes: 1 addition & 1 deletion Source/SeaInk.Core/APIs/IUniversitySystemApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public interface IUniversitySystemApi
StudyAssignment GetStudyAssignment(int id);
Subject GetSubject(int id);
StudentAssignmentProgress GetStudentAssignmentProgress(int studentId, int assignmentId);
Division GetDivision(int mentorId, int subjectId);
StudyGroupSubject GetStudyGroupSubject(int mentorId, int subjectId);

void SaveUser(User user);
void SaveStudent(Student student);
Expand Down
4 changes: 1 addition & 3 deletions Source/SeaInk.Core/Entities/Division.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ public class Division: IEntity

public string Title { get; set; }
public string SpreadsheetId { get; set; }
public virtual Mentor Mentor { get; set; }
public virtual Subject Subject { get; set; }
public virtual List<StudyGroup> Groups { get; set; } = new();
public virtual List<StudyGroupSubject> StudyGroupSubjects { get; set; } = new();
}
}
4 changes: 2 additions & 2 deletions Source/SeaInk.Core/Entities/Mentor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

namespace SeaInk.Core.Entities
{
public class Mentor: User
public class Mentor : User
ronimizy marked this conversation as resolved.
Show resolved Hide resolved
{
public virtual List<Division> Divisions { get; set; } = new();
public virtual List<StudyGroupSubject> StudyGroupSubjects { get; set; } = new();
}
}
13 changes: 13 additions & 0 deletions Source/SeaInk.Core/Entities/StudyGroupSubject.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System.Collections.Generic;

namespace SeaInk.Core.Entities
{
public class StudyGroupSubject : IEntity
{
public int Id { get; set; }

public virtual StudyGroup StudyGroup { get; set; }
public virtual Subject Subject { get; set; }
public virtual List<Mentor> Mentors { get; set; }
}
}
10 changes: 2 additions & 8 deletions Source/SeaInk.Endpoints.Shared/Dto/DivisionDto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@ public record DivisionDto(
int Id,
string Title,
string SpreadsheetId,
int MentorId,
string MentorName,
SubjectDto Subject,
IReadOnlyList<StudyGroupDto> Groups);
IReadOnlyList<StudyGroupSubjectDto> StudyGroupSubjects);

public static class DivisionExtension
{
Expand All @@ -20,10 +17,7 @@ public static DivisionDto ToDto(this Division division)
return new DivisionDto(division.Id,
division.Title,
division.SpreadsheetId,
division.Mentor.Id,
division.Mentor.FullName,
division.Subject.ToDto(),
division.Groups.Select(g => g.ToDto()).ToList());
division.StudyGroupSubjects.Select(s => s.ToDto()).ToList());
}
}
}
16 changes: 2 additions & 14 deletions Source/SeaInk.Endpoints.Shared/Dto/MentorDto.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using MoreLinq;
using SeaInk.Core.Entities;

namespace SeaInk.Endpoints.Shared.Dto
Expand All @@ -12,10 +11,7 @@ public record MentorDto(
string LastName,
string MiddleName,
string FullName,
//SubjectId -> Subject
IReadOnlyDictionary<int, SubjectDto> Subjects,
//SubjectId -> Divisions
IReadOnlyDictionary<int, IReadOnlyList<DivisionDto>> Divisions);
List<StudyGroupSubjectDto> StudyGroupSubjects);

public static class MentorExtension
{
Expand All @@ -27,15 +23,7 @@ public static MentorDto ToDto(this Mentor mentor)
mentor.LastName,
mentor.MiddleName,
mentor.FullName,
mentor.Divisions
.Select(d => d.Subject)
.DistinctBy(s => s.Id)
.ToDictionary(s => s.Id, s => s.ToDto()),
mentor.Divisions
.GroupBy(d => d.Subject)
.ToDictionary(g => g.Key.Id,
g => g.Select(d => d.ToDto())
.ToList() as IReadOnlyList<DivisionDto>));
mentor.StudyGroupSubjects.Select(s => s.ToDto()).ToList());
}
}
}
26 changes: 26 additions & 0 deletions Source/SeaInk.Endpoints.Shared/Dto/StudyGroupSubjectDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System.Collections.Generic;
using System.Linq;
using SeaInk.Core.Entities;

namespace SeaInk.Endpoints.Shared.Dto
{
public record StudyGroupSubjectDto(
int Id,
StudyGroupDto StudyGroup,
SubjectDto Subject,
List<int> MentorIds)
{
}
FrediKats marked this conversation as resolved.
Show resolved Hide resolved

public static class StudyGroupSubjectExtension
{
public static StudyGroupSubjectDto ToDto(this StudyGroupSubject studyGroupSubject)
{
return new StudyGroupSubjectDto(
studyGroupSubject.Id,
studyGroupSubject.StudyGroup.ToDto(),
studyGroupSubject.Subject.ToDto(),
studyGroupSubject.Mentors.Select(m => m.Id).ToList());
}
}
}
3 changes: 3 additions & 0 deletions Source/SeaInk.Endpoints/Client/Client/MentorClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,8 @@ public Task<MentorDto> GetMentorAsync(int mentorId)

public Task<IReadOnlyList<SubjectDto>> GetSubjectsAsync(int mentorId)
=> GetValueAsync<IReadOnlyList<SubjectDto>>($"/mentors/{mentorId}/subjects");

public Task<IReadOnlyList<DivisionDto>> GetDivisionsAsync(int mentorId)
=> GetValueAsync<IReadOnlyList<DivisionDto>>($"/mentors/{mentorId}/divisions");
}
}
15 changes: 10 additions & 5 deletions Source/SeaInk.Endpoints/Client/Pages/Groups/GroupsPage.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using MoreLinq;
using SeaInk.Endpoints.Client.Client;
using SeaInk.Endpoints.Shared.Dto;

Expand All @@ -27,7 +28,8 @@ protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
_currentMentor = await Client.GetCurrentMentorAsync();
_subjects = _currentMentor.Subjects.Values.ToList();
_divisions = await Client.GetDivisionsAsync(_currentMentor.Id);
_subjects = _currentMentor.StudyGroupSubjects.Select(sgs => sgs.Subject).ToList();

if (_subjects.Count != 0)
OnSelectedSubjectChanged(_subjects[0].Id);
Expand All @@ -36,7 +38,6 @@ protected override async Task OnInitializedAsync()
private void OnSelectedSubjectChanged(int subjectId)
{
_selectedSubjectId = subjectId;
_divisions = _currentMentor.Divisions[_selectedSubjectId];

if (_divisions.Count != 0)
OnSelectedDivisionChanged(_divisions[0].Id);
Expand All @@ -45,9 +46,13 @@ private void OnSelectedSubjectChanged(int subjectId)
private void OnSelectedDivisionChanged(int divisionId)
{
_selectedDivisionId = divisionId;
_groups = _currentMentor.Divisions[_selectedSubjectId]
.Single(d => d.Id == _selectedDivisionId)
.Groups;
_groups = _divisions
.Where(d => d.Id == divisionId)
.SelectMany(d => d.StudyGroupSubjects)
.Where(sgs => sgs.Subject.Id == _selectedSubjectId)
.Select(sgs => sgs.StudyGroup)
.DistinctBy(g => g.Id)
.ToList();

if (_groups.Count == 0)
return;
Expand Down
19 changes: 17 additions & 2 deletions Source/SeaInk.Endpoints/Server/Controllers/MentorController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public MentorController(DatabaseContext databaseContext)
[HttpGet("current")]
public IActionResult GetCurrentMentor()
{
Mentor mentor = _databaseContext.Mentors.MaxBy(m => m.Divisions.Count);
Mentor mentor = _databaseContext.Mentors.MaxBy(m => m.StudyGroupSubjects.Count);
return Ok(mentor.ToDto());
}

Expand All @@ -43,13 +43,28 @@ public IActionResult GetSubjects(int mentorId)
if (mentor is null)
return NotFound();

List<SubjectDto> subjects = mentor.Divisions
List<SubjectDto> subjects = mentor.StudyGroupSubjects
.Select(d => d.Subject)
.DistinctBy(s => s.Id)
.Select(s => s.ToDto())
.ToList();

return Ok(subjects);
}

[HttpGet("{mentorId:int}/divisions")]
public ActionResult<List<DivisionDto>> GetDivisions(int mentorId)
{
Mentor mentor = _databaseContext.Mentors.Find(mentorId);
if (mentor is null)
return NotFound();

List<DivisionDto> divisions = _databaseContext.Divisions
.Where(d => d.StudyGroupSubjects.Any(sgs => sgs.Mentors.Any(m => m.Id == mentorId)))
.Select(d => d.ToDto())
.ToList();

return Ok(divisions);
}
}
}
27 changes: 18 additions & 9 deletions Source/SeaInk.Infrastructure/APIs/FakeUniversitySystemApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,11 +169,18 @@ public FakeUniversitySystemApi(int mentorCount = 1)
.CustomInstantiator(faker => new Division
{
SpreadsheetId = faker.Internet.Url(),
Subject = faker.Random.ArrayElement(Subjects.ToArray()),
Mentor = faker.Random.ArrayElement(Mentors.ToArray()),
Groups = faker.Random.ArrayElements(Groups.ToArray(), faker.Random.Int(1, 4)).ToList()
StudyGroupSubjects = faker.Random
.ArrayElements(Groups.ToArray(), faker.Random.Int(1, 4))
.Select(group => new StudyGroupSubject
{
Id = faker.IndexFaker++,
StudyGroup = group,
Subject = faker.Random.ArrayElement(Subjects.ToArray()),
Mentors = new List<Mentor>() { faker.Random.ArrayElement(Mentors.ToArray()) }
})
.ToList()
})
.FinishWith((_, d) => { d.Mentor.Divisions.Add(d); });
.FinishWith((_, d) => { d.StudyGroupSubjects.ForEach(sgs => sgs.Mentors.ForEach(m => m.StudyGroupSubjects.Add(sgs))); });

GenerateInitialData(mentorCount);
}
Expand Down Expand Up @@ -255,12 +262,14 @@ public StudentAssignmentProgress GetStudentAssignmentProgress(int studentId, int
.SingleOrDefault(p => p.Student.UniversityId == studentId && p.Assignment.UniversityId == assignmentId);
}

public Division GetDivision(int mentorId, int subjectId)
//TODO: rework implementation
ronimizy marked this conversation as resolved.
Show resolved Hide resolved
public StudyGroupSubject GetStudyGroupSubject(int mentorId, int subjectId)
{
Interlocked.Increment(ref _totalCallCount);
Interlocked.Increment(ref _getDivisionCallCount);
Log?.Invoke("Got division");
return Divisions.SingleOrDefault(d => d.Mentor.UniversityId == mentorId && d.Subject.UniversityId == subjectId);
throw new NotImplementedException();
//Interlocked.Increment(ref _totalCallCount);
//Interlocked.Increment(ref _getDivisionCallCount);
//Log?.Invoke("Got division");
//return Divisions.SingleOrDefault(d => d.Mentor.UniversityId == mentorId && d.Subject.UniversityId == subjectId);
}

public void SaveUser(User user)
Expand Down
1 change: 1 addition & 0 deletions Source/SeaInk.Infrastructure/Database/DatabaseContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public sealed class DatabaseContext: DbContext
public DbSet<Division> Divisions { get; private set; }
public DbSet<Subject> Subjects { get; private set; }
public DbSet<StudyGroup> StudyGroups { get; private set; }
public DbSet<StudyGroupSubject> StudyGroupSubjects { get; private set; }

public DbSet<StudyAssignment> StudyAssignments { get; private set; }
public DbSet<StudentAssignmentProgress> StudentAssignmentProgresses { get; private set; }
Expand Down
44 changes: 0 additions & 44 deletions Source/SeaInk.Tests.Infrastructure/EntityFrameworkTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,49 +40,5 @@ public void StudentAssignmentProgressRepositoryTest_SAP_AddedToDatabase()
Assert.AreEqual(progress.Progress, createdProgress.Progress);
Assert.AreEqual(progress.Student.Id, createdProgress.Student.Id);
}

[Test]
public void DivisionRepositoryTest_DivisionAddedToDatabase()
{
DbSet<Division> repository = _context.Divisions;

Division division = _api.Divisions.First();
repository.Add(division);
_context.SaveChanges();

Division createdDivision = repository.Find(division.Id);

Assert.NotNull(createdDivision);
Assert.AreEqual(division.Id, createdDivision.Id);
Assert.AreEqual(division.Mentor.Id, createdDivision.Mentor.Id);
Assert.AreEqual(division.Mentor.UniversityId, createdDivision.Mentor.UniversityId);
Assert.AreEqual(division.Subject.Id, createdDivision.Subject.Id);
Assert.AreEqual(division.Subject.UniversityId, createdDivision.Subject.UniversityId);
Assert.True(division.Groups.ToIds().ToHashSet()
.SetEquals(createdDivision.Groups.ToIds()));

List<(StudyGroup found, StudyGroup created)> matchedGroups = division.Groups
.Select(f => (f, createdDivision.Groups.Single(c => c.Id == f.Id))).ToList();

foreach (var groupPair in matchedGroups)
{
Assert.AreEqual(groupPair.found.Name, groupPair.created.Name);
Assert.AreEqual(groupPair.found.AdminId, groupPair.created.AdminId);
Assert.AreEqual(groupPair.found.UniversityId, groupPair.created.UniversityId);
Assert.True(groupPair.found.Students.ToIds().ToHashSet()
.SetEquals(groupPair.created.Students.ToIds()));

List<(Student found, Student created)> matchedStudents = groupPair.found.Students
.Select(f => (f, groupPair.created.Students.Single(c => c.Id == f.Id))).ToList();

foreach (var studentPair in matchedStudents)
{
Assert.AreEqual(studentPair.found.FirstName, studentPair.created.FirstName);
Assert.AreEqual(studentPair.found.MiddleName, studentPair.created.MiddleName);
Assert.AreEqual(studentPair.found.LastName, studentPair.created.LastName);
Assert.AreEqual(studentPair.found.UniversityId, studentPair.created.UniversityId);
}
}
}
}
}