175 lines
4.6 KiB
JavaScript
175 lines
4.6 KiB
JavaScript
import { Box } from '../../classes/display/box.js';
|
|
import { Scene } from '../../classes/display/scene.js';
|
|
import { Expert } from '../../classes/actors/expert.js';
|
|
import { DAO } from '../../classes/dao/dao.js';
|
|
import { Public } from '../../classes/actors/public.js';
|
|
import { PostContent } from '../../classes/supporting/post-content.js';
|
|
import { delayOrWait } from '../../classes/display/controls.js';
|
|
import { mochaRun } from '../../util/helpers.js';
|
|
|
|
const DELAY_INTERVAL = 100;
|
|
const POOL_DURATION = 200;
|
|
let dao;
|
|
let experts;
|
|
let requestor;
|
|
let scene;
|
|
|
|
const newExpert = async () => {
|
|
const index = experts.length;
|
|
const name = `Expert${index + 1}`;
|
|
const expert = await new Expert(dao, name, scene).initialize();
|
|
expert.setDisplayValue(
|
|
'rep',
|
|
() => dao.reputation.valueOwnedBy(expert.reputationPublicKey),
|
|
);
|
|
experts.push(expert);
|
|
return expert;
|
|
};
|
|
|
|
const setup = async () => {
|
|
const rootElement = document.getElementById('scene');
|
|
const rootBox = new Box('rootBox', rootElement).flex();
|
|
|
|
scene = new Scene('Availability test', rootBox);
|
|
scene.withSequenceDiagram();
|
|
scene.withFlowchart();
|
|
scene.withTable();
|
|
|
|
dao = new DAO('DGF', scene);
|
|
await dao.setDisplayValue('total rep', () => dao.reputation.getTotal());
|
|
|
|
experts = [];
|
|
|
|
await newExpert();
|
|
await newExpert();
|
|
requestor = new Public('Public', scene);
|
|
|
|
await delayOrWait(DELAY_INTERVAL);
|
|
|
|
// Experts gain initial reputation by submitting a post with fee
|
|
const { postId: postId1, pool: pool1 } = await experts[0].submitPostWithFee(
|
|
new PostContent({ hello: 'there' }).setTitle('Post 1'),
|
|
{
|
|
fee: 10,
|
|
duration: POOL_DURATION,
|
|
tokenLossRatio: 1,
|
|
},
|
|
);
|
|
await delayOrWait(POOL_DURATION);
|
|
|
|
await pool1.evaluateWinningConditions();
|
|
await delayOrWait(DELAY_INTERVAL);
|
|
|
|
dao.reputation.valueOwnedBy(experts[0].reputationPublicKey).should.equal(10);
|
|
|
|
const { pool: pool2 } = await experts[1].submitPostWithFee(
|
|
new PostContent({ hello: 'to you as well' })
|
|
.setTitle('Post 2')
|
|
.addCitation(postId1, 0.5),
|
|
{
|
|
fee: 10,
|
|
duration: POOL_DURATION,
|
|
tokenLossRatio: 1,
|
|
},
|
|
);
|
|
await delayOrWait(POOL_DURATION);
|
|
|
|
await pool2.evaluateWinningConditions();
|
|
await delayOrWait(DELAY_INTERVAL);
|
|
|
|
dao.reputation.valueOwnedBy(experts[0].reputationPublicKey).should.equal(15);
|
|
dao.reputation.valueOwnedBy(experts[1].reputationPublicKey).should.equal(5);
|
|
};
|
|
|
|
const getActiveWorker = async () => {
|
|
let worker;
|
|
let request;
|
|
for (const expert of experts) {
|
|
request = await expert.getAssignedWork();
|
|
if (request) {
|
|
worker = expert;
|
|
await worker.actions.getAssignedWork.log(worker, dao.availability);
|
|
worker.activate();
|
|
break;
|
|
}
|
|
}
|
|
return { worker, request };
|
|
};
|
|
|
|
const voteForWorkEvidence = async (worker, pool) => {
|
|
for (const expert of experts) {
|
|
if (expert !== worker) {
|
|
await expert.stake(pool, {
|
|
position: true,
|
|
amount: 1,
|
|
});
|
|
}
|
|
}
|
|
};
|
|
|
|
describe('Availability + Business', function tests() {
|
|
this.timeout(0);
|
|
|
|
before(async () => {
|
|
await setup();
|
|
});
|
|
|
|
beforeEach(async () => {
|
|
// await scene.sequence.startSection();
|
|
});
|
|
|
|
afterEach(async () => {
|
|
// await scene.sequence.endSection();
|
|
});
|
|
|
|
it('Experts can register their availability for some duration', async () => {
|
|
await experts[0].registerAvailability(1, 10000);
|
|
await experts[1].registerAvailability(1, 10000);
|
|
await delayOrWait(DELAY_INTERVAL);
|
|
});
|
|
|
|
it('Public can submit a work request', async () => {
|
|
await requestor.submitRequest(
|
|
dao.business,
|
|
{ fee: 100 },
|
|
{ please: 'do some work' },
|
|
);
|
|
await delayOrWait(DELAY_INTERVAL);
|
|
});
|
|
|
|
it('Expert can submit work evidence', async () => {
|
|
// Receive work request
|
|
const { worker, request } = await getActiveWorker();
|
|
const pool3 = await worker.submitWork(
|
|
request.id,
|
|
{
|
|
here: 'is some evidence of work product',
|
|
},
|
|
{
|
|
tokenLossRatio: 1,
|
|
duration: POOL_DURATION,
|
|
},
|
|
);
|
|
await worker.deactivate();
|
|
|
|
// Stake on work evidence
|
|
await voteForWorkEvidence(worker, pool3);
|
|
|
|
// Wait for validation pool duration to elapse
|
|
await delayOrWait(POOL_DURATION);
|
|
|
|
// Distribute reputation awards and fees
|
|
await pool3.evaluateWinningConditions();
|
|
await delayOrWait(DELAY_INTERVAL);
|
|
|
|
// This should throw an exception since the pool is already resolved
|
|
try {
|
|
await pool3.evaluateWinningConditions();
|
|
} catch (e) {
|
|
e.should.match(/Validation pool has already been resolved/);
|
|
}
|
|
}).timeout(10000);
|
|
});
|
|
|
|
mochaRun();
|