Skip to content

Commit a8754a8

Browse files
committed
Verify gzipped content functions correctly
1 parent e056740 commit a8754a8

File tree

7 files changed

+47
-13
lines changed

7 files changed

+47
-13
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { gzipSync } from 'node:zlib'
2+
import type { RequestComposer } from './types.ts'
3+
4+
export const composeGzipped: RequestComposer = (content) => {
5+
return {
6+
method: 'PUT',
7+
headers: {
8+
'Content-Type': 'application/jsonl',
9+
'Content-Encoding': 'gzip',
10+
},
11+
body: gzipSync(content),
12+
}
13+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import type { RequestComposer } from './types.ts'
2+
3+
export const composeUncompressed: RequestComposer = (content) => {
4+
return {
5+
method: 'PUT',
6+
body: content,
7+
}
8+
}

features/actions/publishReport.mts

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ import { stripVTControlCharacters } from 'node:util'
33
import { readFileSync } from 'node:fs'
44
import path from 'node:path'
55
import { type Action } from '../support/Actor.mjs'
6-
import { type PublishResult } from './types'
6+
import { type RequestComposer, type PublishResult } from './types'
77

8-
export const publishReport: (fixture: string, privateToken?: string) => Action<PublishResult> = (
9-
fixture,
10-
privateToken
11-
) => {
8+
export const publishReport: (
9+
fixture: string,
10+
requestComposer: RequestComposer,
11+
privateToken?: string
12+
) => Action<PublishResult> = (fixture, requestComposer, privateToken) => {
1213
return async () => {
1314
const headers = new Headers()
1415
if (privateToken) {
@@ -23,14 +24,11 @@ export const publishReport: (fixture: string, privateToken?: string) => Action<P
2324
const url = banner.split(' ').find((part) => part.startsWith('http'))
2425

2526
if (getResponse.ok && url) {
26-
const putUrl = getResponse.headers.get('Location') as string
27+
const uploadUrl = getResponse.headers.get('Location') as string
2728
const envelopes = readFileSync(path.join(import.meta.dirname, '..', 'fixtures', fixture), {
2829
encoding: 'utf-8',
2930
})
30-
const putResponse = await fetch(putUrl, {
31-
method: 'PUT',
32-
body: envelopes,
33-
})
31+
const putResponse = await fetch(uploadUrl, requestComposer(envelopes))
3432
assert.ok(putResponse.ok)
3533
}
3634

features/actions/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
export type RequestComposer = (content: string) => RequestInit
2+
13
export interface PublishResult {
24
success: boolean
35
banner: string

features/publishing.feature

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,10 @@ Feature: Publishing
1515
Given a Cucumber implementation that omits some fields
1616
When Ira publishes a report
1717
And Ira views the report they just published
18-
Then Ira should see their test results
18+
Then Ira should see their test results
19+
20+
Scenario: Report content can be compressed
21+
Given a Cucumber implementation that compresses content
22+
When Jaqueline publishes a report
23+
And Jaqueline views the report they just published
24+
Then Jaqueline should see their test results

features/steps/steps.mts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,16 @@ import { wasDeleted } from '../actions/wasDeleted.mjs'
1212
import { wasNotFound } from '../actions/wasNotFound.mjs'
1313
import { navigateToSite } from '../actions/navigateToSite.mjs'
1414
import { canSeeSample } from '../actions/canSeeSample.mjs'
15+
import { composeGzipped } from '../actions/composeGzipped.mts'
1516

1617
Given('a Cucumber implementation that omits some fields', async (t) => {
1718
t.world.messagesFixture = 'messages-omissions.ndjson'
1819
})
1920

21+
Given('a Cucumber implementation that compresses content', async (t) => {
22+
t.world.requestComposer = composeGzipped
23+
})
24+
2025
Given('{actor} has a private token', async (t, actor: Actor) => {
2126
actor.remember('privateToken', crypto.randomBytes(16).toString('hex'))
2227
})
@@ -31,7 +36,7 @@ Given('a report previously published by {actor} has been deleted', async (t, act
3136

3237
When('{actor} publishes a report', async (t, actor: Actor) => {
3338
const publishResult = await actor.attemptsTo(
34-
publishReport(t.world.messagesFixture, actor.recall('privateToken'))
39+
publishReport(t.world.messagesFixture, t.world.requestComposer, actor.recall('privateToken'))
3540
)
3641
actor.remember('publishResult', publishResult)
3742
t.world.publishResults.push(publishResult)

features/support/CustomWorld.mts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import { Browser, launch } from 'puppeteer'
22
import { ActorLookup } from './ActorLookup.mjs'
33
import { Actor } from './Actor.mjs'
4-
import { type PublishResult } from '../actions/types'
4+
import { type RequestComposer, type PublishResult } from '../actions/types'
5+
import { composeUncompressed } from '../actions/composeUncompressed.mjs'
56

67
export class CustomWorld {
78
private readonly actorLookup = new ActorLookup()
89
private browser: Browser | undefined
910
public messagesFixture = 'messages-valid.ndjson'
11+
public requestComposer: RequestComposer = composeUncompressed
1012
public publishResults: Array<PublishResult> = []
1113

1214
public findOrCreateActor(actorName: string): Actor {

0 commit comments

Comments
 (0)