Skip to content

Commit

Permalink
feat(storage): add cred store creation implementation (#13575)
Browse files Browse the repository at this point in the history
Co-authored-by: israx <[email protected]>
  • Loading branch information
AllanZhengYP and israx authored Jul 11, 2024
1 parent 1079e7f commit 084b4ff
Show file tree
Hide file tree
Showing 8 changed files with 548 additions and 22 deletions.
14 changes: 7 additions & 7 deletions packages/aws-amplify/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -461,43 +461,43 @@
"name": "[Storage] copy (S3)",
"path": "./dist/esm/storage/index.mjs",
"import": "{ copy }",
"limit": "14.71 kB"
"limit": "14.9 kB"
},
{
"name": "[Storage] downloadData (S3)",
"path": "./dist/esm/storage/index.mjs",
"import": "{ downloadData }",
"limit": "15.31 kB"
"limit": "15.49 kB"
},
{
"name": "[Storage] getProperties (S3)",
"path": "./dist/esm/storage/index.mjs",
"import": "{ getProperties }",
"limit": "14.58 kB"
"limit": "14.77 kB"
},
{
"name": "[Storage] getUrl (S3)",
"path": "./dist/esm/storage/index.mjs",
"import": "{ getUrl }",
"limit": "15.68 kB"
"limit": "15.87 kB"
},
{
"name": "[Storage] list (S3)",
"path": "./dist/esm/storage/index.mjs",
"import": "{ list }",
"limit": "15.18 kB"
"limit": "15.36 kB"
},
{
"name": "[Storage] remove (S3)",
"path": "./dist/esm/storage/index.mjs",
"import": "{ remove }",
"limit": "14.45 kB"
"limit": "14.63 kB"
},
{
"name": "[Storage] uploadData (S3)",
"path": "./dist/esm/storage/index.mjs",
"import": "{ uploadData }",
"limit": "19.77 kB"
"limit": "19.94 kB"
}
]
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,157 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import { AWSCredentials } from '@aws-amplify/core/internals/utils';

import { createLocationCredentialsStore } from '../../../src/storageBrowser/locationCredentialsStore/create';
import {
createStore,
getValue,
removeStore,
} from '../../../src/storageBrowser/locationCredentialsStore/registry';
import { validateCredentialsProviderLocation } from '../../../src/storageBrowser/locationCredentialsStore/validators';
import { LocationCredentialsStore } from '../../../src/storageBrowser/types';
import {
StorageValidationErrorCode,
validationErrorMap,
} from '../../../src/errors/types/validation';

jest.mock('../../../src/storageBrowser/locationCredentialsStore/registry');
jest.mock('../../../src/storageBrowser/locationCredentialsStore/validators');

const mockedCredentials = 'MOCK_CREDS' as any as AWSCredentials;

describe('createLocationCredentialsStore', () => {
it.todo('should create a store');
it('should create a store', () => {
const refreshHandler = jest.fn();
const store = createLocationCredentialsStore({ handler: refreshHandler });

expect(createStore).toHaveBeenCalledWith(refreshHandler);
expect(store.getProvider).toBeDefined();
expect(store.destroy).toBeDefined();
});

describe('created store', () => {
describe('getValue()', () => {
it.todo('should call getValue() from store');
it.todo(
'should validate credentials location with resolved common scope',
describe('getProvider()', () => {
let store: LocationCredentialsStore;

beforeEach(() => {
store = createLocationCredentialsStore({ handler: jest.fn() });
});

afterEach(() => {
jest.clearAllMocks();
store.destroy();
});

it('should call getValue() from store', async () => {
expect.assertions(2);
jest
.mocked(getValue)
.mockResolvedValue({ credentials: mockedCredentials });

const locationCredentialsProvider = store.getProvider({
scope: 's3://bucket/path/*',
permission: 'READ',
});
const { credentials } = await locationCredentialsProvider({
locations: [{ bucket: 'bucket', path: 'path/to/object' }],
permission: 'READ',
});
expect(credentials).toEqual(mockedCredentials);
expect(getValue).toHaveBeenCalledWith(
expect.objectContaining({
location: {
scope: 's3://bucket/path/*',
permission: 'READ',
},
forceRefresh: false,
}),
);
});

it('should validate credentials location with resolved common scope', async () => {
expect.assertions(1);
jest
.mocked(getValue)
.mockResolvedValue({ credentials: mockedCredentials });
const locationCredentialsProvider = store.getProvider({
scope: 's3://bucket/path/*',
permission: 'READWRITE',
});
await locationCredentialsProvider({
locations: [
{ bucket: 'bucket', path: 'path/to/object' },
{ bucket: 'bucket', path: 'path/to/object2' },
{ bucket: 'bucket', path: 'path/folder' },
],
permission: 'READ',
});
expect(validateCredentialsProviderLocation).toHaveBeenCalledWith(
{ bucket: 'bucket', path: 'path/', permission: 'READ' },
{ bucket: 'bucket', path: 'path/*', permission: 'READWRITE' },
);
});

it('should throw if action requires cross-bucket permission', async () => {
expect.assertions(1);
jest
.mocked(getValue)
.mockResolvedValue({ credentials: mockedCredentials });
const locationCredentialsProvider = store.getProvider({
scope: 's3://bucket/path/*',
permission: 'READWRITE',
});
try {
await locationCredentialsProvider({
locations: [
{ bucket: 'bucket-1', path: 'path/to/object' },
{ bucket: 'bucket-2', path: 'path/to/object2' },
],
permission: 'READ',
});
} catch (e: any) {
expect(e.message).toEqual(
validationErrorMap[
StorageValidationErrorCode.LocationCredentialsCrossBucket
].message,
);
}
});

it.each(['invalid-s3-uri', 's3://', 's3:///'])(
'should throw if location credentials provider scope is not a valid S3 URI "%s"',
async invalidScope => {
expect.assertions(1);
jest
.mocked(getValue)
.mockResolvedValue({ credentials: mockedCredentials });
const locationCredentialsProvider = store.getProvider({
scope: invalidScope,
permission: 'READWRITE',
});
try {
await locationCredentialsProvider({
locations: [{ bucket: 'XXXXXXXX', path: 'path/to/object' }],
permission: 'READ',
});
} catch (e: any) {
expect(e.message).toEqual(
validationErrorMap[StorageValidationErrorCode.InvalidS3Uri]
.message,
);
}
},
);
});

describe('destroy()', () => {
it.todo('should call removeStore() from store');
it('should call removeStore() from store', () => {
const store = createLocationCredentialsStore({
handler: jest.fn(),
});
store.destroy();
expect(removeStore).toHaveBeenCalled();
});
});
});
});
Loading

0 comments on commit 084b4ff

Please sign in to comment.