Skip to content

Conversation

@mark-r-bjss
Copy link
Contributor

Description

Context

Type of changes

  • Refactoring (non-breaking change)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would change existing functionality)
  • Bug fix (non-breaking change which fixes an issue)

Checklist

  • I am familiar with the contributing guidelines
  • I have followed the code style of the project
  • I have added tests to cover my changes
  • I have updated the documentation accordingly
  • This PR is a result of pair or mob programming

Sensitive Information Declaration

To ensure the utmost confidentiality and protect your and others privacy, we kindly ask you to NOT including PII (Personal Identifiable Information) / PID (Personal Identifiable Data) or any other sensitive data in this PR (Pull Request) and the codebase changes. We will remove any PR that do contain any sensitive information. We really appreciate your cooperation in this matter.

  • I confirm that neither PII/PID nor sensitive data are included in this PR and the codebase changes.

@mark-r-bjss mark-r-bjss requested a review from a team as a code owner December 23, 2025 11:49

return (
<ErrorSummary ref={errorSummaryRef}>
<ErrorSummary ref={errorSummaryRef} tabIndex={-1}>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is an AI-autocomplete typo, i.e. I didn't notice it had changed it. Reverted.

<div
class="nhsuk-grid-row nhsuk-grid-column-two-thirds"
>
<div
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this test is for the validation being triggered so I'm not convinced the error summary should be removed from the snapshot?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error summary should not show when validation passes (which is the bug that was being fixed). These tests were ambiguous so I've split the form-validation tests into success and fail scenarios.

<div
class="nhsuk-grid-row nhsuk-grid-column-two-thirds"
>
<div
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated as above.

expect(scrollIntoViewMock).not.toHaveBeenCalled();
});

test('Renders NhsNotifyErrorSummary correctly with empty error state', async () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think based on your changes, might also be worth adding tests for errorState object having formError/fieldError keys but with falsy values, since component also won't render in those scenarios either now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

} from '@aws-sdk/client-cognito-identity-provider';
import { logger } from '@/src/utils/logger';

export const INTERNAL_ID_ATTRIBUTE = 'custom:nhs_notify_user_id';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the ticket mentions username but I'm guessing this is what we're using instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a comment to the ticket with a diagram showing an example of the data model and how it will change in the migration.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Essentially "username" is a reference to the Cognito username field, when the ticket was originally written we were going to use that as the primary identifier for the user but instead went with an internally defined UUID.

@@ -1 +0,0 @@
*.json
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we have something similar in the new dir?

if (error instanceof ConditionalCheckFailedException) {
return 'lock-failure';
}
logger.error(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you not want one of these error logs before your lock-failure return?

// act
let caughtError;
try {
await discoverUserPoolId('nonexistent');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not something to change but an FYI you canw write this as

await expect(discoverUserPoolId('nonexistent')).rejects.toThrowError('User pool nhs-notify-nonexistent-app not found')

} while (paginationToken);

const userPoolId = userPools.find(
(pool) => pool.Name === TARGET_USER_POOL_NAME(env)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reduce unnecessary calls to AWS if you do this check before getting each next page

)?.Value;
return [sub, internalId];
})
.filter(([sub, internalId]) => sub && internalId)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are we expecting to have any users that don't have sub and internalId defined?

return [sub, internalId];
})
.filter(([sub, internalId]) => sub && internalId)
.reduce(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't this just Object.fromEntries?

// Read parameters
const { dryRun, env, userDetailsFile } = readParams();

if (!userDetailsFile) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in what circumstances would you expect to start with a reference to a user details file that is only generated by this script?

if (!dryRun) {
const updateResult =
entity === 'template'
? await updateTemplateRecord(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's unnecessary to split this out here - the only difference between what you're doing with templates and routing configs is the table name. just pass the table name into migrateRecord instead of entity and save a lot of duplicate code

id: record.id,
},
UpdateExpression:
'SET createdBy = :createdBy, updatedBy = :updatedBy ADD #lockNumber :lockNumberIncrement',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we really want to be incrementing lock number? elsewhere we've only been doing that for user-initiated changes.

},
ExpressionAttributeValues: {
':expectedLockNumber': record.lockNumber ?? 0,
':createdBy': newCreatedBy ?? record.createdBy,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why the fallback? if we don't have a value to set, why do the update in the first place? and also would we expect there to be any records we want to update that are missing these fields?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants