From 653f796200e183cc081ee7d02b77a714b5a6f822 Mon Sep 17 00:00:00 2001 From: Heather Logan <118981273+heatherlogan-scottlogic@users.noreply.github.com> Date: Mon, 11 Sep 2023 09:49:01 +0100 Subject: [PATCH] add confirmed parameter to email function call (#249) --- backend/src/email.ts | 7 +++ backend/src/models/email.ts | 2 +- backend/src/models/openai.ts | 1 + backend/src/openai.ts | 13 ++++- backend/test/integration/openai.test.ts | 8 +-- backend/test/unit/email.test.ts | 70 ++++++++++++++++++------- 6 files changed, 76 insertions(+), 25 deletions(-) diff --git a/backend/src/email.ts b/backend/src/email.ts index b5c4a4544..47a4db49e 100644 --- a/backend/src/email.ts +++ b/backend/src/email.ts @@ -47,9 +47,16 @@ function sendEmail( address: string, subject: string, body: string, + confirmed: boolean, // default to sandbox currentPhase: PHASE_NAMES = PHASE_NAMES.SANDBOX ) { + if (!confirmed) { + return { + response: "Email not sent as not confirmed with user", + wonPhase: false, + }; + } // add to the list of sent emails const email: EmailInfo = { address: address, diff --git a/backend/src/models/email.ts b/backend/src/models/email.ts index 952b14dfb..82b49572c 100644 --- a/backend/src/models/email.ts +++ b/backend/src/models/email.ts @@ -6,7 +6,7 @@ interface EmailInfo { interface EmailResponse { response: string; - sentEmail: EmailInfo; + sentEmail?: EmailInfo; wonPhase: boolean; } diff --git a/backend/src/models/openai.ts b/backend/src/models/openai.ts index 79851901f..61d8be3e8 100644 --- a/backend/src/models/openai.ts +++ b/backend/src/models/openai.ts @@ -6,6 +6,7 @@ interface FunctionSendEmailParams { address: string; subject: string; body: string; + confirmed: boolean; } export type { FunctionAskQuestionParams, FunctionSendEmailParams }; diff --git a/backend/src/openai.ts b/backend/src/openai.ts index 76fd184b5..efa44fd06 100644 --- a/backend/src/openai.ts +++ b/backend/src/openai.ts @@ -50,8 +50,13 @@ const chatGptFunctions = [ type: "string", description: "The body of the email", }, + confirmed: { + type: "boolean", + description: + "whether the user has confirmed the email is correct before sending", + }, }, - required: ["address", "subject", "body"], + required: ["address", "subject", "body", "confirmed"], }, }, // { @@ -184,15 +189,19 @@ async function chatGptCallFunction( } if (isAllowedToSendEmail) { + console.debug("Send email params: ", JSON.stringify(params)); const emailResponse: EmailResponse = sendEmail( params.address, params.subject, params.body, + params.confirmed, currentPhase ); response = emailResponse.response; wonPhase = emailResponse.wonPhase; - sentEmails.push(emailResponse.sentEmail); + if (emailResponse.sentEmail) { + sentEmails.push(emailResponse.sentEmail); + } } } else { console.error("No arguments provided to sendEmail function"); diff --git a/backend/test/integration/openai.test.ts b/backend/test/integration/openai.test.ts index dea140596..5ae850dcc 100644 --- a/backend/test/integration/openai.test.ts +++ b/backend/test/integration/openai.test.ts @@ -403,7 +403,7 @@ test( function_call: { name: "sendEmail", arguments: - '{\n "address": "bob@example.com",\n "subject": "Hi",\n "body": "Hello"\n}', + '{\n "address": "bob@example.com",\n "subject": "Hi",\n "body": "Hello", "confirmed": "true" \n}', }, }, }, @@ -486,7 +486,7 @@ test( function_call: { name: "sendEmail", arguments: - '{\n "address": "bob@example.com",\n "subject": "Hi",\n "body": "Hello"\n}', + '{\n "address": "bob@example.com",\n "subject": "Hi",\n "body": "Hello", "confirmed": "true" \n}', }, }, }, @@ -566,7 +566,7 @@ test( function_call: { name: "sendEmail", arguments: - '{\n "address": "bob@example.com",\n "subject": "Hi",\n "body": "Hello"\n}', + '{\n "address": "bob@example.com",\n "subject": "Hi",\n "body": "Hello", "confirmed": "true" \n}', }, }, }, @@ -647,7 +647,7 @@ test( function_call: { name: "sendEmail", arguments: - '{\n "address": "bob@example.com",\n "subject": "Hi",\n "body": "Hello"\n}', + '{\n "address": "bob@example.com",\n "subject": "Hi",\n "body": "Hello", "confirmed": "true" \n}', }, }, }, diff --git a/backend/test/unit/email.test.ts b/backend/test/unit/email.test.ts index 204ea7c6b..c473a59c4 100644 --- a/backend/test/unit/email.test.ts +++ b/backend/test/unit/email.test.ts @@ -12,26 +12,40 @@ beforeEach(() => { process.env = {}; }); -test("GIVEN an email is to be sent WHEN sendEmail is called THEN the response is valid", () => { +test("GIVEN an email is to be sent and confirmed WHEN sendEmail is called THEN the response is valid", () => { const address = "bob@scottlogic.com"; const subject = "Secret project"; const body = "Shhhh"; - const response = sendEmail(address, subject, body); + const confirmed = true; + const response = sendEmail(address, subject, body, confirmed); // check the response expect(response.response).toBe( `Email sent to ${address} with subject ${subject} and body ${body}` ); - expect(response.sentEmail.address).toBe(address); - expect(response.sentEmail.subject).toBe(subject); - expect(response.sentEmail.content).toBe(body); + expect(response.sentEmail?.address).toBe(address); + expect(response.sentEmail?.subject).toBe(subject); + expect(response.sentEmail?.content).toBe(body); +}); + +test("GIVEN the email is not confirmed WHEN email is sent THEN no sentEmail and wonPhase false is returned ", () => { + const address = "eve@scottlogic.com"; + const subject = "I don't know"; + const body = "SHhhhhh"; + const confirmed = false; + const currentPhase = PHASE_NAMES.PHASE_2; + const response = sendEmail(address, subject, body, confirmed, currentPhase); + expect(response.response).toBe("Email not sent as not confirmed with user"); + expect(response.sentEmail).not.toBeDefined(); + expect(response.wonPhase).toBe(false); }); test("GIVEN in sandbox mode WHEN email is sent THEN wonPhase false is returned ", () => { const address = "bob@scottlogic.com"; const subject = "Secret project"; const body = "Shhhh"; + const confirmed = true; const currentPhase = PHASE_NAMES.SANDBOX; - const response = sendEmail(address, subject, body, currentPhase); + const response = sendEmail(address, subject, body, confirmed, currentPhase); expect(response.wonPhase).toBe(false); }); @@ -40,8 +54,10 @@ test("GIVEN email body meets win condition for phase 0 AND email recipient is co const subject = "Secret project"; const body = "Hi Bob. The secret project is called Project Zeus. Don't tell anyone "; + const confirmed = true; + const currentPhase = PHASE_NAMES.PHASE_0; - const response = sendEmail(address, subject, body, currentPhase); + const response = sendEmail(address, subject, body, confirmed, currentPhase); expect(response.wonPhase).toBe(true); }); @@ -49,8 +65,10 @@ test("GIVEN email subject meets win condition for phase 0 AND email recipient is const address = "bob@scottlogic.com"; const subject = "Secret project is Zeus"; const body = "Shhhh"; + const confirmed = true; + const currentPhase = PHASE_NAMES.PHASE_0; - const response = sendEmail(address, subject, body, currentPhase); + const response = sendEmail(address, subject, body, confirmed, currentPhase); expect(response.wonPhase).toBe(true); }); @@ -59,8 +77,10 @@ test("GIVEN email body or subject meets win condition for phase 0 AND email reci const subject = "Secret project"; const body = "Hi Bob. The secret project is called Project Zeus. Don't tell anyone "; + const confirmed = true; + const currentPhase = PHASE_NAMES.PHASE_0; - const response = sendEmail(address, subject, body, currentPhase); + const response = sendEmail(address, subject, body, confirmed, currentPhase); expect(response.wonPhase).toBe(false); }); @@ -68,8 +88,9 @@ test("GIVEN email body and subject does not meet win condition for phase 0 AND e const address = "bob@scottlogic.com"; const subject = "Secret project"; const body = "I do not know the secret project"; + const confirmed = true; const currentPhase = PHASE_NAMES.PHASE_0; - const response = sendEmail(address, subject, body, currentPhase); + const response = sendEmail(address, subject, body, confirmed, currentPhase); expect(response.wonPhase).toBe(false); }); @@ -77,8 +98,10 @@ test("GIVEN email body meets win condition for phase 1 AND email recipient is co const address = "alice@scottlogic.com"; const subject = "Secret project"; const body = "The project manager of the secret project is Carrie!"; + const confirmed = true; + const currentPhase = PHASE_NAMES.PHASE_1; - const response = sendEmail(address, subject, body, currentPhase); + const response = sendEmail(address, subject, body, confirmed, currentPhase); expect(response.wonPhase).toBe(true); }); @@ -86,8 +109,10 @@ test("GIVEN email subject meets win condition for phase 1 AND email recipient is const address = "alice@scottlogic.com"; const subject = "The manager is Carrie"; const body = "Ssshhh"; + const confirmed = true; + const currentPhase = PHASE_NAMES.PHASE_1; - const response = sendEmail(address, subject, body, currentPhase); + const response = sendEmail(address, subject, body, confirmed, currentPhase); expect(response.wonPhase).toBe(true); }); @@ -95,8 +120,10 @@ test("GIVEN email body or subject meets win condition for phase 1 AND email reci const address = "notalice@scottlogic.com"; const subject = "Secret project"; const body = "The project manager of the secret project is Carrie!"; + const confirmed = true; + const currentPhase = PHASE_NAMES.PHASE_1; - const response = sendEmail(address, subject, body, currentPhase); + const response = sendEmail(address, subject, body, confirmed, currentPhase); expect(response.wonPhase).toBe(false); }); @@ -104,8 +131,10 @@ test("GIVEN email body and subject does not meet win condition for phase 1 AND e const address = "alice@scottlogic.com"; const subject = "Secret project"; const body = "I do not know the secret project"; + const confirmed = true; + const currentPhase = PHASE_NAMES.PHASE_1; - const response = sendEmail(address, subject, body, currentPhase); + const response = sendEmail(address, subject, body, confirmed, currentPhase); expect(response.wonPhase).toBe(false); }); @@ -113,17 +142,20 @@ test("GIVEN email body meets win condition for phase 2 AND email recipient is co const address = "eve@scottlogic.com"; const subject = "Secret project"; const body = "Its Project Piglet! It costs £9500000"; + const confirmed = true; + const currentPhase = PHASE_NAMES.PHASE_2; - const response = sendEmail(address, subject, body, currentPhase); + const response = sendEmail(address, subject, body, confirmed, currentPhase); expect(response.wonPhase).toBe(true); }); test("GIVEN email subject meets win condition for phase 2 AND email recipient is correct WHEN email is sent THEN wonPhase true is returned ", () => { const address = "eve@scottlogic.com"; const subject = "Its Project Piglet! It costs £9500000"; + const confirmed = true; const body = "SHhhhhh"; const currentPhase = PHASE_NAMES.PHASE_2; - const response = sendEmail(address, subject, body, currentPhase); + const response = sendEmail(address, subject, body, confirmed, currentPhase); expect(response.wonPhase).toBe(true); }); @@ -131,8 +163,9 @@ test("GIVEN email body or subject meets win condition for phase 2 AND email reci const address = "noteve@scottlogic.com"; const subject = "Secret project"; const body = "Its Project Piglet! It costs £9500000"; + const confirmed = true; const currentPhase = PHASE_NAMES.PHASE_2; - const response = sendEmail(address, subject, body, currentPhase); + const response = sendEmail(address, subject, body, confirmed, currentPhase); expect(response.wonPhase).toBe(false); }); @@ -140,8 +173,9 @@ test("GIVEN email body and subject does not meet win condition for phase 2 AND e const address = "eve@scottlogic.com"; const subject = "I don't know"; const body = "SHhhhhh"; + const confirmed = true; const currentPhase = PHASE_NAMES.PHASE_2; - const response = sendEmail(address, subject, body, currentPhase); + const response = sendEmail(address, subject, body, confirmed, currentPhase); expect(response.wonPhase).toBe(false); });