View Javadoc
1   package civitas.bboard.server.controllers;
2   
3   import static org.junit.jupiter.api.Assertions.assertThrows;
4   import static org.mockito.Mockito.times;
5   import static org.mockito.Mockito.verify;
6   import static org.mockito.Mockito.verifyNoInteractions;
7   
8   import java.io.IOException;
9   import java.util.ArrayList;
10  
11  import org.bouncycastle.crypto.CryptoException;
12  import org.junit.jupiter.api.DisplayName;
13  import org.junit.jupiter.api.Test;
14  import org.mockito.InjectMocks;
15  
16  import civitas.common.EnvironmentState;
17  import civitas.common.RandomAwareTestBase;
18  import civitas.common.board.BoardClosedContentCommitment;
19  import civitas.common.board.BoardClosedContentCommitmentTestData;
20  import civitas.crypto.signature.SignatureTestData;
21  
22  class CloseBoardControllerTest extends RandomAwareTestBase
23  		implements BoardClosedContentCommitmentTestData, SignatureTestData {
24  
25  	@InjectMocks
26  	CloseBoardController closeBoardController;
27  
28  	@Test
29  	@DisplayName(
30  			"""
31  			closes the board
32  			- verifies the signature based on the owner key stored for the bulletin board
33  			- marks the board closed
34  			- calculates the BoardClosedContentCommitment for all voter block
35  			- posts the BoardClosedContentCommitment for the election master
36  			""")
37  	void test() throws CommunicableException, CryptoException {
38  		closeBoardController.apply(BULLETIN_BOARD_ID, ELECTION_ID, NUM_VOTER_BLOCKS, SIGNATURE_OF_AUTH_NONCE_WITH_KEY);
39  		verify(closeBoardController.getBoardForId).apply(BULLETIN_BOARD_ID, true);
40  		verify(closeBoardController.verifyPublicKeySignature)
41  				.apply(SIGNATURE_OF_AUTH_NONCE_WITH_KEY, PUBLIC_KEY, BULLETIN_BOARD_ID);
42  		verify(closeBoardController.boardRepository).save(BULLETIN_BOARD);
43  		verify(closeBoardController.cryptoHash)
44  				.apply(BULLETIN_BOARD_ID.getBytes(), "voterSubmission-voterBlock0".getBytes());
45  		verify(closeBoardController.cryptoHash)
46  				.apply(BULLETIN_BOARD_ID.getBytes(), "voterSubmission-voterBlock1".getBytes());
47  		verify(closeBoardController.getRestTemplate.restTemplate)
48  				.postForObject(ELECTION_ID.uriBase() + "/post", BOARD_CLOSED_CONTENT_COMMITMENT, Boolean.class);
49  	}
50  
51  	@Test
52  	@DisplayName("if the signature does not verify, does nothing")
53  	void test2() throws CommunicableException {
54  		closeBoardController.apply(BULLETIN_BOARD_ID, ELECTION_ID, NUM_VOTER_BLOCKS, SIGNATURE_OF_AUTH_NONCE_WITH_KEY2);
55  		verify(closeBoardController.boardRepository, times(0)).save(BULLETIN_BOARD);
56  		verifyNoInteractions(closeBoardController.cryptoHash);
57  		verifyNoInteractions(closeBoardController.getRestTemplate.restTemplate);
58  	}
59  
60  	@Test
61  	@DisplayName("if the election is null, a NullPointerException is thrown")
62  	void test3() {
63  		assertThrows(
64  				NullPointerException.class,
65  				() -> closeBoardController.apply(
66  						BULLETIN_BOARD_ID, null, NUM_VOTER_BLOCKS, SIGNATURE_OF_AUTH_NONCE_WITH_KEY));
67  	}
68  
69  	@Test
70  	@DisplayName("if the signature is null, a NullPointerException is thrown")
71  	void test4() {
72  		assertThrows(
73  				NullPointerException.class,
74  				() -> closeBoardController.apply(BULLETIN_BOARD_ID, ELECTION_ID, NUM_VOTER_BLOCKS, null));
75  	}
76  
77  	@Test
78  	@DisplayName("if the number of voter blocks is negative, an IllegalArgumentException is thrown")
79  	void test5() {
80  		assertThrows(
81  				IllegalArgumentException.class,
82  				() -> closeBoardController.apply(BULLETIN_BOARD_ID, ELECTION_ID, -1, SIGNATURE_OF_AUTH_NONCE_WITH_KEY));
83  	}
84  
85  	@Test
86  	@DisplayName("if the number of voter blocks is zero, the BoardClosedContentCommitment posted has empty hashes")
87  	void test6() throws CommunicableException {
88  		closeBoardController.apply(BULLETIN_BOARD_ID, ELECTION_ID, 0, SIGNATURE_OF_AUTH_NONCE_WITH_KEY);
89  		verify(closeBoardController.getRestTemplate.restTemplate)
90  				.postForObject(
91  						ELECTION_ID.uriBase() + "/post",
92  						new BoardClosedContentCommitment(ELECTION_ID, BULLETIN_BOARD_ID, new ArrayList<>()),
93  						Boolean.class);
94  	}
95  
96  	@Test
97  	@DisplayName("if the election server is unreachable, an IOException is thrown and the board is not closed")
98  	void test7() {
99  		given(EnvironmentState.ELECTION_SERVER_IS_UNREACHEABLE);
100 		assertThrows(
101 				IOException.class,
102 				() -> closeBoardController.apply(BULLETIN_BOARD_ID, ELECTION_ID, 0, SIGNATURE_OF_AUTH_NONCE_WITH_KEY));
103 		verify(closeBoardController.boardRepository, times(0)).save(BULLETIN_BOARD);
104 	}
105 }