82 lines
3.4 KiB
JavaScript
82 lines
3.4 KiB
JavaScript
import { describe, it, expect } from 'vitest'
|
|
|
|
import { planControllingPcChange } from './controllingPc'
|
|
|
|
// Reported: moving machine 3016 on the map, then saving, answered "this
|
|
// relationship already exists" and refused the save. The machine had a
|
|
// controlling PC and the form re-created that link on every save, because it
|
|
// asked "do I know the existing link's id" instead of "is there an existing
|
|
// link" - and the id was read from a key the API does not emit, so it was
|
|
// always undefined.
|
|
//
|
|
// The first two specs are that bug. The rest pin the behaviour it was hiding.
|
|
|
|
describe('planControllingPcChange', () => {
|
|
it('does nothing when the controlling PC is unchanged', () => {
|
|
// The reported case: only the map position moved.
|
|
expect(planControllingPcChange({
|
|
selected: 42, loaded: 42, existingRelationshipId: 7,
|
|
})).toEqual({ action: 'none', deleteId: null })
|
|
})
|
|
|
|
it('still does nothing when the existing row id was never learned', () => {
|
|
// The exact shape of the bug: the link is there, its id is not known. The
|
|
// answer must be "leave it alone", never "create it again" - a create here
|
|
// is the 409.
|
|
expect(planControllingPcChange({
|
|
selected: 42, loaded: 42, existingRelationshipId: undefined,
|
|
})).toEqual({ action: 'none', deleteId: null })
|
|
})
|
|
|
|
it('removes the link when the PC is cleared', () => {
|
|
// This never fired before either: no selection and no known id read as
|
|
// "nothing to do", so clearing a controlling PC silently kept it.
|
|
expect(planControllingPcChange({
|
|
selected: null, loaded: 42, existingRelationshipId: 7,
|
|
})).toEqual({ action: 'unlink', deleteId: 7 })
|
|
})
|
|
|
|
it('creates a link when there was none', () => {
|
|
expect(planControllingPcChange({
|
|
selected: 42, loaded: null, existingRelationshipId: null,
|
|
})).toEqual({ action: 'link', deleteId: null })
|
|
})
|
|
|
|
it('replaces the old row when the PC is swapped', () => {
|
|
// controls is singular per SOURCE, not per target, so the old row has to go
|
|
// or the machine ends up with two controlling PCs.
|
|
expect(planControllingPcChange({
|
|
selected: 99, loaded: 42, existingRelationshipId: 7,
|
|
})).toEqual({ action: 'relink', deleteId: 7 })
|
|
})
|
|
|
|
it('treats a select string and an API number as the same PC', () => {
|
|
// A <select> hands back '42' while the relationship carried 42. Comparing
|
|
// those raw makes an untouched link look like a swap, which is the same
|
|
// duplicate POST by another route.
|
|
expect(planControllingPcChange({
|
|
selected: '42', loaded: 42, existingRelationshipId: 7,
|
|
})).toEqual({ action: 'none', deleteId: null })
|
|
})
|
|
|
|
it('treats an empty selection as cleared, not as a PC named ""', () => {
|
|
expect(planControllingPcChange({
|
|
selected: '', loaded: 42, existingRelationshipId: 7,
|
|
})).toEqual({ action: 'unlink', deleteId: 7 })
|
|
})
|
|
|
|
it('does nothing when there was no PC and none was chosen', () => {
|
|
expect(planControllingPcChange({
|
|
selected: null, loaded: null, existingRelationshipId: null,
|
|
})).toEqual({ action: 'none', deleteId: null })
|
|
})
|
|
|
|
it('does not attempt a delete it cannot perform', () => {
|
|
// Cleared, but the row id was never learned. Asking the API to delete
|
|
// `undefined` produced a request against /relationships/undefined.
|
|
expect(planControllingPcChange({
|
|
selected: null, loaded: 42, existingRelationshipId: undefined,
|
|
})).toEqual({ action: 'none', deleteId: null })
|
|
})
|
|
})
|