-
Notifications
You must be signed in to change notification settings - Fork 73
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
Mark soft conflict if not contiguous with trunk #1187
base: master
Are you sure you want to change the base?
Conversation
I think this is a pretty interesting idea. I don't think it's necessary for this particular issue, but I think it's something we should keep in mind for the future. |
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.
I copied this branch tracking logic directly from Frontend, and there's probably more there than necessary for backend, but I just wanted to see it in action.
I'm going to pare back aspects of the Branch
class and related logic to only what Backend needs, which I think will make the Backend code clearer. However, even pared back, I like the Branch
class here. It moves the branch logic into a separate part of the code from the rest of the getWithConflictDetails()
function, which is already fairly complex. I also think it's very possible that we'll want to grow the Branch
class in the future.
Before I push my commit, I thought I'd leave a few comments about specific things I'm changing.
lib/data/entity.js
Outdated
@@ -417,6 +475,26 @@ const getWithConflictDetails = (defs, audits, relevantToConflict) => { | |||
|
|||
const relevantBaseVersions = new Set(); | |||
|
|||
// build up branches | |||
const branches = new Map(); | |||
for (const version of defs) { |
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.
This ends up looping over defs
twice, which I don't think we need to do. I think we can build up result
and branches
in the same loop, as no version/def needs to look ahead to a later version, including for branch information.
lib/data/entity.js
Outdated
if (existingBranch == null) { | ||
const newBranch = new Branch(version, defs[0]); | ||
branches.set(branchId, newBranch); | ||
version.branch = newBranch; |
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.
I know we do it in Frontend, but I think we should avoid mutating version
here unless it's necessary.
lib/data/entity.js
Outdated
const branches = new Map(); | ||
for (const version of defs) { | ||
const { branchId } = version; | ||
if (branchId != null && version.branchBaseVersion != null) { |
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.
I added version.branchBaseVersion != null
to Frontend mostly as a temporary measure, since at the time, there were submissions where the entity creation got a branch ID. I think we can remove the condition here.
This PR makes changes to the it('should mark an update that is not contiguous with its trunk version as a soft conflict', testOfflineEntities(async (service, container) => {
const asAlice = await service.login('alice');
const branchId = uuid();
// Update existing entity on server (change age from 22 to 24)
await asAlice.patch('/v1/projects/1/datasets/people/entities/12345678-1234-4123-8234-123456789abc?baseVersion=1')
.send({ data: { age: '24' } })
.expect(200);
// Send update (change status from null to arrived)
await asAlice.post('/v1/projects/1/forms/offlineEntity/submissions')
.send(testData.instances.offlineEntity.one
.replace('branchId=""', `branchId="${branchId}"`)
)
.set('Content-Type', 'application/xml')
.expect(200);
await exhaust(container);
await asAlice.patch('/v1/projects/1/datasets/people/entities/12345678-1234-4123-8234-123456789abc?resolve=true&baseVersion=3')
.expect(200);
// Send second update (change age from 22 to 26)
await asAlice.post('/v1/projects/1/forms/offlineEntity/submissions')
.send(testData.instances.offlineEntity.one
.replace('branchId=""', `branchId="${branchId}"`)
.replace('one', 'one-update2')
.replace('baseVersion="1"', 'baseVersion="2"')
.replace('<status>arrived</status>', '<age>26</age>')
)
.set('Content-Type', 'application/xml')
.expect(200);
await exhaust(container);
await asAlice.get('/v1/projects/1/datasets/people/entities/12345678-1234-4123-8234-123456789abc/versions')
.then(({ body: versions }) => {
versions.map(v => v.conflict).should.eql([null, null, 'soft', 'soft']);
});
await asAlice.get('/v1/projects/1/datasets/people/entities/12345678-1234-4123-8234-123456789abc')
.then(({ body: entity }) => {
// This assertion currently fails.
should(entity.conflict).equal('soft');
});
})); |
Also, @ktuite, I've pushed my commit. Would you mind taking a look at it? |
Closes getodk/central#698
I copied this branch tracking logic directly from Frontend, and there's probably more there than necessary for backend, but I just wanted to see it in action. We could also consider having backend return more of the details that frontend is currently computing about branch continuity.
What has been done to verify that this works as intended?
Why is this the best possible solution? Were any other approaches considered?
How does this change affect users? Describe intentional changes to behavior and behavior that could have accidentally been affected by code changes. In other words, what are the regression risks?
Does this change require updates to the API documentation? If so, please update docs/api.yaml as part of this PR.
Before submitting this PR, please make sure you have:
make test
and confirmed all checks still pass OR confirm CircleCI build passes