From 91761b1aec7a8845a68146bc0286da437e4625ef Mon Sep 17 00:00:00 2001
From: rayangler <27821750+rayangler@users.noreply.github.com>
Date: Wed, 28 Feb 2024 15:13:36 -0500
Subject: [PATCH] DOP-4352: Set completion time for Netlify builds (#1002)

---
 api/handlers/jobs.ts              | 18 ++++++++++++++----
 src/repositories/jobRepository.ts |  6 ++++--
 tests/unit/job/api/jobs.test.ts   | 11 +++++++++++
 3 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/api/handlers/jobs.ts b/api/handlers/jobs.ts
index 8aedd6ffd..2f0bfe9ca 100644
--- a/api/handlers/jobs.ts
+++ b/api/handlers/jobs.ts
@@ -246,10 +246,20 @@ export async function snootyBuildComplete(event: APIGatewayEvent): Promise<APIGa
     await client.connect();
     const db = client.db(c.get<string>('dbName'));
     const jobRepository = new JobRepository(db, c, consoleLogger);
-    await jobRepository.updateExecutionTime(jobId, { gatsbyCloudEndTime: new Date() });
-    const updateResponse = await jobRepository.updateWithStatus(jobId, null, payload.status || JobStatus.failed, false);
-    const previewUrl = getPreviewUrl(updateResponse.payload, c.get<string>('env'));
-    await notifyBuildSummary(jobId, { mongoClient: client, previewUrl });
+
+    if (event.queryStringParameters?.builder === 'netlify') {
+      await jobRepository.updateExecutionTime(jobId, { netlifyEndTime: new Date() });
+    } else {
+      await jobRepository.updateExecutionTime(jobId, { gatsbyCloudEndTime: new Date() });
+      const updateResponse = await jobRepository.updateWithStatus(
+        jobId,
+        null,
+        payload.status || JobStatus.failed,
+        false
+      );
+      const previewUrl = getPreviewUrl(updateResponse.payload, c.get<string>('env'));
+      await notifyBuildSummary(jobId, { mongoClient: client, previewUrl });
+    }
   } catch (e) {
     consoleLogger.error('SnootyBuildCompleteError', e);
     return {
diff --git a/src/repositories/jobRepository.ts b/src/repositories/jobRepository.ts
index ba4caa83c..7712f15b3 100644
--- a/src/repositories/jobRepository.ts
+++ b/src/repositories/jobRepository.ts
@@ -106,9 +106,11 @@ export class JobRepository extends BaseRepository {
       _id: new objectId(id),
     };
     const update = { $set: setValues };
-    this.updateOne(query, update, `Mongo Timeout Error: Timed out while retrieving job`).catch((err) => {
+    try {
+      await this.updateOne(query, update, `Mongo Timeout Error: Timed out while retrieving job`);
+    } catch (err) {
       this._logger.error('updateExecutionTime', `Error: ${err}`);
-    });
+    }
   }
 
   async findOneAndUpdateJob(query): Promise<Job | null> {
diff --git a/tests/unit/job/api/jobs.test.ts b/tests/unit/job/api/jobs.test.ts
index c88acca6b..0d834ea4c 100644
--- a/tests/unit/job/api/jobs.test.ts
+++ b/tests/unit/job/api/jobs.test.ts
@@ -77,4 +77,15 @@ describe('Post-build webhook tests', () => {
     );
     expect(res.statusCode).toBe(400);
   });
+
+  test('successfully handles builder=netlify query string param', async () => {
+    const signature = createSha256Signature(payloadString, 'SNOOTY_SECRET');
+    const mockReqEvent = createMockAPIGatewayEvent(payloadString, { 'x-snooty-signature': signature });
+    mockReqEvent.queryStringParameters = {
+      builder: 'netlify',
+    };
+    const res = await SnootyBuildComplete(mockReqEvent);
+    // Ideally, we would have a more robust way to check that only specific data is updated
+    expect(res.statusCode).toBe(200);
+  });
 });