Skip to content
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
761e19d
fix(emailController): validate required fields and process HTML attac…
csk731 Sep 28, 2025
a58da84
feat(emailBatch): integrate email announcement job processor and enha…
csk731 Oct 29, 2025
e4b01b1
feat(email): implement email processing and batch management features
csk731 Oct 30, 2025
be11ad4
feat(email): implement permission checks for email operations
csk731 Oct 30, 2025
e07065b
refactor(emailAnnouncementJobProcessor): streamline cron job initiali…
csk731 Oct 31, 2025
34a2746
feat(email): refactor email processing and enhance job management
csk731 Oct 31, 2025
28cdf56
feat(email): enhance documentation and validation in email controller…
csk731 Oct 31, 2025
6297b20
refactor(email): remove media validation from email controllers and t…
csk731 Oct 31, 2025
20b2cbe
refactor(email): remove announcement email job and related configurat…
csk731 Nov 11, 2025
271cb8e
feat(email): enhance email batch status management with attempt count…
csk731 Nov 11, 2025
e3742bf
feat(email): implement email processing enhancements and startup hand…
csk731 Nov 11, 2025
e27baf6
refactor(email): replace TemplateRenderingService with EmailTemplateS…
csk731 Nov 13, 2025
d627919
refactor(email): streamline email processing and enhance subscription…
csk731 Nov 14, 2025
5090356
refactor(email): update email subscription handling and validation
csk731 Nov 14, 2025
5ab8a2d
feat(email): add sender name configuration and improve logging
csk731 Dec 7, 2025
9a4efd2
refactor(email): update email configuration and enhance error handling.
csk731 Jan 17, 2026
97f19db
Merge branch 'development' into chaitanya-mailchimp-replacement
csk731 Jan 17, 2026
da912f9
refactor(email): implement lazy initialization for email sending serv…
csk731 Jan 17, 2026
66d7aed
feat: Add 'url' and 'textarea' to `TEMPLATE_VARIABLE_TYPES` in email …
csk731 Jan 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 29 additions & 8 deletions requirements/emailController/addNonHgnEmailSubscription.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,40 @@
1. ❌ **Returns error 400 if `email` field is missing from the request**
- Ensures that the function checks for the presence of the `email` field in the request body and responds with a `400` status code if it's missing.

2. ❌ **Returns error 400 if the provided `email` already exists in the subscription list**
2. ❌ **Returns error 400 if the provided `email` is invalid**
- Verifies that the function validates email format using `isValidEmailAddress` and responds with a `400` status code for invalid emails.

3. ❌ **Returns error 400 if the provided `email` already exists in the subscription list**
- This case checks that the function responds with a `400` status code and a message indicating that the email is already subscribed.

3. ❌ **Returns error 500 if there is an internal error while checking the subscription list**
- Covers scenarios where there's an issue querying the `EmailSubscriptionList` collection for the provided email (e.g., database connection issues).
4. ❌ **Returns error 400 if the email is already an HGN user**
- Verifies that the function checks if the email belongs to an existing HGN user and responds with a `400` status code, directing them to use the HGN account profile page.

5. ❌ **Returns error 500 if there is an internal error while checking the subscription list**
- Covers scenarios where there's an issue querying the `EmailSubcriptionList` collection for the provided email (e.g., database connection issues).

4. ❌ **Returns error 500 if there is an error sending the confirmation email**
6. ❌ **Returns error 500 if `FRONT_END_URL` cannot be determined from request**
- Verifies that the function handles cases where the frontend URL cannot be determined from request headers, config, or request information.

7. ❌ **Returns error 500 if there is an error sending the confirmation email**
- This case handles any issues that occur while calling the `emailSender` function, such as network errors or service unavailability.

8. ❌ **Returns error 400 if there's a duplicate key error (race condition)**
- Handles MongoDB duplicate key errors that might occur if the subscription is created simultaneously by multiple requests.

## Positive Cases

1. ❌ **Returns status 200 when a new email is successfully subscribed**
- Ensures that the function successfully creates a JWT token, constructs the email, and sends the subscription confirmation email to the user.
1. ✅ **Returns status 200 when a new email is successfully subscribed**
- Ensures that the function successfully creates an unconfirmed subscription record, generates a JWT token, and sends the subscription confirmation email to the user.

2. ✅ **Creates subscription with correct initial state**
- Verifies that the subscription is created with `isConfirmed: false`, `emailSubscriptions: true`, and proper normalization (lowercase email).

3. ✅ **Successfully sends a confirmation email containing the correct link**
- Verifies that the generated JWT token is correctly included in the confirmation link, and the frontend URL is dynamically determined from the request origin.

4. ✅ **Returns success even if confirmation email fails to send**
- Ensures that if the subscription is saved to the database but the confirmation email fails, the function still returns success (subscription is already saved).

2. ❌ **Successfully sends a confirmation email containing the correct link**
- Verifies that the generated JWT token is correctly included in the confirmation link sent to the user in the email body.
5. ❌ **Correctly normalizes email to lowercase**
- Ensures that email addresses are stored in lowercase format, matching the schema's lowercase enforcement.
31 changes: 21 additions & 10 deletions requirements/emailController/confirmNonHgnEmailSubscription.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,29 @@
# Confirm Non-HGN Email Subscription Function Tests
# Confirm Non-HGN Email Subscription Function

## Negative Cases
1. ✅ **Returns error 400 if `token` field is missing from the request**
- (Test: `should return 400 if token is not provided`)

2. ✅ **Returns error 401 if the provided `token` is invalid or expired**
- (Test: `should return 401 if token is invalid`)
1. ❌ **Returns error 400 if `token` field is missing from the request**
- Ensures that the function checks for the presence of the `token` field in the request body and responds with a `400` status code if it's missing.

3. ✅ **Returns error 400 if the decoded `token` does not contain a valid `email` field**
- (Test: `should return 400 if email is missing from payload`)
2. ❌ **Returns error 401 if the provided `token` is invalid or expired**
- Verifies that the function correctly handles invalid or expired JWT tokens and responds with a `401` status code.

4. ❌ **Returns error 500 if there is an internal error while saving the new email subscription**
3. ❌ **Returns error 400 if the decoded `token` does not contain a valid `email` field**
- Ensures that the function validates the token payload contains a valid email address and responds with a `400` status code if it doesn't.

4. ❌ **Returns error 404 if subscription doesn't exist**
- Verifies that the function only confirms existing subscriptions. If no subscription exists for the email in the token, it should return a `404` status code with a message directing the user to subscribe first.

5. ❌ **Returns error 500 if there is an internal error while updating the subscription**
- Covers scenarios where there's a database error while updating the subscription status.

## Positive Cases
1. ❌ **Returns status 200 when a new email is successfully subscribed**

2. ❌ **Returns status 200 if the email is already subscribed (duplicate email)**
1. ✅ **Returns status 200 when an existing unconfirmed subscription is successfully confirmed**
- Ensures that the function updates an existing unconfirmed subscription to confirmed status, sets `confirmedAt` timestamp, and enables `emailSubscriptions`.

2. ✅ **Returns status 200 if the email subscription is already confirmed (idempotent)**
- Verifies that the function is idempotent - if a subscription is already confirmed, it returns success without attempting to update again.

3. ❌ **Correctly handles email normalization (lowercase)**
- Ensures that email addresses are normalized to lowercase for consistent lookups, matching the schema's lowercase enforcement.
33 changes: 33 additions & 0 deletions requirements/emailController/processPendingAndStuckEmails.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Process Pending and Stuck Emails Function

## Negative Cases

1. ❌ **Returns error 401 if `requestor` is missing from the request**
- Ensures that the function checks for the presence of `requestor.requestorId` in the request body and responds with a `401` status code if it's missing.

2. ❌ **Returns error 403 if user doesn't have `sendEmails` permission**
- Verifies that the function checks user permissions and responds with a `403` status code if the user is not authorized to process emails.

3. ❌ **Returns error 500 if there is an internal error while processing**
- Covers scenarios where there are errors during the processing of pending and stuck emails (e.g., database errors, service failures).

## Positive Cases

1. ✅ **Returns status 200 when processing is triggered successfully**
- Ensures that the function triggers the email processor to handle pending and stuck emails and returns success.

2. ✅ **Resets stuck emails (SENDING status) to PENDING**
- Verifies that emails in SENDING status are reset to PENDING so they can be reprocessed (typically after server restart).

3. ✅ **Resets stuck batches (SENDING status) to PENDING**
- Ensures that EmailBatch items in SENDING status are reset to PENDING so they can be reprocessed.

4. ✅ **Queues all PENDING emails for processing**
- Verifies that all emails in PENDING status are added to the processing queue for immediate processing.

5. ✅ **Handles errors gracefully without throwing**
- Ensures that individual errors during processing (e.g., resetting a specific stuck email) are logged but don't prevent the overall process from completing.

6. ❌ **Provides detailed logging for troubleshooting**
- Verifies that the function logs information about the number of stuck emails/batches found and processed.

27 changes: 23 additions & 4 deletions requirements/emailController/removeNonHgnEmailSubscription.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,29 @@
# Remove Non-HGN Email Subscription Function Tests
# Remove Non-HGN Email Subscription Function

## Negative Cases

1. ✅ **Returns error 400 if `email` field is missing from the request**
- (Test: `should return 400 if email is missing`)
- Ensures that the function checks for the presence of the `email` field in the request body and responds with a `400` status code if it's missing.

2. ❌ **Returns error 400 if the provided `email` is invalid**
- Verifies that the function validates email format using `isValidEmailAddress` and responds with a `400` status code for invalid emails.

2. ❌ **Returns error 500 if there is an internal error while deleting the email subscription**
3. ❌ **Returns error 404 if the email subscription is not found**
- Verifies that the function handles cases where no subscription exists for the given email and responds with a `404` status code.

4. ❌ **Returns error 500 if there is an internal error while deleting the email subscription**
- Covers scenarios where there's a database error while deleting the subscription (e.g., database connection issues).

## Positive Cases
1. ❌ **Returns status 200 when an email is successfully unsubscribed**

1. ✅ **Returns status 200 when an email is successfully unsubscribed**
- Ensures that the function deletes the subscription record from the `EmailSubcriptionList` collection and returns success with a `200` status code.

2. ✅ **Correctly normalizes email to lowercase for lookup**
- Verifies that the email is normalized to lowercase before querying/deleting, ensuring consistent matches with the schema's lowercase enforcement.

3. ✅ **Uses direct email match (no regex needed)**
- Ensures that since the schema enforces lowercase emails, the function uses direct email matching instead of case-insensitive regex.

4. ❌ **Handles concurrent unsubscribe requests gracefully**
- Ensures that if multiple unsubscribe requests are made simultaneously, the function handles race conditions appropriately.
69 changes: 69 additions & 0 deletions requirements/emailController/resendEmail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Resend Email Function

## Negative Cases

1. ❌ **Returns error 401 if `requestor` is missing from the request**
- Ensures that the function checks for the presence of `requestor.requestorId` in the request body and responds with a `401` status code if it's missing.

2. ❌ **Returns error 403 if user doesn't have `sendEmails` permission**
- Verifies that the function checks user permissions and responds with a `403` status code if the user is not authorized to resend emails.

3. ❌ **Returns error 400 if `emailId` is missing or invalid**
- Ensures that the function validates `emailId` is a valid MongoDB ObjectId.

4. ❌ **Returns error 404 if the original email is not found**
- Verifies that the function handles cases where the email with the provided `emailId` doesn't exist.

5. ❌ **Returns error 400 if `recipientOption` is missing**
- Ensures that the `recipientOption` field is required in the request body.

6. ❌ **Returns error 400 if `recipientOption` is invalid**
- Verifies that the `recipientOption` must be one of: `'all'`, `'specific'`, or `'same'`.

7. ❌ **Returns error 400 if `specificRecipients` is required but missing for 'specific' option**
- Ensures that when `recipientOption` is `'specific'`, the `specificRecipients` array must be provided and non-empty.

8. ❌ **Returns error 404 if no recipients found for 'same' option**
- Verifies that when `recipientOption` is `'same'`, the original email must have EmailBatch items with recipients.

9. ❌ **Returns error 400 if recipient count exceeds maximum limit for 'specific' option**
- Ensures that when using `'specific'` option, the recipient limit (2000) is enforced.

10. ❌ **Returns error 400 if no recipients are found**
- Verifies that after determining recipients, at least one recipient must be available.

11. ❌ **Returns error 404 if requestor user is not found**
- Ensures that the function validates the requestor exists in the userProfile collection.

12. ❌ **Returns error 500 if there is an internal error during email creation**
- Covers scenarios where there are database errors or service failures during email/batch creation.

## Positive Cases

1. ✅ **Returns status 200 when email is successfully resent with 'all' option**
- Ensures that when `recipientOption` is `'all'`, the function sends to all active HGN users and confirmed email subscribers.

2. ✅ **Returns status 200 when email is successfully resent with 'specific' option**
- Verifies that when `recipientOption` is `'specific'`, the function sends to only the provided `specificRecipients` list.

3. ✅ **Returns status 200 when email is successfully resent with 'same' option**
- Ensures that when `recipientOption` is `'same'`, the function extracts recipients from the original email's EmailBatch items and deduplicates them.

4. ✅ **Creates new email copy with same subject and HTML content**
- Verifies that the function creates a new Email document with the same `subject` and `htmlContent` as the original, but with a new `createdBy` user.

5. ✅ **Enforces recipient limit only for 'specific' option**
- Ensures that the maximum recipient limit is enforced only when `recipientOption` is `'specific'`, but skipped for `'all'` and `'same'` (broadcast scenarios).

6. ✅ **Skips recipient limit for broadcast scenarios ('all' and 'same')**
- Verifies that when using `'all'` or `'same'` options, the recipient limit is not enforced.

7. ✅ **Deduplicates recipients for 'same' option**
- Ensures that when using `'same'` option, duplicate email addresses are removed from the recipient list.

8. ✅ **Creates email batches in a transaction**
- Ensures that the parent Email and all EmailBatch items are created atomically in a single transaction.

9. ❌ **Handles transaction rollback on errors**
- Ensures that if any part of email/batch creation fails, the entire transaction is rolled back.

51 changes: 51 additions & 0 deletions requirements/emailController/retryEmail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Retry Email Function

## Negative Cases

1. ❌ **Returns error 401 if `requestor` is missing from the request**
- Ensures that the function checks for the presence of `requestor.requestorId` in the request body and responds with a `401` status code if it's missing.

2. ❌ **Returns error 403 if user doesn't have `sendEmails` permission**
- Verifies that the function checks user permissions and responds with a `403` status code if the user is not authorized to retry emails.

3. ❌ **Returns error 400 if `emailId` parameter is missing or invalid**
- Ensures that the function validates `emailId` from `req.params` is a valid MongoDB ObjectId.

4. ❌ **Returns error 404 if the email is not found**
- Verifies that the function handles cases where the email with the provided `emailId` doesn't exist.

5. ❌ **Returns error 400 if email is not in a retryable status**
- Ensures that the function only allows retry for emails in `FAILED` or `PROCESSED` status. Returns `400` for other statuses.

6. ❌ **Returns error 500 if there is an internal error while fetching failed batches**
- Covers scenarios where there are database errors while querying for failed EmailBatch items.

7. ❌ **Returns error 500 if there is an internal error while resetting email status**
- Covers scenarios where there are database errors while updating the email status to PENDING.

8. ❌ **Returns error 500 if there is an internal error while resetting batches**
- Covers scenarios where there are database errors while resetting individual EmailBatch items to PENDING.

## Positive Cases

1. ✅ **Returns status 200 when email is successfully retried with failed batches**
- Ensures that the function marks the parent Email as PENDING, resets all failed EmailBatch items to PENDING, queues the email for processing, and returns success with the count of failed items retried.

2. ✅ **Returns status 200 when email has no failed batches**
- Verifies that if an email has no failed EmailBatch items, the function returns success with `failedItemsRetried: 0` without error.

3. ✅ **Correctly resets only failed EmailBatch items**
- Ensures that only EmailBatch items with `FAILED` status are reset to PENDING for retry.

4. ✅ **Marks parent email as PENDING**
- Verifies that the parent Email status is changed to PENDING, allowing it to be reprocessed.

5. ✅ **Queues email for processing after reset**
- Ensures that after resetting the email and batches, the email is added to the processing queue.

6. ✅ **Returns correct data in response**
- Verifies that the response includes `emailId` and `failedItemsRetried` count in the data field.

7. ❌ **Handles concurrent retry requests gracefully**
- Ensures that if multiple retry requests are made simultaneously, the function handles race conditions appropriately.

40 changes: 37 additions & 3 deletions requirements/emailController/sendEmail.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,43 @@

## Negative Cases

1. ❌ **Returns error 400 if `to`, `subject`, or `html` fields are missing from the request**
2. ❌ **Returns error 500 if there is an internal error while sending the email**
1. ❌ **Returns error 401 if `requestor` is missing from the request**
- Ensures that the function checks for the presence of `requestor.requestorId` in the request body and responds with a `401` status code if it's missing.

2. ❌ **Returns error 403 if user doesn't have `sendEmails` permission**
- Verifies that the function checks user permissions and responds with a `403` status code if the user is not authorized to send emails.

3. ❌ **Returns error 400 if `to`, `subject`, or `html` fields are missing from the request**
- Ensures that all required fields (`to`, `subject`, `html`) are present in the request body.

4. ❌ **Returns error 400 if email contains unreplaced template variables**
- Verifies that the function validates that all template variables in `subject` and `html` have been replaced before sending.

5. ❌ **Returns error 404 if requestor user is not found**
- Ensures that the function validates the requestor exists in the userProfile collection.

6. ❌ **Returns error 400 if recipient count exceeds maximum limit (2000)**
- Verifies that the function enforces the maximum recipients per request limit for specific recipient requests.

7. ❌ **Returns error 400 if any recipient email is invalid**
- Ensures that all recipient email addresses are validated before creating batches.

8. ❌ **Returns error 500 if there is an internal error during email creation**
- Covers scenarios where there are database errors or service failures during email/batch creation.

## Positive Cases

1. ✅ **Returns status 200 when email is successfully sent with `to`, `subject`, and `html` fields provided**
1. ✅ **Returns status 200 when email is successfully created with valid recipients**
- Ensures that the function creates the parent Email document and EmailBatch items in a transaction, queues the email for processing, and returns success.

2. ✅ **Enforces recipient limit for specific recipient requests**
- Verifies that the maximum recipient limit (2000) is enforced when sending to specific recipients.

3. ✅ **Creates email batches correctly**
- Ensures that recipients are properly normalized, validated, and chunked into EmailBatch items according to the configured batch size.

4. ✅ **Validates all template variables are replaced**
- Verifies that the function checks both HTML content and subject for unreplaced template variables before allowing email creation.

5. ❌ **Handles transaction rollback on errors**
- Ensures that if any part of email/batch creation fails, the entire transaction is rolled back.
Loading
Loading