diff --git a/common/commonspace/settingsdocument/idprovider.go b/common/commonspace/settingsdocument/idprovider.go index 6e42d0d2..fd8e1f39 100644 --- a/common/commonspace/settingsdocument/idprovider.go +++ b/common/commonspace/settingsdocument/idprovider.go @@ -12,16 +12,7 @@ type DeletedIdsProvider interface { type provider struct{} -func (p *provider) convert(decrypted []byte) (res any, err error) { - deleteChange := &spacesyncproto.SettingsData{} - err = proto.Unmarshal(decrypted, deleteChange) - if err != nil { - return nil, err - } - return deleteChange, nil -} - -func (p *provider) processChange(change *tree.Change, tr tree.ObjectTree, startId string, ids []string) []string { +func (p *provider) processChange(change *tree.Change, rootId, startId string, ids []string) []string { // ignoring root change which has empty model or startId change if change.Model == nil || (change.Id == startId && startId != "") { return ids @@ -29,7 +20,7 @@ func (p *provider) processChange(change *tree.Change, tr tree.ObjectTree, startI deleteChange := change.Model.(*spacesyncproto.SettingsData) // getting data from snapshot if we start from it - if change.Id == tr.Root().Id { + if change.Id == rootId { ids = deleteChange.Snapshot.DeletedIds return ids } @@ -44,15 +35,25 @@ func (p *provider) processChange(change *tree.Change, tr tree.ObjectTree, startI } func (p *provider) ProvideIds(tr tree.ObjectTree, startId string) (ids []string, lastId string, err error) { + rootId := tr.Root().Id process := func(change *tree.Change) bool { lastId = change.Id - ids = p.processChange(change, tr, startId, ids) + ids = p.processChange(change, rootId, startId, ids) return true } + convert := func(decrypted []byte) (res any, err error) { + deleteChange := &spacesyncproto.SettingsData{} + err = proto.Unmarshal(decrypted, deleteChange) + if err != nil { + return nil, err + } + return deleteChange, nil + } + if startId == "" { - err = tr.IterateFrom(tr.ID(), p.convert, process) + err = tr.IterateFrom(tr.ID(), convert, process) } else { - err = tr.IterateFrom(startId, p.convert, process) + err = tr.IterateFrom(startId, convert, process) } return } diff --git a/common/commonspace/settingsdocument/idprovider_test.go b/common/commonspace/settingsdocument/idprovider_test.go new file mode 100644 index 00000000..435fe210 --- /dev/null +++ b/common/commonspace/settingsdocument/idprovider_test.go @@ -0,0 +1,94 @@ +package settingsdocument + +import ( + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto" + "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree" + mock_tree "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree/mock_objecttree" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" + "testing" +) + +func TestProvider_ProcessChange(t *testing.T) { + //ctrl := gomock.NewController(t) + //objTree := mock_tree.NewMockObjectTree(ctrl) + prov := &provider{} + //defer ctrl.Finish() + + t.Run("empty model", func(t *testing.T) { + ch := &tree.Change{} + startId := "startId" + rootId := "rootId" + ids := []string{startId} + otherIds := prov.processChange(ch, rootId, startId, ids) + require.Equal(t, []string{startId}, otherIds) + }) + + t.Run("changeId is equal to startId", func(t *testing.T) { + ch := &tree.Change{} + ch.Model = &spacesyncproto.SettingsData{} + ch.Id = "startId" + + startId := "startId" + rootId := "rootId" + ids := []string{startId} + otherIds := prov.processChange(ch, rootId, startId, ids) + require.Equal(t, []string{startId}, otherIds) + }) + + t.Run("changeId is equal to rootId, startId is empty", func(t *testing.T) { + ch := &tree.Change{} + ch.Model = &spacesyncproto.SettingsData{ + Snapshot: &spacesyncproto.SpaceSettingsSnapshot{ + DeletedIds: []string{"id1", "id2"}, + }, + } + ch.Id = "rootId" + + startId := "" + rootId := "rootId" + otherIds := prov.processChange(ch, rootId, startId, nil) + require.Equal(t, []string{"id1", "id2"}, otherIds) + }) + + t.Run("changeId is equal to rootId, startId is empty", func(t *testing.T) { + ch := &tree.Change{} + ch.Model = &spacesyncproto.SettingsData{ + Content: []*spacesyncproto.SpaceSettingsContent{ + {&spacesyncproto.SpaceSettingsContent_ObjectDelete{ + ObjectDelete: &spacesyncproto.ObjectDelete{Id: "id1"}, + }}, + }, + } + ch.Id = "someId" + + startId := "startId" + rootId := "rootId" + otherIds := prov.processChange(ch, rootId, startId, nil) + require.Equal(t, []string{"id1"}, otherIds) + }) +} + +func TestProvider_ProvideIds(t *testing.T) { + ctrl := gomock.NewController(t) + objTree := mock_tree.NewMockObjectTree(ctrl) + prov := &provider{} + defer ctrl.Finish() + + t.Run("startId is empty", func(t *testing.T) { + ch := &tree.Change{Id: "rootId"} + objTree.EXPECT().Root().Return(ch) + objTree.EXPECT().ID().Return("id") + objTree.EXPECT().IterateFrom("id", gomock.Any(), gomock.Any()).Return(nil) + _, _, err := prov.ProvideIds(objTree, "") + require.NoError(t, err) + }) + + t.Run("startId is not empty", func(t *testing.T) { + ch := &tree.Change{Id: "rootId"} + objTree.EXPECT().Root().Return(ch) + objTree.EXPECT().IterateFrom("startId", gomock.Any(), gomock.Any()).Return(nil) + _, _, err := prov.ProvideIds(objTree, "startId") + require.NoError(t, err) + }) +}