Flatten threads: fix for application/json+protobuf responses
When a new message is created in a thread, the thread itself is
reloaded, but via an application/json+protobuf request (array-like data)
instead of a regular text/plain request (object-like data). Since the
code didn't work well for these types of requests, the thread didn't
fully load.
This CL fixes this issue by correctly handling application/json+protobuf
responses in the response modifiers.
An issue with the read-only interceptors has also been fixed, and tests
have been added to ensure that the array-like to object-like and
viceversa transformation functions work properly.
Bug: twpowertools:153
Change-Id: If6cd5adc67d676bf36986f325e791124fa71da51
diff --git a/src/xhrInterceptor/XHRProxy.js b/src/xhrInterceptor/XHRProxy.js
index 6254fbf..288142a 100644
--- a/src/xhrInterceptor/XHRProxy.js
+++ b/src/xhrInterceptor/XHRProxy.js
@@ -42,7 +42,7 @@
this.xhr.addEventListener(eventName, function() {
let p;
if (eventName === 'load') {
- p = classThis.responseModifier.intercept(proxyThis, this.response).then(() => {
+ p = classThis.responseModifier.intercept(proxyThis).then(() => {
proxyThis.$responseIntercepted = true;
});
} else {
@@ -82,7 +82,12 @@
utils.matchInterceptors('response', this.$TWPTRequestURL);
if (interceptors.length > 0) {
this.xhr.addEventListener('load', function() {
- var body = utils.getResponseJSON(proxyThis);
+ var body = utils.getResponseJSON({
+ responseType: proxyThis.xhr.responseType,
+ response: proxyThis.xhr.response,
+ $TWPTRequestURL: proxyThis.$TWPTRequestURL,
+ $isArrayProto: proxyThis.$isArrayProto,
+ });
if (body !== undefined)
interceptors.forEach(i => {
utils.triggerEvent(i.eventName, body, proxyThis.$TWPTID);
diff --git a/src/xhrInterceptor/responseModifiers/flattenThread.js b/src/xhrInterceptor/responseModifiers/flattenThread.js
index 6828772..23db6eb 100644
--- a/src/xhrInterceptor/responseModifiers/flattenThread.js
+++ b/src/xhrInterceptor/responseModifiers/flattenThread.js
@@ -71,13 +71,13 @@
}
let prevId;
- if (parentId === prevReplyParentId && prevReplyParentId)
+ if (parentId == prevReplyParentId && prevReplyParentId)
prevId = prevReplyId;
else
prevId = parentId;
const prevMessage =
- prevId ? mogs.find(m => m.getId() === prevId) : null;
+ prevId ? mogs.find(m => m.getId() == prevId) : null;
return {
isComment: true,
@@ -86,8 +86,8 @@
parentId,
prevMessage: {
id: prevId,
- payload: prevMessage.getPayload(),
- author: prevMessage.getAuthor(),
+ payload: prevMessage?.getPayload(),
+ author: prevMessage?.getAuthor(),
},
};
}
diff --git a/src/xhrInterceptor/responseModifiers/index.js b/src/xhrInterceptor/responseModifiers/index.js
index 2d0b7ce..43ffe6c 100644
--- a/src/xhrInterceptor/responseModifiers/index.js
+++ b/src/xhrInterceptor/responseModifiers/index.js
@@ -54,11 +54,11 @@
});
}
- async intercept(request, response) {
+ async intercept(request) {
const matchingModifiers = await this.#getMatchingModifiers(request);
// If we didn't find any matching modifiers, return the response right away.
- if (matchingModifiers.length === 0) return response;
+ if (matchingModifiers.length === 0) return request.xhr.response;
// Otherwise, apply the modifiers sequentially and set the new response.
let json = getResponseJSON({
@@ -70,7 +70,7 @@
for (const modifier of matchingModifiers) {
json = await modifier.interceptor(request, json);
}
- response = convertJSONToResponse(request, json);
+ const response = convertJSONToResponse(request, json);
request.$newResponse = response;
request.$responseModified = true;
}
diff --git a/src/xhrInterceptor/responseModifiers/loadMoreThread.js b/src/xhrInterceptor/responseModifiers/loadMoreThread.js
index f8da127..abea505 100644
--- a/src/xhrInterceptor/responseModifiers/loadMoreThread.js
+++ b/src/xhrInterceptor/responseModifiers/loadMoreThread.js
@@ -38,8 +38,9 @@
}
const messageOrGapPromises = [];
- messageOrGapPromises.push(Promise.resolve(mogs));
- for (const mog of mogs) {
+ messageOrGapPromises.push(
+ Promise.resolve(mogs.filter(mog => mog !== undefined)));
+ mogs.forEach(mog => {
if (mog instanceof GapModel) {
messageOrGapPromises.push(this.loadGap(forumId, threadId, mog));
}
@@ -50,7 +51,7 @@
}
});
}
- }
+ });
return Promise.all(messageOrGapPromises).then(res => {
// #!if !production
@@ -60,6 +61,7 @@
// #!if !production
console.timeEnd('mergeMessages');
// #!endif
+
if (mogs.some(mog => {
return mog instanceof GapModel ||
mog.getCommentsAndGaps().some(cog => cog instanceof GapModel);