diff --git a/CI/.drone.yml b/CI/.drone.yml index cd195bb8c8d..5a7f9967c36 100644 --- a/CI/.drone.yml +++ b/CI/.drone.yml @@ -13,7 +13,7 @@ steps: commands: - (cd samples/client/petstore/dart-jaguar/openapi && pub get && pub run build_runner build --delete-conflicting-outputs) - (cd samples/client/petstore/dart-jaguar/flutter_petstore/openapi && pub get && pub run build_runner build --delete-conflicting-outputs) - - (cd samples/client/petstore/dart2/openapi && pub get && pub run test) + - (cd samples/client/petstore/dart2/petstore && pub get && pub run test) # test Java 11 HTTP client - name: java11-test image: openjdk:11.0 diff --git a/bin/dart2-petstore.sh b/bin/dart2-petstore.sh index e089c52abbb..e309802ed3a 100755 --- a/bin/dart2-petstore.sh +++ b/bin/dart2-petstore.sh @@ -29,5 +29,5 @@ fi export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties" # Generate client -ags="generate -t modules/openapi-generator/src/main/resources/dart2 -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g dart -o samples/client/petstore/dart2/openapi --additional-properties hideGenerationTimestamp=true $@" +ags="generate -t modules/openapi-generator/src/main/resources/dart2 -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g dart -o samples/client/petstore/dart2/petstore_client_lib --additional-properties hideGenerationTimestamp=true $@" java $JAVA_OPTS -jar $executable $ags diff --git a/samples/client/petstore/dart2/petstore/README.md b/samples/client/petstore/dart2/petstore/README.md index 2adfc09c8a3..2139c301745 100644 --- a/samples/client/petstore/dart2/petstore/README.md +++ b/samples/client/petstore/dart2/petstore/README.md @@ -1,3 +1,29 @@ +# Background + +## Current state of tests + +TL;DR currently the only tests are e2e tests that were adapted to use a faked http client. While pushing data around as a smoke test has some value, more testing is required. In particular we need comprehensive unit/integration tests. + +- an old set of e2e tests are skipped for CI, as they hit a live endpoint and so are inherently flaky + - `pet_test.dart` + - `store_test.dart` + - `user_test.dart` +- the above set of tests were adapted to use a faked http client + - the tests are not really well suited to being used with a stubbed client, many are basically just testing the endpoint logic + - while not a great set of tests, they do have some value as a smoke test for template changes +- the adapted tests and files that contain test data: + - `pet_test_fake_client.dart` + - `store_test_fake_client.dart` + - `user_test_fake_client.dart` + - `fake_client.dart` + - `file_upload_response.json` + +## Assumptions + +- the tests will be run as part of CI and so have access to dart:io + +# Running + ## If not already done, resolve dependencies `pub get` @@ -8,4 +34,4 @@ ## To run all tests in the test folder: -`pub run test test` \ No newline at end of file +`pub run test` diff --git a/samples/client/petstore/dart2/petstore/pubspec.lock b/samples/client/petstore/dart2/petstore/pubspec.lock new file mode 100644 index 00000000000..78daa43da5d --- /dev/null +++ b/samples/client/petstore/dart2/petstore/pubspec.lock @@ -0,0 +1,355 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + analyzer: + dependency: transitive + description: + name: analyzer + url: "https://pub.dartlang.org" + source: hosted + version: "0.38.4" + args: + dependency: transitive + description: + name: args + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.2" + async: + dependency: transitive + description: + name: async + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.5" + charcode: + dependency: transitive + description: + name: charcode + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.2" + collection: + dependency: "direct dev" + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.14.12" + convert: + dependency: transitive + description: + name: convert + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.1" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.3" + csslib: + dependency: transitive + description: + name: csslib + url: "https://pub.dartlang.org" + source: hosted + version: "0.16.1" + front_end: + dependency: transitive + description: + name: front_end + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.26" + glob: + dependency: transitive + description: + name: glob + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.7" + html: + dependency: transitive + description: + name: html + url: "https://pub.dartlang.org" + source: hosted + version: "0.14.0+2" + http: + dependency: "direct dev" + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.0+2" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.3" + io: + dependency: transitive + description: + name: io + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.3" + js: + dependency: transitive + description: + name: js + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.1+1" + kernel: + dependency: transitive + description: + name: kernel + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.26" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.5" + meta: + dependency: transitive + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.7" + mime: + dependency: transitive + description: + name: mime + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.6+3" + mockito: + dependency: "direct dev" + description: + name: mockito + url: "https://pub.dartlang.org" + source: hosted + version: "4.1.1" + multi_server_socket: + dependency: transitive + description: + name: multi_server_socket + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" + node_preamble: + dependency: transitive + description: + name: node_preamble + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.8" + openapi: + dependency: "direct main" + description: + path: "../petstore_client_lib" + relative: true + source: path + version: "1.0.0" + package_config: + dependency: transitive + description: + name: package_config + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + package_resolver: + dependency: transitive + description: + name: package_resolver + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.10" + path: + dependency: transitive + description: + name: path + url: "https://pub.dartlang.org" + source: hosted + version: "1.6.4" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.0+1" + pool: + dependency: transitive + description: + name: pool + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.0" + pub_semver: + dependency: transitive + description: + name: pub_semver + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.2" + shelf: + dependency: transitive + description: + name: shelf + url: "https://pub.dartlang.org" + source: hosted + version: "0.7.5" + shelf_packages_handler: + dependency: transitive + description: + name: shelf_packages_handler + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + shelf_static: + dependency: transitive + description: + name: shelf_static + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.8" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.3" + source_map_stack_trace: + dependency: transitive + description: + name: source_map_stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.5" + source_maps: + dependency: transitive + description: + name: source_maps + url: "https://pub.dartlang.org" + source: hosted + version: "0.10.8" + source_span: + dependency: transitive + description: + name: source_span + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.5" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.9.3" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.5" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + test: + dependency: "direct dev" + description: + name: test + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.0" + test_api: + dependency: transitive + description: + name: test_api + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.8" + test_core: + dependency: transitive + description: + name: test_core + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.10" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.6" + vm_service: + dependency: transitive + description: + name: vm_service + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + watcher: + dependency: transitive + description: + name: watcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.7+12" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.15" + yaml: + dependency: transitive + description: + name: yaml + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.0" +sdks: + dart: ">=2.5.0 <3.0.0" diff --git a/samples/client/petstore/dart2/petstore/pubspec.yaml b/samples/client/petstore/dart2/petstore/pubspec.yaml index 1d77c96e46a..f2630175093 100644 --- a/samples/client/petstore/dart2/petstore/pubspec.yaml +++ b/samples/client/petstore/dart2/petstore/pubspec.yaml @@ -2,9 +2,12 @@ name: petstore_client version: 1.0.0 description: Petstore client using OpenAPI library environment: - sdk: '>=2.0.0 <3.0.0' + sdk: '>=2.5.0 <3.0.0' dependencies: openapi: - path: ../openapi + path: ../petstore_client_lib dev_dependencies: - test: ^1.6.8 + test: ^1.8.0 + mockito: ^4.1.1 + http: ^0.12.0 + collection: ^1.14.12 diff --git a/samples/client/petstore/dart2/petstore/test/fake_client.dart b/samples/client/petstore/dart2/petstore/test/fake_client.dart new file mode 100644 index 00000000000..82daf74108e --- /dev/null +++ b/samples/client/petstore/dart2/petstore/test/fake_client.dart @@ -0,0 +1,133 @@ +import 'dart:convert'; + +import 'package:collection/collection.dart'; +import 'package:http/http.dart'; +import 'package:mockito/mockito.dart'; + +/// A fake client that checks for expected values and returns given responses +/// +/// Checks for the expected values (url, headers, body) and throws if not found +/// +/// If exception is non-null the request will throw the exception, after other +/// checks are performed +class FakeClient extends Fake implements Client { + FakeClient({ + this.throwException, + this.expectedPostRequestBody, + this.postResponseBody, + this.expectedGetRequestBody, + this.getResponseBody, + this.deleteResponseBody, + this.expectedPutRequestBody, + this.putResponseBody, + this.sendResponseBody, + this.expectedUrl, + this.expectedHeaders = const {'Content-Type': 'application/json'}, + }); + + Exception throwException; + Object expectedPostRequestBody; + String postResponseBody; + String expectedGetRequestBody; + String getResponseBody; + String deleteResponseBody; + String expectedPutRequestBody; + String putResponseBody; + String sendResponseBody; + String expectedUrl; + Map expectedHeaders; + + @override + Future post(url, + {Map headers, body, Encoding encoding}) async { + // check that the request was made with expected values + if (url != expectedUrl) { + throw StateError( + 'POST was called with unexpected url: ${url} should be ${expectedUrl}'); + } + if (!MapEquality().equals(headers, expectedHeaders)) { + throw StateError( + 'POST was called with unexpected headers: ${headers} should be ${expectedHeaders}'); + } + // currently we only expect Map (and subtypes) or Strings + if (body is Map) { + if (!MapEquality().equals(body, expectedPostRequestBody)) { + throw StateError( + 'POST was called with unexpected body: ${body} should be ${expectedPostRequestBody}'); + } + } else if (body != expectedPostRequestBody) { + throw StateError( + 'POST was called with unexpected body: ${body} should be ${expectedPostRequestBody}'); + } + + // throw if set to throw + if (throwException != null) throw throwException; + + return Response(postResponseBody, 200); + } + + @override + Future get(url, {Map headers}) async { + // check that the request was made with expected values + if (url != expectedUrl) { + throw StateError( + 'GET was called with unexpected url: ${url} should be ${expectedUrl}'); + } + if (!MapEquality().equals(headers, expectedHeaders)) { + throw StateError( + 'GET was called with unexpected headers: ${headers} should be ${expectedHeaders}'); + } + + // throw if set to throw + if (throwException != null) throw throwException; + + return Response(getResponseBody, 200); + } + + @override + Future delete(url, {Map headers}) async { + // check that the request was made with expected values + if (url != expectedUrl) { + throw StateError( + 'DELETE was called with unexpected url: ${url} should be ${expectedUrl}'); + } + if (!MapEquality().equals(headers, expectedHeaders)) { + throw StateError( + 'DELETE was called with unexpected headers: ${headers} should be ${expectedHeaders}'); + } + + // throw if set to throw + if (throwException != null) throw throwException; + + return Response(deleteResponseBody, 200); + } + + @override + Future put(url, + {Map headers, body, Encoding encoding}) async { + // check that the request was made with expected values + if (url != expectedUrl) { + throw StateError( + 'PUT was called with unexpected url: ${url} should be ${expectedUrl}'); + } + if (!MapEquality().equals(headers, expectedHeaders)) { + throw StateError( + 'PUT was called with unexpected headers: ${headers} should be ${expectedHeaders}'); + } + if (body != expectedPutRequestBody) { + throw StateError( + 'PUT was called with unexpected body: ${body} should be ${expectedPutRequestBody}'); + } + + // throw if set to throw + if (throwException != null) throw throwException; + + return Response(putResponseBody, 200); + } + + @override + Future send(BaseRequest request) async { + List bytes = utf8.encode(sendResponseBody); + return StreamedResponse(Stream.fromIterable([bytes]), 200); + } +} diff --git a/samples/client/petstore/dart2/petstore/test/file_upload_response.json b/samples/client/petstore/dart2/petstore/test/file_upload_response.json new file mode 100644 index 00000000000..8855b00d9e3 --- /dev/null +++ b/samples/client/petstore/dart2/petstore/test/file_upload_response.json @@ -0,0 +1 @@ +{"code":200,"type":"unknown","message":"additionalMetadata: \nFile uploaded to ./null, 4 bytes"} \ No newline at end of file diff --git a/samples/client/petstore/dart2/petstore/test/inventory_response.json b/samples/client/petstore/dart2/petstore/test/inventory_response.json new file mode 100644 index 00000000000..b4388d1e7b3 --- /dev/null +++ b/samples/client/petstore/dart2/petstore/test/inventory_response.json @@ -0,0 +1 @@ +{"mine":1,"sold":18,"string":568,"Dead":2,"test":2,"Nonavailable":1,"custom":3,"pending":20,"available":2212,"notAvailable":26,"avaiflable":1,"AVAILABLE":1,"swimming":1,"availablee":2,"success":1,"105":1,"missing":11,"disabled":1,"Available":1,"]]>":1} \ No newline at end of file diff --git a/samples/client/petstore/dart2/petstore/test/pet_faked_client_test.dart b/samples/client/petstore/dart2/petstore/test/pet_faked_client_test.dart new file mode 100644 index 00000000000..c0374e8c8b1 --- /dev/null +++ b/samples/client/petstore/dart2/petstore/test/pet_faked_client_test.dart @@ -0,0 +1,231 @@ +import 'dart:io'; + +import 'package:http/http.dart'; +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +import 'fake_client.dart'; +import 'random_id.dart'; + +void main() { + final petApi = PetApi(); + + Pet makePet({ + int id = 1234, + String name = 'Fluffy', + String status = '', + }) { + final category = Category() + ..id = 1234 + ..name = 'eyeColor'; + final tags = [ + Tag() + ..id = 1234 + ..name = 'New York', + Tag() + ..id = 124321 + ..name = 'Jose' + ]; + return Pet() + ..id = id + ..category = category + ..tags = tags + ..name = name + ..status = status + ..photoUrls = ['https://petstore.com/sample/photo1.jpg']; + } + + /// Setup the fake client then call [petApi.addPet] + Future addPet(Pet pet) { + petApi.apiClient.client = FakeClient( + expectedUrl: 'http://petstore.swagger.io/v2/pet', + expectedPostRequestBody: petApi.apiClient.serialize(pet), + postResponseBody: '', + ); + return petApi.addPet(pet); + } + + group('Pet API with faked client', () { + test('adds a new pet and gets it by id', () async { + final id = newId(); + final newPet = makePet(id: id); + + // use the pet api to add a pet + petApi.apiClient.client = FakeClient( + expectedUrl: 'http://petstore.swagger.io/v2/pet', + expectedPostRequestBody: petApi.apiClient.serialize(newPet), + postResponseBody: '', + ); + await petApi.addPet(newPet); + + // retrieve the same pet by id + petApi.apiClient.client = FakeClient( + expectedUrl: 'http://petstore.swagger.io/v2/pet/$id', + getResponseBody: petApi.apiClient.serialize(newPet), + ); + final retrievedPet = await petApi.getPetById(id); + + // check that the retrieved id is as expected + expect(retrievedPet.id, equals(id)); + }); + + test('doesn\'t get non-existing pet by id', () { + final id = newId(); + petApi.apiClient.client = FakeClient( + expectedUrl: 'http://petstore.swagger.io/v2/pet/$id', + throwException: ApiException(400, 'not found'), + ); + expect( + petApi.getPetById(id), throwsA(equals(TypeMatcher()))); + }); + + test('deletes existing pet by id', () async { + final id = newId(); + Pet newPet = makePet(id: id); + + // add a new pet + petApi.apiClient.client = FakeClient( + expectedUrl: 'http://petstore.swagger.io/v2/pet', + expectedPostRequestBody: petApi.apiClient.serialize(newPet), + postResponseBody: '', + ); + await petApi.addPet(newPet); + + // delete the pet + petApi.apiClient.client = FakeClient( + expectedUrl: 'http://petstore.swagger.io/v2/pet/$id', + expectedHeaders: { + 'Content-Type': 'application/json', + 'api_key': 'special-key' + }, + deleteResponseBody: '', + ); + await petApi.deletePet(id, apiKey: 'special-key'); + + // check for the deleted pet + petApi.apiClient.client = FakeClient( + expectedUrl: 'http://petstore.swagger.io/v2/pet/$id', + throwException: ApiException(400, 'Not found'), + ); + expect( + petApi.getPetById(id), throwsA(equals(TypeMatcher()))); + }); + + test('updates pet with form', () async { + final id = newId(); + final newPet = makePet(id: id, name: 'Snowy'); + + // add a new pet + petApi.apiClient.client = FakeClient( + expectedUrl: 'http://petstore.swagger.io/v2/pet', + expectedPostRequestBody: petApi.apiClient.serialize(newPet), + postResponseBody: '', + ); + await petApi.addPet(newPet); + + final multipartRequest = MultipartRequest(null, null); + multipartRequest.fields['name'] = 'Doge'; + multipartRequest.fields['status'] = ''; + + // update with form + petApi.apiClient.client = FakeClient( + expectedUrl: 'http://petstore.swagger.io/v2/pet/$id', + expectedHeaders: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + expectedPostRequestBody: {'name': 'Doge', 'status': ''}, + postResponseBody: '', + ); + await petApi.updatePetWithForm(id, name: 'Doge', status: ''); + + // check update worked + newPet.name = 'Doge'; + petApi.apiClient.client = FakeClient( + expectedUrl: 'http://petstore.swagger.io/v2/pet/$id', + getResponseBody: petApi.apiClient.serialize(newPet), + ); + final pet = await petApi.getPetById(id); + expect(pet.name, equals('Doge')); + }); + + test('updates existing pet', () async { + final id = newId(); + final name = 'Snowy'; + final newPet = makePet(id: id); + final updatePet = makePet(id: id, name: name); + + // add a new pet + petApi.apiClient.client = FakeClient( + expectedUrl: 'http://petstore.swagger.io/v2/pet', + expectedPostRequestBody: petApi.apiClient.serialize(newPet), + postResponseBody: '', + ); + await petApi.addPet(newPet); + + // update the same pet + petApi.apiClient.client = FakeClient( + expectedUrl: 'http://petstore.swagger.io/v2/pet', + expectedPutRequestBody: petApi.apiClient.serialize(updatePet), + putResponseBody: '', + ); + await petApi.updatePet(updatePet); + + // check update worked + petApi.apiClient.client = FakeClient( + expectedUrl: 'http://petstore.swagger.io/v2/pet/$id', + getResponseBody: petApi.apiClient.serialize(updatePet), + ); + final pet = await petApi.getPetById(id); + expect(pet.name, equals(name)); + }); + + test('finds pets by status', () async { + final id1 = newId(); + final id2 = newId(); + final id3 = newId(); + final status = 'available'; + final pet1 = makePet(id: id1, status: status); + final pet2 = makePet(id: id2, status: status); + final pet3 = makePet(id: id3, status: 'sold'); + + return Future.wait([addPet(pet1), addPet(pet2), addPet(pet3)]) + .then((_) async { + // retrieve pets by status + petApi.apiClient.client = FakeClient( + expectedUrl: + 'http://petstore.swagger.io/v2/pet/findByStatus?status=$status', + getResponseBody: petApi.apiClient.serialize([pet1, pet2]), + ); + final pets = await petApi.findPetsByStatus([status]); + final petIds = pets.map((pet) => pet.id).toList(); + expect(petIds, contains(id1)); + expect(petIds, contains(id2)); + expect(petIds, isNot(contains(id3))); + }); + }); + + test('uploads a pet image', () async { + final id = newId(); + final newPet = makePet(id: id); + // get some test data (recorded from live response) + final uploadResponse = + await File('test/file_upload_response.json').readAsString(); + + // add a new pet + petApi.apiClient.client = FakeClient( + expectedUrl: 'http://petstore.swagger.io/v2/pet', + expectedPostRequestBody: petApi.apiClient.serialize(newPet), + postResponseBody: '', + ); + await petApi.addPet(newPet); + + petApi.apiClient.client = FakeClient( + expectedUrl: 'http://petstore.swagger.io/v2/pet', + sendResponseBody: uploadResponse, + ); + final file = + new MultipartFile.fromBytes('file', [104, 101, 108, 108, 111]); + await petApi.uploadFile(id, additionalMetadata: '', file: file); + }); + }); +} diff --git a/samples/client/petstore/dart2/petstore/test/pet_test.dart b/samples/client/petstore/dart2/petstore/test/pet_test.dart index 3671469c7b7..b978022e565 100644 --- a/samples/client/petstore/dart2/petstore/test/pet_test.dart +++ b/samples/client/petstore/dart2/petstore/test/pet_test.dart @@ -7,7 +7,7 @@ import 'package:test/test.dart'; import 'random_id.dart'; void main() { - var petApi = new PetApi(); + var petApi = PetApi(); Pet makePet({ int id = 1234, @@ -34,7 +34,7 @@ void main() { ..photoUrls = ['https://petstore.com/sample/photo1.jpg']; } - group('Pet API ', () { + group('Pet API with live client', () { test('adds a new pet and gets it by id', () async { var id = newId(); await petApi.addPet(makePet(id: id)); @@ -99,5 +99,5 @@ void main() { var file = new MultipartFile.fromBytes('file', [104, 101, 108, 108, 111]); await petApi.uploadFile(id, additionalMetadata: '', file: file); }); - }); + }, skip: 'e2e tests for CI'); } diff --git a/samples/client/petstore/dart2/petstore/test/store_faked_client_test.dart b/samples/client/petstore/dart2/petstore/test/store_faked_client_test.dart new file mode 100644 index 00000000000..dce22ec58b2 --- /dev/null +++ b/samples/client/petstore/dart2/petstore/test/store_faked_client_test.dart @@ -0,0 +1,85 @@ +import 'dart:io'; + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +import 'fake_client.dart'; +import 'random_id.dart'; + +void main() { + var storeApi = new StoreApi(); + + Order makeOrder({int id}) { + return Order() + ..id = id + ..petId = 1234 + ..quantity = 1 + ..shipDate = DateTime.now() + ..status + ..complete = false; + } + + group('Store API with faked client', () { + test('places an order and gets it by id', () async { + final id = newId(); + final newOrder = makeOrder(id: id); + + // use the store api to add an order + storeApi.apiClient.client = FakeClient( + expectedUrl: 'http://petstore.swagger.io/v2/store/order', + expectedPostRequestBody: storeApi.apiClient.serialize(newOrder), + postResponseBody: storeApi.apiClient.serialize(newOrder), + ); + await storeApi.placeOrder(newOrder); + + // retrieve the same order by id + storeApi.apiClient.client = FakeClient( + expectedUrl: 'http://petstore.swagger.io/v2/store/order/$id', + getResponseBody: storeApi.apiClient.serialize(newOrder), + ); + final placedOrder = await storeApi.getOrderById(id); + expect(placedOrder.id, equals(id)); + }); + + test('deletes an order', () async { + final id = newId(); + final newOrder = makeOrder(id: id); + + // use the store api to add an order + storeApi.apiClient.client = FakeClient( + expectedUrl: 'http://petstore.swagger.io/v2/store/order', + expectedPostRequestBody: storeApi.apiClient.serialize(newOrder), + postResponseBody: storeApi.apiClient.serialize(newOrder), + ); + await storeApi.placeOrder(newOrder); + + // delete the same order + storeApi.apiClient.client = FakeClient( + expectedUrl: 'http://petstore.swagger.io/v2/store/order/$id', + deleteResponseBody: '', + ); + await storeApi.deleteOrder(id.toString()); + + // try and retrieve the order + storeApi.apiClient.client = FakeClient( + expectedUrl: 'http://petstore.swagger.io/v2/store/order/$id', + throwException: ApiException(400, 'Not found'), + ); + expect(storeApi.getOrderById(id), + throwsA(equals(TypeMatcher()))); + }); + + test('gets the store inventory', () async { + // get some test data (recorded from live response) + final inventoryResponse = + await File('test/inventory_response.json').readAsString(); + // use the store api to get the inventory + storeApi.apiClient.client = FakeClient( + expectedUrl: 'http://petstore.swagger.io/v2/store/inventory', + getResponseBody: inventoryResponse, + ); + Map inventory = await storeApi.getInventory(); + expect(inventory.length, isNot(equals(0))); + }); + }); +} diff --git a/samples/client/petstore/dart2/petstore/test/store_test.dart b/samples/client/petstore/dart2/petstore/test/store_test.dart index 0e610e7a67a..ce4531e372d 100644 --- a/samples/client/petstore/dart2/petstore/test/store_test.dart +++ b/samples/client/petstore/dart2/petstore/test/store_test.dart @@ -16,7 +16,7 @@ void main() { ..complete = false; } - group('Store API ', () { + group('Store API with live client', () { test('places an order and gets it by id', () async { var id = newId(); @@ -38,5 +38,5 @@ void main() { Map inventory = await storeApi.getInventory(); expect(inventory.length, isNot(equals(0))); }); - }); + }); // , skip: 'e2e tests for CI' } diff --git a/samples/client/petstore/dart2/petstore/test/user_faked_client_test.dart b/samples/client/petstore/dart2/petstore/test/user_faked_client_test.dart new file mode 100644 index 00000000000..df2b4686f13 --- /dev/null +++ b/samples/client/petstore/dart2/petstore/test/user_faked_client_test.dart @@ -0,0 +1,170 @@ +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +import 'fake_client.dart'; +import 'random_id.dart'; + +void main() { + var userApi = new UserApi(); + + User makeUser( + {int id, String userName = 'username', String password = 'password'}) { + return User() + ..id = id + ..username = userName + ..firstName = 'firstname' + ..lastName = 'lastname' + ..email = 'email' + ..password = password + ..phone = 'phone' + ..userStatus = 0; + } + + group('User API with faked client', () { + test('creates a user', () async { + final id = newId(); + final username = 'Mally45'; + final newUser = makeUser(id: id, userName: username); + + // use the user api to create a user + userApi.apiClient.client = FakeClient( + expectedUrl: 'http://petstore.swagger.io/v2/user', + expectedPostRequestBody: userApi.apiClient.serialize(newUser), + postResponseBody: userApi.apiClient.serialize(newUser), + ); + await userApi.createUser(newUser); + + // retrieve the same user + userApi.apiClient.client = FakeClient( + expectedUrl: 'http://petstore.swagger.io/v2/user/$username', + getResponseBody: userApi.apiClient.serialize(newUser), + ); + var user = await userApi.getUserByName(username); + expect(user.id, equals(id)); + }); + + test('creates users with list input', () async { + final firstId = newId(); + final joe = 'Joe'; + + final sally = 'Sally'; + final secondId = newId(); + + final users = [ + makeUser(id: firstId, userName: joe), + makeUser(id: secondId, userName: sally), + ]; + + // use the user api to create a list of users + userApi.apiClient.client = FakeClient( + expectedUrl: 'http://petstore.swagger.io/v2/user/createWithList', + expectedPostRequestBody: userApi.apiClient.serialize(users), + postResponseBody: userApi.apiClient.serialize(users), + ); + await userApi.createUsersWithListInput(users); + + // retrieve the users + userApi.apiClient.client = FakeClient( + expectedUrl: + 'http://petstore.swagger.io/v2/user/${users.elementAt(0).username}', + getResponseBody: userApi.apiClient.serialize( + users.elementAt(0), + ), + ); + final firstUser = await userApi.getUserByName(joe); + userApi.apiClient.client = FakeClient( + expectedUrl: + 'http://petstore.swagger.io/v2/user/${users.elementAt(1).username}', + getResponseBody: userApi.apiClient.serialize( + users.elementAt(1), + ), + ); + final secondUser = await userApi.getUserByName(sally); + expect(firstUser.id, equals(firstId)); + expect(secondUser.id, equals(secondId)); + }); + + test('updates a user', () async { + final username = 'Arkjam89'; + final email = 'test@example.com'; + final newUser = makeUser(id: newId(), userName: username); + + // use the user api to create a user + userApi.apiClient.client = FakeClient( + expectedUrl: 'http://petstore.swagger.io/v2/user', + expectedPostRequestBody: userApi.apiClient.serialize(newUser), + postResponseBody: userApi.apiClient.serialize(newUser), + ); + await userApi.createUser(newUser); + newUser.email = email; + + // use the user api to update the user + userApi.apiClient.client = FakeClient( + expectedUrl: 'http://petstore.swagger.io/v2/user/${newUser.username}', + expectedPutRequestBody: userApi.apiClient.serialize(newUser), + putResponseBody: userApi.apiClient.serialize(newUser), + ); + await userApi.updateUser(username, newUser); + + // retrieve the same user + userApi.apiClient.client = FakeClient( + expectedUrl: 'http://petstore.swagger.io/v2/user/${newUser.username}', + getResponseBody: userApi.apiClient.serialize(newUser), + ); + var foundUser = await userApi.getUserByName(username); + expect(foundUser.email, equals(email)); + }); + + test('deletes a user', () async { + final username = 'Riddlem325'; + final newUser = makeUser(id: newId(), userName: username); + + // use the user api to create a user + userApi.apiClient.client = FakeClient( + expectedUrl: 'http://petstore.swagger.io/v2/user', + expectedPostRequestBody: userApi.apiClient.serialize(newUser), + postResponseBody: userApi.apiClient.serialize(newUser), + ); + await userApi.createUser(newUser); + + // delete the same user + userApi.apiClient.client = FakeClient( + expectedUrl: 'http://petstore.swagger.io/v2/user/${newUser.username}', + deleteResponseBody: '', + ); + await userApi.deleteUser(username); + + // try and retrieve the user + userApi.apiClient.client = FakeClient( + expectedUrl: 'http://petstore.swagger.io/v2/user/${newUser.username}', + throwException: ApiException(400, 'Not found'), + ); + expect(userApi.getUserByName(username), + throwsA(TypeMatcher())); + }); + + test('logs a user in', () async { + final username = 'sgarad625'; + final password = 'lokimoki1'; + final newUser = + makeUser(id: newId(), userName: username, password: password); + + // use the user api to create a user + userApi.apiClient.client = FakeClient( + expectedUrl: 'http://petstore.swagger.io/v2/user', + expectedPostRequestBody: userApi.apiClient.serialize(newUser), + postResponseBody: userApi.apiClient.serialize(newUser), + ); + await userApi.createUser(newUser); + + // use the user api to login + userApi.apiClient.client = FakeClient( + expectedUrl: + 'http://petstore.swagger.io/v2/user/login?username=${newUser.username}&password=${newUser.password}', + getResponseBody: 'logged in user session:', + ); + final result = await userApi.loginUser(username, password); + expect(result, contains('logged in user session:')); + }); + }); +} diff --git a/samples/client/petstore/dart2/petstore/test/user_test.dart b/samples/client/petstore/dart2/petstore/test/user_test.dart index a9c37e4808b..ea34b3713fa 100644 --- a/samples/client/petstore/dart2/petstore/test/user_test.dart +++ b/samples/client/petstore/dart2/petstore/test/user_test.dart @@ -19,7 +19,7 @@ void main() { ..userStatus = 0; } - group('User API ', () { + group('User API with live client', () { test('creates a user', () async { var id = newId(); var username = 'Mally45'; @@ -76,5 +76,5 @@ void main() { var result = await userApi.loginUser(username, password); expect(result, contains('logged in user session:')); }); - }); + }, skip: 'e2e tests for CI'); } diff --git a/samples/client/petstore/dart2/openapi/.gitignore b/samples/client/petstore/dart2/petstore_client_lib/.gitignore similarity index 100% rename from samples/client/petstore/dart2/openapi/.gitignore rename to samples/client/petstore/dart2/petstore_client_lib/.gitignore diff --git a/samples/client/petstore/dart2/openapi/.openapi-generator-ignore b/samples/client/petstore/dart2/petstore_client_lib/.openapi-generator-ignore similarity index 100% rename from samples/client/petstore/dart2/openapi/.openapi-generator-ignore rename to samples/client/petstore/dart2/petstore_client_lib/.openapi-generator-ignore diff --git a/samples/client/petstore/dart2/openapi/.openapi-generator/VERSION b/samples/client/petstore/dart2/petstore_client_lib/.openapi-generator/VERSION similarity index 100% rename from samples/client/petstore/dart2/openapi/.openapi-generator/VERSION rename to samples/client/petstore/dart2/petstore_client_lib/.openapi-generator/VERSION diff --git a/samples/client/petstore/dart2/openapi/.travis.yml b/samples/client/petstore/dart2/petstore_client_lib/.travis.yml similarity index 100% rename from samples/client/petstore/dart2/openapi/.travis.yml rename to samples/client/petstore/dart2/petstore_client_lib/.travis.yml diff --git a/samples/client/petstore/dart2/openapi/README.md b/samples/client/petstore/dart2/petstore_client_lib/README.md similarity index 100% rename from samples/client/petstore/dart2/openapi/README.md rename to samples/client/petstore/dart2/petstore_client_lib/README.md diff --git a/samples/client/petstore/dart2/openapi/docs/ApiResponse.md b/samples/client/petstore/dart2/petstore_client_lib/docs/ApiResponse.md similarity index 100% rename from samples/client/petstore/dart2/openapi/docs/ApiResponse.md rename to samples/client/petstore/dart2/petstore_client_lib/docs/ApiResponse.md diff --git a/samples/client/petstore/dart2/openapi/docs/Category.md b/samples/client/petstore/dart2/petstore_client_lib/docs/Category.md similarity index 100% rename from samples/client/petstore/dart2/openapi/docs/Category.md rename to samples/client/petstore/dart2/petstore_client_lib/docs/Category.md diff --git a/samples/client/petstore/dart2/openapi/docs/Order.md b/samples/client/petstore/dart2/petstore_client_lib/docs/Order.md similarity index 100% rename from samples/client/petstore/dart2/openapi/docs/Order.md rename to samples/client/petstore/dart2/petstore_client_lib/docs/Order.md diff --git a/samples/client/petstore/dart2/openapi/docs/Pet.md b/samples/client/petstore/dart2/petstore_client_lib/docs/Pet.md similarity index 100% rename from samples/client/petstore/dart2/openapi/docs/Pet.md rename to samples/client/petstore/dart2/petstore_client_lib/docs/Pet.md diff --git a/samples/client/petstore/dart2/openapi/docs/PetApi.md b/samples/client/petstore/dart2/petstore_client_lib/docs/PetApi.md similarity index 100% rename from samples/client/petstore/dart2/openapi/docs/PetApi.md rename to samples/client/petstore/dart2/petstore_client_lib/docs/PetApi.md diff --git a/samples/client/petstore/dart2/openapi/docs/StoreApi.md b/samples/client/petstore/dart2/petstore_client_lib/docs/StoreApi.md similarity index 100% rename from samples/client/petstore/dart2/openapi/docs/StoreApi.md rename to samples/client/petstore/dart2/petstore_client_lib/docs/StoreApi.md diff --git a/samples/client/petstore/dart2/openapi/docs/Tag.md b/samples/client/petstore/dart2/petstore_client_lib/docs/Tag.md similarity index 100% rename from samples/client/petstore/dart2/openapi/docs/Tag.md rename to samples/client/petstore/dart2/petstore_client_lib/docs/Tag.md diff --git a/samples/client/petstore/dart2/openapi/docs/User.md b/samples/client/petstore/dart2/petstore_client_lib/docs/User.md similarity index 100% rename from samples/client/petstore/dart2/openapi/docs/User.md rename to samples/client/petstore/dart2/petstore_client_lib/docs/User.md diff --git a/samples/client/petstore/dart2/openapi/docs/UserApi.md b/samples/client/petstore/dart2/petstore_client_lib/docs/UserApi.md similarity index 100% rename from samples/client/petstore/dart2/openapi/docs/UserApi.md rename to samples/client/petstore/dart2/petstore_client_lib/docs/UserApi.md diff --git a/samples/client/petstore/dart2/openapi/git_push.sh b/samples/client/petstore/dart2/petstore_client_lib/git_push.sh similarity index 100% rename from samples/client/petstore/dart2/openapi/git_push.sh rename to samples/client/petstore/dart2/petstore_client_lib/git_push.sh diff --git a/samples/client/petstore/dart2/openapi/lib/api.dart b/samples/client/petstore/dart2/petstore_client_lib/lib/api.dart similarity index 100% rename from samples/client/petstore/dart2/openapi/lib/api.dart rename to samples/client/petstore/dart2/petstore_client_lib/lib/api.dart diff --git a/samples/client/petstore/dart2/openapi/lib/api/pet_api.dart b/samples/client/petstore/dart2/petstore_client_lib/lib/api/pet_api.dart similarity index 100% rename from samples/client/petstore/dart2/openapi/lib/api/pet_api.dart rename to samples/client/petstore/dart2/petstore_client_lib/lib/api/pet_api.dart diff --git a/samples/client/petstore/dart2/openapi/lib/api/store_api.dart b/samples/client/petstore/dart2/petstore_client_lib/lib/api/store_api.dart similarity index 100% rename from samples/client/petstore/dart2/openapi/lib/api/store_api.dart rename to samples/client/petstore/dart2/petstore_client_lib/lib/api/store_api.dart diff --git a/samples/client/petstore/dart2/openapi/lib/api/user_api.dart b/samples/client/petstore/dart2/petstore_client_lib/lib/api/user_api.dart similarity index 100% rename from samples/client/petstore/dart2/openapi/lib/api/user_api.dart rename to samples/client/petstore/dart2/petstore_client_lib/lib/api/user_api.dart diff --git a/samples/client/petstore/dart2/openapi/lib/api_client.dart b/samples/client/petstore/dart2/petstore_client_lib/lib/api_client.dart similarity index 100% rename from samples/client/petstore/dart2/openapi/lib/api_client.dart rename to samples/client/petstore/dart2/petstore_client_lib/lib/api_client.dart diff --git a/samples/client/petstore/dart2/openapi/lib/api_exception.dart b/samples/client/petstore/dart2/petstore_client_lib/lib/api_exception.dart similarity index 100% rename from samples/client/petstore/dart2/openapi/lib/api_exception.dart rename to samples/client/petstore/dart2/petstore_client_lib/lib/api_exception.dart diff --git a/samples/client/petstore/dart2/openapi/lib/api_helper.dart b/samples/client/petstore/dart2/petstore_client_lib/lib/api_helper.dart similarity index 100% rename from samples/client/petstore/dart2/openapi/lib/api_helper.dart rename to samples/client/petstore/dart2/petstore_client_lib/lib/api_helper.dart diff --git a/samples/client/petstore/dart2/openapi/lib/auth/api_key_auth.dart b/samples/client/petstore/dart2/petstore_client_lib/lib/auth/api_key_auth.dart similarity index 100% rename from samples/client/petstore/dart2/openapi/lib/auth/api_key_auth.dart rename to samples/client/petstore/dart2/petstore_client_lib/lib/auth/api_key_auth.dart diff --git a/samples/client/petstore/dart2/openapi/lib/auth/authentication.dart b/samples/client/petstore/dart2/petstore_client_lib/lib/auth/authentication.dart similarity index 100% rename from samples/client/petstore/dart2/openapi/lib/auth/authentication.dart rename to samples/client/petstore/dart2/petstore_client_lib/lib/auth/authentication.dart diff --git a/samples/client/petstore/dart2/openapi/lib/auth/http_basic_auth.dart b/samples/client/petstore/dart2/petstore_client_lib/lib/auth/http_basic_auth.dart similarity index 100% rename from samples/client/petstore/dart2/openapi/lib/auth/http_basic_auth.dart rename to samples/client/petstore/dart2/petstore_client_lib/lib/auth/http_basic_auth.dart diff --git a/samples/client/petstore/dart2/openapi/lib/auth/oauth.dart b/samples/client/petstore/dart2/petstore_client_lib/lib/auth/oauth.dart similarity index 100% rename from samples/client/petstore/dart2/openapi/lib/auth/oauth.dart rename to samples/client/petstore/dart2/petstore_client_lib/lib/auth/oauth.dart diff --git a/samples/client/petstore/dart2/openapi/lib/model/api_response.dart b/samples/client/petstore/dart2/petstore_client_lib/lib/model/api_response.dart similarity index 100% rename from samples/client/petstore/dart2/openapi/lib/model/api_response.dart rename to samples/client/petstore/dart2/petstore_client_lib/lib/model/api_response.dart diff --git a/samples/client/petstore/dart2/openapi/lib/model/category.dart b/samples/client/petstore/dart2/petstore_client_lib/lib/model/category.dart similarity index 100% rename from samples/client/petstore/dart2/openapi/lib/model/category.dart rename to samples/client/petstore/dart2/petstore_client_lib/lib/model/category.dart diff --git a/samples/client/petstore/dart2/openapi/lib/model/order.dart b/samples/client/petstore/dart2/petstore_client_lib/lib/model/order.dart similarity index 100% rename from samples/client/petstore/dart2/openapi/lib/model/order.dart rename to samples/client/petstore/dart2/petstore_client_lib/lib/model/order.dart diff --git a/samples/client/petstore/dart2/openapi/lib/model/pet.dart b/samples/client/petstore/dart2/petstore_client_lib/lib/model/pet.dart similarity index 100% rename from samples/client/petstore/dart2/openapi/lib/model/pet.dart rename to samples/client/petstore/dart2/petstore_client_lib/lib/model/pet.dart diff --git a/samples/client/petstore/dart2/openapi/lib/model/tag.dart b/samples/client/petstore/dart2/petstore_client_lib/lib/model/tag.dart similarity index 100% rename from samples/client/petstore/dart2/openapi/lib/model/tag.dart rename to samples/client/petstore/dart2/petstore_client_lib/lib/model/tag.dart diff --git a/samples/client/petstore/dart2/openapi/lib/model/user.dart b/samples/client/petstore/dart2/petstore_client_lib/lib/model/user.dart similarity index 100% rename from samples/client/petstore/dart2/openapi/lib/model/user.dart rename to samples/client/petstore/dart2/petstore_client_lib/lib/model/user.dart diff --git a/samples/client/petstore/dart2/openapi/pubspec.yaml b/samples/client/petstore/dart2/petstore_client_lib/pubspec.yaml similarity index 100% rename from samples/client/petstore/dart2/openapi/pubspec.yaml rename to samples/client/petstore/dart2/petstore_client_lib/pubspec.yaml diff --git a/samples/client/petstore/dart2/openapi/test/api_response_test.dart b/samples/client/petstore/dart2/petstore_client_lib/test/api_response_test.dart similarity index 100% rename from samples/client/petstore/dart2/openapi/test/api_response_test.dart rename to samples/client/petstore/dart2/petstore_client_lib/test/api_response_test.dart diff --git a/samples/client/petstore/dart2/openapi/test/category_test.dart b/samples/client/petstore/dart2/petstore_client_lib/test/category_test.dart similarity index 100% rename from samples/client/petstore/dart2/openapi/test/category_test.dart rename to samples/client/petstore/dart2/petstore_client_lib/test/category_test.dart diff --git a/samples/client/petstore/dart2/openapi/test/order_test.dart b/samples/client/petstore/dart2/petstore_client_lib/test/order_test.dart similarity index 100% rename from samples/client/petstore/dart2/openapi/test/order_test.dart rename to samples/client/petstore/dart2/petstore_client_lib/test/order_test.dart diff --git a/samples/client/petstore/dart2/openapi/test/pet_api_test.dart b/samples/client/petstore/dart2/petstore_client_lib/test/pet_api_test.dart similarity index 100% rename from samples/client/petstore/dart2/openapi/test/pet_api_test.dart rename to samples/client/petstore/dart2/petstore_client_lib/test/pet_api_test.dart diff --git a/samples/client/petstore/dart2/openapi/test/pet_test.dart b/samples/client/petstore/dart2/petstore_client_lib/test/pet_test.dart similarity index 100% rename from samples/client/petstore/dart2/openapi/test/pet_test.dart rename to samples/client/petstore/dart2/petstore_client_lib/test/pet_test.dart diff --git a/samples/client/petstore/dart2/openapi/test/store_api_test.dart b/samples/client/petstore/dart2/petstore_client_lib/test/store_api_test.dart similarity index 100% rename from samples/client/petstore/dart2/openapi/test/store_api_test.dart rename to samples/client/petstore/dart2/petstore_client_lib/test/store_api_test.dart diff --git a/samples/client/petstore/dart2/openapi/test/tag_test.dart b/samples/client/petstore/dart2/petstore_client_lib/test/tag_test.dart similarity index 100% rename from samples/client/petstore/dart2/openapi/test/tag_test.dart rename to samples/client/petstore/dart2/petstore_client_lib/test/tag_test.dart diff --git a/samples/client/petstore/dart2/openapi/test/user_api_test.dart b/samples/client/petstore/dart2/petstore_client_lib/test/user_api_test.dart similarity index 100% rename from samples/client/petstore/dart2/openapi/test/user_api_test.dart rename to samples/client/petstore/dart2/petstore_client_lib/test/user_api_test.dart diff --git a/samples/client/petstore/dart2/openapi/test/user_test.dart b/samples/client/petstore/dart2/petstore_client_lib/test/user_test.dart similarity index 100% rename from samples/client/petstore/dart2/openapi/test/user_test.dart rename to samples/client/petstore/dart2/petstore_client_lib/test/user_test.dart diff --git a/samples/client/petstore/dart2/purge_test.sh b/samples/client/petstore/dart2/purge_test.sh deleted file mode 100755 index 6c0aca0ac84..00000000000 --- a/samples/client/petstore/dart2/purge_test.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -echo "purge test fils under 'test' folder" -rm -Rf openapi/test/