Add simple update test
This commit is contained in:
parent
c2bd392c84
commit
eea64a3014
@ -28,7 +28,7 @@ type Document struct {
|
|||||||
type UpdateResult int
|
type UpdateResult int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
UpdateResultNoAction = iota
|
UpdateResultNoAction UpdateResult = iota
|
||||||
UpdateResultAppend
|
UpdateResultAppend
|
||||||
UpdateResultRebuild
|
UpdateResultRebuild
|
||||||
)
|
)
|
||||||
@ -56,6 +56,7 @@ func NewDocument(
|
|||||||
func (d *Document) Update(changes ...*threadmodels.RawChange) (DocumentState, UpdateResult, error) {
|
func (d *Document) Update(changes ...*threadmodels.RawChange) (DocumentState, UpdateResult, error) {
|
||||||
var treeChanges []*Change
|
var treeChanges []*Change
|
||||||
|
|
||||||
|
var foundACLChange bool
|
||||||
for _, ch := range changes {
|
for _, ch := range changes {
|
||||||
aclChange, err := d.treeBuilder.makeVerifiedACLChange(ch)
|
aclChange, err := d.treeBuilder.makeVerifiedACLChange(ch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -71,13 +72,14 @@ func (d *Document) Update(changes ...*threadmodels.RawChange) (DocumentState, Up
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, UpdateResultNoAction, fmt.Errorf("change with id %s cannot be added: %w", ch.Id, err)
|
return nil, UpdateResultNoAction, fmt.Errorf("change with id %s cannot be added: %w", ch.Id, err)
|
||||||
}
|
}
|
||||||
|
if treeChange.IsACLChange() {
|
||||||
|
foundACLChange = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, ch := range treeChanges {
|
if foundACLChange {
|
||||||
if ch.IsACLChange() {
|
res, err := d.Build()
|
||||||
res, err := d.Build()
|
return res, UpdateResultRebuild, err
|
||||||
return res, UpdateResultRebuild, err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
prevHeads := d.docContext.fullTree.Heads()
|
prevHeads := d.docContext.fullTree.Heads()
|
||||||
@ -92,11 +94,28 @@ func (d *Document) Update(changes ...*threadmodels.RawChange) (DocumentState, Up
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// decrypting everything, because we have no new keys
|
||||||
|
for _, ch := range treeChanges {
|
||||||
|
if ch.Content.GetChangesData() != nil {
|
||||||
|
key, exists := d.docContext.aclState.userReadKeys[ch.Content.CurrentReadKeyHash]
|
||||||
|
if !exists {
|
||||||
|
err := fmt.Errorf("failed to find key with hash: %d", ch.Content.CurrentReadKeyHash)
|
||||||
|
return nil, UpdateResultNoAction, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err := ch.DecryptContents(key)
|
||||||
|
if err != nil {
|
||||||
|
err = fmt.Errorf("failed to decrypt contents for hash: %d", ch.Content.CurrentReadKeyHash)
|
||||||
|
return nil, UpdateResultNoAction, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// because for every new change we know it was after any of the previous heads
|
// because for every new change we know it was after any of the previous heads
|
||||||
// each of previous heads must have same "Next" nodes
|
// each of previous heads must have same "Next" nodes
|
||||||
// so it doesn't matter which one we choose
|
// so it doesn't matter which one we choose
|
||||||
// so we choose first one
|
// so we choose first one
|
||||||
newState, err := d.docStateBuilder.appendFrom(prevHeads[0])
|
newState, err := d.docStateBuilder.appendFrom(prevHeads[0], d.docContext.docState)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
res, _ := d.Build()
|
res, _ := d.Build()
|
||||||
return res, UpdateResultRebuild, fmt.Errorf("could not add changes to state, rebuilded")
|
return res, UpdateResultRebuild, fmt.Errorf("could not add changes to state, rebuilded")
|
||||||
|
|||||||
@ -26,3 +26,28 @@ func TestDocument_Build(t *testing.T) {
|
|||||||
st := res.(*PlainTextDocumentState)
|
st := res.(*PlainTextDocumentState)
|
||||||
assert.Equal(t, st.Text, "some text|first")
|
assert.Equal(t, st.Text, "some text|first")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDocument_Update(t *testing.T) {
|
||||||
|
thread, err := threadbuilder.NewThreadBuilderFromFile("threadbuilder/userjoinexample.yml")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
keychain := thread.GetKeychain()
|
||||||
|
accountData := &AccountData{
|
||||||
|
Identity: keychain.GetIdentity("A"),
|
||||||
|
EncKey: keychain.EncryptionKeys["A"],
|
||||||
|
}
|
||||||
|
doc := NewDocument(thread, NewPlainTextDocumentStateProvider(), accountData)
|
||||||
|
res, err := doc.Build()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
st := res.(*PlainTextDocumentState)
|
||||||
|
assert.Equal(t, st.Text, "some text|first")
|
||||||
|
|
||||||
|
rawChs := thread.GetUpdatedChanges()
|
||||||
|
res, updateResult, err := doc.Update(rawChs...)
|
||||||
|
assert.Equal(t, updateResult, UpdateResultAppend)
|
||||||
|
assert.Equal(t, res.(*PlainTextDocumentState).Text, "some text|first|second")
|
||||||
|
}
|
||||||
|
|||||||
@ -63,8 +63,12 @@ func (d *documentStateBuilder) build() (s DocumentState, err error) {
|
|||||||
return s, err
|
return s, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *documentStateBuilder) appendFrom(fromId string) (s DocumentState, err error) {
|
func (d *documentStateBuilder) appendFrom(fromId string, init DocumentState) (s DocumentState, err error) {
|
||||||
|
s = init
|
||||||
d.tree.Iterate(fromId, func(c *Change) (isContinue bool) {
|
d.tree.Iterate(fromId, func(c *Change) (isContinue bool) {
|
||||||
|
if c.Id == fromId {
|
||||||
|
return true
|
||||||
|
}
|
||||||
if c.DecryptedDocumentChange != nil {
|
if c.DecryptedDocumentChange != nil {
|
||||||
s, err = s.ApplyChange(c.DecryptedDocumentChange, c.Id)
|
s, err = s.ApplyChange(c.DecryptedDocumentChange, c.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -106,7 +106,7 @@ updatedChanges:
|
|||||||
identity: B
|
identity: B
|
||||||
changes:
|
changes:
|
||||||
- textAppend:
|
- textAppend:
|
||||||
text: "first"
|
text: "second"
|
||||||
readKey: key.Read.1
|
readKey: key.Read.1
|
||||||
updatedGraph:
|
updatedGraph:
|
||||||
- id: B.1.3
|
- id: B.1.3
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user