Compare commits

..
118 Commits
Author SHA1 Message Date
Chris Troutner b9146bbff9 Merge pull request #72 from Permissionless-Software-Foundation/ct-unstable
Syncing with upstream ipfs-service-provider
2022-03-08 10:15:33 -08:00
Chris Troutner 47f1b84dd8 Merge branch 'master' of https://github.com/Permissionless-Software-Foundation/ipfs-service-provider into ct-unstable 2022-03-08 10:13:37 -08:00
Chris Troutner fdf73610eb Merge pull request #79 from Permissionless-Software-Foundation/ct-unstable
fix(tests): Updating tests for node.js v16
2022-03-08 09:42:42 -08:00
Chris Troutner b09e77c079 fix(tests): Updating tests for node.js v16 2022-03-08 09:39:54 -08:00
Chris Troutner 5050816052 Merge pull request #71 from Permissionless-Software-Foundation/ct-unstable
fix(ipfs-coord): Updating to v7.1.4
2022-03-05 14:26:18 -08:00
Chris Troutner 7193b9d048 Merge branch 'master' of https://github.com/Permissionless-Software-Foundation/ipfs-service-provider into ct-unstable 2022-03-05 14:23:22 -08:00
Chris Troutner c2977c5264 fix(production): Updating to node v16 for IPFS 2022-03-05 14:23:14 -08:00
Chris Troutner 68ad2561b1 Merge pull request #78 from Permissionless-Software-Foundation/ct-unstable
fix(ipfs-coord): Updating to v7.1.4
2022-03-05 14:22:25 -08:00
Chris Troutner 791d11e597 Merge branch 'master' into ct-unstable 2022-03-05 14:20:19 -08:00
Chris Troutner 5489e76f55 fix(ipfs-coord): Updating to v7.1.4 2022-03-05 14:20:13 -08:00
Chris Troutner 2ad10180d0 Merge pull request #70 from Permissionless-Software-Foundation/ct-upstream
fix(ipfs-coord): Updating to v7.1.3
2022-03-05 08:35:10 -08:00
Chris Troutner dd42f5da16 fix(upstream): Syncing with upstream. Updating ipfs-coord 2022-03-05 08:32:38 -08:00
Chris Troutner 496a1dd07c Merge pull request #77 from Permissionless-Software-Foundation/ct-unstable
fix(ipfs-coord): Updating to v7.1.3
2022-03-05 08:26:32 -08:00
Chris Troutner a7b8ca9ad5 linting 2022-03-05 08:24:50 -08:00
Chris Troutner 6eb16eb11a fix(ipfs-coord): Updating to v7.1.3 2022-03-05 08:24:36 -08:00
Chris Troutner 553957a173 Merge pull request #69 from Permissionless-Software-Foundation/ct-unstable
fix(bch-js): Updating to 5.3.1
2022-01-31 21:20:51 -08:00
Chris Troutner 99a737c7e7 fix(bch-js): Updating to 5.3.1 2022-01-31 21:17:40 -08:00
Chris Troutner ffb87d09c2 Merge pull request #68 from Permissionless-Software-Foundation/ct-unstable
Syncing with upstream ipfs-service-provider
2022-01-31 10:39:37 -08:00
Chris Troutner 65ead3568a Merge branch 'master' into ct-unstable 2022-01-31 10:34:52 -08:00
Chris Troutner b4b2aefac6 synced with upstream ipfs-service-provider 2022-01-31 10:33:54 -08:00
Chris Troutner 1844f30dc5 Merge pull request #76 from Permissionless-Software-Foundation/ct-unstable
fix(ipfs-coord): Bumping to v6.8.12
2022-01-31 10:31:20 -08:00
Chris Troutner b6ab2f02f4 Updating package-lock 2022-01-31 10:29:45 -08:00
Chris Troutner b5c76aa5fe fix(ipfs-coord): Bumping to v6.8.12 2022-01-31 10:28:06 -08:00
Chris Troutner 7648c96a70 Removing console logs 2022-01-29 17:37:22 -08:00
Chris Troutner 79f5adaf6b fix(bch-js): Tweeking initialization at startup 2022-01-29 17:29:26 -08:00
Chris Troutner e2f84d661f Debugging bch-js 2022-01-29 17:13:46 -08:00
Chris Troutner 31091a50a8 fix(startup): Announcing APISERVER when default init of bch-js is overridden 2022-01-29 15:53:45 -08:00
Chris Troutner 512775c68f More debugging 2022-01-29 15:42:50 -08:00
Chris Troutner c53394e547 Merge pull request #67 from Permissionless-Software-Foundation/ct-unstable
Adding debugging to txData()
2022-01-29 15:34:56 -08:00
Chris Troutner 79083502fb Adding debugging to txData() 2022-01-29 14:52:19 -08:00
Chris Troutner 6049c6566f Merge pull request #66 from Permissionless-Software-Foundation/ct-unstable
fix(getTxData): Removing txData property from output
2022-01-29 09:21:25 -08:00
Chris Troutner 99a52ec605 fix(getTxData): Removing txData property from output 2022-01-29 09:19:43 -08:00
Chris Troutner 33e7bc2b52 Merge pull request #65 from Permissionless-Software-Foundation/ct-unstable
feat(txData): Renamed transaction JSON endpoint to txData
2022-01-29 07:39:47 -08:00
Chris Troutner a20f30ec1e feat(txData): Renamed transaction JSON endpoint to txData 2022-01-29 07:38:05 -08:00
Chris Troutner b0b12c590c Merge pull request #64 from Permissionless-Software-Foundation/ct-unstable
feat(txHistory): Renamed transactions JSON endpoint to txHistory
2022-01-29 07:11:58 -08:00
Chris Troutner 286092f2e3 feat(txHistory): Renamed transactions JSON endpoint to txHistory 2022-01-29 07:09:40 -08:00
Chris Troutner 5be93afc38 fix(production): adding .env file to docker folder to prevent orphan warning 2022-01-28 19:43:51 -08:00
Chris Troutner 63cb107a25 Merge pull request #63 from Permissionless-Software-Foundation/ct-unstable
fix(ipfs-coord): Updating to 6.8.11
2022-01-28 19:32:43 -08:00
Chris Troutner c54fb73c7d fix(bch): Adding additional debugging statements for BCH endpoints 2022-01-28 19:31:04 -08:00
Chris Troutner 8063c0e922 fix(ipfs-coord): Updating to 6.8.11 2022-01-28 19:26:41 -08:00
Chris Troutner b729c7ed80 Merge pull request #62 from Permissionless-Software-Foundation/ct-unstable
feat(transaction): Refactoring to allow up to 20 TXIDs per call
2022-01-28 12:06:12 -08:00
Chris Troutner 5a3d91e3b0 feat(transaction): Refactoring to allow up to 20 TXIDs per call 2022-01-28 12:04:35 -08:00
Chris Troutner d9fa44328a Merge pull request #61 from Permissionless-Software-Foundation/ct-unstable
Heavily refactored transaction history JSON RPC endpoint
2022-01-28 08:15:36 -08:00
Chris Troutner efaffa8e0f fix(getTransactions()): Added unit tests 2022-01-28 08:03:35 -08:00
Chris Troutner 27a9e9f3f3 Working on unit tests 2022-01-28 06:55:50 -08:00
Chris Troutner 41a5071467 fix(JSON transactions): Updated to new algorithm 2022-01-28 06:37:18 -08:00
Chris Troutner c6c3bb5d9c More debugging of pagination 2022-01-27 19:01:57 -08:00
Chris Troutner e4977a4351 Debugging pagination 2022-01-27 18:58:28 -08:00
Chris Troutner fe3b45f6be fixing typo 2022-01-27 17:54:17 -08:00
Chris Troutner d25b240112 Debugging 2022-01-27 17:52:16 -08:00
Chris Troutner 7a89a06ddb fix(getTransactions()): Adding pagination to tx history 2022-01-27 17:47:03 -08:00
Chris Troutner 74fb65df72 more debugging 2022-01-27 15:10:46 -08:00
Chris Troutner 0b38247f5a more debugging 2022-01-27 15:05:08 -08:00
Chris Troutner 473aaae307 debugging 2022-01-27 15:00:54 -08:00
Chris Troutner 284f4e4478 Debugging and reporting errors 2022-01-27 14:58:00 -08:00
Chris Troutner 56f6dc273a Restoring bch-js 2022-01-27 09:06:39 -08:00
Chris Troutner 4bd3387bde feat(transactions): Refactored JSON RPC transactions endpoint 2022-01-27 08:47:06 -08:00
Chris Troutner 7e7e91460a fix(integration): Adding integration test script to package.json 2022-01-24 13:21:29 -08:00
Chris Troutner e5f6f24570 Created mock unit tests for BCH use cases 2022-01-24 13:13:55 -08:00
Chris Troutner 818c85e3d4 Merge branch 'master' into ct-unstable 2022-01-24 12:32:24 -08:00
Chris Troutner 4101615a4a Merge pull request #75 from Permissionless-Software-Foundation/ct-unstable
Maintenance
2022-01-20 08:05:50 -08:00
Chris Troutner 34a4072384 fix(restart): Removing code the auto-restarts app after 2 hours 2022-01-20 07:56:40 -08:00
Chris Troutner 5fc72be10c fix(fullstack-jwt.js): Got unit test coverage back to 100% 2022-01-20 07:53:12 -08:00
Chris Troutner 651c4a1346 Debugging transactions JSON RPC endpoint 2022-01-19 15:58:25 -08:00
Chris Troutner 4b90ad5009 fix(bch-js): Upgrading to v5.2.2 2022-01-19 15:31:25 -08:00
Chris Troutner 05ddf8521a fix(bch-js): Updating to v5.2.1 2022-01-19 11:34:58 -08:00
Chris Troutner 88d1805685 Merge pull request #60 from Permissionless-Software-Foundation/ct-unstable
No-op
2022-01-18 15:38:12 -08:00
Chris Troutner ea104b5586 Rolling back debug console.logs 2022-01-18 15:31:15 -08:00
Chris Troutner 4251e2a02d more debugging 2022-01-18 15:22:26 -08:00
Chris Troutner 5e0eb017ef Debugging 2022-01-18 15:16:45 -08:00
Chris Troutner 86946968fe Merge pull request #59 from Permissionless-Software-Foundation/ct-unstable
fix(bch-js): Updating to bch-js v5
2022-01-18 12:40:22 -08:00
Chris Troutner 9597f1963f fix(bch-js): Updating to bch-js v5 2022-01-18 12:38:33 -08:00
Chris Troutner 67d80056ff Merge pull request #58 from Permissionless-Software-Foundation/ct-unstable
New version. Syncing with upstream ipfs-service-provider
2022-01-18 12:32:55 -08:00
Chris Troutner 199677e4c6 synced with upstream ipfs-service-provider 2022-01-18 12:14:51 -08:00
Chris Troutner 86ea5c6354 fix(version): Bumping to v2.0.0 2022-01-18 12:08:36 -08:00
Chris Troutner 7b112a13d4 fix(cors): Fixing bug leading to CORS error 2022-01-12 15:33:04 -08:00
Chris Troutner fe5c573291 Merge pull request #74 from Permissionless-Software-Foundation/ct-unstable
fix(tests): Skipping IPFS stuff in test environment
2022-01-09 11:54:41 -08:00
Chris Troutner 463d7df582 fix(tests): Skipping IPFS stuff in test environment 2022-01-09 11:51:15 -08:00
Chris Troutner 5a1ec640a4 Merge pull request #73 from Permissionless-Software-Foundation/ct-unstable
Adding swarm.key
2022-01-03 11:39:57 -08:00
Chris Troutner 8bb8dbcd23 Updating READMe 2022-01-03 11:35:26 -08:00
Chris Troutner ba212b0997 fix(ipfs): Adding swarm.key file for joining network 2022-01-03 11:22:15 -08:00
Chris Troutner 803496fbc3 Merge pull request #57 from Permissionless-Software-Foundation/ct-unstable
Syncing upstream ipfs-service-provider
2022-01-02 19:15:52 -08:00
Chris Troutner c49ab4f58b Merge branch 'master' of https://github.com/Permissionless-Software-Foundation/ipfs-service-provider into ct-unstable 2022-01-02 19:14:28 -08:00
Chris Troutner 4670bd22af Merge pull request #72 from Permissionless-Software-Foundation/ct-unstable
fix(pubsub): Applying fix for pubsub in external node
2022-01-02 19:13:44 -08:00
Chris Troutner b3e7c63e61 fix(pubsub): Applying fix for pubsub in external node 2022-01-02 19:00:50 -08:00
Chris Troutner 421ca359f2 Merge pull request #56 from Permissionless-Software-Foundation/ct-unstable
Syncing with upstream ipfs-service-provider
2022-01-01 21:06:35 -08:00
Chris Troutner 4e6559ac96 Merge branch 'master' of https://github.com/Permissionless-Software-Foundation/ipfs-service-provider into ct-unstable 2022-01-01 21:04:33 -08:00
Chris Troutner 1fcc92e10d Merge pull request #71 from Permissionless-Software-Foundation/ct-unstable
fix(ipsf-coord): Updating to v6.8.10
2022-01-01 21:01:14 -08:00
Chris Troutner f332aece98 fix(ipsf-coord): Updating to v6.8.10 2022-01-01 20:58:56 -08:00
Chris Troutner 4112b34205 Merge pull request #55 from Permissionless-Software-Foundation/ct-unstable
Syncing with upstream ipfs-service-provider
2022-01-01 20:47:11 -08:00
Chris Troutner 30d0a62455 Merge branch 'master' of https://github.com/Permissionless-Software-Foundation/ipfs-service-provider into ct-unstable 2022-01-01 20:44:41 -08:00
Chris Troutner 89f24e9940 Merge pull request #70 from Permissionless-Software-Foundation/ct-unstable
fix(ipfs-coord): Switching to private network. Updating ipfs-coord
2022-01-01 20:40:23 -08:00
Chris Troutner 25a75dc369 fix(ipfs-coord): Switching to private network. Updating ipfs-coord to v6.8.9 2022-01-01 20:25:40 -08:00
Chris Troutner f36ce14087 fix(ipfs-coord): Updating v6.8.8 2022-01-01 18:58:47 -08:00
Chris Troutner df45792f47 fix(ipfs-coord): Updating to v6.8.7 2022-01-01 18:43:24 -08:00
Chris Troutner 9e71e33ccd Merge pull request #69 from Permissionless-Software-Foundation/ct-unstable
fix(ipfs-coord): Updating to v6.8.6
2022-01-01 18:20:30 -08:00
Chris Troutner c7b0b0c1d5 fix(ipfs-coord): Updating to v6.8.6 2022-01-01 18:19:07 -08:00
Chris Troutner e475e5f4c3 Downgrading ipfs-http-client 2022-01-01 16:41:56 -08:00
Chris Troutner 7fff41b702 fix(production): Fixing typo in docker-compose.yml 2022-01-01 06:51:54 -08:00
Chris Troutner a7f7fc4e14 Merge pull request #54 from Permissionless-Software-Foundation/ct-unstable
Syncing with upstream ipfs-service-provider
2022-01-01 06:48:33 -08:00
Chris Troutner 83ad0d8bfa Merge branch 'master' into ct-unstable 2022-01-01 06:44:04 -08:00
Chris Troutner ac4aaca66e fix(production): Explictly using ipfs v0.11.0 docker container 2022-01-01 06:43:16 -08:00
Chris Troutner 0748106637 Merge pull request #68 from Permissionless-Software-Foundation/ct-unstable
fix(production): using explcit v0.11.0 ipfs docker container
2022-01-01 06:41:36 -08:00
Chris Troutner 27dcc219b9 fix(production): using explcit v0.11.0 ipfs docker container 2022-01-01 06:40:15 -08:00
Chris Troutner 1362e64c42 Merge pull request #53 from Permissionless-Software-Foundation/ct-unstable
Syncing with upstream ipfs-service-provider
2021-12-31 18:44:59 -08:00
Chris Troutner 7aad5db594 Merge branch 'master' of https://github.com/Permissionless-Software-Foundation/ipfs-service-provider into ct-unstable 2021-12-31 18:42:36 -08:00
Chris Troutner b231686a64 Merge pull request #67 from Permissionless-Software-Foundation/ct-unstable
fix(ipfs-coord): Updating to v6.8.5
2021-12-31 18:40:55 -08:00
Chris Troutner 60668430f5 fix(ipfs-coord): Updating to v6.8.5 2021-12-31 18:38:17 -08:00
Chris Troutner cf0fb0f572 Merge pull request #52 from Permissionless-Software-Foundation/ct-unstable
Syncing with upstream ipfs-service-provider
2021-12-31 16:04:19 -08:00
Chris Troutner 68b0117c3d Merge branch 'master' of https://github.com/Permissionless-Software-Foundation/ipfs-service-provider into ct-unstable 2021-12-31 16:02:57 -08:00
Chris Troutner e73440f342 fix(production): Slight tweek to start-production.sh 2021-12-31 16:02:37 -08:00
Chris Troutner b9680508db Merge pull request #66 from Permissionless-Software-Foundation/ct-unstable
fix(ipfs-coord): Updating to v6.8.4
2021-12-31 16:01:32 -08:00
Chris Troutner acebfdef09 fix(ipfs-coord): Updating to v6.8.4 2021-12-31 15:59:06 -08:00
Chris Troutner c3ee71a54f Merge pull request #51 from Permissionless-Software-Foundation/ct-unstable
Syncing with upstream ipfs-service-provider
2021-12-31 15:44:39 -08:00
Chris Troutner 0d9a32488e Merge branch 'master' into ct-unstable 2021-12-31 15:43:00 -08:00
Chris Troutner de7629c93d Syncing with upstream ipfs-service-provider 2021-12-31 15:42:16 -08:00
Chris Troutner 3979694109 Merge pull request #65 from Permissionless-Software-Foundation/ct-unstable
fix(production): Adding instructions for customizing IPFS docker cont…
2021-12-31 15:38:39 -08:00
Chris Troutner ae888d094b fix(production): Adding instructions for customizing IPFS docker container 2021-12-31 15:34:40 -08:00
37 changed files with 7617 additions and 15109 deletions
+18 -4
View File
@@ -24,13 +24,17 @@ This repository is one step in a longer path. Here are the major milestones of t
## Requirements
- node **^14.17.0**
- npm **^7.13.0**
- node **^14.18.2**
- npm **^8.3.0**
- Docker **^20.10.8**
- Docker Compose **^1.27.4**
## Installation
### Development Environment
**Note:** This software now uses an external go-ipfs IPFS node. The instructions below have not been updated to reflect this.
A development environment will allow you modify the code on-the-fly and contribute to the code base of this repository. [PM2](https://www.npmjs.com/package/pm2) is recommended for running this code base as an IPFS Circuit Relay.
- [Video: Installing ipfs-service-provider](https://youtu.be/Z0NsboIVN44)
@@ -41,23 +45,33 @@ git clone https://github.com/Permissionless-Software-Foundation/ipfs-bch-wallet-
cd ipfs-bch-wallet-service
./install-mongo.sh
npm install
cd shell-scripts
cd shell-scripts
./ipfs-bch-wallet-service.sh
```
### Production Environment
The [docker](./production/docker) directory contains a Dockerfile for building a production deployment. However, there is currently [a bug](https://github.com/Permissionless-Software-Foundation/ipfs-service-provider/issues/38) preventing the Docker container from being used as a Circuit Relay.
The [docker](./production/docker) directory contains a Dockerfile for building a production deployment.
```
docker-compose build --no-cache
docker-compose up -d
```
- Bring the containers up once, then take them back down with `docker-compose down`.
- Copy the [swarm.key](./swarm.key) file to `ipfs-service-provider/production/data/go-ipfs/data/swarm.key`.
- Bring the containers back up with `docker-compose up -d`.
### Operation Notes
- There is a memory leak in the version of js-ipfs. The app is currently configured to shut down every 8 hours to flush memory. It relies on a process manager like pm2, Docker, or systemd to restart the app after it shuts down, in order to ensure continuous operation.
- The PSF network operates as a private network. It does not connect or interact with the wider PSF network, relying instead on gateways to bridge the two networks, when they need to share content. This improves the performance and experience for everyone in the PSF network. To join the network, you'll need to add the [swarm.key](./swarm.key) file to the IPFS data folder.
- [Instructions on setting up IPFS private networks.](https://github.com/ipfs/go-ipfs/blob/master/docs/experimental-features.md#private-networks)
- For external installations, the swarm.key file will typically go in `~/.ipfs/swarm.key`
- For production Docker containers, the key would go in `ipfs-service-provider/production/data/go-ipfs/data/swarm.key`
## Structure
The file layout of this repository differs from the koa-api-boilerplate. Instead, it follows the file layout of [Clean Architecture](troutsblog.com/blog/clean-architecture).
+10 -13
View File
@@ -68,6 +68,11 @@ class Server {
app.use(passport.initialize())
app.use(passport.session())
// Enable CORS for testing
// THIS IS A SECURITY RISK. COMMENT OUT FOR PRODUCTION
// Dev Note: This line must come BEFORE controllers.attachRESTControllers()
app.use(cors({ origin: '*' }))
// Attach REST API and JSON RPC controllers to the app.
const Controllers = require('../src/controllers')
const controllers = new Controllers()
@@ -75,10 +80,6 @@ class Server {
app.controllers = controllers
// Enable CORS for testing
// THIS IS A SECURITY RISK. COMMENT OUT FOR PRODUCTION
app.use(cors({ origin: '*' }))
// MIDDLEWARE END
console.log(`Running server in environment: ${config.env}`)
@@ -97,15 +98,11 @@ class Server {
)
}
// Attach the other IPFS controllers
await controllers.attachControllers(app)
// ipfs-coord has a memory leak. This app shuts down after 4 hours. It
// expects to be run by Docker or pm2, which can automatically restart
// the app.
setTimeout(function () {
process.exit(0)
}, 60000 * 60 * 2) // 2 hours
// Attach the other IPFS controllers.
// Skip if this is a test environment.
if (config.env !== 'test') {
await controllers.attachControllers(app)
}
return app
} catch (err) {
+6690 -14911
View File
File diff suppressed because it is too large Load Diff
+6 -4
View File
@@ -1,6 +1,6 @@
{
"name": "ipfs-bch-wallet-service",
"version": "1.11.12",
"version": "2.0.0",
"description": "IPFS and REST service providing blockchain access needed by a wallet. ",
"main": "index.js",
"scripts": {
@@ -9,6 +9,7 @@
"test:all": "export SVC_ENV=test && nyc --reporter=text mocha --exit --timeout 15000 --recursive test/unit test/e2e/automated/",
"test:unit": "export SVC_ENV=test && mocha --exit --timeout 15000 --recursive test/unit/",
"test:e2e:auto": "export SVC_ENV=test && mocha --exit --timeout 30000 test/e2e/automated/",
"test:integration": "export SVC_ENV=test && mocha --timeout 30000 --recursive test/integration/",
"test:temp": "export SVC_ENV=test && mocha --exit --timeout 15000 -g '#rate-limit' test/unit/json-rpc/",
"lint": "standard --env mocha --fix",
"docs": "./node_modules/.bin/apidoc -i src/ -o docs",
@@ -23,12 +24,12 @@
},
"repository": "Permissionless-Software-Foundation/ipfs-bch-wallet-service",
"dependencies": {
"@psf/bch-js": "4.20.28",
"axios": "0.21.1",
"@psf/bch-js": "5.3.2",
"axios": "0.25.0",
"bcryptjs": "2.4.3",
"glob": "7.1.6",
"ipfs": "0.60.0",
"ipfs-coord": "6.8.2",
"ipfs-coord": "7.1.4",
"ipfs-http-client": "55.0.0",
"jsonrpc-lite": "2.2.0",
"jsonwebtoken": "8.5.1",
@@ -64,6 +65,7 @@
"eslint-plugin-prettier": "3.3.1",
"eslint-plugin-standard": "4.0.0",
"husky": "4.3.8",
"lodash.clonedeep": "^4.5.0",
"mocha": "8.2.1",
"nyc": "15.1.0",
"semantic-release": "17.4.4",
+1
View File
@@ -0,0 +1 @@
COMPOSE_PROJECT_NAME=bch-wallet-service
+1 -1
View File
@@ -10,7 +10,7 @@ RUN apt-get update
RUN apt-get install -y sudo git curl nano gnupg wget
#Install Node and NPM
RUN curl -sL https://deb.nodesource.com/setup_14.x -o nodesource_setup.sh
RUN curl -sL https://deb.nodesource.com/setup_16.x -o nodesource_setup.sh
RUN bash nodesource_setup.sh
RUN apt-get install -y nodejs build-essential
+61
View File
@@ -0,0 +1,61 @@
# Docker Containers
The 'production' environment is assumed to be a set of Docker containers orchestrated with Docker Compose. The files in this directory will stand up three Docker containers:
1 An instance of go-ipfs.
2 An instance of MongoDB.
3 The JavaScript software in this repository.
The software in this repository depends on the first two containers, so if they aren't running correctly, the application won't run correctly either.
## IPFS
IPFS can be a little tricky to set up. By default, the container uses the following ports:
- 4001 for TCP connections, exposed publicly.
- 5001 for control by the application, exposed privately.
- 8080 for an IPFS gateway, consumed by the application, exposed privately.
If you already have an IPFS node running on a the computer, you will need to change the ports to avaid a conflict. To change the ports from the default, you'll need to perform a series of steps, and the order of the steps matter.
1. Edit the `docker-compose.yml` file and change the ports. Then save the file. Here is an example:
```
ports:
- 4101:4101
- 172.17.0.1:5101:5101
- 172.17.0.1:8180:8180
```
2. Bring the Docker containers up, and then back down. This will allow the IPFS container to create the config file that you'll need to edit.
- `docker-compose up -d`
- Wait a few seconds.
- `docker-compose down`
3. Update the generated config file at `../data/go-ipfs/data/config`, to update the ports in the config file, like this:
```
"Addresses": {
"API": "/ip4/0.0.0.0/tcp/5101",
"Announce": [],
"AppendAnnounce": [],
"Gateway": "/ip4/0.0.0.0/tcp/8180",
"NoAnnounce": [],
"Swarm": [
"/ip4/0.0.0.0/tcp/4101",
"/ip6/::/tcp/4101",
"/ip4/0.0.0.0/udp/4101/quic",
"/ip6/::/udp/4101/quic"
]
},
```
4. Update the port changes in the `start-production.sh` shell script. This tells the application which ports to use, in order to control the IPFS node, are are used when signaling other nodes.
5. Quickly rebuild the containers, to add the modified `start-production.sh` shell script to the application Docker container:
- `docker-compose build`
6. Now start the containers, and the port changes to IPFS should be complete.
+3 -3
View File
@@ -14,7 +14,7 @@ services:
restart: always
ipfs-bch-wallet:
image: ipfs/go-ipfs:latest
image: ipfs/go-ipfs:v0.11.0
container_name: ipfs-bch-wallet
environment:
MY_ENV_VAR: 'placeholder'
@@ -26,8 +26,8 @@ services:
mem_limit: 2000mb
ports:
- 4001:4001
- 5001:5001
- 8080:8080
- 172.17.0.1:5001:5001
- 172.17.0.1:8080:8080
volumes:
- ../data/go-ipfs/data:/data/ipfs
- ../data/go-ipfs/export:/export
+12 -13
View File
@@ -17,7 +17,16 @@ export COORD_NAME=bch-wallet-service-generic
#export CR_DOMAIN=subdomain.yourdomain.com
# Debug level. 0 = minimal info. 2 = max info.
export DEBUG_LEVEL=1
export DEBUG_LEVEL=2
# BCH Wallet Service Settings
# Change APISERVER to point to your own installation of bch-api
export APISERVER=https://api.fullstack.cash/v5/
# These settings are used to proxy a subscription to FullStack.cash.
#export GET_JWT_AT_STARTUP=1
export AUTHSERVER=https://auth.fullstack.cash
export FULLSTACKLOGIN=demo@demo.com
export FULLSTACKPASS=demo
# END: Optional configuration settings
@@ -25,18 +34,6 @@ export DEBUG_LEVEL=1
# Production database connection string.
export DBURL=mongodb://172.17.0.1:5555/ipfs-service-prod
# Customize these environment variables for your own installation.
export GET_JWT_AT_STARTUP=1
export AUTHSERVER=https://auth.fullstack.cash
export APISERVER=https://api.fullstack.cash/v5/
export FULLSTACKLOGIN=demo@demo.com
export FULLSTACKPASS=demo
# Configure IPFS ports
#export IPFS_TCP_PORT=5268
#export IPFS_WS_PORT=5269
# Configure REST API port
export PORT=5010
@@ -44,5 +41,7 @@ export PORT=5010
export SVC_ENV=production
export IPFS_HOST=172.17.0.1
export IPFS_API_PORT=5001
export IPFS_TCP_PORT=4001
#export IPFS_WS_PORT=4002
npm start
+34
View File
@@ -0,0 +1,34 @@
#!/bin/bash
# This script is an example for running a production environment, which is
# defined by running an external go-ipfs node.
# Ports
export PORT=5010 # REST API port
# The human-readible name that is used when displaying data about this node.
export COORD_NAME=ipfs-bch-service-generic
# This is used for end-to-end encryption (e2ee).
export MNEMONIC="churn aisle shield silver ladder swear hunt slim pen demand spoil veteran"
# 0 = less verbose. 3 = most verbose
export DEBUG_LEVEL=2
# Production settings that use external IPFS node.
# https://github.com/christroutner/docker-ipfs
export SVC_ENV=production
export IPFS_HOST=localhost
#export IPFS_HOST=172.17.0.1
export IPFS_API_PORT=5001
# Configure IPFS ports
export IPFS_TCP_PORT=4001
#export IPFS_WS_PORT=5269
# MongoDB connection string.
export DBURL=mongodb://localhost:27017/ipfs-service-dev
export ENABLE_CIRCUIT_RELAY=true
npm start
+5 -1
View File
@@ -13,7 +13,7 @@ export COORD_NAME=ipfs-service-provider-generic
export MNEMONIC="churn aisle shield silver ladder swear hunt slim pen demand spoil veteran"
# 0 = less verbose. 3 = most verbose
export DEBUG_LEVEL=1
export DEBUG_LEVEL=2
# Production settings that use external IPFS node.
# https://github.com/christroutner/docker-ipfs
@@ -22,6 +22,10 @@ export SVC_ENV=production
export IPFS_HOST=172.17.0.1
export IPFS_API_PORT=5001
# Configure IPFS ports
export IPFS_TCP_PORT=4001
#export IPFS_WS_PORT=5269
# MongoDB connection string.
export DBURL=mongodb://localhost:27017/ipfs-service-dev
-6
View File
@@ -52,12 +52,6 @@ class FullStackJWT {
// Get's a JWT token from FullStack.cash.
async getJWT () {
try {
// Skip connecting FullStack.cash auth server to the network if this is an E2E test.
if (process.env.TEST_TYPE === 'e2e') {
this.apiToken = 'faketoken'
return this.apiToken
}
// Log into the auth server.
await this.jwtLib.register()
+9 -4
View File
@@ -22,14 +22,14 @@ const config = require('../../config')
class Adapters {
constructor (localConfig = {}) {
// Encapsulate dependencies
this.config = config
this.ipfs = new IPFSAdapter()
this.localdb = new LocalDB()
this.logapi = new LogsAPI()
this.passport = new Passport()
this.nodemailer = new Nodemailer()
this.jsonFiles = new JSONFiles()
this.bchjs = new BCHJS()
this.config = config
this.bchjs = new BCHJS({ restURL: this.config.apiServer })
// Get a valid JWT API key and instance bch-js.
this.fullStackJwt = new FullStackJWT(config)
@@ -44,11 +44,16 @@ class Adapters {
// Instantiate bch-js with the JWT token, and overwrite the placeholder for bch-js.
this.bchjs = await this.fullStackJwt.instanceBchjs()
} else {
// console.log(
// `Initializing bchjs with this restURL: ${this.config.apiServer}`
// )
this.bchjs = new BCHJS({ restURL: this.config.apiServer })
}
// Start the IPFS node.
await this.ipfs.start({ bchjs: this.bchjs })
if (this.config.env !== 'test') {
// Start the IPFS node.
await this.ipfs.start({ bchjs: this.bchjs })
}
} catch (err) {
console.error('Error in adapters/index.js/start()')
throw err
+1 -1
View File
@@ -98,7 +98,7 @@ class IpfsCoordAdapter {
attachRPCRouter (router) {
try {
_this.ipfsCoord.privateLog = router
_this.ipfsCoord.adapters.orbit.privateLog = router
_this.ipfsCoord.adapters.pubsub.privateLog = router
} catch (err) {
console.error('Error in attachRPCRouter()')
throw err
+3 -1
View File
@@ -14,6 +14,7 @@
const IPFSembedded = require('ipfs')
const IPFSexternal = require('ipfs-http-client')
const fs = require('fs')
const http = require('http')
// Local libraries
const config = require('../../../config')
@@ -74,7 +75,8 @@ class IpfsAdapter {
const ipfsOptionsExternal = {
host: this.config.ipfsHost,
port: this.config.ipfsApiPort
port: this.config.ipfsApiPort,
agent: http.Agent({ keepAlive: true, maxSockets: 2000 })
}
let ipfsOptions = ipfsOptionsEmbedded
+5
View File
@@ -1,5 +1,8 @@
/*
This is the JSON RPC router for the users API
CT 3/5/22: This library can probably be deleted. Handling of the /about endpoint
is now directly controlled by the ipfs-coord library.
*/
// Public npm libraries
@@ -33,6 +36,8 @@ class AboutRPC {
// This is a bit different than other router libraries, because there is
// only one response, which is a string about this node.
async aboutRouter (rpcData) {
console.log('debugging: aboutRouter from ipfs-service-provider triggered')
return {
success: true,
status: 200,
+47 -55
View File
@@ -32,7 +32,6 @@ class BCHRPC {
this.jsonrpc = jsonrpc
this.validators = new Validators(localConfig)
this.rateLimit = new RateLimit()
// this.bchjs = new BCHJS()
this.bchjs = this.adapters.bchjs
}
@@ -49,9 +48,9 @@ class BCHRPC {
// Route the call based on the value of the method property.
switch (endpoint) {
case 'transactions':
case 'txHistory':
await this.rateLimit.limiter(rpcData.from)
return await this.transactions(rpcData)
return await this.txHistory(rpcData)
case 'balance':
await this.rateLimit.limiter(rpcData.from)
@@ -65,9 +64,9 @@ class BCHRPC {
await this.rateLimit.limiter(rpcData.from)
return await this.broadcast(rpcData)
case 'transaction':
case 'txData':
await this.rateLimit.limiter(rpcData.from)
return await this.transaction(rpcData)
return await this.txData(rpcData)
case 'pubkey':
await this.rateLimit.limiter(rpcData.from)
@@ -87,12 +86,20 @@ class BCHRPC {
}
/**
* @api {JSON} /bch Transactions
* @api {JSON} /bch TX History
* @apiPermission public
* @apiName Transactions
* @apiName txHistory
* @apiGroup JSON BCH
* @apiDescription This endpoint wraps the bchjs.Electrumx.transactions([]) function.
* Given the 'addresses' property this endpoint returns an object with the following properties
* It returns the transaction history for an address. This list of TXIDs is
* sorted and paginated.
*
* There are three possible inputs:
* - address: (required) the address to query for a transaction history
* - sortOrder: (optional) will sort results in 'DECENDING' (default) or 'ASCENDING' order.
* - page: (optional) will return a 'page' of 100 results. Default is 0
*
* Given the 'address' property this endpoint returns an object with the following properties
*
* - jsonrpc: "" - jsonrpc version
* - id: "" - jsonrpc id
@@ -101,15 +108,14 @@ class BCHRPC {
* - receiver: "" - Receiver address
* - value: {} - Final result value of the petition
* - success : - Petition status
* - transactions : [] - Transactions of the provided adresses
* - transactions: [] - Transaction details
* - height : - Reference to the blockchain size
* - tx_hash: "" - Hash of the transaction
* - address : "" - Address asociated to the transactions
* - txs : [] - Transactions of the provided address
* - height : - Reference to the blockchain size
* - tx_hash: "" - Hash of the transaction
* - address : "" - Address asociated to the transactions
* - status: - HTTP Status Code
*
* @apiExample Example usage:
* {"jsonrpc":"2.0","id":"555","method":"bch","params":{ "endpoint": "transactions", "addresses": ["bitcoincash:qrl2nlsaayk6ekxn80pq0ks32dya8xfclyktem2mqj"]}}
* {"jsonrpc":"2.0","id":"555","method":"bch","params":{ "endpoint": "txHistory", "addresses": ["bitcoincash:qrl2nlsaayk6ekxn80pq0ks32dya8xfclyktem2mqj"], "sortOrder": "DESCENDING", "page": 0}}
*
* @apiSuccessExample {json} Success-Response:
* {
@@ -119,36 +125,29 @@ class BCHRPC {
* "method":"bch",
* "reciever":"QmU86vLVbUY1UhziKB6rak7GPKRA2QHWvzNm2AjEvXNsT6",
* "value":{
* "address":"bitcoincash:qrl2nlsaayk6ekxn80pq0ks32dya8xfclyktem2mqj"
* "success":true,
* "transactions":[
* {
* "transactions":[
* {
* "height":631219,
* "tx_hash":"ae2daa01c8172545b5edd205ea438706bcb74e63d4084a26b9ff2a46d46dc97f"
* }
* ],
* "address":"bitcoincash:qrl2nlsaayk6ekxn80pq0ks32dya8xfclyktem2mqj"
* }
* "txs":[
* {
* "height":631219,
* "tx_hash":"ae2daa01c8172545b5edd205ea438706bcb74e63d4084a26b9ff2a46d46dc97f"
* }
* ],
* "status":200
* }
* }
* }
*/
async transactions (rpcData) {
async txHistory (rpcData) {
try {
// console.log('createUser rpcData: ', rpcData)
// console.log('transactions rpcData: ', rpcData)
const addrs = rpcData.payload.params.addresses
// const addr = rpcData.payload.params.address
// const sortOrder = rpcData.payload.params.sortOrder
const data = await this.bchjs.Electrumx.transactions(addrs)
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
const data = await this.useCases.bch.getTransactions(rpcData)
const retObj = data
retObj.status = 200
return retObj
return data
} catch (err) {
console.error('Error in JSON RPC BCH transactions()')
// throw err
@@ -158,7 +157,7 @@ class BCHRPC {
success: false,
status: 422,
message: err.message,
endpoint: 'transactions'
endpoint: 'txHistory'
}
}
}
@@ -331,7 +330,7 @@ class BCHRPC {
// console.log('createUser rpcData: ', rpcData)
const addr = rpcData.payload.params.address
console.log('addr: ', addr)
// console.log('addr: ', addr)
const data = await this.bchjs.Utxo.get(addr)
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
@@ -429,12 +428,14 @@ class BCHRPC {
}
/**
* @api {JSON} /bch Transaction
* @api {JSON} /bch Transaction Data
* @apiPermission public
* @apiName Transaction
* @apiName txData
* @apiGroup JSON BCH
* @apiDescription Get data about a specific transaction.
* Given a transaction the endpoint will return an object with the
* @apiDescription Get expanded transaction data for an array of transaction
* IDs. Each call is limited to 20 TXIDs or less.
*
* Given a transaction ID, the endpoint will return an object with the
* following properties
*
* - jsonrpc: "" - jsonrpc version
@@ -459,13 +460,13 @@ class BCHRPC {
* - status: - HTTP Status Code
*
* @apiExample Example usage:
* {"jsonrpc":"2.0","id":"555","method":"bch","params":{ "endpoint": "transaction", "txid": "01517ff1587fa5ffe6f5eb91c99cf3f2d22330cd7ee847e928ce90ca95bf781b"}}
* {"jsonrpc":"2.0","id":"555","method":"bch","params":{ "endpoint": "txData", "txids": ["01517ff1587fa5ffe6f5eb91c99cf3f2d22330cd7ee847e928ce90ca95bf781b"]}}
*
* @apiSuccessExample {json} Success-Response:
* {
* "jsonrpc":"2.0",
* "id":"555",
* "result":{
* "txData": [{
* "method":"bch",
* "reciever":"QmU86vLVbUY1UhziKB6rak7GPKRA2QHWvzNm2AjEvXNsT6",
* "value":{
@@ -520,23 +521,14 @@ class BCHRPC {
* "status":200
* }
* }
* }
* }]
*/
async transaction (rpcData) {
async txData (rpcData) {
try {
// console.log('transaction rpcData: ', rpcData)
const txid = rpcData.payload.params.txid
const data = await this.bchjs.Transaction.get(txid.toString())
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
const retObj = data
retObj.status = 200
const retObj = await this.useCases.bch.getTxData(rpcData)
return retObj
} catch (err) {
console.error('Error in JSON RPC BCH transaction()')
console.error('Error in JSON RPC BCH txData()): ', err)
// throw err
// Return an error response
@@ -544,7 +536,7 @@ class BCHRPC {
success: false,
status: 422,
message: err.message,
endpoint: 'transaction'
endpoint: 'txData'
}
}
}
+7
View File
@@ -92,6 +92,13 @@ class JSONRPC {
wlogger.info(
`JSON RPC received from ${from}, ID: ${parsedData.payload.id}, type: ${parsedData.type}, method: ${parsedData.payload.method}`
)
// Additional debugging for BCH.
if (parsedData.payload.method === 'bch') {
wlogger.info(
`rpcData.payload: ${JSON.stringify(parsedData.payload, null, 2)}`
)
}
}
// Added the property "from" to the parsedData object;
+142
View File
@@ -0,0 +1,142 @@
/*
Use Cases for interacting with the BCH blockchain.
*/
class BCHUseCases {
constructor (localConfig = {}) {
// console.log('User localConfig: ', localConfig)
this.adapters = localConfig.adapters
if (!this.adapters) {
throw new Error(
'Instance of adapters must be passed in when instantiating BCH Use Cases library.'
)
}
// Encapsulate dependencies
this.bchjs = this.adapters.bchjs
}
// Get transaction history for an address, sorted by block height.
async getTransactions (rpcData) {
try {
// console.log(
// `getTransactions rpcData: ${JSON.stringify(rpcData, null, 2)}`
// )
// Get the list of addresses.
const addr = rpcData.payload.params.address
// Default to descending sorting.
let sortOrder = rpcData.payload.params.sortOrder
if (!sortOrder) sortOrder = 'DESCENDING'
// console.log('sortOrder: ', sortOrder)
// Default to page 1
let page = rpcData.payload.params.page
if (!page) page = 0
// console.log('page: ', page)
// Get the transaction history for the list of addresses.
const data = await this.bchjs.Electrumx.transactions([addr])
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
if (!data.success) {
throw new Error('Could not query Fulcrum indexer.')
}
// console.log(`transactions: ${JSON.stringify(transactions, null, 2)}`);
// Sort the transactions.
const txsArr = await this.bchjs.Electrumx.sortAllTxs(
data.transactions[0].transactions,
sortOrder
)
// console.log(`txsArr: ${JSON.stringify(txsArr, null, 2)}`)
// Paginate the results
const pagedResults = this.bchjs.Util.chunk100(txsArr)
// console.log(
// `pagedResults[page]: ${JSON.stringify(pagedResults[page], null, 2)}`
// )
const retObj = {
address: addr,
txs: pagedResults[page],
status: 200,
success: true
}
// console.log(`retObj: ${JSON.stringify(retObj, null, 2)}`)
return retObj
} catch (err) {
console.error('Error in JSON RPC BCH transactions(): ', err)
// throw err
// Return an error response
return {
success: false,
status: 422,
message: err.message,
endpoint: 'txHistory'
}
}
}
// Get transaction data for an array of TXIDs.
async getTxData (rpcData) {
try {
// console.log('transaction rpcData: ', rpcData)
const txids = rpcData.payload.params.txids
// console.log(`txids: ${JSON.stringify(txids, null, 2)}`)
if (!Array.isArray(txids)) {
return {
success: false,
status: 422,
message: 'Input txids must be an array of transaction IDs.',
endpoint: 'txData'
}
}
if (txids.length > 20) {
return {
success: false,
status: 422,
message: 'Array input must be 20 elements or less.',
endpoint: 'txData'
}
}
const txData = []
for (let i = 0; i < txids.length; i++) {
const thisTxid = txids[i]
// console.log(`this.bchjs.restURL: ${this.bchjs.restURL}`)
const data = await this.bchjs.Transaction.get(thisTxid.toString())
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
txData.push(data.txData)
}
const retObj = {
status: 200,
txData
}
return retObj
} catch (err) {
console.error('Error in JSON RPC BCH getTxData(): ', err)
// throw err
// Return an error response
return {
success: false,
status: 422,
message: err.message,
endpoint: 'txData'
}
}
}
}
module.exports = BCHUseCases
+3
View File
@@ -4,7 +4,9 @@
https://troutsblog.com/blog/clean-architecture
*/
// Local libraries
const UserUseCases = require('./user')
const BCHUseCases = require('./bch')
class UseCases {
constructor (localConfig = {}) {
@@ -17,6 +19,7 @@ class UseCases {
// console.log('use-cases/index.js localConfig: ', localConfig)
this.user = new UserUseCases(localConfig)
this.bch = new BCHUseCases(localConfig)
}
}
+3
View File
@@ -0,0 +1,3 @@
/key/swarm/psk/1.0.0/
/base16/
bbd935b70105b03ebd0c6a3c2d2730cd22fc0d18c490ccf689b6c8a22e1bed2a
+12 -4
View File
@@ -5,10 +5,11 @@
// Public npm libraries
const BCHJS = require('@psf/bch-js')
const IpfsCoord = require('ipfs-coord')
const IPFS = require('@chris.troutner/ipfs')
const IPFS = require('ipfs-http-client')
const EventEmitter = require('events')
const { v4: uid } = require('uuid')
const jsonrpc = require('jsonrpc-lite')
const http = require('http')
let _this
@@ -88,8 +89,14 @@ class TestUtils {
async startIpfs () {
try {
const ipfsOptionsExternal = {
host: 'localhost',
port: 5001,
agent: http.Agent({ keepAlive: true, maxSockets: 2000 })
}
// Start the IPFS node.
this.ipfs = await IPFS.create()
this.ipfs = await IPFS.create(ipfsOptionsExternal)
await this.ipfs.config.profiles.apply('server')
// Start ipfs-coord.
@@ -101,7 +108,8 @@ class TestUtils {
privateLog: this.rpcHandler, // Default to console.log
isCircuitRelay: false,
apiInfo: 'none',
announceJsonLd: announceJsonLd
announceJsonLd: announceJsonLd,
nodeType: 'external'
})
await this.ipfsCoord.start()
@@ -214,7 +222,7 @@ class TestUtils {
const id = uid()
const cmd = jsonrpc.request(id, 'bch', {
endpoint: 'transactions',
addresses: ['bitcoincash:qrl2nlsaayk6ekxn80pq0ks32dya8xfclyktem2mqj']
address: 'bitcoincash:qrl2nlsaayk6ekxn80pq0ks32dya8xfclyktem2mqj'
})
const cmdStr = JSON.stringify(cmd)
+2 -2
View File
@@ -1,4 +1,4 @@
{
"uutAddr": "/ip4/127.0.0.1/tcp/5268/p2p/QmdBGB8S6sEr19gaAxJYjhRbz5ZmMiH5a1JyyMmaxcRKnY",
"uutId": "QmdBGB8S6sEr19gaAxJYjhRbz5ZmMiH5a1JyyMmaxcRKnY"
"uutAddr": "/ip4/88.99.188.196/tcp/4001/p2p/12D3KooWT2tDg2pHwKz84Htzh2KsfSUZbZXmoAUFnaSwUVrDsag3/p2p-circuit/ipfs/12D3KooWNuZPDb15ENgk2CYF2dByq1oK6CQ5tUpRW9CpwwNynuJY",
"uutId": "12D3KooWNuZPDb15ENgk2CYF2dByq1oK6CQ5tUpRW9CpwwNynuJY"
}
@@ -0,0 +1,130 @@
/*
Integration tests for the BCH Use Cases library
*/
// Global npm libraries
const assert = require('chai').assert
// Local libraries
const BCHUseCases = require('../../../../src/use-cases/bch')
const Adapters = require('../../../../src/adapters')
describe('#BCH', () => {
let uut
before(async () => {
const adapters = new Adapters()
await adapters.start()
uut = new BCHUseCases({ adapters })
})
describe('#getTransactions', () => {
it('should get transactions for an address, with default descending sorting', async () => {
const rpcData = {
payload: {
params: {
address: 'bitcoincash:qpdh9s677ya8tnx7zdhfrn8qfyvy22wj4qa7nwqa5v'
}
}
}
const result = await uut.getTransactions(rpcData)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.equal(result.success, true)
assert.equal(result.status, 200)
assert.isArray(result.txs)
// Assert descending sort order.
assert.isAbove(result.txs[0].height, result.txs[1].height)
})
it('should get transactions for an address, with explicit descending sorting', async () => {
const rpcData = {
payload: {
params: {
address: 'bitcoincash:qpdh9s677ya8tnx7zdhfrn8qfyvy22wj4qa7nwqa5v',
sortOrder: 'DESCENDING'
}
}
}
const result = await uut.getTransactions(rpcData)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.equal(result.success, true)
assert.equal(result.status, 200)
assert.isArray(result.txs)
// Assert descending sort order.
assert.isAbove(result.txs[0].height, result.txs[1].height)
})
it('should sort in ascending order', async () => {
const rpcData = {
payload: {
params: {
address: 'bitcoincash:qpdh9s677ya8tnx7zdhfrn8qfyvy22wj4qa7nwqa5v',
sortOrder: 'ASCENDING'
}
}
}
const result = await uut.getTransactions(rpcData)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.equal(result.success, true)
assert.equal(result.status, 200)
assert.isArray(result.txs)
// Assert descending sort order.
assert.isAbove(result.txs[1].height, result.txs[0].height)
})
})
describe('#getTxData', () => {
it('should get data for a single non-SLP tx', async () => {
const txids = [
'11384d7e5a8af93806591debe5bbe2d7826aeea987b874dfbe372dfdcc0ee54f'
]
const rpcData = {
payload: {
params: {
txids
}
}
}
const result = await uut.getTxData(rpcData)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.equal(result.status, 200)
assert.isArray(result.txData)
assert.equal(result.txData.length, 1)
})
it('should get data on multiple non-SLP txs', async () => {
const txids = [
'11384d7e5a8af93806591debe5bbe2d7826aeea987b874dfbe372dfdcc0ee54f',
'f9b54fd8d27b0237923437ed4df8d45557f52b3ad4d8d03d4104e925c84ab4ca'
]
const rpcData = {
payload: {
params: {
txids
}
}
}
const result = await uut.getTxData(rpcData)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.equal(result.status, 200)
assert.isArray(result.txData)
assert.equal(result.txData.length, 2)
})
})
})
@@ -89,8 +89,9 @@ describe('#IPFS', () => {
}
},
adapters: {
orbit: {
privateLog: () => {}
pubsub: {
privateLog: () => {
}
}
}
}
@@ -111,7 +112,7 @@ describe('#IPFS', () => {
assert.fail('Unexpected code path')
} catch (err) {
assert.include(err.message, 'Cannot read property')
assert.include(err.message, 'Cannot read')
}
})
})
+22 -21
View File
@@ -52,7 +52,8 @@ describe('#IPFS-adapter', () => {
it('should stop the IPFS node', async () => {
// Mock dependencies
uut.ipfs = {
stop: () => {}
stop: () => {
}
}
const result = await uut.stop()
@@ -61,24 +62,24 @@ describe('#IPFS-adapter', () => {
})
})
describe('#rmBlocksDir', () => {
it('should delete the /blocks directory', () => {
const result = uut.rmBlocksDir()
assert.equal(result, true)
})
it('should catch and throw an error', () => {
try {
// Force an error
sandbox.stub(uut.fs, 'rmdirSync').throws(new Error('test error'))
uut.rmBlocksDir()
assert.fail('Unexpected code path')
} catch (err) {
assert.equal(err.message, 'test error')
}
})
})
// describe('#rmBlocksDir', () => {
// it('should delete the /blocks directory', () => {
// const result = uut.rmBlocksDir()
//
// assert.equal(result, true)
// })
//
// it('should catch and throw an error', () => {
// try {
// // Force an error
// sandbox.stub(uut.fs, 'rmdirSync').throws(new Error('test error'))
//
// uut.rmBlocksDir()
//
// assert.fail('Unexpected code path')
// } catch (err) {
// assert.equal(err.message, 'test error')
// }
// })
// })
})
@@ -61,15 +61,15 @@ describe('#BCHRPC', () => {
})
describe('#bchRouter', () => {
it('should route to the transactions method', async () => {
it('should route to the txHistory method', async () => {
// Mock dependencies
sandbox.stub(uut, 'transactions').resolves(true)
sandbox.stub(uut, 'txHistory').resolves(true)
// Generate the parsed data that the main router would pass to this
// endpoint.
const id = uid()
const txCall = jsonrpc.request(id, 'bch', {
endpoint: 'transactions'
endpoint: 'txHistory'
})
const jsonStr = JSON.stringify(txCall, null, 2)
const rpcData = jsonrpc.parse(jsonStr)
@@ -137,15 +137,15 @@ describe('#BCHRPC', () => {
assert.equal(result, true)
})
it('should route to the transaction method', async () => {
it('should route to the txData method', async () => {
// Mock dependencies
sandbox.stub(uut, 'transaction').resolves(true)
sandbox.stub(uut, 'txData').resolves(true)
// Generate the parsed data that the main router would pass to this
// endpoint.
const id = uid()
const rpcCall = jsonrpc.request(id, 'bch', {
endpoint: 'transaction'
endpoint: 'txData'
})
const jsonStr = JSON.stringify(rpcCall, null, 2)
const rpcData = jsonrpc.parse(jsonStr)
@@ -155,6 +155,7 @@ describe('#BCHRPC', () => {
assert.equal(result, true)
})
it('should route to the pubkey method', async () => {
// Mock dependencies
sandbox.stub(uut, 'pubKey').resolves(true)
@@ -176,13 +177,13 @@ describe('#BCHRPC', () => {
it('should return 500 status on routing issue', async () => {
// Mock dependencies
sandbox.stub(uut, 'transactions').rejects(new Error('test error'))
sandbox.stub(uut, 'txHistory').rejects(new Error('test error'))
// Generate the parsed data that the main router would pass to this
// endpoint.
const id = uid()
const txCall = jsonrpc.request(id, 'bch', {
endpoint: 'transactions'
endpoint: 'txHistory'
})
const jsonStr = JSON.stringify(txCall, null, 2)
const rpcData = jsonrpc.parse(jsonStr)
@@ -193,29 +194,24 @@ describe('#BCHRPC', () => {
assert.equal(result.success, false)
assert.equal(result.status, 500)
assert.equal(result.message, 'test error')
assert.equal(result.endpoint, 'transactions')
assert.equal(result.endpoint, 'txHistory')
})
})
describe('#transactions', () => {
describe('#txHistory', () => {
it('should return data from bchjs', async () => {
// Mock dependencies
sandbox
.stub(uut.bchjs.Electrumx, 'transactions')
.resolves({ success: true })
// Generate the parsed data that the main router would pass to this
// endpoint.
const id = uid()
const txCall = jsonrpc.request(id, 'bch', {
endpoint: 'transactions',
endpoint: 'txHistory',
addresses: 'testAddr'
})
const jsonStr = JSON.stringify(txCall, null, 2)
const rpcData = jsonrpc.parse(jsonStr)
const response = await uut.transactions(rpcData)
// console.log('response: ', response)
const response = await uut.txHistory(rpcData)
console.log('response: ', response)
assert.equal(response.success, true)
assert.equal(response.status, 200)
@@ -224,26 +220,26 @@ describe('#BCHRPC', () => {
it('should return an error for invalid address', async () => {
// Force an error
sandbox
.stub(uut.bchjs.Electrumx, 'transactions')
.stub(uut.useCases.bch, 'getTransactions')
.rejects(new Error('Invalid address'))
// Generate the parsed data that the main router would pass to this
// endpoint.
const id = uid()
const txCall = jsonrpc.request(id, 'bch', {
endpoint: 'transactions',
endpoint: 'txHistory',
addresses: 'testAddr'
})
const jsonStr = JSON.stringify(txCall, null, 2)
const rpcData = jsonrpc.parse(jsonStr)
const response = await uut.transactions(rpcData)
const response = await uut.txHistory(rpcData)
// console.log('response: ', response)
assert.equal(response.success, false)
assert.equal(response.status, 422)
assert.equal(response.message, 'Invalid address')
assert.equal(response.endpoint, 'transactions')
assert.equal(response.endpoint, 'txHistory')
})
})
@@ -391,22 +387,19 @@ describe('#BCHRPC', () => {
})
})
describe('#transaction', () => {
it('should return data from bchjs', async () => {
// Mock dependencies
sandbox.stub(uut.bchjs.Transaction, 'get').resolves({ success: true })
describe('#txData', () => {
it('should route data to the use-case library', async () => {
// Generate the parsed data that the main router would pass to this
// endpoint.
const id = uid()
const rpcCall = jsonrpc.request(id, 'bch', {
endpoint: 'transaction',
endpoint: 'txData',
txid: 'testData'
})
const jsonStr = JSON.stringify(rpcCall, null, 2)
const rpcData = jsonrpc.parse(jsonStr)
const response = await uut.transaction(rpcData)
const response = await uut.txData(rpcData)
// console.log('response: ', response)
assert.equal(response.success, true)
@@ -416,33 +409,37 @@ describe('#BCHRPC', () => {
it('should return an error for invalid input', async () => {
// Force an error
sandbox
.stub(uut.bchjs.Transaction, 'get')
.stub(uut.useCases.bch, 'getTxData')
.rejects(new Error('Invalid data'))
// Generate the parsed data that the main router would pass to this
// endpoint.
const id = uid()
const rpcCall = jsonrpc.request(id, 'bch', {
endpoint: 'transaction',
endpoint: 'txData',
txid: 'testTxid'
})
const jsonStr = JSON.stringify(rpcCall, null, 2)
const rpcData = jsonrpc.parse(jsonStr)
const response = await uut.transaction(rpcData)
const response = await uut.txData(rpcData)
// console.log('response: ', response)
assert.equal(response.success, false)
assert.equal(response.status, 422)
assert.equal(response.message, 'Invalid data')
assert.equal(response.endpoint, 'transaction')
assert.equal(response.endpoint, 'txData')
})
})
describe('#pubKey', () => {
it('should return data from bchjs', async () => {
// Mock dependencies
const mock = { success: true, publicKey: '033f267fec0f7eb2b27f8c2e3052b3d03b09d36b47de4082ffb638ffb334ef0eee' }
const mock = {
success: true,
publicKey:
'033f267fec0f7eb2b27f8c2e3052b3d03b09d36b47de4082ffb638ffb334ef0eee'
}
sandbox.stub(uut.bchjs.encryption, 'getPubKey').resolves(mock)
// Generate the parsed data that the main router would pass to this
@@ -466,6 +463,7 @@ describe('#BCHRPC', () => {
assert.property(pubKey, 'publicKey')
assert.equal(pubKey.publicKey, mock.publicKey)
})
it('should throw an error if public key is not found', async () => {
// Force an error
sandbox
@@ -333,7 +333,7 @@ describe('#UserRPC', () => {
assert.equal(result.endpoint, 'updateUser')
assert.equal(result.success, false)
assert.equal(result.status, 422)
assert.include(result.message, 'Cannot read property')
assert.include(result.message, 'Cannot read')
})
})
@@ -375,7 +375,7 @@ describe('#UserRPC', () => {
assert.equal(result.endpoint, 'getUser')
assert.equal(result.success, false)
assert.equal(result.status, 422)
assert.include(result.message, 'Cannot read property')
assert.include(result.message, 'Cannot read')
})
})
@@ -14,7 +14,8 @@ let ctx
const mockContext = require('../../../../unit/mocks/ctx-mock').context
describe('Contact', () => {
before(async () => {})
before(async () => {
})
beforeEach(() => {
uut = new ContactController()
@@ -36,7 +37,7 @@ describe('Contact', () => {
} catch (err) {
// console.log(err)
assert.equal(err.status, 422)
assert.include(err.message, 'Cannot read property')
assert.include(err.message, 'Cannot read')
}
})
@@ -14,7 +14,8 @@ let ctx
const mockContext = require('../../../../unit/mocks/ctx-mock').context
describe('Logapi', () => {
before(async () => {})
before(async () => {
})
beforeEach(() => {
uut = new LogsApiController()
@@ -35,7 +36,7 @@ describe('Logapi', () => {
assert.fail('Unexpected result')
} catch (err) {
assert.equal(err.status, 422)
assert.include(err.message, 'Cannot read property')
assert.include(err.message, 'Cannot read')
}
})
@@ -69,7 +69,7 @@ describe('#Users-REST-Controller', () => {
} catch (err) {
// console.log(err)
assert.equal(err.status, 422)
assert.include(err.message, 'Cannot read property')
assert.include(err.message, 'Cannot read')
}
})
@@ -91,9 +91,9 @@ describe('#Users-REST-Controller', () => {
assert.property(ctx.response.body, 'user')
assert.property(ctx.response.body, 'token')
// Used by downstream tests.
// testUser = ctx.response.body.user
// console.log('testUser: ', testUser)
// Used by downstream tests.
// testUser = ctx.response.body.user
// console.log('testUser: ', testUser)
})
})
@@ -181,7 +181,7 @@ describe('#Users-REST-Controller', () => {
} catch (err) {
// console.log(err)
assert.equal(err.status, 422)
assert.include(err.message, 'Cannot read property')
assert.include(err.message, 'Cannot read')
}
})
@@ -223,7 +223,7 @@ describe('#Users-REST-Controller', () => {
} catch (err) {
// console.log(err)
assert.equal(err.status, 422)
assert.include(err.message, 'Cannot read property')
assert.include(err.message, 'Cannot read')
}
})
+5 -1
View File
@@ -56,7 +56,8 @@ const localdb = {
const bchjs = {
Electrumx: {
transactions: () => {},
balance: () => {}
balance: () => {},
sortAllTxs: () => {}
},
Utxo: {
get: () => {}
@@ -69,6 +70,9 @@ const bchjs = {
},
encryption: {
getPubKey: () => {}
},
Util: {
chunk100: () => {}
}
}
@@ -0,0 +1,94 @@
/*
Mock data for use-cases/bch/index.js unit tests
*/
const fulcrumOut01 = {
success: true,
transactions: [
{
transactions: [
{
height: 560430,
tx_hash:
'3e1f3e882be9c03897eeb197224bf87f312be556a89f4308fabeeeabcf9bc851'
},
{
height: 560534,
tx_hash:
'4ebbeaac51ce141e262964e3a0ce11b96ca72c0dffe9b4127ce80135f503a280'
}
],
address: 'bitcoincash:qpdh9s677ya8tnx7zdhfrn8qfyvy22wj4qa7nwqa5v'
}
]
}
const txData01 = {
txData: {
txid: '11384d7e5a8af93806591debe5bbe2d7826aeea987b874dfbe372dfdcc0ee54f',
hash: '11384d7e5a8af93806591debe5bbe2d7826aeea987b874dfbe372dfdcc0ee54f',
version: 1,
size: 371,
locktime: 0,
vin: [
{
txid: 'c4f3e3d6f146f1d54bd5c22cad6b189637b44a655b057cd0303d85558c033594',
vout: 310,
scriptSig: {
asm: '304402200d40ad599c7e33c7f5245080c0ea35c837c0d142b82eb6824fceaf049c2a355902200590e35951111f6c603c0fb4e513cf0e47734d7bc8b45f105585bea0f2b923de[ALL|FORKID] 0352ede8ab8f2ae49b3921c385e59f700ae1e6f73cbb37f61cd1244e70c99bf496',
hex: '47304402200d40ad599c7e33c7f5245080c0ea35c837c0d142b82eb6824fceaf049c2a355902200590e35951111f6c603c0fb4e513cf0e47734d7bc8b45f105585bea0f2b923de41210352ede8ab8f2ae49b3921c385e59f700ae1e6f73cbb37f61cd1244e70c99bf496'
},
sequence: 4294967295,
address: 'bitcoincash:qzgkqac0tlrfsajg2f7e4e8nyh3glmn4s523tysd6r',
value: 0.08809511
},
{
txid: 'c32265f89b2d5d1d5ffd5212b3245105d7d0ba726306fbeb93cd866ce0fd2d61',
vout: 1,
scriptSig: {
asm: '3045022100be9cc5e982110b0f563460baa19a42f34ab775708ad3461a6cf065db9dffb1b7022031ffb2721828be4aa1f4967a367e8af2848cdfce41c68565d0a2a2a70117ea5d[ALL|FORKID] 02d2eabc002e25fc08622a71d9ef96c17b21176f438d67bc537ac49a2e0e594372',
hex: '483045022100be9cc5e982110b0f563460baa19a42f34ab775708ad3461a6cf065db9dffb1b7022031ffb2721828be4aa1f4967a367e8af2848cdfce41c68565d0a2a2a70117ea5d412102d2eabc002e25fc08622a71d9ef96c17b21176f438d67bc537ac49a2e0e594372'
},
sequence: 4294967295,
address: 'bitcoincash:qr92r3ms2696ghpmk9467px90jrzzdesy5fmqc05p3',
value: 0.00011805
}
],
vout: [
{
value: 0.0814,
n: 0,
scriptPubKey: {
asm: 'OP_HASH160 84459c796307fe2c0316ce7a8bffc511c27bcd55 OP_EQUAL',
hex: 'a91484459c796307fe2c0316ce7a8bffc511c27bcd5587',
reqSigs: 1,
type: 'scripthash',
addresses: ['bitcoincash:pzzyt8revvrlutqrzm884zllc5guy77d2545uyqe8h']
}
},
{
value: 0.00680944,
n: 1,
scriptPubKey: {
asm: 'OP_DUP OP_HASH160 aab2f091ea97e02c58c4e27fb77afb99538ea39e OP_EQUALVERIFY OP_CHECKSIG',
hex: '76a914aab2f091ea97e02c58c4e27fb77afb99538ea39e88ac',
reqSigs: 1,
type: 'pubkeyhash',
addresses: ['bitcoincash:qz4t9uy3a2t7qtzccn38ldm6lwv48r4rnc9mxdtvt9']
}
}
],
hex: '01000000029435038c55853d30d07c055b654ab43796186bad2cc2d54bd5f146f1d6e3f3c4360100006a47304402200d40ad599c7e33c7f5245080c0ea35c837c0d142b82eb6824fceaf049c2a355902200590e35951111f6c603c0fb4e513cf0e47734d7bc8b45f105585bea0f2b923de41210352ede8ab8f2ae49b3921c385e59f700ae1e6f73cbb37f61cd1244e70c99bf496ffffffff612dfde06c86cd93ebfb066372bad0d7055124b31252fd5f1d5d2d9bf86522c3010000006b483045022100be9cc5e982110b0f563460baa19a42f34ab775708ad3461a6cf065db9dffb1b7022031ffb2721828be4aa1f4967a367e8af2848cdfce41c68565d0a2a2a70117ea5d412102d2eabc002e25fc08622a71d9ef96c17b21176f438d67bc537ac49a2e0e594372ffffffff02e0347c000000000017a91484459c796307fe2c0316ce7a8bffc511c27bcd5587f0630a00000000001976a914aab2f091ea97e02c58c4e27fb77afb99538ea39e88ac00000000',
blockhash:
'000000000000000001e8e99be82172d5fe913e21f5a78e4e3bdce2c7dc6315ce',
confirmations: 94517,
time: 1586584650,
blocktime: 1586584650,
isValidSlp: false
}
}
module.exports = {
fulcrumOut01,
txData01
}
+17
View File
@@ -31,12 +31,29 @@ class UserUseCaseMock {
}
}
class BCH {
async getTransactions(rpcData) {
return {
success: true,
status: 200
}
}
async getTxData(rpcData) {
return {
success: true,
status: 200
}
}
}
class UseCasesMock {
constuctor(localConfig = {}) {
// this.user = new UserUseCaseMock(localConfig)
}
user = new UserUseCaseMock()
bch = new BCH()
}
module.exports = UseCasesMock
@@ -0,0 +1,215 @@
/*
Unit tests for the BCH Use Cases
*/
// Public npm libraries
const assert = require('chai').assert
const sinon = require('sinon')
const clone = require('lodash.clonedeep')
// Local support libraries
const BCHUseCases = require('../../../../src/use-cases/bch')
const adapters = require('../../mocks/adapters')
const mockDataLib = require('../../mocks/use-cases/bch/bch.use-cases.mocks.js')
describe('#bch-use-case', () => {
let uut
let sandbox
let mockData
beforeEach(() => {
sandbox = sinon.createSandbox()
mockData = clone(mockDataLib)
uut = new BCHUseCases({ adapters })
})
afterEach(() => sandbox.restore())
describe('#constructor', () => {
it('should throw an error if adapters are not passed in', () => {
try {
uut = new BCHUseCases()
assert.fail('Unexpected code path')
} catch (err) {
assert.include(
err.message,
'Instance of adapters must be passed in when instantiating BCH Use Cases library.'
)
}
})
})
describe('#getTransactions', () => {
it('should get transactions for an address', async () => {
// Mock dependencies
sandbox
.stub(uut.bchjs.Electrumx, 'transactions')
.resolves(mockData.fulcrumOut01)
sandbox
.stub(uut.bchjs.Electrumx, 'sortAllTxs')
.resolves(mockData.fulcrumOut01.transactions[0].transactions)
sandbox
.stub(uut.bchjs.Util, 'chunk100')
.returns([mockData.fulcrumOut01.transactions[0].transactions])
const address = 'bitcoincash:qpdh9s677ya8tnx7zdhfrn8qfyvy22wj4qa7nwqa5v'
const rpcData = {
payload: {
params: {
address
}
}
}
const result = await uut.getTransactions(rpcData)
// console.log('result: ', result)
// Assert expected values and properties.
assert.equal(result.address, address)
assert.equal(result.status, 200)
assert.equal(result.success, true)
assert.isArray(result.txs)
})
it('should return error if Fulcrum communication is not possible', async () => {
// Force an error
sandbox
.stub(uut.bchjs.Electrumx, 'transactions')
.resolves({ success: false })
const address = 'bitcoincash:qpdh9s677ya8tnx7zdhfrn8qfyvy22wj4qa7nwqa5v'
const rpcData = {
payload: {
params: {
address
}
}
}
const result = await uut.getTransactions(rpcData)
// console.log('result: ', result)
assert.equal(result.success, false)
assert.equal(result.status, 422)
assert.equal(result.message, 'Could not query Fulcrum indexer.')
assert.equal(result.endpoint, 'txHistory')
})
it('should return error if there is an error', async () => {
// Force an error
sandbox
.stub(uut.bchjs.Electrumx, 'transactions')
.rejects(new Error('test error'))
const address = 'bitcoincash:qpdh9s677ya8tnx7zdhfrn8qfyvy22wj4qa7nwqa5v'
const rpcData = {
payload: {
params: {
address
}
}
}
const result = await uut.getTransactions(rpcData)
// console.log('result: ', result)
assert.equal(result.success, false)
assert.equal(result.status, 422)
assert.equal(result.message, 'test error')
assert.equal(result.endpoint, 'txHistory')
})
})
describe('#getTxData', () => {
it('should get tx data', async () => {
// Mock dependencies
sandbox.stub(uut.bchjs.Transaction, 'get').resolves(mockData.txData01)
const rpcData = {
payload: {
params: {
txids: [
'11384d7e5a8af93806591debe5bbe2d7826aeea987b874dfbe372dfdcc0ee54f'
]
}
}
}
const result = await uut.getTxData(rpcData)
// console.log('result: ', result)
assert.equal(result.status, 200)
assert.isArray(result.txData)
})
it('should return error if txids is not an array', async () => {
const rpcData = {
payload: {
params: {
txids: 1234
}
}
}
const result = await uut.getTxData(rpcData)
// console.log('result: ', result)
assert.equal(result.success, false)
assert.equal(result.status, 422)
assert.equal(result.endpoint, 'txData')
assert.equal(
result.message,
'Input txids must be an array of transaction IDs.'
)
})
it('should return error if txids array has more than 20 elements', async () => {
const rpcData = {
payload: {
params: {
txids: [
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
]
}
}
}
const result = await uut.getTxData(rpcData)
// console.log('result: ', result)
assert.equal(result.success, false)
assert.equal(result.status, 422)
assert.equal(result.endpoint, 'txData')
assert.equal(result.message, 'Array input must be 20 elements or less.')
})
it('should handle errors', async () => {
// Force an error
sandbox
.stub(uut.bchjs.Transaction, 'get')
.rejects(new Error('test error'))
const rpcData = {
payload: {
params: {
txids: [
'11384d7e5a8af93806591debe5bbe2d7826aeea987b874dfbe372dfdcc0ee54f'
]
}
}
}
const result = await uut.getTxData(rpcData)
// console.log('result: ', result)
assert.equal(result.success, false)
assert.equal(result.status, 422)
assert.equal(result.endpoint, 'txData')
assert.equal(result.message, 'test error')
})
})
})
@@ -7,9 +7,6 @@ const assert = require('chai').assert
const sinon = require('sinon')
// Local support libraries
// const testUtils = require('../../utils/test-utils')
// Unit under test (uut)
const UseCases = require('../../../src/use-cases')
const adapters = require('../mocks/adapters')
+9 -12
View File
@@ -9,9 +9,6 @@ const assert = require('chai').assert
const sinon = require('sinon')
// Local support libraries
// const testUtils = require('../../utils/test-utils')
// Unit under test (uut)
const UserLib = require('../../../src/use-cases/user')
const adapters = require('../mocks/adapters')
@@ -153,7 +150,7 @@ describe('#users-use-case', () => {
await uut.getAllUsers()
// console.log(`users: ${JSON.stringify(users, null, 2)}`)
// assert.isArray(users)
// assert.isArray(users)
})
it('should catch and throw an error', async () => {
@@ -228,8 +225,8 @@ describe('#users-use-case', () => {
// Assert that the expected properties for the user model exist.
// assert.property(result, 'type')
assert.property(result, '_id')
// assert.property(result, 'email')
// assert.property(result, 'name')
// assert.property(result, 'email')
// assert.property(result, 'name')
})
})
@@ -241,7 +238,7 @@ describe('#users-use-case', () => {
assert.fail('Unexpected code path')
} catch (err) {
// console.log(err)
assert.include(err.message, 'Cannot read property')
assert.include(err.message, 'Cannot read')
}
})
@@ -346,7 +343,7 @@ describe('#users-use-case', () => {
// assert.equal(result.name, 'testy tester')
// })
// TODO: verify that an admin can change the type of a user
// TODO: verify that an admin can change the type of a user
})
describe('#authUser', () => {
@@ -356,9 +353,9 @@ describe('#users-use-case', () => {
await uut.authUser('test@test.com', 'password')
// console.log('user: ', user)
// assert.property(user, '_id')
// assert.property(user, 'email')
// assert.property(user, 'name')
// assert.property(user, '_id')
// assert.property(user, 'email')
// assert.property(user, 'name')
})
it('should throw an error if no user matches the login', async () => {
@@ -399,7 +396,7 @@ describe('#users-use-case', () => {
assert.fail('Unexpected code path.')
} catch (err) {
// console.log(err)
assert.include(err.message, 'Cannot read property')
assert.include(err.message, 'Cannot read')
}
})