Skip to content
Snippets Groups Projects
Select Git revision
  • b369f670d63c574a6e857d9113ba3d988d75f6eb
  • main default protected
  • renovate/main-ghcr.io-renovatebot-base-image-10.x
  • renovate/main-ghcr.io-containerbase-devcontainer-13.x
  • next
  • revert-31645-feat/rename-gradle-wrapper-validation-action
  • renovate/main-redis-5.x
  • fix/36615b-branch-reuse-no-cache
  • chore/punycode
  • fix/36615-branch-reuse-bug
  • refactor/pin-new-value
  • feat/36219--git-x509-signing
  • feat/structured-logger
  • hotfix/39.264.1
  • feat/skip-dangling
  • gh-readonly-queue/next/pr-36034-7a061c4ca1024a19e2c295d773d9642625d1c2be
  • hotfix/39.238.3
  • refactor/gitlab-auto-approve
  • feat/template-strings
  • gh-readonly-queue/next/pr-35654-137d934242c784e0c45d4b957362214f0eade1d7
  • fix/32307-global-extends-merging
  • 41.26.1
  • 41.26.0
  • 41.25.1
  • 41.25.0
  • 41.24.0
  • 41.23.5
  • 41.23.4
  • 41.23.3
  • 41.23.2
  • 41.23.1
  • 41.23.0
  • 41.22.0
  • 41.21.4
  • 41.21.3
  • 41.21.2
  • 41.21.1
  • 41.21.0
  • 41.20.2
  • 41.20.1
  • 41.20.0
41 results

github.js

Blame
  • cache-headers.spec.js 6.81 KiB
    'use strict'
    
    const { test, given } = require('sazerac')
    const chai = require('chai')
    const { expect } = require('chai')
    const sinon = require('sinon')
    const httpMocks = require('node-mocks-http')
    const {
      coalesceCacheLength,
      setHeadersForCacheLength,
      setCacheHeaders,
      setCacheHeadersForStaticResource,
      serverHasBeenUpSinceResourceCached,
    } = require('./cache-headers')
    
    chai.use(require('chai-datetime'))
    
    describe('Cache header functions', function() {
      let res
      beforeEach(function() {
        res = httpMocks.createResponse()
      })
    
      describe('coalesceCacheLength', function() {
        const cacheHeaderConfig = { defaultCacheLengthSeconds: 777 }
        test(coalesceCacheLength, () => {
          given({ cacheHeaderConfig, queryParams: {} }).expect(777)
          given({
            cacheHeaderConfig,
            serviceDefaultCacheLengthSeconds: 900,
            queryParams: {},
          }).expect(900)
          given({
            cacheHeaderConfig,
            serviceDefaultCacheLengthSeconds: 900,
            queryParams: { maxAge: 1000 },
          }).expect(1000)
          given({
            cacheHeaderConfig,
            serviceDefaultCacheLengthSeconds: 900,
            queryParams: { maxAge: 1000, other: 'here', maybe: 'bogus' },
          }).expect(1000)
          given({
            cacheHeaderConfig,
            serviceDefaultCacheLengthSeconds: 900,
            queryParams: { maxAge: 400 },
          }).expect(900)
          given({
            cacheHeaderConfig,
            serviceDefaultCacheLengthSeconds: 900,
            queryParams: { maxAge: '-1000' },
          }).expect(900)
          given({
            cacheHeaderConfig,
            serviceDefaultCacheLengthSeconds: 900,
            queryParams: { maxAge: '' },
          }).expect(900)
          given({
            cacheHeaderConfig,
            serviceDefaultCacheLengthSeconds: 900,
            queryParams: { maxAge: 'not a number' },
          }).expect(900)
          given({
            cacheHeaderConfig,
            serviceDefaultCacheLengthSeconds: 900,
            serviceOverrideCacheLengthSeconds: 400,
            queryParams: {},
          }).expect(900)
          given({
            cacheHeaderConfig,
            serviceOverrideCacheLengthSeconds: 400,
            queryParams: {},
          }).expect(777)
          given({
            cacheHeaderConfig,
            serviceOverrideCacheLengthSeconds: 900,
            queryParams: {},
          }).expect(900)
          given({
            cacheHeaderConfig,
            serviceOverrideCacheLengthSeconds: 800,
            queryParams: { maxAge: 500 },
          }).expect(800)
          given({
            cacheHeaderConfig,
            serviceOverrideCacheLengthSeconds: 900,
            queryParams: { maxAge: 800 },
          }).expect(900)
        })
      })
    
      describe('setHeadersForCacheLength', function() {
        let sandbox
        beforeEach(function() {
          sandbox = sinon.createSandbox()
          sandbox.useFakeTimers()
        })
        afterEach(function() {
          sandbox.restore()
          sandbox = undefined
        })
    
        it('should set the correct Date header', function() {
          // Confidence check.
          expect(res._headers.date).to.equal(undefined)
    
          // Act.
          setHeadersForCacheLength(res, 123)
    
          // Assert.
          const now = new Date().toGMTString()
          expect(res._headers.date).to.equal(now)
        })
    
        context('cacheLengthSeconds is zero', function() {
          beforeEach(function() {
            setHeadersForCacheLength(res, 0)
          })
    
          it('should set the expected Cache-Control header', function() {
            expect(res._headers['cache-control']).to.equal(
              'no-cache, no-store, must-revalidate'
            )
          })
    
          it('should set the expected Expires header', function() {
            expect(res._headers.expires).to.equal(new Date().toGMTString())
          })
        })
    
        context('cacheLengthSeconds is nonzero', function() {
          beforeEach(function() {
            setHeadersForCacheLength(res, 123)
          })
    
          it('should set the expected Cache-Control header', function() {
            expect(res._headers['cache-control']).to.equal('max-age=123')
          })
    
          it('should set the expected Expires header', function() {
            const expires = new Date(Date.now() + 123 * 1000).toGMTString()
            expect(res._headers.expires).to.equal(expires)
          })
        })
      })
    
      describe('setCacheHeaders', function() {
        it('sets the expected fields', function() {
          const expectedFields = ['date', 'cache-control', 'expires']
          expectedFields.forEach(field =>
            expect(res._headers[field]).to.equal(undefined)
          )
    
          setCacheHeaders({
            cacheHeaderConfig: { defaultCacheLengthSeconds: 1234 },
            serviceDefaultCacheLengthSeconds: 567,
            queryParams: { maxAge: 999999 },
            res,
          })
    
          expectedFields.forEach(field =>
            expect(res._headers[field])
              .to.be.a('string')
              .and.have.lengthOf.at.least(1)
          )
        })
      })
    
      describe('setCacheHeadersForStaticResource', function() {
        beforeEach(function() {
          setCacheHeadersForStaticResource(res)
        })
    
        it('should set the expected Cache-Control header', function() {
          expect(res._headers['cache-control']).to.equal(`max-age=${24 * 3600}`)
        })
    
        it('should set the expected Last-Modified header', function() {
          const lastModified = res._headers['last-modified']
          expect(new Date(lastModified)).to.be.withinTime(
            // Within the last 60 seconds.
            new Date(Date.now() - 60 * 1000),
            new Date()
          )
        })
      })
    
      describe('serverHasBeenUpSinceResourceCached', function() {
        // The stringified req's are hard to understand. I thought Sazerac
        // provided a way to override the describe message, though I can't find it.
        context('when there is no If-Modified-Since header', function() {
          it('returns false', function() {
            const req = httpMocks.createRequest()
            expect(serverHasBeenUpSinceResourceCached(req)).to.equal(false)
          })
        })
        context('when the If-Modified-Since header is invalid', function() {
          it('returns false', function() {
            const req = httpMocks.createRequest({
              headers: { 'If-Modified-Since': 'this-is-not-a-date' },
            })
            expect(serverHasBeenUpSinceResourceCached(req)).to.equal(false)
          })
        })
        context(
          'when the If-Modified-Since header is before the process started',
          function() {
            it('returns false', function() {
              const req = httpMocks.createRequest({
                headers: { 'If-Modified-Since': '2018-02-01T05:00:00.000Z' },
              })
              expect(serverHasBeenUpSinceResourceCached(req)).to.equal(false)
            })
          }
        )
        context(
          'when the If-Modified-Since header is after the process started',
          function() {
            it('returns true', function() {
              const modifiedTimeStamp = new Date(Date.now() + 1800000)
              const req = httpMocks.createRequest({
                headers: { 'If-Modified-Since': modifiedTimeStamp.toISOString() },
              })
              expect(serverHasBeenUpSinceResourceCached(req)).to.equal(true)
            })
          }
        )
      })
    })