View Javadoc
1   /*
2    * Copyright (C) 2013 4th Line GmbH, Switzerland
3    *
4    * The contents of this file are subject to the terms of either the GNU
5    * Lesser General Public License Version 2 or later ("LGPL") or the
6    * Common Development and Distribution License Version 1 or later
7    * ("CDDL") (collectively, the "License"). You may not use this file
8    * except in compliance with the License. See LICENSE.txt for more
9    * information.
10   *
11   * This program is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14   */
15  
16  package org.fourthline.cling.test.control;
17  
18  import org.fourthline.cling.UpnpService;
19  import org.fourthline.cling.binding.xml.ServiceDescriptorBinder;
20  import org.fourthline.cling.binding.xml.UDA10ServiceDescriptorBinderImpl;
21  import org.fourthline.cling.mock.MockUpnpService;
22  import org.fourthline.cling.mock.MockUpnpServiceConfiguration;
23  import org.fourthline.cling.model.UnsupportedDataException;
24  import org.fourthline.cling.model.action.ActionInvocation;
25  import org.fourthline.cling.model.message.StreamRequestMessage;
26  import org.fourthline.cling.model.message.StreamResponseMessage;
27  import org.fourthline.cling.model.message.UpnpRequest;
28  import org.fourthline.cling.model.message.control.IncomingActionRequestMessage;
29  import org.fourthline.cling.model.message.control.IncomingActionResponseMessage;
30  import org.fourthline.cling.model.message.header.ContentTypeHeader;
31  import org.fourthline.cling.model.message.header.SoapActionHeader;
32  import org.fourthline.cling.model.message.header.UpnpHeader;
33  import org.fourthline.cling.model.meta.Action;
34  import org.fourthline.cling.model.meta.LocalDevice;
35  import org.fourthline.cling.model.meta.LocalService;
36  import org.fourthline.cling.model.meta.RemoteService;
37  import org.fourthline.cling.model.types.SoapActionType;
38  import org.fourthline.cling.test.data.SampleData;
39  import org.fourthline.cling.transport.impl.PullSOAPActionProcessorImpl;
40  import org.fourthline.cling.transport.impl.RecoveringSOAPActionProcessorImpl;
41  import org.fourthline.cling.transport.spi.SOAPActionProcessor;
42  import org.seamless.util.io.IO;
43  import org.testng.annotations.DataProvider;
44  import org.testng.annotations.Test;
45  
46  import java.net.URI;
47  
48  import static org.testng.Assert.assertEquals;
49  
50  /**
51   * @author Christian Bauer
52   */
53  public class InvalidActionXMLProcessingTest {
54  
55      @DataProvider(name = "invalidXMLFile")
56      public String[][] getInvalidXMLFile() throws Exception {
57          return new String[][]{
58              {"/invalidxml/control/request_missing_envelope.xml"},
59              {"/invalidxml/control/request_missing_action_namespace.xml"},
60              {"/invalidxml/control/request_invalid_action_namespace.xml"},
61          };
62      }
63  
64      @DataProvider(name = "invalidRecoverableXMLFile")
65      public String[][] getInvalidRecoverableXMLFile() throws Exception {
66          return new String[][]{
67              {"/invalidxml/control/request_no_entityencoding.xml"},
68              {"/invalidxml/control/request_wrong_termination.xml"},
69          };
70      }
71  
72      @DataProvider(name = "invalidUnrecoverableXMLFile")
73      public String[][] getInvalidUnrecoverableXMLFile() throws Exception {
74          return new String[][]{
75              {"/invalidxml/control/unrecoverable/naim_unity.xml"},
76          };
77      }
78  
79      /* ############################## TEST FAILURE ############################ */
80  
81      @Test(dataProvider = "invalidXMLFile", expectedExceptions = UnsupportedDataException.class)
82      public void readRequestDefaultFailure(String invalidXMLFile) throws Exception {
83          // This should always fail!
84          readRequest(invalidXMLFile, new MockUpnpService());
85      }
86  
87      @Test(dataProvider = "invalidRecoverableXMLFile", expectedExceptions = UnsupportedDataException.class)
88      public void readRequestRecoverableFailure(String invalidXMLFile) throws Exception {
89          // This should always fail!
90          readRequest(invalidXMLFile, new MockUpnpService());
91      }
92  
93      @Test(dataProvider = "invalidUnrecoverableXMLFile", expectedExceptions = Exception.class)
94      public void readRequestRecoveringFailure(String invalidXMLFile) throws Exception {
95          // This should always fail!
96          readRequest(
97              invalidXMLFile,
98              new MockUpnpService(new MockUpnpServiceConfiguration() {
99                  @Override
100                 public SOAPActionProcessor getSoapActionProcessor() {
101                     return new RecoveringSOAPActionProcessorImpl();
102                 }
103             })
104         );
105     }
106 
107     /* ############################## TEST SUCCESS ############################ */
108 
109     @Test(dataProvider = "invalidXMLFile")
110     public void readRequestPull(String invalidXMLFile) throws Exception {
111         readRequest(
112             invalidXMLFile,
113             new MockUpnpService(new MockUpnpServiceConfiguration() {
114                 @Override
115                 public SOAPActionProcessor getSoapActionProcessor() {
116                     return new PullSOAPActionProcessorImpl();
117                 }
118             })
119         );
120     }
121 
122     @Test(dataProvider = "invalidRecoverableXMLFile")
123     public void readRequestRecovering(String invalidXMLFile) throws Exception {
124         readRequest(
125             invalidXMLFile,
126             new MockUpnpService(new MockUpnpServiceConfiguration() {
127                 @Override
128                 public SOAPActionProcessor getSoapActionProcessor() {
129                     return new RecoveringSOAPActionProcessorImpl();
130                 }
131             })
132         );
133     }
134 
135     @Test
136    	public void uppercaseOutputArguments() throws Exception {
137    		SOAPActionProcessor processor = new RecoveringSOAPActionProcessorImpl();
138    		ServiceDescriptorBinder binder = new UDA10ServiceDescriptorBinderImpl();
139 
140    		RemoteService service = SampleData.createUndescribedRemoteService();
141    		service = binder.describe(
142                service,
143                IO.readLines(getClass().getResourceAsStream("/descriptors/service/uda10_connectionmanager.xml"))
144            );
145 
146    		Action action = service.getAction("GetProtocolInfo");
147 
148    		ActionInvocation actionInvocation = new ActionInvocation(action);
149    		StreamResponseMessage response = new StreamResponseMessage(
150                IO.readLines(getClass().getResourceAsStream("/invalidxml/control/response_uppercase_args.xml"))
151            );
152 
153    		processor.readBody(new IncomingActionResponseMessage(response), actionInvocation);
154    	}
155 
156     protected void readRequest(String invalidXMLFile, UpnpService upnpService) throws Exception {
157         LocalDevice ld = ActionSampleData.createTestDevice(ActionSampleData.LocalTestServiceExtended.class);
158         LocalService svc = ld.getServices()[0];
159 
160         Action action = svc.getAction("SetSomeValue");
161         ActionInvocation actionInvocation = new ActionInvocation(action);
162 
163         StreamRequestMessage message = createRequestMessage(action, invalidXMLFile);
164         IncomingActionRequestMessage request = new IncomingActionRequestMessage(message, svc);
165 
166         upnpService.getConfiguration().getSoapActionProcessor().readBody(request, actionInvocation);
167 
168         assertEquals(actionInvocation.getInput()[0].toString(), "foo&bar");
169     }
170 
171     public StreamRequestMessage createRequestMessage(Action action, String xmlFile) throws Exception {
172         StreamRequestMessage message =
173             new StreamRequestMessage(UpnpRequest.Method.POST, URI.create("http://some.uri"));
174 
175         message.getHeaders().add(
176             UpnpHeader.Type.CONTENT_TYPE,
177             new ContentTypeHeader(ContentTypeHeader.DEFAULT_CONTENT_TYPE_UTF8)
178         );
179         message.getHeaders().add(
180             UpnpHeader.Type.SOAPACTION,
181             new SoapActionHeader(
182                 new SoapActionType(
183                     action.getService().getServiceType(),
184                     action.getName()
185                 )
186             )
187         );
188         message.setBody(IO.readLines(getClass().getResourceAsStream(xmlFile)));
189         return message;
190     }
191 }