This test-only change adds tests for [`Subscription`][0].
I did this because I'll be adding additional behavior to this struct and
want to be ready to test that logic. I think this is a useful change on
its own, however, so I split it out into its own change.
[0]: 2693c55232/SignalMessaging/Subscriptions/SubscriptionManager.swift (L70-L104)
The class can be computed from `self`, and the lookup block is always
the same (essentially `self.value(forKey:)`), so there’s no need to
provide separate implementations for each subclass. The superclass can
provide a single implementation for all subclasses to share.
Messages always have an isGroupStoryReply of true or false (1 or 0),
but non-messages don't have this field, and GRDB treats that as NULL
rather than falling back to the table default.
notImplemented() ends up forwarding to fatalError() anyway, but before
it does so it flushes our logs. That's probably good to have. I think
most of these come from the default implementations Xcode provides for
you with a fix-it.
...so it can use an existing one when there is one, which in practice
there always is because we never refresh one-time pre-keys without
rotating our signed pre-key too.
We're very close to being able to decrypt messages sent to our PNI,
but *until* that point it's best to just drop any such messages. This
should make testing easier.
This is the first meaty part of optimizing
fetching display names.
Some contacts fall back to phone numbers as their
display names. This PR fetches them in a single
SQL query via
`OWSContactsManager.phoneNumbers(for:, transaction)`.
To achieve this, this PR introduces
`GRDBSignalAccountFinder.signalAccounts(for:,transaction:)`
to fetch many accounts at once.
In order to fetch many accounts at once, we need
to be able to fetch many values from a
ModelReadCache at once. So this PR introduces
`ModelReadCache.readValues(for:,transaction:)` and
`ModelReadCache.getValues(for:,transaction:,returnNilOnCacheMiss:)`.
Existing methods that operate on a single value
were refactored to use the batch methods.
This PR adds tests for this functionality, which
necessitated changing the visibility of various
private symbols and also improving the fake
profile manager to make it more configurable.
There's also a tiny optimization for Refinery to
avoid calling a closure that has no work to do.
This helps elide do-nothing SQL queries that would
otherwise have been introduced.
'sessionStore', 'preKeyStore', and 'signedPreKeyStore' are no longer
directly accessible; you have to go through
'signalProtocolStore(for:)' instead. This commit mechanically changes
all use sites to use `signalProtocolStore(for: .aci)`, with the
understanding that they will need cleanup in the future.
This is not enough to actually support multiple stores; they still
store in the database under the same keys. That's coming in the next
commit.
This PR is the first in a series that will
optimize looking up full names of group members.
The biggest source of slowness when opening a
group chat is looking up the full names of group
members in the search for duplicates. It is slow
because it requires multiple db queries for each
member.
The characterstic feature of this algorithm is the
iterative process of assigning names to signal
addresses. For example, some contacts' names may
be cached. For others, their profiles must be
fetched. For those without profiles, their phone
numbers must be formatted (which requires fetching
SignalAccounts). For those without phone numbers,
their user names must be formatted.
This PR creates a class called Refinery. Its job
is to make it easy to assign values to keys
through multiple passes, where each pass may
succeed only for a subset of keys.
This is useful because we will eventually issue a
single DB query for some of these passes.
Commit 451fa08c22
had some bugs and was reverted by commit
12883e5db5.
This commit brings it back along with fixes.
Specific bug fixes:
* Verification status for a group was inverted.
* The local address should not be considered for
deciding if a group is verified.
These tests fulfill an expectation when a write to the database causes
the desired state to be reached. However, there may still be writes to
the database in flight, and the *next* write will *also* probably be
in the desired state, resulting in the expectation being fulfilled
again. Because this happened *after* the test finished, an exception
was thrown, the test environment terminated, and the *next* test (or
possibly a later one) was being blamed for the failure.
Fix this issue in both places where it happens by allowing multiple
fulfills, and re-enable the test that was previously getting blamed
for this.
Generate valid sender certificates in tests, removing the need to
customize validation or build certificate data by hand.
While here, remove "throwswrapped" from some APIs that no longer wrap
ObjC-throwing methods.