Skip to content

Commit b7348ab

Browse files
committed
tests
1 parent bc5b5b1 commit b7348ab

File tree

1 file changed

+103
-2
lines changed

1 file changed

+103
-2
lines changed

packages/bundler-plugin-core/test/build-plugin-manager.test.ts

Lines changed: 103 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,46 @@
11
import { createSentryBuildPluginManager } from "../src/build-plugin-manager";
2+
import fs from "fs";
3+
import { glob } from "glob";
4+
import { prepareBundleForDebugIdUpload } from "../src/debug-id-upload";
25

36
const mockCliExecute = jest.fn();
7+
const mockCliUploadSourceMaps = jest.fn();
8+
49
jest.mock("@sentry/cli", () => {
510
return jest.fn().mockImplementation(() => ({
611
execute: mockCliExecute,
12+
releases: {
13+
uploadSourceMaps: mockCliUploadSourceMaps,
14+
new: jest.fn(),
15+
finalize: jest.fn(),
16+
setCommits: jest.fn(),
17+
newDeploy: jest.fn(),
18+
},
719
}));
820
});
921

1022
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
1123
jest.mock("../src/sentry/telemetry", () => ({
24+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
1225
...jest.requireActual("../src/sentry/telemetry"),
1326
safeFlushTelemetry: jest.fn(),
1427
}));
1528

1629
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
1730
jest.mock("@sentry/core", () => ({
31+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
1832
...jest.requireActual("@sentry/core"),
19-
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-return
20-
startSpan: jest.fn((options, callback) => callback()),
33+
startSpan: jest.fn((options: unknown, callback: () => unknown) => callback()),
2134
}));
2235

36+
jest.mock("glob");
37+
jest.mock("../src/debug-id-upload");
38+
39+
const mockGlob = glob as jest.MockedFunction<typeof glob>;
40+
const mockPrepareBundleForDebugIdUpload = prepareBundleForDebugIdUpload as jest.MockedFunction<
41+
typeof prepareBundleForDebugIdUpload
42+
>;
43+
2344
describe("createSentryBuildPluginManager", () => {
2445
beforeEach(() => {
2546
jest.clearAllMocks();
@@ -73,6 +94,86 @@ describe("createSentryBuildPluginManager", () => {
7394
});
7495
});
7596

97+
describe("uploadSourcemaps", () => {
98+
it("uploads in-place when prepareArtifacts is false", async () => {
99+
mockCliUploadSourceMaps.mockResolvedValue(undefined);
100+
101+
// Return a mixture of files/dirs; in-place path should pass through as-is
102+
mockGlob.mockResolvedValue(["/app/dist/a.js", "/app/dist/dir", "/app/dist/a.js.map"]);
103+
104+
const manager = createSentryBuildPluginManager(
105+
{
106+
authToken: "t",
107+
org: "o",
108+
project: "p",
109+
release: { name: "some-release-name", dist: "1" },
110+
sourcemaps: { assets: ["/app/dist/**/*"] },
111+
},
112+
{ buildTool: "webpack", loggerPrefix: "[sentry-webpack-plugin]" }
113+
);
114+
115+
await manager.uploadSourcemaps(["/unused"], { prepareArtifacts: false });
116+
117+
expect(mockCliUploadSourceMaps).toHaveBeenCalledTimes(1);
118+
expect(mockCliUploadSourceMaps).toHaveBeenCalledWith(
119+
"some-release-name",
120+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
121+
expect.objectContaining({
122+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
123+
include: expect.arrayContaining([
124+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
125+
expect.objectContaining({
126+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
127+
paths: expect.arrayContaining([
128+
"/app/dist/a.js",
129+
"/app/dist/dir",
130+
"/app/dist/a.js.map",
131+
]),
132+
rewrite: false,
133+
dist: "1",
134+
}),
135+
]),
136+
live: "rejectOnError",
137+
})
138+
);
139+
expect(mockPrepareBundleForDebugIdUpload).not.toHaveBeenCalled();
140+
});
141+
142+
it("prepares into temp folder and uploads when prepareArtifacts is true (default)", async () => {
143+
mockCliUploadSourceMaps.mockResolvedValue(undefined);
144+
145+
mockGlob.mockResolvedValue(["/app/dist/a.js", "/app/dist/a.js.map", "/app/dist/other.txt"]);
146+
147+
jest.spyOn(fs.promises, "mkdtemp").mockResolvedValue("/tmp/sentry-upload-xyz");
148+
jest.spyOn(fs.promises, "readdir").mockResolvedValue(["a.js", "a.js.map"] as never);
149+
jest.spyOn(fs.promises, "stat").mockResolvedValue({ size: 10 } as fs.Stats);
150+
jest.spyOn(fs.promises, "rm").mockResolvedValue(undefined as never);
151+
152+
mockPrepareBundleForDebugIdUpload.mockResolvedValue(undefined);
153+
154+
const manager = createSentryBuildPluginManager(
155+
{
156+
authToken: "t",
157+
org: "o",
158+
project: "p",
159+
release: { name: "some-release-name", dist: "1" },
160+
sourcemaps: { assets: ["/app/dist/**/*"] },
161+
},
162+
{ buildTool: "webpack", loggerPrefix: "[sentry-webpack-plugin]" }
163+
);
164+
165+
await manager.uploadSourcemaps(["/unused"]);
166+
167+
// Should call prepare for each JS chunk discovered by glob
168+
expect(mockPrepareBundleForDebugIdUpload).toHaveBeenCalled();
169+
// Should upload from temp folder
170+
expect(mockCliUploadSourceMaps).toHaveBeenCalledWith("some-release-name", {
171+
include: [{ paths: ["/tmp/sentry-upload-xyz"], rewrite: false, dist: "1" }],
172+
live: "rejectOnError",
173+
});
174+
});
175+
});
176+
76177
describe("injectDebugIds", () => {
77178
it("should call CLI with correct sourcemaps inject command", async () => {
78179
mockCliExecute.mockResolvedValue(undefined);

0 commit comments

Comments
 (0)