Skip to content

Commit b2e3e12

Browse files
author
Tess Stoddard
committed
feat: add p2p transfer duration endpoints
1 parent 90a3cb9 commit b2e3e12

7 files changed

Lines changed: 197 additions & 0 deletions

File tree

mdx-models/src/main/java/com/mx/path/model/mdx/accessor/BaseAccessor.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import com.mx.path.model.mdx.accessor.location.LocationBaseAccessor;
2121
import com.mx.path.model.mdx.accessor.managed_card.ManagedCardBaseAccessor;
2222
import com.mx.path.model.mdx.accessor.origination.OriginationBaseAccessor;
23+
import com.mx.path.model.mdx.accessor.p2p_transfer.P2PTransferBaseAccessor;
2324
import com.mx.path.model.mdx.accessor.payment.PaymentBaseAccessor;
2425
import com.mx.path.model.mdx.accessor.payout.PayoutBaseAccessor;
2526
import com.mx.path.model.mdx.accessor.products.ProductBaseAccessor;
@@ -74,6 +75,10 @@ public abstract class BaseAccessor extends Accessor {
7475
@Getter(AccessLevel.PROTECTED)
7576
private OriginationBaseAccessor originations;
7677

78+
@GatewayAPI
79+
@Getter(AccessLevel.PROTECTED)
80+
private P2PTransferBaseAccessor p2pTransfers;
81+
7782
@GatewayAPI
7883
@Getter(AccessLevel.PROTECTED)
7984
private PaymentBaseAccessor payments;
@@ -349,6 +354,29 @@ public void setOriginations(OriginationBaseAccessor originations) {
349354
this.originations = originations;
350355
}
351356

357+
/**
358+
* Accessor for p2p transfer operations
359+
*
360+
* @return accessor
361+
*/
362+
@API
363+
public P2PTransferBaseAccessor p2pTransfers() {
364+
if (p2pTransfers != null) {
365+
return p2pTransfers;
366+
}
367+
368+
throw new AccessorMethodNotImplementedException();
369+
}
370+
371+
/**
372+
* Set p2p transfer accessor
373+
*
374+
* @param p2pTransfers
375+
*/
376+
public void setP2pTransfers(P2PTransferBaseAccessor p2pTransfers) {
377+
this.p2pTransfers = p2pTransfers;
378+
}
379+
352380
/**
353381
* Accessor for payment operations
354382
*
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.mx.path.model.mdx.accessor.p2p_transfer;
2+
3+
import com.mx.path.core.common.accessor.API;
4+
import com.mx.path.core.common.accessor.AccessorMethodNotImplementedException;
5+
import com.mx.path.core.common.gateway.GatewayAPI;
6+
import com.mx.path.core.common.gateway.GatewayClass;
7+
import com.mx.path.gateway.accessor.Accessor;
8+
import com.mx.path.gateway.accessor.AccessorResponse;
9+
import com.mx.path.model.mdx.model.MdxList;
10+
import com.mx.path.model.mdx.model.p2p_transfer.Duration;
11+
12+
/**
13+
* Accessor base for P2P transfer duration operations
14+
*/
15+
@GatewayClass
16+
@API(specificationUrl = "https://developer.mx.com/drafts/mdx/p2p_transfer/index.html#durations")
17+
public class DurationBaseAccessor extends Accessor {
18+
public DurationBaseAccessor() {
19+
}
20+
21+
/**
22+
* List all P2P transfer durations
23+
*
24+
* @return MdxList<Duration>
25+
*/
26+
@GatewayAPI
27+
@API(description = "List all durations for P2P transfers")
28+
public AccessorResponse<MdxList<Duration>> list() {
29+
throw new AccessorMethodNotImplementedException();
30+
}
31+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.mx.path.model.mdx.accessor.p2p_transfer;
2+
3+
import lombok.AccessLevel;
4+
import lombok.Getter;
5+
6+
import com.mx.path.core.common.accessor.API;
7+
import com.mx.path.core.common.gateway.GatewayAPI;
8+
import com.mx.path.core.common.gateway.GatewayClass;
9+
import com.mx.path.gateway.accessor.Accessor;
10+
11+
/**
12+
* Accessor base for p2p transfer operations
13+
*
14+
*/
15+
@GatewayClass
16+
@API(specificationUrl = "https://developer.mx.com/drafts/mdx/p2p_transfer/index.html#p2p-transfers")
17+
public class P2PTransferBaseAccessor extends Accessor {
18+
@GatewayAPI
19+
@Getter(AccessLevel.PROTECTED)
20+
private DurationBaseAccessor durations;
21+
22+
/**
23+
* Accessor for duration operations
24+
*
25+
* @return accessor
26+
*/
27+
@API
28+
public DurationBaseAccessor durations() {
29+
return durations;
30+
}
31+
32+
/**
33+
* Sets duration accessor
34+
* @param durations
35+
*/
36+
public void setDurations(DurationBaseAccessor durations) {
37+
this.durations = durations;
38+
}
39+
}

mdx-models/src/main/java/com/mx/path/model/mdx/model/Resources.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
import com.mx.path.model.mdx.model.ondemand.mixins.TransactionMixIn;
6262
import com.mx.path.model.mdx.model.ondemand.mixins.TransactionsPageMixin;
6363
import com.mx.path.model.mdx.model.origination.Origination;
64+
import com.mx.path.model.mdx.model.p2p_transfer.Duration;
6465
import com.mx.path.model.mdx.model.payment.Bill;
6566
import com.mx.path.model.mdx.model.payment.Enrollment;
6667
import com.mx.path.model.mdx.model.payment.Merchant;
@@ -284,6 +285,8 @@ public static void registerResources(GsonBuilder builder) {
284285
registerAccountAlertModels(builder);
285286
// Register product models
286287
registerProductModels(builder);
288+
// Register P2P transfer models
289+
registerP2PTransferModels(builder);
287290
}
288291

289292
private static void registerDeviceModels(GsonBuilder builder) {
@@ -380,6 +383,13 @@ private static void registerDisputesModels(GsonBuilder builder) {
380383
}.getType(), new ModelWrappableSerializer("disputed_transactions"));
381384
}
382385

386+
private static void registerP2PTransferModels(GsonBuilder builder) {
387+
// Duration
388+
builder.registerTypeAdapter(Frequency.class, new ModelWrappableSerializer("duration"));
389+
builder.registerTypeAdapter(new TypeToken<MdxList<Duration>>() {
390+
}.getType(), new ModelWrappableSerializer("durations"));
391+
}
392+
383393
private static void registerPaymentsModels(GsonBuilder builder) {
384394
// Merchant
385395
builder.registerTypeAdapter(Merchant.class, new ModelWrappableSerializer("merchant"));
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.mx.path.model.mdx.model.p2p_transfer;
2+
3+
import lombok.Data;
4+
import lombok.EqualsAndHashCode;
5+
6+
import com.mx.path.model.mdx.model.MdxBase;
7+
8+
@Data
9+
@EqualsAndHashCode(callSuper = true)
10+
public class Duration extends MdxBase<Duration> {
11+
private String description;
12+
private String name;
13+
private String type;
14+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.mx.path.model.mdx.web.controller;
2+
3+
import com.mx.path.gateway.accessor.AccessorResponse;
4+
import com.mx.path.model.mdx.model.MdxList;
5+
import com.mx.path.model.mdx.model.p2p_transfer.Duration;
6+
7+
import org.springframework.http.HttpStatus;
8+
import org.springframework.http.ResponseEntity;
9+
import org.springframework.web.bind.annotation.RequestMapping;
10+
import org.springframework.web.bind.annotation.RequestMethod;
11+
import org.springframework.web.bind.annotation.RestController;
12+
13+
@RestController
14+
@RequestMapping(value = "{clientId}", produces = BaseController.MDX_MEDIA)
15+
public class P2PTransferDurationsController extends BaseController {
16+
@RequestMapping(value = "/users/{userId}/p2p_transfers/durations", method = RequestMethod.GET)
17+
public final ResponseEntity<MdxList<Duration>> list() {
18+
AccessorResponse<MdxList<Duration>> response = gateway().p2pTransfers().durations().list();
19+
return new ResponseEntity<>(response.getResult().wrapped(), createMultiMapForResponse(response.getHeaders()), HttpStatus.OK);
20+
}
21+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package com.mx.path.model.mdx.web.controller
2+
3+
import static org.mockito.Mockito.doReturn
4+
import static org.mockito.Mockito.mock
5+
import static org.mockito.Mockito.spy
6+
import static org.mockito.Mockito.verify
7+
8+
import com.mx.path.gateway.accessor.AccessorResponse
9+
import com.mx.path.gateway.api.Gateway
10+
import com.mx.path.gateway.api.p2p_transfer.DurationGateway
11+
import com.mx.path.gateway.api.p2p_transfer.P2PTransferGateway
12+
import com.mx.path.model.mdx.model.MdxList
13+
import com.mx.path.model.mdx.model.p2p_transfer.Duration
14+
15+
import org.springframework.http.HttpStatus
16+
17+
import spock.lang.Specification
18+
19+
class P2PTransferDurationsControllerTest extends Specification {
20+
P2PTransferDurationsController subject
21+
Gateway gateway
22+
P2PTransferGateway p2pTransferGateway
23+
DurationGateway durationGateway
24+
25+
def setup() {
26+
subject = new P2PTransferDurationsController()
27+
p2pTransferGateway = mock(P2PTransferGateway)
28+
durationGateway = mock(DurationGateway)
29+
30+
doReturn(durationGateway).when(p2pTransferGateway).durations()
31+
gateway = spy(Gateway.builder().clientId("client-1234").p2pTransfers(p2pTransferGateway).build())
32+
}
33+
34+
def cleanup() {
35+
BaseController.clearGateway()
36+
}
37+
38+
def "list interacts with gateway"() {
39+
given:
40+
BaseController.setGateway(gateway)
41+
def durations = new MdxList().tap {
42+
add(new Duration())
43+
}
44+
doReturn(new AccessorResponse<MdxList<Duration>>().withResult(durations)).when(durationGateway).list()
45+
46+
when:
47+
def result = subject.list()
48+
49+
then:
50+
HttpStatus.OK == result.statusCode
51+
result.body == durations
52+
verify(durationGateway).list() || true
53+
}
54+
}

0 commit comments

Comments
 (0)