Skip to content

Commit

Permalink
[StatisticsService] Use implicit types (#3051)
Browse files Browse the repository at this point in the history
  • Loading branch information
imnasnainaec authored Jun 26, 2024
1 parent e8c1233 commit 34aa08d
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 78 deletions.
58 changes: 25 additions & 33 deletions Backend.Tests/Services/StatisticsServiceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,30 +18,26 @@ public class StatisticsServiceTests

private const string ProjId = "StatsServiceTestProjId";
private const string SemDomId = "StatsServiceTestSemDomId";
private readonly List<SemanticDomainTreeNode> TreeNodes = new List<SemanticDomainTreeNode>
{
new SemanticDomainTreeNode( new SemanticDomain { Id = SemDomId })
};
private readonly List<DateTime> NonEmptySchedule = new() { DateTime.Now };
private readonly List<SemanticDomainTreeNode> TreeNodes = new() { new(new SemanticDomain { Id = SemDomId }) };

private static Sense getSenseWithDomain(string semDomId = SemDomId)
private static Sense GetSenseWithDomain(string semDomId = SemDomId)
{
var semDom = new SemanticDomain { Id = semDomId };
return new Sense { SemanticDomains = new List<SemanticDomain> { semDom } };
return new() { SemanticDomains = new() { new() { Id = semDomId } } };
}
private static User getUserWithProjId(string projId = ProjId)
private static User GetUserWithProjId(string projId = ProjId)
{
var user = new User { Id = Util.RandString(10), Username = Util.RandString(10) };
user.ProjectRoles[projId] = Util.RandString(10);
return user;
}
private static Word getWordWithDomain(string semDomId = SemDomId)
private static Word GetWordWithDomain(string semDomId = SemDomId)
{
var senses = new List<Sense> { getSenseWithDomain(semDomId) };
return new Word
return new()
{
Id = Util.RandString(10),
ProjectId = ProjId,
Senses = senses,
Senses = new() { GetSenseWithDomain(semDomId) },
Vernacular = Util.RandString(10)
};
}
Expand All @@ -59,7 +55,7 @@ public void Setup()
public void GetSemanticDomainCountsTestNullDomainList()
{
// Add a word to the database and leave the semantic domain list null
_wordRepo.AddFrontier(getWordWithDomain());
_wordRepo.AddFrontier(GetWordWithDomain());

var result = _statsService.GetSemanticDomainCounts(ProjId, "").Result;
Assert.That(result, Is.Empty);
Expand All @@ -70,7 +66,7 @@ public void GetSemanticDomainCountsTestEmptyDomainList()
{
// Add to the database a word and an empty list of semantic domains
((SemanticDomainRepositoryMock)_domainRepo).SetNextResponse(new List<SemanticDomainTreeNode>());
_wordRepo.AddFrontier(getWordWithDomain());
_wordRepo.AddFrontier(GetWordWithDomain());

var result = _statsService.GetSemanticDomainCounts(ProjId, "").Result;
Assert.That(result, Is.Empty);
Expand All @@ -91,7 +87,7 @@ public void GetSemanticDomainCountsTestIdMismatch()
{
// Add to the database a semantic domain and a word with a different semantic domain
((SemanticDomainRepositoryMock)_domainRepo).SetNextResponse(TreeNodes);
_wordRepo.AddFrontier(getWordWithDomain("different-id"));
_wordRepo.AddFrontier(GetWordWithDomain("different-id"));

var result = _statsService.GetSemanticDomainCounts(ProjId, "").Result;
Assert.That(result, Has.Count.EqualTo(1));
Expand All @@ -103,7 +99,7 @@ public void GetSemanticDomainCountsTestIdMatch()
{
// Add to the database a semantic domain and a word with the same semantic domain
((SemanticDomainRepositoryMock)_domainRepo).SetNextResponse(TreeNodes);
_wordRepo.AddFrontier(getWordWithDomain());
_wordRepo.AddFrontier(GetWordWithDomain());

var result = _statsService.GetSemanticDomainCounts(ProjId, "").Result;
Assert.That(result, Has.Count.EqualTo(1));
Expand All @@ -120,44 +116,40 @@ public void GetWordsPerDayPerUserCountsTestEmptyFrontier()
[Test]
public void GetProgressEstimationLineChartRootTestEmptyFrontier()
{
var nonEmptySchedule = new List<DateTime> { DateTime.Now };

var result = _statsService.GetProgressEstimationLineChartRoot(ProjId, nonEmptySchedule).Result;
var result = _statsService.GetProgressEstimationLineChartRoot(ProjId, NonEmptySchedule).Result;
Assert.That(result.Dates, Is.Empty);
Assert.That(result.Datasets, Is.Empty);
}

[Test]
public void GetProgressEstimationLineChartRootTestEmptySchedule()
{
_wordRepo.AddFrontier(getWordWithDomain());
_wordRepo.AddFrontier(GetWordWithDomain());

var result = _statsService.GetProgressEstimationLineChartRoot(ProjId, new List<DateTime>()).Result;
var result = _statsService.GetProgressEstimationLineChartRoot(ProjId, new()).Result;
Assert.That(result.Dates, Is.Empty);
Assert.That(result.Datasets, Is.Empty);
}

[Test]
public void GetProgressEstimationLineChartRootTestNoSemanticDomainDates()
{
_wordRepo.AddFrontier(getWordWithDomain());
var nonEmptySchedule = new List<DateTime> { DateTime.Now };
_wordRepo.AddFrontier(GetWordWithDomain());

var result = _statsService.GetProgressEstimationLineChartRoot(ProjId, nonEmptySchedule).Result;
var result = _statsService.GetProgressEstimationLineChartRoot(ProjId, NonEmptySchedule).Result;
Assert.That(result.Dates, Is.Empty);
Assert.That(result.Datasets, Is.Empty);
}

[Test]
public void GetProgressEstimationLineChartRootTestSchedule()
{
var word = getWordWithDomain();
var word = GetWordWithDomain();
word.Senses[0].SemanticDomains[0].Created = DateTime.Now.ToString();
_wordRepo.AddFrontier(word);
var nonEmptySchedule = new List<DateTime> { DateTime.Now };

var result = _statsService.GetProgressEstimationLineChartRoot(ProjId, nonEmptySchedule).Result;
Assert.That(result.Dates, Has.Count.EqualTo(nonEmptySchedule.Count));
var result = _statsService.GetProgressEstimationLineChartRoot(ProjId, NonEmptySchedule).Result;
Assert.That(result.Dates, Has.Count.EqualTo(NonEmptySchedule.Count));
}

[Test]
Expand All @@ -172,9 +164,9 @@ public void GetLineChartRootDataTestNoData()
public void GetSemanticDomainUserCountsTestUsers()
{
var userCount = 4;
foreach (var i in System.Linq.Enumerable.Range(0, userCount))
foreach (var i in Enumerable.Range(0, userCount))
{
_userRepo.Create(getUserWithProjId());
_userRepo.Create(GetUserWithProjId());
}

var result = _statsService.GetSemanticDomainUserCounts(ProjId).Result;
Expand All @@ -185,11 +177,11 @@ public void GetSemanticDomainUserCountsTestUsers()
[Test]
public void GetSemanticDomainUserCountsTestDomMatchesUser()
{
var user = _userRepo.Create(getUserWithProjId()).Result!;
var user = _userRepo.Create(GetUserWithProjId()).Result!;
var wordCount = 4;
foreach (var i in System.Linq.Enumerable.Range(0, wordCount))
foreach (var i in Enumerable.Range(0, wordCount))
{
var word = getWordWithDomain();
var word = GetWordWithDomain();
word.Senses[0].SemanticDomains[0].UserId = user.Id;
_wordRepo.AddFrontier(word);
}
Expand Down
89 changes: 44 additions & 45 deletions Backend/Services/StatisticsService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,30 +28,30 @@ public StatisticsService(
/// </summary>
public async Task<List<SemanticDomainCount>> GetSemanticDomainCounts(string projectId, string lang)
{
Dictionary<string, int> hashMap = new Dictionary<string, int>();
List<SemanticDomainTreeNode>? domainTreeNodeList = await _domainRepo.GetAllSemanticDomainTreeNodes(lang);
List<Word> wordList = await _wordRepo.GetFrontier(projectId);
var hashMap = new Dictionary<string, int>();
var domainTreeNodeList = await _domainRepo.GetAllSemanticDomainTreeNodes(lang);
var wordList = await _wordRepo.GetFrontier(projectId);

if (domainTreeNodeList is null || domainTreeNodeList.Count == 0 || wordList.Count == 0)
{
return new List<SemanticDomainCount>();
return new();
}

foreach (Word word in wordList)
foreach (var word in wordList)
{
foreach (Sense sense in word.Senses)
foreach (var sense in word.Senses)
{
foreach (SemanticDomain sd in sense.SemanticDomains)
foreach (var sd in sense.SemanticDomains)
{
hashMap[sd.Id] = hashMap.GetValueOrDefault(sd.Id, 0) + 1;
}
}
}

List<SemanticDomainCount> resList = new List<SemanticDomainCount>();
foreach (SemanticDomainTreeNode domainTreeNode in domainTreeNodeList)
var resList = new List<SemanticDomainCount>();
foreach (var domainTreeNode in domainTreeNodeList)
{
resList.Add(new SemanticDomainCount(domainTreeNode, hashMap.GetValueOrDefault(domainTreeNode.Id, 0)));
resList.Add(new(domainTreeNode, hashMap.GetValueOrDefault(domainTreeNode.Id, 0)));
}
return resList;
}
Expand All @@ -61,30 +61,29 @@ public async Task<List<SemanticDomainCount>> GetSemanticDomainCounts(string proj
/// </summary>
public async Task<List<WordsPerDayPerUserCount>> GetWordsPerDayPerUserCounts(string projectId)
{
List<Word> wordList = await _wordRepo.GetFrontier(projectId);
Dictionary<string, WordsPerDayPerUserCount> shortTimeDictionary =
new Dictionary<string, WordsPerDayPerUserCount>();
Dictionary<string, string> userNameIdDictionary = new Dictionary<string, string>();
var wordList = await _wordRepo.GetFrontier(projectId);
var shortTimeDictionary = new Dictionary<string, WordsPerDayPerUserCount>();
var userNameIdDictionary = new Dictionary<string, string>();

if (wordList.Count == 0)
{
return new List<WordsPerDayPerUserCount>();
return new();
}

var allUsers = await _userRepo.GetAllUsers();
var projectUsers = allUsers.FindAll(user => user.ProjectRoles.ContainsKey(projectId));

// only count for current valid users of the project
foreach (User u in projectUsers)
foreach (var u in projectUsers)
{
userNameIdDictionary.Add(u.Id, u.Username);
}

foreach (Word word in wordList)
foreach (var word in wordList)
{
foreach (Sense sense in word.Senses)
foreach (var sense in word.Senses)
{
foreach (SemanticDomain sd in sense.SemanticDomains)
foreach (var sd in sense.SemanticDomains)
{
// The created timestamp may not exist for some model
if (!string.IsNullOrEmpty(sd.Created))
Expand Down Expand Up @@ -125,10 +124,10 @@ public async Task<List<WordsPerDayPerUserCount>> GetWordsPerDayPerUserCounts(str
/// </summary>
public async Task<ChartRootData> GetProgressEstimationLineChartRoot(string projectId, List<DateTime> schedule)
{
ChartRootData LineChartData = new ChartRootData();
List<Word> wordList = await _wordRepo.GetFrontier(projectId);
List<string> workshopSchedule = new List<string>();
Dictionary<string, int> totalCountDictionary = new Dictionary<string, int>();
var LineChartData = new ChartRootData();
var wordList = await _wordRepo.GetFrontier(projectId);
var workshopSchedule = new List<string>();
var totalCountDictionary = new Dictionary<string, int>();

// If no schedule yet or wordList is empty, return empty ChartRootData
if (schedule.Count == 0 || wordList.Count == 0)
Expand All @@ -137,17 +136,17 @@ public async Task<ChartRootData> GetProgressEstimationLineChartRoot(string proje
}

// Build workshop schedule hashSet
foreach (DateTime dt in schedule)
foreach (var dt in schedule)
{
workshopSchedule.Add(dt.ToISO8601TimeFormatDateOnlyString());
}

// Build daily count Dictionary
foreach (Word word in wordList)
foreach (var word in wordList)
{
foreach (Sense sense in word.Senses)
foreach (var sense in word.Senses)
{
foreach (SemanticDomain sd in sense.SemanticDomains)
foreach (var sd in sense.SemanticDomains)
{

if (!string.IsNullOrEmpty(sd.Created))
Expand Down Expand Up @@ -206,11 +205,11 @@ public async Task<ChartRootData> GetProgressEstimationLineChartRoot(string proje
if (LineChartData.Datasets.Count == 0)
{
runningTotal = yesterday = today;
LineChartData.Datasets.Add(new Dataset("Daily Total", today));
LineChartData.Datasets.Add(new Dataset("Average", averageValue));
LineChartData.Datasets.Add(new Dataset("Running Total", runningTotal));
LineChartData.Datasets.Add(new Dataset("Projection", projection));
LineChartData.Datasets.Add(new Dataset("Burst Projection", runningTotal));
LineChartData.Datasets.Add(new("Daily Total", today));
LineChartData.Datasets.Add(new("Average", averageValue));
LineChartData.Datasets.Add(new("Running Total", runningTotal));
LineChartData.Datasets.Add(new("Projection", projection));
LineChartData.Datasets.Add(new("Burst Projection", runningTotal));
}
else
{
Expand Down Expand Up @@ -247,16 +246,16 @@ public async Task<ChartRootData> GetProgressEstimationLineChartRoot(string proje
/// </summary>
public async Task<ChartRootData> GetLineChartRootData(string projectId)
{
ChartRootData LineChartData = new ChartRootData();
List<WordsPerDayPerUserCount> list = await GetWordsPerDayPerUserCounts(projectId);
var LineChartData = new ChartRootData();
var list = await GetWordsPerDayPerUserCounts(projectId);
// if the list is null or empty return new ChartRootData to generate a empty Chart
if (list is null || list.Count == 0)
{
return LineChartData;
}

// update the ChartRootData based on the order of the WordsPerDayPerUserCount from the list
foreach (WordsPerDayPerUserCount temp in list)
foreach (var temp in list)
{
LineChartData.Dates.Add(temp.DateTime.ToISO8601TimeFormatDateOnlyString());
// first traversal, generate a new Dataset
Expand All @@ -266,10 +265,10 @@ public async Task<ChartRootData> GetLineChartRootData(string projectId)
foreach (var item in temp.UserNameCountDictionary)
{
totalDay += item.Value;
LineChartData.Datasets.Add(new Dataset(item.Key, item.Value));
LineChartData.Datasets.Add(new(item.Key, item.Value));
}
// update "Total", Line Chart needed
LineChartData.Datasets.Add(new Dataset("Daily Total", totalDay));
LineChartData.Datasets.Add(new("Daily Total", totalDay));
}
// remaining traversal, update the object by pushing the value to Data array
else
Expand All @@ -295,29 +294,29 @@ public async Task<ChartRootData> GetLineChartRootData(string projectId)
/// <returns> A List of SemanticDomainUserCount <see cref="SemanticDomainUserCount"/> </returns>
public async Task<List<SemanticDomainUserCount>> GetSemanticDomainUserCounts(string projectId)
{
List<Word> wordList = await _wordRepo.GetFrontier(projectId);
Dictionary<string, SemanticDomainUserCount> resUserMap = new Dictionary<string, SemanticDomainUserCount>();
var wordList = await _wordRepo.GetFrontier(projectId);
var resUserMap = new Dictionary<string, SemanticDomainUserCount>();

// Get all users of the project
var allUsers = await _userRepo.GetAllUsers();
var projectUsers = allUsers.FindAll(user => user.ProjectRoles.ContainsKey(projectId));

// build a SemanticDomainUserCount object hashMap with userId as the key
foreach (User u in projectUsers)
foreach (var u in projectUsers)
{
resUserMap.Add(u.Id, new SemanticDomainUserCount(u.Id, u.Username));
resUserMap.Add(u.Id, new(u.Id, u.Username));
}

// unknownUser is for legacy data without a userId under SemanticDomain model
var unknownId = "unknownUserId";
var unknownName = "unknownUser";
resUserMap.Add(unknownId, new SemanticDomainUserCount(unknownId, unknownName));
resUserMap.Add(unknownId, new(unknownId, unknownName));

foreach (Word word in wordList)
foreach (var word in wordList)
{
foreach (Sense sense in word.Senses)
foreach (var sense in word.Senses)
{
foreach (SemanticDomain sd in sense.SemanticDomains)
foreach (var sd in sense.SemanticDomains)
{
var userId = sd.UserId;
var domainName = sd.Name;
Expand Down

0 comments on commit 34aa08d

Please sign in to comment.