Created
December 22, 2025 20:24
-
-
Save stopachka/18046a33b6592f363cce6dc91204e0ad to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| import "dotenv/config"; | |
| import { expect, beforeAll, afterAll, test } from "vitest"; | |
| import schema, { AppSchema } from "@/instant.schema"; | |
| import rules from "@/instant.perms"; | |
| import { | |
| id, | |
| init, | |
| InstantAdminDatabase, | |
| InstantConfig, | |
| TransactionChunk, | |
| } from "@instantdb/admin"; | |
| import platformAPI from "./adminLib/platformAPI"; | |
| let app: { id: string; adminToken: string } = null as any; | |
| let adminDB: InstantAdminDatabase< | |
| AppSchema, | |
| InstantConfig<AppSchema, false> | |
| > = null as any; | |
| const gStopaId = id(); | |
| const gJoeId = id(); | |
| beforeAll(async () => { | |
| console.log("[app-creating]..."); | |
| const res = await platformAPI.createApp({ | |
| title: "TestApp" + Date.now(), | |
| perms: rules, | |
| // TODO: I can't seem to get InstantSchemaDefs to agree with eachother | |
| schema: schema as any, | |
| }); | |
| app = res.app; | |
| adminDB = init({ | |
| appId: app.id, | |
| adminToken: app.adminToken, | |
| schema, | |
| }); | |
| console.log("[app-created]", app.id); | |
| console.log("[creating-test-users]..."); | |
| await adminDB.transact(adminDB.tx.guests[gStopaId].create({})); | |
| await adminDB.transact(adminDB.tx.guests[gJoeId].create({})); | |
| console.log("[created-test-users]...", gStopaId, gJoeId); | |
| }); | |
| afterAll(async () => { | |
| console.log("[app-deleting]...", app.id); | |
| await platformAPI.deleteApp(app.id); | |
| console.log("[app-deleted]", app.id); | |
| }); | |
| async function expectOK( | |
| txs: TransactionChunk<any, any> | TransactionChunk<any, any>[] | |
| ) { | |
| await expect(adminDB.asUser({ guest: true }).transact(txs)).resolves.toEqual({ | |
| "tx-id": expect.any(Number), | |
| }); | |
| } | |
| async function expectPermErr(txs: TransactionChunk<any, any>) { | |
| await expect(adminDB.asUser({ guest: true }).transact(txs)).rejects.toThrow( | |
| "Permission denied:" | |
| ); | |
| } | |
| test.concurrent("I can create my own guest account", async () => { | |
| const stopaid = id(); | |
| await expectOK( | |
| adminDB.tx.guests[stopaid] | |
| .ruleParams({ localCreatorId: stopaid }) | |
| .create({}) | |
| ); | |
| }); | |
| test.concurrent("I can see see my own guest account", async () => { | |
| const stopaid = id(); | |
| await expectOK( | |
| adminDB.tx.guests[stopaid] | |
| .ruleParams({ localCreatorId: stopaid }) | |
| .create({}) | |
| ); | |
| await expect( | |
| adminDB | |
| .asUser({ guest: true }) | |
| .query( | |
| { guests: { $: { where: { id: stopaid } } } }, | |
| { ruleParams: { localCreatorId: stopaid } } | |
| ) | |
| ).resolves.toEqual({ guests: [{ id: stopaid }] }); | |
| }); | |
| test.concurrent("I can't create another person's account", async () => { | |
| const stopaid = id(); | |
| const joeid = id(); | |
| await expectPermErr( | |
| adminDB.tx.guests[joeid].ruleParams({ localCreatorId: stopaid }).create({}) | |
| ); | |
| }); | |
| test.concurrent("I can't see another person's account", async () => { | |
| const stopaid = id(); | |
| const joeid = id(); | |
| await expectOK( | |
| adminDB.tx.guests[stopaid] | |
| .ruleParams({ localCreatorId: stopaid }) | |
| .create({}) | |
| ); | |
| await expect( | |
| adminDB | |
| .asUser({ guest: true }) | |
| .query( | |
| { guests: { $: { where: { id: stopaid } } } }, | |
| { ruleParams: { localCreatorId: joeid } } | |
| ) | |
| ).resolves.toEqual({ guests: [] }); | |
| }); | |
| test.concurrent("I can create my own sessions", async () => { | |
| await expectOK( | |
| adminDB.tx.sessions[id()] | |
| .ruleParams({ localCreatorId: gStopaId }) | |
| .create({ | |
| title: "My session", | |
| initialPrompt: "make me a racing game", | |
| }) | |
| .link({ owner: gStopaId }) | |
| ); | |
| }); | |
| test.concurrent("I can't create sessions for other people", async () => { | |
| await expectPermErr( | |
| adminDB.tx.sessions[id()] | |
| .ruleParams({ localCreatorId: gStopaId }) | |
| .create({ | |
| title: "My session", | |
| initialPrompt: "make me a racing game", | |
| }) | |
| .link({ owner: gJoeId }) | |
| ); | |
| }); | |
| test.concurrent("I can delete my own session", async () => { | |
| const sessId = id(); | |
| await expectOK( | |
| adminDB.tx.sessions[sessId] | |
| .ruleParams({ localCreatorId: gStopaId }) | |
| .create({ | |
| title: "My session", | |
| initialPrompt: "make me a racing game", | |
| }) | |
| .link({ owner: gStopaId }) | |
| ); | |
| await expectOK( | |
| adminDB.tx.sessions[sessId] | |
| .ruleParams({ localCreatorId: gStopaId }) | |
| .delete() | |
| ); | |
| }); | |
| test.concurrent("I can't delete sessions for other people", async () => { | |
| const sessId = id(); | |
| await expectOK( | |
| adminDB.tx.sessions[sessId] | |
| .ruleParams({ localCreatorId: gStopaId }) | |
| .create({ | |
| title: "My session", | |
| initialPrompt: "make me a racing game", | |
| }) | |
| .link({ owner: gStopaId }) | |
| ); | |
| await expectPermErr( | |
| adminDB.tx.sessions[sessId].ruleParams({ localCreatorId: gJoeId }).delete() | |
| ); | |
| }); | |
| test.concurrent("Admins can delete other people's sessions", async () => { | |
| const sessId = id(); | |
| await expectOK( | |
| adminDB.tx.sessions[sessId] | |
| .ruleParams({ localCreatorId: gStopaId }) | |
| .create({ | |
| title: "My session", | |
| initialPrompt: "make me a racing game", | |
| }) | |
| .link({ owner: gStopaId }) | |
| ); | |
| const adminUserToken = await adminDB.auth.createToken("[email protected]"); | |
| await expect( | |
| adminDB | |
| .asUser({ token: adminUserToken }) | |
| .transact( | |
| adminDB.tx.sessions[sessId] | |
| .ruleParams({ localCreatorId: gJoeId }) | |
| .delete() | |
| ) | |
| ).resolves.toEqual({ | |
| "tx-id": expect.any(Number), | |
| }); | |
| }); | |
| test.concurrent( | |
| "Authed users can't delete other people's sessions", | |
| async () => { | |
| const sessId = id(); | |
| await expectOK( | |
| adminDB.tx.sessions[sessId] | |
| .ruleParams({ localCreatorId: gStopaId }) | |
| .create({ | |
| title: "My session", | |
| initialPrompt: "make me a racing game", | |
| }) | |
| .link({ owner: gStopaId }) | |
| ); | |
| const authUserToken = await adminDB.auth.createToken("[email protected]"); | |
| await expect( | |
| adminDB | |
| .asUser({ token: authUserToken }) | |
| .transact( | |
| adminDB.tx.sessions[sessId] | |
| .ruleParams({ localCreatorId: gJoeId }) | |
| .delete() | |
| ) | |
| ).rejects.toThrow("Permission denied:"); | |
| } | |
| ); | |
| test.concurrent("I can update my session", async () => { | |
| const sess = id(); | |
| await expectOK( | |
| adminDB.tx.sessions[sess] | |
| .ruleParams({ localCreatorId: gStopaId }) | |
| .create({ | |
| title: "My session", | |
| initialPrompt: "make me a racing game", | |
| }) | |
| .link({ owner: gStopaId }) | |
| ); | |
| await expectOK([ | |
| adminDB.tx.sessions[sess].ruleParams({ localCreatorId: gStopaId }).update({ | |
| title: "My new title", | |
| }), | |
| ]); | |
| }); | |
| test.concurrent("I can link my own builds", async () => { | |
| const sessid = id(); | |
| const buildId = id(); | |
| await expectOK( | |
| adminDB.tx.sessions[sessid] | |
| .ruleParams({ localCreatorId: gStopaId }) | |
| .create({ | |
| title: "My session", | |
| initialPrompt: "make me a racing game", | |
| }) | |
| .link({ owner: gStopaId }) | |
| ); | |
| await expectOK( | |
| adminDB.tx.builds[buildId] | |
| .ruleParams({ localCreatorId: gStopaId }) | |
| .create({ | |
| code: 'console.log("hello")', | |
| instantAppId: "appid", | |
| }) | |
| .link({ owner: gStopaId }) | |
| ); | |
| await expectOK( | |
| adminDB.tx.builds[buildId] | |
| .ruleParams({ localCreatorId: gStopaId }) | |
| .link({ session: buildId }) | |
| ); | |
| }); | |
| test.concurrent("I cannot link other people's builds", async () => { | |
| const sessid = id(); | |
| const buildId = id(); | |
| await expectOK( | |
| adminDB.tx.sessions[sessid] | |
| .ruleParams({ localCreatorId: gStopaId }) | |
| .create({ | |
| title: "My session", | |
| initialPrompt: "make me a racing game", | |
| }) | |
| .link({ owner: gStopaId }) | |
| ); | |
| await expectOK( | |
| adminDB.tx.builds[buildId] | |
| .ruleParams({ localCreatorId: gJoeId }) | |
| .create({ | |
| code: 'console.log("hello")', | |
| instantAppId: "oi", | |
| }) | |
| .link({ owner: gJoeId }) | |
| ); | |
| await expectPermErr( | |
| adminDB.tx.builds[buildId] | |
| .ruleParams({ localCreatorId: gStopaId }) | |
| .link({ session: buildId }) | |
| ); | |
| }); | |
| test.concurrent( | |
| "I can create build and buildPrivateInfo together", | |
| async () => { | |
| const sessionId = id(); | |
| const buildId = id(); | |
| const buildPrivateInfoId = id(); | |
| const localCreatorId = gStopaId; | |
| const instantApp = { | |
| id: "test-instant-app-id", | |
| adminToken: "test-admin-token", | |
| }; | |
| // First create a session | |
| await expectOK( | |
| adminDB.tx.sessions[sessionId] | |
| .ruleParams({ localCreatorId }) | |
| .create({ | |
| title: "Test session", | |
| initialPrompt: "test prompt", | |
| }) | |
| .link({ owner: localCreatorId }) | |
| ); | |
| await expectOK([ | |
| adminDB.tx.builds[buildId] | |
| .ruleParams({ localCreatorId }) | |
| .create({ | |
| instantAppId: instantApp.id, | |
| code: "", | |
| isPreviewable: false, | |
| }) | |
| .link({ owner: localCreatorId, session: sessionId }), | |
| adminDB.tx.buildPrivateInfos[buildPrivateInfoId] | |
| .ruleParams({ localCreatorId }) | |
| .create({ | |
| instantAdminToken: instantApp.adminToken, | |
| }) | |
| .link({ owner: localCreatorId, build: buildId }), | |
| ]); | |
| } | |
| ); | |
| test.concurrent("Admins can view usage info", async () => { | |
| const localCreatorId = gStopaId; | |
| const sessionId = id(); | |
| const buildId = id(); | |
| const usageId = id(); | |
| await expectOK( | |
| adminDB.tx.sessions[sessionId] | |
| .ruleParams({ localCreatorId }) | |
| .create({ | |
| title: "Usage session", | |
| initialPrompt: "count tokens", | |
| }) | |
| .link({ owner: localCreatorId }) | |
| ); | |
| await expectOK( | |
| adminDB.tx.builds[buildId] | |
| .ruleParams({ localCreatorId }) | |
| .create({ | |
| instantAppId: "usage-app", | |
| code: "console.log('hi')", | |
| }) | |
| .link({ owner: localCreatorId, session: sessionId }) | |
| ); | |
| await expectOK( | |
| adminDB.tx.modelUsages[usageId] | |
| .ruleParams({ localCreatorId }) | |
| .create({ | |
| inputTokens: 10, | |
| outputTokens: 5, | |
| }) | |
| .link({ owner: localCreatorId, build: buildId }) | |
| ); | |
| const adminToken = await adminDB.auth.createToken("[email protected]"); | |
| await expect( | |
| adminDB | |
| .asUser({ token: adminToken }) | |
| .query( | |
| { modelUsages: { $: { where: { id: usageId } } } }, | |
| { ruleParams: { localCreatorId } } | |
| ) | |
| ).resolves.toMatchObject({ | |
| modelUsages: [ | |
| { | |
| id: usageId, | |
| inputTokens: 10, | |
| outputTokens: 5, | |
| }, | |
| ], | |
| }); | |
| }); | |
| test.concurrent("Guests cannot view usage info", async () => { | |
| const localCreatorId = gJoeId; | |
| const sessionId = id(); | |
| const buildId = id(); | |
| const usageId = id(); | |
| await expectOK( | |
| adminDB.tx.sessions[sessionId] | |
| .ruleParams({ localCreatorId }) | |
| .create({ | |
| title: "Usage session guest", | |
| initialPrompt: "count tokens", | |
| }) | |
| .link({ owner: localCreatorId }) | |
| ); | |
| await expectOK( | |
| adminDB.tx.builds[buildId] | |
| .ruleParams({ localCreatorId }) | |
| .create({ | |
| instantAppId: "usage-app", | |
| code: "console.log('hi')", | |
| }) | |
| .link({ owner: localCreatorId, session: sessionId }) | |
| ); | |
| await expectOK( | |
| adminDB.tx.modelUsages[usageId] | |
| .ruleParams({ localCreatorId }) | |
| .create({ | |
| inputTokens: 20, | |
| outputTokens: 2, | |
| }) | |
| .link({ owner: localCreatorId, build: buildId }) | |
| ); | |
| await expect( | |
| adminDB | |
| .asUser({ guest: true }) | |
| .query( | |
| { modelUsages: { $: { where: { id: usageId } } } }, | |
| { ruleParams: { localCreatorId } } | |
| ) | |
| ).resolves.toMatchObject({ | |
| modelUsages: [], | |
| }); | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment