@@ -81,7 +81,12 @@ describe("VoteTransaction", () => {
8181 let unvoteTransaction : Interfaces . ITransaction ;
8282 let secondSignatureUnvoteTransaction : Interfaces . ITransaction ;
8383 let multiSignatureUnvoteTransaction : Interfaces . ITransaction ;
84- let delegateWallet : Wallets . Wallet ;
84+ let voteUnvoteTransaction : Interfaces . ITransaction ;
85+ let unvoteVoteTransaction : Interfaces . ITransaction ;
86+ let voteVoteTransaction : Interfaces . ITransaction ;
87+ let unvoteUnvoteTransaction : Interfaces . ITransaction ;
88+ let delegateWallet1 : Wallets . Wallet ;
89+ let delegateWallet2 : Wallets . Wallet ;
8590 let handler : TransactionHandler ;
8691
8792 beforeEach ( async ( ) => {
@@ -93,61 +98,93 @@ describe("VoteTransaction", () => {
9398 2 ,
9499 ) ;
95100
96- delegateWallet = factoryBuilder
101+ delegateWallet1 = factoryBuilder
97102 . get ( "Wallet" )
98103 . withOptions ( {
99104 passphrase : passphrases [ 8 ] ,
100105 nonce : 0 ,
101106 } )
102107 . make ( ) ;
108+ delegateWallet1 . setAttribute ( "delegate" , { username : "test1" } ) ;
109+ walletRepository . index ( delegateWallet1 ) ;
103110
104- delegateWallet . setAttribute ( "delegate" , { username : "test" } ) ;
105-
106- walletRepository . index ( delegateWallet ) ;
111+ delegateWallet2 = factoryBuilder
112+ . get ( "Wallet" )
113+ . withOptions ( {
114+ passphrase : passphrases [ 9 ] ,
115+ nonce : 0 ,
116+ } )
117+ . make ( ) ;
118+ delegateWallet2 . setAttribute ( "delegate" , { username : "test2" } ) ;
119+ walletRepository . index ( delegateWallet2 ) ;
107120
108121 voteTransaction = BuilderFactory . vote ( )
109- . votesAsset ( [ "+" + delegateWallet . publicKey ! ] )
122+ . votesAsset ( [ "+" + delegateWallet1 . publicKey ! ] )
110123 . nonce ( "1" )
111124 . sign ( passphrases [ 0 ] )
112125 . build ( ) ;
113126
114127 secondSignatureVoteTransaction = BuilderFactory . vote ( )
115- . votesAsset ( [ "+" + delegateWallet . publicKey ! ] )
128+ . votesAsset ( [ "+" + delegateWallet1 . publicKey ! ] )
116129 . nonce ( "1" )
117130 . sign ( passphrases [ 1 ] )
118131 . secondSign ( passphrases [ 2 ] )
119132 . build ( ) ;
120133
121134 multiSignatureVoteTransaction = BuilderFactory . vote ( )
122135 . senderPublicKey ( multiSignatureWallet . publicKey ! )
123- . votesAsset ( [ "+" + delegateWallet . publicKey ! ] )
136+ . votesAsset ( [ "+" + delegateWallet1 . publicKey ! ] )
124137 . nonce ( "1" )
125138 . multiSign ( passphrases [ 0 ] , 0 )
126139 . multiSign ( passphrases [ 1 ] , 1 )
127140 . multiSign ( passphrases [ 2 ] , 2 )
128141 . build ( ) ;
129142
130143 unvoteTransaction = BuilderFactory . vote ( )
131- . votesAsset ( [ "-" + delegateWallet . publicKey ! ] )
144+ . votesAsset ( [ "-" + delegateWallet1 . publicKey ! ] )
132145 . nonce ( "1" )
133146 . sign ( passphrases [ 0 ] )
134147 . build ( ) ;
135148
136149 secondSignatureUnvoteTransaction = BuilderFactory . vote ( )
137- . votesAsset ( [ "-" + delegateWallet . publicKey ! ] )
150+ . votesAsset ( [ "-" + delegateWallet1 . publicKey ! ] )
138151 . nonce ( "1" )
139152 . sign ( passphrases [ 1 ] )
140153 . secondSign ( passphrases [ 2 ] )
141154 . build ( ) ;
142155
143156 multiSignatureUnvoteTransaction = BuilderFactory . vote ( )
144157 . senderPublicKey ( multiSignatureWallet . publicKey ! )
145- . votesAsset ( [ "-" + delegateWallet . publicKey ! ] )
158+ . votesAsset ( [ "-" + delegateWallet1 . publicKey ! ] )
146159 . nonce ( "1" )
147160 . multiSign ( passphrases [ 0 ] , 0 )
148161 . multiSign ( passphrases [ 1 ] , 1 )
149162 . multiSign ( passphrases [ 2 ] , 2 )
150163 . build ( ) ;
164+
165+ voteUnvoteTransaction = BuilderFactory . vote ( )
166+ . votesAsset ( [ "+" + delegateWallet1 . publicKey ! , "-" + delegateWallet1 . publicKey ! ] )
167+ . nonce ( "1" )
168+ . sign ( passphrases [ 0 ] )
169+ . build ( ) ;
170+
171+ unvoteVoteTransaction = BuilderFactory . vote ( )
172+ . votesAsset ( [ "-" + delegateWallet1 . publicKey ! , "+" + delegateWallet2 . publicKey ! ] )
173+ . nonce ( "1" )
174+ . sign ( passphrases [ 0 ] )
175+ . build ( ) ;
176+
177+ voteVoteTransaction = BuilderFactory . vote ( )
178+ . votesAsset ( [ "+" + delegateWallet1 . publicKey ! , "+" + delegateWallet2 . publicKey ! ] )
179+ . nonce ( "1" )
180+ . sign ( passphrases [ 0 ] )
181+ . build ( ) ;
182+
183+ unvoteUnvoteTransaction = BuilderFactory . vote ( )
184+ . votesAsset ( [ "-" + delegateWallet1 . publicKey ! , "-" + delegateWallet2 . publicKey ! ] )
185+ . nonce ( "1" )
186+ . sign ( passphrases [ 0 ] )
187+ . build ( ) ;
151188 } ) ;
152189
153190 describe ( "bootstrap" , ( ) => {
@@ -169,7 +206,7 @@ describe("VoteTransaction", () => {
169206 transactionHistoryService . streamByCriteria . mockImplementationOnce ( async function * ( ) {
170207 yield voteTransaction . data ;
171208 } ) ;
172- senderWallet . setAttribute ( "vote" , delegateWallet . publicKey ) ;
209+ senderWallet . setAttribute ( "vote" , delegateWallet1 . publicKey ) ;
173210 await expect ( handler . bootstrap ( ) ) . rejects . toThrow ( AlreadyVotedError ) ;
174211 } ) ;
175212
@@ -258,34 +295,34 @@ describe("VoteTransaction", () => {
258295 } ) ;
259296
260297 it ( "should not throw if the unvote is valid and the wallet has voted" , async ( ) => {
261- senderWallet . setAttribute ( "vote" , delegateWallet . publicKey ) ;
298+ senderWallet . setAttribute ( "vote" , delegateWallet1 . publicKey ) ;
262299 await expect ( handler . throwIfCannotBeApplied ( unvoteTransaction , senderWallet ) ) . toResolve ( ) ;
263300 } ) ;
264301
265302 it ( "should not throw - second sign unvote" , async ( ) => {
266- secondSignatureWallet . setAttribute ( "vote" , delegateWallet . publicKey ) ;
303+ secondSignatureWallet . setAttribute ( "vote" , delegateWallet1 . publicKey ) ;
267304 await expect (
268305 handler . throwIfCannotBeApplied ( secondSignatureUnvoteTransaction , secondSignatureWallet ) ,
269306 ) . toResolve ( ) ;
270307 } ) ;
271308
272309 it ( "should not throw - multi sign unvote" , async ( ) => {
273- multiSignatureWallet . setAttribute ( "vote" , delegateWallet . publicKey ) ;
310+ multiSignatureWallet . setAttribute ( "vote" , delegateWallet1 . publicKey ) ;
274311 await expect (
275312 handler . throwIfCannotBeApplied ( multiSignatureUnvoteTransaction , multiSignatureWallet ) ,
276313 ) . toResolve ( ) ;
277314 } ) ;
278315
279316 it ( "should throw if wallet has already voted" , async ( ) => {
280- senderWallet . setAttribute ( "vote" , delegateWallet . publicKey ) ;
317+ senderWallet . setAttribute ( "vote" , delegateWallet1 . publicKey ) ;
281318 await expect ( handler . throwIfCannotBeApplied ( voteTransaction , senderWallet ) ) . rejects . toThrow (
282319 AlreadyVotedError ,
283320 ) ;
284321 } ) ;
285322
286323 it ( "should throw if vote for non delegate wallet" , async ( ) => {
287- delegateWallet . forgetAttribute ( "delegate" ) ;
288- walletRepository . index ( delegateWallet ) ;
324+ delegateWallet1 . forgetAttribute ( "delegate" ) ;
325+ walletRepository . index ( delegateWallet1 ) ;
289326 await expect ( handler . throwIfCannotBeApplied ( voteTransaction , senderWallet ) ) . rejects . toThrow (
290327 VotedForNonDelegateError ,
291328 ) ;
@@ -311,7 +348,7 @@ describe("VoteTransaction", () => {
311348
312349 it ( "should throw if wallet has insufficient funds for unvote" , async ( ) => {
313350 senderWallet . balance = Utils . BigNumber . ZERO ;
314- senderWallet . setAttribute ( "vote" , delegateWallet . publicKey ) ;
351+ senderWallet . setAttribute ( "vote" , delegateWallet1 . publicKey ) ;
315352 await expect ( handler . throwIfCannotBeApplied ( unvoteTransaction , senderWallet ) ) . rejects . toThrow (
316353 InsufficientBalanceError ,
317354 ) ;
@@ -332,6 +369,44 @@ describe("VoteTransaction", () => {
332369 Exceptions . Runtime . AssertionException ,
333370 ) ;
334371 } ) ;
372+
373+ it ( "should not throw on vote+unvote transaction when wallet has not voted" , async ( ) => {
374+ await handler . throwIfCannotBeApplied ( voteUnvoteTransaction , senderWallet ) ;
375+ } ) ;
376+
377+ it ( "should throw on vote+unvote transaction when wallet has voted" , async ( ) => {
378+ senderWallet . setAttribute ( "vote" , delegateWallet1 . publicKey ) ;
379+
380+ await expect ( handler . throwIfCannotBeApplied ( voteUnvoteTransaction , senderWallet ) ) . rejects . toThrow (
381+ AlreadyVotedError ,
382+ ) ;
383+ } ) ;
384+
385+ it ( "should not throw on unvote+vote transaction when wallet has voted" , async ( ) => {
386+ senderWallet . setAttribute ( "vote" , delegateWallet1 . publicKey ) ;
387+
388+ await handler . throwIfCannotBeApplied ( unvoteVoteTransaction , senderWallet ) ;
389+ } ) ;
390+
391+ it ( "should throw on unvote+vote transaction when wallet has not voted" , async ( ) => {
392+ await expect ( handler . throwIfCannotBeApplied ( unvoteVoteTransaction , senderWallet ) ) . rejects . toThrow (
393+ NoVoteError ,
394+ ) ;
395+ } ) ;
396+
397+ it ( "should throw on vote+vote transaction when wallet has not voted" , async ( ) => {
398+ await expect ( handler . throwIfCannotBeApplied ( voteVoteTransaction , senderWallet ) ) . rejects . toThrow (
399+ AlreadyVotedError ,
400+ ) ;
401+ } ) ;
402+
403+ it ( "should throw on unvote+unvote transaction when wallet has voted" , async ( ) => {
404+ senderWallet . setAttribute ( "vote" , delegateWallet1 . publicKey ) ;
405+
406+ await expect ( handler . throwIfCannotBeApplied ( unvoteUnvoteTransaction , senderWallet ) ) . rejects . toThrow (
407+ NoVoteError ,
408+ ) ;
409+ } ) ;
335410 } ) ;
336411
337412 describe ( "throwIfCannotEnterPool" , ( ) => {
@@ -358,7 +433,7 @@ describe("VoteTransaction", () => {
358433 } ) ;
359434
360435 it ( "should not be ok" , async ( ) => {
361- senderWallet . setAttribute ( "vote" , delegateWallet . publicKey ) ;
436+ senderWallet . setAttribute ( "vote" , delegateWallet1 . publicKey ) ;
362437
363438 expect ( senderWallet . getAttribute ( "vote" ) ) . not . toBeUndefined ( ) ;
364439
@@ -370,7 +445,7 @@ describe("VoteTransaction", () => {
370445
371446 describe ( "unvote" , ( ) => {
372447 it ( "should remove the vote from the wallet" , async ( ) => {
373- senderWallet . setAttribute ( "vote" , delegateWallet . publicKey ) ;
448+ senderWallet . setAttribute ( "vote" , delegateWallet1 . publicKey ) ;
374449
375450 expect ( senderWallet . getAttribute ( "vote" ) ) . not . toBeUndefined ( ) ;
376451
@@ -379,6 +454,40 @@ describe("VoteTransaction", () => {
379454 expect ( senderWallet . hasAttribute ( "vote" ) ) . toBeFalse ( ) ;
380455 } ) ;
381456 } ) ;
457+
458+ describe ( "vote+unvote" , ( ) => {
459+ it ( "should apply when wallet has not voted" , async ( ) => {
460+ await handler . apply ( voteUnvoteTransaction ) ;
461+
462+ expect ( senderWallet . hasAttribute ( "vote" ) ) . toBeFalse ( ) ;
463+ } ) ;
464+
465+ it ( "should throw when wallet has voted" , async ( ) => {
466+ senderWallet . setAttribute ( "vote" , delegateWallet1 . publicKey ) ;
467+
468+ await expect ( handler . apply ( voteUnvoteTransaction ) ) . rejects . toThrow ( AlreadyVotedError ) ;
469+ } ) ;
470+ } ) ;
471+
472+ describe ( "unvote+vote" , ( ) => {
473+ it ( "should apply when wallet has voted" , async ( ) => {
474+ senderWallet . setAttribute ( "vote" , delegateWallet1 . publicKey ) ;
475+
476+ await handler . apply ( unvoteVoteTransaction ) ;
477+
478+ expect ( senderWallet . getAttribute ( "vote" ) ) . toEqual ( delegateWallet2 . publicKey ) ;
479+ } ) ;
480+
481+ it ( "should throw when wallet has not voted" , async ( ) => {
482+ await expect ( handler . apply ( unvoteUnvoteTransaction ) ) . rejects . toThrow ( NoVoteError ) ;
483+ } ) ;
484+
485+ it ( "should throw when wallet has voted for different delegate" , async ( ) => {
486+ senderWallet . setAttribute ( "vote" , delegateWallet2 . publicKey ) ;
487+
488+ await expect ( handler . apply ( unvoteUnvoteTransaction ) ) . rejects . toThrow ( UnvoteMismatchError ) ;
489+ } ) ;
490+ } ) ;
382491 } ) ;
383492
384493 describe ( "applyForSender" , ( ) => {
@@ -402,7 +511,7 @@ describe("VoteTransaction", () => {
402511 describe ( "revert" , ( ) => {
403512 describe ( "vote" , ( ) => {
404513 it ( "should remove the vote from the wallet" , async ( ) => {
405- senderWallet . setAttribute ( "vote" , delegateWallet . publicKey ) ;
514+ senderWallet . setAttribute ( "vote" , delegateWallet1 . publicKey ) ;
406515 senderWallet . nonce = Utils . BigNumber . make ( 1 ) ;
407516
408517 expect ( senderWallet . getAttribute ( "vote" ) ) . not . toBeUndefined ( ) ;
@@ -423,7 +532,28 @@ describe("VoteTransaction", () => {
423532 await handler . revert ( unvoteTransaction ) ;
424533
425534 expect ( senderWallet . nonce . isZero ( ) ) . toBeTrue ( ) ;
426- expect ( senderWallet . getAttribute ( "vote" ) ) . toBe ( delegateWallet . publicKey ) ;
535+ expect ( senderWallet . getAttribute ( "vote" ) ) . toBe ( delegateWallet1 . publicKey ) ;
536+ } ) ;
537+ } ) ;
538+
539+ describe ( "vote+unvote" , ( ) => {
540+ it ( "should revert when wallet has no vote" , async ( ) => {
541+ senderWallet . nonce = Utils . BigNumber . make ( 1 ) ;
542+
543+ await handler . revert ( voteUnvoteTransaction ) ;
544+
545+ expect ( senderWallet . hasAttribute ( "vote" ) ) . toBeFalse ( ) ;
546+ } ) ;
547+ } ) ;
548+
549+ describe ( "unvote+vote" , ( ) => {
550+ it ( "should revert when wallet has no vote" , async ( ) => {
551+ senderWallet . setAttribute ( "vote" , delegateWallet2 . publicKey ) ;
552+ senderWallet . nonce = Utils . BigNumber . make ( 1 ) ;
553+
554+ await handler . revert ( unvoteVoteTransaction ) ;
555+
556+ expect ( senderWallet . getAttribute ( "vote" ) ) . toEqual ( delegateWallet1 . publicKey ) ;
427557 } ) ;
428558 } ) ;
429559 } ) ;
@@ -444,7 +574,9 @@ describe("VoteTransaction", () => {
444574
445575 senderWallet . nonce = Utils . BigNumber . ONE ;
446576
447- await expect ( handler . revertForSender ( voteTransaction ) ) . rejects . toThrow ( Exceptions . Runtime . AssertionException ) ;
577+ await expect ( handler . revertForSender ( voteTransaction ) ) . rejects . toThrow (
578+ Exceptions . Runtime . AssertionException ,
579+ ) ;
448580 } ) ;
449581 } ) ;
450582} ) ;
0 commit comments