diff --git a/server/app/files_test.go b/server/app/files_test.go new file mode 100644 index 000000000..099d573aa --- /dev/null +++ b/server/app/files_test.go @@ -0,0 +1,250 @@ +package app + +import ( + "io" + "strings" + "testing" + + "github.com/mattermost/mattermost-server/v6/plugin/plugintest/mock" + "github.com/mattermost/mattermost-server/v6/shared/filestore" + "github.com/mattermost/mattermost-server/v6/shared/filestore/mocks" + "github.com/stretchr/testify/assert" +) + +const ( + testFileName = "temp-file-name" + testRootID = "test-root-id" + testFilePath = "1/test-root-id/temp-file-name" +) + +type TestError struct{} + +func (err *TestError) Error() string { return "Mocked File backend error" } + +func TestGetFileReader(t *testing.T) { + th, _ := SetupTestHelper(t) + mockedReadCloseSeek := &mocks.ReadCloseSeeker{} + t.Run("should get file reader from filestore successfully", func(t *testing.T) { + mockedFileBackend := &mocks.FileBackend{} + th.App.filesBackend = mockedFileBackend + readerFunc := func(path string) filestore.ReadCloseSeeker { + return mockedReadCloseSeek + } + + readerErrorFunc := func(path string) error { + return nil + } + + fileExistsFunc := func(path string) bool { + return true + } + + fileExistsErrorFunc := func(path string) error { + return nil + } + + mockedFileBackend.On("Reader", testFilePath).Return(readerFunc, readerErrorFunc) + mockedFileBackend.On("FileExists", testFilePath).Return(fileExistsFunc, fileExistsErrorFunc) + actual, _ := th.App.GetFileReader("1", testRootID, testFileName) + assert.Equal(t, mockedReadCloseSeek, actual) + }) + + t.Run("should get error from filestore when file exists return error", func(t *testing.T) { + mockedFileBackend := &mocks.FileBackend{} + th.App.filesBackend = mockedFileBackend + mockedError := &TestError{} + readerFunc := func(path string) filestore.ReadCloseSeeker { + return mockedReadCloseSeek + } + + readerErrorFunc := func(path string) error { + return nil + } + + fileExistsFunc := func(path string) bool { + return false + } + + fileExistsErrorFunc := func(path string) error { + return mockedError + } + + mockedFileBackend.On("Reader", testFilePath).Return(readerFunc, readerErrorFunc) + mockedFileBackend.On("FileExists", testFilePath).Return(fileExistsFunc, fileExistsErrorFunc) + actual, err := th.App.GetFileReader("1", testRootID, testFileName) + assert.Error(t, err, mockedError) + assert.Nil(t, actual) + }) + + t.Run("should return error, if get reader from file backend returns error", func(t *testing.T) { + mockedFileBackend := &mocks.FileBackend{} + th.App.filesBackend = mockedFileBackend + mockedError := &TestError{} + readerFunc := func(path string) filestore.ReadCloseSeeker { + return nil + } + + readerErrorFunc := func(path string) error { + return mockedError + } + + fileExistsFunc := func(path string) bool { + return false + } + + fileExistsErrorFunc := func(path string) error { + return nil + } + + mockedFileBackend.On("Reader", testFilePath).Return(readerFunc, readerErrorFunc) + mockedFileBackend.On("FileExists", testFilePath).Return(fileExistsFunc, fileExistsErrorFunc) + actual, err := th.App.GetFileReader("1", testRootID, testFileName) + assert.Error(t, err, mockedError) + assert.Nil(t, actual) + }) + + t.Run("should move file from old filepath to new filepath, if file doesnot exists in new filepath and workspace id is 0", func(t *testing.T) { + filePath := "0/test-root-id/temp-file-name" + workspaceid := "0" + mockedFileBackend := &mocks.FileBackend{} + th.App.filesBackend = mockedFileBackend + readerFunc := func(path string) filestore.ReadCloseSeeker { + return mockedReadCloseSeek + } + + readerErrorFunc := func(path string) error { + return nil + } + + fileExistsFunc := func(path string) bool { + // return true for old path + return path == testFileName + } + + fileExistsErrorFunc := func(path string) error { + return nil + } + + moveFileFunc := func(oldFileName, newFileName string) error { + return nil + } + + mockedFileBackend.On("FileExists", filePath).Return(fileExistsFunc, fileExistsErrorFunc) + mockedFileBackend.On("FileExists", testFileName).Return(fileExistsFunc, fileExistsErrorFunc) + mockedFileBackend.On("MoveFile", testFileName, filePath).Return(moveFileFunc) + mockedFileBackend.On("Reader", filePath).Return(readerFunc, readerErrorFunc) + + actual, _ := th.App.GetFileReader(workspaceid, testRootID, testFileName) + assert.Equal(t, mockedReadCloseSeek, actual) + }) + + t.Run("should return file reader, if file doesnot exists in new filepath and old file path", func(t *testing.T) { + filePath := "0/test-root-id/temp-file-name" + fileName := testFileName + workspaceid := "0" + mockedFileBackend := &mocks.FileBackend{} + th.App.filesBackend = mockedFileBackend + readerFunc := func(path string) filestore.ReadCloseSeeker { + return mockedReadCloseSeek + } + + readerErrorFunc := func(path string) error { + return nil + } + + fileExistsFunc := func(path string) bool { + // return true for old path + return false + } + + fileExistsErrorFunc := func(path string) error { + return nil + } + + moveFileFunc := func(oldFileName, newFileName string) error { + return nil + } + + mockedFileBackend.On("FileExists", filePath).Return(fileExistsFunc, fileExistsErrorFunc) + mockedFileBackend.On("FileExists", testFileName).Return(fileExistsFunc, fileExistsErrorFunc) + mockedFileBackend.On("MoveFile", fileName, filePath).Return(moveFileFunc) + mockedFileBackend.On("Reader", filePath).Return(readerFunc, readerErrorFunc) + + actual, _ := th.App.GetFileReader(workspaceid, testRootID, testFileName) + assert.Equal(t, mockedReadCloseSeek, actual) + }) +} + +func TestSaveFile(t *testing.T) { + th, _ := SetupTestHelper(t) + mockedReadCloseSeek := &mocks.ReadCloseSeeker{} + t.Run("should save file to file store using file backend", func(t *testing.T) { + fileName := "temp-file-name.txt" + mockedFileBackend := &mocks.FileBackend{} + th.App.filesBackend = mockedFileBackend + + writeFileFunc := func(reader io.Reader, path string) int64 { + paths := strings.Split(path, "/") + assert.Equal(t, "1", paths[0]) + assert.Equal(t, testRootID, paths[1]) + fileName = paths[2] + return int64(10) + } + + writeFileErrorFunc := func(reader io.Reader, filePath string) error { + return nil + } + + mockedFileBackend.On("WriteFile", mockedReadCloseSeek, mock.Anything).Return(writeFileFunc, writeFileErrorFunc) + actual, err := th.App.SaveFile(mockedReadCloseSeek, "1", testRootID, fileName) + assert.Equal(t, fileName, actual) + assert.Nil(t, err) + }) + + t.Run("should save .jpeg file as jpg file to file store using file backend", func(t *testing.T) { + fileName := "temp-file-name.jpeg" + mockedFileBackend := &mocks.FileBackend{} + th.App.filesBackend = mockedFileBackend + + writeFileFunc := func(reader io.Reader, path string) int64 { + paths := strings.Split(path, "/") + assert.Equal(t, "1", paths[0]) + assert.Equal(t, "test-root-id", paths[1]) + assert.Equal(t, "jpg", strings.Split(paths[2], ".")[1]) + return int64(10) + } + + writeFileErrorFunc := func(reader io.Reader, filePath string) error { + return nil + } + + mockedFileBackend.On("WriteFile", mockedReadCloseSeek, mock.Anything).Return(writeFileFunc, writeFileErrorFunc) + actual, err := th.App.SaveFile(mockedReadCloseSeek, "1", "test-root-id", fileName) + assert.Nil(t, err) + assert.NotNil(t, actual) + }) + + t.Run("should return error when fileBackend.WriteFile returns error", func(t *testing.T) { + fileName := "temp-file-name.jpeg" + mockedFileBackend := &mocks.FileBackend{} + th.App.filesBackend = mockedFileBackend + mockedError := &TestError{} + + writeFileFunc := func(reader io.Reader, path string) int64 { + paths := strings.Split(path, "/") + assert.Equal(t, "1", paths[0]) + assert.Equal(t, "test-root-id", paths[1]) + assert.Equal(t, "jpg", strings.Split(paths[2], ".")[1]) + return int64(10) + } + + writeFileErrorFunc := func(reader io.Reader, filePath string) error { + return mockedError + } + + mockedFileBackend.On("WriteFile", mockedReadCloseSeek, mock.Anything).Return(writeFileFunc, writeFileErrorFunc) + actual, err := th.App.SaveFile(mockedReadCloseSeek, "1", "test-root-id", fileName) + assert.Equal(t, "", actual) + assert.Equal(t, "unable to store the file in the files storage: Mocked File backend error", err.Error()) + }) +}