Summary: It's common for responses to be completely missing in the network inspector. This is because they are larger than can be serialized in one go on some devices, so we drop all messages larger than 1MB. This changes the android client to send large responses in individually serialized batches. This way we avoid running out of memory and can still send arbitrarily large payloads. Changelog: Android network inspector can now handle responses large than 1MB. Reviewed By: passy Differential Revision: D22999905 fbshipit-source-id: ff4eb8fa72a7e42ea90d12ffe0f20c6d1e58b7e5
128 lines
2.9 KiB
TypeScript
128 lines
2.9 KiB
TypeScript
/**
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* @format
|
|
*/
|
|
|
|
import {combineBase64Chunks} from '../chunks';
|
|
import network from '../index';
|
|
import {PersistedState} from '../types';
|
|
|
|
test('Test assembling base64 chunks', () => {
|
|
const message = 'wassup john?';
|
|
const chunks = message.match(/.{1,2}/g)?.map(btoa);
|
|
|
|
if (chunks === undefined) {
|
|
throw new Error('invalid chunks');
|
|
}
|
|
|
|
const output = combineBase64Chunks(chunks);
|
|
expect(output).toBe('wassup john?');
|
|
});
|
|
|
|
test('Reducer correctly adds initial chunk', () => {
|
|
const state: PersistedState = {
|
|
requests: {},
|
|
responses: {},
|
|
partialResponses: {},
|
|
};
|
|
const result = network.persistedStateReducer(state, 'partialResponse', {
|
|
id: '1',
|
|
timestamp: 123,
|
|
status: 200,
|
|
data: 'hello',
|
|
reason: 'nothing',
|
|
headers: [],
|
|
isMock: false,
|
|
insights: null,
|
|
index: 0,
|
|
totalChunks: 2,
|
|
});
|
|
expect(result.partialResponses['1']).toMatchInlineSnapshot(`
|
|
Object {
|
|
"followupChunks": Object {},
|
|
"initialResponse": Object {
|
|
"data": "hello",
|
|
"headers": Array [],
|
|
"id": "1",
|
|
"index": 0,
|
|
"insights": null,
|
|
"isMock": false,
|
|
"reason": "nothing",
|
|
"status": 200,
|
|
"timestamp": 123,
|
|
"totalChunks": 2,
|
|
},
|
|
}
|
|
`);
|
|
});
|
|
|
|
test('Reducer correctly adds followup chunk', () => {
|
|
const state: PersistedState = {
|
|
requests: {},
|
|
responses: {},
|
|
partialResponses: {},
|
|
};
|
|
const result = network.persistedStateReducer(state, 'partialResponse', {
|
|
id: '1',
|
|
totalChunks: 2,
|
|
index: 1,
|
|
data: 'hello',
|
|
});
|
|
expect(result.partialResponses['1']).toMatchInlineSnapshot(`
|
|
Object {
|
|
"followupChunks": Object {
|
|
"1": "hello",
|
|
},
|
|
}
|
|
`);
|
|
});
|
|
|
|
test('Reducer correctly combines initial response and followup chunk', () => {
|
|
const state: PersistedState = {
|
|
requests: {},
|
|
responses: {},
|
|
partialResponses: {
|
|
'1': {
|
|
followupChunks: {},
|
|
initialResponse: {
|
|
data: 'aGVs',
|
|
headers: [],
|
|
id: '1',
|
|
insights: null,
|
|
isMock: false,
|
|
reason: 'nothing',
|
|
status: 200,
|
|
timestamp: 123,
|
|
index: 0,
|
|
totalChunks: 2,
|
|
},
|
|
},
|
|
},
|
|
};
|
|
const result = network.persistedStateReducer(state, 'partialResponse', {
|
|
id: '1',
|
|
totalChunks: 2,
|
|
index: 1,
|
|
data: 'bG8=',
|
|
});
|
|
expect(result.partialResponses).toEqual({});
|
|
expect(result.responses['1']).toMatchInlineSnapshot(`
|
|
Object {
|
|
"data": "aGVsbG8=",
|
|
"headers": Array [],
|
|
"id": "1",
|
|
"index": 0,
|
|
"insights": null,
|
|
"isMock": false,
|
|
"reason": "nothing",
|
|
"status": 200,
|
|
"timestamp": 123,
|
|
"totalChunks": 2,
|
|
}
|
|
`);
|
|
});
|