From 4b9c8a8ea55090b3dee0bbbb5414bbaab2377f26 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sat, 26 Oct 2024 22:00:55 +0100 Subject: [PATCH 1/2] Add "Gallery" field to return multiple images in 1 post (#242) # Description Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. - Added a `Gallery` option to the return parameters, which will be an array of image links for every image of that post - The JSON will always show it - The human readable will only show it if there is more than 1 image #161 ## Type of change Please delete options that are not relevant. - [x] New feature (non-breaking change which adds functionality) - [x] This change requires a documentation update # How Has This Been Tested? Please describe the tests that you ran to verify the changes. Provide instructions so we can reproduce. Please also list any relevant details to your test configuration. - Added new unit tests for these changes # Checklist - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [x] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that provide my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [x] Any dependent changes have been merged and published in downstream modules Reviewed-on: https://git.vylpes.xyz/RabbitLabs/random-bunny/pulls/242 Reviewed-by: VylpesTester Co-authored-by: Ethan Lane Co-committed-by: Ethan Lane --- docs/cli.md | 7 +++- readme.md | 1 + src/contracts/IRedditResult.ts | 3 +- src/helpers/imageHelper.ts | 10 +++-- src/helpers/outputHelper.ts | 7 ++++ src/index.ts | 6 ++- .../__snapshots__/outputHelper.test.ts.snap | 16 +++++++- tests/helpers/imageHelper.test.ts | 27 ++++++------- tests/helpers/outputHelper.test.ts | 39 +++++++++++++++++++ 9 files changed, 95 insertions(+), 21 deletions(-) diff --git a/docs/cli.md b/docs/cli.md index 9d25110..41abac8 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -26,6 +26,7 @@ $ random-bunny Archived = false Author = Rabbit_Owner Downvotes = 0 +Gallery = https://i.redd.it/sfz0srdrimjc1.png, https://i.redd.it/sfz0srdrimjc1.png Hidden = false Permalink = /r/Rabbits/comments/1av1rg9/cute_baby_bun/ Subreddit = Rabbits @@ -35,6 +36,8 @@ Upvotes = 211 Url = https://i.redd.it/sfz0srdrimjc1.png ``` +- The `Gallery` field is only shown when there is more than 1 image returned, which then the `Url` field is the first image of that list. + ## Help The command also includes a help option in case you are stuck. @@ -72,9 +75,11 @@ $ random-bunny --json $ randon-bunny -j -{"Archived":false,"Author":"Rabbit_Owner","Downs":0,"Hidden":false,"Permalink":"/r/Rabbits/comments/1av1rg9/cute_baby_bun/","Subreddit":"Rabbits","SubredditSubscribers":486085,"Title":"Cute baby bun","Ups":210,"Url":"https://i.redd.it/sfz0srdrimjc1.png"} +{"Archived":false,"Author":"Rabbit_Owner","Downs":0,"Hidden":false,"Permalink":"/r/Rabbits/comments/1av1rg9/cute_baby_bun/","Subreddit":"Rabbits","SubredditSubscribers":486085,"Title":"Cute baby bun","Ups":210,"Url":"https://i.redd.it/sfz0srdrimjc1.png","Gallery":["https://i.redd.it/sfz0srdrimjc1.png"]} ``` +- The `Url` field is the first image of the `Gallery` array + ## Sort You can also choose the sorting option which reddit will use to return the available posts to randomise from. diff --git a/readme.md b/readme.md index e7ba49c..570625a 100644 --- a/readme.md +++ b/readme.md @@ -39,6 +39,7 @@ The json string which gets returned consists of: - archived - author - downs +- gallery - hidden - permalink - subreddit diff --git a/src/contracts/IRedditResult.ts b/src/contracts/IRedditResult.ts index 13fef75..2c78e78 100644 --- a/src/contracts/IRedditResult.ts +++ b/src/contracts/IRedditResult.ts @@ -2,11 +2,12 @@ export default interface IRedditResult { Archived: boolean, Author: string, Downs: number, + Gallery: string[], Hidden: boolean, Permalink: string, Subreddit: string, SubredditSubscribers: number, Title: string, Ups: number, - Url: string + Url: string, } \ No newline at end of file diff --git a/src/helpers/imageHelper.ts b/src/helpers/imageHelper.ts index 3da0fc9..5c096ea 100644 --- a/src/helpers/imageHelper.ts +++ b/src/helpers/imageHelper.ts @@ -2,17 +2,19 @@ import fetch from "got-cjs"; import * as htmlparser from "htmlparser2"; export default class ImageHelper { - public static async FetchImageFromRedditGallery(url: string): Promise { + public static async FetchImageFromRedditGallery(url: string): Promise { const fetched = await fetch(url); if (!fetched || fetched.errored || fetched.statusCode != 200) { - return undefined; + return []; } const dom = htmlparser.parseDocument(fetched.body); - const img = htmlparser.DomUtils.findOne((x => x.tagName == "img" && x.attributes.find(y => y.value.includes("https://preview.redd.it")) != null), dom.children, true); + const img = htmlparser.DomUtils.findAll((x => x.tagName == "img" && x.attributes.find(y => y.value.includes("https://preview.redd.it")) != null), dom.children); - const imgSrc = img?.attributes.find(x => x.name == "src")?.value; + const imgSrc = img + .flatMap(x => x.attributes.find(x => x.name == "src")?.value) + .filter(x => x != undefined); return imgSrc; } diff --git a/src/helpers/outputHelper.ts b/src/helpers/outputHelper.ts index 808634d..0cee9d6 100644 --- a/src/helpers/outputHelper.ts +++ b/src/helpers/outputHelper.ts @@ -14,7 +14,13 @@ export default class OutputHelper { outputLines.push(`Archived = ${result.Archived}`); outputLines.push(`Author = ${result.Author}`); outputLines.push(`Downvotes = ${result.Downs}`); + + if (result.Gallery.length > 1) { + outputLines.push(`Gallery = ${result.Gallery.join(", ")}`); + } + outputLines.push(`Hidden = ${result.Hidden}`); + outputLines.push(`Permalink = ${result.Permalink}`); outputLines.push(`Subreddit = ${result.Subreddit}`); outputLines.push(`Subreddit Subscribers = ${result.SubredditSubscribers}`); @@ -22,6 +28,7 @@ export default class OutputHelper { outputLines.push(`Upvotes = ${result.Ups}`); outputLines.push(`Url = ${result.Url}`); + if (options.queryMetadata != null) { outputLines.push(`Query.Subreddit = ${response.Query.subreddit}`); outputLines.push(`Query.Sort By = ${response.Query.sortBy}`); diff --git a/src/index.ts b/src/index.ts index 056fe1f..b9ed5f9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -93,6 +93,7 @@ export default async function randomBunny(subreddit: string, sortBy: "new" | "ho const randomData = randomSelect.data; let url: string; + let gallery: string[]; if (randomData.url.includes("/gallery")) { const galleryImage = await ImageHelper.FetchImageFromRedditGallery(randomData.url); @@ -112,9 +113,11 @@ export default async function randomBunny(subreddit: string, sortBy: "new" | "ho } } - url = galleryImage; + url = galleryImage[0]; + gallery = galleryImage; } else { url = randomData.url; + gallery = [randomData.url]; } const redditResult: IRedditResult = { @@ -128,6 +131,7 @@ export default async function randomBunny(subreddit: string, sortBy: "new" | "ho Title: randomData['title'], Ups: randomData['ups'], Url: url, + Gallery: gallery, }; return { diff --git a/tests/helpers/__snapshots__/outputHelper.test.ts.snap b/tests/helpers/__snapshots__/outputHelper.test.ts.snap index 39e952e..73d61c6 100644 --- a/tests/helpers/__snapshots__/outputHelper.test.ts.snap +++ b/tests/helpers/__snapshots__/outputHelper.test.ts.snap @@ -13,7 +13,7 @@ Upvotes = 17 Url = https://preview.redd.it/d5yno653zf7d1.jpg?width=640&crop=smart&auto=webp&s=5064d1caec3c12ac2855eb57ff131d0b313d5e9d" `; -exports[`GenerateOutput GIVEN options.json is true, EXPECT output to be returned as JSON 1`] = `"{"Archived":false,"Author":"author","Downs":0,"Hidden":false,"Permalink":"/r/Rabbits/comments/1dj8pbt/this_is_my_ms_bear/","Subreddit":"Rabbits","SubredditSubscribers":654751,"Title":"This is my Ms Bear!","Ups":17,"Url":"https://preview.redd.it/d5yno653zf7d1.jpg?width=640&crop=smart&auto=webp&s=5064d1caec3c12ac2855eb57ff131d0b313d5e9d"}"`; +exports[`GenerateOutput GIVEN options.json is true, EXPECT output to be returned as JSON 1`] = `"{"Archived":false,"Author":"author","Downs":0,"Hidden":false,"Permalink":"/r/Rabbits/comments/1dj8pbt/this_is_my_ms_bear/","Subreddit":"Rabbits","SubredditSubscribers":654751,"Title":"This is my Ms Bear!","Ups":17,"Url":"https://preview.redd.it/d5yno653zf7d1.jpg?width=640&crop=smart&auto=webp&s=5064d1caec3c12ac2855eb57ff131d0b313d5e9d","Gallery":["https://preview.redd.it/d5yno653zf7d1.jpg?width=640&crop=smart&auto=webp&s=5064d1caec3c12ac2855eb57ff131d0b313d5e9d"]}"`; exports[`GenerateOutput GIVEN options.queryMetadata is supplied, EXPECT query metadata to be added 1`] = ` "Archived = false @@ -30,3 +30,17 @@ Query.Subreddit = rabbits Query.Sort By = hot Query.Limit = 100" `; + +exports[`GenerateOutput GIVEN the Gallery input has more than 1 item, EXPECT Gallery line to be added 1`] = ` +"Archived = false +Author = author +Downvotes = 0 +Gallery = https://preview.redd.it/d5yno653zf7d1.jpg?width=640&crop=smart&auto=webp&s=5064d1caec3c12ac2855eb57ff131d0b313d5e9d, https://preview.redd.it/d5yno653zf7d1.jpg?width=640&crop=smart&auto=webp&s=5064d1caec3c12ac2855eb57ff131d0b313d5e9d +Hidden = false +Permalink = /r/Rabbits/comments/1dj8pbt/this_is_my_ms_bear/ +Subreddit = Rabbits +Subreddit Subscribers = 654751 +Title = This is my Ms Bear! +Upvotes = 17 +Url = https://preview.redd.it/d5yno653zf7d1.jpg?width=640&crop=smart&auto=webp&s=5064d1caec3c12ac2855eb57ff131d0b313d5e9d" +`; diff --git a/tests/helpers/imageHelper.test.ts b/tests/helpers/imageHelper.test.ts index 3c6f44e..3eeb789 100644 --- a/tests/helpers/imageHelper.test.ts +++ b/tests/helpers/imageHelper.test.ts @@ -17,18 +17,19 @@ describe("FetchImageFromRedditGallery", () => { expect(fetchMock).toHaveBeenCalledTimes(1); expect(fetchMock).toHaveBeenCalledWith("https://redd.it/gallery/image"); - expect(result).toBe("https://preview.redd.it/image.png"); + expect(result.length).toBe(1); + expect(result[0]).toBe("https://preview.redd.it/image.png"); }); - test("GIVEN fetch is unable to return data, EXPECT undefined returned", async () => { + test("GIVEN fetch is unable to return data, EXPECT empty array returned", async () => { fetchMock.mockResolvedValue(null); const result = await ImageHelper.FetchImageFromRedditGallery("https://redd.it/gallery/image"); - expect(result).toBeUndefined(); + expect(result.length).toBe(0); }); - test("GIVEN fetch is an error, EXPECT undefined returned", async () => { + test("GIVEN fetch is an error, EXPECT empty array returned", async () => { fetchMock.mockResolvedValue({ body: "", errored: "Error", @@ -37,10 +38,10 @@ describe("FetchImageFromRedditGallery", () => { const result = await ImageHelper.FetchImageFromRedditGallery("https://redd.it/gallery/image"); - expect(result).toBeUndefined(); + expect(result.length).toBe(0); }); - test("GIVEN fetch is not status code of 200, EXPECT undefined returned", async () => { + test("GIVEN fetch is not status code of 200, EXPECT empty array returned", async () => { fetchMock.mockResolvedValue({ body: "", errored: undefined, @@ -49,10 +50,10 @@ describe("FetchImageFromRedditGallery", () => { const result = await ImageHelper.FetchImageFromRedditGallery("https://redd.it/gallery/image"); - expect(result).toBeUndefined(); + expect(result.length).toBe(0); }); - test("GIVEN image tag is not found, EXPECT undefined returned", async () => { + test("GIVEN image tag is not found, EXPECT empty array returned", async () => { fetchMock.mockResolvedValue({ body: "", errored: undefined, @@ -61,10 +62,10 @@ describe("FetchImageFromRedditGallery", () => { const result = await ImageHelper.FetchImageFromRedditGallery("https://redd.it/gallery/image"); - expect(result).toBeUndefined(); + expect(result.length).toBe(0); }); - test("GIVEN image source attribute is not found, EXPECT undefined returned", async () => { + test("GIVEN image source attribute is not found, EXPECT empty array returned", async () => { fetchMock.mockResolvedValue({ body: "", errored: undefined, @@ -73,10 +74,10 @@ describe("FetchImageFromRedditGallery", () => { const result = await ImageHelper.FetchImageFromRedditGallery("https://redd.it/gallery/image"); - expect(result).toBeUndefined(); + expect(result.length).toBe(0); }); - test("GIVEN image source attribute is not found that is a preview.redd.it url, EXPECT undefined returned", async () => { + test("GIVEN image source attribute is not found that is a preview.redd.it url, EXPECT empty array returned", async () => { fetchMock.mockResolvedValue({ body: "", errored: undefined, @@ -85,6 +86,6 @@ describe("FetchImageFromRedditGallery", () => { const result = await ImageHelper.FetchImageFromRedditGallery("https://redd.it/gallery/image"); - expect(result).toBeUndefined(); + expect(result.length).toBe(0); }); }); \ No newline at end of file diff --git a/tests/helpers/outputHelper.test.ts b/tests/helpers/outputHelper.test.ts index 5e90dc8..1581964 100644 --- a/tests/helpers/outputHelper.test.ts +++ b/tests/helpers/outputHelper.test.ts @@ -23,6 +23,7 @@ describe("GenerateOutput", () => { Title: "This is my Ms Bear!", Ups: 17, Url: "https://preview.redd.it/d5yno653zf7d1.jpg?width=640&crop=smart&auto=webp&s=5064d1caec3c12ac2855eb57ff131d0b313d5e9d", + Gallery: ["https://preview.redd.it/d5yno653zf7d1.jpg?width=640&crop=smart&auto=webp&s=5064d1caec3c12ac2855eb57ff131d0b313d5e9d"], }, } as IReturnResult; @@ -55,6 +56,7 @@ describe("GenerateOutput", () => { Title: "This is my Ms Bear!", Ups: 17, Url: "https://preview.redd.it/d5yno653zf7d1.jpg?width=640&crop=smart&auto=webp&s=5064d1caec3c12ac2855eb57ff131d0b313d5e9d", + Gallery: ["https://preview.redd.it/d5yno653zf7d1.jpg?width=640&crop=smart&auto=webp&s=5064d1caec3c12ac2855eb57ff131d0b313d5e9d"], }, } as IReturnResult; @@ -89,6 +91,7 @@ describe("GenerateOutput", () => { Title: "This is my Ms Bear!", Ups: 17, Url: "https://preview.redd.it/d5yno653zf7d1.jpg?width=640&crop=smart&auto=webp&s=5064d1caec3c12ac2855eb57ff131d0b313d5e9d", + Gallery: ["https://preview.redd.it/d5yno653zf7d1.jpg?width=640&crop=smart&auto=webp&s=5064d1caec3c12ac2855eb57ff131d0b313d5e9d"], }, } as IReturnResult; @@ -102,4 +105,40 @@ describe("GenerateOutput", () => { // Assert expect(result).toMatchSnapshot(); }); + + test("GIVEN the Gallery input has more than 1 item, EXPECT Gallery line to be added", () => { + // Arrange + const response = { + IsSuccess: true, + Query: { + subreddit: "rabbits", + sortBy: "hot", + limit: 100, + }, + Result: { + Archived: false, + Author: 'author', + Downs: 0, + Hidden: false, + Permalink: "/r/Rabbits/comments/1dj8pbt/this_is_my_ms_bear/", + Subreddit: "Rabbits", + SubredditSubscribers: 654751, + Title: "This is my Ms Bear!", + Ups: 17, + Url: "https://preview.redd.it/d5yno653zf7d1.jpg?width=640&crop=smart&auto=webp&s=5064d1caec3c12ac2855eb57ff131d0b313d5e9d", + Gallery: [ + "https://preview.redd.it/d5yno653zf7d1.jpg?width=640&crop=smart&auto=webp&s=5064d1caec3c12ac2855eb57ff131d0b313d5e9d", + "https://preview.redd.it/d5yno653zf7d1.jpg?width=640&crop=smart&auto=webp&s=5064d1caec3c12ac2855eb57ff131d0b313d5e9d" + ], + }, + } as IReturnResult; + + const options = {} as ICliOptions; + + // Act + const result = OutputHelper.GenerateOutput(response, options); + + // Assert + expect(result).toMatchSnapshot(); + }); }); \ No newline at end of file From 52df3e843eb518e3e7e29e4e591165eab59b2df1 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Wed, 27 Nov 2024 18:40:11 +0000 Subject: [PATCH 2/2] Fix tests --- .../__snapshots__/outputHelper.test.ts.snap | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/tests/helpers/__snapshots__/outputHelper.test.ts.snap b/tests/helpers/__snapshots__/outputHelper.test.ts.snap index 21d4e00..a044c01 100644 --- a/tests/helpers/__snapshots__/outputHelper.test.ts.snap +++ b/tests/helpers/__snapshots__/outputHelper.test.ts.snap @@ -10,7 +10,8 @@ Subreddit = Rabbits SubredditSubscribers = 654751 Title = This is my Ms Bear! Ups = 17 -Url = https://preview.redd.it/d5yno653zf7d1.jpg?width=640&crop=smart&auto=webp&s=5064d1caec3c12ac2855eb57ff131d0b313d5e9d" +Url = https://preview.redd.it/d5yno653zf7d1.jpg?width=640&crop=smart&auto=webp&s=5064d1caec3c12ac2855eb57ff131d0b313d5e9d +Gallery = https://preview.redd.it/d5yno653zf7d1.jpg?width=640&crop=smart&auto=webp&s=5064d1caec3c12ac2855eb57ff131d0b313d5e9d" `; exports[`GenerateOutput GIVEN options.json is true, EXPECT output to be returned as JSON 1`] = `"{"Archived":false,"Author":"author","Downs":0,"Hidden":false,"Permalink":"/r/Rabbits/comments/1dj8pbt/this_is_my_ms_bear/","Subreddit":"Rabbits","SubredditSubscribers":654751,"Title":"This is my Ms Bear!","Ups":17,"Url":"https://preview.redd.it/d5yno653zf7d1.jpg?width=640&crop=smart&auto=webp&s=5064d1caec3c12ac2855eb57ff131d0b313d5e9d","Gallery":["https://preview.redd.it/d5yno653zf7d1.jpg?width=640&crop=smart&auto=webp&s=5064d1caec3c12ac2855eb57ff131d0b313d5e9d"]}"`; @@ -28,21 +29,8 @@ SubredditSubscribers = 654751 Title = This is my Ms Bear! Ups = 17 Url = https://preview.redd.it/d5yno653zf7d1.jpg?width=640&crop=smart&auto=webp&s=5064d1caec3c12ac2855eb57ff131d0b313d5e9d +Gallery = https://preview.redd.it/d5yno653zf7d1.jpg?width=640&crop=smart&auto=webp&s=5064d1caec3c12ac2855eb57ff131d0b313d5e9d subreddit = rabbits sortBy = hot limit = 100" `; - -exports[`GenerateOutput GIVEN the Gallery input has more than 1 item, EXPECT Gallery line to be added 1`] = ` -"Archived = false -Author = author -Downvotes = 0 -Gallery = https://preview.redd.it/d5yno653zf7d1.jpg?width=640&crop=smart&auto=webp&s=5064d1caec3c12ac2855eb57ff131d0b313d5e9d, https://preview.redd.it/d5yno653zf7d1.jpg?width=640&crop=smart&auto=webp&s=5064d1caec3c12ac2855eb57ff131d0b313d5e9d -Hidden = false -Permalink = /r/Rabbits/comments/1dj8pbt/this_is_my_ms_bear/ -Subreddit = Rabbits -Subreddit Subscribers = 654751 -Title = This is my Ms Bear! -Upvotes = 17 -Url = https://preview.redd.it/d5yno653zf7d1.jpg?width=640&crop=smart&auto=webp&s=5064d1caec3c12ac2855eb57ff131d0b313d5e9d" -`;