From 3f7adba825b79d5093d64116f7e5111f8ec798e3 Mon Sep 17 00:00:00 2001 From: Alistair Brown Date: Sun, 18 Nov 2018 09:09:03 +0000 Subject: [PATCH 1/2] Add tests for Meetup.com producer lambda --- .../tests/meetupcom/handlers/producer.test.js | 308 +++++++++++++++- .../test-data/group-events-payload-empty.json | 1 + .../test-data/group-events-payload-error.json | 8 + .../group-events-payload-populated.json | 42 +++ .../test-data/groups-payload-empty.json | 1 + .../test-data/groups-payload-error.json | 8 + .../test-data/groups-payload-populated.json | 328 ++++++++++++++++++ lambdas/tests/meetupcom/test-utils.js | 25 ++ 8 files changed, 720 insertions(+), 1 deletion(-) create mode 100644 lambdas/tests/meetupcom/handlers/test-data/group-events-payload-empty.json create mode 100644 lambdas/tests/meetupcom/handlers/test-data/group-events-payload-error.json create mode 100644 lambdas/tests/meetupcom/handlers/test-data/group-events-payload-populated.json create mode 100644 lambdas/tests/meetupcom/handlers/test-data/groups-payload-empty.json create mode 100644 lambdas/tests/meetupcom/handlers/test-data/groups-payload-error.json create mode 100644 lambdas/tests/meetupcom/handlers/test-data/groups-payload-populated.json create mode 100644 lambdas/tests/meetupcom/test-utils.js diff --git a/lambdas/tests/meetupcom/handlers/producer.test.js b/lambdas/tests/meetupcom/handlers/producer.test.js index 678cca4f..a9c36cfb 100644 --- a/lambdas/tests/meetupcom/handlers/producer.test.js +++ b/lambdas/tests/meetupcom/handlers/producer.test.js @@ -1,8 +1,314 @@ -const producer = require("../../../meetupcom/handlers/producer"); +process.env.MEETUPCOM_API_TOKEN = "meetupcom-token-abc123"; + +const { prefix, resolved } = require("../test-utils"); +const { getFromWeb } = require(`${prefix}/node_modules/aws-lambda-data-utils`); +const { uploadTo } = require(`${prefix}/node_modules/@muxer/lambda-utils`); +const producer = require(`${prefix}/handlers/producer`); +const identity = value => value; + +const requireData = (filename, transform = identity) => + JSON.stringify(transform(require(`./test-data/${filename}.json`))); // eslint-disable-line global-require + +const erroredGroupsData = requireData("groups-payload-error"); +const populatedGroupsData = requireData("groups-payload-populated"); +const emptyGroupsData = requireData("groups-payload-empty"); +const erroredGroupEventssData = requireData("group-events-payload-error"); +const emptyGroupEventsData = requireData("group-events-payload-empty"); + +const groupsUrl = + "https://api.meetup.com/find/groups?photo-host=public&country=GB&lon=-6.762739&lat=54.6425126&radius=60&fields=approved,best_topics,description_images,past_event_count_inclusive,group_past_event_count,plain_text_description,plain_text_no_images_description,topics&fallback_suggestions=false&category=34&page=200&sign=true&key=meetupcom-token-abc123"; + +const matchGroupEventsUrl = url => + url.match( + /https:\/\/api\.meetup\.com\/(.+)\/events\?photo-host=public&status=cancelled,past,proposed,suggested,upcoming&page=200/ + ); + +const getGroupEventsUrl = groupName => + `https://api.meetup.com/${groupName}/events?photo-host=public&status=cancelled,past,proposed,suggested,upcoming&page=200`; + +const groupEventsTransform = groupName => events => + events.map(event => + Object.assign({}, event, { + description: `${event.description} [${groupName}]` + }) + ); + +const requireEventsFor = group => + requireData("group-events-payload-populated", groupEventsTransform(group)); + +const groupedErroredResponse = resolved(erroredGroupsData); +const groupsPopulatedResponse = resolved(populatedGroupsData); +const groupsEmptyResponse = resolved(emptyGroupsData); +const groupEventsErroredResponse = resolved(erroredGroupEventssData); +const groupEventsPopulatedResponse = group => + Promise.resolve(requireEventsFor(group)); +const groupEventsEmptyResponse = resolved(emptyGroupEventsData); + +const event = null; +const context = null; describe("Meetup.com Producer", function() { + beforeEach(function() { + jest.clearAllMocks(); + uploadTo.mockImplementation(resolved({ key: "path/to/new/file.json" })); + }); + it("is a lambda handler", function() { expect(typeof producer).toBe("object"); expect(typeof producer.produce).toBe("function"); }); + + describe("when an error is returned from groups request", function() { + beforeEach(function() { + getFromWeb.mockImplementation(url => { + if (url === groupsUrl) return groupedErroredResponse(); + throw new Error("Mock setup mismatch"); + }); + }); + + it("makes a request to the API for groups data", function(done) { + producer.produce(event, context, function() { + expect(getFromWeb).toHaveBeenCalledTimes(1); + expect(getFromWeb).toHaveBeenCalledWith(groupsUrl); + done(); + }); + }); + + it("does not upload data", function(done) { + producer.produce(event, context, function() { + expect(uploadTo).not.toHaveBeenCalled(); + done(); + }); + }); + + it("return an error and no file paths", function(done) { + producer.produce(event, context, function(err, response) { + expect(err).toEqual([ + { + code: "auth_fail", + message: "Invalid signature" + } + ]); + expect(response).toBe(null); + done(); + }); + }); + }); + + describe("when no groups are returned", function() { + beforeEach(function() { + getFromWeb.mockImplementation(url => { + if (url === groupsUrl) return groupsEmptyResponse(); + throw new Error("Mock setup mismatch"); + }); + }); + + it("makes a request to the API for groups data", function(done) { + producer.produce(event, context, function(err) { + expect(getFromWeb).toHaveBeenCalledTimes(1); + expect(getFromWeb).toHaveBeenCalledWith(groupsUrl); + done(err); + }); + }); + + it("uploads data", function(done) { + producer.produce(event, context, function(err) { + expect(uploadTo).toHaveBeenCalledTimes(1); + expect(uploadTo).toHaveBeenCalledWith( + "muxer-produced-events-meetupcom", + expect.any(Function), + [] + ); + done(err); + }); + }); + }); + + describe("when the groups are returned", function() { + beforeEach(function() { + getFromWeb.mockImplementation(url => { + if (url === groupsUrl) return groupsPopulatedResponse(); + if (matchGroupEventsUrl(url)) return groupEventsEmptyResponse(); + throw new Error("Mock setup mismatch"); + }); + }); + + it("makes a request to the API for groups data", function(done) { + producer.produce(event, context, function(err) { + expect(getFromWeb).toHaveBeenCalledWith(groupsUrl); + done(err); + }); + }); + + it("requests data for each group", function(done) { + producer.produce(event, context, function(err) { + expect(getFromWeb).toHaveBeenCalledTimes(5); // + 1 for the groups URL + expect(getFromWeb).toHaveBeenCalledWith( + getGroupEventsUrl("AWS-Usergroup-Belfast") + ); + expect(getFromWeb).toHaveBeenCalledWith( + getGroupEventsUrl("Women-Who-Code-Belfast") + ); + expect(getFromWeb).toHaveBeenCalledWith( + getGroupEventsUrl("Belfast-Selenium-Meetup-Group") + ); + expect(getFromWeb).toHaveBeenCalledWith( + getGroupEventsUrl("CodeCoop-NI") + ); + done(err); + }); + }); + + describe("and there is an error getting events", function() { + beforeEach(function() { + getFromWeb.mockImplementation(url => { + if (url === groupsUrl) return groupsPopulatedResponse(); + if (matchGroupEventsUrl(url)) { + if (url.includes("AWS-Usergroup-Belfast")) { + return groupEventsErroredResponse(); + } + return groupEventsPopulatedResponse("foo"); + } + throw new Error("Mock setup mismatch"); + }); + }); + + it("does not upload data", function(done) { + producer.produce(event, context, function() { + expect(uploadTo).not.toHaveBeenCalled(); + done(); + }); + }); + + it("return the errors and no file paths", function(done) { + producer.produce(event, context, function(err, response) { + expect(err).toEqual([ + [{ code: "auth_fail", message: "Invalid signature" }] + ]); + expect(response).toBe(null); + done(); + }); + }); + }); + + describe("and there are no events for those groups", function() { + beforeEach(function() { + getFromWeb.mockImplementation(url => { + if (url === groupsUrl) return groupsPopulatedResponse(); + const eventsUrlMatch = matchGroupEventsUrl(url); + if (eventsUrlMatch && eventsUrlMatch[1]) { + return groupEventsEmptyResponse(); + } + throw new Error("Mock setup mismatch"); + }); + }); + + it("uploads data", function(done) { + producer.produce(event, context, function(err) { + expect(uploadTo).toHaveBeenCalledTimes(5); + expect(uploadTo).toHaveBeenCalledWith( + "muxer-produced-events-meetupcom", + expect.any(Function), + JSON.parse(populatedGroupsData) + ); + expect(uploadTo).toHaveBeenCalledWith( + "muxer-produced-events-meetupcom", + expect.any(Function), + [] + ); + expect(uploadTo).toHaveBeenCalledWith( + "muxer-produced-events-meetupcom", + expect.any(Function), + [] + ); + expect(uploadTo).toHaveBeenCalledWith( + "muxer-produced-events-meetupcom", + expect.any(Function), + [] + ); + expect(uploadTo).toHaveBeenCalledWith( + "muxer-produced-events-meetupcom", + expect.any(Function), + [] + ); + done(err); + }); + }); + + it("returns file paths", function(done) { + producer.produce(event, context, function(err, response) { + expect(response).toEqual({ + message: [ + "path/to/new/file.json", + "path/to/new/file.json", + "path/to/new/file.json", + "path/to/new/file.json", + "path/to/new/file.json" + ] + }); + done(err); + }); + }); + }); + + describe("and there are events for those groups", function() { + beforeEach(function() { + getFromWeb.mockImplementation(url => { + if (url === groupsUrl) return groupsPopulatedResponse(); + const eventsUrlMatch = matchGroupEventsUrl(url); + if (eventsUrlMatch && eventsUrlMatch[1]) { + return groupEventsPopulatedResponse(eventsUrlMatch[1]); + } + throw new Error("Mock setup mismatch"); + }); + }); + + it("uploads data", function(done) { + producer.produce(event, context, function(err) { + expect(uploadTo).toHaveBeenCalledTimes(5); + expect(uploadTo).toHaveBeenCalledWith( + "muxer-produced-events-meetupcom", + expect.any(Function), + JSON.parse(populatedGroupsData) + ); + expect(uploadTo).toHaveBeenCalledWith( + "muxer-produced-events-meetupcom", + expect.any(Function), + JSON.parse(requireEventsFor("AWS-Usergroup-Belfast")) + ); + expect(uploadTo).toHaveBeenCalledWith( + "muxer-produced-events-meetupcom", + expect.any(Function), + JSON.parse(requireEventsFor("Women-Who-Code-Belfast")) + ); + expect(uploadTo).toHaveBeenCalledWith( + "muxer-produced-events-meetupcom", + expect.any(Function), + JSON.parse(requireEventsFor("Belfast-Selenium-Meetup-Group")) + ); + expect(uploadTo).toHaveBeenCalledWith( + "muxer-produced-events-meetupcom", + expect.any(Function), + JSON.parse(requireEventsFor("CodeCoop-NI")) + ); + done(err); + }); + }); + + it("returns file paths", function(done) { + producer.produce(event, context, function(err, response) { + expect(response).toEqual({ + message: [ + "path/to/new/file.json", + "path/to/new/file.json", + "path/to/new/file.json", + "path/to/new/file.json", + "path/to/new/file.json" + ] + }); + done(err); + }); + }); + }); + }); }); diff --git a/lambdas/tests/meetupcom/handlers/test-data/group-events-payload-empty.json b/lambdas/tests/meetupcom/handlers/test-data/group-events-payload-empty.json new file mode 100644 index 00000000..fe51488c --- /dev/null +++ b/lambdas/tests/meetupcom/handlers/test-data/group-events-payload-empty.json @@ -0,0 +1 @@ +[] diff --git a/lambdas/tests/meetupcom/handlers/test-data/group-events-payload-error.json b/lambdas/tests/meetupcom/handlers/test-data/group-events-payload-error.json new file mode 100644 index 00000000..9620829b --- /dev/null +++ b/lambdas/tests/meetupcom/handlers/test-data/group-events-payload-error.json @@ -0,0 +1,8 @@ +{ + "errors": [ + { + "code": "auth_fail", + "message": "Invalid signature" + } + ] +} diff --git a/lambdas/tests/meetupcom/handlers/test-data/group-events-payload-populated.json b/lambdas/tests/meetupcom/handlers/test-data/group-events-payload-populated.json new file mode 100644 index 00000000..b3077d1a --- /dev/null +++ b/lambdas/tests/meetupcom/handlers/test-data/group-events-payload-populated.json @@ -0,0 +1,42 @@ +[ + { + "created": 1492609621000, + "duration": 8100000, + "id": "239325936", + "name": "Test name 1", + "rsvp_limit": 140, + "status": "past", + "time": 1495729800000, + "local_date": "2017-05-25", + "local_time": "17:30", + "updated": 1496153858000, + "utc_offset": 3600000, + "waitlist_count": 0, + "yes_rsvp_count": 91, + "venue": null, + "group": null, + "link": "", + "description": "Test description 1", + "visibility": "public" + }, + { + "created": 1532946640000, + "duration": 8100000, + "id": "253297474", + "name": "Test name 2", + "rsvp_limit": 115, + "status": "upcoming", + "time": 1536683400000, + "local_date": "2018-09-11", + "local_time": "17:30", + "updated": 1535105404000, + "utc_offset": 3600000, + "waitlist_count": 5, + "yes_rsvp_count": 115, + "venue": null, + "group": null, + "link": "", + "description": "Test description 2", + "visibility": "public" + } +] diff --git a/lambdas/tests/meetupcom/handlers/test-data/groups-payload-empty.json b/lambdas/tests/meetupcom/handlers/test-data/groups-payload-empty.json new file mode 100644 index 00000000..fe51488c --- /dev/null +++ b/lambdas/tests/meetupcom/handlers/test-data/groups-payload-empty.json @@ -0,0 +1 @@ +[] diff --git a/lambdas/tests/meetupcom/handlers/test-data/groups-payload-error.json b/lambdas/tests/meetupcom/handlers/test-data/groups-payload-error.json new file mode 100644 index 00000000..9620829b --- /dev/null +++ b/lambdas/tests/meetupcom/handlers/test-data/groups-payload-error.json @@ -0,0 +1,8 @@ +{ + "errors": [ + { + "code": "auth_fail", + "message": "Invalid signature" + } + ] +} diff --git a/lambdas/tests/meetupcom/handlers/test-data/groups-payload-populated.json b/lambdas/tests/meetupcom/handlers/test-data/groups-payload-populated.json new file mode 100644 index 00000000..7a8f0282 --- /dev/null +++ b/lambdas/tests/meetupcom/handlers/test-data/groups-payload-populated.json @@ -0,0 +1,328 @@ +[ + { + "score": 1, + "id": 18944424, + "name": "AWS User Group Belfast", + "status": "active", + "link": "https://www.meetup.com/AWS-Usergroup-Belfast/", + "urlname": "AWS-Usergroup-Belfast", + "description": "

This is a group for all-things AWS in Belfast. We're a community of users, developers and business professionals meeting to share ideas & learn from each other and from leading figures in the AWS technology space. Our aim is to become an important resource for technical & business professionals who want to stay up to speed with developments in AWS Cloud and related technologies. Look out for more events and announcements in 2015! For sponsorship & speaking requests please contact awsbelfast@gmail.com

", + "created": 1442591614000, + "city": "Belfast", + "untranslated_city": "Belfast", + "country": "GB", + "localized_country_name": "United Kingdom", + "localized_location": "Belfast, United Kingdom", + "state": "R3", + "join_mode": "open", + "visibility": "public", + "lat": 54.6, + "lon": -5.93, + "members": 489, + "organizer": { + "id": 139596322, + "name": "Ronan OC", + "bio": "", + "photo": { + "id": 187849042, + "highres_link": "https://secure.meetupstatic.com/photos/member/b/f/9/2/highres_187849042.jpeg", + "photo_link": "https://secure.meetupstatic.com/photos/member/b/f/9/2/member_187849042.jpeg", + "thumb_link": "https://secure.meetupstatic.com/photos/member/b/f/9/2/thumb_187849042.jpeg", + "type": "member", + "base_url": "https://secure.meetupstatic.com" + } + }, + "who": "Members", + "key_photo": { + "id": 451627771, + "highres_link": "https://secure.meetupstatic.com/photos/event/1/e/5/b/highres_451627771.jpeg", + "photo_link": "https://secure.meetupstatic.com/photos/event/1/e/5/b/600_451627771.jpeg", + "thumb_link": "https://secure.meetupstatic.com/photos/event/1/e/5/b/thumb_451627771.jpeg", + "type": "event", + "base_url": "https://secure.meetupstatic.com" + }, + "timezone": "Europe/Belfast", + "next_event": { + "id": "253784234", + "name": "AWS | Belfast Meetup - THU, 6th SEPTEMBER @ 6pm!", + "yes_rsvp_count": 128, + "time": 1536253200000, + "utc_offset": 3600000 + }, + "category": { + "id": 34, + "name": "Tech", + "shortname": "tech", + "sort_name": "Tech" + }, + "meta_category": { + "id": 292, + "shortname": "tech", + "name": "Tech", + "sort_name": "Tech", + "photo": { + "id": 450131949, + "highres_link": "https://secure.meetupstatic.com/photos/event/2/e/a/d/highres_450131949.jpeg", + "photo_link": "https://secure.meetupstatic.com/photos/event/2/e/a/d/600_450131949.jpeg", + "thumb_link": "https://secure.meetupstatic.com/photos/event/2/e/a/d/thumb_450131949.jpeg", + "type": "event", + "base_url": "https://secure.meetupstatic.com" + }, + "category_ids": [ + 34 + ] + }, + "pro_network": { + "name": "AWS Communities", + "urlname": "aws", + "number_of_groups": 6, + "network_url": "https://www.meetup.com/pro/aws/" + } + }, + { + "score": 1, + "id": 11013632, + "name": "Women Who Code Belfast", + "status": "active", + "link": "https://www.meetup.com/Women-Who-Code-Belfast/", + "urlname": "Women-Who-Code-Belfast", + "description": "

Join us by attending a WWCode event or signing up at www.womenwhocode.com.

\n

Women Who Code is the largest and most active community of engineers dedicated to inspiring women to excel in technology careers. We envision a world where women are representative as technical executives, founders, VCs, board members, and software engineers. Our programs are designed to get you there

\n

Who should join?

\n

Our community is for professional women in technology careers, including software engineers, developers, UX/UI designers, data scientists and more. Current and aspiring coders are welcome. Bring your laptop and a friend!

\n

What to expect?

\n

Our events offer free hands on technical events, study groups, panel discussions, lightning talks, and keynotes featuring influential tech industry experts, innovators, and investors. We help you build the skills you need to raise your professional profile and achieve greater career success.

\n

Support us:

\n

WWCode relies on donations to support this catalytic movement. Funding directly impacts our ability to deliver programs and expand to more cities, ensuring that even more women have the opportunity to excel in tech careers. womenwhocode.com/donate

\n

Share a Job with our Community:

\n

Post your jobs on the Women Who Code Job Board and hire from our exclusive community of technical professionals. Get started at womenwhocode.com/companies.

\n

Code of Conduct:

\n

WWCode is an inclusive community, dedicated to providing an empowering experience for everyone who participates in or supports our community, regardless of gender, gender identity and expression, sexual orientation, ability, physical appearance, body size, race, ethnicity, age, religion, socioeconomic status, caste, creed, political affiliation, or preferred programming language(s). Our events are intended to inspire women to excel in technology careers, and anyone who is there for this purpose is welcome. We do not tolerate harassment of members in any form.

\n

Our Code of Conduct applies to all WWCode events and online communities. Read the full version and access our incident report form at www.womenwhocode.com/codeofconduct

\n

Terms of Service:

\n

Everyone who participates in our community agrees to abide by our Terms of Service. Read it at www.womenwhocode.com/tos

\n

Privacy Policy:

\n

Everyone who participates in our community agrees to abide by our Privacy Policy.
Read it at www.womenwhocode.com/privacy-policy

\nConnect with #WWCode Belfast:\n
\n

womenwhocode.com/belfast
facebook.com/facebook.com/groups/WWCodeBelfast/ 
twitter.com/wwcbelfast

\n

#WWCode Global Network

\n

facebook.com/womenwhocode 
twitter.com/womenwhocode 
bit.ly/WWCodeReview  
github.com/orgs/WomenWhoCode 
womenwhocode.com

\n
\n

", + "created": 1383866929000, + "city": "Belfast", + "untranslated_city": "Belfast", + "country": "GB", + "localized_country_name": "United Kingdom", + "localized_location": "Belfast, United Kingdom", + "state": "R3", + "join_mode": "open", + "visibility": "public", + "lat": 54.59, + "lon": -5.94, + "members": 922, + "organizer": { + "id": 129339582, + "name": "Women Who Code", + "bio": "", + "photo": { + "id": 172594242, + "highres_link": "https://secure.meetupstatic.com/photos/member/8/5/c/2/highres_172594242.jpeg", + "photo_link": "https://secure.meetupstatic.com/photos/member/8/5/c/2/member_172594242.jpeg", + "thumb_link": "https://secure.meetupstatic.com/photos/member/8/5/c/2/thumb_172594242.jpeg", + "type": "member", + "base_url": "https://secure.meetupstatic.com" + } + }, + "who": "Coders", + "group_photo": { + "id": 431686980, + "highres_link": "https://secure.meetupstatic.com/photos/event/b/7/8/4/highres_431686980.jpeg", + "photo_link": "https://secure.meetupstatic.com/photos/event/b/7/8/4/600_431686980.jpeg", + "thumb_link": "https://secure.meetupstatic.com/photos/event/b/7/8/4/thumb_431686980.jpeg", + "type": "event", + "base_url": "https://secure.meetupstatic.com" + }, + "key_photo": { + "id": 443933459, + "highres_link": "https://secure.meetupstatic.com/photos/event/d/0/d/3/highres_443933459.jpeg", + "photo_link": "https://secure.meetupstatic.com/photos/event/d/0/d/3/600_443933459.jpeg", + "thumb_link": "https://secure.meetupstatic.com/photos/event/d/0/d/3/thumb_443933459.jpeg", + "type": "event", + "base_url": "https://secure.meetupstatic.com" + }, + "timezone": "Europe/Belfast", + "next_event": { + "id": "253524217", + "name": "Tech Talk Thursday at Deloitte", + "yes_rsvp_count": 45, + "time": 1536253200000, + "utc_offset": 3600000 + }, + "category": { + "id": 34, + "name": "Tech", + "shortname": "tech", + "sort_name": "Tech" + }, + "meta_category": { + "id": 292, + "shortname": "tech", + "name": "Tech", + "sort_name": "Tech", + "photo": { + "id": 450131949, + "highres_link": "https://secure.meetupstatic.com/photos/event/2/e/a/d/highres_450131949.jpeg", + "photo_link": "https://secure.meetupstatic.com/photos/event/2/e/a/d/600_450131949.jpeg", + "thumb_link": "https://secure.meetupstatic.com/photos/event/2/e/a/d/thumb_450131949.jpeg", + "type": "event", + "base_url": "https://secure.meetupstatic.com" + }, + "category_ids": [ + 34 + ] + } + }, + { + "score": 1, + "id": 8819612, + "name": "Belfast Selenium Meetup Group", + "status": "active", + "link": "https://www.meetup.com/Belfast-Selenium-Meetup-Group/", + "urlname": "Belfast-Selenium-Meetup-Group", + "description": "

The Belfast Selenium Meetup Group is a place where new and existing Selenium users can come together to share ideas, learn, network, or just have a good time. Our focus is on Selenium and any related topics that extend through related areas of use, such as Agile, Test-Driven Development, Continuous Integration, Continuous Deployment, building maintainable automation and much more.

", + "created": 1370575338000, + "city": "Belfast", + "untranslated_city": "Belfast", + "country": "GB", + "localized_country_name": "United Kingdom", + "localized_location": "Belfast, United Kingdom", + "state": "R3", + "join_mode": "open", + "visibility": "public", + "lat": 54.59, + "lon": -5.93, + "members": 719, + "organizer": { + "id": 86400732, + "name": "Hugh McCamphill", + "bio": "", + "photo": { + "id": 278744091, + "highres_link": "https://secure.meetupstatic.com/photos/member/a/c/3/b/highres_278744091.jpeg", + "photo_link": "https://secure.meetupstatic.com/photos/member/a/c/3/b/member_278744091.jpeg", + "thumb_link": "https://secure.meetupstatic.com/photos/member/a/c/3/b/thumb_278744091.jpeg", + "type": "member", + "base_url": "https://secure.meetupstatic.com" + } + }, + "who": "Members", + "group_photo": { + "id": 306247222, + "highres_link": "https://secure.meetupstatic.com/photos/event/1/c/3/6/highres_306247222.jpeg", + "photo_link": "https://secure.meetupstatic.com/photos/event/1/c/3/6/600_306247222.jpeg", + "thumb_link": "https://secure.meetupstatic.com/photos/event/1/c/3/6/thumb_306247222.jpeg", + "type": "event", + "base_url": "https://secure.meetupstatic.com" + }, + "key_photo": { + "id": 306247222, + "highres_link": "https://secure.meetupstatic.com/photos/event/1/c/3/6/highres_306247222.jpeg", + "photo_link": "https://secure.meetupstatic.com/photos/event/1/c/3/6/600_306247222.jpeg", + "thumb_link": "https://secure.meetupstatic.com/photos/event/1/c/3/6/thumb_306247222.jpeg", + "type": "event", + "base_url": "https://secure.meetupstatic.com" + }, + "timezone": "Europe/Belfast", + "next_event": { + "id": "254184527", + "name": "Appium and React Native with special guest Wim Selles", + "yes_rsvp_count": 17, + "time": 1537376400000, + "utc_offset": 3600000 + }, + "category": { + "id": 34, + "name": "Tech", + "shortname": "tech", + "sort_name": "Tech" + }, + "meta_category": { + "id": 292, + "shortname": "tech", + "name": "Tech", + "sort_name": "Tech", + "photo": { + "id": 450131949, + "highres_link": "https://secure.meetupstatic.com/photos/event/2/e/a/d/highres_450131949.jpeg", + "photo_link": "https://secure.meetupstatic.com/photos/event/2/e/a/d/600_450131949.jpeg", + "thumb_link": "https://secure.meetupstatic.com/photos/event/2/e/a/d/thumb_450131949.jpeg", + "type": "event", + "base_url": "https://secure.meetupstatic.com" + }, + "category_ids": [ + 34 + ] + } + }, + { + "score": 1, + "id": 20229401, + "name": "Code Co-Op", + "status": "active", + "link": "https://www.meetup.com/CodeCoop-NI/", + "urlname": "CodeCoop-NI", + "description": "

A bi-weekly club for adults to come together and work on fun projects to upskill themselves at Farset Labs. Whether you're a beginner who wants an insight into the world of programming, or an experienced programmer who wants to work on a side project in a social setting - all are welcome.

\n

Bring a laptop and yourself and come get involved! We suggest a £3 donation to Farset Labs for letting us use the venue to get together, tinker and share knowledge.

\n

Join our conversations on Slack for real-time chat:
Go to http://nitech.herokuapp.com/ to join NI Tech & Design, and then find #codeco-op

", + "created": 1469603863000, + "city": "Belfast", + "untranslated_city": "Belfast", + "country": "GB", + "localized_country_name": "United Kingdom", + "localized_location": "Belfast, United Kingdom", + "state": "R3", + "join_mode": "open", + "visibility": "public", + "lat": 54.6, + "lon": -5.93, + "members": 887, + "organizer": { + "id": 203325989, + "name": "Farset Labs", + "bio": "", + "photo": { + "id": 258690583, + "highres_link": "https://secure.meetupstatic.com/photos/member/7/7/7/7/highres_258690583.jpeg", + "photo_link": "https://secure.meetupstatic.com/photos/member/7/7/7/7/member_258690583.jpeg", + "thumb_link": "https://secure.meetupstatic.com/photos/member/7/7/7/7/thumb_258690583.jpeg", + "type": "member", + "base_url": "https://secure.meetupstatic.com" + } + }, + "who": "Members", + "group_photo": { + "id": 452635788, + "highres_link": "https://secure.meetupstatic.com/photos/event/d/9/e/c/highres_452635788.jpeg", + "photo_link": "https://secure.meetupstatic.com/photos/event/d/9/e/c/600_452635788.jpeg", + "thumb_link": "https://secure.meetupstatic.com/photos/event/d/9/e/c/thumb_452635788.jpeg", + "type": "event", + "base_url": "https://secure.meetupstatic.com" + }, + "key_photo": { + "id": 452635757, + "highres_link": "https://secure.meetupstatic.com/photos/event/d/9/c/d/highres_452635757.jpeg", + "photo_link": "https://secure.meetupstatic.com/photos/event/d/9/c/d/600_452635757.jpeg", + "thumb_link": "https://secure.meetupstatic.com/photos/event/d/9/c/d/thumb_452635757.jpeg", + "type": "event", + "base_url": "https://secure.meetupstatic.com" + }, + "timezone": "Europe/Belfast", + "next_event": { + "id": "lhmvfpyxmbjb", + "name": "Code Co-Op Challenge", + "yes_rsvp_count": 13, + "time": 1536256800000, + "utc_offset": 3600000 + }, + "category": { + "id": 34, + "name": "Tech", + "shortname": "tech", + "sort_name": "Tech" + }, + "meta_category": { + "id": 292, + "shortname": "tech", + "name": "Tech", + "sort_name": "Tech", + "photo": { + "id": 450131949, + "highres_link": "https://secure.meetupstatic.com/photos/event/2/e/a/d/highres_450131949.jpeg", + "photo_link": "https://secure.meetupstatic.com/photos/event/2/e/a/d/600_450131949.jpeg", + "thumb_link": "https://secure.meetupstatic.com/photos/event/2/e/a/d/thumb_450131949.jpeg", + "type": "event", + "base_url": "https://secure.meetupstatic.com" + }, + "category_ids": [ + 34 + ] + } + } +] diff --git a/lambdas/tests/meetupcom/test-utils.js b/lambdas/tests/meetupcom/test-utils.js new file mode 100644 index 00000000..01805e6e --- /dev/null +++ b/lambdas/tests/meetupcom/test-utils.js @@ -0,0 +1,25 @@ +jest.mock("../../meetupcom/node_modules/aws-lambda-data-utils", () => ({ + getFromWeb: jest.fn(), + getFromS3: jest.fn() +})); + +jest.mock("../../meetupcom/node_modules/@muxer/lambda-utils", () => + Object.assign( + require.requireActual("../../meetupcom/node_modules/@muxer/lambda-utils"), + { + uploadTo: jest.fn() + } + ) +); + +const prefix = "../../../meetupcom"; + +const resolved = data => () => Promise.resolve(data); + +const resolvedResponse = data => Promise.resolve(JSON.stringify(data)); + +module.exports = { + prefix, + resolved, + resolvedResponse +}; From 856b7e95ee06639f83d811ed170271018e007212 Mon Sep 17 00:00:00 2001 From: Alistair Brown Date: Sun, 18 Nov 2018 09:37:22 +0000 Subject: [PATCH 2/2] Update other producer tests to align --- .../eventbrite/handlers/producer.test.js | 82 +++++++++---------- .../farsetlabs/handlers/producer.test.js | 31 +++---- .../tests/meetupcom/handlers/producer.test.js | 18 ++-- 3 files changed, 65 insertions(+), 66 deletions(-) diff --git a/lambdas/tests/eventbrite/handlers/producer.test.js b/lambdas/tests/eventbrite/handlers/producer.test.js index bda4d8fb..bd6ba0e1 100644 --- a/lambdas/tests/eventbrite/handlers/producer.test.js +++ b/lambdas/tests/eventbrite/handlers/producer.test.js @@ -44,7 +44,7 @@ describe("Eventbrite Producer", function() { getFromWeb.mockImplementation(() => errorResponse()); }); - it("returns an error", function(done) { + it("returns an error and no file paths", function(done) { producer.produce(event, context, function(err, response) { expect(err).toEqual([{ error: "test error" }]); expect(response).toBe(null); @@ -73,31 +73,30 @@ describe("Eventbrite Producer", function() { getFromWeb.mockImplementation(() => singleResponse()); }); - it("does not return an error and returns message", function(done) { - producer.produce(event, context, function(err, response) { - expect(err).toBe(null); - expect(response).toEqual({ message: ["path/to/new/file.json"] }); - done(); - }); - }); - it("makes a request to the API", function(done) { - producer.produce(event, context, function() { + producer.produce(event, context, function(err) { expect(getFromWeb).toHaveBeenCalledTimes(1); expect(getFromWeb).toHaveBeenCalledWith(apiCallPage(1)); - done(); + done(err); }); }); it("uploads data", function(done) { - producer.produce(event, context, function() { + producer.produce(event, context, function(err) { expect(uploadTo).toHaveBeenCalledTimes(1); expect(uploadTo).toHaveBeenCalledWith( "muxer-produced-events-eventbrite", expect.any(Function), { pagination: { has_more_items: false, page_count: 1 } } ); - done(); + done(err); + }); + }); + + it("returns file paths", function(done) { + producer.produce(event, context, function(err, response) { + expect(response).toEqual({ message: ["path/to/new/file.json"] }); + done(err); }); }); }); @@ -114,32 +113,18 @@ describe("Eventbrite Producer", function() { .mockReturnValue(finalResponse({ events: [{ name: "Last Event" }] })); }); - it("does not return an error and returns message", function(done) { - producer.produce(event, context, function(err, response) { - expect(err).toBe(null); - expect(response).toEqual({ - message: [ - "path/to/new/file.json", - "path/to/new/file.json", - "path/to/new/file.json" - ] - }); - done(); - }); - }); - it("makes a request to the API", function(done) { - producer.produce(event, context, function() { + producer.produce(event, context, function(err) { expect(getFromWeb).toHaveBeenCalledTimes(3); expect(getFromWeb).toHaveBeenCalledWith(apiCallPage(1)); expect(getFromWeb).toHaveBeenCalledWith(apiCallPage(2)); expect(getFromWeb).toHaveBeenCalledWith(apiCallPage(3)); - done(); + done(err); }); }); it("uploads data", function(done) { - producer.produce(event, context, function() { + producer.produce(event, context, function(err) { expect(uploadTo).toHaveBeenCalledTimes(3); expect(uploadTo).toHaveBeenCalledWith( "muxer-produced-events-eventbrite", @@ -165,7 +150,20 @@ describe("Eventbrite Producer", function() { pagination: { has_more_items: false, page_count: 3 } } ); - done(); + done(err); + }); + }); + + it("returns file paths", function(done) { + producer.produce(event, context, function(err, response) { + expect(response).toEqual({ + message: [ + "path/to/new/file.json", + "path/to/new/file.json", + "path/to/new/file.json" + ] + }); + done(err); }); }); }); @@ -180,17 +178,6 @@ describe("Eventbrite Producer", function() { .mockReturnValue(errorResponse({ page: 3 })); }); - it("return the errors", function(done) { - producer.produce(event, context, function(err, response) { - expect(err).toEqual([ - { error: "test error", page: 2 }, - { error: "test error", page: 3 } - ]); - expect(response).toBe(null); - done(); - }); - }); - it("makes a request to the API", function(done) { producer.produce(event, context, function() { expect(getFromWeb).toHaveBeenCalledTimes(3); @@ -207,5 +194,16 @@ describe("Eventbrite Producer", function() { done(); }); }); + + it("returns the errors and no file paths", function(done) { + producer.produce(event, context, function(err, response) { + expect(err).toEqual([ + { error: "test error", page: 2 }, + { error: "test error", page: 3 } + ]); + expect(response).toBe(null); + done(); + }); + }); }); }); diff --git a/lambdas/tests/farsetlabs/handlers/producer.test.js b/lambdas/tests/farsetlabs/handlers/producer.test.js index 8aedc40d..30a1973c 100644 --- a/lambdas/tests/farsetlabs/handlers/producer.test.js +++ b/lambdas/tests/farsetlabs/handlers/producer.test.js @@ -6,16 +6,18 @@ const { uploadTo } = require(`${prefix}/node_modules/@muxer/lambda-utils`); const producer = require(`${prefix}/handlers/producer`); const apicall = - "https://www.googleapis.com/calendar/v3/calendars/farsetlabs.org.uk_srmqnkn373auq51u00s2nijrq8%40group.calendar.google.com/events?maxResults=2500&singleEvents=true&orderBy=startTime&timeMin=2019-11-06T10:30:00.000Z&timeMax=2020-11-06T10:30:00.000Z&key=google-calendar-token-abc123"; + "https://www.googleapis.com/calendar/v3/calendars/farsetlabs.org.uk_srmqnkn373auq51u00s2nijrq8%40group.calendar.google.com/events?maxResults=2500&singleEvents=true&orderBy=startTime&timeMin=2018-11-06T10:30:00.000Z&timeMax=2019-11-06T10:30:00.000Z&key=google-calendar-token-abc123"; const event = null; const context = null; describe("Farsetlabs Producer", function() { beforeEach(function() { - const frozenDate = new Date("2018-11-06T10:30:00"); + const NativeDate = Date; + global.Date = jest.fn( + input => new NativeDate(input || "2018-11-06T10:30:00") + ); jest.clearAllMocks(); - global.Date = jest.fn(() => frozenDate); uploadTo.mockImplementation(resolved({ key: "path/to/new/file.json" })); }); @@ -29,31 +31,30 @@ describe("Farsetlabs Producer", function() { getFromWeb.mockImplementation(() => resolvedResponse({ items: [] })); }); - it("does not return an error and returns message", function(done) { - producer.produce(event, context, function(err, response) { - expect(err).toBe(null); - expect(response).toEqual({ message: ["path/to/new/file.json"] }); - done(); - }); - }); - it("makes a request to the API", function(done) { - producer.produce(event, context, function() { + producer.produce(event, context, function(err) { expect(getFromWeb).toHaveBeenCalledTimes(1); expect(getFromWeb).toHaveBeenCalledWith(apicall); - done(); + done(err); }); }); it("uploads data", function(done) { - producer.produce(event, context, function() { + producer.produce(event, context, function(err) { expect(uploadTo).toHaveBeenCalledTimes(1); expect(uploadTo).toHaveBeenCalledWith( "muxer-produced-events-farsetlabs", expect.any(Function), { items: [] } ); - done(); + done(err); + }); + }); + + it("returns file paths", function(done) { + producer.produce(event, context, function(err, response) { + expect(response).toEqual({ message: ["path/to/new/file.json"] }); + done(err); }); }); }); diff --git a/lambdas/tests/meetupcom/handlers/producer.test.js b/lambdas/tests/meetupcom/handlers/producer.test.js index a9c36cfb..e0b5c846 100644 --- a/lambdas/tests/meetupcom/handlers/producer.test.js +++ b/lambdas/tests/meetupcom/handlers/producer.test.js @@ -74,14 +74,7 @@ describe("Meetup.com Producer", function() { }); }); - it("does not upload data", function(done) { - producer.produce(event, context, function() { - expect(uploadTo).not.toHaveBeenCalled(); - done(); - }); - }); - - it("return an error and no file paths", function(done) { + it("returns an error and no file paths", function(done) { producer.produce(event, context, function(err, response) { expect(err).toEqual([ { @@ -93,6 +86,13 @@ describe("Meetup.com Producer", function() { done(); }); }); + + it("does not upload data", function(done) { + producer.produce(event, context, function() { + expect(uploadTo).not.toHaveBeenCalled(); + done(); + }); + }); }); describe("when no groups are returned", function() { @@ -180,7 +180,7 @@ describe("Meetup.com Producer", function() { }); }); - it("return the errors and no file paths", function(done) { + it("returns the errors and no file paths", function(done) { producer.produce(event, context, function(err, response) { expect(err).toEqual([ [{ code: "auth_fail", message: "Invalid signature" }]