Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 86
feat(training): Add edit functionality for training module#319
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
ada0e5571726021ead6ab6aae0cd923c2b6c2a3e6d9c35c064c21f2c91e01fb22a731285bf4d3de7ac44b1c15a44eae821d84dcfc52798f9903359dabdc4b3a0ec5c01c663052e31931e28e4429898d66a39494cbcc39549f1828790b172c98f6ff449fbda770165a29c71e226f7f95ee99378b83647ad014b4881f3cc3cb232bdc73c44d2bb07d5833e394d0abb4a2c96c5ea7d8b6e926a2b3acd4eaa86b7da55257211f183a27997b6e260f3015e69a83737b2a220ead0799b28a253d69a97648552acee808d30e5ad482d4a7803fac2b43edc0423a4fde6963535b0ea711e8b3f079d0d01c089727e54e54b00298b09b713677c0f606fe52df83184356ce9b5e9ebe4a8de43eacf2acc736bee909879069179f1da63abf509d389a67d37f7ffd8b6d308953a5b03393ba417cce3c4f3e41cf5115a62cb9c1c752dcedecf4ef7f291514441e4c5be1a0db64c3060956f96fa79b70aa31606ee0dbbce636beef8b79bf71d0f57208981666282809597f5ab14a5d4a8aFile filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,103 @@ | ||
| using System.Collections.Generic; | ||
| using System.Linq; | ||
| using System.Threading; | ||
| using System.Threading.Tasks; | ||
| using Resgrid.Model; | ||
| using Resgrid.Model.Repositories; | ||
| namespace Resgrid.Tests.Mocks | ||
| { | ||
| /// <summary> | ||
| /// In-memory mock for <see cref="ITrainingAttachmentRepository"/> | ||
| /// </summary> | ||
| public sealed class MockTrainingAttachmentRepository : ITrainingAttachmentRepository | ||
| { | ||
| private readonly List<TrainingAttachment> _attachments = new List<TrainingAttachment>(); | ||
| private int _nextId = 1; | ||
| public Task<IEnumerable<TrainingAttachment>> GetAllAsync() | ||
| => Task.FromResult<IEnumerable<TrainingAttachment>>(_attachments.ToList()); | ||
| public Task<TrainingAttachment> GetByIdAsync(object id) | ||
| { | ||
| var intId = (int)id; | ||
| var attachment = _attachments.FirstOrDefault(a => a.TrainingAttachmentId == intId); | ||
| return Task.FromResult(attachment); | ||
| } | ||
| public Task<IEnumerable<TrainingAttachment>> GetAllByDepartmentIdAsync(int departmentId) | ||
| => Task.FromResult<IEnumerable<TrainingAttachment>>(new List<TrainingAttachment>()); | ||
| public Task<IEnumerable<TrainingAttachment>> GetAllByUserIdAsync(string userId) | ||
| => Task.FromResult<IEnumerable<TrainingAttachment>>(new List<TrainingAttachment>()); | ||
| public Task<TrainingAttachment> InsertAsync(TrainingAttachment entity, CancellationToken cancellationToken, bool firstLevelOnly = false) | ||
| { | ||
| entity.TrainingAttachmentId = _nextId++; | ||
| _attachments.Add(entity); | ||
| return Task.FromResult(entity); | ||
| } | ||
| public Task<TrainingAttachment> UpdateAsync(TrainingAttachment entity, CancellationToken cancellationToken, bool firstLevelOnly = false) | ||
| { | ||
| var existing = _attachments.FirstOrDefault(a => a.TrainingAttachmentId == entity.TrainingAttachmentId); | ||
| if (existing != null) | ||
| { | ||
| _attachments.Remove(existing); | ||
| } | ||
| _attachments.Add(entity); | ||
| return Task.FromResult(entity); | ||
| } | ||
| public Task<bool> DeleteAsync(TrainingAttachment entity, CancellationToken cancellationToken) | ||
| { | ||
| var existing = _attachments.FirstOrDefault(a => a.TrainingAttachmentId == entity.TrainingAttachmentId); | ||
| if (existing != null) | ||
| { | ||
| _attachments.Remove(existing); | ||
| } | ||
| return Task.FromResult(true); | ||
| } | ||
| public Task<TrainingAttachment> SaveOrUpdateAsync(TrainingAttachment entity, CancellationToken cancellationToken, bool firstLevelOnly = false) | ||
| { | ||
| if (entity.TrainingAttachmentId == 0) | ||
| { | ||
| entity.TrainingAttachmentId = _nextId++; | ||
| _attachments.Add(entity); | ||
| } | ||
| else | ||
| { | ||
| var existing = _attachments.FirstOrDefault(a => a.TrainingAttachmentId == entity.TrainingAttachmentId); | ||
| if (existing != null) | ||
| { | ||
| _attachments.Remove(existing); | ||
| } | ||
| _attachments.Add(entity); | ||
| } | ||
| return Task.FromResult(entity); | ||
| } | ||
| public Task<bool> DeleteMultipleAsync(TrainingAttachment entity, string parentKeyName, object parentKeyId, List<object> ids, CancellationToken cancellationToken) | ||
| => Task.FromResult(true); | ||
| public Task<IEnumerable<TrainingAttachment>> GetTrainingAttachmentsByTrainingIdAsync(int trainingId) | ||
| { | ||
| var result = _attachments.Where(a => a.TrainingId == trainingId).ToList(); | ||
| return Task.FromResult<IEnumerable<TrainingAttachment>>(result); | ||
| } | ||
| public void SeedAttachment(TrainingAttachment attachment) | ||
| { | ||
| if (attachment.TrainingAttachmentId == 0) | ||
| { | ||
| attachment.TrainingAttachmentId = _nextId++; | ||
| } | ||
| else | ||
| { | ||
| _nextId = System.Math.Max(_nextId, attachment.TrainingAttachmentId + 1); | ||
| } | ||
| _attachments.Add(attachment); | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,103 @@ | ||
| using System.Collections.Generic; | ||
| using System.Linq; | ||
| using System.Threading; | ||
| using System.Threading.Tasks; | ||
| using Resgrid.Model; | ||
| using Resgrid.Model.Repositories; | ||
| namespace Resgrid.Tests.Mocks | ||
| { | ||
| /// <summary> | ||
| /// In-memory mock for <see cref="ITrainingQuestionRepository"/> | ||
| /// </summary> | ||
| public sealed class MockTrainingQuestionRepository : ITrainingQuestionRepository | ||
| { | ||
| private readonly List<TrainingQuestion> _questions = new List<TrainingQuestion>(); | ||
| private int _nextId = 1; | ||
| public Task<IEnumerable<TrainingQuestion>> GetAllAsync() | ||
| => Task.FromResult<IEnumerable<TrainingQuestion>>(_questions.ToList()); | ||
| public Task<TrainingQuestion> GetByIdAsync(object id) | ||
| { | ||
| var intId = (int)id; | ||
| var question = _questions.FirstOrDefault(q => q.TrainingQuestionId == intId); | ||
| return Task.FromResult(question); | ||
| } | ||
| public Task<IEnumerable<TrainingQuestion>> GetAllByDepartmentIdAsync(int departmentId) | ||
| => Task.FromResult<IEnumerable<TrainingQuestion>>(new List<TrainingQuestion>()); | ||
| public Task<IEnumerable<TrainingQuestion>> GetAllByUserIdAsync(string userId) | ||
| => Task.FromResult<IEnumerable<TrainingQuestion>>(new List<TrainingQuestion>()); | ||
| public Task<TrainingQuestion> InsertAsync(TrainingQuestion entity, CancellationToken cancellationToken, bool firstLevelOnly = false) | ||
| { | ||
| entity.TrainingQuestionId = _nextId++; | ||
| _questions.Add(entity); | ||
| return Task.FromResult(entity); | ||
| } | ||
| public Task<TrainingQuestion> UpdateAsync(TrainingQuestion entity, CancellationToken cancellationToken, bool firstLevelOnly = false) | ||
| { | ||
| var existing = _questions.FirstOrDefault(q => q.TrainingQuestionId == entity.TrainingQuestionId); | ||
| if (existing != null) | ||
| { | ||
| _questions.Remove(existing); | ||
| } | ||
| _questions.Add(entity); | ||
| return Task.FromResult(entity); | ||
| } | ||
| public Task<bool> DeleteAsync(TrainingQuestion entity, CancellationToken cancellationToken) | ||
| { | ||
| var existing = _questions.FirstOrDefault(q => q.TrainingQuestionId == entity.TrainingQuestionId); | ||
| if (existing != null) | ||
| { | ||
| _questions.Remove(existing); | ||
| } | ||
| return Task.FromResult(true); | ||
| } | ||
| public Task<TrainingQuestion> SaveOrUpdateAsync(TrainingQuestion entity, CancellationToken cancellationToken, bool firstLevelOnly = false) | ||
| { | ||
| if (entity.TrainingQuestionId == 0) | ||
| { | ||
| entity.TrainingQuestionId = _nextId++; | ||
| _questions.Add(entity); | ||
| } | ||
| else | ||
| { | ||
| var existing = _questions.FirstOrDefault(q => q.TrainingQuestionId == entity.TrainingQuestionId); | ||
| if (existing != null) | ||
| { | ||
| _questions.Remove(existing); | ||
| } | ||
| _questions.Add(entity); | ||
| } | ||
| return Task.FromResult(entity); | ||
| } | ||
| public Task<bool> DeleteMultipleAsync(TrainingQuestion entity, string parentKeyName, object parentKeyId, List<object> ids, CancellationToken cancellationToken) | ||
| => Task.FromResult(true); | ||
| public Task<IEnumerable<TrainingQuestion>> GetTrainingQuestionsByTrainingIdAsync(int trainingId) | ||
| { | ||
| var result = _questions.Where(q => q.TrainingId == trainingId).ToList(); | ||
| return Task.FromResult<IEnumerable<TrainingQuestion>>(result); | ||
| } | ||
| public void SeedQuestion(TrainingQuestion question) | ||
| { | ||
| if (question.TrainingQuestionId == 0) | ||
| { | ||
| question.TrainingQuestionId = _nextId++; | ||
| } | ||
| else | ||
| { | ||
| _nextId = System.Math.Max(_nextId, question.TrainingQuestionId + 1); | ||
| } | ||
| _questions.Add(question); | ||
| } | ||
Comment on lines
+90
to
+101
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Seeding the same Proposed fix public void SeedQuestion(TrainingQuestion question)
{
+ var existing = _questions.FirstOrDefault(q => q.TrainingQuestionId == question.TrainingQuestionId);+ if (existing != null)+ {+ _questions.Remove(existing);+ }+
if (question.TrainingQuestionId == 0)
{
question.TrainingQuestionId = _nextId++;
}
else
{
_nextId = System.Math.Max(_nextId, question.TrainingQuestionId + 1);
}
_questions.Add(question);
}🤖 Prompt for AI Agents | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,121 @@ | ||
| using System.Collections.Generic; | ||
| using System.Linq; | ||
| using System.Threading; | ||
| using System.Threading.Tasks; | ||
| using Resgrid.Model; | ||
| using Resgrid.Model.Repositories; | ||
| namespace Resgrid.Tests.Mocks | ||
| { | ||
| /// <summary> | ||
| /// In-memory mock for <see cref="ITrainingRepository"/> that stores trainings | ||
| /// without requiring a database connection. | ||
| /// </summary> | ||
| public sealed class MockTrainingRepository : ITrainingRepository | ||
| { | ||
| private readonly List<Training> _trainings = new List<Training>(); | ||
| private int _nextId = 1; | ||
| public List<Training> Trainings => _trainings; | ||
| public Task<IEnumerable<Training>> GetAllAsync() | ||
| => Task.FromResult<IEnumerable<Training>>(_trainings.ToList()); | ||
| public Task<Training> GetByIdAsync(object id) | ||
| { | ||
| var intId = (int)id; | ||
| var training = _trainings.FirstOrDefault(t => t.TrainingId == intId); | ||
| return Task.FromResult(training); | ||
| } | ||
| public Task<IEnumerable<Training>> GetAllByDepartmentIdAsync(int departmentId) | ||
| { | ||
| var result = _trainings.Where(t => t.DepartmentId == departmentId).ToList(); | ||
| return Task.FromResult<IEnumerable<Training>>(result); | ||
| } | ||
| public Task<IEnumerable<Training>> GetAllByUserIdAsync(string userId) | ||
| => Task.FromResult<IEnumerable<Training>>(new List<Training>()); | ||
| public Task<Training> InsertAsync(Training entity, CancellationToken cancellationToken, bool firstLevelOnly = false) | ||
| { | ||
| entity.TrainingId = _nextId++; | ||
| _trainings.Add(entity); | ||
| return Task.FromResult(entity); | ||
| } | ||
| public Task<Training> UpdateAsync(Training entity, CancellationToken cancellationToken, bool firstLevelOnly = false) | ||
| { | ||
| var existing = _trainings.FirstOrDefault(t => t.TrainingId == entity.TrainingId); | ||
| if (existing != null) | ||
| { | ||
| _trainings.Remove(existing); | ||
| } | ||
| _trainings.Add(entity); | ||
| return Task.FromResult(entity); | ||
| } | ||
| public Task<bool> DeleteAsync(Training entity, CancellationToken cancellationToken) | ||
| { | ||
| var existing = _trainings.FirstOrDefault(t => t.TrainingId == entity.TrainingId); | ||
| if (existing != null) | ||
| { | ||
| _trainings.Remove(existing); | ||
| } | ||
| return Task.FromResult(true); | ||
| } | ||
| public Task<Training> SaveOrUpdateAsync(Training entity, CancellationToken cancellationToken, bool firstLevelOnly = false) | ||
| { | ||
| if (entity.TrainingId == 0) | ||
| { | ||
| entity.TrainingId = _nextId++; | ||
| _trainings.Add(entity); | ||
| } | ||
| else | ||
| { | ||
| var existing = _trainings.FirstOrDefault(t => t.TrainingId == entity.TrainingId); | ||
| if (existing != null) | ||
| { | ||
| _trainings.Remove(existing); | ||
| } | ||
| _trainings.Add(entity); | ||
| } | ||
| return Task.FromResult(entity); | ||
| } | ||
| public Task<bool> DeleteMultipleAsync(Training entity, string parentKeyName, object parentKeyId, List<object> ids, CancellationToken cancellationToken) | ||
| => Task.FromResult(true); | ||
| public List<Training> GetAllTrainings() | ||
| => _trainings.ToList(); | ||
| public Task<IEnumerable<Training>> GetTrainingsByDepartmentIdAsync(int departmentId) | ||
| { | ||
| var result = _trainings.Where(t => t.DepartmentId == departmentId).ToList(); | ||
| return Task.FromResult<IEnumerable<Training>>(result); | ||
| } | ||
| public Task<Training> GetTrainingByTrainingIdAsync(int trainingId) | ||
| { | ||
| var training = _trainings.FirstOrDefault(t => t.TrainingId == trainingId); | ||
| return Task.FromResult(training); | ||
| } | ||
| /// <summary> | ||
| /// Helper method to seed test data | ||
| /// </summary> | ||
| public void SeedTraining(Training training) | ||
| { | ||
| if (training.TrainingId == 0) | ||
| { | ||
| training.TrainingId = _nextId++; | ||
| } | ||
| else | ||
| { | ||
| _nextId = System.Math.Max(_nextId, training.TrainingId + 1); | ||
| } | ||
| _trainings.Add(training); | ||
| } | ||
| } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DeleteMultipleAsyncis a no-op and can mask edit-flow bugs in tests.This currently returns success without deleting anything from
_questions, so tests can pass even when deletion logic regresses.Proposed fix
🤖 Prompt for AI Agents