Skip to content

Commit 7cdb496

Browse files
Tess Stoddardtessstoddard
authored andcommitted
feat: add p2p transfer recipient endpoints
1 parent 1b26f9e commit 7cdb496

6 files changed

Lines changed: 284 additions & 0 deletions

File tree

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ public class P2PTransferBaseAccessor extends Accessor {
2727
@Getter(AccessLevel.PROTECTED)
2828
private FrequencyBaseAccessor frequencies;
2929

30+
@GatewayAPI
31+
@Getter(AccessLevel.PROTECTED)
32+
private RecipientBaseAccessor recipients;
33+
3034
/**
3135
* Accessor for account operations
3236
*
@@ -80,4 +84,22 @@ public FrequencyBaseAccessor frequencies() {
8084
public void setFrequencies(FrequencyBaseAccessor frequencies) {
8185
this.frequencies = frequencies;
8286
}
87+
88+
/**
89+
* Accessor for recipient operations
90+
*
91+
* @return accessor
92+
*/
93+
@API
94+
public RecipientBaseAccessor recipients() {
95+
return recipients;
96+
}
97+
98+
/**
99+
* Sets recipient accessor
100+
* @param recipients
101+
*/
102+
public void setRecipients(RecipientBaseAccessor recipients) {
103+
this.recipients = recipients;
104+
}
83105
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
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.Recipient;
11+
12+
/**
13+
* Accessor base for p2p transfer recipient operations
14+
*/
15+
@GatewayClass
16+
@API(specificationUrl = "https://developer.mx.com/drafts/mdx/p2p_transfer/index.html#recipients")
17+
public class RecipientBaseAccessor extends Accessor {
18+
public RecipientBaseAccessor() {
19+
}
20+
21+
/**
22+
* Create a recipient
23+
*
24+
* @param recipient
25+
* @return
26+
*/
27+
@GatewayAPI
28+
@API(description = "Create a recipient")
29+
public AccessorResponse<Recipient> create(Recipient recipient) {
30+
throw new AccessorMethodNotImplementedException();
31+
}
32+
33+
/**
34+
* Delete a recipient
35+
*
36+
* @param id
37+
* @return
38+
*/
39+
@GatewayAPI
40+
@API(description = "Delete a recipient")
41+
public AccessorResponse<Void> delete(String id) {
42+
throw new AccessorMethodNotImplementedException();
43+
}
44+
45+
/**
46+
* Get a recipient
47+
*
48+
* @param id
49+
* @return
50+
*/
51+
@GatewayAPI
52+
@API(description = "Get a recipient")
53+
public AccessorResponse<Recipient> get(String id) {
54+
throw new AccessorMethodNotImplementedException();
55+
}
56+
57+
/**
58+
* List all recipients
59+
*
60+
* @return
61+
*/
62+
@GatewayAPI
63+
@API(description = "List all recipients")
64+
public AccessorResponse<MdxList<Recipient>> list() {
65+
throw new AccessorMethodNotImplementedException();
66+
}
67+
68+
/**
69+
* Update a recipient
70+
*
71+
* @param id
72+
* @param recipient
73+
* @return
74+
*/
75+
@GatewayAPI
76+
@API(description = "Update a recipient")
77+
public AccessorResponse<Recipient> update(String id, Recipient recipient) {
78+
throw new AccessorMethodNotImplementedException();
79+
}
80+
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,10 @@ private static void registerP2PTransferModels(GsonBuilder builder) {
388388
builder.registerTypeAdapter(Frequency.class, new ModelWrappableSerializer("duration"));
389389
builder.registerTypeAdapter(new TypeToken<MdxList<Duration>>() {
390390
}.getType(), new ModelWrappableSerializer("durations"));
391+
// Recipients
392+
builder.registerTypeAdapter(com.mx.path.model.mdx.model.p2p_transfer.Recipient.class, new ModelWrappableSerializer("recipient"));
393+
builder.registerTypeAdapter(new TypeToken<MdxList<com.mx.path.model.mdx.model.p2p_transfer.Recipient>>() {
394+
}.getType(), new ModelWrappableSerializer("recipients"));
391395
}
392396

393397
private static void registerPaymentsModels(GsonBuilder builder) {
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
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 Recipient extends MdxBase<Recipient> {
11+
private String id;
12+
private String emailAddress;
13+
private String firstName;
14+
private String lastName;
15+
private String phoneNumber;
16+
}
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.Recipient;
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 P2PTransferRecipientsController extends BaseController {
18+
@RequestMapping(value = "/users/{userId}/p2p_transfers/recipients", method = RequestMethod.POST, consumes = BaseController.MDX_MEDIA)
19+
public final ResponseEntity<Recipient> create(@RequestBody Recipient recipientRequest) {
20+
AccessorResponse<Recipient> response = gateway().p2pTransfers().recipients().create(recipientRequest);
21+
return new ResponseEntity<>(response.getResult().wrapped(), createMultiMapForResponse(response.getHeaders()), HttpStatus.OK);
22+
}
23+
24+
@RequestMapping(value = "/users/{userId}/p2p_transfers/recipients/{id}", method = RequestMethod.DELETE)
25+
public final ResponseEntity<?> delete(@PathVariable("id") String recipientId) {
26+
AccessorResponse<Void> response = gateway().p2pTransfers().recipients().delete(recipientId);
27+
return new ResponseEntity<>(createMultiMapForResponse(response.getHeaders()), HttpStatus.NO_CONTENT);
28+
}
29+
30+
@RequestMapping(value = "/users/{userId}/p2p_transfers/recipients/{id}", method = RequestMethod.GET)
31+
public final ResponseEntity<Recipient> get(@PathVariable("id") String recipientId) {
32+
AccessorResponse<Recipient> response = gateway().p2pTransfers().recipients().get(recipientId);
33+
return new ResponseEntity<>(response.getResult().wrapped(), createMultiMapForResponse(response.getHeaders()), HttpStatus.OK);
34+
}
35+
36+
@RequestMapping(value = "/users/{userId}/p2p_transfers/recipients", method = RequestMethod.GET)
37+
public final ResponseEntity<MdxList<Recipient>> list() {
38+
AccessorResponse<MdxList<Recipient>> response = gateway().p2pTransfers().recipients().list();
39+
return new ResponseEntity<>(response.getResult().wrapped(), createMultiMapForResponse(response.getHeaders()), HttpStatus.OK);
40+
}
41+
42+
@RequestMapping(value = "/users/{userId}/p2p_transfers/recipients/{id}", method = RequestMethod.PUT, consumes = BaseController.MDX_MEDIA)
43+
public final ResponseEntity<Recipient> update(@PathVariable("id") String recipientId, @RequestBody Recipient recipientRequest) {
44+
AccessorResponse<Recipient> response = gateway().p2pTransfers().recipients().update(recipientId, recipientRequest);
45+
return new ResponseEntity<>(response.getResult().wrapped(), createMultiMapForResponse(response.getHeaders()), HttpStatus.OK);
46+
}
47+
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
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.gateway.api.p2p_transfer.RecipientGateway
12+
import com.mx.path.model.mdx.model.MdxList
13+
import com.mx.path.model.mdx.model.p2p_transfer.Recipient
14+
15+
import org.springframework.http.HttpStatus
16+
17+
import spock.lang.Specification
18+
19+
class P2PTransferRecipientsControllerTest extends Specification {
20+
P2PTransferRecipientsController subject
21+
Gateway gateway
22+
P2PTransferGateway p2pTransferGateway
23+
RecipientGateway recipientGateway
24+
25+
def setup() {
26+
subject = new P2PTransferRecipientsController()
27+
p2pTransferGateway = mock(P2PTransferGateway)
28+
recipientGateway = mock(RecipientGateway)
29+
30+
doReturn(recipientGateway).when(p2pTransferGateway).recipients()
31+
gateway = spy(Gateway.builder().clientId("client-1234").p2pTransfers(p2pTransferGateway).build())
32+
}
33+
34+
def cleanup() {
35+
BaseController.clearGateway()
36+
}
37+
38+
def "create interacts with gateway"() {
39+
given:
40+
BaseController.setGateway(gateway)
41+
def recipient = new Recipient()
42+
doReturn(new AccessorResponse<Recipient>().withResult(recipient)).when(recipientGateway).create(recipient)
43+
44+
when:
45+
def result = subject.create(recipient)
46+
47+
then:
48+
HttpStatus.OK == result.statusCode
49+
result.body == recipient
50+
verify(recipientGateway).create(recipient) || true
51+
}
52+
53+
def "delete interacts with gateway"() {
54+
given:
55+
BaseController.setGateway(gateway)
56+
def id = "id-1234"
57+
doReturn(new AccessorResponse<Void>()).when(recipientGateway).delete(id)
58+
59+
when:
60+
def result = subject.delete(id)
61+
62+
then:
63+
HttpStatus.NO_CONTENT == result.statusCode
64+
verify(recipientGateway).delete(id) || true
65+
}
66+
67+
def "get interacts with gateway"() {
68+
given:
69+
BaseController.setGateway(gateway)
70+
def id = "id-1234"
71+
def recipient = new Recipient()
72+
doReturn(new AccessorResponse<Recipient>().withResult(recipient)).when(recipientGateway).get(id)
73+
74+
when:
75+
def result = subject.get(id)
76+
77+
then:
78+
HttpStatus.OK == result.statusCode
79+
result.body == recipient
80+
verify(recipientGateway).get(id) || true
81+
}
82+
83+
def "list interacts with gateway"() {
84+
given:
85+
BaseController.setGateway(gateway)
86+
def recipients = new MdxList().tap {
87+
add(new Recipient())
88+
}
89+
doReturn(new AccessorResponse<MdxList<Recipient>>().withResult(recipients)).when(recipientGateway).list()
90+
91+
when:
92+
def result = subject.list()
93+
94+
then:
95+
HttpStatus.OK == result.statusCode
96+
result.body == recipients
97+
verify(recipientGateway).list() || true
98+
}
99+
100+
def "update interacts with gateway"() {
101+
given:
102+
BaseController.setGateway(gateway)
103+
def id = "id-1234"
104+
def recipient = new Recipient()
105+
doReturn(new AccessorResponse<Recipient>().withResult(recipient)).when(recipientGateway).update(id, recipient)
106+
107+
when:
108+
def result = subject.update(id, recipient)
109+
110+
then:
111+
HttpStatus.OK == result.statusCode
112+
result.body == recipient
113+
verify(recipientGateway).update(id, recipient) || true
114+
}
115+
}

0 commit comments

Comments
 (0)