Issue 4824 fix gson deserialize format byte (#7473)

* Build sample prior to code changes so differences are easier to decipher

* Add byte array type adapter for okhttp-gson (java8 only)

* Unit revealed that Gson (or GsonFire) defaults to escape = (equal sign) out of base64 string.  Add disableHtmlEscaping() to gsonbuilder.

* Update specs and samples to include format=byte and include junit test of byte array serialization and deserialization.

* Implement recommendations by @cbornet including: Use okio.ByteString for base64 conversions instead of java 8 lib since the okhttp-gson client already includes okio. Remove setting to disableHtmlEscaping. Rename LocalByteArrayAdapter to ByteArrayAdapter.

* Update spec and sample for java okhttp-gson library client

* Undo addition of profilePhoto property.  A format byte property is already available under the format_test definition.

* Put previously deleted tests back. Modified testFindPetsByTags() to verify exception since the server now returns a 500 for this request.

* Update test to pass when run against docker containerized server swaggerapi/petstore (heads up, this test fails if calling out to the internet published version of http://petstore.swagger.io)
This commit is contained in:
Benjamin Roedell 2018-01-25 20:52:49 -05:00 committed by William Cheng
parent 2d898511a8
commit 47111b3241
16 changed files with 374 additions and 251 deletions

View File

@ -5,6 +5,6 @@ If Not Exist %executable% (
) )
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
set ags=generate -i modules\swagger-codegen\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -l java -o samples\client\petstore\java --library=okhttp-gson -DdateLibrary=joda -DhideGenerationTimestamp=true set ags=generate -t modules\swagger-codegen\src\main\resources\Java\libraries\okhttp-gson -i modules\swagger-codegen\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -l java -c bin\java-petstore-okhttp-gson.json -o samples\client\petstore\java\okhttp-gson -DhideGenerationTimestamp=true
java %JAVA_OPTS% -jar %executable% %ags% java %JAVA_OPTS% -jar %executable% %ags%

View File

@ -26,6 +26,7 @@ import org.threeten.bp.format.DateTimeFormatter;
{{/threetenbp}} {{/threetenbp}}
import {{modelPackage}}.*; import {{modelPackage}}.*;
import okio.ByteString;
import java.io.IOException; import java.io.IOException;
import java.io.StringReader; import java.io.StringReader;
@ -55,6 +56,7 @@ public class JSON {
private OffsetDateTimeTypeAdapter offsetDateTimeTypeAdapter = new OffsetDateTimeTypeAdapter(); private OffsetDateTimeTypeAdapter offsetDateTimeTypeAdapter = new OffsetDateTimeTypeAdapter();
private LocalDateTypeAdapter localDateTypeAdapter = new LocalDateTypeAdapter(); private LocalDateTypeAdapter localDateTypeAdapter = new LocalDateTypeAdapter();
{{/jsr310}} {{/jsr310}}
private ByteArrayAdapter byteArrayAdapter = new ByteArrayAdapter();
public static GsonBuilder createGson() { public static GsonBuilder createGson() {
GsonFireBuilder fireBuilder = new GsonFireBuilder() GsonFireBuilder fireBuilder = new GsonFireBuilder()
@ -105,6 +107,7 @@ public class JSON {
.registerTypeAdapter(OffsetDateTime.class, offsetDateTimeTypeAdapter) .registerTypeAdapter(OffsetDateTime.class, offsetDateTimeTypeAdapter)
.registerTypeAdapter(LocalDate.class, localDateTypeAdapter) .registerTypeAdapter(LocalDate.class, localDateTypeAdapter)
{{/jsr310}} {{/jsr310}}
.registerTypeAdapter(byte[].class, byteArrayAdapter)
.create(); .create();
} }
@ -171,6 +174,34 @@ public class JSON {
} }
} }
/**
* Gson TypeAdapter for Byte Array type
*/
public class ByteArrayAdapter extends TypeAdapter<byte[]> {
@Override
public void write(JsonWriter out, byte[] value) throws IOException {
if (value == null) {
out.nullValue();
} else {
out.value(ByteString.of(value).base64());
}
}
@Override
public byte[] read(JsonReader in) throws IOException {
switch (in.peek()) {
case NULL:
in.nextNull();
return null;
default:
String bytesAsBase64 = in.nextString();
ByteString byteString = ByteString.decodeBase64(bytesAsBase64);
return byteString.toByteArray();
}
}
}
{{#joda}} {{#joda}}
/** /**
* Gson TypeAdapter for Joda DateTime type * Gson TypeAdapter for Joda DateTime type

View File

@ -1 +1 @@
2.4.0-SNAPSHOT 2.4.0-SNAPSHOT

View File

@ -1,24 +1,35 @@
# swagger-petstore-okhttp-gson # swagger-petstore-okhttp-gson
Swagger Petstore
- API version: 1.0.0
This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
*Automatically generated by the [Swagger Codegen](https://github.com/swagger-api/swagger-codegen)*
## Requirements ## Requirements
Building the API client library requires [Maven](https://maven.apache.org/) to be installed. Building the API client library requires:
1. Java 1.7+
2. Maven/Gradle
## Installation ## Installation
To install the API client library to your local Maven repository, simply execute: To install the API client library to your local Maven repository, simply execute:
```shell ```shell
mvn install mvn clean install
``` ```
To deploy it to a remote Maven repository instead, configure the settings of the repository and execute: To deploy it to a remote Maven repository instead, configure the settings of the repository and execute:
```shell ```shell
mvn deploy mvn clean deploy
``` ```
Refer to the [official documentation](https://maven.apache.org/plugins/maven-deploy-plugin/usage.html) for more information. Refer to the [OSSRH Guide](http://central.sonatype.org/pages/ossrh-guide.html) for more information.
### Maven users ### Maven users
@ -26,10 +37,10 @@ Add this dependency to your project's POM:
```xml ```xml
<dependency> <dependency>
<groupId>io.swagger</groupId> <groupId>io.swagger</groupId>
<artifactId>swagger-petstore-okhttp-gson</artifactId> <artifactId>swagger-petstore-okhttp-gson</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
``` ```
@ -45,12 +56,14 @@ compile "io.swagger:swagger-petstore-okhttp-gson:1.0.0"
At first generate the JAR by executing: At first generate the JAR by executing:
mvn package ```shell
mvn clean package
```
Then manually install the following JARs: Then manually install the following JARs:
* target/swagger-petstore-okhttp-gson-1.0.0.jar * `target/swagger-petstore-okhttp-gson-1.0.0.jar`
* target/lib/*.jar * `target/lib/*.jar`
## Getting Started ## Getting Started
@ -61,30 +74,22 @@ Please follow the [installation](#installation) instruction and execute the foll
import io.swagger.client.*; import io.swagger.client.*;
import io.swagger.client.auth.*; import io.swagger.client.auth.*;
import io.swagger.client.model.*; import io.swagger.client.model.*;
import io.swagger.client.api.PetApi; import io.swagger.client.api.AnotherFakeApi;
import java.io.File; import java.io.File;
import java.util.*; import java.util.*;
public class PetApiExample { public class AnotherFakeApiExample {
public static void main(String[] args) { public static void main(String[] args) {
ApiClient defaultClient = Configuration.getDefaultApiClient();
// Configure OAuth2 access token for authorization: petstore_auth
OAuth petstore_auth = (OAuth) defaultClient.getAuthentication("petstore_auth");
petstore_auth.setAccessToken("YOUR ACCESS TOKEN");
PetApi apiInstance = new PetApi();
Pet body = new Pet(); // Pet | Pet object that needs to be added to the store
AnotherFakeApi apiInstance = new AnotherFakeApi();
Client body = new Client(); // Client | client model
try { try {
apiInstance.addPet(body); Client result = apiInstance.testSpecialTags(body);
System.out.println(result);
} catch (ApiException e) { } catch (ApiException e) {
System.err.println("Exception when calling PetApi#addPet"); System.err.println("Exception when calling AnotherFakeApi#testSpecialTags");
e.printStackTrace(); e.printStackTrace();
} }
} }
@ -94,26 +99,32 @@ public class PetApiExample {
## Documentation for API Endpoints ## Documentation for API Endpoints
All URIs are relative to *http://petstore.swagger.io/v2* All URIs are relative to *http://petstore.swagger.io:80/v2*
Class | Method | HTTP request | Description Class | Method | HTTP request | Description
------------ | ------------- | ------------- | ------------- ------------ | ------------- | ------------- | -------------
*AnotherFakeApi* | [**testSpecialTags**](docs/AnotherFakeApi.md#testSpecialTags) | **PATCH** /another-fake/dummy | To test special tags
*FakeApi* | [**fakeOuterBooleanSerialize**](docs/FakeApi.md#fakeOuterBooleanSerialize) | **POST** /fake/outer/boolean |
*FakeApi* | [**fakeOuterCompositeSerialize**](docs/FakeApi.md#fakeOuterCompositeSerialize) | **POST** /fake/outer/composite |
*FakeApi* | [**fakeOuterNumberSerialize**](docs/FakeApi.md#fakeOuterNumberSerialize) | **POST** /fake/outer/number |
*FakeApi* | [**fakeOuterStringSerialize**](docs/FakeApi.md#fakeOuterStringSerialize) | **POST** /fake/outer/string |
*FakeApi* | [**testClientModel**](docs/FakeApi.md#testClientModel) | **PATCH** /fake | To test \&quot;client\&quot; model
*FakeApi* | [**testEndpointParameters**](docs/FakeApi.md#testEndpointParameters) | **POST** /fake | Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트
*FakeApi* | [**testEnumParameters**](docs/FakeApi.md#testEnumParameters) | **GET** /fake | To test enum parameters
*FakeApi* | [**testInlineAdditionalProperties**](docs/FakeApi.md#testInlineAdditionalProperties) | **POST** /fake/inline-additionalProperties | test inline additionalProperties
*FakeApi* | [**testJsonFormData**](docs/FakeApi.md#testJsonFormData) | **GET** /fake/jsonFormData | test json serialization of form data
*FakeClassnameTags123Api* | [**testClassname**](docs/FakeClassnameTags123Api.md#testClassname) | **PATCH** /fake_classname_test | To test class name in snake case
*PetApi* | [**addPet**](docs/PetApi.md#addPet) | **POST** /pet | Add a new pet to the store *PetApi* | [**addPet**](docs/PetApi.md#addPet) | **POST** /pet | Add a new pet to the store
*PetApi* | [**addPetUsingByteArray**](docs/PetApi.md#addPetUsingByteArray) | **POST** /pet?testing_byte_array=true | Fake endpoint to test byte array in body parameter for adding a new pet to the store
*PetApi* | [**deletePet**](docs/PetApi.md#deletePet) | **DELETE** /pet/{petId} | Deletes a pet *PetApi* | [**deletePet**](docs/PetApi.md#deletePet) | **DELETE** /pet/{petId} | Deletes a pet
*PetApi* | [**findPetsByStatus**](docs/PetApi.md#findPetsByStatus) | **GET** /pet/findByStatus | Finds Pets by status *PetApi* | [**findPetsByStatus**](docs/PetApi.md#findPetsByStatus) | **GET** /pet/findByStatus | Finds Pets by status
*PetApi* | [**findPetsByTags**](docs/PetApi.md#findPetsByTags) | **GET** /pet/findByTags | Finds Pets by tags *PetApi* | [**findPetsByTags**](docs/PetApi.md#findPetsByTags) | **GET** /pet/findByTags | Finds Pets by tags
*PetApi* | [**getPetById**](docs/PetApi.md#getPetById) | **GET** /pet/{petId} | Find pet by ID *PetApi* | [**getPetById**](docs/PetApi.md#getPetById) | **GET** /pet/{petId} | Find pet by ID
*PetApi* | [**getPetByIdInObject**](docs/PetApi.md#getPetByIdInObject) | **GET** /pet/{petId}?response=inline_arbitrary_object | Fake endpoint to test inline arbitrary object return by &#39;Find pet by ID&#39;
*PetApi* | [**petPetIdtestingByteArraytrueGet**](docs/PetApi.md#petPetIdtestingByteArraytrueGet) | **GET** /pet/{petId}?testing_byte_array=true | Fake endpoint to test byte array return by &#39;Find pet by ID&#39;
*PetApi* | [**updatePet**](docs/PetApi.md#updatePet) | **PUT** /pet | Update an existing pet *PetApi* | [**updatePet**](docs/PetApi.md#updatePet) | **PUT** /pet | Update an existing pet
*PetApi* | [**updatePetWithForm**](docs/PetApi.md#updatePetWithForm) | **POST** /pet/{petId} | Updates a pet in the store with form data *PetApi* | [**updatePetWithForm**](docs/PetApi.md#updatePetWithForm) | **POST** /pet/{petId} | Updates a pet in the store with form data
*PetApi* | [**uploadFile**](docs/PetApi.md#uploadFile) | **POST** /pet/{petId}/uploadImage | uploads an image *PetApi* | [**uploadFile**](docs/PetApi.md#uploadFile) | **POST** /pet/{petId}/uploadImage | uploads an image
*StoreApi* | [**deleteOrder**](docs/StoreApi.md#deleteOrder) | **DELETE** /store/order/{orderId} | Delete purchase order by ID *StoreApi* | [**deleteOrder**](docs/StoreApi.md#deleteOrder) | **DELETE** /store/order/{order_id} | Delete purchase order by ID
*StoreApi* | [**findOrdersByStatus**](docs/StoreApi.md#findOrdersByStatus) | **GET** /store/findByStatus | Finds orders by status
*StoreApi* | [**getInventory**](docs/StoreApi.md#getInventory) | **GET** /store/inventory | Returns pet inventories by status *StoreApi* | [**getInventory**](docs/StoreApi.md#getInventory) | **GET** /store/inventory | Returns pet inventories by status
*StoreApi* | [**getInventoryInObject**](docs/StoreApi.md#getInventoryInObject) | **GET** /store/inventory?response=arbitrary_object | Fake endpoint to test arbitrary object return by &#39;Get inventory&#39; *StoreApi* | [**getOrderById**](docs/StoreApi.md#getOrderById) | **GET** /store/order/{order_id} | Find purchase order by ID
*StoreApi* | [**getOrderById**](docs/StoreApi.md#getOrderById) | **GET** /store/order/{orderId} | Find purchase order by ID
*StoreApi* | [**placeOrder**](docs/StoreApi.md#placeOrder) | **POST** /store/order | Place an order for a pet *StoreApi* | [**placeOrder**](docs/StoreApi.md#placeOrder) | **POST** /store/order | Place an order for a pet
*UserApi* | [**createUser**](docs/UserApi.md#createUser) | **POST** /user | Create user *UserApi* | [**createUser**](docs/UserApi.md#createUser) | **POST** /user | Create user
*UserApi* | [**createUsersWithArrayInput**](docs/UserApi.md#createUsersWithArrayInput) | **POST** /user/createWithArray | Creates list of users with given input array *UserApi* | [**createUsersWithArrayInput**](docs/UserApi.md#createUsersWithArrayInput) | **POST** /user/createWithArray | Creates list of users with given input array
@ -127,24 +138,59 @@ Class | Method | HTTP request | Description
## Documentation for Models ## Documentation for Models
- [AdditionalPropertiesClass](docs/AdditionalPropertiesClass.md)
- [Animal](docs/Animal.md) - [Animal](docs/Animal.md)
- [Cat](docs/Cat.md) - [AnimalFarm](docs/AnimalFarm.md)
- [ArrayOfArrayOfNumberOnly](docs/ArrayOfArrayOfNumberOnly.md)
- [ArrayOfNumberOnly](docs/ArrayOfNumberOnly.md)
- [ArrayTest](docs/ArrayTest.md)
- [Capitalization](docs/Capitalization.md)
- [Category](docs/Category.md) - [Category](docs/Category.md)
- [Dog](docs/Dog.md) - [ClassModel](docs/ClassModel.md)
- [InlineResponse200](docs/InlineResponse200.md) - [Client](docs/Client.md)
- [EnumArrays](docs/EnumArrays.md)
- [EnumClass](docs/EnumClass.md)
- [EnumTest](docs/EnumTest.md)
- [FormatTest](docs/FormatTest.md)
- [HasOnlyReadOnly](docs/HasOnlyReadOnly.md)
- [MapTest](docs/MapTest.md)
- [MixedPropertiesAndAdditionalPropertiesClass](docs/MixedPropertiesAndAdditionalPropertiesClass.md)
- [Model200Response](docs/Model200Response.md) - [Model200Response](docs/Model200Response.md)
- [ModelApiResponse](docs/ModelApiResponse.md)
- [ModelReturn](docs/ModelReturn.md) - [ModelReturn](docs/ModelReturn.md)
- [Name](docs/Name.md) - [Name](docs/Name.md)
- [NumberOnly](docs/NumberOnly.md)
- [Order](docs/Order.md) - [Order](docs/Order.md)
- [OuterComposite](docs/OuterComposite.md)
- [OuterEnum](docs/OuterEnum.md)
- [Pet](docs/Pet.md) - [Pet](docs/Pet.md)
- [ReadOnlyFirst](docs/ReadOnlyFirst.md)
- [SpecialModelName](docs/SpecialModelName.md) - [SpecialModelName](docs/SpecialModelName.md)
- [Tag](docs/Tag.md) - [Tag](docs/Tag.md)
- [User](docs/User.md) - [User](docs/User.md)
- [Cat](docs/Cat.md)
- [Dog](docs/Dog.md)
## Documentation for Authorization ## Documentation for Authorization
Authentication schemes defined for the API: Authentication schemes defined for the API:
### api_key
- **Type**: API key
- **API key parameter name**: api_key
- **Location**: HTTP header
### api_key_query
- **Type**: API key
- **API key parameter name**: api_key_query
- **Location**: URL query string
### http_basic_test
- **Type**: HTTP basic authentication
### petstore_auth ### petstore_auth
- **Type**: OAuth - **Type**: OAuth
@ -154,44 +200,10 @@ Authentication schemes defined for the API:
- write:pets: modify pets in your account - write:pets: modify pets in your account
- read:pets: read your pets - read:pets: read your pets
### test_api_client_id
- **Type**: API key
- **API key parameter name**: x-test_api_client_id
- **Location**: HTTP header
### test_api_client_secret
- **Type**: API key
- **API key parameter name**: x-test_api_client_secret
- **Location**: HTTP header
### api_key
- **Type**: API key
- **API key parameter name**: api_key
- **Location**: HTTP header
### test_http_basic
- **Type**: HTTP basic authentication
### test_api_key_query
- **Type**: API key
- **API key parameter name**: test_api_key_query
- **Location**: URL query string
### test_api_key_header
- **Type**: API key
- **API key parameter name**: test_api_key_header
- **Location**: HTTP header
## Recommendation ## Recommendation
It's recommended to create an instance of `ApiClient` per thread in a multithreaded environment to avoid any potential issue. It's recommended to create an instance of `ApiClient` per thread in a multithreaded environment to avoid any potential issues.
## Author ## Author

View File

@ -91,6 +91,14 @@ if(hasProperty('target') && target == 'android') {
main = System.getProperty('mainClass') main = System.getProperty('mainClass')
classpath = sourceSets.main.runtimeClasspath classpath = sourceSets.main.runtimeClasspath
} }
compileJava {
options.encoding = "UTF8"
}
compileTestJava {
options.encoding = "UTF8"
}
} }
dependencies { dependencies {

View File

@ -1,12 +0,0 @@
# ApiResponse
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**code** | **Integer** | | [optional]
**type** | **String** | | [optional]
**message** | **String** | | [optional]

View File

@ -1,52 +0,0 @@
# Fake_classname_tags123Api
All URIs are relative to *http://petstore.swagger.io/v2*
Method | HTTP request | Description
------------- | ------------- | -------------
[**testClassname**](Fake_classname_tags123Api.md#testClassname) | **PATCH** /fake_classname_test | To test class name in snake case
<a name="testClassname"></a>
# **testClassname**
> Client testClassname(body)
To test class name in snake case
### Example
```java
// Import classes:
//import io.swagger.client.ApiException;
//import io.swagger.client.api.Fake_classname_tags123Api;
Fake_classname_tags123Api apiInstance = new Fake_classname_tags123Api();
Client body = new Client(); // Client | client model
try {
Client result = apiInstance.testClassname(body);
System.out.println(result);
} catch (ApiException e) {
System.err.println("Exception when calling Fake_classname_tags123Api#testClassname");
e.printStackTrace();
}
```
### Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**body** | [**Client**](Client.md)| client model |
### Return type
[**Client**](Client.md)
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: application/json
- **Accept**: application/json

View File

@ -1,52 +0,0 @@
# FakeclassnametagsApi
All URIs are relative to *http://petstore.swagger.io/v2*
Method | HTTP request | Description
------------- | ------------- | -------------
[**testClassname**](FakeclassnametagsApi.md#testClassname) | **PATCH** /fake_classname_test | To test class name in snake case
<a name="testClassname"></a>
# **testClassname**
> Client testClassname(body)
To test class name in snake case
### Example
```java
// Import classes:
//import io.swagger.client.ApiException;
//import io.swagger.client.api.FakeclassnametagsApi;
FakeclassnametagsApi apiInstance = new FakeclassnametagsApi();
Client body = new Client(); // Client | client model
try {
Client result = apiInstance.testClassname(body);
System.out.println(result);
} catch (ApiException e) {
System.err.println("Exception when calling FakeclassnametagsApi#testClassname");
e.printStackTrace();
}
```
### Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**body** | [**Client**](Client.md)| client model |
### Return type
[**Client**](Client.md)
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: application/json
- **Accept**: application/json

View File

@ -1,24 +0,0 @@
# InlineResponse200
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**photoUrls** | **List&lt;String&gt;** | | [optional]
**name** | **String** | | [optional]
**id** | **Long** | |
**category** | **Object** | | [optional]
**tags** | [**List&lt;Tag&gt;**](Tag.md) | | [optional]
**status** | [**StatusEnum**](#StatusEnum) | pet status in the store | [optional]
<a name="StatusEnum"></a>
## Enum: StatusEnum
Name | Value
---- | -----
AVAILABLE | available
PENDING | pending
SOLD | sold

View File

@ -1,9 +0,0 @@
# OuterBoolean
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------

View File

@ -1,9 +0,0 @@
# OuterNumber
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------

View File

@ -1,9 +0,0 @@
# OuterString
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------

View File

@ -28,6 +28,7 @@ import org.threeten.bp.OffsetDateTime;
import org.threeten.bp.format.DateTimeFormatter; import org.threeten.bp.format.DateTimeFormatter;
import io.swagger.client.model.*; import io.swagger.client.model.*;
import okio.ByteString;
import java.io.IOException; import java.io.IOException;
import java.io.StringReader; import java.io.StringReader;
@ -46,6 +47,7 @@ public class JSON {
private SqlDateTypeAdapter sqlDateTypeAdapter = new SqlDateTypeAdapter(); private SqlDateTypeAdapter sqlDateTypeAdapter = new SqlDateTypeAdapter();
private OffsetDateTimeTypeAdapter offsetDateTimeTypeAdapter = new OffsetDateTimeTypeAdapter(); private OffsetDateTimeTypeAdapter offsetDateTimeTypeAdapter = new OffsetDateTimeTypeAdapter();
private LocalDateTypeAdapter localDateTypeAdapter = new LocalDateTypeAdapter(); private LocalDateTypeAdapter localDateTypeAdapter = new LocalDateTypeAdapter();
private ByteArrayAdapter byteArrayAdapter = new ByteArrayAdapter();
public static GsonBuilder createGson() { public static GsonBuilder createGson() {
GsonFireBuilder fireBuilder = new GsonFireBuilder() GsonFireBuilder fireBuilder = new GsonFireBuilder()
@ -87,6 +89,7 @@ public class JSON {
.registerTypeAdapter(java.sql.Date.class, sqlDateTypeAdapter) .registerTypeAdapter(java.sql.Date.class, sqlDateTypeAdapter)
.registerTypeAdapter(OffsetDateTime.class, offsetDateTimeTypeAdapter) .registerTypeAdapter(OffsetDateTime.class, offsetDateTimeTypeAdapter)
.registerTypeAdapter(LocalDate.class, localDateTypeAdapter) .registerTypeAdapter(LocalDate.class, localDateTypeAdapter)
.registerTypeAdapter(byte[].class, byteArrayAdapter)
.create(); .create();
} }
@ -153,6 +156,34 @@ public class JSON {
} }
} }
/**
* Gson TypeAdapter for Byte Array type
*/
public class ByteArrayAdapter extends TypeAdapter<byte[]> {
@Override
public void write(JsonWriter out, byte[] value) throws IOException {
if (value == null) {
out.nullValue();
} else {
out.value(ByteString.of(value).base64());
}
}
@Override
public byte[] read(JsonReader in) throws IOException {
switch (in.peek()) {
case NULL:
in.nextNull();
return null;
default:
String bytesAsBase64 = in.nextString();
ByteString byteString = ByteString.decodeBase64(bytesAsBase64);
return byteString.toByteArray();
}
}
}
/** /**
* Gson TypeAdapter for JSR310 OffsetDateTime type * Gson TypeAdapter for JSR310 OffsetDateTime type
*/ */

View File

@ -6,6 +6,7 @@ import io.swagger.client.model.Order;
import java.lang.Exception; import java.lang.Exception;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Calendar; import java.util.Calendar;
@ -13,6 +14,7 @@ import java.util.Date;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
import java.util.TimeZone; import java.util.TimeZone;
import okio.ByteString;
import org.junit.*; import org.junit.*;
import org.threeten.bp.LocalDate; import org.threeten.bp.LocalDate;
import org.threeten.bp.OffsetDateTime; import org.threeten.bp.OffsetDateTime;
@ -41,7 +43,7 @@ public class JSONTest {
assertEquals(str, json.serialize(date)); assertEquals(str, json.serialize(date));
assertEquals(json.deserialize(str, java.sql.Date.class), date); assertEquals(json.deserialize(str, java.sql.Date.class), date);
assertEquals(json.deserialize("\"2015-11-07T03:49:09.356+00:00\"", java.sql.Date.class).toString(), date.toString()); assertEquals(json.deserialize("\"2015-11-07T03:49:09.356" + getCurrentTimezoneOffset() + "\"", java.sql.Date.class).toString(), date.toString());
// custom date format: without day // custom date format: without day
DateFormat format = new SimpleDateFormat("yyyy-MM"); DateFormat format = new SimpleDateFormat("yyyy-MM");
@ -146,4 +148,54 @@ public class JSONTest {
Order o = json.deserialize(str, type); Order o = json.deserialize(str, type);
assertEquals(dateStr, datetimeFormat.format(o.getShipDate())); assertEquals(dateStr, datetimeFormat.format(o.getShipDate()));
} }
@Test
public void testByteArrayTypeAdapterSerialization() {
// Arrange
final String expectedBytesAsString = "Let's pretend this a jpg or something";
final byte[] expectedBytes = expectedBytesAsString.getBytes(StandardCharsets.UTF_8);
// Act
String serializedBytesWithQuotes = json.serialize(expectedBytes);
// Assert
String serializedBytes = serializedBytesWithQuotes.substring(1, serializedBytesWithQuotes.length() - 1);
if (json.getGson().htmlSafe()) {
serializedBytes = serializedBytes.replaceAll("\\\\u003d", "=");
}
ByteString actualAsByteString = ByteString.decodeBase64(serializedBytes);
byte[] actualBytes = actualAsByteString.toByteArray();
assertEquals(expectedBytesAsString, new String(actualBytes, StandardCharsets.UTF_8));
}
@Test
public void testByteArrayTypeAdapterDeserialization() {
// Arrange
final String expectedBytesAsString = "Let's pretend this a jpg or something";
final byte[] expectedBytes = expectedBytesAsString.getBytes(StandardCharsets.UTF_8);
final ByteString expectedByteString = ByteString.of(expectedBytes);
final String serializedBytes = expectedByteString.base64();
final String serializedBytesWithQuotes = "\"" + serializedBytes + "\"";
Type type = new TypeToken<byte[]>() { }.getType();
// Act
byte[] actualDeserializedBytes = json.deserialize(serializedBytesWithQuotes, type);
// Assert
assertEquals(expectedBytesAsString, new String(actualDeserializedBytes, StandardCharsets.UTF_8));
}
// Obtained 22JAN2018 from stackoverflow answer by PuguaSoft https://stackoverflow.com/questions/11399491/java-timezone-offset
// Direct link https://stackoverflow.com/a/16680815/3166133
public static String getCurrentTimezoneOffset() {
TimeZone tz = TimeZone.getDefault();
Calendar cal = GregorianCalendar.getInstance(tz);
int offsetInMillis = tz.getOffset(cal.getTimeInMillis());
String offset = String.format("%02d:%02d", Math.abs(offsetInMillis / 3600000), Math.abs((offsetInMillis / 60000) % 60));
offset = (offsetInMillis >= 0 ? "+" : "-") + offset;
return offset;
}
} }

View File

@ -1,9 +1,26 @@
/*
* Swagger Petstore
* This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
*
* OpenAPI spec version: 1.0.0
* Contact: apiteam@swagger.io
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
package io.swagger.client.api; package io.swagger.client.api;
import io.swagger.client.ApiException; import io.swagger.client.ApiException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Date; import io.swagger.client.model.Client;
import org.threeten.bp.LocalDate;
import org.threeten.bp.OffsetDateTime;
import io.swagger.client.model.OuterComposite;
import org.junit.Test; import org.junit.Test;
import org.junit.Ignore;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -13,11 +30,92 @@ import java.util.Map;
/** /**
* API tests for FakeApi * API tests for FakeApi
*/ */
@Ignore
public class FakeApiTest { public class FakeApiTest {
private final FakeApi api = new FakeApi(); private final FakeApi api = new FakeApi();
/**
*
*
* Test serialization of outer boolean types
*
* @throws ApiException
* if the Api call fails
*/
@Test
public void fakeOuterBooleanSerializeTest() throws ApiException {
Boolean body = null;
Boolean response = api.fakeOuterBooleanSerialize(body);
// TODO: test validations
}
/**
*
*
* Test serialization of object with outer number type
*
* @throws ApiException
* if the Api call fails
*/
@Test
public void fakeOuterCompositeSerializeTest() throws ApiException {
OuterComposite body = null;
OuterComposite response = api.fakeOuterCompositeSerialize(body);
// TODO: test validations
}
/**
*
*
* Test serialization of outer number types
*
* @throws ApiException
* if the Api call fails
*/
@Test
public void fakeOuterNumberSerializeTest() throws ApiException {
BigDecimal body = null;
BigDecimal response = api.fakeOuterNumberSerialize(body);
// TODO: test validations
}
/**
*
*
* Test serialization of outer string types
*
* @throws ApiException
* if the Api call fails
*/
@Test
public void fakeOuterStringSerializeTest() throws ApiException {
String body = null;
String response = api.fakeOuterStringSerialize(body);
// TODO: test validations
}
/**
* To test \&quot;client\&quot; model
*
* To test \&quot;client\&quot; model
*
* @throws ApiException
* if the Api call fails
*/
@Test
public void testClientModelTest() throws ApiException {
Client body = null;
Client response = api.testClientModel(body);
// TODO: test validations
}
/** /**
* Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트 * Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트
* *
@ -30,17 +128,75 @@ public class FakeApiTest {
public void testEndpointParametersTest() throws ApiException { public void testEndpointParametersTest() throws ApiException {
BigDecimal number = null; BigDecimal number = null;
Double _double = null; Double _double = null;
String string = null; String patternWithoutDelimiter = null;
byte[] _byte = null; byte[] _byte = null;
Integer integer = null; Integer integer = null;
Integer int32 = null; Integer int32 = null;
Long int64 = null; Long int64 = null;
Float _float = null; Float _float = null;
String string = null;
byte[] binary = null; byte[] binary = null;
Date date = null; LocalDate date = null;
Date dateTime = null; OffsetDateTime dateTime = null;
String password = null; String password = null;
// api.testEndpointParameters(number, _double, string, _byte, integer, int32, int64, _float, binary, date, dateTime, password); String paramCallback = null;
api.testEndpointParameters(number, _double, patternWithoutDelimiter, _byte, integer, int32, int64, _float, string, binary, date, dateTime, password, paramCallback);
// TODO: test validations
}
/**
* To test enum parameters
*
* To test enum parameters
*
* @throws ApiException
* if the Api call fails
*/
@Test
public void testEnumParametersTest() throws ApiException {
List<String> enumFormStringArray = null;
String enumFormString = null;
List<String> enumHeaderStringArray = null;
String enumHeaderString = null;
List<String> enumQueryStringArray = null;
String enumQueryString = null;
Integer enumQueryInteger = null;
Double enumQueryDouble = null;
api.testEnumParameters(enumFormStringArray, enumFormString, enumHeaderStringArray, enumHeaderString, enumQueryStringArray, enumQueryString, enumQueryInteger, enumQueryDouble);
// TODO: test validations
}
/**
* test inline additionalProperties
*
*
*
* @throws ApiException
* if the Api call fails
*/
@Test
public void testInlineAdditionalPropertiesTest() throws ApiException {
Object param = null;
api.testInlineAdditionalProperties(param);
// TODO: test validations
}
/**
* test json serialization of form data
*
*
*
* @throws ApiException
* if the Api call fails
*/
@Test
public void testJsonFormDataTest() throws ApiException {
String param = null;
String param2 = null;
api.testJsonFormData(param, param2);
// TODO: test validations // TODO: test validations
} }

View File

@ -87,11 +87,11 @@ public class StoreApiTest {
order.setComplete(true); order.setComplete(true);
try { try {
Field idField = Order.class.getDeclaredField("id"); Field idField = Order.class.getDeclaredField("id");
idField.setAccessible(true); idField.setAccessible(true);
idField.set(order, TestUtils.nextId()); idField.set(order, TestUtils.nextId());
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
return order; return order;