UNPKG

hubot-heroku

Version:

Run heroku commands via hubot without direct access to Heroku

336 lines (269 loc) 13.3 kB
require('dotenv').load() HubotHelper = require("hubot-test-helper") path = require("path") chai = require("chai") nock = require("nock") process.env.HUBOT_HEROKU_API_KEY = 'fake_key' useAuth = (process.env.HUBOT_HEROKU_USE_AUTH or '').trim().toLowerCase() is 'true' withAuth = if useAuth then ' w/Auth' else '' { expect } = chai describe "Heroku Commands#{withAuth}", -> helper = new HubotHelper("../index.coffee") room = helper.createRoom() mockHeroku = nock("https://api.heroku.com") duration = 5 deniedMessage = "@Damon Access denied. You must have this role to use this command: heroku-shield-global-watch" beforeEach -> room.messages = [] afterEach -> nock.cleanAll() it "exposes help commands", -> commands = room.robot.commands.filter (command) -> command.slice(0,12) is "hubot heroku" expect(commands).to.have.length(9) expect(commands).to.include("hubot heroku info <app> - Returns useful information about the app") expect(commands).to.include("hubot heroku dynos <app> - Lists all dynos and their status") expect(commands).to.include("hubot heroku releases <app> - Latest 10 releases") expect(commands).to.include("hubot heroku rollback <app> <version> - Rollback to a release") expect(commands).to.include("hubot heroku restart <app> <dyno> - Restarts the specified app or dyno/s (e.g. worker or web.2)") expect(commands).to.include("hubot heroku migrate <app> - Runs migrations. Remember to restart the app =)") expect(commands).to.include("hubot heroku config <app> - Get config keys for the app. Values not given for security") expect(commands).to.include("hubot heroku config:set <app> <KEY=value> - Set KEY to value. Case sensitive and overrides present key") expect(commands).to.include("hubot heroku config:unset <app> <KEY> - Unsets KEY, does not throw error if key is not present") describe "heroku info <app>", -> it "gets information about the app's dynos", (done) -> mockHeroku .get("/apps/shield-global-watch") .replyWithFile(200, __dirname + "/fixtures/app-info.json") room.user.say "Damon", "hubot heroku info shield-global-watch" setTimeout(-> if useAuth expect(room.messages[1][1]).to.equal(deniedMessage) else expect(room.messages[1][1]).to.equal("@Damon Getting information about shield-global-watch") expect(room.messages[2][1]).to.contain("last_release : 2014-12-12T02:16:59Z") done() , duration) describe "heroku dynos <app>", -> it "lists all dynos and their status", (done) -> mockHeroku .get("/apps/shield-global-watch/dynos") .replyWithFile(200, __dirname + "/fixtures/dynos.json") room.user.say "Damon", "hubot heroku dynos shield-global-watch" setTimeout(-> if useAuth expect(room.messages[1][1]).to.equal(deniedMessage) else expect(room.messages[1][1]).to.equal("@Damon Getting dynos of shield-global-watch") expect(room.messages[2][1]).to.include("@Damon Dynos of shield-global-watch\n=== web (1X): `forever server.js`\nweb.1: up 2015/01/01 12:00:00") expect(room.messages[2][1]).to.include("\nweb.2: crashed 2015/01/01 12:00:00") expect(room.messages[2][1]).to.include("\n\n=== worker (2X): `celery worker`\nworker.1: up 2015/06/01 12:00:00") done() , duration) describe "heroku releases <app>", -> it "gets the 10 recent releases", (done) -> mockHeroku .get("/apps/shield-global-watch/releases") .replyWithFile(200, __dirname + "/fixtures/releases.json") room.user.say "Damon", "hubot heroku releases shield-global-watch" setTimeout(-> if useAuth expect(room.messages[1][1]).to.equal(deniedMessage) else expect(room.messages[1][1]).to.equal("@Damon Getting releases for shield-global-watch") expect(room.messages[2][1]).to.include("@Damon Recent releases of shield-global-watch\nv352 - Promote shield-global-watch v287 fb2b5ff - phil@shield.com") done() , duration) describe "heroku rollback <app> <version>", -> beforeEach -> mockHeroku .get("/apps/shield-global-watch/releases") .replyWithFile(200, __dirname + "/fixtures/releases.json") mockHeroku .post('/apps/shield-global-watch/releases') .replyWithFile(200, __dirname + "/fixtures/rollback.json",) it "rolls back the app to the specified version", (done) -> room.user.say "Damon", "hubot heroku rollback shield-global-watch v352" setTimeout(-> if useAuth expect(room.messages[1][1]).to.equal(deniedMessage) else expect(room.messages[1][1]).to.equal("@Damon Telling Heroku to rollback to v352") expect(room.messages[2][1]).to.equal("@Damon Success! v353 -> Rollback to v352") done() , duration) it "tells the user about a bad supplied version", (done) -> room.user.say "Damon", "hubot heroku rollback shield-global-watch v999" setTimeout(-> if useAuth expect(room.messages[1][1]).to.equal(deniedMessage) else expect(room.messages[1][1]).to.equal("@Damon Telling Heroku to rollback to v999") expect(room.messages[2][1]).to.equal("@Damon Version v999 not found for shield-global-watch :(") done() , duration) describe "heroku restart <app> <dyno>", -> it "restarts the app", (done) -> mockHeroku .delete("/apps/shield-global-watch/dynos") .reply(200, {}) room.user.say "Damon", "hubot heroku restart shield-global-watch" setTimeout(-> if useAuth expect(room.messages[1][1]).to.equal(deniedMessage) else expect(room.messages[1][1]).to.equal("@Damon Telling Heroku to restart shield-global-watch") expect(room.messages[2][1]).to.equal("@Damon Heroku: Restarting shield-global-watch") done() , duration) it "restarts all dynos of a process", (done) -> mockHeroku .delete("/apps/shield-global-watch/dynos/web") .reply(200, {}) room.user.say "Damon", "hubot heroku restart shield-global-watch web" setTimeout(-> if useAuth expect(room.messages[1][1]).to.equal(deniedMessage) else expect(room.messages[1][1]).to.equal("@Damon Telling Heroku to restart shield-global-watch web") expect(room.messages[2][1]).to.equal("@Damon Heroku: Restarting shield-global-watch web") done() , duration) it "restarts specific dynos", (done) -> mockHeroku .delete("/apps/shield-global-watch/dynos/web.1") .reply(200, {}) room.user.say "Damon", "hubot heroku restart shield-global-watch web.1" setTimeout(-> if useAuth expect(room.messages[1][1]).to.equal(deniedMessage) else expect(room.messages[1][1]).to.equal("@Damon Telling Heroku to restart shield-global-watch web.1") expect(room.messages[2][1]).to.equal("@Damon Heroku: Restarting shield-global-watch web.1") done() , duration) describe "heroku migrate <app>", -> beforeEach -> mockHeroku .post("/apps/shield-global-watch/dynos", command: "rake db:migrate" attach: false size: "1X" ).replyWithFile(200, __dirname + "/fixtures/migrate.json") mockHeroku .post("/apps/shield-global-watch/log-sessions", dyno: "run.6454" tail: true ).replyWithFile(200, __dirname + "/fixtures/log-session.json") room.user.say "Damon", "hubot heroku migrate shield-global-watch" it "runs migrations", (done) -> setTimeout(-> if useAuth expect(room.messages[1][1]).to.equal(deniedMessage) else expect(room.messages[1][1]).to.equal("@Damon Telling Heroku to migrate shield-global-watch") expect(room.messages[2][1]).to.equal("@Damon Heroku: Running migrations for shield-global-watch") done() , duration) it "returns the logplex_url", (done) -> setTimeout(-> if useAuth expect(room.messages[1][1]).to.equal(deniedMessage) else expect(room.messages[3][1]).to.equal("@Damon View logs at: https://logplex.heroku.com/sessions/9d4f18cd-d9k8-39a5-ddef-a47dfa443z74?srv=1418011757") done() , duration) describe "heroku config <app>", -> it "gets a list of config keys without values", (done) -> mockHeroku .get("/apps/shield-global-watch/config-vars") .replyWithFile(200, __dirname + "/fixtures/config.json") room.user.say "Damon", "hubot heroku config shield-global-watch" setTimeout(-> if useAuth expect(room.messages[1][1]).to.equal(deniedMessage) else expect(room.messages[1][1]).to.equal("@Damon Getting config keys for shield-global-watch") expect(room.messages[2][1]).to.equal("@Damon CLOAK, COMMANDER, AUTOPILOT, PILOT_NAME") done() , duration) describe "heroku config:set <app> <KEY=value>", -> mockRequest = (keyPair) -> mockHeroku .patch("/apps/shield-global-watch/config-vars",keyPair) .replyWithFile(200, __dirname + "/fixtures/config-set.json") it "sets config <KEY=value>", (done) -> mockRequest({ "CLOAK_ID": "example.com" }) room.user.say "Damon", "hubot heroku config:set shield-global-watch CLOAK_ID=example.com" setTimeout(-> if useAuth expect(room.messages[1][1]).to.equal(deniedMessage) else expect(room.messages[1][1]).to.equal("@Damon Setting config CLOAK_ID => example.com") expect(room.messages[2][1]).to.equal("@Damon Heroku: CLOAK_ID is set to example.com") done() , duration) it "handles UUIDs", (done) -> mockRequest("UUID": "d5126f0d-b3be-46af-883f-b330a73964f9") room.user.say "Damon", "hubot heroku config:set shield-global-watch UUID=d5126f0d-b3be-46af-883f-b330a73964f9" setTimeout(-> if useAuth expect(room.messages[1][1]).to.equal(deniedMessage) else expect(room.messages[2][1]).to.equal("@Damon Heroku: UUID is set to d5126f0d-b3be-46af-883f-b330a73964f9") done() , duration) it "handles URLs", (done) -> mockRequest("PUSHER_URL": "http://c0d9g8najfcc4634kd3:cf2eeas0d8dghfa847d@api.pusherapp.com/apps/1234") room.user.say "Damon", "hubot heroku config:set shield-global-watch PUSHER_URL=http://c0d9g8najfcc4634kd3:cf2eeas0d8dghfa847d@api.pusherapp.com/apps/1234" setTimeout(-> if useAuth expect(room.messages[1][1]).to.equal(deniedMessage) else expect(room.messages[2][1]).to.equal("@Damon Heroku: PUSHER_URL is set to http://c0d9g8najfcc4634kd3:cf2eeas0d8dghfa847d@api.pusherapp.com/apps/1234") done() , duration) it "handles comma delimited strings", (done) -> mockRequest("COMMA_DELIMITED_STRING": "MiD,DA,MDe") room.user.say "Damon", "hubot heroku config:set shield-global-watch COMMA_DELIMITED_STRING=MiD,DA,MDe" setTimeout(-> if useAuth expect(room.messages[1][1]).to.equal(deniedMessage) else expect(room.messages[2][1]).to.equal("@Damon Heroku: COMMA_DELIMITED_STRING is set to MiD,DA,MDe") done() , duration) it "handles text strings", (done) -> mockRequest("SENTENCE": "Don\'t stop believin.") room.user.say "Damon", "hubot heroku config:set shield-global-watch SENTENCE=\"Don't stop believin.\"" setTimeout(-> if useAuth expect(room.messages[1][1]).to.equal(deniedMessage) else expect(room.messages[2][1]).to.equal("@Damon Heroku: SENTENCE is set to Don\'t stop believin.") done() , duration) it "handles RSA secret keys", (done) -> mockRequest("RSA_SECRET_KEY": "----BEGIN RSA PRIVATE KEY-----\nsfsdfdssfdsFDSFDGSDfsdfsfs\nSDfSDFdUbOfFRocKsSFDSFSDFDS=\n-----END RSA PRIVATE KEY-----\n") room.user.say "Damon", "hubot heroku config:set shield-global-watch RSA_SECRET_KEY=\"----BEGIN RSA PRIVATE KEY-----\nsfsdfdssfdsFDSFDGSDfsdfsfs\nSDfSDFdUbOfFRocKsSFDSFSDFDS=\n-----END RSA PRIVATE KEY-----\n\"" setTimeout(-> if useAuth expect(room.messages[1][1]).to.equal(deniedMessage) else expect(room.messages[2][1]).to.equal("@Damon Heroku: RSA_SECRET_KEY is set to \"----BEGIN RSA PRIVATE KEY-----\nsfsdfdssfdsFDSFDGSDfsdfsfs\nSDfSDFdUbOfFRocKsSFDSFSDFDS=\n-----END RSA PRIVATE KEY-----\n\"") done() , duration) describe "heroku config:unset <KEY>", -> it "unsets config <KEY>", (done) -> mockHeroku .patch("/apps/shield-global-watch/config-vars", "CLOAK_ID": null ).reply(200, {}) room.user.say "Damon", "hubot heroku config:unset shield-global-watch CLOAK_ID" setTimeout(-> if useAuth expect(room.messages[1][1]).to.equal(deniedMessage) else expect(room.messages[1][1]).to.equal("@Damon Unsetting config CLOAK_ID") expect(room.messages[2][1]).to.equal("@Damon Heroku: CLOAK_ID has been unset") done() , duration)