Remove obsolete donation endpoint

This commit is contained in:
Chris Eager 2022-10-12 12:41:45 -05:00 committed by Chris Eager
parent ce5a4bd94a
commit bd69905f2e
8 changed files with 5 additions and 363 deletions

View File

@ -294,14 +294,6 @@ paymentsService:
# list of symbols for supported currencies # list of symbols for supported currencies
- MOB - MOB
donation:
uri: donation.example.com # value
supportedCurrencies:
- # 1st supported currency
- # 2nd supported currency
- # ...
- # Nth supported currency
badges: badges:
badges: badges:
- id: TEST - id: TEST

View File

@ -24,7 +24,6 @@ import org.whispersystems.textsecuregcm.configuration.CdnConfiguration;
import org.whispersystems.textsecuregcm.configuration.DatadogConfiguration; import org.whispersystems.textsecuregcm.configuration.DatadogConfiguration;
import org.whispersystems.textsecuregcm.configuration.DirectoryConfiguration; import org.whispersystems.textsecuregcm.configuration.DirectoryConfiguration;
import org.whispersystems.textsecuregcm.configuration.DirectoryV2Configuration; import org.whispersystems.textsecuregcm.configuration.DirectoryV2Configuration;
import org.whispersystems.textsecuregcm.configuration.DonationConfiguration;
import org.whispersystems.textsecuregcm.configuration.DynamoDbClientConfiguration; import org.whispersystems.textsecuregcm.configuration.DynamoDbClientConfiguration;
import org.whispersystems.textsecuregcm.configuration.DynamoDbTables; import org.whispersystems.textsecuregcm.configuration.DynamoDbTables;
import org.whispersystems.textsecuregcm.configuration.FcmConfiguration; import org.whispersystems.textsecuregcm.configuration.FcmConfiguration;
@ -219,11 +218,6 @@ public class WhisperServerConfiguration extends Configuration {
@JsonProperty @JsonProperty
private AppConfigConfiguration appConfig; private AppConfigConfiguration appConfig;
@Valid
@NotNull
@JsonProperty
private DonationConfiguration donation;
@Valid @Valid
@NotNull @NotNull
@JsonProperty @JsonProperty
@ -409,10 +403,6 @@ public class WhisperServerConfiguration extends Configuration {
return appConfig; return appConfig;
} }
public DonationConfiguration getDonationConfiguration() {
return donation;
}
public BadgesConfiguration getBadges() { public BadgesConfiguration getBadges() {
return badges; return badges;
} }

View File

@ -659,7 +659,7 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
new DirectoryController(directoryCredentialsGenerator), new DirectoryController(directoryCredentialsGenerator),
new DirectoryV2Controller(directoryV2CredentialsGenerator), new DirectoryV2Controller(directoryV2CredentialsGenerator),
new DonationController(clock, zkReceiptOperations, redeemedReceiptsManager, accountsManager, config.getBadges(), new DonationController(clock, zkReceiptOperations, redeemedReceiptsManager, accountsManager, config.getBadges(),
ReceiptCredentialPresentation::new, stripeExecutor, config.getDonationConfiguration(), config.getStripe()), ReceiptCredentialPresentation::new),
new MessageController(rateLimiters, messageSender, receiptSender, accountsManager, deletedAccountsManager, messagesManager, pushNotificationManager, reportMessageManager, multiRecipientMessageExecutor), new MessageController(rateLimiters, messageSender, receiptSender, accountsManager, deletedAccountsManager, messagesManager, pushNotificationManager, reportMessageManager, multiRecipientMessageExecutor),
new PaymentsController(currencyManager, paymentsCredentialsGenerator), new PaymentsController(currencyManager, paymentsCredentialsGenerator),
new ProfileController(clock, rateLimiters, accountsManager, profilesManager, dynamicConfigurationManager, profileBadgeConverter, config.getBadges(), cdnS3Client, profileCdnPolicyGenerator, profileCdnPolicySigner, config.getCdnConfiguration().getBucket(), zkProfileOperations, batchIdentityCheckExecutor), new ProfileController(clock, rateLimiters, accountsManager, profilesManager, dynamicConfigurationManager, profileBadgeConverter, config.getBadges(), cdnS3Client, profileCdnPolicyGenerator, profileCdnPolicySigner, config.getCdnConfiguration().getBucket(), zkProfileOperations, batchIdentityCheckExecutor),

View File

@ -1,78 +0,0 @@
/*
* Copyright 2021 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.configuration;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.annotations.VisibleForTesting;
import java.util.Set;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
public class DonationConfiguration {
private String uri;
private String description;
private Set<String> supportedCurrencies;
private CircuitBreakerConfiguration circuitBreaker = new CircuitBreakerConfiguration();
private RetryConfiguration retry = new RetryConfiguration();
@JsonProperty
@NotEmpty
public String getUri() {
return uri;
}
@VisibleForTesting
public void setUri(final String uri) {
this.uri = uri;
}
@JsonProperty
public String getDescription() {
return description;
}
@VisibleForTesting
public void setDescription(final String description) {
this.description = description;
}
@JsonProperty
@NotEmpty
public Set<String> getSupportedCurrencies() {
return supportedCurrencies;
}
@VisibleForTesting
public void setSupportedCurrencies(final Set<String> supportedCurrencies) {
this.supportedCurrencies = supportedCurrencies;
}
@JsonProperty
@NotNull
@Valid
public CircuitBreakerConfiguration getCircuitBreaker() {
return circuitBreaker;
}
@VisibleForTesting
public void setCircuitBreaker(final CircuitBreakerConfiguration circuitBreaker) {
this.circuitBreaker = circuitBreaker;
}
@JsonProperty
@NotNull
@Valid
public RetryConfiguration getRetry() {
return retry;
}
@VisibleForTesting
public void setRetry(final RetryConfiguration retry) {
this.retry = retry;
}
}

View File

@ -6,30 +6,13 @@
package org.whispersystems.textsecuregcm.controllers; package org.whispersystems.textsecuregcm.controllers;
import com.codahale.metrics.annotation.Timed; import com.codahale.metrics.annotation.Timed;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.dropwizard.auth.Auth; import io.dropwizard.auth.Auth;
import io.dropwizard.util.Strings;
import java.net.URI;
import java.net.http.HttpClient.Redirect;
import java.net.http.HttpClient.Version;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers;
import java.nio.charset.StandardCharsets;
import java.time.Clock; import java.time.Clock;
import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage; import java.util.concurrent.CompletionStage;
import java.util.concurrent.Executor;
import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinPool.ManagedBlocker; import java.util.concurrent.ForkJoinPool.ManagedBlocker;
import java.util.function.Function; import java.util.function.Function;
@ -52,18 +35,11 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount; import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
import org.whispersystems.textsecuregcm.configuration.BadgesConfiguration; import org.whispersystems.textsecuregcm.configuration.BadgesConfiguration;
import org.whispersystems.textsecuregcm.configuration.DonationConfiguration;
import org.whispersystems.textsecuregcm.configuration.StripeConfiguration;
import org.whispersystems.textsecuregcm.entities.ApplePayAuthorizationRequest;
import org.whispersystems.textsecuregcm.entities.ApplePayAuthorizationResponse;
import org.whispersystems.textsecuregcm.entities.RedeemReceiptRequest; import org.whispersystems.textsecuregcm.entities.RedeemReceiptRequest;
import org.whispersystems.textsecuregcm.http.FaultTolerantHttpClient;
import org.whispersystems.textsecuregcm.http.FormDataBodyPublisher;
import org.whispersystems.textsecuregcm.storage.Account; import org.whispersystems.textsecuregcm.storage.Account;
import org.whispersystems.textsecuregcm.storage.AccountBadge; import org.whispersystems.textsecuregcm.storage.AccountBadge;
import org.whispersystems.textsecuregcm.storage.AccountsManager; import org.whispersystems.textsecuregcm.storage.AccountsManager;
import org.whispersystems.textsecuregcm.storage.RedeemedReceiptsManager; import org.whispersystems.textsecuregcm.storage.RedeemedReceiptsManager;
import org.whispersystems.textsecuregcm.util.SystemMapper;
@Path("/v1/donation") @Path("/v1/donation")
public class DonationController { public class DonationController {
@ -80,11 +56,6 @@ public class DonationController {
private final AccountsManager accountsManager; private final AccountsManager accountsManager;
private final BadgesConfiguration badgesConfiguration; private final BadgesConfiguration badgesConfiguration;
private final ReceiptCredentialPresentationFactory receiptCredentialPresentationFactory; private final ReceiptCredentialPresentationFactory receiptCredentialPresentationFactory;
private final URI uri;
private final String apiKey;
private final String description;
private final Set<String> supportedCurrencies;
private final FaultTolerantHttpClient httpClient;
public DonationController( public DonationController(
@Nonnull final Clock clock, @Nonnull final Clock clock,
@ -92,30 +63,13 @@ public class DonationController {
@Nonnull final RedeemedReceiptsManager redeemedReceiptsManager, @Nonnull final RedeemedReceiptsManager redeemedReceiptsManager,
@Nonnull final AccountsManager accountsManager, @Nonnull final AccountsManager accountsManager,
@Nonnull final BadgesConfiguration badgesConfiguration, @Nonnull final BadgesConfiguration badgesConfiguration,
@Nonnull final ReceiptCredentialPresentationFactory receiptCredentialPresentationFactory, @Nonnull final ReceiptCredentialPresentationFactory receiptCredentialPresentationFactory) {
@Nonnull final Executor httpClientExecutor,
@Nonnull final DonationConfiguration configuration,
@Nonnull final StripeConfiguration stripeConfiguration) {
this.clock = Objects.requireNonNull(clock); this.clock = Objects.requireNonNull(clock);
this.serverZkReceiptOperations = Objects.requireNonNull(serverZkReceiptOperations); this.serverZkReceiptOperations = Objects.requireNonNull(serverZkReceiptOperations);
this.redeemedReceiptsManager = Objects.requireNonNull(redeemedReceiptsManager); this.redeemedReceiptsManager = Objects.requireNonNull(redeemedReceiptsManager);
this.accountsManager = Objects.requireNonNull(accountsManager); this.accountsManager = Objects.requireNonNull(accountsManager);
this.badgesConfiguration = Objects.requireNonNull(badgesConfiguration); this.badgesConfiguration = Objects.requireNonNull(badgesConfiguration);
this.receiptCredentialPresentationFactory = Objects.requireNonNull(receiptCredentialPresentationFactory); this.receiptCredentialPresentationFactory = Objects.requireNonNull(receiptCredentialPresentationFactory);
this.uri = URI.create(configuration.getUri());
this.apiKey = stripeConfiguration.getApiKey();
this.description = configuration.getDescription();
this.supportedCurrencies = configuration.getSupportedCurrencies();
this.httpClient = FaultTolerantHttpClient.newBuilder()
.withCircuitBreaker(configuration.getCircuitBreaker())
.withRetry(configuration.getRetry())
.withVersion(Version.HTTP_2)
.withConnectTimeout(Duration.ofSeconds(10))
.withRedirect(Redirect.NEVER)
.withExecutor(Objects.requireNonNull(httpClientExecutor))
.withName("donation")
.withSecurityProtocol(FaultTolerantHttpClient.SECURITY_PROTOCOL_TLS_1_3)
.build();
} }
@Timed @Timed
@ -188,55 +142,4 @@ public class DonationController {
}).thenCompose(Function.identity()); }).thenCompose(Function.identity());
} }
@Timed
@POST
@Path("/authorize-apple-pay")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public CompletableFuture<Response> getApplePayAuthorization(@Auth AuthenticatedAccount auth, @NotNull @Valid ApplePayAuthorizationRequest request) {
if (!supportedCurrencies.contains(request.getCurrency())) {
return CompletableFuture.completedFuture(Response.status(422).build());
}
final Map<String, String> formData = new HashMap<>();
formData.put("amount", Long.toString(request.getAmount()));
formData.put("currency", request.getCurrency());
if (!Strings.isNullOrEmpty(description)) {
formData.put("description", description);
}
final HttpRequest httpRequest = HttpRequest.newBuilder()
.uri(uri)
.POST(FormDataBodyPublisher.of(formData))
.header("Authorization", "Basic " + Base64.getEncoder().encodeToString(
(apiKey + ":").getBytes(StandardCharsets.UTF_8)))
.header("Content-Type", "application/x-www-form-urlencoded")
.build();
return httpClient.sendAsync(httpRequest, BodyHandlers.ofString())
.thenApply(this::processApplePayAuthorizationRemoteResponse);
}
private Response processApplePayAuthorizationRemoteResponse(HttpResponse<String> response) {
ObjectMapper mapper = SystemMapper.getMapper();
if (response.statusCode() >= 200 && response.statusCode() < 300 &&
MediaType.APPLICATION_JSON.equalsIgnoreCase(response.headers().firstValue("Content-Type").orElse(null))) {
try {
final JsonNode jsonResponse = mapper.readTree(response.body());
final String id = jsonResponse.get("id").asText(null);
final String clientSecret = jsonResponse.get("client_secret").asText(null);
if (Strings.isNullOrEmpty(id) || Strings.isNullOrEmpty(clientSecret)) {
logger.warn("missing fields in json response in donation controller");
return Response.status(500).build();
}
final String responseJson = mapper.writeValueAsString(new ApplePayAuthorizationResponse(id, clientSecret));
return Response.ok(responseJson, MediaType.APPLICATION_JSON_TYPE).build();
} catch (JsonProcessingException e) {
logger.warn("json processing error in donation controller", e);
return Response.status(500).build();
}
} else {
logger.warn("unexpected response code returned to donation controller");
return Response.status(500).build();
}
}
} }

View File

@ -1,42 +0,0 @@
/*
* Copyright 2021 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.entities;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.annotations.VisibleForTesting;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
public class ApplePayAuthorizationRequest {
private String currency;
private long amount;
@JsonProperty
@NotEmpty
@Size(min=3, max=3)
@Pattern(regexp="[a-z]{3}")
public String getCurrency() {
return currency;
}
public void setCurrency(final String currency) {
this.currency = currency;
}
@JsonProperty
@Min(0)
public long getAmount() {
return amount;
}
@VisibleForTesting
public void setAmount(final long amount) {
this.amount = amount;
}
}

View File

@ -1,44 +0,0 @@
/*
* Copyright 2021 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.entities;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.dropwizard.util.Strings;
import javax.validation.constraints.NotEmpty;
public class ApplePayAuthorizationResponse {
private final String id;
private final String clientSecret;
@JsonCreator
public ApplePayAuthorizationResponse(
@JsonProperty("id") final String id,
@JsonProperty("client_secret") final String clientSecret) {
if (Strings.isNullOrEmpty(id)) {
throw new IllegalArgumentException("id cannot be empty");
}
if (Strings.isNullOrEmpty(clientSecret)) {
throw new IllegalArgumentException("clientSecret cannot be empty");
}
this.id = id;
this.clientSecret = clientSecret;
}
@JsonProperty("id")
@NotEmpty
public String getId() {
return id;
}
@JsonProperty("client_secret")
@NotEmpty
public String getClientSecret() {
return clientSecret;
}
}

View File

@ -5,9 +5,6 @@
package org.whispersystems.textsecuregcm.tests.controllers; package org.whispersystems.textsecuregcm.tests.controllers;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.post;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
@ -27,10 +24,7 @@ import java.time.Instant;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import javax.ws.rs.client.Entity; import javax.ws.rs.client.Entity;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
@ -47,13 +41,7 @@ import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAuthenticatedAccount; import org.whispersystems.textsecuregcm.auth.DisabledPermittedAuthenticatedAccount;
import org.whispersystems.textsecuregcm.configuration.BadgeConfiguration; import org.whispersystems.textsecuregcm.configuration.BadgeConfiguration;
import org.whispersystems.textsecuregcm.configuration.BadgesConfiguration; import org.whispersystems.textsecuregcm.configuration.BadgesConfiguration;
import org.whispersystems.textsecuregcm.configuration.CircuitBreakerConfiguration;
import org.whispersystems.textsecuregcm.configuration.DonationConfiguration;
import org.whispersystems.textsecuregcm.configuration.RetryConfiguration;
import org.whispersystems.textsecuregcm.configuration.StripeConfiguration;
import org.whispersystems.textsecuregcm.controllers.DonationController; import org.whispersystems.textsecuregcm.controllers.DonationController;
import org.whispersystems.textsecuregcm.entities.ApplePayAuthorizationRequest;
import org.whispersystems.textsecuregcm.entities.ApplePayAuthorizationResponse;
import org.whispersystems.textsecuregcm.entities.BadgeSvg; import org.whispersystems.textsecuregcm.entities.BadgeSvg;
import org.whispersystems.textsecuregcm.entities.RedeemReceiptRequest; import org.whispersystems.textsecuregcm.entities.RedeemReceiptRequest;
import org.whispersystems.textsecuregcm.storage.AccountBadge; import org.whispersystems.textsecuregcm.storage.AccountBadge;
@ -65,7 +53,6 @@ import org.whispersystems.textsecuregcm.util.TestClock;
class DonationControllerTest { class DonationControllerTest {
private static final Executor httpClientExecutor = Executors.newSingleThreadExecutor();
private static final long nowEpochSeconds = 1_500_000_000L; private static final long nowEpochSeconds = 1_500_000_000L;
@RegisterExtension @RegisterExtension
@ -75,20 +62,6 @@ class DonationControllerTest {
private static final SecureRandom SECURE_RANDOM = new SecureRandom(); private static final SecureRandom SECURE_RANDOM = new SecureRandom();
static DonationConfiguration getDonationConfiguration() {
DonationConfiguration configuration = new DonationConfiguration();
configuration.setDescription("some description");
configuration.setUri("http://localhost:" + wm.getRuntimeInfo().getHttpPort() + "/foo/bar");
configuration.setCircuitBreaker(new CircuitBreakerConfiguration());
configuration.setRetry(new RetryConfiguration());
configuration.setSupportedCurrencies(Set.of("usd", "gbp"));
return configuration;
}
static StripeConfiguration getStripeConfiguration() {
return new StripeConfiguration("test-api-key", new byte[16], "Boost Description String");
}
static BadgesConfiguration getBadgesConfiguration() { static BadgesConfiguration getBadgesConfiguration() {
return new BadgesConfiguration( return new BadgesConfiguration(
List.of( List.of(
@ -137,8 +110,7 @@ class DonationControllerTest {
ImmutableSet.of(AuthenticatedAccount.class, DisabledPermittedAuthenticatedAccount.class))) ImmutableSet.of(AuthenticatedAccount.class, DisabledPermittedAuthenticatedAccount.class)))
.setTestContainerFactory(new GrizzlyWebTestContainerFactory()) .setTestContainerFactory(new GrizzlyWebTestContainerFactory())
.addResource(new DonationController(clock, zkReceiptOperations, redeemedReceiptsManager, accountsManager, .addResource(new DonationController(clock, zkReceiptOperations, redeemedReceiptsManager, accountsManager,
getBadgesConfiguration(), receiptCredentialPresentationFactory, httpClientExecutor, getBadgesConfiguration(), receiptCredentialPresentationFactory))
getDonationConfiguration(), getStripeConfiguration()))
.build(); .build();
resources.before(); resources.before();
} }
@ -148,57 +120,6 @@ class DonationControllerTest {
resources.after(); resources.after();
} }
@Test
void testGetApplePayAuthorizationReturns200() {
wm.stubFor(post(urlEqualTo("/foo/bar"))
.withBasicAuth("test-api-key", "")
.willReturn(aResponse()
.withHeader("Content-Type", MediaType.APPLICATION_JSON)
.withBody("{\"id\":\"an_id\",\"client_secret\":\"some_secret\"}")));
ApplePayAuthorizationRequest request = new ApplePayAuthorizationRequest();
request.setCurrency("usd");
request.setAmount(1000);
Response response = resources.getJerseyTest()
.target("/v1/donation/authorize-apple-pay")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.post(Entity.entity(request, MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus()).isEqualTo(200);
ApplePayAuthorizationResponse responseObject = response.readEntity(ApplePayAuthorizationResponse.class);
assertThat(responseObject.getId()).isEqualTo("an_id");
assertThat(responseObject.getClientSecret()).isEqualTo("some_secret");
}
@Test
void testGetApplePayAuthorizationWithoutAuthHeaderReturns401() {
ApplePayAuthorizationRequest request = new ApplePayAuthorizationRequest();
request.setCurrency("usd");
request.setAmount(1000);
Response response = resources.getJerseyTest()
.target("/v1/donation/authorize-apple-pay")
.request()
.post(Entity.entity(request, MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus()).isEqualTo(401);
}
@Test
void testGetApplePayAuthorizationWithUnsupportedCurrencyReturns422() {
ApplePayAuthorizationRequest request = new ApplePayAuthorizationRequest();
request.setCurrency("zzz");
request.setAmount(1000);
Response response = resources.getJerseyTest()
.target("/v1/donation/authorize-apple-pay")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.post(Entity.entity(request, MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus()).isEqualTo(422);
}
@Test @Test
void testRedeemReceipt() { void testRedeemReceipt() {
when(receiptCredentialPresentation.getReceiptSerial()).thenReturn(receiptSerial); when(receiptCredentialPresentation.getReceiptSerial()).thenReturn(receiptSerial);
@ -246,13 +167,13 @@ class DonationControllerTest {
@Test @Test
void testRedeemReceiptBadCredentialPresentation() throws InvalidInputException { void testRedeemReceiptBadCredentialPresentation() throws InvalidInputException {
when(receiptCredentialPresentationFactory.build(any())).thenThrow(new InvalidInputException()); when(receiptCredentialPresentationFactory.build(any())).thenThrow(new InvalidInputException());
final Response response = resources.getJerseyTest() final Response response = resources.getJerseyTest()
.target("/v1/donation/redeem-receipt") .target("/v1/donation/redeem-receipt")
.request() .request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD)) .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.post(Entity.entity(new RedeemReceiptRequest(presentation, true, true), MediaType.APPLICATION_JSON_TYPE)); .post(Entity.entity(new RedeemReceiptRequest(presentation, true, true), MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus()).isEqualTo(400); assertThat(response.getStatus()).isEqualTo(400);
} }
} }