]>
nmode's Git Repositories - signal-cli/blob - lib/src/test/java/org/asamk/signal/manager/storage/recipients/MergeRecipientHelperTest.java
770054f32aba08ac401d0981dd6eb3dc9b6e2f7a
1 package org
.asamk
.signal
.manager
.storage
.recipients
;
3 import org
.junit
.jupiter
.params
.ParameterizedTest
;
4 import org
.junit
.jupiter
.params
.provider
.Arguments
;
5 import org
.junit
.jupiter
.params
.provider
.MethodSource
;
6 import org
.whispersystems
.signalservice
.api
.push
.ServiceId
;
7 import org
.whispersystems
.signalservice
.api
.push
.ServiceId
.PNI
;
9 import java
.util
.Arrays
;
10 import java
.util
.HashSet
;
12 import java
.util
.UUID
;
13 import java
.util
.stream
.Collectors
;
14 import java
.util
.stream
.Stream
;
16 import static org
.junit
.jupiter
.api
.Assertions
.assertEquals
;
18 class MergeRecipientHelperTest
{
20 static final ServiceId SERVICE_ID_A
= ServiceId
.ACI
.from(UUID
.randomUUID());
21 static final ServiceId SERVICE_ID_B
= ServiceId
.ACI
.from(UUID
.randomUUID());
22 static final PNI PNI_A
= PNI
.from(UUID
.randomUUID());
23 static final PNI PNI_B
= PNI
.from(UUID
.randomUUID());
24 static final String NUMBER_A
= "+AAA";
25 static final String NUMBER_B
= "+BBB";
27 static final PartialAddresses ADDR_A
= new PartialAddresses(SERVICE_ID_A
, PNI_A
, NUMBER_A
);
28 static final PartialAddresses ADDR_B
= new PartialAddresses(SERVICE_ID_B
, PNI_B
, NUMBER_B
);
30 static final T
[] testInstancesNone
= new T
[]{
31 new T(Set
.of(), ADDR_A
.FULL
, Set
.of(rec(1000000, ADDR_A
.FULL
))),
32 new T(Set
.of(), ADDR_A
.ACI_NUM
, Set
.of(rec(1000000, ADDR_A
.ACI_NUM
))),
33 new T(Set
.of(), ADDR_A
.ACI_PNI
, Set
.of(rec(1000000, ADDR_A
.ACI_PNI
))),
34 new T(Set
.of(), ADDR_A
.PNI_NUM
, Set
.of(rec(1000000, ADDR_A
.PNI_NUM
))),
37 static final T
[] testInstancesSingle
= new T
[]{
38 new T(Set
.of(rec(1, ADDR_A
.FULL
)), ADDR_A
.FULL
, Set
.of(rec(1, ADDR_A
.FULL
))),
39 new T(Set
.of(rec(1, ADDR_A
.ACI
)), ADDR_A
.FULL
, Set
.of(rec(1, ADDR_A
.FULL
))),
40 new T(Set
.of(rec(1, ADDR_A
.PNI
)), ADDR_A
.FULL
, Set
.of(rec(1, ADDR_A
.FULL
))),
41 new T(Set
.of(rec(1, ADDR_A
.NUM
)), ADDR_A
.FULL
, Set
.of(rec(1, ADDR_A
.FULL
))),
42 new T(Set
.of(rec(1, ADDR_A
.ACI_NUM
)), ADDR_A
.FULL
, Set
.of(rec(1, ADDR_A
.FULL
))),
43 new T(Set
.of(rec(1, ADDR_A
.PNI_NUM
)), ADDR_A
.FULL
, Set
.of(rec(1, ADDR_A
.FULL
))),
44 new T(Set
.of(rec(1, ADDR_A
.ACI_PNI
)), ADDR_A
.FULL
, Set
.of(rec(1, ADDR_A
.FULL
))),
46 new T(Set
.of(rec(1, ADDR_A
.FULL
)), ADDR_A
.ACI_NUM
, Set
.of(rec(1, ADDR_A
.FULL
))),
47 new T(Set
.of(rec(1, ADDR_A
.ACI
)), ADDR_A
.ACI_NUM
, Set
.of(rec(1, ADDR_A
.ACI_NUM
))),
48 new T(Set
.of(rec(1, ADDR_A
.PNI
)), ADDR_A
.ACI_NUM
, Set
.of(rec(1, ADDR_A
.PNI
), rec(1000000, ADDR_A
.ACI_NUM
))),
49 new T(Set
.of(rec(1, ADDR_A
.NUM
)), ADDR_A
.ACI_NUM
, Set
.of(rec(1, ADDR_A
.ACI_NUM
))),
50 new T(Set
.of(rec(1, ADDR_A
.ACI_NUM
)), ADDR_A
.ACI_NUM
, Set
.of(rec(1, ADDR_A
.ACI_NUM
))),
51 new T(Set
.of(rec(1, ADDR_A
.PNI_NUM
)),
53 Set
.of(rec(1, ADDR_A
.PNI
), rec(1000000, ADDR_A
.ACI_NUM
))),
54 new T(Set
.of(rec(1, ADDR_A
.ACI_PNI
)), ADDR_A
.ACI_NUM
, Set
.of(rec(1, ADDR_A
.FULL
))),
56 new T(Set
.of(rec(1, ADDR_A
.FULL
)), ADDR_A
.PNI_NUM
, Set
.of(rec(1, ADDR_A
.FULL
))),
57 new T(Set
.of(rec(1, ADDR_A
.ACI
)), ADDR_A
.PNI_NUM
, Set
.of(rec(1, ADDR_A
.ACI
), rec(1000000, ADDR_A
.PNI_NUM
))),
58 new T(Set
.of(rec(1, ADDR_A
.PNI
)), ADDR_A
.PNI_NUM
, Set
.of(rec(1, ADDR_A
.PNI_NUM
))),
59 new T(Set
.of(rec(1, ADDR_A
.NUM
)), ADDR_A
.PNI_NUM
, Set
.of(rec(1, ADDR_A
.PNI_NUM
))),
60 new T(Set
.of(rec(1, ADDR_A
.ACI_NUM
)),
62 Set
.of(rec(1, ADDR_A
.ACI
), rec(1000000, ADDR_A
.PNI_NUM
))),
63 new T(Set
.of(rec(1, ADDR_A
.PNI_NUM
)), ADDR_A
.PNI_NUM
, Set
.of(rec(1, ADDR_A
.PNI_NUM
))),
64 new T(Set
.of(rec(1, ADDR_A
.ACI_PNI
)), ADDR_A
.PNI_NUM
, Set
.of(rec(1, ADDR_A
.FULL
))),
66 new T(Set
.of(rec(1, ADDR_A
.FULL
)), ADDR_A
.ACI_PNI
, Set
.of(rec(1, ADDR_A
.FULL
))),
67 new T(Set
.of(rec(1, ADDR_A
.ACI
)), ADDR_A
.ACI_PNI
, Set
.of(rec(1, ADDR_A
.ACI_PNI
))),
68 new T(Set
.of(rec(1, ADDR_A
.PNI
)), ADDR_A
.ACI_PNI
, Set
.of(rec(1, ADDR_A
.ACI_PNI
))),
69 new T(Set
.of(rec(1, ADDR_A
.NUM
)), ADDR_A
.ACI_PNI
, Set
.of(rec(1, ADDR_A
.NUM
), rec(1000000, ADDR_A
.ACI_PNI
))),
70 new T(Set
.of(rec(1, ADDR_A
.ACI_NUM
)), ADDR_A
.ACI_PNI
, Set
.of(rec(1, ADDR_A
.FULL
))),
71 new T(Set
.of(rec(1, ADDR_A
.PNI_NUM
)), ADDR_A
.ACI_PNI
, Set
.of(rec(1, ADDR_A
.FULL
))),
72 new T(Set
.of(rec(1, ADDR_A
.ACI_PNI
)), ADDR_A
.ACI_PNI
, Set
.of(rec(1, ADDR_A
.ACI_PNI
))),
74 new T(Set
.of(rec(1, ADDR_A
.FULL
)), ADDR_B
.FULL
, Set
.of(rec(1, ADDR_A
.FULL
), rec(1000000, ADDR_B
.FULL
))),
77 static final T
[] testInstancesTwo
= new T
[]{
78 new T(Set
.of(rec(1, ADDR_A
.ACI
), rec(2, ADDR_A
.PNI
)), ADDR_A
.FULL
, Set
.of(rec(1, ADDR_A
.FULL
))),
79 new T(Set
.of(rec(1, ADDR_A
.ACI
), rec(2, ADDR_A
.NUM
)), ADDR_A
.FULL
, Set
.of(rec(1, ADDR_A
.FULL
))),
80 new T(Set
.of(rec(1, ADDR_A
.ACI
), rec(2, ADDR_A
.PNI_NUM
)), ADDR_A
.FULL
, Set
.of(rec(1, ADDR_A
.FULL
))),
81 new T(Set
.of(rec(1, ADDR_A
.PNI
), rec(2, ADDR_A
.NUM
)), ADDR_A
.FULL
, Set
.of(rec(1, ADDR_A
.FULL
))),
82 new T(Set
.of(rec(1, ADDR_A
.PNI
), rec(2, ADDR_A
.ACI_NUM
)), ADDR_A
.FULL
, Set
.of(rec(2, ADDR_A
.FULL
))),
83 new T(Set
.of(rec(1, ADDR_A
.NUM
), rec(2, ADDR_A
.ACI_PNI
)), ADDR_A
.FULL
, Set
.of(rec(2, ADDR_A
.FULL
))),
85 new T(Set
.of(rec(1, ADDR_A
.ACI
), rec(2, ADDR_A
.NUM
)), ADDR_A
.ACI_NUM
, Set
.of(rec(1, ADDR_A
.ACI_NUM
))),
86 new T(Set
.of(rec(1, ADDR_A
.ACI
), rec(2, ADDR_A
.PNI_NUM
)), ADDR_A
.ACI_NUM
, Set
.of(rec(1, ADDR_A
.FULL
))),
87 new T(Set
.of(rec(1, ADDR_A
.NUM
), rec(2, ADDR_A
.ACI_PNI
)), ADDR_A
.ACI_NUM
, Set
.of(rec(2, ADDR_A
.FULL
))),
89 new T(Set
.of(rec(1, ADDR_A
.ACI
), rec(2, ADDR_A
.PNI_NUM
)),
91 Set
.of(rec(1, ADDR_A
.ACI
), rec(2, ADDR_A
.PNI_NUM
))),
92 new T(Set
.of(rec(1, ADDR_A
.PNI
), rec(2, ADDR_A
.NUM
)), ADDR_A
.PNI_NUM
, Set
.of(rec(1, ADDR_A
.PNI_NUM
))),
93 new T(Set
.of(rec(1, ADDR_A
.PNI
), rec(2, ADDR_A
.ACI_NUM
)),
95 Set
.of(rec(1, ADDR_A
.PNI_NUM
), rec(2, ADDR_A
.ACI
))),
96 new T(Set
.of(rec(1, ADDR_A
.NUM
), rec(2, ADDR_A
.ACI_PNI
)), ADDR_A
.PNI_NUM
, Set
.of(rec(2, ADDR_A
.FULL
))),
98 new T(Set
.of(rec(1, ADDR_A
.ACI
), rec(2, ADDR_A
.PNI
)), ADDR_A
.ACI_PNI
, Set
.of(rec(1, ADDR_A
.ACI_PNI
))),
99 new T(Set
.of(rec(1, ADDR_A
.ACI
), rec(2, ADDR_A
.PNI_NUM
)), ADDR_A
.ACI_PNI
, Set
.of(rec(1, ADDR_A
.FULL
))),
100 new T(Set
.of(rec(1, ADDR_A
.PNI
), rec(2, ADDR_A
.ACI_NUM
)), ADDR_A
.ACI_PNI
, Set
.of(rec(2, ADDR_A
.FULL
))),
103 static final T
[] testInstancesThree
= new T
[]{
104 new T(Set
.of(rec(1, ADDR_A
.ACI
), rec(2, ADDR_A
.PNI
), rec(3, ADDR_A
.NUM
)),
106 Set
.of(rec(1, ADDR_A
.FULL
))),
107 new T(Set
.of(rec(1, ADDR_A
.ACI
.withIdentifiersFrom(ADDR_B
.PNI
)), rec(2, ADDR_A
.PNI
), rec(3, ADDR_A
.NUM
)),
109 Set
.of(rec(1, ADDR_A
.FULL
))),
110 new T(Set
.of(rec(1, ADDR_A
.ACI
.withIdentifiersFrom(ADDR_B
.NUM
)), rec(2, ADDR_A
.PNI
), rec(3, ADDR_A
.NUM
)),
112 Set
.of(rec(1, ADDR_A
.FULL
))),
113 new T(Set
.of(rec(1, ADDR_A
.ACI
), rec(2, ADDR_A
.PNI
), rec(3, ADDR_A
.NUM
.withIdentifiersFrom(ADDR_B
.ACI
))),
115 Set
.of(rec(1, ADDR_A
.FULL
), rec(3, ADDR_B
.ACI
))),
116 new T(Set
.of(rec(1, ADDR_A
.ACI
), rec(2, ADDR_A
.PNI
.withIdentifiersFrom(ADDR_B
.ACI
)), rec(3, ADDR_A
.NUM
)),
118 Set
.of(rec(1, ADDR_A
.FULL
), rec(2, ADDR_B
.ACI
))),
123 void resolveRecipientTrustedLocked_NoneExisting(T test
) throws Exception
{
124 final var testStore
= new TestStore(test
.input
);
125 MergeRecipientHelper
.resolveRecipientTrustedLocked(testStore
, test
.request
);
126 assertEquals(test
.output
, testStore
.getRecipients());
129 private static Stream
<Arguments
> resolveRecipientTrustedLocked_NoneExisting() {
130 return Arrays
.stream(testInstancesNone
).map(Arguments
::of
);
135 void resolveRecipientTrustedLocked_SingleExisting(T test
) throws Exception
{
136 final var testStore
= new TestStore(test
.input
);
137 MergeRecipientHelper
.resolveRecipientTrustedLocked(testStore
, test
.request
);
138 assertEquals(test
.output
, testStore
.getRecipients());
141 private static Stream
<Arguments
> resolveRecipientTrustedLocked_SingleExisting() {
142 return Arrays
.stream(testInstancesSingle
).map(Arguments
::of
);
147 void resolveRecipientTrustedLocked_TwoExisting(T test
) throws Exception
{
148 final var testStore
= new TestStore(test
.input
);
149 MergeRecipientHelper
.resolveRecipientTrustedLocked(testStore
, test
.request
);
150 assertEquals(test
.output
, testStore
.getRecipients());
153 private static Stream
<Arguments
> resolveRecipientTrustedLocked_TwoExisting() {
154 return Arrays
.stream(testInstancesTwo
).map(Arguments
::of
);
159 void resolveRecipientTrustedLocked_ThreeExisting(T test
) throws Exception
{
160 final var testStore
= new TestStore(test
.input
);
161 MergeRecipientHelper
.resolveRecipientTrustedLocked(testStore
, test
.request
);
162 assertEquals(test
.output
, testStore
.getRecipients());
165 private static Stream
<Arguments
> resolveRecipientTrustedLocked_ThreeExisting() {
166 return Arrays
.stream(testInstancesThree
).map(Arguments
::of
);
169 private static RecipientWithAddress
rec(long recipientId
, RecipientAddress address
) {
170 return new RecipientWithAddress(new RecipientId(recipientId
, null), address
);
174 Set
<RecipientWithAddress
> input
, RecipientAddress request
, Set
<RecipientWithAddress
> output
178 public String
toString() {
179 return "T{#input=%s, request=%s_%s_%s, #output=%s}".formatted(input
.size(),
180 request
.serviceId().isPresent() ?
"SVI" : "",
181 request
.pni().isPresent() ?
"PNI" : "",
182 request
.number().isPresent() ?
"NUM" : "",
187 static class TestStore
implements MergeRecipientHelper
.Store
{
189 final Set
<RecipientWithAddress
> recipients
;
190 long nextRecipientId
= 1000000;
192 TestStore(final Set
<RecipientWithAddress
> recipients
) {
193 this.recipients
= new HashSet
<>(recipients
);
196 public Set
<RecipientWithAddress
> getRecipients() {
201 public Set
<RecipientWithAddress
> findAllByAddress(final RecipientAddress address
) {
202 return recipients
.stream().filter(r
-> r
.address().matches(address
)).collect(Collectors
.toSet());
206 public RecipientId
addNewRecipient(final RecipientAddress address
) {
207 final var recipientId
= new RecipientId(nextRecipientId
++, null);
208 recipients
.add(new RecipientWithAddress(recipientId
, address
));
213 public void updateRecipientAddress(
214 final RecipientId recipientId
, final RecipientAddress address
216 recipients
.removeIf(r
-> r
.id().equals(recipientId
));
217 recipients
.add(new RecipientWithAddress(recipientId
, address
));
221 public void removeRecipientAddress(final RecipientId recipientId
) {
222 recipients
.removeIf(r
-> r
.id().equals(recipientId
));
226 private record PartialAddresses(
227 RecipientAddress FULL
,
228 RecipientAddress ACI
,
229 RecipientAddress PNI
,
230 RecipientAddress NUM
,
231 RecipientAddress ACI_NUM
,
232 RecipientAddress PNI_NUM
,
233 RecipientAddress ACI_PNI
236 PartialAddresses(ServiceId serviceId
, PNI pni
, String number
) {
237 this(new RecipientAddress(serviceId
, pni
, number
),
238 new RecipientAddress(serviceId
, null, null),
239 new RecipientAddress(null, pni
, null),
240 new RecipientAddress(null, null, number
),
241 new RecipientAddress(serviceId
, null, number
),
242 new RecipientAddress(null, pni
, number
),
243 new RecipientAddress(serviceId
, pni
, null));