Skip to content

Commit

Permalink
introduce storedName for files, so files can be stored with a differe…
Browse files Browse the repository at this point in the history
…nt name from their real uploaded name
  • Loading branch information
khanzadimahdi committed Jan 11, 2025
1 parent 14be04a commit 29f8945
Show file tree
Hide file tree
Showing 17 changed files with 169 additions and 142 deletions.
2 changes: 1 addition & 1 deletion backend/application/dashboard/file/deleteFile/usecase.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func (uc *UseCase) Execute(request Request) error {
return err
}

if err := uc.storage.Delete(context.Background(), file.Name); err != nil {
if err := uc.storage.Delete(context.Background(), file.StoredName); err != nil {
return err
}

Expand Down
21 changes: 12 additions & 9 deletions backend/application/dashboard/file/deleteFile/usecase_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,17 @@ func TestUseCase_Execute(t *testing.T) {
r = Request{FileUUID: "file-uuid"}

f = file.File{
UUID: r.FileUUID,
Name: "file-name",
UUID: r.FileUUID,
Name: "file-name",
StoredName: "store-name",
}
)

filesRepository.On("GetOne", r.FileUUID).Once().Return(f, nil)
filesRepository.On("Delete", r.FileUUID).Return(nil)
defer filesRepository.AssertExpectations(t)

storage.On("Delete", context.Background(), f.Name).Once().Return(nil)
storage.On("Delete", context.Background(), f.StoredName).Once().Return(nil)
defer storage.AssertExpectations(t)

err := NewUseCase(&filesRepository, &storage).Execute(r)
Expand Down Expand Up @@ -73,8 +74,9 @@ func TestUseCase_Execute(t *testing.T) {
r = Request{FileUUID: "file-uuid"}

f = file.File{
UUID: r.FileUUID,
Name: "file-name",
UUID: r.FileUUID,
Name: "file-name",
StoredName: "store-name",
}

expectedErr = errors.New("error")
Expand All @@ -83,7 +85,7 @@ func TestUseCase_Execute(t *testing.T) {
filesRepository.On("GetOne", r.FileUUID).Once().Return(f, nil)
defer filesRepository.AssertExpectations(t)

storage.On("Delete", context.Background(), f.Name).Once().Return(expectedErr)
storage.On("Delete", context.Background(), f.StoredName).Once().Return(expectedErr)
defer storage.AssertExpectations(t)

err := NewUseCase(&filesRepository, &storage).Execute(r)
Expand All @@ -103,8 +105,9 @@ func TestUseCase_Execute(t *testing.T) {
r = Request{FileUUID: "file-uuid"}

f = file.File{
UUID: r.FileUUID,
Name: "file-name",
UUID: r.FileUUID,
Name: "file-name",
StoredName: "store-name",
}

expectedErr = errors.New("error")
Expand All @@ -114,7 +117,7 @@ func TestUseCase_Execute(t *testing.T) {
filesRepository.On("Delete", r.FileUUID).Return(expectedErr)
defer filesRepository.AssertExpectations(t)

storage.On("Delete", context.Background(), f.Name).Once().Return(nil)
storage.On("Delete", context.Background(), f.StoredName).Once().Return(nil)
defer storage.AssertExpectations(t)

err := NewUseCase(&filesRepository, &storage).Execute(r)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func (uc *UseCase) Execute(request Request) error {
return err
}

if err := uc.storage.Delete(context.Background(), file.Name); err != nil {
if err := uc.storage.Delete(context.Background(), file.StoredName); err != nil {
return err
}

Expand Down
27 changes: 15 additions & 12 deletions backend/application/dashboard/file/deleteUserFile/usecase_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,18 @@ func TestUseCase_Execute(t *testing.T) {
}

f = file.File{
UUID: r.FileUUID,
Name: "file-name",
OwnerUUID: r.OwnerUUID,
UUID: r.FileUUID,
Name: "file-name",
StoredName: "store-name",
OwnerUUID: r.OwnerUUID,
}
)

filesRepository.On("GetOneByOwnerUUID", r.OwnerUUID, r.FileUUID).Once().Return(f, nil)
filesRepository.On("DeleteByOwnerUUID", r.OwnerUUID, r.FileUUID).Return(nil)
defer filesRepository.AssertExpectations(t)

storage.On("Delete", context.Background(), f.Name).Once().Return(nil)
storage.On("Delete", context.Background(), f.StoredName).Once().Return(nil)
defer storage.AssertExpectations(t)

err := NewUseCase(&filesRepository, &storage).Execute(r)
Expand Down Expand Up @@ -83,9 +84,10 @@ func TestUseCase_Execute(t *testing.T) {
}

f = file.File{
UUID: r.FileUUID,
Name: "file-name",
OwnerUUID: r.OwnerUUID,
UUID: r.FileUUID,
Name: "file-name",
StoredName: "store-name",
OwnerUUID: r.OwnerUUID,
}

expectedErr = errors.New("error")
Expand All @@ -94,7 +96,7 @@ func TestUseCase_Execute(t *testing.T) {
filesRepository.On("GetOneByOwnerUUID", r.OwnerUUID, r.FileUUID).Once().Return(f, nil)
defer filesRepository.AssertExpectations(t)

storage.On("Delete", context.Background(), f.Name).Once().Return(expectedErr)
storage.On("Delete", context.Background(), f.StoredName).Once().Return(expectedErr)
defer storage.AssertExpectations(t)

err := NewUseCase(&filesRepository, &storage).Execute(r)
Expand All @@ -117,9 +119,10 @@ func TestUseCase_Execute(t *testing.T) {
}

f = file.File{
UUID: r.FileUUID,
Name: "file-name",
OwnerUUID: r.OwnerUUID,
UUID: r.FileUUID,
Name: "file-name",
StoredName: "store-name",
OwnerUUID: r.OwnerUUID,
}

expectedErr = errors.New("error")
Expand All @@ -129,7 +132,7 @@ func TestUseCase_Execute(t *testing.T) {
filesRepository.On("DeleteByOwnerUUID", r.OwnerUUID, r.FileUUID).Return(expectedErr)
defer filesRepository.AssertExpectations(t)

storage.On("Delete", context.Background(), f.Name).Once().Return(nil)
storage.On("Delete", context.Background(), f.StoredName).Once().Return(nil)
defer storage.AssertExpectations(t)

err := NewUseCase(&filesRepository, &storage).Execute(r)
Expand Down
2 changes: 1 addition & 1 deletion backend/application/dashboard/file/getFile/useCase.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func (uc *UseCase) Execute(UUID string) (*Response, error) {
return nil, err
}

reader, err := uc.storage.Read(context.Background(), f.UUID)
reader, err := uc.storage.Read(context.Background(), f.StoredName)
if err != nil {
return nil, err
}
Expand Down
16 changes: 16 additions & 0 deletions backend/application/dashboard/file/uploadFile/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package createfile

import (
"io"
"path/filepath"

"github.com/gofrs/uuid/v5"
"github.com/khanzadimahdi/testproject/domain"
)

Expand Down Expand Up @@ -37,3 +39,17 @@ func (r *Request) Validate() domain.ValidationErrors {

return validationErrors
}

func (r *Request) StoredName() (string, error) {
var filename string

extension := filepath.Ext(r.Name)

uuid, err := uuid.NewV7()
if err != nil {
return filename, err
}
filename = uuid.String() + extension

return filename, nil
}
20 changes: 12 additions & 8 deletions backend/application/dashboard/file/uploadFile/usecase.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,23 @@ func (uc *UseCase) Execute(request *Request) (*Response, error) {
}, nil
}

uuid, err := uc.filesRepository.Save(&file.File{
Name: request.Name,
Size: request.Size,
OwnerUUID: request.OwnerUUID,
MimeType: request.MimeType,
})
storedName, err := request.StoredName()
if err != nil {
return nil, err
}

if err := uc.storage.Store(context.Background(), uuid, request.FileReader, request.Size); err != nil {
_ = uc.filesRepository.Delete(uuid)
if err := uc.storage.Store(context.Background(), storedName, request.FileReader, request.Size); err != nil {
return nil, err
}

uuid, err := uc.filesRepository.Save(&file.File{
Name: request.Name,
StoredName: storedName,
Size: request.Size,
OwnerUUID: request.OwnerUUID,
MimeType: request.MimeType,
})
if err != nil {
return nil, err
}

Expand Down
66 changes: 28 additions & 38 deletions backend/application/dashboard/file/uploadFile/usecase_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ package createfile
import (
"context"
"errors"
"path/filepath"
"strings"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"

"github.com/khanzadimahdi/testproject/domain"
"github.com/khanzadimahdi/testproject/domain/file"
Expand All @@ -33,12 +35,7 @@ func TestUseCase_Execute(t *testing.T) {
OwnerUUID: "owner-uuid",
FileReader: strings.NewReader(fileContent),
Size: int64(len(fileContent)),
}

f = file.File{
Name: r.Name,
Size: r.Size,
OwnerUUID: r.OwnerUUID,
MimeType: "application/octet-stream",
}

fileUUID = "test-file-uuid"
Expand All @@ -51,15 +48,17 @@ func TestUseCase_Execute(t *testing.T) {
validator.On("Validate", &r).Once().Return(nil)
defer validator.AssertExpectations(t)

filesRepository.On("Save", &f).Once().Return(fileUUID, nil)
defer filesRepository.AssertExpectations(t)

storage.On("Store", context.Background(), fileUUID, r.FileReader, r.Size).Once().Return(nil)
storage.On("Store", context.Background(), mock.Anything, r.FileReader, r.Size).Once().Return(nil)
defer storage.AssertExpectations(t)

response, err := NewUseCase(&filesRepository, &storage, &validator).Execute(&r)
matchingFile := mock.MatchedBy(func(f *file.File) bool {
return f.Name == r.Name && f.Size == r.Size && f.OwnerUUID == r.OwnerUUID && f.MimeType == r.MimeType && filepath.Ext(f.Name) == filepath.Ext(f.StoredName)
})

filesRepository.AssertNotCalled(t, "Delete")
filesRepository.On("Save", matchingFile).Once().Return(fileUUID, nil)
defer filesRepository.AssertExpectations(t)

response, err := NewUseCase(&filesRepository, &storage, &validator).Execute(&r)

assert.NoError(t, err)
assert.Equal(t, &expectedResponse, response)
Expand Down Expand Up @@ -91,7 +90,6 @@ func TestUseCase_Execute(t *testing.T) {

filesRepository.AssertNotCalled(t, "Save")
storage.AssertNotCalled(t, "Store")
filesRepository.AssertNotCalled(t, "Delete")

assert.NoError(t, err)
assert.Equal(t, &expectedResponse, response)
Expand All @@ -112,33 +110,24 @@ func TestUseCase_Execute(t *testing.T) {
OwnerUUID: "owner-uuid",
FileReader: strings.NewReader(fileContent),
Size: int64(len(fileContent)),
MimeType: "application/octet-stream",
}

f = file.File{
Name: r.Name,
Size: r.Size,
OwnerUUID: r.OwnerUUID,
}

fileUUID = "test-file-uuid"

expectedErr = errors.New("storage error")
)

validator.On("Validate", &r).Once().Return(nil)
defer validator.AssertExpectations(t)

filesRepository.On("Save", &f).Once().Return(fileUUID, nil)
defer filesRepository.AssertExpectations(t)

storage.On("Store", context.Background(), fileUUID, r.FileReader, r.Size).Once().Return(expectedErr)
storage.On("Store", context.Background(), mock.MatchedBy(func(storedName string) bool {
return filepath.Ext(r.Name) == filepath.Ext(storedName) && storedName != r.Name
}), r.FileReader, r.Size).Once().Return(expectedErr)
defer storage.AssertExpectations(t)

filesRepository.On("Delete", fileUUID).Once().Return(nil)
defer filesRepository.AssertExpectations(t)

response, err := NewUseCase(&filesRepository, &storage, &validator).Execute(&r)

filesRepository.AssertNotCalled(t, "Save")

assert.ErrorIs(t, err, expectedErr)
assert.Nil(t, response)
})
Expand All @@ -158,12 +147,7 @@ func TestUseCase_Execute(t *testing.T) {
OwnerUUID: "owner-uuid",
FileReader: strings.NewReader(fileContent),
Size: int64(len(fileContent)),
}

f = file.File{
Name: r.Name,
Size: r.Size,
OwnerUUID: r.OwnerUUID,
MimeType: "application/octet-stream",
}

expectedErr = errors.New("error")
Expand All @@ -172,14 +156,20 @@ func TestUseCase_Execute(t *testing.T) {
validator.On("Validate", &r).Once().Return(nil)
defer validator.AssertExpectations(t)

filesRepository.On("Save", &f).Once().Return("", expectedErr)
storage.On("Store", context.Background(), mock.MatchedBy(func(storedName string) bool {
return filepath.Ext(r.Name) == filepath.Ext(storedName) && storedName != r.Name
}), r.FileReader, r.Size).Once().Return(nil)
defer storage.AssertExpectations(t)

matchingFile := mock.MatchedBy(func(f *file.File) bool {
return f.Name == r.Name && f.Size == r.Size && f.OwnerUUID == r.OwnerUUID && f.MimeType == r.MimeType && filepath.Ext(f.Name) == filepath.Ext(f.StoredName)
})

filesRepository.On("Save", matchingFile).Once().Return("", expectedErr)
defer filesRepository.AssertExpectations(t)

response, err := NewUseCase(&filesRepository, &storage, &validator).Execute(&r)

storage.AssertNotCalled(t, "Store")
filesRepository.AssertNotCalled(t, "Delete")

assert.ErrorIs(t, err, expectedErr)
assert.Nil(t, response)
})
Expand Down
2 changes: 1 addition & 1 deletion backend/application/file/getFile/useCase.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func (uc *UseCase) Execute(UUID string) (*Response, error) {
return nil, err
}

reader, err := uc.storage.Read(context.Background(), f.UUID)
reader, err := uc.storage.Read(context.Background(), f.StoredName)
if err != nil {
return nil, err
}
Expand Down
13 changes: 7 additions & 6 deletions backend/domain/file/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ import (
)

type File struct {
UUID string
Name string
Size int64
OwnerUUID string
MimeType string
CreatedAt time.Time
UUID string
Name string
StoredName string
Size int64
OwnerUUID string
MimeType string
CreatedAt time.Time
}

type Repository interface {
Expand Down
Loading

0 comments on commit 29f8945

Please sign in to comment.