From 4dbdbb8b3f37b7dd63f1ea569175b1986bbcc4a0 Mon Sep 17 00:00:00 2001 From: wm798222 Date: Thu, 18 Feb 2021 18:30:00 -0800 Subject: [PATCH] feat: add more code for transfer bundle and check if token is already claimed --- server/models/Session.js | 1 + server/models/Wallet.js | 22 +++++++++++++++++++--- server/models/Wallet.spec.js | 21 +++++++++++++++++++++ server/routes/transferRouter.js | 10 +++++++++- server/routes/transferRouter.spec.js | 5 +++++ 5 files changed, 55 insertions(+), 4 deletions(-) diff --git a/server/models/Session.js b/server/models/Session.js index f8c9ebb2..0ae16fbc 100644 --- a/server/models/Session.js +++ b/server/models/Session.js @@ -21,6 +21,7 @@ class Session{ throw new Error("Can not start transaction in transaction"); } this.thx = await knex.transaction(); + console.log('HEREbbba'); } async commitTransaction(){ diff --git a/server/models/Wallet.js b/server/models/Wallet.js index 51271cbf..bde5570f 100644 --- a/server/models/Wallet.js +++ b/server/models/Wallet.js @@ -453,6 +453,12 @@ class Wallet{ */ async transfer(sender, receiver, tokens, claimBoolean){ // await this.checkDeduct(sender, receiver); + // check is claim is already set to true, if so, we cannot transfer this token. + if (claim === true) { + console.log("token is claimed, cannot be transfered"); + throw new HttpError(403, `The token ${uuid} is claimed, cannot be transfered`); + } + //check tokens belong to sender for(const token of tokens){ if(!await token.belongsTo(sender)){ @@ -544,7 +550,7 @@ class Wallet{ } } - async transferBundle(sender, receiver, bundleSize){ + async transferBundle(sender, receiver, bundleSize, claimBoolean){ //check has enough tokens to sender const tokenCount = await this.tokenService.countTokenByWallet(sender); expect(tokenCount).number(); @@ -570,13 +576,23 @@ class Wallet{ bundle: { bundleSize: bundleSize, } - } + }, //TODO: boolean for claim + claim: claimBoolean, }); log.debug("now, deal with tokens"); const tokens = await this.tokenService.getTokensByBundle(sender, bundleSize) + + + for(let token of tokens){ - await token.completeTransfer(transfer); + // check is claim is already set to true, if so, we cannot transfer this token. + if (token.claim === true) { + console.log("token is claimed, cannot be transfered"); + throw new HttpError(403, `The token ${uuid} is claimed, cannot be transfered`); + } else { + await token.completeTransfer(transfer); + } } return transfer; }else{ diff --git a/server/models/Wallet.spec.js b/server/models/Wallet.spec.js index e9e0a1b4..408818bd 100644 --- a/server/models/Wallet.spec.js +++ b/server/models/Wallet.spec.js @@ -307,6 +307,27 @@ describe("Wallet", () => { fn1.restore(); }); + it.only("Claim set to true, should success", async () => { + const fn0 = sinon.stub(Token.prototype, "belongsTo").resolves(true); + // const fn1 = sinon.stub(TransferRepository.prototype, "create").resolves({ + // id: 1, + // state: Transfer.STATE.completed, + + // }); + const fn1 = sinon.stub(wallet, "hasTrust").resolves(true); + const sender = new Wallet(1, session); + const receiver = new Wallet(2, session); + const token = new Token({ + id: 1, + uuid: "uu", + transfer_pending: false, + }, session); + const transfer = await wallet.transfer(sender, receiver, [token], true); + expect(transfer).property("state").eq(Transfer.STATE.completed); + fn0.restore(); + fn1.restore(); + }); + it("don't have trust, sender under control, should return transfer with pending state", async () => { sinon.stub(Wallet.prototype, "isDeduct").resolves(false); const fn3 = sinon.stub(Wallet.prototype, "hasControlOver"); diff --git a/server/routes/transferRouter.js b/server/routes/transferRouter.js index a584b73c..d47a3d2a 100644 --- a/server/routes/transferRouter.js +++ b/server/routes/transferRouter.js @@ -47,19 +47,25 @@ transferRouter.post( }), }) ); + console.log('HERE0'); const session = new Session(); + //begin transaction try{ + console.log('HERE00'); await session.beginTransaction(); + console.log('HERE000'); const walletService = new WalletService(session); const walletLogin = await walletService.getById(res.locals.wallet_id); + console.log('HERE001'); const walletSender = await walletService.getByIdOrName(req.body.sender_wallet); const walletReceiver = await walletService.getByIdOrName(req.body.receiver_wallet); // check if this transfer is a claim (claim == not transferrrable tokens) const claim = req.body.claim; let result; + //TODO: put the claim boolean into each tokens if(req.body.tokens){ const tokens = []; const tokenService = new TokenService(session); @@ -73,8 +79,10 @@ transferRouter.post( }else{ //Case 2: with trust, bundle transfer // TODO: get only transferrable tokens - result = await walletLogin.transferBundle(walletSender, walletReceiver, req.body.bundle.bundle_size); + console.log('HERE2'); + result = await walletLogin.transferBundle(walletSender, walletReceiver, req.body.bundle.bundle_size, claim); } + // console.log('HERE3'); const transferService = new TransferService(session); result = await transferService.convertToResponse(result); if(result.state === Transfer.STATE.completed){ diff --git a/server/routes/transferRouter.spec.js b/server/routes/transferRouter.spec.js index 8494adcb..99e7b904 100644 --- a/server/routes/transferRouter.spec.js +++ b/server/routes/transferRouter.spec.js @@ -27,6 +27,7 @@ describe("transferRouter", () => { } beforeEach(() => { + sinon.stub(Session.prototype); sinon.stub(ApiKeyService.prototype, "check"); sinon.stub(JWTService.prototype, "verify").returns({ id: walletLogin.id, @@ -210,6 +211,7 @@ describe("transferRouter", () => { id: 1, state: Transfer.STATE.completed, }); + const res = await request(app) .post('/') .send({ @@ -223,6 +225,9 @@ describe("transferRouter", () => { expect(res).property('statusCode').eq(201); }); + //check what's in the db, after transfer claim + // test transfer, in wallet.spec.js + it("all parameters fine, but no trust relationship, should return 202", async () => { sinon.stub(WalletService.prototype, "getByIdOrName").resolves(new Wallet(1)); sinon.stub(WalletService.prototype, "getById").resolves({