package filestore_test import ( "context" "io/ioutil" "net/url" "os" "path" "strings" "testing" "git.netflux.io/rob/clipper/filestore" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestFileStoreGetObject(t *testing.T) { baseURL, err := url.Parse("/") require.NoError(t, err) store, err := filestore.NewFileSystemStore("testdata/", baseURL) require.NoError(t, err) reader, err := store.GetObject(context.Background(), "file.txt") require.NoError(t, err) defer reader.Close() content, err := ioutil.ReadAll(reader) require.NoError(t, err) assert.Equal(t, "hello world", string(content)) } func TestFileStoreGetObjectWithRange(t *testing.T) { testCases := []struct { name string start, end int64 wantErr string wantContent string }{ { name: "happy path, complete object", start: 0, end: 12, wantContent: "hello world", }, { name: "happy path, partial object", start: 6, end: 10, wantContent: "worl", }, { name: "empty range", start: 1, end: 1, wantContent: "", }, { name: "bad range", start: -10, end: 0, wantErr: "error seeking in file: seek testdata/file.txt: invalid argument", }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { baseURL, err := url.Parse("/") require.NoError(t, err) store, err := filestore.NewFileSystemStore("testdata/", baseURL) require.NoError(t, err) reader, err := store.GetObjectWithRange(context.Background(), "file.txt", tc.start, tc.end) if tc.wantErr == "" { defer reader.Close() require.NoError(t, err) content, readErr := ioutil.ReadAll(reader) require.NoError(t, readErr) assert.Equal(t, tc.wantContent, string(content)) } else { assert.EqualError(t, err, tc.wantErr) } }) } } func TestFileStoreGetURL(t *testing.T) { testCases := []struct { name string baseURL string key string wantURL string }{ { name: "URL with host and no path, no trailing slash", baseURL: "https://foo.example.com", key: "bar", wantURL: "https://foo.example.com/bar", }, { name: "URL with host and no path, trailing slash", baseURL: "https://foo.example.com/", key: "bar", wantURL: "https://foo.example.com/bar", }, { name: "URL with host and path, no trailing slash", baseURL: "https://foo.example.com/bar", key: "baz", wantURL: "https://foo.example.com/bar/baz", }, { name: "URL with host and path, trailing slash", baseURL: "https://foo.example.com/bar/", key: "baz", wantURL: "https://foo.example.com/bar/baz", }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { baseURL, err := url.Parse(tc.baseURL) require.NoError(t, err) store, err := filestore.NewFileSystemStore("testdata/", baseURL) require.NoError(t, err) url, err := store.GetURL(context.Background(), tc.key) require.NoError(t, err) assert.Equal(t, tc.wantURL, url) }) } } func TestFileStorePutObject(t *testing.T) { rootPath := t.TempDir() testCases := []struct { name string key string content string wantCount int64 wantErr string }{ { name: "happy path, no created directory", key: "foo.txt", content: "hello world", wantCount: 11, }, { name: "happy path, with sub-directories", key: "foo/bar/baz.txt", content: "hello world", wantCount: 11, }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { baseURL, err := url.Parse("/") require.NoError(t, err) store, err := filestore.NewFileSystemStore(rootPath, baseURL) require.NoError(t, err) n, err := store.PutObject(context.Background(), tc.key, strings.NewReader(tc.content), "text/plain") require.NoError(t, err) content, err := os.ReadFile(path.Join(rootPath, tc.key)) require.NoError(t, err) assert.Equal(t, tc.wantCount, n) assert.Equal(t, tc.content, string(content)) }) } }