-
Notifications
You must be signed in to change notification settings - Fork 1
/
localnode.test.ts
178 lines (157 loc) · 7.24 KB
/
localnode.test.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
import { expect } from 'chai';
import { before, describe, it, beforeEach, after } from 'mocha';
import { agent as request } from 'supertest';
import userModel from '../model/user.model';
import providerModel from '../model/provider.model';
import geotsModel from '../model/geots.model';
import ProviderController from "../controller/provider.controller";
import AuthService from '../service/auth.service';
import validateEnv from '../util/validateEnv';
import dotenv from 'dotenv';
import HttpApp from '../http-app';
import { INGEST_PATH, PROVIDER_PATH, ANCHOR_PATH, VALIDATOR_PATH, SUPER_PATH, VALIDATE_PATH } from '../util/common';
import Mongo from "../mongo";
import IProvider from '../interface/provider.interface';
import IGeots from '../interface/geots.interface';
import IPoint from '../interface/point.interface';
import IMetadata from '../interface/metadata.interface';
import { IMeasurement, Measurement, Unit } from '../interface/measurement.interface';
import anchorModel from '../model/anchor.model';
import ValidatorService from '../service/validator.service';
import { ANCHOR_NOT_FOUND } from '../util/constants';
import SuperController from '../controller/super.controller';
import ValidatorController from '../controller/validatorController';
process.env.NODE_ENV = process.env.NODE_ENV === undefined ? 'test' : process.env.NODE_ENV;
dotenv.config();
validateEnv();
const mongo = new Mongo();
mongo.connect().then(() => {
console.log(`database connected`);
});
let authService: AuthService;
let provider;
export const app = new HttpApp(
[
new ProviderController(),
new SuperController(),
new ValidatorController(),
],
);
const testprovider: IProvider = { name: 'Test Provider', path: '4818b0' };
// 3 different endpoints, 3 different users/roles
const PROVIDER_API = `http://localhost:3000/api/${PROVIDER_PATH}`;
const SUPER_API = `http://localhost:3000/api/${SUPER_PATH}`;
const VALIDATOR_API = `http://localhost:3000/api/${VALIDATOR_PATH}`;
describe('test anchor and validate', () => {
before(done => {
app.listen();
done();
});
after(done => {
app.close();
done();
});
beforeEach(done => {
providerModel.deleteMany({}, err => {
console.log(err);
});
geotsModel.deleteMany({}, err => {
console.log(err);
});
anchorModel.deleteMany({}, err => {
console.log(err);
});
userModel.deleteMany({}, () => {
done();
});
});
describe('create anchor and validate', () => {
it('should create, anchor and validate 2 geots with appropriate user/roles', async () => {
authService = await AuthService.getInstance();
await providerModel.create(testprovider)
.then(() => {
console.log(
`${testprovider.name} created`
);
})
.catch((error: string) => { console.log(error); });
provider = await providerModel.findOne({ name: testprovider.name });
// providerUser creates data, requires provider role
const providerUser = new userModel({
username: 'provider', email: 'provider@example.com', password: 'provider',
roles: [authService.roleUser, authService.roleProvider], provider: provider
});
await providerUser.save();
const providerToken = authService.createToken(providerUser);
// create sample data
const point: IPoint = { type: 'Point', coordinates: [-73.91320, 40.68405] };
const metadata: IMetadata = {
model: 'mri-esm2-ssp126',
project_id: 'proj_29lo8RFQiVowh4u5WHdbFSLKExL',
source: 'station xxxxx',
ip: '::ffff:127.0.0.1',
provider: provider,
location: { type: 'GeometryCollection', geometries: [point] },
};
const m1: IMeasurement = { type: Measurement.Temperature, unit: Unit.Celsius, value: 20 };
const m2: IMeasurement = { type: Measurement.Humidity, unit: Unit.Percent, value: 30 };
const geots: IGeots = {
metadata: metadata,
ts: new Date('2020-01-01T00:00:00.000Z'),
measurements: [m1, m2],
};
// call ProviderController ingest endpoint create the geots data
let res = await request(PROVIDER_API).post(`/${INGEST_PATH}`).set({ 'x-access-token': [providerToken.token] }).send(geots);
expect(res.status).to.equal(200);
let createdData: IGeots = res.body.geots;
expect(createdData.ts).to.equal(geots.ts.toISOString());
// add another data point with new timestamp
geots.ts = new Date('2020-01-01T10:00:00.000Z');
res = await request(PROVIDER_API).post(`/${INGEST_PATH}`).set({ 'x-access-token': [providerToken.token] }).send(geots);
expect(res.status).to.equal(200);
createdData = res.body.geots;
expect(createdData.ts).to.equal(geots.ts.toISOString());
// anchorUser anchors data, requires superuser role, no provider
const anchorUser = new userModel({
username: 'anchorer', email: 'anchorer@example.com', password: 'anchorer',
roles: [authService.roleUser, authService.roleSuper]
});
await anchorUser.save();
const anchorToken = authService.createToken(anchorUser);
// Call SuperController anchor endpoint, creates a new anchor, creates a hash summary of geots data,
// and saves it to the database anchor and the CELO contract
// it also updates the geots metadata with the anchor id
res = await request(SUPER_API).post(`/${ANCHOR_PATH}`).set({ 'x-access-token': [anchorToken.token] }).send({ provider: provider, limit: 100 });
expect(res.status).to.equal(200);
const anchorResponse = res.body.count;
expect(anchorResponse).to.equal(2);
// read the geots data and check that the anchor id is set
let anchor = await anchorModel.findOne();
const anchored = await geotsModel.findOne({ _id: createdData._id });
expect(anchored.metadata.anchor).to.equal(anchor._id);
expect(anchor.count).to.equal(2);
expect(anchor.validation_count).to.equal(0);
// via validatorService, validate that the anchor hash is derived from the data hash and matches both the database and the CELO contract
const validatorService = new ValidatorService();
const dbHash = await validatorService.getAnchorHashDB(anchor._id);
expect(dbHash).to.equal(anchor.hash);
const celoHash = await validatorService.getAnchorHashBC(anchor._id);
expect(celoHash).to.equal(anchor.hash);
// check failure condition, throws error, ignore log message in console
const notFound = await validatorService.getAnchorHashBC('test');
expect(notFound).to.equal(ANCHOR_NOT_FOUND);
// validatorUser anchors data, requires validator role, no provider
const validatorUser = new userModel({
username: 'validator', email: 'validator@example.com', password: 'validator',
roles: [authService.roleUser, authService.roleValidator]
});
await validatorUser.save();
const validatorToken = authService.createToken(validatorUser);
// call ValidatorController validate endpoint
res = await request(VALIDATOR_API).post(`/${VALIDATE_PATH}`).set({ 'x-access-token': [validatorToken.token] }).send({ provider: provider, limit: 100 });
expect(res.status).to.equal(200);
anchor = await anchorModel.findOne({ _id: anchor._id });
expect(anchor.validation_count).to.equal(1);
});
})
});