make assignment unittests green

Signed-off-by: jkoberg <jkoberg@owncloud.com>
This commit is contained in:
jkoberg
2022-02-24 18:16:58 +01:00
parent 25191fe7d7
commit a762e3cf69
5 changed files with 137 additions and 31 deletions
+76 -4
View File
@@ -2,22 +2,94 @@
package store
import (
"errors"
"encoding/json"
"fmt"
"github.com/gofrs/uuid"
settingsmsg "github.com/owncloud/ocis/protogen/gen/ocis/messages/settings/v0"
)
var accountsFolderLocation = "settings/accounts"
// ListRoleAssignments loads and returns all role assignments matching the given assignment identifier.
func (s Store) ListRoleAssignments(accountUUID string) ([]*settingsmsg.UserRoleAssignment, error) {
return nil, errors.New("not implemented")
assIDs, err := s.mdc.ReadDir(nil, accountPath(accountUUID))
if err != nil {
return nil, err
}
var ass []*settingsmsg.UserRoleAssignment
for _, assID := range assIDs {
b, err := s.mdc.SimpleDownload(nil, assignmentPath(accountUUID, assID))
if err != nil {
return nil, err
}
a := &settingsmsg.UserRoleAssignment{}
err = json.Unmarshal(b, a)
if err != nil {
return nil, err
}
ass = append(ass, a)
}
return ass, nil
}
// WriteRoleAssignment appends the given role assignment to the existing assignments of the respective account.
func (s Store) WriteRoleAssignment(accountUUID, roleID string) (*settingsmsg.UserRoleAssignment, error) {
return nil, errors.New("not implemented")
// as per https://github.com/owncloud/product/issues/103 "Each user can have exactly one role"
assIDs, err := s.mdc.ReadDir(nil, accountPath(accountUUID))
if err != nil {
return nil, err
}
for _, assID := range assIDs {
err := s.mdc.Delete(nil, assignmentPath(accountUUID, assID))
if err != nil {
return nil, err
}
}
ass := &settingsmsg.UserRoleAssignment{
Id: uuid.Must(uuid.NewV4()).String(),
AccountUuid: accountUUID,
RoleId: roleID,
}
b, err := json.Marshal(ass)
if err != nil {
return nil, err
}
return ass, s.mdc.SimpleUpload(nil, assignmentPath(accountUUID, ass.Id), b)
}
// RemoveRoleAssignment deletes the given role assignment from the existing assignments of the respective account.
func (s Store) RemoveRoleAssignment(assignmentID string) error {
return errors.New("not implemented")
accounts, err := s.mdc.ReadDir(nil, accountsFolderLocation)
if err != nil {
return err
}
// TODO: use indexer to avoid spamming Metadata service
for _, accID := range accounts {
assIDs, err := s.mdc.ReadDir(nil, accountPath(accID))
if err != nil {
// TODO: error?
continue
}
for _, assID := range assIDs {
if assID == assignmentID {
return s.mdc.Delete(nil, assignmentPath(accID, assID))
}
}
}
return fmt.Errorf("assignmentID '%s' not found", assignmentID)
}
func accountPath(accountUUID string) string {
return fmt.Sprintf("%s/%s", accountsFolderLocation, accountUUID)
}
func assignmentPath(accountUUID string, assignmentID string) string {
return fmt.Sprintf("%s/%s/%s", accountsFolderLocation, accountUUID, assignmentID)
}
+22 -21
View File
@@ -6,7 +6,7 @@ import (
olog "github.com/owncloud/ocis/ocis-pkg/log"
settingsmsg "github.com/owncloud/ocis/protogen/gen/ocis/messages/settings/v0"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
var (
@@ -109,25 +109,25 @@ func TestAssignmentUniqueness(t *testing.T) {
scenario := scenario
t.Run(scenario.name, func(t *testing.T) {
firstAssignment, err := s.WriteRoleAssignment(scenario.userID, scenario.firstRole)
assert.NoError(t, err)
assert.Equal(t, firstAssignment.RoleId, scenario.firstRole)
require.NoError(t, err)
require.Equal(t, firstAssignment.RoleId, scenario.firstRole)
// TODO: check entry exists
list, err := s.ListRoleAssignments(scenario.userID)
assert.NoError(t, err)
assert.Equal(t, 1, len(list))
assert.Equal(t, list[0].RoleId, scenario.firstRole)
require.NoError(t, err)
require.Equal(t, 1, len(list))
require.Equal(t, list[0].RoleId, scenario.firstRole)
// creating another assignment shouldn't add another entry, as we support max one role per user.
// assigning the second role should remove the old
secondAssignment, err := s.WriteRoleAssignment(scenario.userID, scenario.secondRole)
assert.NoError(t, err)
assert.Equal(t, secondAssignment.RoleId, scenario.secondRole)
require.NoError(t, err)
require.Equal(t, secondAssignment.RoleId, scenario.secondRole)
list, err = s.ListRoleAssignments(scenario.userID)
assert.NoError(t, err)
assert.Equal(t, 1, len(list))
assert.Equal(t, list[0].RoleId, scenario.secondRole)
require.NoError(t, err)
require.Equal(t, 1, len(list))
require.Equal(t, list[0].RoleId, scenario.secondRole)
})
}
}
@@ -151,26 +151,27 @@ func TestDeleteAssignment(t *testing.T) {
scenario := scenario
t.Run(scenario.name, func(t *testing.T) {
assignment, err := s.WriteRoleAssignment(scenario.userID, scenario.firstRole)
assert.NoError(t, err)
assert.Equal(t, assignment.RoleId, scenario.firstRole)
require.NoError(t, err)
require.Equal(t, assignment.RoleId, scenario.firstRole)
// TODO: uncomment
// assert.True(t, mdc.IDExists(assignment.RoleId))
// require.True(t, mdc.IDExists(assignment.RoleId))
list, err := s.ListRoleAssignments(scenario.userID)
assert.NoError(t, err)
assert.Equal(t, 1, len(list))
require.NoError(t, err)
require.Equal(t, 1, len(list))
require.Equal(t, assignment.Id, list[0].Id)
err = s.RemoveRoleAssignment(assignment.Id)
assert.NoError(t, err)
require.NoError(t, err)
// TODO: uncomment
// assert.False(t, mdc.IDExists(assignment.RoleId))
// require.False(t, mdc.IDExists(assignment.RoleId))
list, err = s.ListRoleAssignments(scenario.userID)
assert.NoError(t, err)
assert.Equal(t, 0, len(list))
require.NoError(t, err)
require.Equal(t, 0, len(list))
err = s.RemoveRoleAssignment(assignment.Id)
assert.Error(t, err)
require.Error(t, err)
// TODO: do we want a custom error message?
})
}
+12 -5
View File
@@ -2,14 +2,13 @@
package store
import (
"encoding/json"
"errors"
"sync"
"fmt"
settingsmsg "github.com/owncloud/ocis/protogen/gen/ocis/messages/settings/v0"
)
var m = &sync.RWMutex{}
// ListBundles returns all bundles in the dataPath folder that match the given type.
func (s Store) ListBundles(bundleType settingsmsg.Bundle_Type, bundleIDs []string) ([]*settingsmsg.Bundle, error) {
return nil, errors.New("not implemented")
@@ -25,9 +24,13 @@ func (s Store) ReadSetting(settingID string) (*settingsmsg.Setting, error) {
return nil, errors.New("not implemented")
}
// WriteBundle writes the given record into a file within the dataPath.
// WriteBundle sends the givens record to the metadataclient. returns `record` for legacy reasons
func (s Store) WriteBundle(record *settingsmsg.Bundle) (*settingsmsg.Bundle, error) {
return nil, errors.New("not implemented")
b, err := json.Marshal(record)
if err != nil {
return nil, err
}
return record, s.mdc.SimpleUpload(nil, bundlePath(record.Id), b)
}
// AddSettingToBundle adds the given setting to the bundle with the given bundleID.
@@ -39,3 +42,7 @@ func (s Store) AddSettingToBundle(bundleID string, setting *settingsmsg.Setting)
func (s Store) RemoveSettingFromBundle(bundleID string, settingID string) error {
return errors.New("not implemented")
}
func bundlePath(id string) string {
return fmt.Sprintf("bundle/%s", id)
}
+1
View File
@@ -21,6 +21,7 @@ type MetadataClient interface {
SimpleDownload(ctx context.Context, id string) ([]byte, error)
SimpleUpload(ctx context.Context, id string, content []byte) error
Delete(ctx context.Context, id string) error
ReadDir(ctx context.Context, id string) ([]string, error)
}
// Store interacts with the filesystem to manage settings information
+26 -1
View File
@@ -1,6 +1,9 @@
package store
import "context"
import (
"context"
"strings"
)
const (
// account UUIDs
@@ -33,6 +36,13 @@ type MockedMetadataClient struct {
data map[string][]byte
}
func keys(m map[string][]byte) (s []string) {
for k := range m {
s = append(s, k)
}
return
}
// SimpleDownload returns nil if not found
func (m *MockedMetadataClient) SimpleDownload(_ context.Context, id string) ([]byte, error) {
return m.data[id], nil
@@ -50,6 +60,21 @@ func (m *MockedMetadataClient) Delete(_ context.Context, id string) error {
return nil
}
// ReadDir returns nil, nil if not found
// Known flaw: lists also subdirs
func (m *MockedMetadataClient) ReadDir(_ context.Context, id string) ([]string, error) {
var out []string
for k := range m.data {
if strings.HasPrefix(k, id) {
dir := strings.TrimPrefix(k, id+"/")
// filter subfolders the lame way
s := strings.Trim(strings.SplitAfter(dir, "/")[0], "/")
out = append(out, s)
}
}
return out, nil
}
// IDExists is a helper to check if an id exists
func (m *MockedMetadataClient) IDExists(id string) bool {
_, ok := m.data[id]