Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into feature/governance
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelTaylor3D committed Mar 18, 2022
2 parents 087944d + 35c88ef commit 6c8de1f
Show file tree
Hide file tree
Showing 11 changed files with 247 additions and 45 deletions.
2 changes: 1 addition & 1 deletion src/controllers/units.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ export const findAll = async (req, res) => {
where = {};
}

where.warehouseProjectId = {
where.warehouseUnitId = {
[Sequelize.Op.in]: mappedResults,
};
}
Expand Down
22 changes: 22 additions & 0 deletions src/datalayer/wallet.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,30 @@ const hasUnconfirmedTransactions = async () => {
return false;
};

const getPublicAddress = async () => {
if (process.env.USE_SIMULATOR === 'true') {
return Promise.resolve('xch33300ddsje98f33hkkdf9dfuSIMULATED_ADDRESS');
}

const options = {
url: `${rpcUrl}/get_next_address`,
body: JSON.stringify({ wallet_id: 1, new_address: false }),
};

const response = await request(Object.assign({}, getBaseOptions(), options));

const data = JSON.parse(response);

if (data.success) {
return data.address;
}

return false;
};

export default {
hasUnconfirmedTransactions,
walletIsSynced,
walletIsAvailable,
getPublicAddress,
};
77 changes: 76 additions & 1 deletion src/models/governance/governance.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,85 @@
import Sequelize from 'sequelize';
const { Model } = Sequelize;
import { sequelize } from '../../database';
import { Meta } from '../../models';
import datalayer from '../../datalayer';
import { keyValueToChangeList } from '../../utils/datalayer-utils';

import ModelTypes from './governance.modeltypes.cjs';

class Governance extends Model {}
class Governance extends Model {
static async createGoveranceBody() {
const goveranceBodyId = await datalayer.createDataLayerStore();

if (process.env.GOVERANCE_BODY_ID && process.env.GOVERANCE_BODY_ID !== '') {
throw new Error(
'You are already listening to another governance body. Please clear GOVERANCE_BODY_ID from your env and try again',
);
}

await Meta.upsert({
metaKey: 'goveranceBodyId',
goveranceBodyId,
});

return goveranceBodyId;
}

static async updateGoveranceBodyData(keyValueArray) {
const goveranceBodyId = await Meta.find({
where: { metaKey: 'goveranceBodyId' },
});

if (!goveranceBodyId) {
throw new Error(
'There is no Goverance Body that you own that can be edited',
);
}

const existingRecords = Governance.findAll({ raw: true });

const changeList = [];

await Promise.all(
keyValueArray.map(async (keyValue) => {
const valueExists = existingRecords.find(
(record) => record.metaKey === keyValue.key,
);

await Governance.upsert({
metaKey: keyValue.key,
metaValue: keyValue.value,
confirmed: false,
});
changeList.push(
keyValueToChangeList(keyValue.key, keyValue.value, valueExists),
);
}),
);

const rollbackChangesIfFailed = async () => {
await Promise.all(
existingRecords.map(async (record) => await Governance.upsert(record)),
);
};

const onConfirm = async () => {
await Promise.all(
keyValueArray.map(async (keyValue) => {
await Governance.upsert({
metaKey: keyValue.key,
metaValue: keyValue.value,
confirmed: true,
});
}),
);
};

await datalayer.pushDataLayerChangeList(goveranceBodyId, changeList);

datalayer.getStoreData(goveranceBodyId, onConfirm, rollbackChangesIfFailed);
}
}

Governance.init(ModelTypes, {
sequelize,
Expand Down
10 changes: 10 additions & 0 deletions src/models/organizations/organizations.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class Organization extends Model {
});

if (myOrganization) {
myOrganization.xchAddress = await datalayer.getPublicAddress();
return myOrganization;
}

Expand All @@ -52,8 +53,17 @@ class Organization extends Model {
attributes: ['orgUid', 'name', 'icon', 'isHome', 'subscribed'],
});

for (let i = 0; i < organizations.length; i++) {
if (organizations[i].dataValues.isHome) {
organizations[i].dataValues.xchAddress =
await datalayer.getPublicAddress();
break;
}
}

return organizations.reduce((map, current) => {
map[current.orgUid] = current.dataValues;

return map;
}, {});
}
Expand Down
2 changes: 0 additions & 2 deletions src/utils/data-assertions.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ export const assertNoPendingCommits = async () => {
raw: true,
});

console.log(pendingCommits);

if (pendingCommits.length > 0) {
throw new Error(
'You currently have changes pending on the blockchain. Please wait for them to propagate before making more changes',
Expand Down
19 changes: 19 additions & 0 deletions src/utils/datalayer-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,22 @@ export const decodeDataLayerResponse = (data) => {
value: decodeHex(item.value),
}));
};

export const keyValueToChangeList = (key, value, includeDelete) => {
const changeList = [];

if (includeDelete) {
changeList.push({
action: 'delete',
key: encodeHex(key),
});
}

changeList.push({
action: 'insert',
key: encodeHex(key),
value: encodeHex(value),
});

return changeList;
};
1 change: 1 addition & 0 deletions src/websocket.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const socketSubscriptions = {};
const authenticate = () => true;

export const connection = (socket) => {
console.log(socketSubscriptions);
socket.on('authentication', () => {
if (!authenticate(socket)) {
console.log('authentication failure');
Expand Down
6 changes: 4 additions & 2 deletions tests/resources/organization.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import app from '../../src/server';
import { Organization } from '../../src/models/organizations/index.js';
import { expect } from 'chai';
import { prepareDb } from '../../src/database';
import datalayer from '../../src/datalayer';
const TEST_WAIT_TIME = datalayer.POLLING_INTERVAL * 2;

const orgName = Math.random().toString();
describe('Orgainzation Resource CRUD', function () {
Expand All @@ -25,14 +27,14 @@ describe('Orgainzation Resource CRUD', function () {
expect(response.body.message).to.equal(
'New organization created successfully.',
);
});
}).timeout(TEST_WAIT_TIME * 10);
it('Organization can be retreived from datalayer', async function () {
const response = await supertest(app).get(`/v1/organizations`).send();

expect(Object.values(response.body)[0].name).to.equal(orgName);
expect(Object.values(response.body)[0].icon).to.equal(
'https://climate-warehouse.s3.us-west-2.amazonaws.com/public/orgs/me.svg',
);
});
}).timeout(TEST_WAIT_TIME * 10);
});
});
26 changes: 14 additions & 12 deletions tests/resources/projects.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { pullPickListValues } from '../../src/utils/data-loaders';
import { Staging, Project } from '../../src/models/index.js';
import { uuid as uuidv4 } from 'uuidv4';
import { prepareDb, seedDb, sequelize } from '../../src/database';
const TEST_WAIT_TIME = datalayer.POLLING_INTERVAL * 2;

describe('Project Resource CRUD', function () {
afterEach(function () {
Expand All @@ -37,31 +38,31 @@ describe('Project Resource CRUD', function () {
expect(response.body.error).to.equal(
'Can not establish connection to Chia Datalayer',
);
});
}).timeout(TEST_WAIT_TIME * 10);
});

describe('success states', function () {
it('gets all the projects available', async function () {
// no query params
const projects = await testFixtures.getProjectByQuery();
expect(projects.length).to.equal(11);
});
}).timeout(TEST_WAIT_TIME * 10);

it('gets all the projects filtered by orgUid', async function () {
// ?orgUid=XXXX
const projects = await testFixtures.getProjectByQuery({
orgUid: 'a807e453-6524-49df-a32d-785e56cf560e',
});
expect(projects.length).to.equal(3);
});
}).timeout(TEST_WAIT_TIME * 10);

it('gets all the projects for a search term', async function () {
// ?search=XXXX
const projects = await testFixtures.getProjectByQuery({
search: 'City of Arcata',
});
expect(projects.length).to.equal(1);
});
}).timeout(TEST_WAIT_TIME * 10);

it('gets all the projects for a search term filtered by orgUid', async function () {
// ?orgUid=XXXX&search=XXXX
Expand All @@ -71,7 +72,7 @@ describe('Project Resource CRUD', function () {
});

expect(projects.length).to.equal(1);
});
}).timeout(TEST_WAIT_TIME * 10);

it('gets optional paginated results', async function () {
// ?page=X&limit=10
Expand All @@ -94,7 +95,7 @@ describe('Project Resource CRUD', function () {
limit: 2,
});
expect(projectsLimit2.data.length).to.equal(2);
});
}).timeout(TEST_WAIT_TIME * 10);

it('finds a single result by warehouseProjectId', async function () {
// ?warehouseProjectId=XXXX
Expand All @@ -104,7 +105,7 @@ describe('Project Resource CRUD', function () {

// should get only 1 result
expect(projects).to.be.a('object');
});
}).timeout(TEST_WAIT_TIME * 10);
});
});

Expand Down Expand Up @@ -148,7 +149,7 @@ describe('Project Resource CRUD', function () {
'You currently have changes pending on the blockchain. Please wait for them to propagate before making more changes',
);
expect(response.statusCode).to.equal(400);
});
}).timeout(TEST_WAIT_TIME * 10);

it('errors if there if there is no connection to the datalayer', async function () {
sinon.stub(datalayer, 'dataLayerAvailable').resolves(false);
Expand All @@ -160,7 +161,7 @@ describe('Project Resource CRUD', function () {
'Can not establish connection to Chia Datalayer',
);
expect(response.statusCode).to.equal(400);
});
}).timeout(TEST_WAIT_TIME * 10);
});

describe('success states', function () {
Expand All @@ -186,7 +187,8 @@ describe('Project Resource CRUD', function () {

expect(response.body.message).to.equal('Project staged successfully');
expect(response.statusCode).to.equal(200);
});
}).timeout(TEST_WAIT_TIME * 10);

it('creates a new project with all child tables', async function () {
await Staging.destroy({
where: {},
Expand All @@ -201,7 +203,7 @@ describe('Project Resource CRUD', function () {

expect(response.body.message).to.equal('Project staged successfully');
expect(response.statusCode).to.equal(200);
});
}).timeout(TEST_WAIT_TIME * 10);
});
});

Expand Down Expand Up @@ -238,7 +240,7 @@ describe('Project Resource CRUD', function () {
name: 'Test',
icon: 'https://climate-warehouse.s3.us-west-2.amazonaws.com/public/orgs/me.svg',
});
});
}).timeout(TEST_WAIT_TIME * 10);
it('errors if there is a current set of pending commits', function () {});
it('errors if there if there is no connection to the datalayer', function () {});
it('errors if the warehouseProjectId is not in the payload', function () {});
Expand Down
6 changes: 4 additions & 2 deletions tests/resources/staging.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import newProject from '../test-data/new-project.json';
import { pullPickListValues } from '../../src/utils/data-loaders';
import { expect } from 'chai';
import { prepareDb } from '../../src/database';
import datalayer from '../../src/datalayer';
const TEST_WAIT_TIME = datalayer.POLLING_INTERVAL * 2;

describe('Staging Resource CRUD', function () {
before(async function () {
Expand All @@ -21,7 +23,7 @@ describe('Staging Resource CRUD', function () {

const response = await supertest(app).get('/v1/staging');
expect(response.body.length).to.equal(1);
});
}).timeout(TEST_WAIT_TIME * 10);
it('generates a diff object for the change', async function () {
const responseCreate = await supertest(app)
.post('/v1/projects')
Expand All @@ -36,7 +38,7 @@ describe('Staging Resource CRUD', function () {
).to.deep.equal(
'Biodiversity through planting a variety of trees that are home to many native Singaporean species',
);
});
}).timeout(TEST_WAIT_TIME * 10);
});

describe('POST - Commit Records to datalayer', function () {
Expand Down
Loading

0 comments on commit 6c8de1f

Please sign in to comment.