From 431a6bf286dbb82b6209a9b07064b407f688c1fb Mon Sep 17 00:00:00 2001 From: Mariusz Woloszyn Date: Sun, 20 Sep 2026 15:22:05 +0000 Subject: [PATCH] Address numberless linking review cleanup Reuse AccountApiV2 through SignalDependencies and use the shared suspend response helper while preserving linking error handling. Remove the unused account-number accessor and unsupported D-Bus version fallback. Keep numberless linking documentation in the man page and point the README to the wiki. Validate linking errors through HTTP response fixtures. All 196 tests pass on JDK 25 with an isolated D-Bus session; build and JSON schema generation also pass. Account-index classification is unchanged pending review discussion. --- README.md | 2 +- doc/numberless-accounts.md | 73 ------------------- .../signal/manager/MultiAccountManager.java | 2 - .../signal/manager/helper/AccountHelper.java | 17 ++--- .../internal/MultiAccountManagerImpl.java | 7 -- .../internal/ProvisioningManagerImpl.java | 36 ++++----- .../manager/internal/SignalDependencies.java | 7 ++ .../internal/NumberlessProvisioningTest.java | 73 ++++++++++++------- man/signal-cli.1.adoc | 4 + .../asamk/signal/dbus/DbusManagerImpl.java | 13 +--- .../dbus/DbusMultiAccountManagerImpl.java | 5 -- .../asamk/signal/dbus/NumberlessDbusTest.java | 22 +----- .../jsonrpc/SubscribeCallEventsTest.java | 5 -- 13 files changed, 81 insertions(+), 185 deletions(-) delete mode 100644 doc/numberless-accounts.md diff --git a/README.md b/README.md index 32f4a29c..a98f651c 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ For a numbered account, ACCOUNT is your phone number in international format and should start with a "+" sign. (See [Wikipedia](https://en.wikipedia.org/wiki/List_of_country_calling_codes) for a list of all country codes.) For a linked account without a phone number, use its ACI (Account ID) instead. -See [numberless accounts](doc/numberless-accounts.md) for details. +See the [wiki](https://github.com/AsamK/signal-cli/wiki) for further documentation. * Link to an existing account diff --git a/doc/numberless-accounts.md b/doc/numberless-accounts.md deleted file mode 100644 index fa8c3b47..00000000 --- a/doc/numberless-accounts.md +++ /dev/null @@ -1,73 +0,0 @@ -# Linking an account without a phone number - -signal-cli can link as a secondary device to an account registered without a phone -number, such as those created in Signal Android 8.28. Creating or recovering a -primary numberless account using an Account Key is not supported. - -Run `signal-cli link -n signal-cli`, then scan the QR code from the mobile app's -Linked devices screen. The linking URI advertises `capabilities=nopni`. If linking -completes, the CLI prints the account's ACI instead of a phone number. - -Use that ACI with `-a` for subsequent commands: - -```sh -signal-cli -a YOUR_ACCOUNT_ACI receive -signal-cli -a YOUR_ACCOUNT_ACI listGroups -signal-cli -a YOUR_ACCOUNT_ACI send --note-to-self -m 'Numberless account test' -``` - -When only one local account exists, `-a` can be omitted. Numbered accounts continue -to accept their phone number or ACI. A numberless account cannot infer a country -code for a recipient's phone number; use a complete international number beginning -with `+`, an ACI, or a Signal username. - -In JSON-RPC, use the ACI in the `account` parameter. `listAccounts` and `finishLink` -return an `aci` field alongside `number`; `number` is null for a numberless account. -Receive events use the ACI in their `account` field when there is no phone number. -REST wrappers must understand those nullable numbers and ACI selectors before they -can be assumed compatible. - -Numberless accounts are also supported through D-Bus. Start -`signal-cli daemon --dbus`, then use the ACI with the D-Bus client: - -```sh -signal-cli --dbus -a YOUR_ACCOUNT_ACI listGroups -signal-cli --dbus -a YOUR_ACCOUNT_ACI send --note-to-self -m 'Numberless account test' -``` - -In multi-account mode, D-Bus exports numberless accounts under -`/org/asamk/Signal/ACI`, with the ACI's hyphens replaced by underscores. Numbered -accounts retain their phone-number-based paths. Use `SignalControl.listAccounts` -or `SignalControl.getAccount` to discover paths; `getAccount` accepts either a -phone number or an ACI. `Signal.getSelfNumber` returns an empty string when the -account has no phone number, and `Signal.getSelfACI` returns the ACI. -`Signal.listRecipientIdentifiers` includes contacts without a phone number; -`Signal.listNumbers` continues to return only phone numbers. - -## Validation - -Run `./gradlew test installDist` with JDK 25. Regression tests cover the linking -request (including ACI authentication and omission of PNI keys), numbered-account -linking, missing group credential salts, persisted account reload, account discovery -(including superseded accounts and legacy indexes), group membership lookup, -recipient-number formatting, and JSON account identifiers. - -D-Bus transport tests require a session bus. To run them on an isolated bus, use -`dbus-run-session -- ./gradlew --no-daemon :test --tests '*NumberlessDbusTest*' --rerun-tasks`. -These tests exercise the D-Bus server and client with a local test backend, including -mixed accounts, direct and group messages, self-directed operations, and account -removal. They do not contact Signal. Without a session bus, only the D-Bus unit -tests run and the transport tests are skipped. - -Live acceptance requires a real mobile account and is separate from these tests: - -1. Link a newly created secondary device using the numberless mobile account. -2. Restart signal-cli and verify that `listAccounts` still reports the ACI. -3. Send and receive a Note to Self message and a DM with a second account. -4. Receive a group message, list the group, and send a reply to that test group. -5. Run the JSON-RPC daemon, restart it, and repeat receiving and sending by ACI. -6. Repeat with `daemon --dbus` and the `--dbus -a YOUR_ACCOUNT_ACI` client, checking - direct messages, group messages, and Note to Self. - -Only one signal-cli process may open an account's state at a time. Stop the daemon -before running one-off commands against the same configuration directory. diff --git a/lib/src/main/java/org/asamk/signal/manager/MultiAccountManager.java b/lib/src/main/java/org/asamk/signal/manager/MultiAccountManager.java index 15b60594..5d83819b 100644 --- a/lib/src/main/java/org/asamk/signal/manager/MultiAccountManager.java +++ b/lib/src/main/java/org/asamk/signal/manager/MultiAccountManager.java @@ -8,8 +8,6 @@ import java.util.function.Consumer; public interface MultiAccountManager extends AutoCloseable { - List getAccountNumbers(); - List getManagers(); void addOnManagerAddedHandler(Consumer handler); diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/AccountHelper.java b/lib/src/main/java/org/asamk/signal/manager/helper/AccountHelper.java index 6ada2fd7..210a5906 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/AccountHelper.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/AccountHelper.java @@ -1,5 +1,6 @@ package org.asamk.signal.manager.helper; +import org.asamk.signal.manager.api.BadRequestException; import org.asamk.signal.manager.api.CaptchaRequiredException; import org.asamk.signal.manager.api.DeviceLinkUrl; import org.asamk.signal.manager.api.IncorrectPinException; @@ -18,7 +19,6 @@ import org.signal.core.models.ServiceId.ACI; import org.signal.core.models.ServiceId.PNI; import org.signal.core.util.Base64; import org.signal.core.util.crypto.DeviceNameCipher; -import org.signal.libsignal.net.RequestResult; import org.signal.libsignal.protocol.IdentityKeyPair; import org.signal.libsignal.protocol.InvalidKeyException; import org.signal.libsignal.protocol.NoSessionException; @@ -28,7 +28,6 @@ import org.signal.libsignal.protocol.state.SignedPreKeyRecord; import org.signal.libsignal.protocol.util.KeyHelper; import org.signal.libsignal.usernames.BaseUsernameException; import org.signal.libsignal.usernames.Username; -import org.signal.network.api.AccountApiV2; import org.signal.network.api.AccountApiV2.SetAccountAttributesError; import org.signal.network.exceptions.NonSuccessfulResponseCodeException; import org.slf4j.Logger; @@ -60,13 +59,11 @@ import java.util.Objects; import java.util.UUID; import java.util.concurrent.TimeUnit; -import kotlin.Unit; import okio.ByteString; import static org.asamk.signal.manager.config.ServiceConfig.PREKEY_MAXIMUM_ID; import static org.asamk.signal.manager.util.Utils.handleResponseException; import static org.asamk.signal.manager.util.Utils.handleResponseExceptionSuspend; -import static org.asamk.signal.manager.util.Utils.runSuspendBlocking; import static org.whispersystems.signalservice.internal.util.Util.isEmpty; public class AccountHelper { @@ -575,17 +572,15 @@ public class AccountHelper { .setAccountAttributes(account.getAccountAttributes(null))); return; } - final var api = new AccountApiV2(dependencies.getAuthenticatedSignalWebSocket()); - final RequestResult result = runSuspendBlocking(cont -> api.setAccountAttributes( - account.getAccountAttributesV2(), - cont)); - if (result instanceof RequestResult.NonSuccess failure) { - if (failure.getError() instanceof SetAccountAttributesError.Unauthorized) { + try { + handleResponseExceptionSuspend(cont -> dependencies.getAccountApiV2() + .setAccountAttributes(account.getAccountAttributesV2(), cont)); + } catch (BadRequestException e) { + if (e.getError() instanceof SetAccountAttributesError.Unauthorized) { throw new AuthorizationFailedException(401, "Authorization failed!"); } throw new IOException("Account attribute update rate limited; try again later"); } - handleResponseException(result); } public void addDevice(DeviceLinkUrl deviceLinkInfo) throws IOException, org.asamk.signal.manager.api.DeviceLimitExceededException { diff --git a/lib/src/main/java/org/asamk/signal/manager/internal/MultiAccountManagerImpl.java b/lib/src/main/java/org/asamk/signal/manager/internal/MultiAccountManagerImpl.java index 0d6a60a8..c767afba 100644 --- a/lib/src/main/java/org/asamk/signal/manager/internal/MultiAccountManagerImpl.java +++ b/lib/src/main/java/org/asamk/signal/manager/internal/MultiAccountManagerImpl.java @@ -39,13 +39,6 @@ public class MultiAccountManagerImpl implements MultiAccountManager { managers.forEach(m -> m.addClosedListener(() -> this.removeManager(m))); } - @Override - public List getAccountNumbers() { - synchronized (managers) { - return managers.stream().map(Manager::getSelfNumber).toList(); - } - } - @Override public List getManagers() { synchronized (managers) { diff --git a/lib/src/main/java/org/asamk/signal/manager/internal/ProvisioningManagerImpl.java b/lib/src/main/java/org/asamk/signal/manager/internal/ProvisioningManagerImpl.java index aca7e3f3..c92aec12 100644 --- a/lib/src/main/java/org/asamk/signal/manager/internal/ProvisioningManagerImpl.java +++ b/lib/src/main/java/org/asamk/signal/manager/internal/ProvisioningManagerImpl.java @@ -19,6 +19,7 @@ package org.asamk.signal.manager.internal; import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.ProvisioningManager; import org.asamk.signal.manager.Settings; +import org.asamk.signal.manager.api.BadRequestException; import org.asamk.signal.manager.api.UserAlreadyExistsException; import org.asamk.signal.manager.config.ServiceEnvironmentConfig; import org.asamk.signal.manager.storage.SignalAccount; @@ -29,7 +30,6 @@ import org.signal.core.models.ServiceId.ACI; import org.signal.core.models.ServiceId.PNI; import org.signal.core.models.backup.MediaRootBackupKey; import org.signal.core.util.crypto.DeviceNameCipher; -import org.signal.libsignal.net.RequestResult; import org.signal.libsignal.protocol.IdentityKey; import org.signal.libsignal.protocol.IdentityKeyPair; import org.signal.libsignal.protocol.ecc.ECPrivateKey; @@ -69,8 +69,7 @@ import kotlinx.coroutines.BuildersKt; import kotlinx.coroutines.CoroutineScope; import static org.asamk.signal.manager.util.KeyUtils.generatePreKeysForType; -import static org.asamk.signal.manager.util.Utils.handleResponseException; -import static org.asamk.signal.manager.util.Utils.runSuspendBlocking; +import static org.asamk.signal.manager.util.Utils.handleResponseExceptionSuspend; public class ProvisioningManagerImpl implements ProvisioningManager, Closeable { @@ -324,23 +323,19 @@ public class ProvisioningManagerImpl implements ProvisioningManager, Closeable { attrs.getPniRegistrationId(), attrs.getName(), attrs.getCapabilities()); - final RequestResult result = runSuspendBlocking(cont -> registrationApi.registerAsSecondaryDevice( - account.getAci(), - account.getPassword(), - provisioningCode, - deviceAttributes, - toRegistrationPreKeys(aciPreKeys), - toRegistrationPreKeys(pniPreKeys), - null, - cont)); - return getLinkedDeviceId(result); - } - - static int getLinkedDeviceId( - final RequestResult result - ) throws IOException { - if (result instanceof RequestResult.NonSuccess failure) { - throw switch (failure.getError()) { + try { + final LinkDeviceResponse result = handleResponseExceptionSuspend(cont -> registrationApi.registerAsSecondaryDevice( + account.getAci(), + account.getPassword(), + provisioningCode, + deviceAttributes, + toRegistrationPreKeys(aciPreKeys), + toRegistrationPreKeys(pniPreKeys), + null, + cont)); + return result.getDeviceId(); + } catch (BadRequestException e) { + throw switch (e.getError()) { case RegisterAsLinkedDeviceError.IncorrectVerification ignored -> new AuthorizationFailedException(403, "Device verification failed"); case RegisterAsLinkedDeviceError.MissingCapability ignored -> @@ -354,7 +349,6 @@ public class ProvisioningManagerImpl implements ProvisioningManager, Closeable { default -> new IOException("Unexpected device linking response"); }; } - return handleResponseException(result).getDeviceId(); } static RegistrationApiV2.PreKeyCollection toRegistrationPreKeys(final PreKeyCollection preKeys) { diff --git a/lib/src/main/java/org/asamk/signal/manager/internal/SignalDependencies.java b/lib/src/main/java/org/asamk/signal/manager/internal/SignalDependencies.java index 643e81df..7add6211 100644 --- a/lib/src/main/java/org/asamk/signal/manager/internal/SignalDependencies.java +++ b/lib/src/main/java/org/asamk/signal/manager/internal/SignalDependencies.java @@ -8,6 +8,7 @@ import org.signal.libsignal.metadata.certificate.CertificateValidator; import org.signal.libsignal.net.Network; import org.signal.libsignal.protocol.SignalProtocolAddress; import org.signal.libsignal.zkgroup.profiles.ClientZkProfileOperations; +import org.signal.network.api.AccountApiV2; import org.signal.network.api.AttachmentApi; import org.signal.network.api.CallingApi; import org.signal.network.api.CdsApi; @@ -73,6 +74,7 @@ public class SignalDependencies { private SignalServiceAccountManager accountManager; private AccountApi accountApi; + private AccountApiV2 accountApiV2; private RateLimitChallengeApi rateLimitChallengeApi; private CdsApi cdsApi; private UsernameApi usernameApi; @@ -221,6 +223,11 @@ public class SignalDependencies { return getOrCreate(() -> accountApi, () -> accountApi = new AccountApi(getAuthenticatedSignalWebSocket())); } + public AccountApiV2 getAccountApiV2() { + return getOrCreate(() -> accountApiV2, + () -> accountApiV2 = new AccountApiV2(getAuthenticatedSignalWebSocket())); + } + public RateLimitChallengeApi getRateLimitChallengeApi() { return getOrCreate(() -> rateLimitChallengeApi, () -> rateLimitChallengeApi = new RateLimitChallengeApi(getAuthenticatedSignalWebSocket())); diff --git a/lib/src/test/java/org/asamk/signal/manager/internal/NumberlessProvisioningTest.java b/lib/src/test/java/org/asamk/signal/manager/internal/NumberlessProvisioningTest.java index 6e143cb9..1510a871 100644 --- a/lib/src/test/java/org/asamk/signal/manager/internal/NumberlessProvisioningTest.java +++ b/lib/src/test/java/org/asamk/signal/manager/internal/NumberlessProvisioningTest.java @@ -10,11 +10,11 @@ import org.asamk.signal.manager.storage.SignalAccount; import org.asamk.signal.manager.util.KeyUtils; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; import org.signal.core.models.ServiceId.ACI; import org.signal.core.models.ServiceId.PNI; -import org.signal.libsignal.net.RequestResult; import org.signal.network.api.RegistrationApiV2; -import org.signal.network.api.RegistrationApiV2.RegisterAsLinkedDeviceError; import org.signal.network.rest.SignalRestClient; import org.whispersystems.signalservice.api.push.ServiceIdType; import org.whispersystems.signalservice.api.push.exceptions.AuthorizationFailedException; @@ -36,7 +36,7 @@ import okio.Buffer; import okio.ByteString; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -72,15 +72,35 @@ class NumberlessProvisioningTest { @Test void numberlessLinkRequestOmitsPniAndAuthenticatesWithAci() throws Exception { - checkLinkRequest(null, null); + checkLinkRequest(null, null, 200, null); } @Test void numberedLinkRequestStillIncludesPniKeys() throws Exception { - checkLinkRequest("+12025550123", PNI_ID); + checkLinkRequest("+12025550123", PNI_ID, 200, null); } - private void checkLinkRequest(final String number, final PNI pni) throws Exception { + @ParameterizedTest + @CsvSource({ + "422, Signal rejected the device linking request", + "403, [403] Device verification failed", + "409, Linked device is missing a required account capability", + "411, Account has reached its linked device limit", + "429, Device linking rate limited; try again later" + }) + void linkingErrorsAreReportedWithoutCrashingOrIncludingServerBody( + final int statusCode, + final String errorMessage + ) throws Exception { + checkLinkRequest(null, null, statusCode, errorMessage); + } + + private void checkLinkRequest( + final String number, + final PNI pni, + final int statusCode, + final String errorMessage + ) throws Exception { final var request = new AtomicReference(); final var body = new AtomicReference(); final var mapper = new ObjectMapper(); @@ -91,9 +111,10 @@ class NumberlessProvisioningTest { body.set(mapper.readTree(buffer.readUtf8())); return new Response.Builder().request(chain.request()) .protocol(Protocol.HTTP_1_1) - .code(200) - .message("OK") - .body(ResponseBody.create("{\"deviceId\":2}", MediaType.get("application/json"))) + .code(statusCode) + .message("Test response") + .body(ResponseBody.create(statusCode == 200 ? "{\"deviceId\":2}" : "secret payload", + MediaType.get("application/json"))) .build(); }).build(); final var config = ServiceConfig.getServiceEnvironmentConfig(ServiceEnvironment.STAGING, "signal-cli-test"); @@ -125,13 +146,21 @@ class NumberlessProvisioningTest { final var pniKeys = pni == null ? null : KeyUtils.generatePreKeysForType(account.getAccountData(ServiceIdType.PNI)); - final var deviceId = ProvisioningManagerImpl.registerLinkedDevice(api, - account, - "test-code", - aciKeys, - pniKeys); - - assertEquals(2, deviceId); + if (statusCode == 200) { + assertEquals(2, + ProvisioningManagerImpl.registerLinkedDevice(api, account, "test-code", aciKeys, pniKeys)); + } else { + final var error = assertThrows(IOException.class, + () -> ProvisioningManagerImpl.registerLinkedDevice(api, + account, + "test-code", + aciKeys, + pniKeys)); + assertEquals(errorMessage, error.getMessage()); + if (statusCode == 403) { + assertInstanceOf(AuthorizationFailedException.class, error); + } + } assertEquals("PUT", request.get().method()); assertEquals("/v1/devices/link", request.get().url().encodedPath()); assertEquals(Credentials.basic(ACI_ID.toString(), "test-password"), request.get().header("Authorization")); @@ -150,16 +179,4 @@ class NumberlessProvisioningTest { client.connectionPool().evictAll(); } } - - @Test - @SuppressWarnings("unchecked") - void linkingErrorsAreReportedWithoutCrashingOrIncludingServerBody() { - final var incorrectVerification = RegisterAsLinkedDeviceError.IncorrectVerification.INSTANCE; - assertThrows(AuthorizationFailedException.class, - () -> ProvisioningManagerImpl.getLinkedDeviceId(new RequestResult.NonSuccess<>(incorrectVerification))); - final var invalidRequest = new RegisterAsLinkedDeviceError.InvalidRequest("secret payload"); - final var error = assertThrows(IOException.class, - () -> ProvisioningManagerImpl.getLinkedDeviceId(new RequestResult.NonSuccess<>(invalidRequest))); - assertFalse(error.getMessage().contains("secret payload")); - } } diff --git a/man/signal-cli.1.adoc b/man/signal-cli.1.adoc index ffe9e2a6..375bfbb2 100644 --- a/man/signal-cli.1.adoc +++ b/man/signal-cli.1.adoc @@ -251,6 +251,10 @@ If you want to connect to another signal-cli instance, you can just use this URI If you want to link to an Android/iOS device, scan the QR code that signal-cli prints in the terminal with the Signal app. If signal-cli is not running in a terminal, only the URI is printed and you can create a QR code from it yourself (e.g. with qrencode). +Accounts without a phone number can also be linked. +After linking, use the account's ACI (Account ID) with `-a`; recipient phone numbers must include the international country code. +Creating or recovering a primary account without a phone number using an Account Key is not supported. + *-n* NAME, *--name* NAME:: Optionally specify a name to describe this new device. By default "cli" will be used. diff --git a/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java b/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java index d9c3cf98..091816cc 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java +++ b/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java @@ -56,7 +56,6 @@ import org.asamk.signal.manager.api.UsernameLinkUrl; import org.asamk.signal.manager.api.UsernameStatus; import org.freedesktop.dbus.DBusPath; import org.freedesktop.dbus.connections.impl.DBusConnection; -import org.freedesktop.dbus.errors.UnknownMethod; import org.freedesktop.dbus.exceptions.DBusException; import org.freedesktop.dbus.exceptions.DBusExecutionException; import org.freedesktop.dbus.interfaces.DBusInterface; @@ -815,7 +814,8 @@ public class DbusManagerImpl implements Manager { final var identifiers = addresses.stream() .map(RecipientIdentifier.Single::getIdentifier) .collect(Collectors.toSet()); - return listRecipientIdentifiers().stream() + return signal.listRecipientIdentifiers() + .stream() .filter(n -> addresses.isEmpty() || identifiers.contains(n)) .map(n -> { final var contactBlocked = signal.isContactBlocked(n); @@ -1090,15 +1090,6 @@ public class DbusManagerImpl implements Manager { } } - private List listRecipientIdentifiers() { - try { - return signal.listRecipientIdentifiers(); - } catch (UnknownMethod e) { - // Older daemons only expose recipients with a known phone number. - return signal.listNumbers(); - } - } - private T getRemoteObject(final DBusPath path, final Class type) { try { return connection.getRemoteObject(busname, path.getPath(), type); diff --git a/src/main/java/org/asamk/signal/dbus/DbusMultiAccountManagerImpl.java b/src/main/java/org/asamk/signal/dbus/DbusMultiAccountManagerImpl.java index a0083270..da88343b 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusMultiAccountManagerImpl.java +++ b/src/main/java/org/asamk/signal/dbus/DbusMultiAccountManagerImpl.java @@ -43,11 +43,6 @@ public class DbusMultiAccountManagerImpl implements MultiAccountManager { this.busname = busname; } - @Override - public List getAccountNumbers() { - return getManagers().stream().map(Manager::getSelfNumber).toList(); - } - @Override public List getManagers() { return signalControl.listAccounts() diff --git a/src/test/java/org/asamk/signal/dbus/NumberlessDbusTest.java b/src/test/java/org/asamk/signal/dbus/NumberlessDbusTest.java index c805a5b7..cf6520f5 100644 --- a/src/test/java/org/asamk/signal/dbus/NumberlessDbusTest.java +++ b/src/test/java/org/asamk/signal/dbus/NumberlessDbusTest.java @@ -24,7 +24,6 @@ import org.asamk.signal.manager.internal.MultiAccountManagerImpl; import org.freedesktop.dbus.DBusPath; import org.freedesktop.dbus.connections.impl.DBusConnection; import org.freedesktop.dbus.connections.impl.DBusConnectionBuilder; -import org.freedesktop.dbus.errors.UnknownMethod; import org.freedesktop.dbus.exceptions.DBusExecutionException; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -94,25 +93,6 @@ class NumberlessDbusTest { : new RecipientIdentifier.Number(number)); } - @Test - void readsContactsFromOlderDaemonsWithoutTheNewRecipientListingMethod() { - final var account = new TestAccount(NUMBER, ACI); - account.recipients = List.of(Recipient.newBuilder().withAddress(new RecipientAddress(NUMBER)).build()); - final var signal = new DbusSignalImpl(account.manager, null, DbusConfig.getObjectPath(), true) { - @Override - public List listRecipientIdentifiers() { - throw new UnknownMethod("Not implemented by this daemon"); - } - }; - final var client = new DbusManagerImpl(signal, null, "org.asamk.Signal.Test"); - assertEquals(NUMBER, - client.getRecipients(false, Optional.empty(), Set.of(), Optional.empty()) - .getFirst() - .getAddress() - .number() - .orElseThrow()); - } - // Run with: dbus-run-session -- ./gradlew --no-daemon :test --tests '*NumberlessDbusTest*' --rerun-tasks @Nested @Timeout(20) @@ -148,7 +128,7 @@ class NumberlessDbusTest { final var client = new DbusMultiAccountManagerImpl(control, connection, busname); assertEquals(3, client.getManagers().size()); - assertEquals(2, client.getAccountNumbers().stream().filter(n -> n == null).count()); + assertEquals(2, client.getManagers().stream().filter(m -> m.getSelfNumber() == null).count()); assertNull(client.getManager(ACI).getSelfNumber()); assertEquals(NUMBER, client.getManager(OTHER_ACI).getSelfNumber()); diff --git a/src/test/java/org/asamk/signal/jsonrpc/SubscribeCallEventsTest.java b/src/test/java/org/asamk/signal/jsonrpc/SubscribeCallEventsTest.java index 80fc63e2..9ec1c87d 100644 --- a/src/test/java/org/asamk/signal/jsonrpc/SubscribeCallEventsTest.java +++ b/src/test/java/org/asamk/signal/jsonrpc/SubscribeCallEventsTest.java @@ -72,11 +72,6 @@ class SubscribeCallEventsTest { this.managers = new ArrayList<>(managers); } - @Override - public List getAccountNumbers() { - return managers.stream().map(Manager::getSelfNumber).toList(); - } - @Override public List getManagers() { return managers;