refactor: align AX surfaces and semantic file names
This commit is contained in:
parent
e8b87dfbee
commit
0927aab29d
7 changed files with 86 additions and 48 deletions
|
|
@ -1,4 +1,4 @@
|
|||
// Package datanode keeps io.Medium data in Borg's DataNode.
|
||||
// Package datanode provides an io.Medium implementation backed by Borg's DataNode.
|
||||
//
|
||||
// medium := datanode.New()
|
||||
// _ = medium.Write("jobs/run.log", "started")
|
||||
|
|
@ -96,7 +96,7 @@ func TestClient_Delete_Good(t *testing.T) {
|
|||
func TestClient_Delete_Bad(t *testing.T) {
|
||||
m := New()
|
||||
|
||||
// Delete non-existent
|
||||
// Example: m.Delete("ghost.txt")
|
||||
assert.Error(t, m.Delete("ghost.txt"))
|
||||
|
||||
// Delete non-empty dir
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Package local binds io.Medium to the local filesystem.
|
||||
// Package local provides the io.Medium implementation for the local filesystem.
|
||||
//
|
||||
// medium, _ := local.New("/srv/app")
|
||||
// _ = medium.Write("config/app.yaml", "port: 8080")
|
||||
|
|
@ -15,7 +15,7 @@ func TestClient_New_ResolvesRoot_Good(t *testing.T) {
|
|||
root := t.TempDir()
|
||||
m, err := New(root)
|
||||
assert.NoError(t, err)
|
||||
// New() resolves symlinks (macOS /var → /private/var), so compare resolved paths.
|
||||
// Example: local.New("/srv/app") resolves macOS "/var" to "/private/var" before sandbox checks.
|
||||
resolved, err := resolveSymlinksPath(root)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, resolved, m.filesystemRoot)
|
||||
|
|
@ -9,7 +9,7 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// --- MemoryMedium Compatibility Tests ---
|
||||
// --- MemoryMedium Tests ---
|
||||
|
||||
func TestClient_NewMemoryMedium_Good(t *testing.T) {
|
||||
medium := NewMemoryMedium()
|
||||
|
|
@ -24,6 +24,23 @@ type CryptProvider interface {
|
|||
CreateKeyPair(name, passphrase string) (string, error)
|
||||
}
|
||||
|
||||
const (
|
||||
WorkspaceCreateAction = "workspace.create"
|
||||
WorkspaceSwitchAction = "workspace.switch"
|
||||
)
|
||||
|
||||
// Example: command := WorkspaceCommand{
|
||||
// Action: WorkspaceCreateAction,
|
||||
// Identifier: "alice",
|
||||
// Password: "pass123",
|
||||
// }
|
||||
type WorkspaceCommand struct {
|
||||
Action string
|
||||
Identifier string
|
||||
Password string
|
||||
WorkspaceID string
|
||||
}
|
||||
|
||||
// Example: service, _ := workspace.New(workspace.Options{Core: core.New(), Crypt: cryptProvider})
|
||||
type Options struct {
|
||||
// Core is the Core runtime used by the service.
|
||||
|
|
@ -168,41 +185,44 @@ func (service *Service) WorkspaceFileSet(workspaceFilePath, content string) erro
|
|||
return service.medium.Write(filePath, content)
|
||||
}
|
||||
|
||||
// service, _ := workspace.New(workspace.Options{Core: core.New(), Crypt: myCryptProvider})
|
||||
//
|
||||
// createResult := service.HandleIPCEvents(core.New(), map[string]any{
|
||||
// "action": "workspace.create",
|
||||
// "identifier": "alice",
|
||||
// "password": "pass123",
|
||||
// })
|
||||
//
|
||||
// switchResult := service.HandleIPCEvents(core.New(), map[string]any{
|
||||
// "action": "workspace.switch",
|
||||
// "workspaceID": "f3f0d7",
|
||||
// })
|
||||
//
|
||||
// _ = createResult.OK
|
||||
// _ = switchResult.OK
|
||||
// Example: result := service.HandleWorkspaceCommand(WorkspaceCommand{
|
||||
// Action: WorkspaceCreateAction,
|
||||
// Identifier: "alice",
|
||||
// Password: "pass123",
|
||||
// })
|
||||
func (service *Service) HandleWorkspaceCommand(command WorkspaceCommand) core.Result {
|
||||
switch command.Action {
|
||||
case WorkspaceCreateAction:
|
||||
workspaceID, err := service.CreateWorkspace(command.Identifier, command.Password)
|
||||
if err != nil {
|
||||
return core.Result{}.New(err)
|
||||
}
|
||||
return core.Result{Value: workspaceID, OK: true}
|
||||
case WorkspaceSwitchAction:
|
||||
if err := service.SwitchWorkspace(command.WorkspaceID); err != nil {
|
||||
return core.Result{}.New(err)
|
||||
}
|
||||
return core.Result{OK: true}
|
||||
}
|
||||
return core.Result{OK: true}
|
||||
}
|
||||
|
||||
// Example: result := service.HandleIPCEvents(core.New(), map[string]any{
|
||||
// "action": WorkspaceSwitchAction,
|
||||
// "workspaceID": "f3f0d7",
|
||||
// })
|
||||
// HandleIPCEvents preserves the legacy map[string]any payload and still accepts WorkspaceCommand values.
|
||||
func (service *Service) HandleIPCEvents(_ *core.Core, message core.Message) core.Result {
|
||||
switch payload := message.(type) {
|
||||
case WorkspaceCommand:
|
||||
return service.HandleWorkspaceCommand(payload)
|
||||
case map[string]any:
|
||||
action, _ := payload["action"].(string)
|
||||
switch action {
|
||||
case "workspace.create":
|
||||
identifier, _ := payload["identifier"].(string)
|
||||
password, _ := payload["password"].(string)
|
||||
workspaceID, err := service.CreateWorkspace(identifier, password)
|
||||
if err != nil {
|
||||
return core.Result{}.New(err)
|
||||
}
|
||||
return core.Result{Value: workspaceID, OK: true}
|
||||
case "workspace.switch":
|
||||
workspaceID, _ := payload["workspaceID"].(string)
|
||||
if err := service.SwitchWorkspace(workspaceID); err != nil {
|
||||
return core.Result{}.New(err)
|
||||
}
|
||||
return core.Result{OK: true}
|
||||
}
|
||||
command := WorkspaceCommand{}
|
||||
command.Action, _ = payload["action"].(string)
|
||||
command.Identifier, _ = payload["identifier"].(string)
|
||||
command.Password, _ = payload["password"].(string)
|
||||
command.WorkspaceID, _ = payload["workspaceID"].(string)
|
||||
return service.HandleWorkspaceCommand(command)
|
||||
}
|
||||
return core.Result{OK: true}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,13 +88,13 @@ func TestService_WorkspaceFileSet_TraversalBlocked_Bad(t *testing.T) {
|
|||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestService_HandleIPCEvents_Good(t *testing.T) {
|
||||
func TestService_HandleWorkspaceCommand_Good(t *testing.T) {
|
||||
s, _ := newTestService(t)
|
||||
|
||||
create := s.HandleIPCEvents(core.New(), map[string]any{
|
||||
"action": "workspace.create",
|
||||
"identifier": "ipc-user",
|
||||
"password": "pass123",
|
||||
create := s.HandleWorkspaceCommand(WorkspaceCommand{
|
||||
Action: WorkspaceCreateAction,
|
||||
Identifier: "ipc-user",
|
||||
Password: "pass123",
|
||||
})
|
||||
assert.True(t, create.OK)
|
||||
|
||||
|
|
@ -102,22 +102,40 @@ func TestService_HandleIPCEvents_Good(t *testing.T) {
|
|||
require.True(t, ok)
|
||||
require.NotEmpty(t, workspaceID)
|
||||
|
||||
switchResult := s.HandleIPCEvents(core.New(), map[string]any{
|
||||
"action": "workspace.switch",
|
||||
"workspaceID": workspaceID,
|
||||
switchResult := s.HandleWorkspaceCommand(WorkspaceCommand{
|
||||
Action: WorkspaceSwitchAction,
|
||||
WorkspaceID: workspaceID,
|
||||
})
|
||||
assert.True(t, switchResult.OK)
|
||||
assert.Equal(t, workspaceID, s.activeWorkspaceID)
|
||||
|
||||
legacyCreate := s.HandleIPCEvents(core.New(), map[string]any{
|
||||
"action": WorkspaceCreateAction,
|
||||
"identifier": "legacy-user",
|
||||
"password": "pass123",
|
||||
})
|
||||
assert.True(t, legacyCreate.OK)
|
||||
|
||||
legacyWorkspaceID, ok := legacyCreate.Value.(string)
|
||||
require.True(t, ok)
|
||||
require.NotEmpty(t, legacyWorkspaceID)
|
||||
|
||||
legacySwitch := s.HandleIPCEvents(core.New(), WorkspaceCommand{
|
||||
Action: WorkspaceSwitchAction,
|
||||
WorkspaceID: legacyWorkspaceID,
|
||||
})
|
||||
assert.True(t, legacySwitch.OK)
|
||||
assert.Equal(t, legacyWorkspaceID, s.activeWorkspaceID)
|
||||
|
||||
rejectedLegacySwitch := s.HandleIPCEvents(core.New(), map[string]any{
|
||||
"action": "workspace.switch",
|
||||
"action": WorkspaceSwitchAction,
|
||||
"name": workspaceID,
|
||||
})
|
||||
assert.False(t, rejectedLegacySwitch.OK)
|
||||
assert.Equal(t, workspaceID, s.activeWorkspaceID)
|
||||
assert.Equal(t, legacyWorkspaceID, s.activeWorkspaceID)
|
||||
|
||||
failedSwitch := s.HandleIPCEvents(core.New(), map[string]any{
|
||||
"action": "workspace.switch",
|
||||
"action": WorkspaceSwitchAction,
|
||||
"workspaceID": "missing",
|
||||
})
|
||||
assert.False(t, failedSwitch.OK)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue