mirror of
https://github.com/anyproto/any-sync.git
synced 2025-06-09 09:35:03 +09:00
Prevent deletion for derived
This commit is contained in:
parent
3608a6949f
commit
61bd9aae1e
6 changed files with 91 additions and 18 deletions
|
@ -31,10 +31,11 @@ type SettingsObject interface {
|
|||
}
|
||||
|
||||
var (
|
||||
ErrDeleteSelf = errors.New("cannot delete self")
|
||||
ErrAlreadyDeleted = errors.New("the object is already deleted")
|
||||
ErrObjDoesNotExist = errors.New("the object does not exist")
|
||||
ErrCantDeleteSpace = errors.New("not able to delete space")
|
||||
ErrDeleteSelf = errors.New("cannot delete self")
|
||||
ErrAlreadyDeleted = errors.New("the object is already deleted")
|
||||
ErrObjDoesNotExist = errors.New("the object does not exist")
|
||||
ErrCantDeleteDerivedObject = errors.New("can't delete derived object")
|
||||
ErrCantDeleteSpace = errors.New("not able to delete space")
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -168,21 +169,31 @@ func (s *settingsObject) Close() error {
|
|||
return s.SyncTree.Close()
|
||||
}
|
||||
|
||||
var isDerivedRoot = objecttree.IsDerivedRoot
|
||||
|
||||
func (s *settingsObject) DeleteObject(id string) (err error) {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
if s.Id() == id {
|
||||
err = ErrDeleteSelf
|
||||
return
|
||||
return ErrDeleteSelf
|
||||
}
|
||||
if s.state.Exists(id) {
|
||||
err = ErrAlreadyDeleted
|
||||
return nil
|
||||
return ErrAlreadyDeleted
|
||||
}
|
||||
_, err = s.store.TreeStorage(id)
|
||||
st, err := s.store.TreeStorage(id)
|
||||
if err != nil {
|
||||
err = ErrObjDoesNotExist
|
||||
return
|
||||
return ErrObjDoesNotExist
|
||||
}
|
||||
root, err := st.Root()
|
||||
if err != nil {
|
||||
return ErrObjDoesNotExist
|
||||
}
|
||||
isDerived, err := isDerivedRoot(root)
|
||||
if err != nil {
|
||||
return ErrObjDoesNotExist
|
||||
}
|
||||
if isDerived {
|
||||
return ErrCantDeleteDerivedObject
|
||||
}
|
||||
isSnapshot := DoSnapshot(s.Len())
|
||||
res, err := s.changeFactory.CreateObjectDeleteChange(id, s.state, isSnapshot)
|
||||
|
|
|
@ -10,6 +10,8 @@ import (
|
|||
"github.com/anyproto/any-sync/commonspace/object/tree/synctree"
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/synctree/mock_synctree"
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/synctree/updatelistener"
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto"
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/treestorage/mock_treestorage"
|
||||
"github.com/anyproto/any-sync/commonspace/object/treemanager/mock_treemanager"
|
||||
"github.com/anyproto/any-sync/commonspace/settings/settingsstate"
|
||||
"github.com/anyproto/any-sync/commonspace/settings/settingsstate/mock_settingsstate"
|
||||
|
@ -128,6 +130,9 @@ func TestSettingsObject_Init(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSettingsObject_DeleteObject_NoSnapshot(t *testing.T) {
|
||||
isDerivedRoot = func(root *treechangeproto.RawTreeChangeWithId) (derived bool, err error) {
|
||||
return false, nil
|
||||
}
|
||||
fx := newSettingsFixture(t)
|
||||
defer fx.stop(t)
|
||||
|
||||
|
@ -140,7 +145,9 @@ func TestSettingsObject_DeleteObject_NoSnapshot(t *testing.T) {
|
|||
|
||||
fx.syncTree.EXPECT().Id().Return("syncId")
|
||||
fx.syncTree.EXPECT().Len().Return(10)
|
||||
fx.spaceStorage.EXPECT().TreeStorage(delId).Return(nil, nil)
|
||||
treeStorageMock := mock_treestorage.NewMockTreeStorage(fx.ctrl)
|
||||
fx.spaceStorage.EXPECT().TreeStorage(delId).Return(treeStorageMock, nil)
|
||||
treeStorageMock.EXPECT().Root().Return(&treechangeproto.RawTreeChangeWithId{}, nil)
|
||||
res := []byte("settingsData")
|
||||
fx.doc.state = &settingsstate.State{LastIteratedId: "someId"}
|
||||
fx.changeFactory.EXPECT().CreateObjectDeleteChange(delId, fx.doc.state, false).Return(res, nil)
|
||||
|
@ -162,9 +169,11 @@ func TestSettingsObject_DeleteObject_NoSnapshot(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSettingsObject_DeleteObject_WithSnapshot(t *testing.T) {
|
||||
isDerivedRoot = func(root *treechangeproto.RawTreeChangeWithId) (derived bool, err error) {
|
||||
return false, nil
|
||||
}
|
||||
fx := newSettingsFixture(t)
|
||||
defer fx.stop(t)
|
||||
|
||||
fx.init(t)
|
||||
delId := "delId"
|
||||
DoSnapshot = func(len int) bool {
|
||||
|
@ -173,7 +182,9 @@ func TestSettingsObject_DeleteObject_WithSnapshot(t *testing.T) {
|
|||
|
||||
fx.syncTree.EXPECT().Id().Return("syncId")
|
||||
fx.syncTree.EXPECT().Len().Return(10)
|
||||
fx.spaceStorage.EXPECT().TreeStorage(delId).Return(nil, nil)
|
||||
treeStorageMock := mock_treestorage.NewMockTreeStorage(fx.ctrl)
|
||||
fx.spaceStorage.EXPECT().TreeStorage(delId).Return(treeStorageMock, nil)
|
||||
treeStorageMock.EXPECT().Root().Return(&treechangeproto.RawTreeChangeWithId{}, nil)
|
||||
res := []byte("settingsData")
|
||||
fx.doc.state = &settingsstate.State{LastIteratedId: "someId"}
|
||||
fx.changeFactory.EXPECT().CreateObjectDeleteChange(delId, fx.doc.state, true).Return(res, nil)
|
||||
|
@ -194,6 +205,26 @@ func TestSettingsObject_DeleteObject_WithSnapshot(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestSettingsObject_DeleteDerivedObject(t *testing.T) {
|
||||
isDerivedRoot = func(root *treechangeproto.RawTreeChangeWithId) (derived bool, err error) {
|
||||
return true, nil
|
||||
}
|
||||
fx := newSettingsFixture(t)
|
||||
defer fx.stop(t)
|
||||
fx.init(t)
|
||||
delId := "delId"
|
||||
DoSnapshot = func(len int) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
fx.syncTree.EXPECT().Id().Return("syncId")
|
||||
treeStorageMock := mock_treestorage.NewMockTreeStorage(fx.ctrl)
|
||||
fx.spaceStorage.EXPECT().TreeStorage(delId).Return(treeStorageMock, nil)
|
||||
treeStorageMock.EXPECT().Root().Return(&treechangeproto.RawTreeChangeWithId{}, nil)
|
||||
err := fx.doc.DeleteObject(delId)
|
||||
require.Equal(t, ErrCantDeleteDerivedObject, err)
|
||||
}
|
||||
|
||||
func TestSettingsObject_Rebuild(t *testing.T) {
|
||||
fx := newSettingsFixture(t)
|
||||
defer fx.stop(t)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue