Skip to content

Commit

Permalink
test: add tests for patterns in makeInvitation()
Browse files Browse the repository at this point in the history
correct one typeGuard

Also noticed that the types documented for
getProposalShapeForInvitation were incorrect. fixed that with
Agoric/documentation#1258
  • Loading branch information
Chris-Hibbert committed Dec 17, 2024
1 parent 140c1be commit 0f7b7b8
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 1 deletion.
2 changes: 1 addition & 1 deletion packages/zoe/src/typeGuards.js
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ export const ZoeServiceI = M.interface('ZoeService', {
}),
getInvitationDetails: M.call(M.eref(InvitationShape)).returns(M.any()),
getProposalShapeForInvitation: M.call(InvitationHandleShape).returns(
M.opt(ProposalShape),
M.opt(M.pattern()),
),
});

Expand Down
143 changes: 143 additions & 0 deletions packages/zoe/test/unitTests/zcf/offer-proposalShape.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import { test } from '@agoric/swingset-vat/tools/prepare-test-env-ava.js';

import path from 'path';

import { E } from '@endo/eventual-send';
import bundleSource from '@endo/bundle-source';

import { M } from '@endo/patterns';
import { AmountShape } from '@agoric/ertp';
import { makeZoeForTest } from '../../../tools/setup-zoe.js';
import { setup } from '../setupBasicMints.js';
import { makeFakeVatAdmin } from '../../../tools/fakeVatAdmin.js';

const dirname = path.dirname(new URL(import.meta.url).pathname);

const contractRoot = `${dirname}/zcfTesterContract.js`;

test(`ProposalShapes mismatch`, async t => {
const { moolaIssuer, simoleanIssuer, moola, moolaMint } = setup();
let testJig;
const setJig = jig => {
testJig = jig;
};
const { admin: fakeVatAdminSvc, vatAdminState } = makeFakeVatAdmin(setJig);
/** @type {ZoeService} */
const zoe = makeZoeForTest(fakeVatAdminSvc);

// pack the contract
const bundle = await bundleSource(contractRoot);
// install the contract
vatAdminState.installBundle('b1-zcftester', bundle);
const installation = await E(zoe).installBundleID('b1-zcftester');

// Alice creates an instance
const issuerKeywordRecord = harden({
Pixels: moolaIssuer,
Money: simoleanIssuer,
});

await E(zoe).startInstance(installation, issuerKeywordRecord);

// The contract uses the testJig so the contractFacet
// is available here for testing purposes
/** @type {ZCF} */
// @ts-expect-error cast
const zcf = testJig.zcf;

const boring = () => {
return 'ok';
};

const proposalShape = M.splitRecord({
give: { B: AmountShape },
exit: { deadline: M.any() },
});
const invitation = await zcf.makeInvitation(
boring,
'seat1',
{},
proposalShape,
);
const { handle } = await E(zoe).getInvitationDetails(invitation);
const shape = await E(zoe).getProposalShapeForInvitation(handle);
t.deepEqual(shape, proposalShape);

const proposal = harden({
give: { B: moola(5n) },
exit: { onDemand: null },
});

const fiveMoola = moolaMint.mintPayment(moola(5n));
await t.throwsAsync(
() =>
E(zoe).offer(invitation, proposal, {
B: fiveMoola,
}),
{
message:
'"seat1" proposal: exit: {"onDemand":null} - Must have missing properties ["deadline"]',
},
);
t.falsy(vatAdminState.getHasExited());
// The moola was not deposited.
t.true(await E(moolaIssuer).isLive(fiveMoola));
});

test(`ProposalShapes matched`, async t => {
const { moolaIssuer, simoleanIssuer } = setup();
let testJig;
const setJig = jig => {
testJig = jig;
};
const { admin: fakeVatAdminSvc, vatAdminState } = makeFakeVatAdmin(setJig);
/** @type {ZoeService} */
const zoe = makeZoeForTest(fakeVatAdminSvc);

// pack the contract
const bundle = await bundleSource(contractRoot);
// install the contract
vatAdminState.installBundle('b1-zcftester', bundle);
const installation = await E(zoe).installBundleID('b1-zcftester');

// Alice creates an instance
const issuerKeywordRecord = harden({
Pixels: moolaIssuer,
Money: simoleanIssuer,
});

await E(zoe).startInstance(installation, issuerKeywordRecord);

// The contract uses the testJig so the contractFacet
// is available here for testing purposes
/** @type {ZCF} */
// @ts-expect-error cast
const zcf = testJig.zcf;

const boring = () => {
return 'ok';
};

const proposalShape = M.splitRecord({ exit: { onDemand: null } });
const invitation = await zcf.makeInvitation(
boring,
'seat',
{},
proposalShape,
);
const { handle } = await E(zoe).getInvitationDetails(invitation);
const shape = await E(zoe).getProposalShapeForInvitation(handle);
t.deepEqual(shape, proposalShape);

// onDemand is the default
const seat = await E(zoe).offer(invitation);

const result = await E(seat).getOfferResult();
t.is(result, 'ok', `userSeat1 offer result`);

t.falsy(await E(seat).hasExited());
await E(seat).tryExit();
t.true(await E(seat).hasExited());
const payouts = await E(seat).getPayouts();
t.deepEqual(payouts, {});
});

0 comments on commit 0f7b7b8

Please sign in to comment.