Skip to content

Commit 172bb79

Browse files
committed
test: add tests for POST requests
1 parent af98955 commit 172bb79

4 files changed

Lines changed: 114 additions & 91 deletions

File tree

packages/plugin-http-errors/test/http-errors-xhr.test.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ describe('plugin-http-errors', () => {
211211
expect(notifyCallbacks.length).toBe(0)
212212
})
213213

214-
it('should redact specified headers and query parameters in XHR URLs', async () => {
214+
it('should redact specified query parameters in XHR URLs', async () => {
215215
const notifyCallbacks: Event[] = []
216216

217217
plugin = createPlugin({
@@ -228,7 +228,6 @@ describe('plugin-http-errors', () => {
228228
xhr.responseText = 'Forbidden'
229229

230230
xhr.open('GET', 'https://api.example.com/data?userId=42')
231-
xhr.setRequestHeader('token', 'super-secret-token')
232231
xhr.send()
233232

234233
await new Promise(resolve => setTimeout(resolve, 20))
@@ -238,8 +237,6 @@ describe('plugin-http-errors', () => {
238237

239238
// Verify that sensitive query parameters are redacted
240239
expect(event.request.url).toBe('https://api.example.com/data?userId=[REDACTED]')
241-
expect(event.request.params).toEqual({ userId: '[REDACTED]' })
242-
expect(event.request.headers?.['token']).toBe('[REDACTED]')
243240
})
244241
})
245242
})

packages/plugin-http-errors/test/http-errors.test.ts

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -682,72 +682,4 @@ describe('plugin-http-errors', () => {
682682
expect(requestMetadata.params).toEqual({})
683683
})
684684
})
685-
686-
describe('redacted keys', () => {
687-
it('should redact specified headers in request and response', async () => {
688-
const notifyCallbacks: Event[] = []
689-
690-
plugin = createPlugin({
691-
httpErrorCodes: { min: 400, max: 499 }
692-
})
693-
694-
const client = new Client({ apiKey: 'api_key', plugins: [plugin], redactedKeys: ['authorization'] })
695-
client._setDelivery(createMockDelivery(notifyCallbacks))
696-
697-
mockFetch.mockResolvedValue({
698-
ok: false,
699-
status: 404,
700-
url: 'https://example.com/api/users',
701-
headers: new Headers({
702-
'content-type': 'application/json',
703-
authorization: 'Bearer secret-token'
704-
}),
705-
text: async () => 'Not found'
706-
})
707-
708-
await fetch('https://example.com/api/users', {
709-
headers: new Headers({
710-
authorization: 'Bearer secret-token'
711-
})
712-
})
713-
await new Promise(resolve => setTimeout(resolve, 10))
714-
715-
expect(notifyCallbacks.length).toBe(1)
716-
const event = notifyCallbacks[0].toJSON()
717-
const requestHeaders = event.request.headers
718-
const responseHeaders = event.response.headers
719-
720-
expect(requestHeaders?.authorization).toBe('[REDACTED]')
721-
expect(responseHeaders.authorization).toBe('[REDACTED]')
722-
})
723-
724-
it('should redact specified query parameters', async () => {
725-
const notifyCallbacks: Event[] = []
726-
727-
plugin = createPlugin({
728-
httpErrorCodes: { min: 400, max: 499 }
729-
})
730-
731-
const client = new Client({ apiKey: 'api_key', plugins: [plugin], redactedKeys: ['token'] })
732-
client._setDelivery(createMockDelivery(notifyCallbacks))
733-
734-
mockFetch.mockResolvedValue({
735-
ok: false,
736-
status: 404,
737-
url: 'https://example.com/api/users?token=secret-token&userId=123',
738-
headers: new Headers(),
739-
text: async () => 'Not found'
740-
})
741-
742-
await fetch('https://example.com/api/users?token=secret-token&userId=123')
743-
await new Promise(resolve => setTimeout(resolve, 10))
744-
745-
expect(notifyCallbacks.length).toBe(1)
746-
const event = notifyCallbacks[0].toJSON()
747-
const params = event.request.params
748-
749-
expect(params.token).toBe('[REDACTED]')
750-
expect(params.userId).toBe('123')
751-
})
752-
})
753685
})

test/browser/features/fixtures/http_errors/src/app.tsx

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,54 @@ import { apiKey, endpoints, plugins, REFLECT_ENDPOINT } from './lib/config'
55

66
Bugsnag.start({ apiKey, endpoints, plugins, redactedKeys: ['X-Token', 'userId'] })
77

8+
function xhrGet () {
9+
const xhr = new XMLHttpRequest()
10+
xhr.open('GET', `${REFLECT_ENDPOINT}?status=404&userId=12345`)
11+
xhr.setRequestHeader('X-Token', 'super-secret-token')
12+
xhr.send()
13+
}
14+
15+
function xhrPost () {
16+
const xhr = new XMLHttpRequest()
17+
xhr.open('POST', `${REFLECT_ENDPOINT}?status=403&userId=12345`)
18+
xhr.setRequestHeader('X-Token', 'super-secret-token')
19+
xhr.send('this is the request body')
20+
}
21+
22+
function fetchGet () {
23+
fetch(`${REFLECT_ENDPOINT}?status=401&userId=12345`, {
24+
headers: { 'x-token': 'super-secret-token' }
25+
})
26+
}
27+
28+
function fetchPost () {
29+
fetch(`${REFLECT_ENDPOINT}?status=408&userId=12345`, {
30+
method: 'POST',
31+
body: 'this is the request body',
32+
headers: { 'x-token': 'super-secret-token' }
33+
})
34+
}
35+
836
function App () {
937
useEffect(() => {
1038
const params = new URLSearchParams(window.location.search)
11-
const type = params.get('request') === 'xhr' ? 'xhr' : 'fetch'
1239

13-
switch(type) {
40+
switch(params.get('request')) {
1441
case 'xhr':
15-
const xhr = new XMLHttpRequest()
16-
xhr.open('GET', `${REFLECT_ENDPOINT}?status=404&userId=12345`)
17-
xhr.setRequestHeader('X-Token', 'super-secret-token')
18-
xhr.send()
42+
case 'xhr-get':
43+
xhrGet()
44+
break
45+
case 'xhr-post':
46+
xhrPost()
1947
break
2048
case 'fetch':
21-
default:
22-
fetch(`${REFLECT_ENDPOINT}?status=404&userId=12345`, { headers: { 'x-token': 'super-secret-token' }})
49+
case 'fetch-get':
50+
fetchGet()
51+
break
52+
case 'fetch-post':
53+
fetchPost()
2354
break
55+
default:
2456
}
2557

2658
}, [])

test/browser/features/http_errors.feature

Lines changed: 73 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ Feature: HTTP Errors
44
HTTP errors plugin reports network request failures, including those made using fetch, and xml http requests.
55

66
@requires_fetch
7-
Scenario: Fetch request
7+
Scenario: Fetch Request - GET
88
When I navigate to the test URL "/http_errors?request=fetch"
99
And I wait to receive an error
1010
Then the error is a valid browser payload for the error reporting API
1111

1212
And I define "expected.context" as "GET <browser.hostname>"
13-
And I define "expected.exception.message" as "404: <browser.url>/reflect?status=404&userId=[REDACTED]"
14-
And I define "expected.request.url" as "<browser.url>/reflect?status=404&userId=[REDACTED]"
13+
And I define "expected.exception.message" as "401: <browser.url>/reflect?status=401&userId=[REDACTED]"
14+
And I define "expected.request.url" as "<browser.url>/reflect?status=401&userId=[REDACTED]"
1515

1616
And the exception "errorClass" equals "HTTPError"
1717
And the error payload field "events.0.exceptions.0.message" equals the stored value "expected.exception.message"
@@ -22,20 +22,52 @@ Feature: HTTP Errors
2222

2323
And the error payload field "events.0.request.url" equals the stored value "expected.request.url"
2424
And the event "request.httpMethod" equals "GET"
25-
And the event "request.params.status" equals "404"
25+
And the event "request.params.status" equals "401"
2626
And the event "request.params.userId" equals "[REDACTED]"
2727
And the event "request.headers.x-token" equals "[REDACTED]"
28-
And the event "request.body" equals ""
29-
And the event "request.bodyLength" equals 0
28+
And the event "request.body" is null
29+
And the event "request.bodyLength" is null
3030

31-
And the event "response.statusCode" equals 404
31+
And the event "response.statusCode" equals 401
3232
And the event "response.headers.content-length" equals "37"
33+
34+
# Response body is not captured for fetch requests
35+
And the event "response.body" is null
36+
And the event "response.bodyLength" is null
37+
38+
Scenario: Fetch Request - POST
39+
When I navigate to the test URL "/http_errors?request=fetch-post"
40+
And I wait to receive an error
41+
Then the error is a valid browser payload for the error reporting API
42+
43+
And I define "expected.context" as "POST <browser.hostname>"
44+
And I define "expected.exception.message" as "408: <browser.url>/reflect?status=408&userId=[REDACTED]"
45+
And I define "expected.request.url" as "<browser.url>/reflect?status=408&userId=[REDACTED]"
46+
47+
And the exception "errorClass" equals "HTTPError"
48+
And the error payload field "events.0.exceptions.0.message" equals the stored value "expected.exception.message"
49+
And the event "severity" equals "error"
50+
And the event "unhandled" is true
51+
And the event "severityReason.type" equals "httpError"
52+
And the error payload field "events.0.context" equals the stored value "expected.context"
53+
54+
And the error payload field "events.0.request.url" equals the stored value "expected.request.url"
55+
And the event "request.httpMethod" equals "POST"
56+
And the event "request.params.status" equals "408"
57+
And the event "request.params.userId" equals "[REDACTED]"
58+
And the event "request.headers.x-token" equals "[REDACTED]"
59+
And the event "request.body" equals "this is the request body"
60+
And the event "request.bodyLength" equals 24
61+
62+
And the event "response.statusCode" equals 408
63+
And the event "response.headers.content-length" equals "37"
64+
3365
# Response body is not captured for fetch requests
3466
And the event "response.body" is null
3567
And the event "response.bodyLength" is null
3668

3769
@requires_xml_http_request
38-
Scenario: XML HTTP Request
70+
Scenario: XHR - GET
3971
When I navigate to the test URL "/http_errors?request=xhr"
4072
And I wait to receive an error
4173
Then the error is a valid browser payload for the error reporting API
@@ -56,10 +88,40 @@ Feature: HTTP Errors
5688
And the event "request.headers.X-Token" equals "[REDACTED]"
5789
And the event "request.params.status" equals "404"
5890
And the event "request.params.userId" equals "[REDACTED]"
59-
And the event "request.body" equals ""
60-
And the event "request.bodyLength" equals 0
91+
And the event "request.body" is null
92+
And the event "request.bodyLength" is null
6193

6294
And the event "response.statusCode" equals 404
6395
And the event "response.headers.content-length" equals "37"
6496
And the event "response.body" equals "Returned status 404 after waiting ms"
65-
And the event "response.bodyLength" equals 37
97+
And the event "response.bodyLength" equals 37
98+
99+
@requires_xml_http_request
100+
Scenario: XHR - POST
101+
When I navigate to the test URL "/http_errors?request=xhr-post"
102+
And I wait to receive an error
103+
Then the error is a valid browser payload for the error reporting API
104+
105+
And I define "expected.context" as "POST <browser.hostname>"
106+
And I define "expected.exception.message" as "403: <browser.url>/reflect?status=403&userId=[REDACTED]"
107+
And I define "expected.request.url" as "<browser.url>/reflect?status=403&userId=[REDACTED]"
108+
109+
And the exception "errorClass" equals "HTTPError"
110+
And the error payload field "events.0.exceptions.0.message" equals the stored value "expected.exception.message"
111+
And the event "severity" equals "error"
112+
And the event "unhandled" is true
113+
And the event "severityReason.type" equals "httpError"
114+
And the error payload field "events.0.context" equals the stored value "expected.context"
115+
116+
And the error payload field "events.0.request.url" equals the stored value "expected.request.url"
117+
And the event "request.httpMethod" equals "POST"
118+
And the event "request.headers.X-Token" equals "[REDACTED]"
119+
And the event "request.params.status" equals "403"
120+
And the event "request.params.userId" equals "[REDACTED]"
121+
And the event "request.body" equals "this is the request body"
122+
And the event "request.bodyLength" equals 24
123+
124+
And the event "response.statusCode" equals 403
125+
And the event "response.headers.content-length" equals "37"
126+
And the event "response.body" equals "Returned status 403 after waiting ms"
127+
And the event "response.bodyLength" equals 37

0 commit comments

Comments
 (0)