mirror of
https://github.com/anyproto/any-sync.git
synced 2025-06-08 05:57:03 +09:00
237 lines
6.2 KiB
Go
237 lines
6.2 KiB
Go
package acl
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"go.uber.org/mock/gomock"
|
|
|
|
"github.com/anyproto/any-sync/app"
|
|
"github.com/anyproto/any-sync/commonspace/object/accountdata"
|
|
"github.com/anyproto/any-sync/commonspace/object/acl/list"
|
|
"github.com/anyproto/any-sync/consensus/consensusclient"
|
|
"github.com/anyproto/any-sync/consensus/consensusclient/mock_consensusclient"
|
|
"github.com/anyproto/any-sync/consensus/consensusproto"
|
|
"github.com/anyproto/any-sync/testutil/accounttest"
|
|
)
|
|
|
|
var ctx = context.Background()
|
|
|
|
func TestAclService_AddRecord(t *testing.T) {
|
|
ownerKeys, err := accountdata.NewRandom()
|
|
require.NoError(t, err)
|
|
spaceId := "spaceId"
|
|
ownerAcl, err := list.NewInMemoryDerivedAcl(spaceId, ownerKeys)
|
|
require.NoError(t, err)
|
|
inv, err := ownerAcl.RecordBuilder().BuildInvite()
|
|
require.NoError(t, err)
|
|
|
|
t.Run("success", func(t *testing.T) {
|
|
fx := newFixture(t)
|
|
defer fx.finish(t)
|
|
|
|
expRes := list.WrapAclRecord(inv.InviteRec)
|
|
var watcherCh = make(chan consensusclient.Watcher)
|
|
fx.consCl.EXPECT().Watch(spaceId, gomock.Any()).DoAndReturn(func(spaceId string, w consensusclient.Watcher) error {
|
|
go func() {
|
|
w.AddConsensusRecords([]*consensusproto.RawRecordWithId{
|
|
ownerAcl.Root(),
|
|
})
|
|
watcherCh <- w
|
|
}()
|
|
return nil
|
|
})
|
|
|
|
fx.consCl.EXPECT().AddRecord(ctx, spaceId, inv.InviteRec).Return(expRes, nil)
|
|
fx.consCl.EXPECT().UnWatch(spaceId)
|
|
|
|
res, err := fx.AddRecord(ctx, spaceId, inv.InviteRec, Limits{
|
|
ReadMembers: 10,
|
|
WriteMembers: 10,
|
|
})
|
|
assert.Equal(t, expRes, res)
|
|
assert.NoError(t, err)
|
|
|
|
w := <-watcherCh
|
|
w.AddConsensusRecords([]*consensusproto.RawRecordWithId{
|
|
expRes,
|
|
})
|
|
})
|
|
t.Run("error", func(t *testing.T) {
|
|
fx := newFixture(t)
|
|
defer fx.finish(t)
|
|
|
|
var testErr = errors.New("test")
|
|
|
|
fx.consCl.EXPECT().Watch(spaceId, gomock.Any()).DoAndReturn(func(spaceId string, w consensusclient.Watcher) error {
|
|
go func() {
|
|
w.AddConsensusError(testErr)
|
|
}()
|
|
return nil
|
|
})
|
|
fx.consCl.EXPECT().UnWatch(spaceId)
|
|
|
|
res, err := fx.AddRecord(ctx, spaceId, inv.InviteRec, Limits{
|
|
ReadMembers: 10,
|
|
WriteMembers: 10,
|
|
})
|
|
assert.Nil(t, res)
|
|
assert.EqualError(t, err, testErr.Error())
|
|
})
|
|
t.Run("limit exceed", func(t *testing.T) {
|
|
fx := newFixture(t)
|
|
defer fx.finish(t)
|
|
_, err := fx.AddRecord(ctx, spaceId, inv.InviteRec, Limits{
|
|
ReadMembers: 1,
|
|
WriteMembers: 1,
|
|
})
|
|
assert.ErrorIs(t, err, ErrLimitExceed)
|
|
})
|
|
}
|
|
|
|
func TestAclService_RecordsAfter(t *testing.T) {
|
|
ownerKeys, err := accountdata.NewRandom()
|
|
require.NoError(t, err)
|
|
spaceId := "spaceId"
|
|
ownerAcl, err := list.NewInMemoryDerivedAcl(spaceId, ownerKeys)
|
|
require.NoError(t, err)
|
|
|
|
fx := newFixture(t)
|
|
defer fx.finish(t)
|
|
|
|
fx.consCl.EXPECT().Watch(spaceId, gomock.Any()).DoAndReturn(func(spaceId string, w consensusclient.Watcher) error {
|
|
go func() {
|
|
w.AddConsensusRecords([]*consensusproto.RawRecordWithId{
|
|
ownerAcl.Root(),
|
|
})
|
|
}()
|
|
return nil
|
|
})
|
|
fx.consCl.EXPECT().UnWatch(spaceId)
|
|
|
|
res, err := fx.RecordsAfter(ctx, spaceId, "")
|
|
require.NoError(t, err)
|
|
assert.Len(t, res, 1)
|
|
}
|
|
|
|
func TestAclService(t *testing.T) {
|
|
ownerKeys, err := accountdata.NewRandom()
|
|
require.NoError(t, err)
|
|
spaceId := "spaceId"
|
|
ownerAcl, err := list.NewInMemoryDerivedAcl(spaceId, ownerKeys)
|
|
require.NoError(t, err)
|
|
|
|
fx := newFixture(t)
|
|
defer fx.finish(t)
|
|
|
|
fx.consCl.EXPECT().Watch(spaceId, gomock.Any()).DoAndReturn(func(spaceId string, w consensusclient.Watcher) error {
|
|
go func() {
|
|
w.AddConsensusRecords([]*consensusproto.RawRecordWithId{
|
|
ownerAcl.Root(),
|
|
})
|
|
}()
|
|
return nil
|
|
})
|
|
fx.consCl.EXPECT().UnWatch(spaceId)
|
|
|
|
t.Run("permissions", func(t *testing.T) {
|
|
res, err := fx.Permissions(ctx, ownerKeys.SignKey.GetPublic(), spaceId)
|
|
require.NoError(t, err)
|
|
assert.True(t, res.IsOwner())
|
|
})
|
|
t.Run("ownerPubKey", func(t *testing.T) {
|
|
res, err := fx.OwnerPubKey(ctx, spaceId)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, ownerKeys.SignKey.GetPublic().Account(), res.Account())
|
|
})
|
|
}
|
|
|
|
func TestAclService_ReadState(t *testing.T) {
|
|
ownerKeys, err := accountdata.NewRandom()
|
|
require.NoError(t, err)
|
|
spaceId := "spaceId"
|
|
ownerAcl, err := list.NewInMemoryDerivedAcl(spaceId, ownerKeys)
|
|
require.NoError(t, err)
|
|
|
|
fx := newFixture(t)
|
|
defer fx.finish(t)
|
|
|
|
fx.consCl.EXPECT().Watch(spaceId, gomock.Any()).DoAndReturn(func(spaceId string, w consensusclient.Watcher) error {
|
|
go func() {
|
|
w.AddConsensusRecords([]*consensusproto.RawRecordWithId{
|
|
ownerAcl.Root(),
|
|
})
|
|
}()
|
|
return nil
|
|
})
|
|
fx.consCl.EXPECT().UnWatch(spaceId)
|
|
|
|
require.NoError(t, fx.ReadState(ctx, spaceId, func(s *list.AclState) error {
|
|
assert.NotNil(t, s)
|
|
return nil
|
|
}))
|
|
}
|
|
|
|
func TestAclService_HasRecord(t *testing.T) {
|
|
ownerKeys, err := accountdata.NewRandom()
|
|
require.NoError(t, err)
|
|
spaceId := "spaceId"
|
|
ownerAcl, err := list.NewInMemoryDerivedAcl(spaceId, ownerKeys)
|
|
require.NoError(t, err)
|
|
|
|
fx := newFixture(t)
|
|
defer fx.finish(t)
|
|
|
|
fx.consCl.EXPECT().Watch(spaceId, gomock.Any()).DoAndReturn(func(spaceId string, w consensusclient.Watcher) error {
|
|
go func() {
|
|
w.AddConsensusRecords([]*consensusproto.RawRecordWithId{
|
|
ownerAcl.Root(),
|
|
})
|
|
}()
|
|
return nil
|
|
})
|
|
fx.consCl.EXPECT().UnWatch(spaceId)
|
|
|
|
has, err := fx.HasRecord(ctx, spaceId, ownerAcl.Root().Id)
|
|
require.NoError(t, err)
|
|
assert.True(t, has)
|
|
|
|
has, err = fx.HasRecord(ctx, spaceId, "non-exists")
|
|
require.NoError(t, err)
|
|
assert.False(t, has)
|
|
}
|
|
|
|
func newFixture(t *testing.T) *fixture {
|
|
ctrl := gomock.NewController(t)
|
|
fx := &fixture{
|
|
a: new(app.App),
|
|
ctrl: ctrl,
|
|
consCl: mock_consensusclient.NewMockService(ctrl),
|
|
AclService: New(),
|
|
}
|
|
|
|
fx.consCl.EXPECT().Name().Return(consensusclient.CName).AnyTimes()
|
|
fx.consCl.EXPECT().Init(gomock.Any()).AnyTimes()
|
|
fx.consCl.EXPECT().Run(gomock.Any()).AnyTimes()
|
|
fx.consCl.EXPECT().Close(gomock.Any()).AnyTimes()
|
|
|
|
fx.a.Register(fx.consCl).Register(fx.AclService).Register(&accounttest.AccountTestService{})
|
|
|
|
require.NoError(t, fx.a.Start(ctx))
|
|
return fx
|
|
}
|
|
|
|
type fixture struct {
|
|
a *app.App
|
|
ctrl *gomock.Controller
|
|
consCl *mock_consensusclient.MockService
|
|
AclService
|
|
}
|
|
|
|
func (fx *fixture) finish(t *testing.T) {
|
|
require.NoError(t, fx.a.Close(ctx))
|
|
fx.ctrl.Finish()
|
|
}
|