Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions static/app/components/events/interfaces/request/index.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
import {DataScrubbingRelayPiiConfigFixture} from 'sentry-fixture/dataScrubbingRelayPiiConfig';
import {EventFixture} from 'sentry-fixture/event';
import {UserFixture} from 'sentry-fixture/user';

import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
import {textWithMarkupMatcher} from 'sentry-test/utils';

import {Request} from 'sentry/components/events/interfaces/request';
import ConfigStore from 'sentry/stores/configStore';
import type {EntryRequest} from 'sentry/types/event';
import {EntryType} from 'sentry/types/event';

jest.unmock('prismjs');

describe('Request entry', function () {
beforeEach(() => {
ConfigStore.set('user', UserFixture());
});

it('display redacted data', async function () {
const event = EventFixture({
entries: [
Expand Down Expand Up @@ -327,6 +333,38 @@ describe('Request entry', function () {
).not.toThrow();
});

it('should remove any non-tuple values from array', function () {
const user = UserFixture();
user.options.prefersIssueDetailsStreamlinedUI = true;
ConfigStore.set('user', user);

const data: EntryRequest['data'] = {
apiTarget: null,
query: 'a%AFc',
data: '',
headers: [['foo', 'bar'], null],
cookies: [],
env: {},
method: 'POST',
url: '/Home/PostIndex',
};
const event = EventFixture({
entries: [
{
type: EntryType.REQUEST,
data,
},
],
});
expect(() =>
render(<Request event={event} data={event.entries[0].data} />, {
organization: {
relayPiiConfig: JSON.stringify(DataScrubbingRelayPiiConfigFixture()),
},
})
).not.toThrow();
});

it("should not cause an invariant violation if data.data isn't a string", function () {
const data: EntryRequest['data'] = {
apiTarget: null,
Expand Down
11 changes: 7 additions & 4 deletions static/app/components/events/interfaces/request/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -251,10 +251,13 @@ function RequestDataCard({
const contentItems: KeyValueDataContentProps[] = [];

if (Array.isArray(data) && data.length > 0) {
data.forEach(([key, value], i: number) => {
const valueMeta = meta?.[i] ? meta[i]?.[1] : undefined;
contentItems.push({item: {key, subject: key, value}, meta: valueMeta});
});
data
// Remove any non-tuple values
.filter(x => Array.isArray(x))
.forEach(([key, value], i: number) => {
const valueMeta = meta?.[i] ? meta[i]?.[1] : undefined;
contentItems.push({item: {key, subject: key, value}, meta: valueMeta});
});
} else if (typeof data === 'object') {
// Spread to flatten if it's a proxy
Object.entries({...data}).forEach(([key, value]) => {
Expand Down
20 changes: 11 additions & 9 deletions static/app/components/events/interfaces/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,22 +125,22 @@ export function getCurlCommand(data: EntryRequest['data']) {
result += ' \\\n -X ' + data.method;
}

data.headers = data.headers?.filter(defined);
const headers =
data.headers
?.filter(defined)
// sort headers
.sort(function (a, b) {
return a[0] === b[0] ? 0 : a[0] < b[0] ? -1 : 1;
}) ?? [];

// TODO(benvinegar): just gzip? what about deflate?
const compressed = data.headers?.find(
const compressed = headers?.find(
h => h[0] === 'Accept-Encoding' && h[1].includes('gzip')
);
if (compressed) {
result += ' \\\n --compressed';
}

// sort headers
const headers =
data.headers?.sort(function (a, b) {
return a[0] === b[0] ? 0 : a[0] < b[0] ? -1 : 1;
}) ?? [];

for (const header of headers) {
result += ' \\\n -H "' + header[0] + ': ' + escapeBashString(header[1] + '') + '"';
}
Expand Down Expand Up @@ -172,7 +172,9 @@ export function getCurlCommand(data: EntryRequest['data']) {
return result;
}

export function stringifyQueryList(query: string | [key: string, value: string][]) {
export function stringifyQueryList(
query: string | Array<[key: string, value: string] | null>
) {
if (typeof query === 'string') {
return query;
}
Expand Down
6 changes: 3 additions & 3 deletions static/app/types/event.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -336,17 +336,17 @@ export interface EntryRequestDataDefault {
apiTarget: null;
method: string;
url: string;
cookies?: [key: string, value: string][];
cookies?: Array<[key: string, value: string] | null>;
data?: string | null | Record<string, any> | [key: string, value: any][];
env?: Record<string, string>;
fragment?: string | null;
headers?: [key: string, value: string][];
headers?: Array<[key: string, value: string] | null>;
inferredContentType?:
| null
| 'application/json'
| 'application/x-www-form-urlencoded'
| 'multipart/form-data';
query?: [key: string, value: string][] | string;
query?: Array<[key: string, value: string] | null> | string;
}

export interface EntryRequestDataGraphQl
Expand Down
Loading