Skip to content

Commit a6375d7

Browse files
author
Tess Stoddard
committed
feat: add p2p transfers endpoints
1 parent 7cdb496 commit a6375d7

File tree

5 files changed

+258
-0
lines changed

5 files changed

+258
-0
lines changed

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

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,13 @@
44
import lombok.Getter;
55

66
import com.mx.path.core.common.accessor.API;
7+
import com.mx.path.core.common.accessor.AccessorMethodNotImplementedException;
78
import com.mx.path.core.common.gateway.GatewayAPI;
89
import com.mx.path.core.common.gateway.GatewayClass;
910
import com.mx.path.gateway.accessor.Accessor;
11+
import com.mx.path.gateway.accessor.AccessorResponse;
12+
import com.mx.path.model.mdx.model.MdxList;
13+
import com.mx.path.model.mdx.model.p2p_transfer.P2PTransfer;
1014

1115
/**
1216
* Accessor base for p2p transfer operations
@@ -31,6 +35,69 @@ public class P2PTransferBaseAccessor extends Accessor {
3135
@Getter(AccessLevel.PROTECTED)
3236
private RecipientBaseAccessor recipients;
3337

38+
public P2PTransferBaseAccessor() {
39+
}
40+
41+
/**
42+
* Create a P2P transfer
43+
*
44+
* @param p2pTransfer
45+
* @return
46+
*/
47+
@GatewayAPI
48+
@API(description = "Create a P2P transfer")
49+
public AccessorResponse<P2PTransfer> create(P2PTransfer p2pTransfer) {
50+
throw new AccessorMethodNotImplementedException();
51+
}
52+
53+
/**
54+
* Delete a P2P transfer
55+
*
56+
* @param id
57+
* @return
58+
*/
59+
@GatewayAPI
60+
@API(description = "Delete a P2P transfer")
61+
public AccessorResponse<Void> delete(String id) {
62+
throw new AccessorMethodNotImplementedException();
63+
}
64+
65+
/**
66+
* Get a P2P Transfer
67+
*
68+
* @param id
69+
* @return
70+
*/
71+
@GatewayAPI
72+
@API(description = "Get a P2P transfer")
73+
public AccessorResponse<P2PTransfer> get(String id) {
74+
throw new AccessorMethodNotImplementedException();
75+
}
76+
77+
/**
78+
* List all P2P transfers
79+
*
80+
* @return
81+
*/
82+
@GatewayAPI
83+
@API(description = "List all P2P transfers")
84+
public AccessorResponse<MdxList<P2PTransfer>> list() {
85+
throw new AccessorMethodNotImplementedException();
86+
}
87+
88+
/**
89+
* Update a P2P transfer
90+
*
91+
* @param id
92+
* @param p2pTransfer
93+
* @return
94+
*/
95+
@GatewayAPI
96+
@API(description = "Update a P2P transfer")
97+
public AccessorResponse<P2PTransfer> update(String id, P2PTransfer p2pTransfer) {
98+
throw new AccessorMethodNotImplementedException();
99+
}
100+
34101
/**
35102
* Accessor for account operations
36103
*

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
import com.mx.path.model.mdx.model.ondemand.mixins.TransactionsPageMixin;
6363
import com.mx.path.model.mdx.model.origination.Origination;
6464
import com.mx.path.model.mdx.model.p2p_transfer.Duration;
65+
import com.mx.path.model.mdx.model.p2p_transfer.P2PTransfer;
6566
import com.mx.path.model.mdx.model.payment.Bill;
6667
import com.mx.path.model.mdx.model.payment.Enrollment;
6768
import com.mx.path.model.mdx.model.payment.Merchant;
@@ -392,6 +393,10 @@ private static void registerP2PTransferModels(GsonBuilder builder) {
392393
builder.registerTypeAdapter(com.mx.path.model.mdx.model.p2p_transfer.Recipient.class, new ModelWrappableSerializer("recipient"));
393394
builder.registerTypeAdapter(new TypeToken<MdxList<com.mx.path.model.mdx.model.p2p_transfer.Recipient>>() {
394395
}.getType(), new ModelWrappableSerializer("recipients"));
396+
// P2P Transfers
397+
builder.registerTypeAdapter(P2PTransfer.class, new ModelWrappableSerializer("p2p_transfer"));
398+
builder.registerTypeAdapter(new TypeToken<MdxList<P2PTransfer>>() {
399+
}.getType(), new ModelWrappableSerializer("p2p_transfers"));
395400
}
396401

397402
private static void registerPaymentsModels(GsonBuilder builder) {
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.mx.path.model.mdx.model.p2p_transfer;
2+
3+
import java.math.BigDecimal;
4+
import java.time.LocalDate;
5+
6+
import lombok.Data;
7+
import lombok.EqualsAndHashCode;
8+
9+
import com.mx.path.model.mdx.model.MdxBase;
10+
import com.mx.path.model.mdx.model.MdxList;
11+
import com.mx.path.model.mdx.model.challenges.Challenge;
12+
13+
@Data
14+
@EqualsAndHashCode(callSuper = true)
15+
public class P2PTransfer extends MdxBase<P2PTransfer> {
16+
private String id;
17+
private String accountId;
18+
private BigDecimal amount;
19+
private MdxList<Challenge> challenges;
20+
private String confirmationId;
21+
private String deliveryMethod;
22+
private String memo;
23+
private String recipientId;
24+
private String recipientVerificationAnswer;
25+
private String recipientVerificationQuestion;
26+
private LocalDate sendOn;
27+
private LocalDate sentOn;
28+
private String status;
29+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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.P2PTransfer;
6+
7+
import org.springframework.http.HttpStatus;
8+
import org.springframework.http.ResponseEntity;
9+
import org.springframework.web.bind.annotation.PathVariable;
10+
import org.springframework.web.bind.annotation.RequestBody;
11+
import org.springframework.web.bind.annotation.RequestMapping;
12+
import org.springframework.web.bind.annotation.RequestMethod;
13+
import org.springframework.web.bind.annotation.RestController;
14+
15+
@RestController
16+
@RequestMapping(value = "{clientId}", produces = BaseController.MDX_MEDIA)
17+
public class P2PTransfersController extends BaseController {
18+
@RequestMapping(value = "/users/{userId}/p2p_transfers", method = RequestMethod.POST, consumes = BaseController.MDX_MEDIA)
19+
public final ResponseEntity<P2PTransfer> create(@RequestBody P2PTransfer p2pTransferRequest) {
20+
AccessorResponse<P2PTransfer> response = gateway().p2pTransfers().create(p2pTransferRequest);
21+
return new ResponseEntity<>(response.getResult().wrapped(), createMultiMapForResponse(response.getHeaders()), HttpStatus.OK);
22+
}
23+
24+
@RequestMapping(value = "/users/{userId}/p2p_transfers/{id}", method = RequestMethod.DELETE)
25+
public final ResponseEntity<?> delete(@PathVariable("id") String p2pTransferId) {
26+
AccessorResponse<Void> response = gateway().p2pTransfers().delete(p2pTransferId);
27+
return new ResponseEntity<>(createMultiMapForResponse(response.getHeaders()), HttpStatus.NO_CONTENT);
28+
}
29+
30+
@RequestMapping(value = "/users/{userId}/p2p_transfers/{id}", method = RequestMethod.GET)
31+
public final ResponseEntity<P2PTransfer> get(@PathVariable("id") String p2pTransferId) {
32+
AccessorResponse<P2PTransfer> response = gateway().p2pTransfers().get(p2pTransferId);
33+
return new ResponseEntity<>(response.getResult().wrapped(), createMultiMapForResponse(response.getHeaders()), HttpStatus.OK);
34+
}
35+
36+
@RequestMapping(value = "/users/{userId}/p2p_transfers", method = RequestMethod.GET)
37+
public final ResponseEntity<MdxList<P2PTransfer>> list() {
38+
AccessorResponse<MdxList<P2PTransfer>> response = gateway().p2pTransfers().list();
39+
return new ResponseEntity<>(response.getResult().wrapped(), createMultiMapForResponse(response.getHeaders()), HttpStatus.OK);
40+
}
41+
42+
@RequestMapping(value = "/users/{userId}/p2p_transfers/{id}", method = RequestMethod.PUT, consumes = BaseController.MDX_MEDIA)
43+
public final ResponseEntity<P2PTransfer> update(@PathVariable("id") String p2pTransferId, @RequestBody P2PTransfer p2pTransferRequest) {
44+
AccessorResponse<P2PTransfer> response = gateway().p2pTransfers().update(p2pTransferId, p2pTransferRequest);
45+
return new ResponseEntity<>(response.getResult().wrapped(), createMultiMapForResponse(response.getHeaders()), HttpStatus.OK);
46+
}
47+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
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.P2PTransferGateway
11+
import com.mx.path.model.mdx.model.MdxList
12+
import com.mx.path.model.mdx.model.p2p_transfer.P2PTransfer
13+
14+
import org.springframework.http.HttpStatus
15+
16+
import spock.lang.Specification
17+
18+
class P2PTransfersControllerTest extends Specification {
19+
P2PTransfersController subject
20+
Gateway gateway
21+
P2PTransferGateway p2pTransferGateway
22+
23+
def setup() {
24+
subject = new P2PTransfersController()
25+
p2pTransferGateway = mock(P2PTransferGateway)
26+
gateway = spy(Gateway.builder().clientId("client-1234").p2pTransfers(p2pTransferGateway).build())
27+
}
28+
29+
def cleanup() {
30+
BaseController.clearGateway()
31+
}
32+
33+
def "create interacts with gateway"() {
34+
given:
35+
BaseController.setGateway(gateway)
36+
def p2pTransfer = new P2PTransfer()
37+
doReturn(new AccessorResponse<P2PTransfer>().withResult(p2pTransfer)).when(p2pTransferGateway).create(p2pTransfer)
38+
39+
when:
40+
def result = subject.create(p2pTransfer)
41+
42+
then:
43+
HttpStatus.OK == result.statusCode
44+
result.body == p2pTransfer
45+
verify(p2pTransferGateway).create(p2pTransfer) || true
46+
}
47+
48+
def "delete interacts with gateway"() {
49+
given:
50+
BaseController.setGateway(gateway)
51+
def id = "transfer-1234"
52+
doReturn(new AccessorResponse<Void>()).when(p2pTransferGateway).delete(id)
53+
54+
when:
55+
def result = subject.delete(id)
56+
57+
then:
58+
HttpStatus.NO_CONTENT == result.statusCode
59+
verify(p2pTransferGateway).delete(id) || true
60+
}
61+
62+
def "get interacts with gateway"() {
63+
given:
64+
BaseController.setGateway(gateway)
65+
def id = "transfer-1234"
66+
def p2pTransfer = new P2PTransfer()
67+
doReturn(new AccessorResponse<P2PTransfer>().withResult(p2pTransfer)).when(p2pTransferGateway).get(id)
68+
69+
when:
70+
def result = subject.get(id)
71+
72+
then:
73+
HttpStatus.OK == result.statusCode
74+
result.body == p2pTransfer
75+
verify(p2pTransferGateway).get(id) || true
76+
}
77+
78+
def "list interacts with gateway"() {
79+
given:
80+
BaseController.setGateway(gateway)
81+
def p2pTransfers = new MdxList().tap {
82+
add(new P2PTransfer())
83+
}
84+
doReturn(new AccessorResponse<MdxList<P2PTransfer>>().withResult(p2pTransfers)).when(p2pTransferGateway).list()
85+
86+
when:
87+
def result = subject.list()
88+
89+
then:
90+
HttpStatus.OK == result.statusCode
91+
result.body == p2pTransfers
92+
verify(p2pTransferGateway).list() || true
93+
}
94+
95+
def "update interacts with gateway"() {
96+
given:
97+
BaseController.setGateway(gateway)
98+
def id = "transfer-1234"
99+
def p2pTransfer = new P2PTransfer()
100+
doReturn(new AccessorResponse<P2PTransfer>().withResult(p2pTransfer)).when(p2pTransferGateway).update(id, p2pTransfer)
101+
102+
when:
103+
def result = subject.update(id, p2pTransfer)
104+
105+
then:
106+
HttpStatus.OK == result.statusCode
107+
result.body == p2pTransfer
108+
verify(p2pTransferGateway).update(id, p2pTransfer) || true
109+
}
110+
}

0 commit comments

Comments
 (0)