-
Notifications
You must be signed in to change notification settings - Fork 825
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* feat: display SNS sandbox status * chore: SNS API error handling * chore: add support for SMS Sandbox check * chore: auth add show sandbox warning * chore: add some tests * chore: address review comments and remove unused code
- Loading branch information
Showing
6 changed files
with
276 additions
and
39 deletions.
There are no files selected for viewing
29 changes: 29 additions & 0 deletions
29
...ategory-auth/src/__tests__/provider-utils/awscloudformation/utils/message-printer.test.ts
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 |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { printSMSSandboxWarning } from '../../../../provider-utils/awscloudformation/utils/message-printer'; | ||
import { BannerMessage } from 'amplify-cli-core'; | ||
jest.mock('amplify-cli-core'); | ||
const printMock = { | ||
info: jest.fn(), | ||
}; | ||
|
||
describe('printSMSSandboxWarning', () => { | ||
const mockedGetMessage = jest.spyOn(BannerMessage, 'getMessage'); | ||
|
||
beforeEach(() => { | ||
jest.resetAllMocks(); | ||
}); | ||
|
||
it('should print warning when the message is present', async () => { | ||
const message = 'BannerMessage'; | ||
mockedGetMessage.mockResolvedValueOnce(message); | ||
await printSMSSandboxWarning(printMock); | ||
expect(printMock.info).toHaveBeenCalledWith(`${message}\n`); | ||
expect(mockedGetMessage).toHaveBeenCalledWith('COGNITO_SMS_SANDBOX_CATEGORY_AUTH_ADD_OR_UPDATE_INFO'); | ||
}); | ||
|
||
it('should not print warning when the banner message is missing', async () => { | ||
mockedGetMessage.mockResolvedValueOnce(undefined); | ||
await printSMSSandboxWarning(printMock); | ||
expect(printMock.info).not.toHaveBeenCalled(); | ||
expect(mockedGetMessage).toHaveBeenCalledWith('COGNITO_SMS_SANDBOX_CATEGORY_AUTH_ADD_OR_UPDATE_INFO'); | ||
}); | ||
}); |
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
116 changes: 116 additions & 0 deletions
116
packages/amplify-provider-awscloudformation/src/__tests__/display-helpful-urls.test.ts
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 |
---|---|---|
@@ -0,0 +1,116 @@ | ||
import { showSMSSandboxWarning } from '../display-helpful-urls'; | ||
import { BannerMessage } from 'amplify-cli-core'; | ||
import { SNS } from '../aws-utils/aws-sns'; | ||
import { AWSError } from 'aws-sdk'; | ||
|
||
jest.mock('../aws-utils/aws-sns'); | ||
jest.mock('amplify-cli-core'); | ||
|
||
describe('showSMSSandBoxWarning', () => { | ||
const mockedGetMessage = jest.spyOn(BannerMessage, 'getMessage'); | ||
const mockedSNSClientInstance = { | ||
isInSandboxMode: jest.fn(), | ||
}; | ||
|
||
let mockedSNSClass; | ||
const context = { | ||
print: { | ||
warning: jest.fn(), | ||
}, | ||
}; | ||
|
||
beforeEach(() => { | ||
jest.resetAllMocks(); | ||
mockedSNSClass = jest.spyOn(SNS, 'getInstance').mockResolvedValue((mockedSNSClientInstance as unknown) as SNS); | ||
}); | ||
|
||
describe('when API is missing in SDK', () => { | ||
beforeEach(() => { | ||
mockedSNSClientInstance.isInSandboxMode.mockRejectedValue(new TypeError()); | ||
}); | ||
|
||
it('should not show warning when SNS client is missing sandbox api and there is no banner message associated', async () => { | ||
await showSMSSandboxWarning(context); | ||
|
||
expect(mockedGetMessage).toHaveBeenCalledWith('COGNITO_SMS_SANDBOX_UPDATE_WARNING'); | ||
expect(context.print.warning).not.toHaveBeenCalled(); | ||
}); | ||
|
||
it('should show warning when SNS Client is missing sandbox API and there is a banner message associated', async () => { | ||
const message = 'UPGRADE YOUR CLI!!!!'; | ||
mockedGetMessage.mockImplementation(async messageId => (messageId === 'COGNITO_SMS_SANDBOX_UPDATE_WARNING' ? message : undefined)); | ||
|
||
await showSMSSandboxWarning(context); | ||
|
||
expect(mockedGetMessage).toHaveBeenCalledWith('COGNITO_SMS_SANDBOX_UPDATE_WARNING'); | ||
expect(context.print.warning).toHaveBeenCalledWith(message); | ||
}); | ||
}); | ||
|
||
describe('when IAM user is missing sandbox permission', () => { | ||
beforeEach(() => { | ||
const authError = new Error() as AWSError; | ||
authError.code = 'AuthorizationError'; | ||
mockedSNSClientInstance.isInSandboxMode.mockRejectedValue(authError); | ||
}); | ||
it('should not show any warning if there is no message associated', async () => { | ||
await showSMSSandboxWarning(context); | ||
|
||
expect(mockedGetMessage).toHaveBeenCalledWith('COGNITO_SMS_SANDBOX_MISSING_PERMISSION'); | ||
expect(context.print.warning).not.toHaveBeenCalled(); | ||
}); | ||
|
||
it('should show any warning if there is no message associated', async () => { | ||
const message = 'UPDATE YOUR PROFILE USER WITH SANDBOX PERMISSION'; | ||
|
||
mockedGetMessage.mockImplementation(async messageId => { | ||
switch (messageId) { | ||
case 'COGNITO_SMS_SANDBOX_MISSING_PERMISSION': | ||
return message; | ||
case 'COGNITO_SMS_SANDBOX_UPDATE_WARNING': | ||
return 'enabled'; | ||
} | ||
}); | ||
|
||
await showSMSSandboxWarning(context); | ||
|
||
expect(mockedGetMessage).toHaveBeenCalledWith('COGNITO_SMS_SANDBOX_MISSING_PERMISSION'); | ||
expect(context.print.warning).toHaveBeenCalledWith(message); | ||
}); | ||
}); | ||
|
||
describe('it should not show any warning message when the SNS API is not deployed', () => { | ||
beforeEach(() => { | ||
const resourceNotFoundError = new Error() as AWSError; | ||
resourceNotFoundError.code = 'ResourceNotFound'; | ||
mockedSNSClientInstance.isInSandboxMode.mockRejectedValue(resourceNotFoundError); | ||
}); | ||
it('should not print error', async () => { | ||
const message = 'UPGRADE YOUR CLI!!!!'; | ||
mockedGetMessage.mockImplementation(async messageId => (messageId === 'COGNITO_SMS_SANDBOX_UPDATE_WARNING' ? message : undefined)); | ||
|
||
await showSMSSandboxWarning(context); | ||
|
||
expect(mockedGetMessage).toHaveBeenCalledWith('COGNITO_SMS_SANDBOX_UPDATE_WARNING'); | ||
expect(context.print.warning).not.toHaveBeenCalledWith(message); | ||
}); | ||
}); | ||
|
||
describe('it should not show any warning message when there is a network error', () => { | ||
beforeEach(() => { | ||
const networkError = new Error() as AWSError; | ||
networkError.code = 'UnknownEndpoint'; | ||
mockedSNSClientInstance.isInSandboxMode.mockRejectedValue(networkError); | ||
}); | ||
|
||
it('should not print error', async () => { | ||
const message = 'UPGRADE YOUR CLI!!!!'; | ||
mockedGetMessage.mockImplementation(async messageId => (messageId === 'COGNITO_SMS_SANDBOX_UPDATE_WARNING' ? message : undefined)); | ||
|
||
await showSMSSandboxWarning(context); | ||
|
||
expect(mockedGetMessage).toHaveBeenCalledWith('COGNITO_SMS_SANDBOX_UPDATE_WARNING'); | ||
expect(context.print.warning).not.toHaveBeenCalledWith(message); | ||
}); | ||
}); | ||
}); |
34 changes: 34 additions & 0 deletions
34
packages/amplify-provider-awscloudformation/src/aws-utils/aws-sns.ts
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 |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { $TSAny, $TSContext } from 'amplify-cli-core'; | ||
import { loadConfiguration } from '../configuration-manager'; | ||
import aws from './aws.js'; | ||
|
||
export class SNS { | ||
private static instance: SNS; | ||
private readonly sns: AWS.SNS; | ||
|
||
static async getInstance(context: $TSContext, options = {}): Promise<SNS> { | ||
if (!SNS.instance) { | ||
let cred = {}; | ||
try { | ||
cred = await loadConfiguration(context); | ||
} catch (e) { | ||
// ignore missing config | ||
} | ||
|
||
SNS.instance = new SNS(context, cred, options); | ||
} | ||
return SNS.instance; | ||
} | ||
|
||
private constructor(context: $TSContext, cred: $TSAny, options = {}) { | ||
this.sns = new aws.SNS({ ...cred, ...options }); | ||
} | ||
|
||
public async isInSandboxMode(): Promise<boolean> { | ||
// AWS SDK still does not have getSMSSandboxAccountStatus. Casting sns to any to avoid compile error | ||
// Todo: remove any casting once aws-sdk is updated | ||
const snsClient = this.sns as any; | ||
const result = await snsClient.getSMSSandboxAccountStatus().promise(); | ||
return result.IsInSandbox; | ||
} | ||
} |
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