Agent Tests for API, MAUI, and Slop Features

This commit is contained in:
2026-06-03 19:08:35 -04:00
parent 46150d3a69
commit 0feac0f0a0
142 changed files with 4156 additions and 1462 deletions
+3 -8
View File
@@ -1,6 +1,4 @@
using Blazor.Analytics;
namespace Services.Website;
namespace Services.Website;
public class DataCollectionKeys
{
@@ -12,15 +10,12 @@ public class DataCollectionKeys
public class DataCollectionService : IDataCollectionService, IDisposable
{
private readonly IAnalytics _globalTracking;
private readonly IStorageService _storageService;
private bool _isEnabled;
public DataCollectionService(IAnalytics globalTracking,
IStorageService storageService)
public DataCollectionService(IStorageService storageService)
{
_globalTracking = globalTracking;
_storageService = storageService;
_storageService.Subscribe(Refresh);
@@ -30,7 +25,7 @@ public class DataCollectionService : IDataCollectionService, IDisposable
public void SendEvent<T>(string eventName, T eventData)
{
if (_isEnabled) _globalTracking.TrackEvent(eventName, eventData);
// No-op
}
void IDisposable.Dispose()
+63
View File
@@ -0,0 +1,63 @@
namespace Services.Website;
public class GlossaryDialogService : IGlossaryDialogService
{
private readonly List<string> history = new();
private string? termId;
public void Subscribe(Action action)
{
OnChange += action;
}
public void Unsubscribe(Action action)
{
OnChange += action;
}
public void AddDialog(string id)
{
termId = id;
history.Add(id);
NotifyDataChanged();
}
public void CloseDialog()
{
termId = null;
history.Clear();
NotifyDataChanged();
}
public void BackDialog()
{
if (history.Count > 1)
{
history.RemoveAt(history.Count - 1);
termId = history.Count > 0 ? history.Last() : null;
NotifyDataChanged();
}
}
public bool HasDialog()
{
return termId != null;
}
public bool HasHistory()
{
return history.Count > 1;
}
public string? GetTermId()
{
return termId;
}
private event Action OnChange = null!;
private void NotifyDataChanged()
{
OnChange?.Invoke();
}
}
+103
View File
@@ -0,0 +1,103 @@
using System.Text.RegularExpressions;
using Model.Glossary;
namespace Services.Website;
public class GlossaryService : IGlossaryService
{
private List<string>? _sortedTerms;
private Dictionary<string, GlossaryTermModel>? _terms;
public GlossaryTermModel? GetTerm(string id)
{
var terms = GetAllTermsDict();
return terms.TryGetValue(id, out var term) ? term : null;
}
public List<GlossaryTermModel> SearchTerms(string query)
{
var q = query.ToLowerInvariant();
return GetAllTerms().Where(t =>
t.Term.Contains(q, StringComparison.OrdinalIgnoreCase) ||
t.ShortDefinition.Contains(q, StringComparison.OrdinalIgnoreCase) ||
t.Category.Contains(q, StringComparison.OrdinalIgnoreCase)).ToList();
}
public List<GlossaryTermModel> GetTermsByCategory(string category)
{
return GetAllTerms().Where(t =>
t.Category.Equals(category, StringComparison.OrdinalIgnoreCase)).ToList();
}
public List<GlossaryTermModel> GetAllTerms()
{
return GetAllTermsDict().Values.ToList();
}
public List<string> GetCategories()
{
return GetAllTerms().Select(t => t.Category).Distinct().ToList();
}
public string LinkifyText(string text)
{
if (string.IsNullOrEmpty(text)) return text;
var sorted = GetSortedTerms();
foreach (var term in sorted)
{
var pattern = $@"\b{Regex.Escape(term)}\b";
text = Regex.Replace(text, pattern, match =>
{
var termData = GetTermByName(term);
if (termData == null) return match.Value;
return
$"<span class=\"glossary-link\" data-glossary-id=\"{termData.Id}\">{match.Value}</span>";
});
}
return text;
}
public void Subscribe(Action action)
{
OnChange += action;
}
public void Unsubscribe(Action action)
{
OnChange += action;
}
private event Action OnChange = null!;
private void NotifyDataChanged()
{
OnChange?.Invoke();
}
private Dictionary<string, GlossaryTermModel> GetAllTermsDict()
{
_terms ??= GlossaryData.GetTerms();
return _terms;
}
private List<string> GetSortedTerms()
{
if (_sortedTerms != null) return _sortedTerms;
_sortedTerms = GetAllTerms()
.Select(t => t.Term)
.OrderByDescending(t => t.Length)
.ToList();
return _sortedTerms;
}
private GlossaryTermModel? GetTermByName(string name)
{
return GetAllTerms().FirstOrDefault(t =>
t.Term.Equals(name, StringComparison.OrdinalIgnoreCase));
}
}
+16
View File
@@ -1,4 +1,5 @@
using Model.Entity.Data;
using Model.Glossary;
using Model.Website;
using Model.Website.Data;
@@ -43,6 +44,7 @@ public class SearchService : ISearchService
Searches.Add("Pages", new List<SearchPointModel>());
Searches.Add("Notes", new List<SearchPointModel>());
Searches.Add("Entities", new List<SearchPointModel>());
Searches.Add("Glossary", new List<SearchPointModel>());
foreach (var webPage in WebsiteData.GetPages())
{
@@ -92,6 +94,20 @@ public class SearchService : ISearchService
Searches["Entities"].Add(SearchPoints.Last());
}
if (WebsiteData.allowSlopData)
foreach (var term in GlossaryData.GetTerms().Values)
{
SearchPoints.Add(new SearchPointModel
{
Title = term.Term,
PointType = "Glossary",
Summary = term.ShortDefinition,
Href = $"glossary/{term.Id}"
});
Searches["Glossary"].Add(SearchPoints.Last());
}
isLoaded = true;
NotifyDataChanged();