diff --git a/packages/storage/__tests__/providers/s3/apis/copy.test.ts b/packages/storage/__tests__/providers/s3/apis/copy.test.ts index a15fb06a8b3..83d8dbd2176 100644 --- a/packages/storage/__tests__/providers/s3/apis/copy.test.ts +++ b/packages/storage/__tests__/providers/s3/apis/copy.test.ts @@ -8,7 +8,6 @@ import { copy } from '../../../../src/providers/s3/apis'; jest.mock('../../../../src/providers/s3/utils/client'); jest.mock('@aws-amplify/core', () => ({ - fetchAuthSession: jest.fn(), Amplify: { getConfig: jest.fn(), Auth: { @@ -42,7 +41,7 @@ const copyObjectClientBaseParams = { /** * bucket is appended at start if it's a sourceKey - * guest: public/${targetIdentityId}/${key}` + * guest: public/${key}` * private: private/${targetIdentityId}/${key}` * protected: protected/${targetIdentityId}/${key}` */ @@ -51,6 +50,8 @@ const buildClientRequestKey = ( KeyType: 'source' | 'destination', accessLevel: StorageAccessLevel ) => { + const targetIdentityId = 'targetIdentityId'; + const bucket = 'bucket'; const finalAccessLevel = accessLevel == 'guest' ? 'public' : accessLevel; let finalKey = KeyType == 'source' ? `${bucket}/` : ''; finalKey += `${finalAccessLevel}/`; diff --git a/packages/storage/__tests__/providers/s3/apis/getProperties.test.ts b/packages/storage/__tests__/providers/s3/apis/getProperties.test.ts index f993720c27d..0485b8c5869 100644 --- a/packages/storage/__tests__/providers/s3/apis/getProperties.test.ts +++ b/packages/storage/__tests__/providers/s3/apis/getProperties.test.ts @@ -5,10 +5,10 @@ import { headObject } from '../../../../src/providers/s3/utils/client'; import { getProperties } from '../../../../src/providers/s3'; import { Credentials } from '@aws-sdk/types'; import { Amplify } from '@aws-amplify/core'; +import { StorageOptions } from '../../../../src/types'; jest.mock('../../../../src/providers/s3/utils/client'); jest.mock('@aws-amplify/core', () => ({ - fetchAuthSession: jest.fn(), Amplify: { getConfig: jest.fn(), Auth: { @@ -28,87 +28,116 @@ const credentials: Credentials = { secretAccessKey: 'secretAccessKey', }; const targetIdentityId = 'targetIdentityId'; +const identityId = 'identityId'; -describe('getProperties test', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - mockFetchAuthSession.mockResolvedValue({ - credentials, - identityId: targetIdentityId, - }); - mockGetConfig.mockReturnValue({ - Storage: { - S3: { - bucket, - region, - }, - }, - }); - it('getProperties happy path case with private check', async () => { - expect.assertions(3); - mockHeadObject.mockReturnValueOnce({ - ContentLength: '100', - ContentType: 'text/plain', - ETag: 'etag', - LastModified: 'last-modified', - Metadata: { key: 'value' }, - VersionId: 'version-id', +describe('getProperties api', () => { + beforeAll(() => { + mockFetchAuthSession.mockResolvedValue({ + credentials, + identityId, }); - const metadata = { key: 'value' }; - expect( - await getProperties({ - key: 'key', - options: { - targetIdentityId: 'targetIdentityId', - accessLevel: 'protected', + mockGetConfig.mockReturnValue({ + Storage: { + S3: { + bucket, + region, }, - }) - ).toEqual({ + }, + }); + }); + describe('getProperties happy path ', () => { + const expected = { key: 'key', size: '100', contentType: 'text/plain', eTag: 'etag', - metadata, + metadata: { key: 'value' }, lastModified: 'last-modified', versionId: 'version-id', + }; + const config = { + credentials, + region: 'region', + }; + const key = 'key'; + beforeEach(() => { + mockHeadObject.mockReturnValueOnce({ + ContentLength: '100', + ContentType: 'text/plain', + ETag: 'etag', + LastModified: 'last-modified', + Metadata: { key: 'value' }, + VersionId: 'version-id', + }); + }); + afterEach(() => { + jest.clearAllMocks(); }); - expect(headObject).toBeCalledTimes(1); - expect(headObject).toHaveBeenCalledWith( + it.each([ + { + options: { accessLevel: 'guest' }, + expectedKey: 'public/key', + }, { - credentials, - region: 'region', + options: { accessLevel: 'protected', targetIdentityId }, + expectedKey: 'protected/targetIdentityId/key', }, { - Bucket: 'bucket', - Key: 'protected/targetIdentityId/key', + options: { accessLevel: 'protected' }, + expectedKey: 'protected/identityId/key', + }, + { + options: { accessLevel: 'private' }, + expectedKey: 'private/identityId/key', + }, + ])( + 'getProperties api with $options.accessLevel', + async ({ options, expectedKey }) => { + const headObjectOptions = { + Bucket: 'bucket', + Key: expectedKey, + }; + expect.assertions(3); + expect( + await getProperties({ + key, + options: options as StorageOptions, + }) + ).toEqual(expected); + expect(headObject).toBeCalledTimes(1); + expect(headObject).toHaveBeenCalledWith(config, headObjectOptions); } ); }); - it('getProperties should return a not found error', async () => { - mockHeadObject.mockRejectedValueOnce( - Object.assign(new Error(), { - $metadata: { httpStatusCode: 404 }, - name: 'NotFound', - }) - ); - try { - await getProperties({ key: 'keyed' }); - } catch (error) { - expect.assertions(3); - expect(headObject).toBeCalledTimes(1); - expect(headObject).toHaveBeenCalledWith( - { - credentials, - region: 'region', - }, - { - Bucket: 'bucket', - Key: 'public/keyed', - } + describe('getProperties error path', () => { + afterEach(() => { + jest.clearAllMocks(); + }); + it('getProperties should return a not found error', async () => { + mockHeadObject.mockRejectedValueOnce( + Object.assign(new Error(), { + $metadata: { httpStatusCode: 404 }, + name: 'NotFound', + }) ); - expect(error.$metadata.httpStatusCode).toBe(404); - } + try { + await getProperties({ key: 'keyed' }); + } catch (error) { + expect.assertions(3); + expect(headObject).toBeCalledTimes(1); + expect(headObject).toHaveBeenCalledWith( + { + credentials, + region: 'region', + }, + { + Bucket: 'bucket', + Key: 'public/keyed', + } + ); + expect(error.$metadata.httpStatusCode).toBe(404); + } + }); }); }); diff --git a/packages/storage/__tests__/providers/s3/apis/getUrl.test.ts b/packages/storage/__tests__/providers/s3/apis/getUrl.test.ts index 464a92680e9..4cd7d7586bf 100644 --- a/packages/storage/__tests__/providers/s3/apis/getUrl.test.ts +++ b/packages/storage/__tests__/providers/s3/apis/getUrl.test.ts @@ -8,10 +8,10 @@ import { getPresignedGetObjectUrl, headObject, } from '../../../../src/providers/s3/utils/client'; +import { StorageOptions } from '../../../../src/types'; jest.mock('../../../../src/providers/s3/utils/client'); jest.mock('@aws-amplify/core', () => ({ - fetchAuthSession: jest.fn(), Amplify: { getConfig: jest.fn(), Auth: { @@ -30,60 +30,105 @@ const credentials: Credentials = { secretAccessKey: 'secretAccessKey', }; const targetIdentityId = 'targetIdentityId'; +const identityId = 'identityId'; -describe('getProperties test', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - mockFetchAuthSession.mockResolvedValue({ - credentials, - identityId: targetIdentityId, - }); - mockGetConfig.mockReturnValue({ - Storage: { - S3: { - bucket, - region, +describe('getUrl test', () => { + beforeAll(() => { + mockFetchAuthSession.mockResolvedValue({ + credentials, + identityId, + }); + mockGetConfig.mockReturnValue({ + Storage: { + S3: { + bucket, + region, + }, }, - }, - }); - it('get presigned url happy case', async () => { - expect.assertions(2); - (headObject as jest.Mock).mockImplementation(() => { - return { - Key: 'key', - ContentLength: '100', - ContentType: 'text/plain', - ETag: 'etag', - LastModified: 'last-modified', - Metadata: { key: 'value' }, - }; }); - (getPresignedGetObjectUrl as jest.Mock).mockReturnValueOnce({ - url: new URL('https://google.com'), + }); + describe('getUrl happy path', () => { + const config = { + credentials, + region: 'region', + }; + const key = 'key'; + beforeEach(() => { + (headObject as jest.Mock).mockImplementation(() => { + return { + Key: 'key', + ContentLength: '100', + ContentType: 'text/plain', + ETag: 'etag', + LastModified: 'last-modified', + Metadata: { key: 'value' }, + }; + }); + (getPresignedGetObjectUrl as jest.Mock).mockReturnValueOnce({ + url: new URL('https://google.com'), + }); }); - const result = await getUrl({ key: 'key' }); - expect(getPresignedGetObjectUrl).toBeCalledTimes(1); - expect(result.url).toEqual({ - url: new URL('https://google.com'), + afterEach(() => { + jest.clearAllMocks(); }); - }); - test('Should return not found error when the object is not found', async () => { - (headObject as jest.Mock).mockImplementation(() => - Object.assign(new Error(), { - $metadata: { httpStatusCode: 404 }, - name: 'NotFound', - }) - ); - try { - await getUrl({ - key: 'invalid_key', - options: { validateObjectExistence: true }, + it.each([ + { + options: { accessLevel: 'guest' }, + expectedKey: 'public/key', + }, + { + options: { accessLevel: 'protected', targetIdentityId }, + expectedKey: 'protected/targetIdentityId/key', + }, + { + options: { accessLevel: 'protected' }, + expectedKey: 'protected/identityId/key', + }, + { + options: { accessLevel: 'private' }, + expectedKey: 'private/identityId/key', + }, + ])('getUrl with $options.accessLevel', async ({ options, expectedKey }) => { + const headObjectOptions = { + Bucket: 'bucket', + Key: expectedKey, + }; + const optionsVal = { ...options, validateObjectExistence: true }; + + expect.assertions(4); + const result = await getUrl({ + key, + options: optionsVal as StorageOptions, }); - } catch (error) { - expect.assertions(2); + expect(getPresignedGetObjectUrl).toBeCalledTimes(1); expect(headObject).toBeCalledTimes(1); - expect(error.$metadata?.httpStatusCode).toBe(404); - } + expect(headObject).toHaveBeenCalledWith(config, headObjectOptions); + expect(result.url).toEqual({ + url: new URL('https://google.com'), + }); + }); + }); + describe('getUrl error path', () => { + afterAll(() => { + jest.clearAllMocks(); + }); + it('Should return not found error when the object is not found', async () => { + (headObject as jest.Mock).mockImplementation(() => + Object.assign(new Error(), { + $metadata: { httpStatusCode: 404 }, + name: 'NotFound', + }) + ); + try { + await getUrl({ + key: 'invalid_key', + options: { validateObjectExistence: true }, + }); + } catch (error) { + expect.assertions(2); + expect(headObject).toBeCalledTimes(1); + expect(error.$metadata?.httpStatusCode).toBe(404); + } + }); }); }); diff --git a/packages/storage/__tests__/providers/s3/apis/list.test.ts b/packages/storage/__tests__/providers/s3/apis/list.test.ts index fa23e9a035b..6defa0e89aa 100644 --- a/packages/storage/__tests__/providers/s3/apis/list.test.ts +++ b/packages/storage/__tests__/providers/s3/apis/list.test.ts @@ -8,7 +8,6 @@ import { list } from '../../../../src/providers/s3/apis'; jest.mock('../../../../src/providers/s3/utils/client'); jest.mock('@aws-amplify/core', () => ({ - fetchAuthSession: jest.fn(), Amplify: { getConfig: jest.fn(), Auth: { diff --git a/packages/storage/__tests__/providers/s3/apis/remove.test.ts b/packages/storage/__tests__/providers/s3/apis/remove.test.ts index b682a4d068b..365d38ecb9c 100644 --- a/packages/storage/__tests__/providers/s3/apis/remove.test.ts +++ b/packages/storage/__tests__/providers/s3/apis/remove.test.ts @@ -8,7 +8,6 @@ import { remove } from '../../../../src/providers/s3/apis'; jest.mock('../../../../src/providers/s3/utils/client'); jest.mock('@aws-amplify/core', () => ({ - fetchAuthSession: jest.fn(), Amplify: { getConfig: jest.fn(), Auth: {