Skip to content

Commit

Permalink
[Multi-bucket] Update options to include bucket (#13574)
Browse files Browse the repository at this point in the history
* update options and test
* update assertion error & download test
* update getUrl & getProp test
* update remove and list tests
* update multi-part tests
* update list & download test
* update more storage tests
* update bundle size
* address comments
  • Loading branch information
ashika112 authored Jul 18, 2024
1 parent bfb3b00 commit 9073217
Show file tree
Hide file tree
Showing 13 changed files with 947 additions and 32 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.64 kB"
"limit": "14.76 kB"
},
{
"name": "[Storage] downloadData (S3)",
"path": "./dist/esm/storage/index.mjs",
"import": "{ downloadData }",
"limit": "15.25 kB"
"limit": "15.38 kB"
},
{
"name": "[Storage] getProperties (S3)",
"path": "./dist/esm/storage/index.mjs",
"import": "{ getProperties }",
"limit": "14.51 kB"
"limit": "14.64 kB"
},
{
"name": "[Storage] getUrl (S3)",
"path": "./dist/esm/storage/index.mjs",
"import": "{ getUrl }",
"limit": "15.60 kB"
"limit": "15.74 kB"
},
{
"name": "[Storage] list (S3)",
"path": "./dist/esm/storage/index.mjs",
"import": "{ list }",
"limit": "15.02 kB"
"limit": "15.15 kB"
},
{
"name": "[Storage] remove (S3)",
"path": "./dist/esm/storage/index.mjs",
"import": "{ remove }",
"limit": "14.37 kB"
"limit": "14.50 kB"
},
{
"name": "[Storage] uploadData (S3)",
"path": "./dist/esm/storage/index.mjs",
"import": "{ uploadData }",
"limit": "19.68 kB"
"limit": "19.79 kB"
}
]
}
6 changes: 6 additions & 0 deletions packages/core/src/singleton/AmplifyOutputs/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,19 @@ export interface AmplifyOutputsAuthProperties {
}

export interface AmplifyOutputsStorageBucketProperties {
/** Friendly bucket name provided in Amplify Outputs */
name: string;
/** Actual S3 bucket name given */
bucket_name: string;
/** Region for the bucket */
aws_region: string;
}
export interface AmplifyOutputsStorageProperties {
/** Default region for Storage */
aws_region: string;
/** Default bucket for Storage */
bucket_name: string;
/** List of buckets for Storage */
buckets?: AmplifyOutputsStorageBucketProperties[];
}

Expand Down
133 changes: 132 additions & 1 deletion packages/storage/__tests__/providers/s3/apis/downloadData.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
ItemWithPath,
} from '../../../../src/providers/s3/types/outputs';
import './testUtils';
import { BucketInfo } from '../../../../src/providers/s3/types/options';

jest.mock('../../../../src/providers/s3/utils/client');
jest.mock('../../../../src/providers/s3/utils');
Expand Down Expand Up @@ -62,7 +63,7 @@ const mockDownloadResultBase = {
const mockFetchAuthSession = Amplify.Auth.fetchAuthSession as jest.Mock;
const mockCreateDownloadTask = createDownloadTask as jest.Mock;
const mockValidateStorageInput = validateStorageOperationInput as jest.Mock;
const mockGetConfig = Amplify.getConfig as jest.Mock;
const mockGetConfig = jest.mocked(Amplify.getConfig);

describe('downloadData with key', () => {
beforeAll(() => {
Expand All @@ -75,6 +76,7 @@ describe('downloadData with key', () => {
S3: {
bucket,
region,
buckets: { 'default-bucket': { bucketName: bucket, region } },
},
},
});
Expand Down Expand Up @@ -220,6 +222,70 @@ describe('downloadData with key', () => {
}),
);
});

describe('bucket passed in options', () => {
it('should override bucket in getObject call when bucket is object', async () => {
(getObject as jest.Mock).mockResolvedValueOnce({ Body: 'body' });
const abortController = new AbortController();
const bucketInfo: BucketInfo = {
bucketName: 'bucket-1',
region: 'region-1',
};

downloadData({
key: inputKey,
options: {
bucket: bucketInfo,
},
});

const { job } = mockCreateDownloadTask.mock.calls[0][0];
await job();

expect(getObject).toHaveBeenCalledTimes(1);
await expect(getObject).toBeLastCalledWithConfigAndInput(
{
credentials,
region: bucketInfo.region,
abortSignal: abortController.signal,
userAgentValue: expect.any(String),
},
{
Bucket: bucketInfo.bucketName,
Key: `public/${inputKey}`,
},
);
});

it('should override bucket in getObject call when bucket is string', async () => {
(getObject as jest.Mock).mockResolvedValueOnce({ Body: 'body' });
const abortController = new AbortController();

downloadData({
key: inputKey,
options: {
bucket: 'default-bucket',
},
});

const { job } = mockCreateDownloadTask.mock.calls[0][0];
await job();

expect(getObject).toHaveBeenCalledTimes(1);
await expect(getObject).toBeLastCalledWithConfigAndInput(
{
credentials,
region,
abortSignal: abortController.signal,
userAgentValue: expect.any(String),
},
{
Bucket: bucket,
Key: `public/${inputKey}`,
},
);
});
});
});

describe('downloadData with path', () => {
Expand All @@ -233,6 +299,7 @@ describe('downloadData with path', () => {
S3: {
bucket,
region,
buckets: { 'default-bucket': { bucketName: bucket, region } },
},
},
});
Expand Down Expand Up @@ -366,4 +433,68 @@ describe('downloadData with path', () => {
}),
);
});

describe('bucket passed in options', () => {
it('should override bucket in getObject call when bucket is object', async () => {
(getObject as jest.Mock).mockResolvedValueOnce({ Body: 'body' });
const abortController = new AbortController();
const bucketInfo: BucketInfo = {
bucketName: 'bucket-1',
region: 'region-1',
};

downloadData({
path: inputPath,
options: {
bucket: bucketInfo,
},
});

const { job } = mockCreateDownloadTask.mock.calls[0][0];
await job();

expect(getObject).toHaveBeenCalledTimes(1);
await expect(getObject).toBeLastCalledWithConfigAndInput(
{
credentials,
region: bucketInfo.region,
abortSignal: abortController.signal,
userAgentValue: expect.any(String),
},
{
Bucket: bucketInfo.bucketName,
Key: inputPath,
},
);
});

it('should override bucket in getObject call when bucket is string', async () => {
(getObject as jest.Mock).mockResolvedValueOnce({ Body: 'body' });
const abortController = new AbortController();

downloadData({
path: inputPath,
options: {
bucket: 'default-bucket',
},
});

const { job } = mockCreateDownloadTask.mock.calls[0][0];
await job();

expect(getObject).toHaveBeenCalledTimes(1);
await expect(getObject).toBeLastCalledWithConfigAndInput(
{
credentials,
region,
abortSignal: abortController.signal,
userAgentValue: expect.any(String),
},
{
Bucket: bucket,
Key: inputPath,
},
);
});
});
});
107 changes: 105 additions & 2 deletions packages/storage/__tests__/providers/s3/apis/getProperties.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
GetPropertiesWithPathOutput,
} from '../../../../src/providers/s3/types';
import './testUtils';
import { BucketInfo } from '../../../../src/providers/s3/types/options';

jest.mock('../../../../src/providers/s3/utils/client');
jest.mock('@aws-amplify/core', () => ({
Expand All @@ -28,7 +29,7 @@ jest.mock('@aws-amplify/core', () => ({
}));
const mockHeadObject = headObject as jest.MockedFunction<typeof headObject>;
const mockFetchAuthSession = Amplify.Auth.fetchAuthSession as jest.Mock;
const mockGetConfig = Amplify.getConfig as jest.Mock;
const mockGetConfig = jest.mocked(Amplify.getConfig);

const bucket = 'bucket';
const region = 'region';
Expand Down Expand Up @@ -65,14 +66,16 @@ describe('getProperties with key', () => {
S3: {
bucket,
region,
buckets: { 'default-bucket': { bucketName: bucket, region } },
},
},
});
});

describe('Happy cases: With key', () => {
const config = {
credentials,
region: 'region',
region,
userAgentValue: expect.any(String),
};
beforeEach(() => {
Expand Down Expand Up @@ -152,6 +155,56 @@ describe('getProperties with key', () => {
);
},
);

describe('bucket passed in options', () => {
it('should override bucket in headObject call when bucket is object', async () => {
const bucketInfo: BucketInfo = {
bucketName: 'bucket-1',
region: 'region-1',
};
const headObjectOptions = {
Bucket: bucketInfo.bucketName,
Key: `public/${inputKey}`,
};

await getPropertiesWrapper({
key: inputKey,
options: {
bucket: bucketInfo,
},
});
expect(headObject).toHaveBeenCalledTimes(1);
await expect(headObject).toBeLastCalledWithConfigAndInput(
{
credentials,
region: bucketInfo.region,

userAgentValue: expect.any(String),
},
headObjectOptions,
);
});
it('should override bucket in headObject call when bucket is string', async () => {
await getPropertiesWrapper({
key: inputKey,
options: {
bucket: 'default-bucket',
},
});
expect(headObject).toHaveBeenCalledTimes(1);
await expect(headObject).toBeLastCalledWithConfigAndInput(
{
credentials,
region,
userAgentValue: expect.any(String),
},
{
Bucket: bucket,
Key: `public/${inputKey}`,
},
);
});
});
});

describe('Error cases : With key', () => {
Expand Down Expand Up @@ -201,6 +254,7 @@ describe('Happy cases: With path', () => {
S3: {
bucket,
region,
buckets: { 'default-bucket': { bucketName: bucket, region } },
},
},
});
Expand Down Expand Up @@ -275,6 +329,55 @@ describe('Happy cases: With path', () => {
);
},
);
describe('bucket passed in options', () => {
it('should override bucket in headObject call when bucket is object', async () => {
const bucketInfo: BucketInfo = {
bucketName: 'bucket-1',
region: 'region-1',
};
const headObjectOptions = {
Bucket: bucketInfo.bucketName,
Key: inputPath,
};

await getPropertiesWrapper({
path: inputPath,
options: {
bucket: bucketInfo,
},
});
expect(headObject).toHaveBeenCalledTimes(1);
await expect(headObject).toBeLastCalledWithConfigAndInput(
{
credentials,
region: bucketInfo.region,

userAgentValue: expect.any(String),
},
headObjectOptions,
);
});
it('should override bucket in headObject call when bucket is string', async () => {
await getPropertiesWrapper({
path: inputPath,
options: {
bucket: 'default-bucket',
},
});
expect(headObject).toHaveBeenCalledTimes(1);
await expect(headObject).toBeLastCalledWithConfigAndInput(
{
credentials,
region,
userAgentValue: expect.any(String),
},
{
Bucket: bucket,
Key: inputPath,
},
);
});
});
});

describe('Error cases : With path', () => {
Expand Down
Loading

0 comments on commit 9073217

Please sign in to comment.