001/*
002 * Stallion Core: A Modern Web Framework
003 *
004 * Copyright (C) 2015 - 2016 Stallion Software LLC.
005 *
006 * This program is free software: you can redistribute it and/or modify it under the terms of the
007 * GNU General Public License as published by the Free Software Foundation, either version 2 of
008 * the License, or (at your option) any later version. This program is distributed in the hope that
009 * it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
011 * License for more details. You should have received a copy of the GNU General Public License
012 * along with this program.  If not, see <http://www.gnu.org/licenses/gpl-2.0.html>.
013 *
014 *
015 *
016 */
017
018package io.stallion.testing;
019
020import com.fasterxml.jackson.annotation.JsonView;
021import com.fasterxml.jackson.databind.ObjectMapper;
022import io.stallion.requests.StRequest;
023import io.stallion.services.Log;
024import io.stallion.utils.json.JSON;
025import io.stallion.utils.json.RestrictedViews;
026
027import javax.servlet.http.Cookie;
028import java.io.BufferedReader;
029import java.io.StringReader;
030import java.io.UnsupportedEncodingException;
031import java.net.URL;
032import java.net.URLDecoder;
033import java.util.HashMap;
034
035import java.util.List;
036import java.util.Map;
037
038import static io.stallion.utils.Literals.*;
039
040
041public class MockRequest extends StRequest {
042    private boolean handled = false;
043    private Map<String, String> headers = new HashMap<>();
044    private String path = "";
045    private String query = "";
046    private String method = "GET";
047    private String content = null;
048    private Map<String, Object> data = new HashMap<>();
049    private Object dataObject = null;
050    private Map<String, String> queryMap = null;
051    private List<Cookie> cookies = list();
052
053    public MockRequest(String path)  {
054        this.path = path;
055        init();
056    }
057
058    public MockRequest(String path, String method) {
059        setPath(path);
060        this.method = method;
061        init();
062    }
063
064    private void init() {
065
066    }
067
068    public static Map<String, String> splitQuery(URL url) {
069        Map<String, String> query_pairs = new HashMap<String, String>();
070        String query = url.getQuery();
071        String[] pairs = query.split("&");
072        for (String pair : pairs) {
073            int idx = pair.indexOf("=");
074            try {
075                query_pairs.put(URLDecoder.decode(pair.substring(0, idx), "UTF-8"), URLDecoder.decode(pair.substring(idx + 1), "UTF-8"));
076            } catch (UnsupportedEncodingException e) {
077                Log.exception(e, "Error parsing url {0}", url);
078            }
079        }
080        return query_pairs;
081    }
082
083    public MockRequest addHeader(String name, String value) {
084        headers.put(name, value);
085        return this;
086    }
087
088    public MockRequest addData(String key, Object value) {
089        data.put(key, value);
090        return this;
091    }
092
093    public MockRequest setData(Map<String, Object> data) {
094        this.data = data;
095        return this;
096    }
097
098    public MockRequest setDataObject(Object dataObject) {
099        this.dataObject = dataObject;
100        return this;
101    }
102
103    public MockRequest setContent(String content) {
104        this.content = content;
105        return this;
106    }
107
108    @Override
109    public String getContent() {
110        if (content != null) {
111            return content;
112        }
113        if (dataObject != null) {
114            content = dataObjectToString();
115        } else if (data != null && data.size() > 0) {
116            content = dataToString();
117        }
118        if (content == null) {
119            content = "";
120        }
121        return content;
122    }
123
124
125    public BufferedReader getReader() {
126        if (content != null) {
127            return contentToReader();
128        }
129        if (dataObject != null) {
130            content = dataObjectToString();
131        } else if (data.size() > 0) {
132            content = dataToString();
133        } else {
134            content = "";
135        }
136        return contentToReader();
137
138    }
139
140
141    public StRequest setHandled(Boolean val) {
142
143        handled = val;
144        return this;
145    }
146
147    public String getPath() {
148        return path;
149    }
150
151    public void setPath(String path) {
152        int q = path.indexOf("?");
153        if (q != -1) {
154            this.path = path.substring(0, q);
155            this.query = path.substring(q + 1);
156        } else {
157            this.path = path;
158        }
159    }
160
161    public String getHeader(String name) {
162        if (headers.containsKey(name)) {
163            return headers.get(name);
164        } else {
165            return "";
166        }
167    }
168
169    @Override
170    public String getParameter(String paramName) {
171        return getQueryParams().getOrDefault(paramName, null);
172    }
173
174    @Override
175    public String getMethod() {
176        return this.method;
177    }
178
179    /* Private helpers */
180    @Override
181    public Map<String, String> getQueryParams()
182    {
183        if (queryMap == null) {
184            queryMap = new HashMap<String, String>();
185            String[] pairs = query.split("&");
186            for (String pair : pairs) {
187                int idx = pair.indexOf("=");
188                if (idx > -1) {
189                    try {
190                        queryMap.put(URLDecoder.decode(pair.substring(0, idx), "UTF-8"), URLDecoder.decode(pair.substring(idx + 1), "UTF-8"));
191                    } catch (UnsupportedEncodingException e) {
192                        Log.exception(e, "Error parsing query {0}", query);
193                    }
194                }
195            }
196        }
197        return queryMap;
198    }
199
200    @Override
201    public String getActualIp() {
202        return "127.0.0.100";
203    }
204
205    protected String dataToString() {
206        try {
207            ObjectMapper mapper = new ObjectMapper();
208            return mapper.writeValueAsString(this.data);
209        } catch(Exception e) {
210            throw new RuntimeException(e);
211        }
212    }
213
214    protected String dataObjectToString() {
215        try {
216            return JSON.stringify(this.dataObject, RestrictedViews.Internal.class);
217        } catch(Exception e) {
218            throw new RuntimeException(e);
219        }
220    }
221
222    protected BufferedReader contentToReader() {
223        StringReader sr = new StringReader(content);
224        BufferedReader br = new BufferedReader(sr);
225        return br;
226    }
227
228    public Cookie getCookie(String name) {
229        for(Cookie cookie: cookies) {
230            if (name.equals(cookie.getName())) {
231                return cookie;
232            }
233        }
234        return null;
235    }
236
237    public Cookie[] getCookies() {
238        return cookies.toArray(new Cookie[cookies.size()]);
239    }
240
241    public StRequest setCookies(Cookie ...cookies) {
242        this.cookies = list(cookies);
243        return this;
244    }
245
246    @Override
247    public void setQuery(String q) {
248        this.query = q;
249    }
250
251    @Override
252    public String getQueryString() {
253        if (query == null) {
254            if (!requestUrl().contains("?")) {
255                query = "";
256            } else {
257                query = requestUrl().split("\\?", 2)[1];
258            }
259        }
260        return query;
261    }
262
263}