Files
shields/services/service-tester.js
T
Paul MelnikowandGitHub 73fcc1ccac Deprecate old [StaticBadge] using a redirect (#2333)
Now that the static badge has been moved in #2284, next in line for cleaning out `server.js` is this “static badge, old format.” I imagine this route is _very, very old_. (I wouldn’t be surprised if it’s not used at all. I’d be curious to see some stats on that endpoint. If it's not regularly getting requests I could see dropping it.)

In the case of URLs which have permanently changed, an approach I’d like to try is issuing a 301 Redirect.

The benefit is that if a user pastes the URL into the address bar while they are previewing or editing it, the browser will replace the address with the corrected URL when it loads. I figure this will cause some people to update their URLs with no effort, simply because they previewed the badge in their browser, and others to change over, if they notice it.

We incur a slight cost, which is a second request. However many browsers cache the 301’s indefinitely, and we can set an effectively infinite cache duration so the CDN and most other downstream caches will keep them a long time. And handling the redirect is extremely cheap.

This is a nice way to preserve backward compatibility of old routes without having to complicate the new route, such as in the case of vso -> azure-devops. For maintenance purposes, the route that redirects can effectively be treated separately.

It’s also a nice, gentle, and confidence-inspiring way to signal that users should update their URLs.

We could generalize this code, though I think this is a good place to start. This route is tricky because it needs to be loaded last, complicating a reusable solution.
2018-11-17 15:22:03 -05:00

106 lines
2.6 KiB
JavaScript

'use strict'
const frisby = require('icedfrisby-nock')(require('icedfrisby'))
const emojic = require('emojic')
const config = require('../lib/test-config')
const trace = require('./trace')
/**
* Encapsulate a suite of tests. Create new tests using create() and register
* them with Mocha using toss().
*/
class ServiceTester {
/**
* @param attrs { id, title, pathPrefix } The `id` is used to specify which
* tests to run from the CLI or pull requests. The `title` prints in the
* Mocha output. The `path` is the path prefix which is automatically
* prepended to each tested URI. The default is `/${attrs.id}`.
*/
constructor({ id, title, pathPrefix }) {
if (pathPrefix === undefined) {
pathPrefix = `/${id}`
}
Object.assign(this, {
id,
title,
pathPrefix,
specs: [],
_only: false,
})
}
static forServiceClass(ServiceClass) {
const id = ServiceClass.name
const pathPrefix = ServiceClass.route.base
? `/${ServiceClass.route.base}`
: ''
return new this({
id,
title: id,
pathPrefix,
})
}
/**
* Invoked before each test. This is a stub which can be overridden on
* instances.
*/
beforeEach() {}
/**
* Create a new test. The hard work is delegated to IcedFrisby.
* https://github.com/MarkHerhold/IcedFrisby/#show-me-some-code
*
* Note: The caller should not invoke toss() on the Frisby chain, as it's
* invoked automatically by the tester.
* @param msg The name of the test
*/
create(msg) {
const spec = frisby
.create(msg)
.baseUri(`http://localhost:${config.port}${this.pathPrefix}`)
.before(() => {
this.beforeEach()
})
// eslint-disable-next-line mocha/prefer-arrow-callback
.finally(function() {
// `this` is the IcedFrisby instance.
let responseBody
try {
responseBody = JSON.parse(this._response.body)
} catch (e) {
responseBody = this._response.body
}
trace.logTrace('outbound', emojic.shield, 'Response', responseBody)
})
this.specs.push(spec)
return spec
}
/**
* Run only this tester. This can be invoked using the --only argument to
* the CLI, or directly on the tester.
*/
only() {
this._only = true
}
/**
* Register the tests with Mocha.
*/
toss() {
const specs = this.specs
const fn = this._only ? describe.only : describe
// eslint-disable-next-line mocha/prefer-arrow-callback
fn(this.title, function() {
specs.forEach(spec => {
spec.toss()
})
})
}
}
module.exports = ServiceTester