1 package civitas.bboard.server.controllers;
2
3 import static org.junit.jupiter.api.Assertions.assertEquals;
4 import static org.junit.jupiter.api.Assertions.assertThrows;
5 import static org.mockito.Mockito.verify;
6
7 import java.io.IOException;
8 import java.math.BigInteger;
9
10 import org.bouncycastle.crypto.CryptoException;
11 import org.junit.jupiter.api.DisplayName;
12 import org.junit.jupiter.api.Test;
13 import org.mockito.InjectMocks;
14 import org.slf4j.MarkerFactory;
15
16 import civitas.bboard.common.BBPostTestData;
17 import civitas.common.EnvironmentState;
18 import civitas.common.Operation;
19 import civitas.common.RandomAwareTestBase;
20 import civitas.common.board.BulletinBoardTestData;
21 import jakarta.xml.bind.JAXBException;
22
23 class PostControllerTest extends RandomAwareTestBase implements BulletinBoardTestData, BBPostTestData {
24
25 @InjectMocks
26 PostController postController;
27
28 @Test
29 @DisplayName(
30 """
31 records a post to a bulletin board and returns the time of recording
32 - checks access right
33 - verifies the signature
34 - retrieves the last post for the serial and hash
35 - computes the hash using the previous hash and the signature
36 - records the hash, serial and current time in the post and saves it
37 - updates the election cache
38 - logs the transaction with its meta and board id
39 """)
40 void test() throws CommunicableException, JAXBException, IOException, CryptoException {
41 assertEquals(
42 CURRENT_TIME,
43 postController.apply(
44 BULLETIN_BOARD_ID,
45 new PostDTO(
46 BOARD_CLOSED_CONTENT_COMMITMENT_META,
47 BOARD_CLOSED_CONTENT_COMMITMENT_XML,
48 BOARD_CLOSED_CONTENT_COMMITMENT_SIGNATURE)));
49 verify(postController.checkAccess)
50 .apply(
51 Operation.POST,
52 BOARD_CLOSED_CONTENT_COMMITMENT_SIGNATURE.getSignerPubKey(),
53 BOARD_CLOSED_CONTENT_COMMITMENT_META + BULLETIN_BOARD_ID);
54 verify(postController.verifyPublicKeySignature)
55 .apply(BOARD_CLOSED_CONTENT_COMMITMENT_SIGNATURE, BOARD_CLOSED_CONTENT_COMMITMENT_XML.getBytes());
56 verify(postController.getBoardForId).apply(BULLETIN_BOARD_ID, true);
57 verify(postController.updateCache)
58 .apply(
59 BULLETIN_BOARD_ID,
60 BOARD_CLOSED_CONTENT_COMMITMENT_META,
61 BOARD_CLOSED_CONTENT_COMMITMENT_XML,
62 CURRENT_TIME);
63 verify(postController.bBPostRepository).findByBbidOrderBySerialDesc(BULLETIN_BOARD_ID);
64 verify(postController.cryptoHash)
65 .apply(
66 BBPOST.hash,
67 BigInteger.valueOf(CURRENT_TIME).toByteArray(),
68 BOARD_CLOSED_CONTENT_COMMITMENT_SIGNATURE.signatureBytes);
69 verify(postController.loggerController)
70 .apply(MarkerFactory.getMarker("bbs_post"), BOARD_CLOSED_CONTENT_COMMITMENT_META + BULLETIN_BOARD_ID);
71 verify(postController.bBPostRepository).save(NEXT_POST);
72 }
73
74 @Test
75 @DisplayName("if the signature does not check, a CommunicableException is thrown")
76 void test1() {
77 assertThrows(
78 CommunicableException.class,
79 () -> postController.apply(
80 BULLETIN_BOARD_ID,
81 new PostDTO(
82 BOARD_CLOSED_CONTENT_COMMITMENT_META,
83 BOARD_CLOSED_CONTENT_COMMITMENT_XML,
84 BOARD_CLOSED_CONTENT_COMMITMENT_SIGNATURE_BAD)));
85 }
86
87 @Test
88 @DisplayName("if the signer is not authorized to post, a SecurityException is thrown")
89 void test2() {
90 assertThrows(
91 SecurityException.class,
92 () -> postController.apply(
93 BULLETIN_BOARD_ID,
94 new PostDTO(
95 BOARD_CLOSED_CONTENT_COMMITMENT_META,
96 BOARD_CLOSED_CONTENT_COMMITMENT_XML,
97 BOARD_CLOSED_CONTENT_COMMITMENT_SIGNATURE_BAD_ACTOR)));
98 }
99
100 @Test
101 @DisplayName("if there is no previous post the hash uses only the time and signature, and the serial is 1 ")
102 void test3() throws CommunicableException {
103 given(EnvironmentState.EMPTY_BOARD);
104 Long actual = postController.apply(
105 BULLETIN_BOARD_ID,
106 new PostDTO(
107 BOARD_CLOSED_CONTENT_COMMITMENT_META,
108 BOARD_CLOSED_CONTENT_COMMITMENT_XML,
109 BOARD_CLOSED_CONTENT_COMMITMENT_SIGNATURE));
110 verify(postController.cryptoHash)
111 .apply(
112 new byte[0],
113 BigInteger.valueOf(CURRENT_TIME).toByteArray(),
114 BOARD_CLOSED_CONTENT_COMMITMENT_SIGNATURE.signatureBytes);
115 verify(postController.bBPostRepository).save(FIRST_POST);
116 assertEquals(CURRENT_TIME, actual);
117 }
118 }