Skip to content

Commit efb08b8

Browse files
committed
Update test.js
1 parent 0cdcccb commit efb08b8

1 file changed

Lines changed: 70 additions & 14 deletions

File tree

  • src/sentry/javascript/bridge

src/sentry/javascript/bridge/test.js

Lines changed: 70 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ try {
6060
"scopeSetFingerprint",
6161
"scopeSetUser",
6262
"scopeAddBytesAttachment",
63+
"scopeAddFileAttachment",
6364
"scopeClear",
6465
"logTrace",
6566
"logDebug",
@@ -72,8 +73,8 @@ try {
7273
"lastEventId",
7374
"addBreadcrumb",
7475
"addBytesAttachment",
76+
"addFileAttachment",
7577
"clearAttachments",
76-
"pushAttachmentData",
7778
"storeBytes",
7879
"takeBytes",
7980
"releaseBytes",
@@ -110,8 +111,24 @@ try {
110111

111112
console.log("\n🧪 Functional tests:");
112113

114+
// Stands in for the C++ layer: hands back fixed bytes, leaving "user://missing.txt" unread like a missing file.
115+
const readAttachmentPaths = [];
116+
const readAttachment = (request) => {
117+
readAttachmentPaths.push(request.path);
118+
if (request.path !== "user://missing.txt") {
119+
request.data = new Uint8Array([ 1, 2, 3, 4 ]);
120+
}
121+
};
122+
113123
runTest("init()", () => {
114-
bridge.init(() => {}, null, null, "https://test@sentry.io/123", false, "1.0.0", "1", "production", 1.0, 100, false, false, false, "0.1.0");
124+
bridge.init(() => {}, null, null, readAttachment, "https://test@sentry.io/123", false, "1.0.0", "1", "production", 1.0, 100, false, false, false, "0.1.0");
125+
});
126+
127+
// Observes what actually goes out with an event. The bridge registers its own handler during
128+
// init() and handlers run in registration order, so this one sees the resolved and filtered list.
129+
const sentAttachments = [];
130+
bridge.createScope().getClient().on("beforeSendEvent", (_event, hint) => {
131+
sentAttachments.push(hint?.attachments ?? []);
115132
});
116133

117134
runTest("isEnabled()", () => {
@@ -229,6 +246,47 @@ try {
229246
assertEqual(attachments[0].data.length, 3, "scopeAddBytesAttachment should carry the bytes");
230247
});
231248

249+
runTest("scopeAddFileAttachment()", () => {
250+
const scope = bridge.createScope();
251+
bridge.scopeAddFileAttachment(scope, "user://save.dat", "save.dat", "application/octet-stream", "");
252+
const attachments = scope.getScopeData().attachments;
253+
assertEqual(attachments.length, 1, "scopeAddFileAttachment should add the attachment to the scope");
254+
assertEqual(attachments[0].filename, "save.dat", "scopeAddFileAttachment should set the filename");
255+
assertEqual(attachments[0].data.length, 0, "scopeAddFileAttachment should leave the bytes for capture time");
256+
assertEqual(attachments[0].__godotPath, "user://save.dat",
257+
"scopeAddFileAttachment should mark the attachment with the path to read at capture time");
258+
});
259+
260+
runTest("file attachments resolve on capture", () => {
261+
const scope = bridge.createScope();
262+
bridge.scopeAddFileAttachment(scope, "user://save.dat", "save.dat", "application/octet-stream", "");
263+
264+
const readCountBefore = readAttachmentPaths.length;
265+
bridge.captureEvent({ message : "Event with a file attachment" }, scope);
266+
assertEqual(readAttachmentPaths.length, readCountBefore + 1, "captureEvent should read the file once");
267+
assertEqual(readAttachmentPaths[readAttachmentPaths.length - 1], "user://save.dat", "captureEvent should read the attachment path");
268+
269+
const sent = sentAttachments[sentAttachments.length - 1];
270+
assertEqual(sent.length, 1, "captureEvent should send the resolved attachment");
271+
assertEqual(sent[0].data.length, 4, "the sent attachment should carry the bytes that were read");
272+
assertEqual(sent[0].filename, "save.dat", "resolving should keep the filename");
273+
assertEqual(sent[0].__godotPath, undefined, "the path marker should not be sent with the event");
274+
275+
const kept = scope.getScopeData().attachments[0];
276+
assertEqual(kept.data.length, 0, "the scope's own attachment should not keep the bytes");
277+
assertEqual(kept.__godotPath, "user://save.dat",
278+
"the scope should keep the path so the next capture reads the file again");
279+
});
280+
281+
runTest("unreadable file attachments are dropped", () => {
282+
const scope = bridge.createScope();
283+
bridge.scopeAddFileAttachment(scope, "user://missing.txt", "missing.txt", "", "");
284+
bridge.captureEvent({ message : "Event with a missing file attachment" }, scope);
285+
286+
const sent = sentAttachments[sentAttachments.length - 1];
287+
assertEqual(sent.length, 0, "an attachment the C++ layer could not read should not be sent");
288+
});
289+
232290
runTest("scopeClear()", () => {
233291
const scope = bridge.createScope();
234292
bridge.scopeSetContext(scope, "test-context", '{"key": "value"}');
@@ -306,19 +364,17 @@ try {
306364
assertEqual(bridge.takeBytes(id), undefined, "releaseBytes should discard bytes");
307365
});
308366

309-
runTest("pushAttachmentData()", () => {
310-
const attachments = [];
311-
bridge.pushAttachmentData(attachments, new Uint8Array([ 1, 2, 3 ]), "test.bin", "application/octet-stream", "event.attachment");
312-
assertEqual(attachments.length, 1, "should push one attachment");
313-
assertEqual(attachments[0].filename, "test.bin", "filename should match");
314-
assertEqual(attachments[0].bytes.length, 3, "bytes length should match");
315-
assertEqual(attachments[0].contentType, "application/octet-stream", "contentType should match");
316-
assertEqual(attachments[0].attachmentType, "event.attachment", "attachmentType should match");
367+
// Globally added file attachments go through the same resolution as the scoped ones above.
368+
runTest("addFileAttachment()", () => {
369+
bridge.addFileAttachment("user://global.dat", "global.dat", "application/json", "event.view_hierarchy");
370+
bridge.captureEvent({ message : "Event with a global file attachment" }, bridge.createScope());
317371

318-
bridge.pushAttachmentData(attachments, new Uint8Array([ 4, 5 ]), "test2.bin");
319-
assertEqual(attachments.length, 2, "should push second attachment");
320-
assertEqual(attachments[1].contentType, undefined, "optional contentType should be undefined");
321-
assertEqual(attachments[1].attachmentType, undefined, "optional attachmentType should be undefined");
372+
const sent = sentAttachments[sentAttachments.length - 1];
373+
const globalAttachment = sent.find((attachment) => attachment.filename === "global.dat");
374+
assert(globalAttachment, "addFileAttachment should send the attachment with the event");
375+
assertEqual(globalAttachment.data.length, 4, "the global attachment should carry the bytes that were read");
376+
assertEqual(globalAttachment.contentType, "application/json", "addFileAttachment should set the content type");
377+
assertEqual(globalAttachment.attachmentType, "event.view_hierarchy", "addFileAttachment should set the attachment type");
322378
});
323379

324380
runTest("addBytesAttachment()", () => {

0 commit comments

Comments
 (0)