UNPKG

hubot-pollen

Version:

Retrieves the latest from the Pollen.com API

309 lines (283 loc) 9.82 kB
const Helper = require('./helpers/hubot-room-helper'); const assert = require('assert'); const nock = require('nock'); const sinon = require('./helpers/sinon-lite'); const helper = new Helper([ `${__dirname}/adapters/slack.js`, `${__dirname}/../src/pollen.js`, ]); const buildOpenMeteoNoData = (latitude, longitude) => ({ latitude, longitude, hourly: { alder_pollen: [null], birch_pollen: [null], grass_pollen: [null], mugwort_pollen: [null], olive_pollen: [null], ragweed_pollen: [null], }, }); const mockOpenMeteoGeocode = (name, result) => nock('https://geocoding-api.open-meteo.com') .get('/v1/search') .query((query) => query.name === `${name}`) .reply(200, { results: [result] }); const mockOpenMeteoAirQuality = (latitude, longitude, body) => nock('https://air-quality-api.open-meteo.com') .get('/v1/air-quality') .query((query) => Number(query.latitude) === latitude && Number(query.longitude) === longitude) .reply(200, body); describe('hubot-pollen with slack adapter', () => { beforeEach(function () { process.env.HUBOT_LOG_LEVEL = 'error'; process.env.HUBOT_POLLEN_ZIP = 37206; nock.disableNetConnect(); // Mock console methods to suppress output this.consoleStubs = { log: sinon.stub(console, 'log'), error: sinon.stub(console, 'error'), warn: sinon.stub(console, 'warn'), debug: sinon.stub(console, 'debug'), info: sinon.stub(console, 'info'), }; this.room = helper.createRoom(); }); afterEach(function () { delete process.env.HUBOT_LOG_LEVEL; delete process.env.HUBOT_POLLEN_ZIP; nock.cleanAll(); // Restore console methods Object.values(this.consoleStubs).forEach((stub) => stub.restore()); this.room.destroy(); }); it('responds to pollen forecast for default location', function (done) { mockOpenMeteoGeocode('37206', { name: 'Nashville', latitude: 36.17, longitude: -86.78, postcodes: ['37206'], country_code: 'US', admin1: 'TN', }); mockOpenMeteoAirQuality(36.17, -86.78, buildOpenMeteoNoData(36.17, -86.78)); nock('https://www.pollen.com') .get('/api/forecast/current/pollen/37206') .matchHeader('User-Agent', /Mozilla\/.*/) .matchHeader('Referer', 'https://www.pollen.com/forecast/current/pollen/37206') .replyWithFile(200, `${__dirname}/fixtures/37206.json`); const selfRoom = this.room; selfRoom.user.say('alice', '@hubot pollen'); setTimeout( () => { try { assert.deepStrictEqual(selfRoom.messages, [ ['alice', '@hubot pollen'], [ 'hubot', { attachments: [ { author_icon: 'https://www.pollen.com/Content/favicon/apple-touch-icon-72x72.png', author_link: 'https://www.pollen.com/', author_name: 'Pollen.com', color: 'danger', fallback: 'Nashville, TN Pollen: 8.2 (Medium-High) - Alder, Juniper, Maple', fields: [ { short: true, title: 'Level', value: 'Medium-High', }, { short: true, title: 'Count', value: '8.2', }, { short: false, title: 'Types', value: 'Alder, Juniper, Maple', }, ], footer: 'Pollen.com', title: 'Nashville, TN Pollen', title_link: 'https://www.pollen.com/forecast/current/pollen/37206', ts: 1520827200, }, ], }, ], ]); done(); } catch (err) { done(err); } }, 100, ); }); it('responds to pollen forecast plus a zip code', function (done) { mockOpenMeteoGeocode('90210', { name: 'Beverly Hills', latitude: 34.09, longitude: -118.41, postcodes: ['90210'], country_code: 'US', admin1: 'CA', }); mockOpenMeteoAirQuality(34.09, -118.41, buildOpenMeteoNoData(34.09, -118.41)); nock('https://www.pollen.com') .get('/api/forecast/current/pollen/90210') .matchHeader('User-Agent', /Mozilla\/.*/) .matchHeader('Referer', 'https://www.pollen.com/forecast/current/pollen/90210') .replyWithFile(200, `${__dirname}/fixtures/90210.json`); const selfRoom = this.room; selfRoom.user.say('alice', '@hubot pollen 90210'); setTimeout( () => { try { assert.deepStrictEqual(selfRoom.messages, [ ['alice', '@hubot pollen 90210'], [ 'hubot', { attachments: [ { author_icon: 'https://www.pollen.com/Content/favicon/apple-touch-icon-72x72.png', author_link: 'https://www.pollen.com/', author_name: 'Pollen.com', color: 'warning', fallback: 'Beverly Hills, CA Pollen: 7.2 (Medium) - Alder, Juniper, Ash', fields: [ { short: true, title: 'Level', value: 'Medium', }, { short: true, title: 'Count', value: '7.2', }, { short: false, title: 'Types', value: 'Alder, Juniper, Ash', }, ], footer: 'Pollen.com', title: 'Beverly Hills, CA Pollen', title_link: 'https://www.pollen.com/forecast/current/pollen/90210', ts: 1520827200, }, ], }, ], ]); done(); } catch (err) { done(err); } }, 100, ); }); it('responds to pollen forecast for a zip code with no results', function (done) { mockOpenMeteoGeocode('99501', { name: 'Anchorage', latitude: 61.2, longitude: -149.9, postcodes: ['99501'], country_code: 'US', admin1: 'AK', }); mockOpenMeteoAirQuality(61.2, -149.9, buildOpenMeteoNoData(61.2, -149.9)); nock('https://www.pollen.com') .get('/api/forecast/current/pollen/99501') .matchHeader('User-Agent', /Mozilla\/.*/) .matchHeader('Referer', 'https://www.pollen.com/forecast/current/pollen/99501') .replyWithFile(200, `${__dirname}/fixtures/99501.json`); const selfRoom = this.room; selfRoom.user.say('alice', '@hubot pollen 99501'); setTimeout( () => { try { assert.deepStrictEqual(selfRoom.messages, [ ['alice', '@hubot pollen 99501'], ['hubot', '99501 Pollen: No forecast available.'], ]); done(); } catch (err) { done(err); } }, 100, ); }); it('responds with a Slack payload from Open-Meteo when pollen data is available', function (done) { mockOpenMeteoGeocode('London', { name: 'London', latitude: 51.5, longitude: -0.1, country_code: 'GB', }); mockOpenMeteoAirQuality(51.5, -0.1, { latitude: 51.5, longitude: -0.1, hourly: { alder_pollen: [0.0, 0.0], birch_pollen: [0.1, 0.6], grass_pollen: [1.2, 1.7], mugwort_pollen: [0.0, 0.0], olive_pollen: [0.0, 0.0], ragweed_pollen: [0.0, 0.0], }, }); const selfRoom = this.room; selfRoom.user.say('alice', '@hubot pollen London'); setTimeout( () => { try { assert.strictEqual(selfRoom.messages[0][0], 'alice'); assert.strictEqual(selfRoom.messages[0][1], '@hubot pollen London'); const message = selfRoom.messages[1][1]; assert.strictEqual(selfRoom.messages[1][0], 'hubot'); assert(Array.isArray(message.attachments), 'Expected Slack attachments payload'); assert.strictEqual(message.attachments.length, 1); const attachment = message.attachments[0]; assert.strictEqual(attachment.author_name, 'Open-Meteo'); assert.strictEqual(attachment.author_link, 'https://open-meteo.com/'); assert.strictEqual(attachment.color, 'warning'); assert.strictEqual(attachment.title, 'London, GB Pollen'); assert.strictEqual(attachment.title_link, 'https://open-meteo.com/en/docs/air-quality-api'); assert.strictEqual( attachment.fallback, 'London, GB Pollen: Low intensity (1.7 grains/m^3 peak) - Grass 1.7, Birch 0.6', ); assert.strictEqual(attachment.footer, 'Data: Open-Meteo'); assert.strictEqual(typeof attachment.ts, 'number'); assert.deepStrictEqual(attachment.fields, [ { title: 'Intensity', value: 'Low (Open-Meteo model scale)', short: true, }, { title: 'Peak', value: '1.7 grains/m^3', short: true, }, { title: 'Types', value: 'Grass 1.7, Birch 0.6', short: false, }, ]); done(); } catch (err) { done(err); } }, 100, ); }); });