-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(s3): just use S3ServerSide, inject dependencies
S3LocalDev and S3ServerSide differ significantly only by the S3 API client, and the prefix for the short URL. Apply DRY to the two classes so that the same code is exercised both in local and live environments, injecting appropriate state into S3ServerSide at runtime - DependencyIds: Define new constants for s3Client and fileURLPrefix - S3ServerSide: Use injectable ctor parameters instead of module-level constants - inversify.config: Rework config so that only S3ServerSide inputs are determined by `NODE_ENV`, not the entire s3 dependency - `api/user`: Use the s3 held by the container, not the methods it destructures into, so that we can properly refer to the object's state through `this` - Rework `aws.test.ts` to account for changes - Remove S3LocalDev, no longer used
- Loading branch information
Showing
6 changed files
with
128 additions
and
87 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,82 @@ | ||
import { container } from '../../../src/server/util/inversify' | ||
import { S3Interface, S3ServerSide } from '../../../src/server/util/aws' | ||
import { | ||
FileVisibility, | ||
S3Interface, | ||
S3ServerSide, | ||
} from '../../../src/server/util/aws' | ||
import { DependencyIds } from '../../../src/server/constants' | ||
|
||
describe('S3 link validator', () => { | ||
describe('S3ServerSide', () => { | ||
const fileURLPrefix = 'https://' | ||
const s3Bucket = 'file-staging.go.gov.sg' | ||
|
||
const MockS3 = jest.fn(() => ({ | ||
putObjectAcl: jest.fn(() => ({ promise: jest.fn() })), | ||
putObject: jest.fn(() => ({ promise: jest.fn() })), | ||
})) | ||
let mockS3Client = new MockS3() | ||
|
||
afterEach(() => { | ||
container.unbindAll() | ||
}) | ||
beforeEach(() => { | ||
mockS3Client = new MockS3() | ||
container.bind(DependencyIds.fileURLPrefix).toConstantValue(fileURLPrefix) | ||
container.bind(DependencyIds.s3Bucket).toConstantValue(s3Bucket) | ||
container.bind(DependencyIds.s3Client).toConstantValue(mockS3Client) | ||
container.bind<S3Interface>(DependencyIds.s3).to(S3ServerSide) | ||
}) | ||
|
||
it('should call s3Client.putObjectAcl on setS3ObjectACL', () => { | ||
const key = 'key' | ||
const acl = FileVisibility.Private | ||
const s3 = container.get<S3Interface>(DependencyIds.s3) | ||
s3.setS3ObjectACL(key, acl) | ||
expect(mockS3Client.putObjectAcl).toHaveBeenCalled() | ||
expect(mockS3Client.putObjectAcl).toHaveBeenCalledWith({ | ||
Bucket: s3Bucket, | ||
Key: key, | ||
ACL: acl, | ||
}) | ||
}) | ||
|
||
it('should call s3Client.putObject on uploadFileToS3', () => { | ||
const file = Buffer.from([]) | ||
const key = 'key' | ||
const fileType = 'type' | ||
|
||
const s3 = container.get<S3Interface>(DependencyIds.s3) | ||
s3.uploadFileToS3(file, key, fileType) | ||
expect(mockS3Client.putObject).toHaveBeenCalled() | ||
expect(mockS3Client.putObject).toHaveBeenCalledWith({ | ||
ContentType: fileType, | ||
Bucket: s3Bucket, | ||
Body: file, | ||
Key: key, | ||
ACL: FileVisibility.Public, | ||
CacheControl: `no-cache`, | ||
}) | ||
}) | ||
|
||
it('should return correct file link when provided with a short url', () => { | ||
const shortUrl = 'test' | ||
const validLink = `https://file-staging.go.gov.sg/${shortUrl}` | ||
const { buildFileLongUrl } = container.get<S3Interface>(DependencyIds.s3) | ||
expect(buildFileLongUrl(shortUrl)).toBe(validLink) | ||
const validLink = `${fileURLPrefix}${s3Bucket}/${shortUrl}` | ||
const s3 = container.get<S3Interface>(DependencyIds.s3) | ||
expect(s3.buildFileLongUrl(shortUrl)).toBe(validLink) | ||
}) | ||
|
||
describe('getKeyFromLongUrl', () => { | ||
it('should return correct key when provided a long URL', () => { | ||
const shortUrl = 'test' | ||
const validLink = `${fileURLPrefix}${s3Bucket}/${shortUrl}` | ||
const s3 = container.get<S3Interface>(DependencyIds.s3) | ||
expect(s3.getKeyFromLongUrl(validLink)).toBe(shortUrl) | ||
}) | ||
|
||
it('should throw when provided a long URL', () => { | ||
const validLink = `${fileURLPrefix}${s3Bucket}/` | ||
const s3 = container.get<S3Interface>(DependencyIds.s3) | ||
expect(() => s3.getKeyFromLongUrl(validLink)).toThrow('Invalid URL') | ||
}) | ||
}) | ||
}) |