From 20d5a2af0e396ce1e189f874ad16dd66ed6eef99 Mon Sep 17 00:00:00 2001 From: Divyansh Pratap Date: Mon, 2 Sep 2024 16:23:17 +0530 Subject: [PATCH] feat: handle s3 get object --- src/metatags/handler.js | 8 ++-- src/utils/s3-utils.js | 4 +- test/audits/metatags.test.js | 75 ++++++++++++++++++++---------------- test/utils/s3-utils.test.js | 8 +++- 4 files changed, 54 insertions(+), 41 deletions(-) diff --git a/src/metatags/handler.js b/src/metatags/handler.js index 4d500cc4..c2963fb4 100644 --- a/src/metatags/handler.js +++ b/src/metatags/handler.js @@ -19,16 +19,16 @@ import SeoChecks from './seo-checks.js'; async function fetchAndProcessPageObject(s3Client, bucketName, key, prefix, log) { const object = await getObjectFromKey(s3Client, bucketName, key, log); - if (!object?.Body?.tags || typeof object.Body.tags !== 'object') { + if (!object?.tags || typeof object.tags !== 'object') { log.error(`No Scraped tags found in S3 ${key} object, body ${JSON.stringify(object.Body)}`); return null; } const pageUrl = key.slice(prefix.length - 1).replace('scrape.json', ''); // Remove the prefix and .json suffix return { [pageUrl]: { - title: object.Body.tags.title, - description: object.Body.tags.description, - h1: object.Body.tags.h1 || [], + title: object.tags.title, + description: object.tags.description, + h1: object.tags.h1 || [], }, }; } diff --git a/src/utils/s3-utils.js b/src/utils/s3-utils.js index dfdcd0da..188d6de0 100644 --- a/src/utils/s3-utils.js +++ b/src/utils/s3-utils.js @@ -36,7 +36,9 @@ export async function getObjectFromKey(s3Client, bucketName, key, log) { Key: key, }); try { - return await s3Client.send(command); + const response = await s3Client.send(command); + const body = await response.Body.transformToString(); + return JSON.parse(body); } catch (err) { log.error(`Error while fetching S3 object from bucket ${bucketName} using key ${key}`, err); return null; diff --git a/test/audits/metatags.test.js b/test/audits/metatags.test.js index e2254f24..ea4be41b 100644 --- a/test/audits/metatags.test.js +++ b/test/audits/metatags.test.js @@ -245,35 +245,39 @@ describe('Meta Tags', () => { }))) .resolves({ Contents: [ - { Key: 'scrapes/site-id/blog/page1.json' }, - { Key: 'scrapes/site-id/blog/page2.json' }, + { Key: 'scrapes/site-id/blog/page1/scrape.json' }, + { Key: 'scrapes/site-id/blog/page2/scrape.json' }, ], }); s3ClientStub.send .withArgs(sinon.match.instanceOf(GetObjectCommand).and(sinon.match.has('input', { Bucket: 'test-bucket', - Key: 'scrapes/site-id/blog/page1.json', + Key: 'scrapes/site-id/blog/page1/scrape.json', }))).returns({ Body: { - tags: { - title: 'Test Page', - description: '', - }, + transformToString: () => JSON.stringify({ + tags: { + title: 'Test Page', + description: '', + }, + }), }, }); s3ClientStub.send .withArgs(sinon.match.instanceOf(GetObjectCommand).and(sinon.match.has('input', { Bucket: 'test-bucket', - Key: 'scrapes/site-id/blog/page2.json', + Key: 'scrapes/site-id/blog/page2/scrape.json', }))).returns({ Body: { - tags: { - title: 'Test Page', - h1: [ - 'This is a dummy H1 that is overly length from SEO perspective', - ], - }, + transformToString: () => JSON.stringify({ + tags: { + title: 'Test Page', + h1: [ + 'This is a dummy H1 that is overly length from SEO perspective', + ], + }, + }), }, }); const addAuditStub = sinon.stub().resolves(); @@ -362,41 +366,44 @@ describe('Meta Tags', () => { }))) .resolves({ Contents: [ - { Key: 'scrapes/site-id/blog/page1.json' }, - { Key: 'scrapes/site-id/blog/page2.json' }, + { Key: 'scrapes/site-id/blog/page1/scrape.json' }, + { Key: 'scrapes/site-id/blog/page2/scrape.json' }, ], }); s3ClientStub.send .withArgs(sinon.match.instanceOf(GetObjectCommand).and(sinon.match.has('input', { Bucket: 'test-bucket', - Key: 'scrapes/site-id/blog/page1.json', + Key: 'scrapes/site-id/blog/page1/scrape.json', }))).returns({ - Body: { - tags: { - title: 'This is an SEO optimal page1 valid title.', - description: 'This is a dummy description that is optimal from SEO perspective for page1. It has the correct length of characters, and is unique across all pages.', - h1: [ - 'This is an overly long H1 tag from SEO perspective due to its length exceeding 60 chars', - 'This is second h1 tag on same page', - ], - }, + transformToString: () => JSON.stringify({ + tags: { + title: 'This is an SEO optimal page1 valid title.', + description: 'This is a dummy description that is optimal from SEO perspective for page1. It has the correct length of characters, and is unique across all pages.', + h1: [ + 'This is an overly long H1 tag from SEO perspective due to its length exceeding 60 chars', + 'This is second h1 tag on same page', + ], + }, + }), }, }); s3ClientStub.send .withArgs(sinon.match.instanceOf(GetObjectCommand).and(sinon.match.has('input', { Bucket: 'test-bucket', - Key: 'scrapes/site-id/blog/page2.json', + Key: 'scrapes/site-id/blog/page2/scrape.json', }))).returns({ Body: { - tags: { - title: 'This is a SEO wise optimised page2 title.', - description: 'This is a dummy description that is optimal from SEO perspective for page2. It has the correct length of characters, and is unique across all pages.', - h1: [ - 'This is an overly long H1 tag from SEO perspective', - ], - }, + transformToString: () => JSON.stringify({ + tags: { + title: 'This is a SEO wise optimised page2 title.', + description: 'This is a dummy description that is optimal from SEO perspective for page2. It has the correct length of characters, and is unique across all pages.', + h1: [ + 'This is an overly long H1 tag from SEO perspective', + ], + }, + }), }, }); const addAuditStub = sinon.stub().resolves(); diff --git a/test/utils/s3-utils.test.js b/test/utils/s3-utils.test.js index 17d698ff..c8a20534 100644 --- a/test/utils/s3-utils.test.js +++ b/test/utils/s3-utils.test.js @@ -75,14 +75,18 @@ describe('S3 Utility Functions', () => { it('should return the S3 object when getObject succeeds', async () => { const bucketName = 'test-bucket'; const key = 'test-key'; - const expectedObject = { Body: 'file contents' }; + const expectedObject = { Body: { transformToString: () => '{"tags": {"title": "sample-title"}}' } }; const s3ClientMock = { send: () => expectedObject, }; const result = await getObjectFromKey(s3ClientMock, bucketName, key, logMock); - expect(result).to.deep.equal(expectedObject); + expect(result).to.deep.equal({ + tags: { + title: 'sample-title', + }, + }); }); it('should return null and log an error when getObject fails', async () => {