Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue-425: fix NPE while importing postman collection with item array #473

Merged
merged 3 commits into from
Jul 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 66 additions & 38 deletions karate-core/src/main/java/com/intuit/karate/convert/ConvertUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,63 +28,91 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;

/**
* Created by rkumar32 on 7/5/17.
*/
public class ConvertUtils {

private static final Logger logger = LoggerFactory.getLogger(ConvertUtils.class);

private ConvertUtils() {
// only static methods
}

public static String toKarateFeature(List<PostmanRequest> requests) {
String scenarios = "";
for (PostmanRequest request : requests) {
scenarios += request.convert();
public static String toKarateFeature(List<PostmanItem> items) {
return toKarateFeature(UUID.randomUUID().toString(), items);
}

public static String toKarateFeature(String collectionName, List<PostmanItem> items) {
StringBuilder sb = new StringBuilder("Feature: ").append(collectionName);
sb.append(System.lineSeparator()).append(System.lineSeparator());
for (PostmanItem item : items) {
sb.append(item.convert());
}
String feature = "Feature: \n\n" + scenarios;
return feature;
return sb.toString();
}
public static List<PostmanRequest> readPostmanJson(String json) {

public static List<PostmanItem> readPostmanJson(String json) {
DocumentContext doc = JsonPath.parse(json);
List<Map<String, Object>> list = (List) doc.read("$.item");
List<PostmanRequest> requests = new ArrayList<>(list.size());
return readPostmanItems(null, list);
}

private static List<PostmanItem> readPostmanItems(PostmanItem parent, List<Map<String, Object>> list) {
PostmanItem item;
List<PostmanItem> requests = new ArrayList<>(list.size());
for (Map<String, Object> map : list) {
logger.debug("map: {}", map);
String name = (String) map.get("name");
Map<String, Object> requestInfo = (Map) map.get("request");
String url = (String) requestInfo.get("url");
String method = (String) requestInfo.get("method");
List<Map<String, Object>> headersList = (List) requestInfo.get("header");
Map<String, String> headers = new HashMap<>();
item = readPosmanItem(parent, map);
requests.add(item);
}
return requests;
}

private static PostmanItem readPosmanItem(PostmanItem parent, Map<String, Object> itemMap) {
PostmanItem item = new PostmanItem();
String name = (String) itemMap.get("name");
item.setName(name);
item.setParent(Optional.ofNullable(parent));
Map<String, Object> requestInfo = (Map) itemMap.get("request");
if (requestInfo != null) {
item.setRequest(readPostmanRequest(requestInfo));
} else { // this may have list of sub-items
List<PostmanItem> subItems = readPostmanItems(item, (List<Map<String, Object>>) itemMap.get("item"));
item.setItems(Optional.of(subItems));
}
return item;
}

private static PostmanRequest readPostmanRequest(Map<String, Object> requestInfo) {
String url = getUrl(requestInfo.get("url"));
String method = (String) requestInfo.get("method");
List<Map<String, Object>> headersList = (List) requestInfo.get("header");
Map<String, String> headers = new HashMap<>();
if (headersList != null) {
for (Map<String, Object> header : headersList) {
headers.put((String) header.get("key"), (String) header.get("value"));
}
Map<String, Object> bodyInfo = (Map) requestInfo.get("body");
String body = null;
if (bodyInfo.containsKey("raw")) {
body = ((String) bodyInfo.get("raw")).replace(System.lineSeparator(), "");
}
else if (bodyInfo.containsKey("formdata")) {
body = ((List) bodyInfo.get("formdata")).toString().replace(System.lineSeparator(), "");
}
PostmanRequest request = new PostmanRequest();
request.setName(name);
request.setUrl(url);
request.setMethod(method);
request.setHeaders(headers);
request.setBody(body);
requests.add(request);
}
return requests;
}

Map<String, Object> bodyInfo = (Map) requestInfo.get("body");
String body = null;
if (bodyInfo.containsKey("raw")) {
body = ((String) bodyInfo.get("raw")).replace(System.lineSeparator(), "");
} else if (bodyInfo.containsKey("formdata")) {
body = ((List) bodyInfo.get("formdata")).toString().replace(System.lineSeparator(), "");
}
PostmanRequest request = new PostmanRequest();
request.setUrl(url);
request.setMethod(method);
request.setHeaders(headers);
request.setBody(body);
return request;
}

private static String getUrl(Object url) {
return (url instanceof String) ? (String) url : (String) ((Map) url).get("raw");
}

}
111 changes: 111 additions & 0 deletions karate-core/src/main/java/com/intuit/karate/convert/PostmanItem.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
* The MIT License
*
* Copyright 2017 Intuit Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.intuit.karate.convert;

import java.util.List;
import java.util.Optional;

/**
* @author vmchukky
*/

//http://schema.getpostman.com/json/collection/v2.1.0/docs/index.html
public class PostmanItem {

private String name;
private PostmanRequest request; // schema says request is mandatory but have seen example collections without it
private Optional<PostmanItem> parent; // top level item (without a parent becomes a scenario)
private Optional<List<PostmanItem>> items; // items within an item become part of the same scenario associated with parent

public PostmanItem() {
this.items = Optional.empty();
this.parent = Optional.empty();
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = (name == null) ? "" : name;
}

public PostmanRequest getRequest() {
return request;
}

public void setRequest(PostmanRequest request) {
this.request = request;
}

public Optional<PostmanItem> getParent() {
return parent;
}

public void setParent(Optional<PostmanItem> parent) {
this.parent = parent;
}

public Optional<List<PostmanItem>> getItems() {
return items;
}

public void setItems(Optional<List<PostmanItem>> items) {
this.items = items;
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[name: ").append(name);
if (items.isPresent()) {
sb.append(items.toString());
} else {
sb.append(", request: ").append(request.toString());
}
sb.append("]");
return sb.toString();
}

public String convert() {
StringBuilder sb = new StringBuilder();

sb.append(parent.isPresent() ? "# " : "Scenario: ");
sb.append(name).append(System.lineSeparator());
if (items.isPresent()) {
for (PostmanItem item : items.get()) {
sb.append(item.convert());
}
} else {
RequestBuilder builder = new RequestBuilder();
sb.append(builder.addUrl(request.getUrl())
.addHeaders(request.getHeaders())
.addBody(request.getBody())
.addMethod(request.getMethod())
.build());
}
return sb.toString();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@
* @author pthomas3
*/
public class PostmanRequest {

private String name;

private String url;
private String method;
private Map<String, String> headers;
Expand Down Expand Up @@ -68,31 +67,20 @@ public String getUrl() {
public void setUrl(String url) {
this.url = url;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[name: ").append(name);
sb.append(", url: ").append(url);
sb.append("[url: ").append(url);
sb.append(", method: ").append(method);
sb.append(", headers: ").append(headers);
sb.append(", body: ").append(body);
sb.append("]");
return sb.toString();
}


public String convert() {
return new FeatureBuilder()
.addName(name)
return new RequestBuilder()
.addUrl(url)
.addHeaders(headers)
.addBody(body)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,78 +24,60 @@
package com.intuit.karate.convert;

import com.intuit.karate.StringUtils;

import java.util.Map;

/**
* Created by rkumar32 on 5/24/17.
*/
public class FeatureBuilder {
public class RequestBuilder {

private String name;
private String url;
private String method;
private String headers;
private String body;

private final String SCENARIO_TEMPLATE = "Scenario: %s" + // Scenario Description
"Given url " + "%s" + // url
"%s" + // Headers
"%s" + // Body
"When method %s" + System.lineSeparator(); // Method
private final String REQUEST_TEMPLATE = "Given url " + "%s" + // url
"%s" + // Headers
"%s" + // Body
"When method %s" + System.lineSeparator(); // Method

public FeatureBuilder addName(String name) {
if (name != null) {
this.name = name + System.lineSeparator();
}
else {
this.name = "";
}
return this;
}

public FeatureBuilder addUrl(String url) {
public RequestBuilder addUrl(String url) {
if (url != null) {
this.url = "'" + url + "'" + System.lineSeparator();
}
else {
} else {
throw new IllegalArgumentException("Url is null");
}
return this;
}

public FeatureBuilder addMethod(String method) {
public RequestBuilder addMethod(String method) {
if (url != null) {
this.method = method + System.lineSeparator();
}
else {
} else {
throw new IllegalArgumentException("Method is null");
}
return this;
}

public FeatureBuilder addHeaders(Map<String, String > headers) {
public RequestBuilder addHeaders(Map<String, String> headers) {
this.headers = "";
for (Map.Entry<String, String> entry: headers.entrySet()) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
this.headers += "And header " + entry.getKey() + " = " + "'" +
entry.getValue() + "'" + System.lineSeparator();
}
return this;
}

public FeatureBuilder addBody(String body) {
public RequestBuilder addBody(String body) {
if (body != null) {
this.body = "And request " + body + System.lineSeparator();
}
else {
} else {
this.body = "";
}
return this;
}

public String getName() {
return name;
}

public String getUrl() {
return url;
}
Expand All @@ -116,12 +98,10 @@ public String build() {
if ("POST".equals(method) && StringUtils.isBlank(body)) {
throw new IllegalArgumentException("Body can't be null if method is POST");
}
return String.format(SCENARIO_TEMPLATE, name,
url,
return String.format(REQUEST_TEMPLATE, url,
headers,
body,
method);
}

}

}
Loading