1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.messaging.simp.annotation.support;
18
19 import java.lang.reflect.Method;
20 import java.nio.charset.Charset;
21 import java.security.Principal;
22
23 import org.junit.Before;
24 import org.junit.Test;
25 import org.mockito.ArgumentCaptor;
26 import org.mockito.Captor;
27 import org.mockito.Mock;
28 import org.mockito.Mockito;
29 import org.mockito.MockitoAnnotations;
30
31 import org.springframework.core.MethodParameter;
32 import org.springframework.messaging.Message;
33 import org.springframework.messaging.MessageChannel;
34 import org.springframework.messaging.MessageHeaders;
35 import org.springframework.messaging.converter.StringMessageConverter;
36 import org.springframework.messaging.core.MessageSendingOperations;
37 import org.springframework.messaging.handler.annotation.MessageMapping;
38 import org.springframework.messaging.handler.annotation.SendTo;
39 import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
40 import org.springframework.messaging.simp.SimpMessagingTemplate;
41 import org.springframework.messaging.simp.annotation.SubscribeMapping;
42 import org.springframework.messaging.support.MessageBuilder;
43 import org.springframework.messaging.support.MessageHeaderAccessor;
44 import org.springframework.util.MimeType;
45
46 import static org.junit.Assert.*;
47 import static org.mockito.BDDMockito.*;
48
49
50
51
52
53
54 public class SubscriptionMethodReturnValueHandlerTests {
55
56 public static final MimeType MIME_TYPE = new MimeType("text", "plain", Charset.forName("UTF-8"));
57
58 private static final String PAYLOAD = "payload";
59
60
61 private SubscriptionMethodReturnValueHandler handler;
62
63 @Mock private MessageChannel messageChannel;
64
65 @Captor ArgumentCaptor<Message<?>> messageCaptor;
66
67 private MethodParameter subscribeEventReturnType;
68
69 private MethodParameter subscribeEventSendToReturnType;
70
71 private MethodParameter messageMappingReturnType;
72
73
74 @Before
75 public void setup() throws Exception {
76
77 MockitoAnnotations.initMocks(this);
78
79 SimpMessagingTemplate messagingTemplate = new SimpMessagingTemplate(this.messageChannel);
80 messagingTemplate.setMessageConverter(new StringMessageConverter());
81
82 this.handler = new SubscriptionMethodReturnValueHandler(messagingTemplate);
83
84 Method method = this.getClass().getDeclaredMethod("getData");
85 this.subscribeEventReturnType = new MethodParameter(method, -1);
86
87 method = this.getClass().getDeclaredMethod("getDataAndSendTo");
88 this.subscribeEventSendToReturnType = new MethodParameter(method, -1);
89
90 method = this.getClass().getDeclaredMethod("handle");
91 this.messageMappingReturnType = new MethodParameter(method, -1);
92 }
93
94
95 @Test
96 public void supportsReturnType() throws Exception {
97 assertTrue(this.handler.supportsReturnType(this.subscribeEventReturnType));
98 assertFalse(this.handler.supportsReturnType(this.subscribeEventSendToReturnType));
99 assertFalse(this.handler.supportsReturnType(this.messageMappingReturnType));
100 }
101
102 @Test
103 public void testMessageSentToChannel() throws Exception {
104
105 given(this.messageChannel.send(any(Message.class))).willReturn(true);
106
107 String sessionId = "sess1";
108 String subscriptionId = "subs1";
109 String destination = "/dest";
110 Message<?> inputMessage = createInputMessage(sessionId, subscriptionId, destination, null);
111
112 this.handler.handleReturnValue(PAYLOAD, this.subscribeEventReturnType, inputMessage);
113
114 verify(this.messageChannel).send(this.messageCaptor.capture());
115 assertNotNull(this.messageCaptor.getValue());
116
117 Message<?> message = this.messageCaptor.getValue();
118 SimpMessageHeaderAccessor headerAccessor = SimpMessageHeaderAccessor.wrap(message);
119
120 assertNull("SimpMessageHeaderAccessor should have disabled id", headerAccessor.getId());
121 assertNull("SimpMessageHeaderAccessor should have disabled timestamp", headerAccessor.getTimestamp());
122 assertEquals(sessionId, headerAccessor.getSessionId());
123 assertEquals(subscriptionId, headerAccessor.getSubscriptionId());
124 assertEquals(destination, headerAccessor.getDestination());
125 assertEquals(MIME_TYPE, headerAccessor.getContentType());
126 }
127
128 @Test
129 @SuppressWarnings({ "unchecked", "rawtypes" })
130 public void testHeadersPassedToMessagingTemplate() throws Exception {
131
132 String sessionId = "sess1";
133 String subscriptionId = "subs1";
134 String destination = "/dest";
135 Message<?> inputMessage = createInputMessage(sessionId, subscriptionId, destination, null);
136
137 MessageSendingOperations messagingTemplate = Mockito.mock(MessageSendingOperations.class);
138 SubscriptionMethodReturnValueHandler handler = new SubscriptionMethodReturnValueHandler(messagingTemplate);
139
140 handler.handleReturnValue(PAYLOAD, this.subscribeEventReturnType, inputMessage);
141
142 ArgumentCaptor<MessageHeaders> captor = ArgumentCaptor.forClass(MessageHeaders.class);
143 verify(messagingTemplate).convertAndSend(eq("/dest"), eq(PAYLOAD), captor.capture());
144
145 SimpMessageHeaderAccessor headerAccessor =
146 MessageHeaderAccessor.getAccessor(captor.getValue(), SimpMessageHeaderAccessor.class);
147
148 assertNotNull(headerAccessor);
149 assertTrue(headerAccessor.isMutable());
150 assertEquals(sessionId, headerAccessor.getSessionId());
151 assertEquals(subscriptionId, headerAccessor.getSubscriptionId());
152 }
153
154
155 private Message<?> createInputMessage(String sessId, String subsId, String dest, Principal principal) {
156 SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create();
157 headers.setSessionId(sessId);
158 headers.setSubscriptionId(subsId);
159 headers.setDestination(dest);
160 headers.setUser(principal);
161 return MessageBuilder.withPayload(new byte[0]).copyHeaders(headers.toMap()).build();
162 }
163
164
165 @SubscribeMapping("/data")
166 private String getData() {
167 return PAYLOAD;
168 }
169
170 @SubscribeMapping("/data")
171 @SendTo("/sendToDest")
172 private String getDataAndSendTo() {
173 return PAYLOAD;
174 }
175
176 @MessageMapping("/handle")
177 public String handle() {
178 return PAYLOAD;
179 }
180 }