Repository navigation
test(repositories): pin that UpdateAsync does not rewrite tracked related entities (#361) - #376
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #361
Summary
Issue #361 asked whether
UpdateAsyncre-marks already-tracked related entities as Modified, which would rewrite the related row and risk a lost update. It was verify-first: characterization tests were written and run before any production change.Result: Outcome A for both repositories. Neither re-marks the related entity, so no production repository code changes. This matches the EF Core documentation for
DbSet.Update(it marks only reachable entities that are not already tracked).Characterization evidence (AC 4)
Recorded with a
SaveChangesInterceptoron SQLite, fresh context per simulated request. Both tests passed on the first run with no production edits.JournalLogEntryRepository.UpdateAsync, log relinked to a different task (oldTaskItemtracked viaInclude)JournalLogEntryModifiedTaskItementry recordedTaskRepository.UpdateAsync, tracked task edited (Projecttracked viaInclude)TaskItemModifiedProjectentry recordedThe root entity is asserted Modified in both tests, so the recorder demonstrably sees writes and "not written" is meaningful. The relink test also reloads in a fresh context and asserts the FK is the new task id, with the log's navigation still pointing at the old tracked task beforehand.
Changes
TaskFlow.Api.Tests/Repositories/RepositoryUpdateWritesOnlyRootTests.cs:Update_RelinkDoesNotModifyOldTaskandUpdate_TrackedTaskEdit_DoesNotModifyProject, kept as regression guards. Each asserts the related entity isUnchangedbeforeUpdateAsync.JournalLogEntriesControllerRealStackTests.Update_RelinkDoesNotModifyLinkedTasksnow also asserts the old task is not written, and the stale "may be marked Modified" comment is corrected.ProjectRepository.UpdateAsync: comment-only fix (it claimedUpdatewould mark every loaded task Modified). No code change.Verification
dotnet test --project TaskFlow.Api.Tests(CI coverage flags): 782/782 passed, line coverage 94.43% (threshold 75%)dotnet format TaskFlow.sln --verify-no-changes: cleandotnet build TaskFlow.sln -c Release: 0 warnings, 0 errorsTaskItem/ProjectModified in the two repositories makes exactly 3 tests fail (the two new tests andUpdate_RelinkDoesNotModifyLinkedTasks). Mutations were reverted.Notes
TaskRepository.UpdateAsync; it is not affected.TryAutoCompleteParentAsyncgoes through the same tracked path and is covered by the tracked-task test.TaskRepository.UpdateAsyncstill callsUpdateunconditionally on the root, so a no-op update still writes the task row. That is existing behavior and out of scope here.maintriggers the production deploy; this PR is tests plus a comment only.