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
.PNI
;
7 import org
.whispersystems
.signalservice
.api
.push
.ServiceId
;
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
.from(UUID
.randomUUID());
21 static final ServiceId SERVICE_ID_B
= ServiceId
.from(UUID
.randomUUID());
22 static final ServiceId SERVICE_ID_C
= ServiceId
.from(UUID
.randomUUID());
23 static final PNI PNI_A
= PNI
.from(UUID
.randomUUID());
24 static final PNI PNI_B
= PNI
.from(UUID
.randomUUID());
25 static final PNI PNI_C
= PNI
.from(UUID
.randomUUID());
26 static final String NUMBER_A
= "+AAA";
27 static final String NUMBER_B
= "+BBB";
28 static final String NUMBER_C
= "+CCC";
30 static final PartialAddresses ADDR_A
= new PartialAddresses(SERVICE_ID_A
, PNI_A
, NUMBER_A
);
31 static final PartialAddresses ADDR_B
= new PartialAddresses(SERVICE_ID_B
, PNI_B
, NUMBER_B
);
33 static T
[] testInstancesNone
= new T
[]{
35 new T(Set
.of(), ADDR_A
.FULL
, Set
.of(rec(1000000, ADDR_A
.FULL
))),
36 new T(Set
.of(), ADDR_A
.ACI_NUM
, Set
.of(rec(1000000, ADDR_A
.ACI_NUM
))),
37 new T(Set
.of(), ADDR_A
.ACI_PNI
, Set
.of(rec(1000000, ADDR_A
.ACI_PNI
))),
38 new T(Set
.of(), ADDR_A
.PNI_S_NUM
, Set
.of(rec(1000000, ADDR_A
.PNI_S_NUM
))),
39 new T(Set
.of(), ADDR_A
.PNI_NUM
, Set
.of(rec(1000000, ADDR_A
.PNI_NUM
))),
42 static T
[] testInstancesSingle
= new T
[]{
44 new T(Set
.of(rec(1, ADDR_A
.FULL
)), ADDR_A
.FULL
, Set
.of(rec(1, ADDR_A
.FULL
))),
45 new T(Set
.of(rec(1, ADDR_A
.ACI
)), ADDR_A
.FULL
, Set
.of(rec(1, ADDR_A
.FULL
))),
46 new T(Set
.of(rec(1, ADDR_A
.PNI
)), ADDR_A
.FULL
, Set
.of(rec(1, ADDR_A
.FULL
))),
47 new T(Set
.of(rec(1, ADDR_A
.PNI_S
)), ADDR_A
.FULL
, Set
.of(rec(1, ADDR_A
.FULL
))),
48 new T(Set
.of(rec(1, ADDR_A
.NUM
)), ADDR_A
.FULL
, Set
.of(rec(1, ADDR_A
.FULL
))),
49 new T(Set
.of(rec(1, ADDR_A
.ACI_NUM
)), ADDR_A
.FULL
, Set
.of(rec(1, ADDR_A
.FULL
))),
50 new T(Set
.of(rec(1, ADDR_A
.PNI_NUM
)), ADDR_A
.FULL
, Set
.of(rec(1, ADDR_A
.FULL
))),
51 new T(Set
.of(rec(1, ADDR_A
.PNI_S_NUM
)), ADDR_A
.FULL
, Set
.of(rec(1, ADDR_A
.FULL
))),
52 new T(Set
.of(rec(1, ADDR_A
.ACI_PNI
)), ADDR_A
.FULL
, Set
.of(rec(1, ADDR_A
.FULL
))),
55 new T(Set
.of(rec(1, ADDR_A
.FULL
)), ADDR_A
.ACI_NUM
, Set
.of(rec(1, ADDR_A
.FULL
))),
56 new T(Set
.of(rec(1, ADDR_A
.ACI
)), ADDR_A
.ACI_NUM
, Set
.of(rec(1, ADDR_A
.ACI_NUM
))),
57 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
))),
58 new T(Set
.of(rec(1, ADDR_A
.PNI_S
)),
60 Set
.of(rec(1, ADDR_A
.PNI_S
), rec(1000000, ADDR_A
.ACI_NUM
))),
61 new T(Set
.of(rec(1, ADDR_A
.NUM
)), ADDR_A
.ACI_NUM
, Set
.of(rec(1, ADDR_A
.ACI_NUM
))),
62 new T(Set
.of(rec(1, ADDR_A
.ACI_NUM
)), ADDR_A
.ACI_NUM
, Set
.of(rec(1, ADDR_A
.ACI_NUM
))),
63 new T(Set
.of(rec(1, ADDR_A
.PNI_NUM
)),
65 Set
.of(rec(1, ADDR_A
.PNI
), rec(1000000, ADDR_A
.ACI_NUM
))),
66 new T(Set
.of(rec(1, ADDR_A
.PNI_S_NUM
)),
68 Set
.of(rec(1, ADDR_A
.PNI_S
), rec(1000000, ADDR_A
.ACI_NUM
))),
69 new T(Set
.of(rec(1, ADDR_A
.ACI_PNI
)), ADDR_A
.ACI_NUM
, Set
.of(rec(1, ADDR_A
.FULL
))),
72 new T(Set
.of(rec(1, ADDR_A
.FULL
)), ADDR_A
.PNI_NUM
, Set
.of(rec(1, ADDR_A
.FULL
))),
73 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
))),
74 new T(Set
.of(rec(1, ADDR_A
.PNI
)), ADDR_A
.PNI_NUM
, Set
.of(rec(1, ADDR_A
.PNI_NUM
))),
75 new T(Set
.of(rec(1, ADDR_A
.PNI_S
)), ADDR_A
.PNI_NUM
, Set
.of(rec(1, ADDR_A
.PNI_NUM
))),
76 new T(Set
.of(rec(1, ADDR_A
.NUM
)), ADDR_A
.PNI_NUM
, Set
.of(rec(1, ADDR_A
.PNI_NUM
))),
77 new T(Set
.of(rec(1, ADDR_A
.ACI_NUM
)),
79 Set
.of(rec(1, ADDR_A
.ACI
), rec(1000000, ADDR_A
.PNI_NUM
))),
80 new T(Set
.of(rec(1, ADDR_A
.PNI_NUM
)), ADDR_A
.PNI_NUM
, Set
.of(rec(1, ADDR_A
.PNI_NUM
))),
81 new T(Set
.of(rec(1, ADDR_A
.PNI_S_NUM
)), ADDR_A
.PNI_NUM
, Set
.of(rec(1, ADDR_A
.PNI_NUM
))),
82 new T(Set
.of(rec(1, ADDR_A
.ACI_PNI
)), ADDR_A
.PNI_NUM
, Set
.of(rec(1, ADDR_A
.FULL
))),
85 new T(Set
.of(rec(1, ADDR_A
.FULL
)), ADDR_A
.PNI_S_NUM
, Set
.of(rec(1, ADDR_A
.FULL
))),
86 new T(Set
.of(rec(1, ADDR_A
.ACI
)),
88 Set
.of(rec(1, ADDR_A
.ACI
), rec(1000000, ADDR_A
.PNI_S_NUM
))),
89 new T(Set
.of(rec(1, ADDR_A
.PNI
)), ADDR_A
.PNI_S_NUM
, Set
.of(rec(1, ADDR_A
.PNI_NUM
))),
90 new T(Set
.of(rec(1, ADDR_A
.PNI_S
)), ADDR_A
.PNI_S_NUM
, Set
.of(rec(1, ADDR_A
.PNI_S_NUM
))),
91 new T(Set
.of(rec(1, ADDR_A
.NUM
)), ADDR_A
.PNI_S_NUM
, Set
.of(rec(1, ADDR_A
.PNI_S_NUM
))),
92 new T(Set
.of(rec(1, ADDR_A
.ACI_NUM
)),
94 Set
.of(rec(1, ADDR_A
.ACI
), rec(1000000, ADDR_A
.PNI_S_NUM
))),
95 new T(Set
.of(rec(1, ADDR_A
.PNI_NUM
)), ADDR_A
.PNI_S_NUM
, Set
.of(rec(1, ADDR_A
.PNI_NUM
))),
96 new T(Set
.of(rec(1, ADDR_A
.PNI_S_NUM
)), ADDR_A
.PNI_S_NUM
, Set
.of(rec(1, ADDR_A
.PNI_S_NUM
))),
97 new T(Set
.of(rec(1, ADDR_A
.ACI_PNI
)), ADDR_A
.PNI_S_NUM
, Set
.of(rec(1, ADDR_A
.FULL
))),
100 new T(Set
.of(rec(1, ADDR_A
.FULL
)), ADDR_A
.ACI_PNI
, Set
.of(rec(1, ADDR_A
.FULL
))),
101 new T(Set
.of(rec(1, ADDR_A
.ACI
)), ADDR_A
.ACI_PNI
, Set
.of(rec(1, ADDR_A
.ACI_PNI
))),
102 new T(Set
.of(rec(1, ADDR_A
.PNI
)), ADDR_A
.ACI_PNI
, Set
.of(rec(1, ADDR_A
.ACI_PNI
))),
103 new T(Set
.of(rec(1, ADDR_A
.PNI_S
)), ADDR_A
.ACI_PNI
, Set
.of(rec(1, ADDR_A
.ACI_PNI
))),
104 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
))),
105 new T(Set
.of(rec(1, ADDR_A
.ACI_NUM
)), ADDR_A
.ACI_PNI
, Set
.of(rec(1, ADDR_A
.FULL
))),
106 new T(Set
.of(rec(1, ADDR_A
.PNI_NUM
)), ADDR_A
.ACI_PNI
, Set
.of(rec(1, ADDR_A
.FULL
))),
107 new T(Set
.of(rec(1, ADDR_A
.PNI_S_NUM
)), ADDR_A
.ACI_PNI
, Set
.of(rec(1, ADDR_A
.FULL
))),
108 new T(Set
.of(rec(1, ADDR_A
.ACI_PNI
)), ADDR_A
.ACI_PNI
, Set
.of(rec(1, ADDR_A
.ACI_PNI
))),
110 new T(Set
.of(rec(1, ADDR_A
.FULL
)), ADDR_B
.FULL
, Set
.of(rec(1, ADDR_A
.FULL
), rec(1000000, ADDR_B
.FULL
))),
113 static T
[] testInstancesTwo
= new T
[]{
115 new T(Set
.of(rec(1, ADDR_A
.ACI
), rec(2, ADDR_A
.PNI
)), ADDR_A
.FULL
, Set
.of(rec(1, ADDR_A
.FULL
))),
116 new T(Set
.of(rec(1, ADDR_A
.ACI
), rec(2, ADDR_A
.PNI_S
)), ADDR_A
.FULL
, Set
.of(rec(1, ADDR_A
.FULL
))),
117 new T(Set
.of(rec(1, ADDR_A
.ACI
), rec(2, ADDR_A
.NUM
)), ADDR_A
.FULL
, Set
.of(rec(1, ADDR_A
.FULL
))),
118 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
))),
119 new T(Set
.of(rec(1, ADDR_A
.ACI
), rec(2, ADDR_A
.PNI_S_NUM
)), ADDR_A
.FULL
, Set
.of(rec(1, ADDR_A
.FULL
))),
120 new T(Set
.of(rec(1, ADDR_A
.PNI
), rec(2, ADDR_A
.NUM
)), ADDR_A
.FULL
, Set
.of(rec(1, ADDR_A
.FULL
))),
121 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
))),
122 new T(Set
.of(rec(1, ADDR_A
.PNI_S
), rec(2, ADDR_A
.NUM
)), ADDR_A
.FULL
, Set
.of(rec(1, ADDR_A
.FULL
))),
123 new T(Set
.of(rec(1, ADDR_A
.PNI_S
), rec(2, ADDR_A
.ACI_NUM
)), ADDR_A
.FULL
, Set
.of(rec(2, ADDR_A
.FULL
))),
124 new T(Set
.of(rec(1, ADDR_A
.NUM
), rec(2, ADDR_A
.PNI_S
)), ADDR_A
.FULL
, Set
.of(rec(2, ADDR_A
.FULL
))),
125 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
))),
128 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
))),
129 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
))),
130 new T(Set
.of(rec(1, ADDR_A
.ACI
), rec(2, ADDR_A
.PNI_S_NUM
)),
132 Set
.of(rec(1, ADDR_A
.ACI_NUM
), rec(2, ADDR_A
.PNI_S
))),
133 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
))),
136 new T(Set
.of(rec(1, ADDR_A
.ACI
), rec(2, ADDR_A
.PNI_NUM
)),
138 Set
.of(rec(1, ADDR_A
.ACI
), rec(2, ADDR_A
.PNI_NUM
))),
139 new T(Set
.of(rec(1, ADDR_A
.ACI
), rec(2, ADDR_A
.PNI_S_NUM
)),
141 Set
.of(rec(1, ADDR_A
.ACI
), rec(2, ADDR_A
.PNI_NUM
))),
142 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
))),
143 new T(Set
.of(rec(1, ADDR_A
.PNI
), rec(2, ADDR_A
.ACI_NUM
)),
145 Set
.of(rec(1, ADDR_A
.PNI_NUM
), rec(2, ADDR_A
.ACI
))),
146 new T(Set
.of(rec(1, ADDR_A
.PNI_S
), rec(2, ADDR_A
.NUM
)), ADDR_A
.PNI_NUM
, Set
.of(rec(1, ADDR_A
.PNI_NUM
))),
147 new T(Set
.of(rec(1, ADDR_A
.PNI_S
), rec(2, ADDR_A
.ACI_NUM
)),
149 Set
.of(rec(1, ADDR_A
.PNI_NUM
), rec(2, ADDR_A
.ACI
))),
150 new T(Set
.of(rec(1, ADDR_A
.NUM
), rec(2, ADDR_A
.PNI_S
)), ADDR_A
.PNI_NUM
, Set
.of(rec(2, ADDR_A
.PNI_NUM
))),
151 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
))),
154 new T(Set
.of(rec(1, ADDR_A
.ACI
), rec(2, ADDR_A
.PNI_NUM
)),
156 Set
.of(rec(1, ADDR_A
.ACI
), rec(2, ADDR_A
.PNI_NUM
))),
157 new T(Set
.of(rec(1, ADDR_A
.ACI
), rec(2, ADDR_A
.PNI_S_NUM
)),
159 Set
.of(rec(1, ADDR_A
.ACI
), rec(2, ADDR_A
.PNI_S_NUM
))),
160 new T(Set
.of(rec(1, ADDR_A
.PNI
), rec(2, ADDR_A
.NUM
)), ADDR_A
.PNI_S_NUM
, Set
.of(rec(1, ADDR_A
.PNI_NUM
))),
161 new T(Set
.of(rec(1, ADDR_A
.PNI
), rec(2, ADDR_A
.ACI_NUM
)),
163 Set
.of(rec(1, ADDR_A
.PNI_NUM
), rec(2, ADDR_A
.ACI
))),
164 new T(Set
.of(rec(1, ADDR_A
.PNI_S
), rec(2, ADDR_A
.NUM
)), ADDR_A
.PNI_S_NUM
, Set
.of(rec(1, ADDR_A
.PNI_S_NUM
))),
165 new T(Set
.of(rec(1, ADDR_A
.PNI_S
), rec(2, ADDR_A
.ACI_NUM
)),
167 Set
.of(rec(1, ADDR_A
.PNI_S_NUM
), rec(2, ADDR_A
.ACI
))),
168 new T(Set
.of(rec(1, ADDR_A
.NUM
), rec(2, ADDR_A
.PNI_S
)), ADDR_A
.PNI_S_NUM
, Set
.of(rec(2, ADDR_A
.PNI_S_NUM
))),
169 new T(Set
.of(rec(1, ADDR_A
.NUM
), rec(2, ADDR_A
.ACI_PNI
)), ADDR_A
.PNI_S_NUM
, Set
.of(rec(2, ADDR_A
.FULL
))),
172 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
))),
173 new T(Set
.of(rec(1, ADDR_A
.ACI
), rec(2, ADDR_A
.PNI_S
)), ADDR_A
.ACI_PNI
, Set
.of(rec(1, ADDR_A
.ACI_PNI
))),
174 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
))),
175 new T(Set
.of(rec(1, ADDR_A
.ACI
), rec(2, ADDR_A
.PNI_S_NUM
)),
177 Set
.of(rec(1, ADDR_A
.ACI_PNI
), rec(2, ADDR_A
.NUM
))),
178 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
))),
179 new T(Set
.of(rec(1, ADDR_A
.PNI_S
), rec(2, ADDR_A
.ACI_NUM
)), ADDR_A
.ACI_PNI
, Set
.of(rec(2, ADDR_A
.FULL
))),
182 static T
[] testInstancesThree
= new T
[]{
184 new T(Set
.of(rec(1, ADDR_A
.ACI
), rec(2, ADDR_A
.PNI
), rec(3, ADDR_A
.NUM
)),
186 Set
.of(rec(1, ADDR_A
.FULL
))),
187 new T(Set
.of(rec(1, ADDR_A
.ACI
.withIdentifiersFrom(ADDR_B
.PNI
)), rec(2, ADDR_A
.PNI
), rec(3, ADDR_A
.NUM
)),
189 Set
.of(rec(1, ADDR_A
.FULL
))),
190 new T(Set
.of(rec(1, ADDR_A
.ACI
.withIdentifiersFrom(ADDR_B
.NUM
)), rec(2, ADDR_A
.PNI
), rec(3, ADDR_A
.NUM
)),
192 Set
.of(rec(1, ADDR_A
.FULL
))),
193 new T(Set
.of(rec(1, ADDR_A
.ACI
), rec(2, ADDR_A
.PNI
), rec(3, ADDR_A
.NUM
.withIdentifiersFrom(ADDR_B
.ACI
))),
195 Set
.of(rec(1, ADDR_A
.FULL
), rec(3, ADDR_B
.ACI
))),
196 new T(Set
.of(rec(1, ADDR_A
.ACI
), rec(2, ADDR_A
.PNI
.withIdentifiersFrom(ADDR_B
.ACI
)), rec(3, ADDR_A
.NUM
)),
198 Set
.of(rec(1, ADDR_A
.FULL
), rec(2, ADDR_B
.ACI
))),
203 void resolveRecipientTrustedLocked_NoneExisting(T test
) throws Exception
{
204 final var testStore
= new TestStore(test
.input
);
205 MergeRecipientHelper
.resolveRecipientTrustedLocked(testStore
, test
.request
);
206 assertEquals(test
.output
, testStore
.getRecipients());
209 private static Stream
<Arguments
> resolveRecipientTrustedLocked_NoneExisting() {
210 return Arrays
.stream(testInstancesNone
).map(Arguments
::of
);
215 void resolveRecipientTrustedLocked_SingleExisting(T test
) throws Exception
{
216 final var testStore
= new TestStore(test
.input
);
217 MergeRecipientHelper
.resolveRecipientTrustedLocked(testStore
, test
.request
);
218 assertEquals(test
.output
, testStore
.getRecipients());
221 private static Stream
<Arguments
> resolveRecipientTrustedLocked_SingleExisting() {
222 return Arrays
.stream(testInstancesSingle
).map(Arguments
::of
);
227 void resolveRecipientTrustedLocked_TwoExisting(T test
) throws Exception
{
228 final var testStore
= new TestStore(test
.input
);
229 MergeRecipientHelper
.resolveRecipientTrustedLocked(testStore
, test
.request
);
230 assertEquals(test
.output
, testStore
.getRecipients());
233 private static Stream
<Arguments
> resolveRecipientTrustedLocked_TwoExisting() {
234 return Arrays
.stream(testInstancesTwo
).map(Arguments
::of
);
239 void resolveRecipientTrustedLocked_ThreeExisting(T test
) throws Exception
{
240 final var testStore
= new TestStore(test
.input
);
241 MergeRecipientHelper
.resolveRecipientTrustedLocked(testStore
, test
.request
);
242 assertEquals(test
.output
, testStore
.getRecipients());
245 private static Stream
<Arguments
> resolveRecipientTrustedLocked_ThreeExisting() {
246 return Arrays
.stream(testInstancesThree
).map(Arguments
::of
);
249 private static RecipientWithAddress
rec(long recipientId
, RecipientAddress address
) {
250 return new RecipientWithAddress(new RecipientId(recipientId
, null), address
);
254 Set
<RecipientWithAddress
> input
, RecipientAddress request
, Set
<RecipientWithAddress
> output
258 public String
toString() {
259 return "T{#input=%s, request=%s_%s_%s, #output=%s}".formatted(input
.size(),
260 request
.serviceId().isPresent() ?
"SVI" : "",
261 request
.pni().isPresent() ?
"PNI" : "",
262 request
.number().isPresent() ?
"NUM" : "",
267 static class TestStore
implements MergeRecipientHelper
.Store
{
269 final Set
<RecipientWithAddress
> recipients
;
270 long nextRecipientId
= 1000000;
272 TestStore(final Set
<RecipientWithAddress
> recipients
) {
273 this.recipients
= new HashSet
<>(recipients
);
276 public Set
<RecipientWithAddress
> getRecipients() {
281 public Set
<RecipientWithAddress
> findAllByAddress(final RecipientAddress address
) {
282 return recipients
.stream().filter(r
-> r
.address().matches(address
)).collect(Collectors
.toSet());
286 public RecipientId
addNewRecipient(final RecipientAddress address
) {
287 final var recipientId
= new RecipientId(nextRecipientId
++, null);
288 recipients
.add(new RecipientWithAddress(recipientId
, address
));
293 public void updateRecipientAddress(
294 final RecipientId recipientId
, final RecipientAddress address
296 recipients
.removeIf(r
-> r
.id().equals(recipientId
));
297 recipients
.add(new RecipientWithAddress(recipientId
, address
));
301 public void removeRecipientAddress(final RecipientId recipientId
) {
302 recipients
.removeIf(r
-> r
.id().equals(recipientId
));
306 private record PartialAddresses(
307 RecipientAddress FULL
,
308 RecipientAddress ACI
,
309 RecipientAddress PNI
,
310 RecipientAddress PNI_S
,
311 RecipientAddress NUM
,
312 RecipientAddress ACI_NUM
,
313 RecipientAddress PNI_NUM
,
314 RecipientAddress PNI_S_NUM
,
315 RecipientAddress ACI_PNI
318 PartialAddresses(ServiceId serviceId
, PNI pni
, String number
) {
319 this(new RecipientAddress(serviceId
, pni
, number
),
320 new RecipientAddress(serviceId
, null, null),
321 new RecipientAddress(null, pni
, null),
322 new RecipientAddress(ServiceId
.from(pni
.uuid()), null, null),
323 new RecipientAddress(null, null, number
),
324 new RecipientAddress(serviceId
, null, number
),
325 new RecipientAddress(null, pni
, number
),
326 new RecipientAddress(ServiceId
.from(pni
.uuid()), null, number
),
327 new RecipientAddress(serviceId
, pni
, null));