Skip to content

Commit

Permalink
GO-2734 Move updateDetails to basic
Browse files Browse the repository at this point in the history
  • Loading branch information
KirillSto committed Apr 8, 2024
1 parent 2198b47 commit 0174ea5
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 83 deletions.
20 changes: 2 additions & 18 deletions core/block/editor.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"fmt"

"github.com/gogo/protobuf/types"
"golang.org/x/exp/maps"

"github.com/anyproto/anytype-heart/core/block/editor/basic"
"github.com/anyproto/anytype-heart/core/block/editor/bookmark"
Expand Down Expand Up @@ -616,23 +615,8 @@ func (s *Service) GetRelations(ctx session.Context, objectId string) (relations

// ModifyDetails performs details get and update under the sb lock to make sure no modifications are done in the middle
func (s *Service) ModifyDetails(objectId string, modifier func(current *types.Struct) (*types.Struct, error)) (err error) {
if modifier == nil {
return fmt.Errorf("modifier is nil")
}
return Do(s, objectId, func(b smartblock.SmartBlock) error {
dets, err := modifier(b.CombinedDetails())
if err != nil {
return err
}

rels, err := s.objectStore.FetchRelationByKeys(b.SpaceID(), maps.Keys(dets.Fields)...)
if err != nil {
return err
}

st := b.NewState().SetDetails(dets)
st.AddRelationLinks(rels.RelationLinks()...)
return b.Apply(st)
return Do(s, objectId, func(du basic.DetailsUpdatable) error {
return du.UpdateDetails(modifier)
})
}

Expand Down
8 changes: 7 additions & 1 deletion core/block/editor/basic/basic.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"

"github.com/globalsign/mgo/bson"
"github.com/gogo/protobuf/types"
"github.com/samber/lo"

"github.com/anyproto/anytype-heart/core/block/editor/converter"
Expand Down Expand Up @@ -40,6 +41,7 @@ type AllOperations interface {

type CommonOperations interface {
DetailsSettable
DetailsUpdatable

SetFields(ctx session.Context, fields ...*pb.RpcBlockListSetFieldsRequestBlockField) (err error)
SetDivStyle(ctx session.Context, style model.BlockContentDivStyle, ids ...string) (err error)
Expand All @@ -64,6 +66,10 @@ type DetailsSettable interface {
SetDetails(ctx session.Context, details []*pb.RpcObjectSetDetailsDetail, showEvent bool) (err error)
}

type DetailsUpdatable interface {
UpdateDetails(update func(current *types.Struct) (*types.Struct, error)) (err error)
}

type Restrictionable interface {
Restrictions() restriction.Restrictions
}
Expand Down Expand Up @@ -402,7 +408,7 @@ func (bs *basic) FeaturedRelationAdd(ctx session.Context, relations ...string) (
}
frc = append(frc, r)
if !bs.HasRelation(s, r) {
err = bs.addRelationLink(r, s)
err = bs.addRelationLink(s, r)
if err != nil {
return fmt.Errorf("failed to add relation link on adding featured relation '%s': %w", r, err)
}
Expand Down
36 changes: 34 additions & 2 deletions core/block/editor/basic/details.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"strings"

"github.com/gogo/protobuf/types"
"golang.org/x/exp/maps"

"github.com/anyproto/anytype-heart/core/block/editor/objecttype"
"github.com/anyproto/anytype-heart/core/block/editor/smartblock"
Expand Down Expand Up @@ -52,6 +53,25 @@ func (bs *basic) SetDetails(ctx session.Context, details []*pb.RpcObjectSetDetai
return nil
}

func (bs *basic) UpdateDetails(update func(current *types.Struct) (*types.Struct, error)) (err error) {
if update == nil {
return fmt.Errorf("update function is nil")
}
s := bs.NewState()

newDetails, err := update(s.CombinedDetails())
if err != nil {
return
}
s.SetDetails(newDetails)

if err = bs.addRelationLinks(s, maps.Keys(newDetails.Fields)...); err != nil {
return
}

return bs.Apply(s)
}

func (bs *basic) collectDetailUpdates(details []*pb.RpcObjectSetDetailsDetail, s *state.State) []*detailUpdate {
updates := make([]*detailUpdate, 0, len(details))
for _, detail := range details {
Expand Down Expand Up @@ -90,7 +110,7 @@ func (bs *basic) createDetailUpdate(st *state.State, detail *pb.RpcObjectSetDeta
if err := bs.setDetailSpecialCases(st, detail); err != nil {
return nil, fmt.Errorf("special case: %w", err)
}
if err := bs.addRelationLink(detail.Key, st); err != nil {
if err := bs.addRelationLink(st, detail.Key); err != nil {
return nil, err
}
if err := bs.validateDetailFormat(bs.SpaceID(), detail.Key, detail.Value); err != nil {
Expand Down Expand Up @@ -246,7 +266,7 @@ func (bs *basic) setDetailSpecialCases(st *state.State, detail *pb.RpcObjectSetD
return nil
}

func (bs *basic) addRelationLink(relationKey string, st *state.State) error {
func (bs *basic) addRelationLink(st *state.State, relationKey string) error {
relLink, err := bs.objectStore.GetRelationLink(bs.SpaceID(), relationKey)
if err != nil || relLink == nil {
return fmt.Errorf("failed to get relation: %w", err)
Expand All @@ -255,6 +275,18 @@ func (bs *basic) addRelationLink(relationKey string, st *state.State) error {
return nil
}

func (bs *basic) addRelationLinks(st *state.State, relationKeys ...string) error {
if len(relationKeys) == 0 {
return nil
}
relations, err := bs.objectStore.FetchRelationByKeys(bs.SpaceID(), relationKeys...)
if err != nil || relations == nil {
return fmt.Errorf("failed to get relations: %w", err)
}
st.AddRelationLinks(relations.RelationLinks()...)
return nil
}

func (bs *basic) discardOwnSetDetailsEvent(ctx session.Context, showEvent bool) {
if !showEvent && ctx != nil {
var filtered []*pb.EventMessage
Expand Down
105 changes: 44 additions & 61 deletions core/block/editor_test.go → core/block/editor/basic/details_test.go
Original file line number Diff line number Diff line change
@@ -1,84 +1,67 @@
package block
package basic

import (
"testing"

"github.com/gogo/protobuf/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"

"github.com/anyproto/anytype-heart/core/block/editor/converter"
"github.com/anyproto/anytype-heart/core/block/editor/smartblock/smarttest"
"github.com/anyproto/anytype-heart/core/block/object/idresolver/mock_idresolver"
"github.com/anyproto/anytype-heart/core/relationutils"
"github.com/anyproto/anytype-heart/pb"
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/mock_objectstore"
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore"
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
"github.com/anyproto/anytype-heart/space/clientspace/mock_clientspace"
"github.com/anyproto/anytype-heart/space/mock_space"
"github.com/anyproto/anytype-heart/util/pbtypes"
)

type fixture struct {
blockService *Service
store *mock_objectstore.MockObjectStore

sb *smarttest.SmartTest
spc *mock_clientspace.MockSpace
type duFixture struct {
sb *smarttest.SmartTest
store *objectstore.StoreFixture
basic DetailsUpdatable
}

var (
objectId = "id"
spaceId = "spaceId"
objectId = "objectId"
spaceId = "space1"
)

func newFixture(t *testing.T) *fixture {
blockService := New()

func newDUFixture(t *testing.T) *duFixture {
sb := smarttest.New(objectId)
sb.SetDetails(nil, nil, false)
sb.SetSpaceId(spaceId)

spc := mock_clientspace.NewMockSpace(t)
spc.EXPECT().GetObject(mock.Anything, objectId).Return(sb, nil).Times(1)

spaceService := mock_space.NewMockService(t)
spaceService.EXPECT().Get(mock.Anything, spaceId).Return(spc, nil).Times(1)
store := objectstore.NewStoreFixture(t)

resolver := mock_idresolver.NewMockResolver(t)
resolver.EXPECT().ResolveSpaceID(objectId).Return(spaceId, nil).Times(1)
b := NewBasic(sb, store, converter.NewLayoutConverter())

store := mock_objectstore.NewMockObjectStore(t)

blockService.spaceService = spaceService
blockService.resolver = resolver
blockService.objectStore = store

return &fixture{
blockService: blockService,
sb: sb,
store: store,
spc: spc,
return &duFixture{
sb: sb,
store: store,
basic: b,
}
}

func TestService_ModifyDetails(t *testing.T) {

func TestBasic_UpdateDetails(t *testing.T) {
t.Run("add new details", func(t *testing.T) {
// given
f := newFixture(t)
f.store.EXPECT().FetchRelationByKeys(spaceId, bundle.RelationKeyAperture.String(), bundle.RelationKeyRelationMaxCount.String()).
Return(relationutils.Relations{
{&model.Relation{
Key: bundle.RelationKeyAperture.String(),
Format: model.RelationFormat_longtext,
}}, {&model.Relation{
Key: bundle.RelationKeyRelationMaxCount.String(),
Format: model.RelationFormat_number,
}}}, nil)
f := newDUFixture(t)
f.store.AddObjects(t, []objectstore.TestObject{{
bundle.RelationKeyId: pbtypes.String("rel-aperture"),
bundle.RelationKeySpaceId: pbtypes.String(spaceId),
bundle.RelationKeyRelationKey: pbtypes.String("aperture"),
bundle.RelationKeyUniqueKey: pbtypes.String("rel-aperture"),
bundle.RelationKeyRelationFormat: pbtypes.Int64(int64(model.RelationFormat_longtext)),
}, {
bundle.RelationKeyId: pbtypes.String("rel-maxCount"),
bundle.RelationKeySpaceId: pbtypes.String(spaceId),
bundle.RelationKeyRelationKey: pbtypes.String("relationMaxCount"),
bundle.RelationKeyUniqueKey: pbtypes.String("rel-relationMaxCount"),
bundle.RelationKeyRelationFormat: pbtypes.Int64(int64(model.RelationFormat_number)),
}})

// when
err := f.blockService.ModifyDetails(objectId, func(current *types.Struct) (*types.Struct, error) {
err := f.basic.UpdateDetails(func(current *types.Struct) (*types.Struct, error) {
current.Fields[bundle.RelationKeyAperture.String()] = pbtypes.String("aperture")
current.Fields[bundle.RelationKeyRelationMaxCount.String()] = pbtypes.Int64(5)
return current, nil
Expand All @@ -100,21 +83,22 @@ func TestService_ModifyDetails(t *testing.T) {

t.Run("modify details", func(t *testing.T) {
// given
f := newFixture(t)
f := newDUFixture(t)
err := f.sb.SetDetails(nil, []*pb.RpcObjectSetDetailsDetail{{
Key: bundle.RelationKeySpaceDashboardId.String(),
Value: pbtypes.String("123"),
}}, false)
assert.NoError(t, err)
f.store.EXPECT().FetchRelationByKeys(spaceId, bundle.RelationKeySpaceDashboardId.String()).
Return(relationutils.Relations{
{&model.Relation{
Key: bundle.RelationKeySpaceDashboardId.String(),
Format: model.RelationFormat_object,
}}}, nil)
f.store.AddObjects(t, []objectstore.TestObject{{
bundle.RelationKeyId: pbtypes.String("rel-spaceDashboardId"),
bundle.RelationKeySpaceId: pbtypes.String(spaceId),
bundle.RelationKeyRelationKey: pbtypes.String("spaceDashboardId"),
bundle.RelationKeyUniqueKey: pbtypes.String("rel-spaceDashboardId"),
bundle.RelationKeyRelationFormat: pbtypes.Int64(int64(model.RelationFormat_object)),
}})

// when
err = f.blockService.ModifyDetails(objectId, func(current *types.Struct) (*types.Struct, error) {
err = f.basic.UpdateDetails(func(current *types.Struct) (*types.Struct, error) {
current.Fields[bundle.RelationKeySpaceDashboardId.String()] = pbtypes.String("new123")
return current, nil
})
Expand All @@ -130,16 +114,15 @@ func TestService_ModifyDetails(t *testing.T) {

t.Run("delete details", func(t *testing.T) {
// given
f := newFixture(t)
f := newDUFixture(t)
err := f.sb.SetDetails(nil, []*pb.RpcObjectSetDetailsDetail{{
Key: bundle.RelationKeyTargetObjectType.String(),
Value: pbtypes.String("note"),
Value: pbtypes.String("ot-note"),
}}, false)
assert.NoError(t, err)
f.store.EXPECT().FetchRelationByKeys(spaceId).Return(nil, nil)

// when
err = f.blockService.ModifyDetails(objectId, func(current *types.Struct) (*types.Struct, error) {
err = f.basic.UpdateDetails(func(current *types.Struct) (*types.Struct, error) {
delete(current.Fields, bundle.RelationKeyTargetObjectType.String())
return current, nil
})
Expand Down
6 changes: 5 additions & 1 deletion core/block/editor/participant.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package editor
import (
"time"

"github.com/anyproto/anytype-heart/core/block/editor/basic"
"github.com/anyproto/anytype-heart/core/block/editor/smartblock"
"github.com/anyproto/anytype-heart/core/block/editor/template"
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
Expand All @@ -12,11 +13,14 @@ import (

type participant struct {
smartblock.SmartBlock
basic.DetailsUpdatable
}

func (f *ObjectFactory) newParticipant(sb smartblock.SmartBlock) *participant {
basicComponent := basic.NewBasic(sb, f.objectStore, f.layoutConverter)
return &participant{
SmartBlock: sb,
SmartBlock: sb,
DetailsUpdatable: basicComponent,
}
}

Expand Down

0 comments on commit 0174ea5

Please sign in to comment.