Add simple update test

This commit is contained in:
mcrakhman 2022-07-07 09:18:55 +02:00 committed by Mikhail Iudin
parent c2bd392c84
commit eea64a3014
No known key found for this signature in database
GPG Key ID: FAAAA8BAABDFF1C0
4 changed files with 57 additions and 9 deletions

View File

@ -28,7 +28,7 @@ type Document struct {
type UpdateResult int
const (
UpdateResultNoAction = iota
UpdateResultNoAction UpdateResult = iota
UpdateResultAppend
UpdateResultRebuild
)
@ -56,6 +56,7 @@ func NewDocument(
func (d *Document) Update(changes ...*threadmodels.RawChange) (DocumentState, UpdateResult, error) {
var treeChanges []*Change
var foundACLChange bool
for _, ch := range changes {
aclChange, err := d.treeBuilder.makeVerifiedACLChange(ch)
if err != nil {
@ -71,13 +72,14 @@ func (d *Document) Update(changes ...*threadmodels.RawChange) (DocumentState, Up
if err != nil {
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 ch.IsACLChange() {
res, err := d.Build()
return res, UpdateResultRebuild, err
}
if foundACLChange {
res, err := d.Build()
return res, UpdateResultRebuild, err
}
prevHeads := d.docContext.fullTree.Heads()
@ -92,11 +94,28 @@ func (d *Document) Update(changes ...*threadmodels.RawChange) (DocumentState, Up
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
// each of previous heads must have same "Next" nodes
// so it doesn't matter which one we choose
// 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 {
res, _ := d.Build()
return res, UpdateResultRebuild, fmt.Errorf("could not add changes to state, rebuilded")

View File

@ -26,3 +26,28 @@ func TestDocument_Build(t *testing.T) {
st := res.(*PlainTextDocumentState)
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")
}

View File

@ -63,8 +63,12 @@ func (d *documentStateBuilder) build() (s DocumentState, err error) {
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) {
if c.Id == fromId {
return true
}
if c.DecryptedDocumentChange != nil {
s, err = s.ApplyChange(c.DecryptedDocumentChange, c.Id)
if err != nil {

View File

@ -106,7 +106,7 @@ updatedChanges:
identity: B
changes:
- textAppend:
text: "first"
text: "second"
readKey: key.Read.1
updatedGraph:
- id: B.1.3