-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
139 additions
and
139 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,220 +1,220 @@ | ||
import fs from "node:fs"; | ||
import fsPromises from "node:fs/promises"; | ||
import maybeGetSnarkArtifactsBrowser from "../src/download/index.browser"; | ||
import maybeGetSnarkArtifacts from "../src/download/index.node"; | ||
import { getAvailableVersions } from "../src/download/urls"; | ||
import { Project } from "../src/projects"; | ||
|
||
const version = "1.0.0-beta.1"; | ||
|
||
describe("getAvailableVersions", () => { | ||
it("Should return available versions", async () => { | ||
const versions = await getAvailableVersions(Project.POSEIDON); | ||
|
||
expect(versions).toContain(version); | ||
}, 20_000); | ||
}); | ||
|
||
describe("maybeGetSnarkArtifacts", () => { | ||
describe("browser", () => { | ||
it("Should return valid urls", async () => { | ||
import fs from 'node:fs' | ||
import fsPromises from 'node:fs/promises' | ||
import maybeGetSnarkArtifactsBrowser from '../src/download/index.browser' | ||
import maybeGetSnarkArtifacts from '../src/download/index.node' | ||
import { getAvailableVersions } from '../src/download/urls' | ||
import { Project } from '../src/projects' | ||
|
||
const version = '1.0.0-beta.1' | ||
|
||
describe('getAvailableVersions', () => { | ||
it('Should return available versions', async () => { | ||
const versions = await getAvailableVersions(Project.POSEIDON) | ||
|
||
expect(versions).toContain(version) | ||
}, 20_000) | ||
}) | ||
|
||
describe('maybeGetSnarkArtifacts', () => { | ||
describe('browser', () => { | ||
it('Should return valid urls', async () => { | ||
const { wasm, zkey } = await maybeGetSnarkArtifactsBrowser( | ||
Project.POSEIDON, | ||
{ | ||
parameters: ["2"], | ||
parameters: ['2'], | ||
version, | ||
} | ||
); | ||
}, | ||
) | ||
|
||
console.log({ wasm, zkey }); | ||
await expect(fetch(wasm)).resolves.toHaveProperty("ok", true); | ||
await expect(fetch(zkey)).resolves.toHaveProperty("ok", true); | ||
}, 20_000); | ||
console.log({ wasm, zkey }) | ||
await expect(fetch(wasm)).resolves.toHaveProperty('ok', true) | ||
await expect(fetch(zkey)).resolves.toHaveProperty('ok', true) | ||
}, 20_000) | ||
|
||
it("should throw if the project is not supported", async () => { | ||
it('should throw if the project is not supported', async () => { | ||
await expect( | ||
maybeGetSnarkArtifactsBrowser("project" as Project, { | ||
parameters: ["2"], | ||
version: "latest", | ||
}) | ||
).rejects.toThrow("Project 'project' is not supported"); | ||
}); | ||
|
||
it("should throw if the version is not available", async () => { | ||
maybeGetSnarkArtifactsBrowser('project' as Project, { | ||
parameters: ['2'], | ||
version: 'latest', | ||
}), | ||
).rejects.toThrow("Project 'project' is not supported") | ||
}) | ||
|
||
it('should throw if the version is not available', async () => { | ||
await expect( | ||
maybeGetSnarkArtifactsBrowser(Project.POSEIDON, { | ||
parameters: ["2"], | ||
version: "0.1.0-beta", | ||
}) | ||
parameters: ['2'], | ||
version: '0.1.0-beta', | ||
}), | ||
).rejects.toThrowErrorMatchingInlineSnapshot( | ||
`"Version '0.1.0-beta' is not available for project 'poseidon'"` | ||
); | ||
}); | ||
`"Version '0.1.0-beta' is not available for project 'poseidon'"`, | ||
) | ||
}) | ||
|
||
it("Should return artifact file paths with parameters", async () => { | ||
it('Should return artifact file paths with parameters', async () => { | ||
const { wasm, zkey } = await maybeGetSnarkArtifactsBrowser( | ||
Project.POSEIDON, | ||
{ | ||
parameters: ["2"], | ||
} | ||
); | ||
parameters: ['2'], | ||
}, | ||
) | ||
|
||
expect(wasm).toMatchInlineSnapshot( | ||
`"https://snark-artifacts.pse.dev/poseidon/latest/poseidon-2.wasm"` | ||
); | ||
`"https://snark-artifacts.pse.dev/poseidon/latest/poseidon-2.wasm"`, | ||
) | ||
expect(zkey).toMatchInlineSnapshot( | ||
`"https://snark-artifacts.pse.dev/poseidon/latest/poseidon-2.zkey"` | ||
); | ||
}); | ||
`"https://snark-artifacts.pse.dev/poseidon/latest/poseidon-2.zkey"`, | ||
) | ||
}) | ||
|
||
it("Should return artifact files paths without parameters", async () => { | ||
it('Should return artifact files paths without parameters', async () => { | ||
const { wasm, zkey } = await maybeGetSnarkArtifactsBrowser( | ||
Project.SEMAPHORE | ||
); | ||
Project.SEMAPHORE, | ||
) | ||
|
||
expect(wasm).toMatchInlineSnapshot( | ||
`"https://snark-artifacts.pse.dev/semaphore/latest/semaphore.wasm"` | ||
); | ||
`"https://snark-artifacts.pse.dev/semaphore/latest/semaphore.wasm"`, | ||
) | ||
expect(zkey).toMatchInlineSnapshot( | ||
`"https://snark-artifacts.pse.dev/semaphore/latest/semaphore.zkey"` | ||
); | ||
}); | ||
}); | ||
`"https://snark-artifacts.pse.dev/semaphore/latest/semaphore.zkey"`, | ||
) | ||
}) | ||
}) | ||
|
||
describe("node", () => { | ||
let fetchSpy: jest.SpyInstance; | ||
let mkdirSpy: jest.SpyInstance; | ||
let createWriteStreamSpy: jest.SpyInstance; | ||
let existsSyncSpy: jest.SpyInstance; | ||
describe('node', () => { | ||
let fetchSpy: jest.SpyInstance | ||
let mkdirSpy: jest.SpyInstance | ||
let createWriteStreamSpy: jest.SpyInstance | ||
let existsSyncSpy: jest.SpyInstance | ||
|
||
beforeEach(() => { | ||
// @ts-expect-error non exhaustive mock of fetch | ||
fetchSpy = jest.spyOn(global, "fetch").mockResolvedValueOnce({ | ||
fetchSpy = jest.spyOn(global, 'fetch').mockResolvedValueOnce({ | ||
json: async () => ({ versions: { [version]: {} } }), | ||
}); | ||
createWriteStreamSpy = jest.spyOn(fs, "createWriteStream"); | ||
existsSyncSpy = jest.spyOn(fs, "existsSync"); | ||
mkdirSpy = jest.spyOn(fsPromises, "mkdir"); | ||
mkdirSpy.mockResolvedValue(undefined); | ||
}); | ||
}) | ||
createWriteStreamSpy = jest.spyOn(fs, 'createWriteStream') | ||
existsSyncSpy = jest.spyOn(fs, 'existsSync') | ||
mkdirSpy = jest.spyOn(fsPromises, 'mkdir') | ||
mkdirSpy.mockResolvedValue(undefined) | ||
}) | ||
|
||
afterEach(() => { | ||
jest.restoreAllMocks(); | ||
}); | ||
jest.restoreAllMocks() | ||
}) | ||
|
||
it("Should throw an error if the project is not supported", async () => { | ||
it('Should throw an error if the project is not supported', async () => { | ||
await expect( | ||
maybeGetSnarkArtifacts("project" as Project, { | ||
parameters: ["2"], | ||
version: "latest", | ||
}) | ||
).rejects.toThrow("Project 'project' is not supported"); | ||
maybeGetSnarkArtifacts('project' as Project, { | ||
parameters: ['2'], | ||
version: 'latest', | ||
}), | ||
).rejects.toThrow("Project 'project' is not supported") | ||
|
||
await expect( | ||
maybeGetSnarkArtifactsBrowser("project" as Project) | ||
).rejects.toThrow("Project 'project' is not supported"); | ||
}); | ||
maybeGetSnarkArtifactsBrowser('project' as Project), | ||
).rejects.toThrow("Project 'project' is not supported") | ||
}) | ||
|
||
it("Should throw on fetch errors", async () => { | ||
existsSyncSpy.mockReturnValue(false); | ||
it('Should throw on fetch errors', async () => { | ||
existsSyncSpy.mockReturnValue(false) | ||
fetchSpy.mockResolvedValueOnce({ | ||
ok: false, | ||
statusText: "TEST", | ||
url: "https://test.com", | ||
}); | ||
statusText: 'TEST', | ||
url: 'https://test.com', | ||
}) | ||
|
||
await expect( | ||
maybeGetSnarkArtifacts(Project.POSEIDON, { | ||
parameters: ["2"], | ||
version: "latest", | ||
}) | ||
parameters: ['2'], | ||
version: 'latest', | ||
}), | ||
).rejects.toThrowErrorMatchingInlineSnapshot( | ||
`"Failed to fetch https://snark-artifacts.pse.dev/poseidon/latest/poseidon-2.wasm: TEST"` | ||
); | ||
}); | ||
`"Failed to fetch https://snark-artifacts.pse.dev/poseidon/latest/poseidon-2.wasm: TEST"`, | ||
) | ||
}) | ||
|
||
it("Should throw if missing body", async () => { | ||
existsSyncSpy.mockReturnValue(false); | ||
it('Should throw if missing body', async () => { | ||
existsSyncSpy.mockReturnValue(false) | ||
fetchSpy.mockResolvedValueOnce({ | ||
ok: true, | ||
statusText: "OK", | ||
}); | ||
statusText: 'OK', | ||
}) | ||
|
||
await expect( | ||
maybeGetSnarkArtifacts(Project.POSEIDON, { | ||
parameters: ["2"], | ||
}) | ||
parameters: ['2'], | ||
}), | ||
).rejects.toThrowErrorMatchingInlineSnapshot( | ||
`"Failed to get response body"` | ||
); | ||
}); | ||
`"Failed to get response body"`, | ||
) | ||
}) | ||
|
||
it("Should throw on stream error", async () => { | ||
existsSyncSpy.mockReturnValue(false); | ||
it('Should throw on stream error', async () => { | ||
existsSyncSpy.mockReturnValue(false) | ||
const mockResponseStream = { | ||
body: { | ||
getReader: jest.fn(() => ({ | ||
read: jest | ||
.fn() | ||
.mockRejectedValueOnce(new Error("TEST STREAM ERROR")), | ||
.mockRejectedValueOnce(new Error('TEST STREAM ERROR')), | ||
})), | ||
}, | ||
ok: true, | ||
statusText: "OK", | ||
}; | ||
fetchSpy.mockResolvedValue(mockResponseStream); | ||
statusText: 'OK', | ||
} | ||
fetchSpy.mockResolvedValue(mockResponseStream) | ||
createWriteStreamSpy.mockReturnValue({ | ||
close: jest.fn(), | ||
end: jest.fn(), | ||
write: jest.fn(), | ||
}); | ||
}) | ||
|
||
await expect( | ||
maybeGetSnarkArtifacts(Project.POSEIDON, { | ||
parameters: ["2"], | ||
}) | ||
).rejects.toThrowErrorMatchingInlineSnapshot(`"TEST STREAM ERROR"`); | ||
}); | ||
parameters: ['2'], | ||
}), | ||
).rejects.toThrowErrorMatchingInlineSnapshot(`"TEST STREAM ERROR"`) | ||
}) | ||
|
||
it("Should download files only if don't exist yet", async () => { | ||
existsSyncSpy.mockReturnValue(true); | ||
existsSyncSpy.mockReturnValue(true) | ||
|
||
await maybeGetSnarkArtifacts(Project.POSEIDON, { parameters: ["2"] }); | ||
await maybeGetSnarkArtifacts(Project.POSEIDON, { parameters: ['2'] }) | ||
|
||
expect(global.fetch).toHaveBeenCalledTimes(1); | ||
expect(global.fetch).toHaveBeenCalledTimes(1) | ||
expect(global.fetch).toHaveBeenLastCalledWith( | ||
"https://registry.npmjs.org/@zk-kit/poseidon-artifacts" | ||
); | ||
}); | ||
'https://registry.npmjs.org/@zk-kit/poseidon-artifacts', | ||
) | ||
}) | ||
|
||
it("Should return artifact file paths in node environment", async () => { | ||
mkdirSpy.mockRestore(); | ||
existsSyncSpy.mockReturnValue(false); | ||
it('Should return artifact file paths in node environment', async () => { | ||
mkdirSpy.mockRestore() | ||
existsSyncSpy.mockReturnValue(false) | ||
|
||
const { wasm, zkey } = await maybeGetSnarkArtifacts(Project.POSEIDON, { | ||
parameters: ["2"], | ||
}); | ||
parameters: ['2'], | ||
}) | ||
|
||
expect(wasm).toMatchInlineSnapshot( | ||
`"/tmp/snark-artifacts/poseidon/latest/poseidon-2.wasm"` | ||
); | ||
`"/tmp/snark-artifacts/poseidon/latest/poseidon-2.wasm"`, | ||
) | ||
expect(zkey).toMatchInlineSnapshot( | ||
`"/tmp/snark-artifacts/poseidon/latest/poseidon-2.zkey"` | ||
); | ||
`"/tmp/snark-artifacts/poseidon/latest/poseidon-2.zkey"`, | ||
) | ||
|
||
expect(fetchSpy).toHaveBeenCalledTimes(3); | ||
expect(fetchSpy).toHaveBeenCalledTimes(3) | ||
expect(fetchSpy).toHaveBeenNthCalledWith( | ||
1, | ||
"https://registry.npmjs.org/@zk-kit/poseidon-artifacts" | ||
); | ||
'https://registry.npmjs.org/@zk-kit/poseidon-artifacts', | ||
) | ||
expect(fetchSpy).toHaveBeenNthCalledWith( | ||
2, | ||
"https://snark-artifacts.pse.dev/poseidon/latest/poseidon-2.wasm" | ||
); | ||
'https://snark-artifacts.pse.dev/poseidon/latest/poseidon-2.wasm', | ||
) | ||
expect(fetchSpy).toHaveBeenNthCalledWith( | ||
3, | ||
"https://snark-artifacts.pse.dev/poseidon/latest/poseidon-2.zkey" | ||
); | ||
}, 25_000); | ||
}); | ||
}); | ||
'https://snark-artifacts.pse.dev/poseidon/latest/poseidon-2.zkey', | ||
) | ||
}, 25_000) | ||
}) | ||
}) |