From 3b8a585eafdb37aadc6b1b601a0617be59462ecd Mon Sep 17 00:00:00 2001
From: Sam Schumacher <42777208+sam-schu@users.noreply.github.com>
Date: Fri, 4 Oct 2024 13:08:01 -0400
Subject: [PATCH] Do not allow existing users to be added again
---
.../workflow/common/PermissionsModal.test.tsx | 40 +++++++++++++++++++
.../workflow/common/PermissionsModal.tsx | 16 +++++---
2 files changed, 51 insertions(+), 5 deletions(-)
diff --git a/src/pages/workflows/workflow/common/PermissionsModal.test.tsx b/src/pages/workflows/workflow/common/PermissionsModal.test.tsx
index be52281c95..4863493739 100644
--- a/src/pages/workflows/workflow/common/PermissionsModal.test.tsx
+++ b/src/pages/workflows/workflow/common/PermissionsModal.test.tsx
@@ -275,6 +275,46 @@ describe('PermissionsModal', () => {
expect(addButton).toHaveAttribute('aria-disabled', 'true');
});
+ it('gives an error with a user email that already exists', async () => {
+ // ARRANGE
+ mockAjax();
+ const user: UserEvent = userEvent.setup();
+
+ await act(async () => {
+ renderWithAppContexts(
+
+ );
+ });
+
+ // ACT/ASSERT
+ const textbox = screen.getByRole('textbox');
+ const addButton = screen.getByRole('button', { name: 'Add' });
+
+ fireEvent.change(textbox, { target: { value: 'user1@foo.com' } });
+
+ expect(screen.getByText('User has already been added')).toBeInTheDocument();
+ expect(addButton).toHaveAttribute('aria-disabled', 'true');
+
+ fireEvent.change(textbox, { target: { value: 'user3@test.com' } });
+
+ expect(screen.queryByText('User has already been added')).not.toBeInTheDocument();
+ expect(addButton).toHaveAttribute('aria-disabled', 'false');
+
+ await user.click(addButton);
+
+ fireEvent.change(textbox, { target: { value: 'user3@test.com' } });
+
+ expect(screen.getByText('User has already been added')).toBeInTheDocument();
+ expect(addButton).toHaveAttribute('aria-disabled', 'true');
+ });
+
it('lets you make a public workflow private', async () => {
// ARRANGE
mockAjax({
diff --git a/src/pages/workflows/workflow/common/PermissionsModal.tsx b/src/pages/workflows/workflow/common/PermissionsModal.tsx
index c37c73b7ae..7fa512a5d9 100644
--- a/src/pages/workflows/workflow/common/PermissionsModal.tsx
+++ b/src/pages/workflows/workflow/common/PermissionsModal.tsx
@@ -56,10 +56,16 @@ type CurrentUsersProps = {
setAllPermissions: Dispatch>;
};
-const constraints = {
- searchValue: {
- email: true,
- },
+const constraints = (existingUserEmails: string[]) => {
+ return {
+ searchValue: {
+ email: true,
+ exclusion: {
+ within: existingUserEmails,
+ message: 'has already been added',
+ },
+ },
+ };
};
const styles: CSSProperties = {
@@ -171,7 +177,7 @@ export const PermissionsModal = (props: WorkflowPermissionsModalProps) => {
const userEmails = _.map('user', permissions);
const [userValueModified, setUserValueModified] = useState(false);
const publicAccessLevel: WorkflowAccessLevel = _.find(publicUser, permissions)?.role ?? 'NO ACCESS';
- const errors = validate({ searchValue }, constraints, {
+ const errors = validate({ searchValue }, constraints(userEmails), {
prettify: (v) => ({ searchValue: 'User' }[v] || validate.prettify(v)),
});