Skip to content

Commit

Permalink
go part cms-307
Browse files Browse the repository at this point in the history
  • Loading branch information
hdphuong committed Jan 31, 2023
1 parent 17a6ef6 commit 5a6f3ae
Show file tree
Hide file tree
Showing 10 changed files with 99 additions and 8 deletions.
2 changes: 1 addition & 1 deletion backend/editor/OT/operations/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,5 @@ func (op Operation) ApplyTo(document cmsjson.AstNode) (cmsjson.AstNode, error) {
}

applicationIndex := op.Path[len(op.Path)-1]
return op.Operation.Apply(parent, applicationIndex, op.OperationType)
return op.Operation.Apply(parent, applicationIndex, op.Operation.GetEditType())
}
7 changes: 7 additions & 0 deletions backend/editor/OT/operations/array_operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
// @implements OperationModel
type ArrayOperation struct {
NewValue float64
operationType EditType
}

// TransformAgainst is the ArrayOperation implementation of the operationModel interface
Expand Down Expand Up @@ -38,3 +39,9 @@ func (arrOp ArrayOperation) Apply(parentNode cmsjson.AstNode, applicationIndex i

return nil, errors.New("invalid application of an array operation, expected parent node to be an array")
}

// getEditType is the ArrayOperation implementation of the OperationModel interface
func (arrOp ArrayOperation) GetEditType() EditType {
return arrOp.operationType
}

7 changes: 7 additions & 0 deletions backend/editor/OT/operations/boolean_operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
// @implements OperationModel
type BooleanOperation struct {
NewValue bool
operationType EditType
}

// TransformAgainst is the BooleanOperation implementation of the operationModel interface
Expand All @@ -31,3 +32,9 @@ func (boolOp BooleanOperation) Apply(parentNode cmsjson.AstNode, applicationInde
}
return nil, errors.New("invalid application of a primitive operation, expected parent node to be a primitive")
}

// getEditType is the BooleanOperation implementation of the OperationModel interface
func (boolOp BooleanOperation) GetEditType() EditType {
return boolOp.operationType
}

7 changes: 7 additions & 0 deletions backend/editor/OT/operations/integer_operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
// @implementations of OperationModel
type IntegerOperation struct {
NewValue int
operationType EditType
}

// TransformAgainst is the IntegerOperation implementation of the operationModel interface
Expand All @@ -31,3 +32,9 @@ func (intOp IntegerOperation) Apply(parentNode cmsjson.AstNode, applicationIndex
}
return nil, errors.New("invalid application of a primitive operation, expected parent node to be a primitive")
}

// getEditType is the IntegerOperation implementation of the OperationModel interface
func (intOp IntegerOperation) GetEditType() EditType {
return intOp.operationType
}

9 changes: 8 additions & 1 deletion backend/editor/OT/operations/noop_operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import "cms.csesoc.unsw.edu.au/pkg/cmsjson"

// Noop represents a non-existent operation
// @implements OperationModel
type Noop struct{}
type Noop struct {
operationType EditType
}

// TransformAgainst is the noop implementation of the operationModel interface
func (noop Noop) TransformAgainst(operation OperationModel, applicationType EditType) (OperationModel, OperationModel) {
Expand All @@ -15,3 +17,8 @@ func (noop Noop) TransformAgainst(operation OperationModel, applicationType Edit
func (noop Noop) Apply(parentNode cmsjson.AstNode, applicationIndex int, applicationType EditType) (cmsjson.AstNode, error) {
return parentNode, nil
}

// getEditType is the noop implementation of the OperationModel interface
func (noop Noop) GetEditType() EditType {
return noop.operationType
}
7 changes: 7 additions & 0 deletions backend/editor/OT/operations/object_operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
// ObjectOperation represents an operation we perform on an object
type ObjectOperation struct {
NewValue datamodel.DataType
operationType EditType
}

// TransformAgainst is the ArrayOperation implementation of the operationModel interface
Expand All @@ -37,3 +38,9 @@ func (objOp ObjectOperation) Apply(parentNode cmsjson.AstNode, applicationIndex
}
return nil, errors.New("invalid application of an object operation, expected parent node to be an object")
}

// getEditType is the ArrayOperation implementation of the OperationModel interface
func (objOp ObjectOperation) GetEditType() EditType {
return objOp.operationType
}

7 changes: 3 additions & 4 deletions backend/editor/OT/operations/operation_model.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,15 @@ type (
OperationModel interface {
TransformAgainst(op OperationModel, applicationType EditType) (OperationModel, OperationModel)
Apply(parentNode cmsjson.AstNode, applicationIndex int, applicationType EditType) (cmsjson.AstNode, error)
GetEditType() EditType
}

// Operation is the fundamental incoming type from the frontend
Operation struct {
Path []int
OperationType EditType
AcknowledgedServerOps int

IsNoOp bool
Operation OperationModel
IsNoOp bool
Operation OperationModel
}
)

Expand Down
7 changes: 7 additions & 0 deletions backend/editor/OT/operations/string_operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
type StringOperation struct {
RangeStart, RangeEnd int
NewValue string
operationType EditType
}

// If NewValue == "", delete every character between RangeStart and RangeEnd
Expand Down Expand Up @@ -139,3 +140,9 @@ func deleteDelete(o1 StringOperation, o2 StringOperation, isLast bool) StringOpe
}
return o1
}

// getEditType is the ArrayOperation implementation of the OperationModel interface
func (arrOp StringOperation) GetEditType() EditType {
return arrOp.operationType
}

4 changes: 2 additions & 2 deletions backend/editor/OT/operations/transform.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ package operations
func TransformPipeline(x Operation, y Operation) (Operation, Operation) {
// Finally normalise the operations to account for no-op return values
needsAppSpecific := false
x.Path, y.Path, needsAppSpecific = transformPaths(x.Path, y.Path, x.OperationType, y.OperationType)
x.Path, y.Path, needsAppSpecific = transformPaths(x.Path, y.Path, x.Operation.GetEditType(), y.Operation.GetEditType())
x, y = normaliseOperation(x), normaliseOperation(y)

if needsAppSpecific {
x.Operation.TransformAgainst(y.Operation, x.OperationType)
x.Operation.TransformAgainst(y.Operation, x.Operation.GetEditType())
}

return x, y
Expand Down
50 changes: 50 additions & 0 deletions backend/endpoints/tests/volume_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,56 @@ import (
)

func TestUploadDocument(t *testing.T) {
controller := gomock.NewController(t)
assert := assert.New(t)
defer controller.Finish()

// ==== test setup =====
entityID := uuid.New()
parentID := uuid.New()
entityToCreate := repositories.FilesystemEntry{
LogicalName: "file",
ParentFileID: parentID,
IsDocument: true,
OwnerUserId: 1,
}

mockFileRepo := repMocks.NewMockIFilesystemRepository(controller)
mockFileRepo.EXPECT().CreateEntry(entityToCreate).Return(repositories.FilesystemEntry{
EntityID: entityID,
LogicalName: "file",
ParentFileID: parentID,
IsDocument: true,
OwnerUserId: 1,
}, nil).Times(1)

temp, _ := ioutil.TempFile(os.TempDir(), "expected")
defer os.Remove(temp.Name())

mockDockerFileSystemRepo := repMocks.NewMockIUnpublishedVolumeRepository(controller)
mockDockerFileSystemRepo.EXPECT().GetFromVolume(entityID.String()).Return(temp, nil).Times(1)

mockDepFactory := createMockDependencyFactory(controller, mockFileRepo, true)
mockDepFactory.EXPECT().GetUnpublishedVolumeRepo().Return(mockDockerFileSystemRepo)

const fileContent = "Hello World"

form := models.ValidDocumentUploadRequest{
Parent: parentID,
DocumentName: "file",
Content: fileContent,
}

response := endpoints.UploadDocument(form, mockDepFactory)
assert.Equal(response.Status, http.StatusOK)
assert.Equal(response.Response, models.NewEntityResponse{
NewID: entityID,
})

// check that the file was written to the docker volume
actual, _ := ioutil.ReadFile(temp.Name())
assert.Equal(actual, []byte(fileContent))

}

func TestGetPublishedDocument(t *testing.T) {
Expand Down

0 comments on commit 5a6f3ae

Please sign in to comment.