github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/Decentralized-Energy-Composer-master/test/test.js (about) 1 /* 2 * Licensed under the Apache License, Version 2.0 (the "License"); 3 * you may not use this file except in compliance with the License. 4 * You may obtain a copy of the License at 5 * 6 * http://www.apache.org/licenses/LICENSE-2.0 7 * 8 * Unless required by applicable law or agreed to in writing, software 9 * distributed under the License is distributed on an "AS IS" BASIS, 10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 * See the License for the specific language governing permissions and 12 * limitations under the License. 13 */ 14 15 'use strict'; 16 17 const AdminConnection = require('composer-admin').AdminConnection; 18 const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; 19 const { BusinessNetworkDefinition, CertificateUtil, IdCard } = require('composer-common'); 20 const path = require('path'); 21 22 require('chai').should(); 23 24 //declare namespace 25 const NS = 'org.decentralized.energy.network'; 26 27 //describe test 28 describe('Decentralized Energy - check transactions, access', () => { 29 30 // in-memory card store for testing so cards are not persisted to the file system 31 const cardStore = require('composer-common').NetworkCardStoreManager.getCardStore( { type: 'composer-wallet-inmemory' } ); 32 33 // embedded connection used for local testing 34 const connectionProfile = { 35 name: 'embedded', 36 'x-type': 'embedded' 37 }; 38 39 // name of the business network card containing the administrative identity for the business network 40 const adminCardName = 'admin'; 41 42 // admin connection to the blockchain, used to deploy the business network 43 let adminConnection; 44 45 // this is the business network connection the tests will use. 46 let businessNetworkConnection; 47 48 // these are the identities 49 const R1Identity = 'R1i'; 50 const R2Identity = 'R2i'; 51 const B1Identity = 'B1i'; 52 const U1Identity = 'U1i'; 53 54 let businessNetworkName; 55 let factory; 56 57 // these are a list of receieved events. 58 let events; 59 60 61 before(async () => { 62 // generate certificates for use with the embedded connection 63 const credentials = CertificateUtil.generate({ commonName: 'admin' }); 64 65 // identity used with the admin connection to deploy business networks 66 const deployerMetadata = { 67 version: 1, 68 userName: 'PeerAdmin', 69 roles: [ 'PeerAdmin', 'ChannelAdmin' ] 70 }; 71 const deployerCard = new IdCard(deployerMetadata, connectionProfile); 72 deployerCard.setCredentials(credentials); 73 const deployerCardName = 'PeerAdmin'; 74 75 adminConnection = new AdminConnection({ cardStore: cardStore }); 76 77 await adminConnection.importCard(deployerCardName, deployerCard); 78 await adminConnection.connect(deployerCardName); 79 }); 80 81 /** 82 * 83 * @param {String} cardName The card name to use for this identity 84 * @param {Object} identity The identity details 85 */ 86 async function importCardForIdentity(cardName, identity) { 87 const metadata = { 88 userName: identity.userID, 89 version: 1, 90 enrollmentSecret: identity.userSecret, 91 businessNetwork: businessNetworkName 92 }; 93 const card = new IdCard(metadata, connectionProfile); 94 await adminConnection.importCard(cardName, card); 95 } 96 97 // this is called before each test is executed. 98 beforeEach(async () => { 99 100 // generate a business network definition from the project directory. 101 const businessNetworkDefinition = await BusinessNetworkDefinition.fromDirectory(path.resolve(__dirname, '..')); 102 103 businessNetworkName = businessNetworkDefinition.getName(); 104 await adminConnection.install(businessNetworkDefinition); 105 106 const startOptions = { 107 networkAdmins: [ 108 { 109 userName: 'admin', 110 enrollmentSecret: 'adminpw' 111 } 112 ] 113 }; 114 const adminCards = await adminConnection.start(businessNetworkName, businessNetworkDefinition.getVersion(), startOptions); 115 await adminConnection.importCard(adminCardName, adminCards.get('admin')); 116 117 // create and establish a business network connection 118 businessNetworkConnection = new BusinessNetworkConnection({ cardStore: cardStore }); 119 events = []; 120 businessNetworkConnection.on('event', event => { 121 events.push(event); 122 }); 123 await businessNetworkConnection.connect(adminCardName); 124 125 // get the factory for the business network. 126 factory = businessNetworkConnection.getBusinessNetwork().getFactory(); 127 128 // create 2 coins assets 129 const producer_coins = factory.newResource(NS, 'Coins', 'CO_R1'); 130 producer_coins.value = 300; 131 producer_coins.ownerID = 'R1'; 132 producer_coins.ownerEntity = 'Resident'; 133 134 const consumer_coins = factory.newResource(NS, 'Coins', 'CO_R2'); 135 consumer_coins.value = 450; 136 consumer_coins.ownerID = 'R2'; 137 consumer_coins.ownerEntity = 'Resident'; 138 139 // create 2 energy assets 140 const producer_energy = factory.newResource(NS, 'Energy', 'EN_R1'); 141 producer_energy.value = 35; 142 producer_energy.units = 'kwH'; 143 producer_energy.ownerID = 'R1'; 144 producer_energy.ownerEntity = 'Resident'; 145 146 const consumer_energy = factory.newResource(NS, 'Energy', 'EN_R2'); 147 consumer_energy.value = 5; 148 consumer_energy.units = 'kwH'; 149 consumer_energy.ownerID = 'R2'; 150 consumer_energy.ownerEntity = 'Resident'; 151 152 // create 2 cash assets 153 const producer_cash = factory.newResource(NS, 'Cash', 'CA_R1'); 154 producer_cash.value = 150; 155 producer_cash.currency = 'USD'; 156 producer_cash.ownerID = 'R1'; 157 producer_cash.ownerEntity = 'Resident'; 158 159 const consumer_cash = factory.newResource(NS, 'Cash', 'CA_R2'); 160 consumer_cash.value = 70; 161 consumer_cash.currency = 'USD'; 162 consumer_cash.ownerID = 'R2'; 163 consumer_cash.ownerEntity = 'Resident'; 164 165 // create residents 166 const R1 = factory.newResource(NS, 'Resident', 'R1'); 167 R1.firstName = 'Carlos'; 168 R1.lastName = 'Roca'; 169 R1.coins = factory.newRelationship(NS, 'Coins', producer_coins.$identifier); 170 R1.cash = factory.newRelationship(NS, 'Cash', producer_energy.$identifier); 171 R1.energy = factory.newRelationship(NS, 'Energy', producer_cash.$identifier); 172 173 const R2 = factory.newResource(NS, 'Resident', 'R2'); 174 R2.firstName = 'James'; 175 R2.lastName = 'Jones'; 176 R2.coins = factory.newRelationship(NS, 'Coins', consumer_coins.$identifier); 177 R2.cash = factory.newRelationship(NS, 'Cash', consumer_energy.$identifier); 178 R2.energy = factory.newRelationship(NS, 'Energy', consumer_cash.$identifier); 179 180 // create bank coins asset 181 const bank_coins = factory.newResource(NS, 'Coins', 'CO_B1'); 182 bank_coins.value = 5000; 183 bank_coins.ownerID = 'B1'; 184 bank_coins.ownerEntity = 'Bank'; 185 186 // create bank cash asset 187 const bank_cash = factory.newResource(NS, 'Cash', 'CA_B1'); 188 bank_cash.value = 7000; 189 bank_cash.currency = 'USD'; 190 bank_cash.ownerID = 'B1'; 191 bank_cash.ownerEntity = 'Bank'; 192 193 // create Bank 194 const B1 = factory.newResource(NS, 'Bank', 'B1'); 195 B1.name = 'United Bank'; 196 B1.coins = factory.newRelationship(NS, 'Coins', bank_coins.$identifier); 197 B1.cash = factory.newRelationship(NS, 'Cash', bank_cash.$identifier); 198 199 //confirm the original values 200 bank_coins.value.should.equal(5000); 201 bank_cash.value.should.equal(7000); 202 203 // create utility company coins asset 204 const utility_coins = factory.newResource(NS, 'Coins', 'CO_U1'); 205 utility_coins.value = 5000; 206 utility_coins.ownerID = 'U1'; 207 utility_coins.ownerEntity = 'UtilityCompany'; 208 209 // create utility energy asset 210 const utility_energy = factory.newResource(NS, 'Energy', 'EN_U1'); 211 utility_energy.value = 1000; 212 utility_energy.units = 'kwh'; 213 utility_energy.ownerID = 'U1'; 214 utility_energy.ownerEntity = 'UtilityCompany'; 215 216 // create Utility Company 217 const U1 = factory.newResource(NS, 'UtilityCompany', 'U1'); 218 U1.name = 'New Utility'; 219 U1.coins = factory.newRelationship(NS, 'Coins', utility_coins.$identifier); 220 U1.energy = factory.newRelationship(NS, 'Energy', utility_energy.$identifier); 221 222 //confirm the original values 223 utility_coins.value.should.equal(5000); 224 utility_energy.value.should.equal(1000); 225 226 // Get the coins registry 227 return businessNetworkConnection.getAssetRegistry(NS + '.Coins') 228 .then((assetRegistry) => { 229 // add coins to the coins asset registry. 230 return assetRegistry.addAll([producer_coins, consumer_coins, bank_coins, utility_coins]) 231 232 .then(() => { 233 // Get the energy registry 234 return businessNetworkConnection.getAssetRegistry(NS + '.Energy'); 235 }) 236 .then((assetRegistry) => { 237 // add energy to the energy asset registry. 238 return assetRegistry.addAll([producer_energy, consumer_energy, utility_energy]); 239 }) 240 .then(() => { 241 // Get the cash registry 242 return businessNetworkConnection.getAssetRegistry(NS + '.Cash'); 243 }) 244 .then((assetRegistry) => { 245 // add cash to the cash asset registry. 246 return assetRegistry.addAll([producer_cash, consumer_cash, bank_cash]); 247 }) 248 .then(() => { 249 return businessNetworkConnection.getParticipantRegistry(NS + '.Resident'); 250 }) 251 .then((participantRegistry) => { 252 // add resident 253 return participantRegistry.addAll([R1, R2]); 254 }) 255 .then(() => { 256 return businessNetworkConnection.getParticipantRegistry(NS + '.Bank'); 257 }) 258 .then((participantRegistry) => { 259 // add bank 260 return participantRegistry.add(B1); 261 }) 262 .then(() => { 263 return businessNetworkConnection.getParticipantRegistry(NS + '.UtilityCompany'); 264 }) 265 .then((participantRegistry) => { 266 // add utility company 267 return participantRegistry.add(U1); 268 }) 269 .then(() => { 270 return businessNetworkConnection.issueIdentity('org.decentralized.energy.network.Resident#R1', 'resident1'); 271 }) 272 .then((identity) => { 273 return importCardForIdentity(R1Identity, identity); 274 }) 275 .then(() => { 276 return businessNetworkConnection.issueIdentity('org.decentralized.energy.network.Resident#R2', 'resident2'); 277 }) 278 .then((identity) => { 279 return importCardForIdentity(R2Identity, identity); 280 }) 281 .then(() => { 282 return businessNetworkConnection.issueIdentity('org.decentralized.energy.network.Bank#B1', 'bank1'); 283 }) 284 .then((identity) => { 285 return importCardForIdentity(B1Identity, identity); 286 }) 287 .then(() => { 288 return businessNetworkConnection.issueIdentity('org.decentralized.energy.network.UtilityCompany#U1', 'utility1'); 289 }) 290 .then((identity) => { 291 return importCardForIdentity(U1Identity, identity); 292 }); 293 }); 294 }); 295 296 297 298 describe('#ResidentToResident Transaction', () => { 299 300 it('Residents should be able to execute transactions with Residents' , () => { 301 302 // create the resident to resident transaction 303 const resident_to_resident = factory.newTransaction(NS, 'EnergyToCoins'); 304 resident_to_resident.energyRate = 4; 305 resident_to_resident.energyValue = 10; 306 resident_to_resident.coinsInc = factory.newRelationship(NS, 'Coins', 'CO_R1'); 307 resident_to_resident.coinsDec = factory.newRelationship(NS, 'Coins', 'CO_R2'); 308 resident_to_resident.energyInc = factory.newRelationship(NS, 'Energy', 'EN_R2'); 309 resident_to_resident.energyDec = factory.newRelationship(NS, 'Energy', 'EN_R1'); 310 311 return businessNetworkConnection.submitTransaction(resident_to_resident) 312 .then(() => { 313 return businessNetworkConnection.getAssetRegistry(NS + '.Coins'); 314 }) 315 .then((assetRegistry) => { 316 // re-get the producer_coins 317 return assetRegistry.get('CO_R1'); 318 }) 319 .then((updated_producer_coins) => { 320 // the updated values of coins 321 updated_producer_coins.value.should.equal(340); 322 return businessNetworkConnection.getAssetRegistry(NS + '.Coins'); 323 }) 324 .then((assetRegistry) => { 325 // re-get the consumer_coins 326 return assetRegistry.get('CO_R2'); 327 }) 328 .then((updated_consumer_coins) => { 329 // the updated values of coins 330 updated_consumer_coins.value.should.equal(410); 331 return businessNetworkConnection.getAssetRegistry(NS + '.Energy'); 332 }) 333 .then((assetRegistry) => { 334 // re-get the consumer_energy 335 return assetRegistry.get('EN_R2'); 336 }) 337 .then((updated_consumer_energy) => { 338 // the updated values of energy 339 updated_consumer_energy.value.should.equal(15); 340 return businessNetworkConnection.getAssetRegistry(NS + '.Energy'); 341 }) 342 .then((assetRegistry) => { 343 // re-get the producer_energy 344 return assetRegistry.get('EN_R1'); 345 }) 346 .then((updated_producer_energy) => { 347 // the updated values of energy 348 updated_producer_energy.value.should.equal(25); 349 }); 350 351 }); 352 }); 353 354 describe('#ResidentToBank Transaction', () => { 355 356 it('Residents should be able to execute transactions with Banks' , () => { 357 358 // create the resident to resident transaction 359 const resident_to_bank = factory.newTransaction(NS, 'CashToCoins'); 360 resident_to_bank.cashRate = 2; 361 resident_to_bank.cashValue = 20; 362 resident_to_bank.coinsInc = factory.newRelationship(NS, 'Coins', 'CO_B1'); 363 resident_to_bank.coinsDec = factory.newRelationship(NS, 'Coins', 'CO_R1'); 364 resident_to_bank.cashInc = factory.newRelationship(NS, 'Cash', 'CA_R1'); 365 resident_to_bank.cashDec = factory.newRelationship(NS, 'Cash', 'CA_B1'); 366 367 // submit the transaction 368 return businessNetworkConnection.submitTransaction(resident_to_bank) 369 .then(() => { 370 return businessNetworkConnection.getAssetRegistry(NS + '.Coins'); 371 }) 372 .then((assetRegistry) => { 373 // re-get the producer_coins 374 return assetRegistry.get('CO_R1'); 375 }) 376 .then((updated_resident_coins) => { 377 // the updated values of coins 378 updated_resident_coins.value.should.equal(260); 379 return businessNetworkConnection.getAssetRegistry(NS + '.Coins'); 380 }) 381 .then((assetRegistry) => { 382 // re-get the consumer_coins 383 return assetRegistry.get('CO_B1'); 384 }) 385 .then((updated_bank_coins) => { 386 // the updated values of coins 387 updated_bank_coins.value.should.equal(5040); 388 return businessNetworkConnection.getAssetRegistry(NS + '.Cash'); 389 }) 390 .then((assetRegistry) => { 391 // re-get the resident_cash 392 return assetRegistry.get('CA_R1'); 393 }) 394 .then((updated_resident_cash) => { 395 // the updated values of energy 396 updated_resident_cash.value.should.equal(170); 397 return businessNetworkConnection.getAssetRegistry(NS + '.Cash'); 398 }) 399 .then((assetRegistry) => { 400 // re-get the resident_cash 401 return assetRegistry.get('CA_B1'); 402 }) 403 .then((updated_bank_cash) => { 404 // the updated values ofenergyenergy 405 updated_bank_cash.value.should.equal(6980); 406 }); 407 }); 408 }); 409 410 411 describe('#ResidentToUtilityCompany Transaction', () => { 412 413 it('Residents should be able to execute transactions with UtilityCompanies' , () => { 414 415 416 // create the resident to utility company transaction 417 const resident_to_utility = factory.newTransaction(NS, 'EnergyToCoins'); 418 resident_to_utility.energyRate = 4; 419 resident_to_utility.energyValue = 10; 420 resident_to_utility.coinsInc = factory.newRelationship(NS, 'Coins', 'CO_U1'); 421 resident_to_utility.coinsDec = factory.newRelationship(NS, 'Coins', 'CO_R2'); 422 resident_to_utility.energyInc = factory.newRelationship(NS, 'Energy', 'EN_R2'); 423 resident_to_utility.energyDec = factory.newRelationship(NS, 'Energy', 'EN_U1'); 424 425 return businessNetworkConnection.submitTransaction(resident_to_utility) 426 .then(() => { 427 return businessNetworkConnection.getAssetRegistry(NS + '.Coins'); 428 }) 429 .then((assetRegistry) => { 430 // re-get the utility_coins 431 return assetRegistry.get('CO_U1'); 432 }) 433 .then((updated_utility_coins) => { 434 // the updated values of coins 435 updated_utility_coins.value.should.equal(5040); 436 return businessNetworkConnection.getAssetRegistry(NS + '.Coins'); 437 }) 438 .then((assetRegistry) => { 439 // re-get the consumer_coins 440 return assetRegistry.get('CO_R2'); 441 }) 442 .then((updated_consumer_coins) => { 443 // the updated values of coins 444 updated_consumer_coins.value.should.equal(410); 445 return businessNetworkConnection.getAssetRegistry(NS + '.Energy'); 446 }) 447 .then((assetRegistry) => { 448 // re-get the consumer_energy 449 return assetRegistry.get('EN_R2'); 450 }) 451 .then((updated_consumer_energy) => { 452 // the updated values of energy 453 updated_consumer_energy.value.should.equal(15); 454 return businessNetworkConnection.getAssetRegistry(NS + '.Energy'); 455 }) 456 .then((assetRegistry) => { 457 // re-get the utility_energy 458 return assetRegistry.get('EN_U1'); 459 }) 460 .then((updated_utility_energy) => { 461 // the updated values of energy 462 updated_utility_energy.value.should.equal(990); 463 464 }); 465 }); 466 }); 467 468 /** 469 * Reconnect using a different identity. 470 * @param {String} cardName The identity to use. 471 * @return {Promise} A promise that will be resolved when complete. 472 */ 473 function useIdentity(cardName) { 474 475 return businessNetworkConnection.disconnect() 476 .then(() => { 477 businessNetworkConnection = new BusinessNetworkConnection({ cardStore: cardStore }); 478 return businessNetworkConnection.connect(cardName); 479 }); 480 } 481 482 483 describe('#Residents Access', () => { 484 485 it('Residents should have read access to all coins, energy and cash assets, read access to other Residents, Banks and Utility Companies, and update only their own Resident record' , () => { 486 487 return useIdentity(R2Identity) 488 .then(() => { 489 // use a query 490 return businessNetworkConnection.query('selectResidents'); 491 }) 492 .then((results) => { 493 // check results 494 results.length.should.equal(2); 495 //results[0].getIdentifier().should.equal('R2'); 496 }) 497 .then(() => { 498 // use a query 499 return businessNetworkConnection.query('selectBanks'); 500 }) 501 .then((results) => { 502 // check results 503 results.length.should.equal(1); 504 }) 505 .then(() => { 506 // use a query 507 return businessNetworkConnection.query('selectUtilityCompanies'); 508 }) 509 .then((results) => { 510 // check results 511 results.length.should.equal(1); 512 }) 513 .then(() => { 514 // use a query 515 return businessNetworkConnection.query('selectCoins'); 516 }) 517 .then((results) => { 518 // check results 519 results.length.should.equal(4); 520 }) 521 .then(() => { 522 // use a query 523 return businessNetworkConnection.query('selectCash'); 524 }) 525 .then((results) => { 526 // check results 527 results.length.should.equal(3); 528 }) 529 .then(() => { 530 // use a query 531 return businessNetworkConnection.query('selectEnergy'); 532 }) 533 .then((results) => { 534 // check results 535 results.length.should.equal(3); 536 }); 537 538 }); 539 }); 540 541 describe('#Banks Access', () => { 542 543 it('Banks should have read only access to all coins and cash assets, read access to other Banks and Residents, and update access to their own Bank record' , () => { 544 545 return useIdentity(B1Identity) 546 .then(() => { 547 // use a query 548 return businessNetworkConnection.query('selectResidents'); 549 }) 550 .then((results) => { 551 // check results 552 results.length.should.equal(2); 553 //results[0].getIdentifier().should.equal('R2'); 554 }) 555 .then(() => { 556 // use a query 557 return businessNetworkConnection.query('selectBanks'); 558 }) 559 .then((results) => { 560 // check results 561 results.length.should.equal(1); 562 }) 563 .then(() => { 564 // use a query 565 return businessNetworkConnection.query('selectUtilityCompanies'); 566 }) 567 .then((results) => { 568 // check results 569 results.length.should.equal(0); 570 }) 571 .then(() => { 572 // use a query 573 return businessNetworkConnection.query('selectCoins'); 574 }) 575 .then((results) => { 576 // check results 577 results.length.should.equal(4); 578 }) 579 .then(() => { 580 // use a query 581 return businessNetworkConnection.query('selectCash'); 582 }) 583 .then((results) => { 584 // check results 585 results.length.should.equal(3); 586 }) 587 .then(() => { 588 // use a query 589 return businessNetworkConnection.query('selectEnergy'); 590 }) 591 .then((results) => { 592 // check results 593 results.length.should.equal(0); 594 }); 595 596 }); 597 }); 598 599 600 describe('#Utility Company Access', () => { 601 602 it('Utility Company should have read only access to all coins, and energy assets, read access to other Utilty Companies and Residents, and update access to their own Bank record' , () => { 603 604 return useIdentity(U1Identity) 605 .then(() => { 606 // use a query 607 return businessNetworkConnection.query('selectResidents'); 608 }) 609 .then((results) => { 610 // check results 611 results.length.should.equal(2); 612 //results[0].getIdentifier().should.equal('R2'); 613 }) 614 .then(() => { 615 // use a query 616 return businessNetworkConnection.query('selectBanks'); 617 }) 618 .then((results) => { 619 // check results 620 results.length.should.equal(0); 621 }) 622 .then(() => { 623 // use a query 624 return businessNetworkConnection.query('selectUtilityCompanies'); 625 }) 626 .then((results) => { 627 // check results 628 results.length.should.equal(1); 629 }) 630 .then(() => { 631 // use a query 632 return businessNetworkConnection.query('selectCoins'); 633 }) 634 .then((results) => { 635 // check results 636 results.length.should.equal(4); 637 }) 638 .then(() => { 639 // use a query 640 return businessNetworkConnection.query('selectCash'); 641 }) 642 .then((results) => { 643 // check results 644 results.length.should.equal(0); 645 }) 646 .then(() => { 647 // use a query 648 return businessNetworkConnection.query('selectEnergy'); 649 }) 650 .then((results) => { 651 // check results 652 results.length.should.equal(3); 653 }); 654 655 }); 656 }); 657 658 });