Skip to content

Instantly share code, notes, and snippets.

@xfy0012
Last active March 26, 2024 01:14
Show Gist options
  • Select an option

  • Save xfy0012/94f4b9d3b1bbad0e1eb07f1626f4ad8a to your computer and use it in GitHub Desktop.

Select an option

Save xfy0012/94f4b9d3b1bbad0e1eb07f1626f4ad8a to your computer and use it in GitHub Desktop.
whatsapp_sendmessage_api_test
/**
* 1. API Functionality Description
* This API receives a JSON request body containing message content, sender and receiver information, and message template with its data. It sends messages to specified WhatsApp numbers via the InfoBip platform. The API supports internationalization of messages, allowing the language of the message content to be specified.
*
* 2. Input and Output
* Input:
* - from: The WhatsApp number of the message sender.
* - to: The WhatsApp number of the message recipient.
* - messageId: A unique identifier for the message.
* - content:
* - templateName: The name of the message template to be used.
* - templateData: The data needed within the message template, such as contents for placeholders.
* - language: The language of the message content.
* Output:
* - Successful Response: A status code of 200 indicates that the message has been sent successfully.
* Error Responses:
* - BAD_REQUEST: Indicates a request format error or that template data does not meet the requirements.
* - UNAUTHORIZED: Authorization failed, possibly due to an invalid API key provided.
* - TOO_MANY_REQUESTS: Too many requests have been sent in a short period, exceeding the API's rate limits.
* - GENERAL_ERROR: A general error that may require contacting technical support to resolve.
*
* 3. Testing Plan
* The testing will cover the following scenarios:
* - Successful Message Sending: Validate that correct input results in successful message delivery.
* - Request Format Error: Test the behavior when the request body format is incorrect.
* - Authorization Failure: Simulate the situation where an incorrect API key is provided.
* - Rate Limiting: Simulate an excessively frequent series of requests to test rate limiting.
* - General Error Handling: Test the API's response to unexpected errors.
*
* 4. Test Cases and Coverage Points
* - Successful Case: Ensure that when all required fields are correctly filled, the message is sent successfully.
* - Template Data Validation: Verify that the template data fields are validated according to requirements (e.g., file name length restrictions).
* - Authorization Validation: Attempt to use an incorrect API key, expecting an “Unauthorized” error response.
* - Request Frequency Limitation: Send a large number of requests in a short time, expecting a “Too many requests” error response.
* - Exception Handling: Simulate an internal API error to verify that a general error message is returned, suggesting to contact support.
*
* 5. Limitations and Uncovered Test Cases
* - Network Issues: Delays or disruptions in network connectivity can impact API calls, but these are usually handled at the client or network level, not by the API itself.
* - Long-Running Performance Testing: The performance of the API under high load over an extended period has not been tested, which may require additional testing environments and setup.
* - Internationalization and Localization Testing: Although a language parameter is supported, detailed testing for various language environments may be limited or not conducted.
* - Real Environment Testing: Testing that simulates real user behavior (such as the diversity and complexity of message content) is limited and typically requires more monitoring and analysis in a production environment.
* Test Outcomes
*
* In the series of tests designed, all cases passed except for the final GENERAL_ERROR test, which failed. This was an attempt to simulate a 500 Internal Server Error condition within the API to assess the error handling capabilities of the system. However, the expected outcome of receiving a GENERAL_ERROR response was not achieved. Instead, the test may have resulted in a different error code or no error response at all, indicating a discrepancy between expected and actual API behavior in scenarios where the server encounters an unexpected condition.
*
* The failure of the GENERAL_ERROR test suggests that the API's behavior under internal server error conditions may not align with the documented expectations or that our method of simulating the error was not accurate. To gain a clearer understanding of the API's response to internal server errors and to ensure that the application can gracefully handle such errors when they occur in a production environment, it will be necessary to engage with the InfoBip support or development team. Direct communication with InfoBip will allow for clarification on how the API is designed to respond to internal server errors and may provide insight into how such errors can be reliably simulated for testing purposes.
*
* Recommendations:
* - Contact InfoBip technical support to inquire about the specifics of handling 500 Internal Server Errors within their API, with an emphasis on understanding the conditions that trigger such errors and the expected response structure.
*/
describe('WhatsApp Message Sending Feature', () => {
// Test Case: Successfully sends a WhatsApp message
it('successfully sends a WhatsApp message', () => {
// Construct the request data with valid message structure
const requestData = {
"messages": [
{
"from": "447860099299",
"to": "447570461417",
"messageId": "0287c2fa-792b-4e62-8de7-f650c16f2460",
"content": {
"templateName": "message_test",
"templateData": {
"body": {
"placeholders": ["hi"]
}
},
"language": "en"
}
}
]
}
// Perform a POST request to send the message
cy.request({
method: 'POST',
url: 'https://pp5443.api.infobip.com/whatsapp/1/message/template',
headers: {
'Authorization': `App ff67d657889149a69fa4d8fb4c7598ed-3d3221e4-aff8-4f80-8b04-2a3afe1812f1`,
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: requestData,
}).then((response) => {
// Verify the response status code is 200, indicating success
expect(response.status).to.eq(200);
});
});
// Test Case: Fails with bad request on incorrect template data
it('fails with bad request on incorrect template data', () => {
// Construct the request data with an incorrect template structure
const requestData = {
"messages": [
{
"from": "447860099299",
"to": "447570461417",
"messageId": "0287c2fa-792b-4e62-8de7-f650c16f2460",
"content": {
"templateName": "message_test",
"templateData": {
"body": {
// wrong template
"placeholders": [{ "incorrectFormat": true }]
}
},
"language": "en"
}
}
]
};
cy.request({
method: 'POST',
url: 'https://pp5443.api.infobip.com/whatsapp/1/message/template',
headers: {
'Authorization': `App ff67d657889149a69fa4d8fb4c7598ed-3d3221e4-aff8-4f80-8b04-2a3afe1812f1`,
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: requestData,
failOnStatusCode: false
}).then((response) => {
// The verification response status code is 400, indicating that the request format is incorrect.
expect(response.status).to.eq(400);
// can further check whether the response body contains a specific error message to ensure it is the expected error type
expect(response.body).to.have.property('requestError');
expect(response.body.requestError.serviceException).to.have.property('messageId', 'BAD_REQUEST');
});
});
// Test Case: Fails with unauthorized error on invalid API key
it('fails with unauthorized error on invalid API key', () => {
const requestData = {
"messages": [
{
"from": "447860099299",
"to": "447570461417",
"messageId": "0287c2fa-792b-4e62-8de7-f650c16f2460",
"content": {
"templateName": "message_test",
"templateData": {
"body": {
"placeholders": ["hi"]
}
},
"language": "en"
}
}
]
};
cy.request({
method: 'POST',
url: 'https://pp5443.api.infobip.com/whatsapp/1/message/template',
headers: {
// Deliberately using the wrong API key
'Authorization': 'App incorrectApiKey',
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: requestData,
failOnStatusCode: false
}).then((response) => {
// The verification response status code is 401, indicating unauthorized
expect(response.status).to.eq(401);
// Can further check whether the response body contains a specific error message to ensure it is the expected error type
expect(response.body).to.have.property('requestError');
expect(response.body.requestError.serviceException).to.have.property('messageId', 'UNAUTHORIZED');
});
});
// Test Case: Fails with too many requests error when rate limit is exceeded
it('fails with too many requests error when rate limit is exceeded', () => {
const makeRequest = () => cy.request({
method: 'POST',
url: 'https://pp5443.api.infobip.com/whatsapp/1/message/template',
headers: {
'Authorization': `App ff67d657889149a69fa4d8fb4c7598ed-3d3221e4-aff8-4f80-8b04-2a3afe1812f1`,
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: {
"messages": [
{
"from": "447860099299",
"to": "447570461417",
"messageId": `test-msg-${Date.now()}`, // Use current timestamp to ensure uniqueness of messageId
"content": {
"templateName": "message_test",
"templateData": {
"body": {
"placeholders": ["hi"]
}
},
"language": "en"
}
}
]
},
failOnStatusCode: false
});
// Send multiple requests to try to trigger the rate limit
const requestCount = 10;
for (let i = 0; i < requestCount; i++) {
makeRequest().then((response) => {
if (response.status === 429) { // 检Check if 429 TOO_MANY_REQUESTS error is returned
expect(response.status).to.eq(429);
expect(response.body).to.have.property('requestError');
expect(response.body.requestError.serviceException).to.have.property('messageId', 'TOO_MANY_REQUESTS');
return false; // Once a rate limit is detected, interrupt the loop
}
});
}
});
// Test Case: Handles general errors appropriately
it('handles general errors appropriately', () => {
const requestData = {
"messages": [
{
"from": "invalidNumber", // a number in an invalid format
"to": "invalidNumber", //Same as above
"messageId": "invalid-message-id", // invalid message ID
"content": {
"templateName": "nonexistent_template", // a non-existent template name
"templateData": {
"body": {
"placeholders": ["This is a test"]
}
},
"language": "invalid" // an invalid language code
}
}
]
};
cy.request({
method: 'POST',
url: 'https://pp5443.api.infobip.com/whatsapp/1/message/template',
headers: {
'Authorization': `App ff67d657889149a69fa4d8fb4c7598ed-3d3221e4-aff8-4f80-8b04-2a3afe1812f1`,
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: requestData,
failOnStatusCode: false
}).then((response) => {
// Verify the response status code, which is expected to be an error code, such as 500
expect(response.status).to.be.oneOf([500, 400]); // Assume GENERAL_ERROR may return a 500 or 400 error code
// further check whether the response body contains a specific error message to ensure it is the expected error type
expect(response.body).to.have.property('requestError');
expect(response.body.requestError.serviceException).to.have.property('messageId', 'GENERAL_ERROR');
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment