-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8e598c1
commit 9f3ffa3
Showing
6 changed files
with
215 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
63 changes: 63 additions & 0 deletions
63
service/src/main/java/org/whispersystems/textsecuregcm/grpc/PaymentsGrpcService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/* | ||
* Copyright 2023 Signal Messenger, LLC | ||
* SPDX-License-Identifier: AGPL-3.0-only | ||
*/ | ||
|
||
package org.whispersystems.textsecuregcm.grpc; | ||
|
||
import static java.util.Objects.requireNonNull; | ||
|
||
import io.grpc.Status; | ||
import java.math.BigDecimal; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.stream.Collectors; | ||
import javax.annotation.Nonnull; | ||
import org.apache.commons.lang3.tuple.Pair; | ||
import org.signal.chat.payments.GetCurrencyConversionsRequest; | ||
import org.signal.chat.payments.GetCurrencyConversionsResponse; | ||
import org.signal.chat.payments.ReactorPaymentsGrpc; | ||
import org.whispersystems.textsecuregcm.auth.grpc.AuthenticationUtil; | ||
import org.whispersystems.textsecuregcm.currency.CurrencyConversionManager; | ||
import org.whispersystems.textsecuregcm.entities.CurrencyConversionEntityList; | ||
import reactor.core.publisher.Mono; | ||
|
||
public class PaymentsGrpcService extends ReactorPaymentsGrpc.PaymentsImplBase { | ||
|
||
private final CurrencyConversionManager currencyManager; | ||
|
||
|
||
public PaymentsGrpcService(final CurrencyConversionManager currencyManager) { | ||
this.currencyManager = requireNonNull(currencyManager); | ||
} | ||
|
||
@Override | ||
public Mono<GetCurrencyConversionsResponse> getCurrencyConversions(final GetCurrencyConversionsRequest request) { | ||
AuthenticationUtil.requireAuthenticatedDevice(); | ||
|
||
final CurrencyConversionEntityList currencyConversionEntityList = currencyManager | ||
.getCurrencyConversions() | ||
.orElseThrow(Status.UNAVAILABLE::asRuntimeException); | ||
|
||
final List<GetCurrencyConversionsResponse.CurrencyConversionEntity> currencyConversionEntities = currencyConversionEntityList | ||
.getCurrencies() | ||
.stream() | ||
.map(cce -> GetCurrencyConversionsResponse.CurrencyConversionEntity.newBuilder() | ||
.setBase(cce.getBase()) | ||
.putAllConversions(transformBigDecimalsToStrings(cce.getConversions())) | ||
.build()) | ||
.toList(); | ||
|
||
return Mono.just(GetCurrencyConversionsResponse.newBuilder() | ||
.addAllCurrencies(currencyConversionEntities).setTimestamp(currencyConversionEntityList.getTimestamp()) | ||
.build()); | ||
} | ||
|
||
@Nonnull | ||
private static Map<String, String> transformBigDecimalsToStrings(final Map<String, BigDecimal> conversions) { | ||
AuthenticationUtil.requireAuthenticatedDevice(); | ||
return conversions.entrySet().stream() | ||
.map(e -> Pair.of(e.getKey(), e.getValue().toString())) | ||
.collect(Collectors.toMap(Pair::getKey, Pair::getValue)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/* | ||
* Copyright 2023 Signal Messenger, LLC | ||
* SPDX-License-Identifier: AGPL-3.0-only | ||
*/ | ||
|
||
syntax = "proto3"; | ||
|
||
option java_multiple_files = true; | ||
|
||
package org.signal.chat.payments; | ||
|
||
/** | ||
* Provides methods for working with payments. | ||
*/ | ||
service Payments { | ||
/** | ||
*/ | ||
rpc GetCurrencyConversions(GetCurrencyConversionsRequest) returns (GetCurrencyConversionsResponse) {} | ||
} | ||
|
||
message GetCurrencyConversionsRequest { | ||
} | ||
|
||
message GetCurrencyConversionsResponse { | ||
|
||
message CurrencyConversionEntity { | ||
|
||
string base = 1; | ||
|
||
map<string, string> conversions = 2; | ||
} | ||
|
||
uint64 timestamp = 1; | ||
|
||
repeated CurrencyConversionEntity currencies = 2; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
72 changes: 72 additions & 0 deletions
72
service/src/test/java/org/whispersystems/textsecuregcm/grpc/PaymentsGrpcServiceTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
/* | ||
* Copyright 2023 Signal Messenger, LLC | ||
* SPDX-License-Identifier: AGPL-3.0-only | ||
*/ | ||
|
||
package org.whispersystems.textsecuregcm.grpc; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.mockito.Mockito.when; | ||
import static org.whispersystems.textsecuregcm.grpc.GrpcTestUtils.assertStatusException; | ||
|
||
import io.grpc.Status; | ||
import java.math.BigDecimal; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Optional; | ||
import org.junit.jupiter.api.Test; | ||
import org.mockito.Mock; | ||
import org.signal.chat.payments.GetCurrencyConversionsRequest; | ||
import org.signal.chat.payments.GetCurrencyConversionsResponse; | ||
import org.signal.chat.payments.PaymentsGrpc; | ||
import org.whispersystems.textsecuregcm.currency.CurrencyConversionManager; | ||
import org.whispersystems.textsecuregcm.entities.CurrencyConversionEntity; | ||
import org.whispersystems.textsecuregcm.entities.CurrencyConversionEntityList; | ||
|
||
class PaymentsGrpcServiceTest extends SimpleBaseGrpcTest<PaymentsGrpcService, PaymentsGrpc.PaymentsBlockingStub> { | ||
|
||
@Mock | ||
private CurrencyConversionManager currencyManager; | ||
|
||
@Override | ||
protected PaymentsGrpcService createServiceBeforeEachTest() { | ||
return new PaymentsGrpcService(currencyManager); | ||
} | ||
|
||
@Test | ||
void testGetCurrencyConversions() { | ||
final long timestamp = System.currentTimeMillis(); | ||
when(currencyManager.getCurrencyConversions()).thenReturn(Optional.of( | ||
new CurrencyConversionEntityList(List.of( | ||
new CurrencyConversionEntity("FOO", Map.of( | ||
"USD", new BigDecimal("2.35"), | ||
"EUR", new BigDecimal("1.89") | ||
)), | ||
new CurrencyConversionEntity("BAR", Map.of( | ||
"USD", new BigDecimal("1.50"), | ||
"EUR", new BigDecimal("0.98") | ||
)) | ||
), timestamp))); | ||
|
||
final GetCurrencyConversionsResponse currencyConversions = authenticatedServiceStub().getCurrencyConversions( | ||
GetCurrencyConversionsRequest.newBuilder().build()); | ||
|
||
assertEquals(timestamp, currencyConversions.getTimestamp()); | ||
assertEquals(2, currencyConversions.getCurrenciesCount()); | ||
assertEquals("FOO", currencyConversions.getCurrencies(0).getBase()); | ||
assertEquals("2.35", currencyConversions.getCurrencies(0).getConversionsMap().get("USD")); | ||
} | ||
|
||
@Test | ||
void testUnavailable() { | ||
when(currencyManager.getCurrencyConversions()).thenReturn(Optional.empty()); | ||
assertStatusException(Status.UNAVAILABLE, () -> authenticatedServiceStub().getCurrencyConversions( | ||
GetCurrencyConversionsRequest.newBuilder().build())); | ||
} | ||
|
||
@Test | ||
public void testUnauthenticated() throws Exception { | ||
assertStatusException(Status.UNAUTHENTICATED, () -> unauthenticatedServiceStub().getCurrencyConversions( | ||
GetCurrencyConversionsRequest.newBuilder().build())); | ||
} | ||
} |