From adab974383b45f62226d78d5253eb59c7285168e Mon Sep 17 00:00:00 2001 From: Chris Lloyd Date: Sun, 14 Nov 2021 17:50:20 +0000 Subject: [PATCH] WIP --- .github/workflows/docs.yml | 2 +- .github/workflows/tests.yml | 4 +- composer.lock | 1481 +++++++------ doc/getting-started/README.md | 2 +- doc/introduction/compliance.md | 1 + doc/introduction/reporting-issues.md | 2 +- doc/making-requests/querying-data.md | 46 +- doc/modelling/drivers/database.md | 2 +- doc/modelling/drivers/eloquent.md | 136 +- doc/modelling/operations.md | 562 ++++- phpdoc.xml | 21 - src/Annotation/Core/V1/PositionalInsert.php | 22 + src/Attributes/LodataAction.php | 14 + src/Attributes/LodataFunction.php | 14 + src/Attributes/LodataNamespace.php | 23 + src/Attributes/LodataOperation.php | 54 + src/Attributes/LodataRelationship.php | 12 + src/ComplexValue.php | 11 +- src/Console/ActionCommand.php | 16 - src/Console/ClassCreator.php | 53 - src/Console/FunctionCommand.php | 16 - src/Console/_stubs_/action.php.stub | 13 - src/Console/_stubs_/function.php.stub | 13 - src/Controller/ODCFF.php | 2 +- src/Controller/PBIDS.php | 3 +- src/Controller/Response.php | 2 +- src/Controller/Transaction.php | 59 +- src/Drivers/CollectionEntitySet.php | 47 +- src/Drivers/EloquentEntitySet.php | 53 +- src/Drivers/SQL/SQLConnection.php | 4 +- src/Drivers/SQLEntitySet.php | 13 + src/Drivers/StaticEntitySet.php | 6 +- src/Entity.php | 2 +- src/EntitySet.php | 35 +- src/EntityType.php | 11 + src/EnumerationType.php | 6 +- .../Protocol/ConfigurationException.php | 15 + src/Exception/Protocol/ProtocolException.php | 3 +- src/Facades/Lodata.php | 7 +- src/GeneratedProperty.php | 2 +- src/Helper/Constants.php | 5 + src/Helper/Discovery.php | 135 ++ src/Helper/Gate.php | 61 +- src/Helper/Identifier.php | 59 +- src/Helper/Name.php | 4 +- src/Helper/ObjectArray.php | 54 +- src/Interfaces/IdentifierInterface.php | 19 +- src/Interfaces/Operation/ActionInterface.php | 13 - .../Operation/ArgumentInterface.php | 13 - .../Operation/FunctionInterface.php | 13 - src/Interfaces/RepositoryInterface.php | 10 + src/Interfaces/ServiceInterface.php | 6 +- src/Model.php | 35 +- src/NavigationProperty.php | 4 +- src/Operation.php | 780 ++++--- src/Operation/Action.php | 12 + src/Operation/Argument.php | 88 +- src/Operation/EntityArgument.php | 42 +- src/Operation/EntityFunction.php | 26 + src/Operation/EntitySetArgument.php | 47 +- src/Operation/Function_.php | 12 + src/Operation/PrimitiveArgument.php | 58 +- src/Operation/Repository.php | 62 + src/Operation/TransactionArgument.php | 18 +- src/Operation/TypeArgument.php | 35 - src/Operation/ValueArgument.php | 29 + src/PathSegment/Batch/JSON.php | 5 +- src/PathSegment/Metadata/JSON.php | 33 +- src/PathSegment/Metadata/XML.php | 50 +- src/PathSegment/OpenAPI.php | 29 +- src/Primitive.php | 45 +- src/PrimitiveType.php | 36 +- src/ServiceProvider.php | 7 - src/Singleton.php | 14 +- src/Traits/HasIdentifier.php | 47 +- src/Traits/HasNavigation.php | 4 +- src/Transaction/MetadataContainer.php | 6 +- src/Transaction/MultipartDocument.php | 5 +- src/Transaction/Option/Index.php | 16 + src/Type.php | 34 +- src/Type/Collection.php | 6 +- src/Type/Enum.php | 8 +- src/Type/Untyped.php | 5 +- tests/Command/CommandTest.php | 21 - .../files/CommandTest__test_action__1.php | 13 - .../files/CommandTest__test_function__1.php | 13 - tests/Data/TestModels.php | 19 +- tests/Data/TestOperations.php | 19 + tests/Models/Airport.php | 17 + tests/Models/Passenger.php | 2 + tests/Models/Pet.php | 2 + tests/Models/Repository.php | 22 + tests/Operations/Instance.php | 18 + tests/Operations/Math.php | 18 + tests/Operations/Service.php | 60 + tests/TestCase.php | 12 +- .../Unit/Collection/NumericCollectionTest.php | 28 + ...ectionTest__test_create_positional__1.json | 5 + ...lectionTest__test_create_positional__2.yml | 8 + ...ectionTest__test_create_positional__3.json | 25 + ...ectionTest__test_create_positional__4.json | 5 + ...umericCollectionTest__test_metadata__1.xml | 126 ++ ...umericCollectionTest__test_metadata__2.yml | 6 + ...mericCollectionTest__test_metadata__3.json | 113 + ...mericCollectionTest__test_metadata__4.json | 623 ++++++ tests/Unit/Eloquent/CastingTest.php | 2 +- tests/Unit/Eloquent/EloquentTest.php | 8 +- tests/Unit/Eloquent/InvalidModelTest.php | 4 +- tests/Unit/Eloquent/OperationTest.php | 43 + .../EloquentTest__test_create__3.yml | 2 +- .../EloquentTest__test_create_deep__2.yml | 6 +- ...st__test_create_navigation_property__3.yml | 26 +- .../EloquentTest__test_metadata__1.xml | 103 + .../EloquentTest__test_metadata__3.json | 98 + .../EloquentTest__test_metadata__4.json | 743 ++++++- .../EloquentTest__test_update__3.yml | 2 +- .../OperationTest__test_op1__1.json | 4 + .../OperationTest__test_op2__1.json | 4 + .../CreateTest__test_create__3.yml | 26 +- ...est__test_create_content_type_error__2.yml | 24 +- .../CreateTest__test_create_deep__3.yml | 32 +- ...eateTest__test_create_deep_metadata__6.yml | 32 +- ...ot_modify_existing_related_entities__2.yml | 24 +- ...tity_with_existing_related_entities__3.yml | 26 +- .../CreateTest__test_create_ref__3.yml | 26 +- ...ateTest__test_create_related_entity__4.yml | 26 +- ...ateTest__test_create_return_minimal__2.yml | 26 +- .../DeleteTest__test_delete__1.yml | 22 +- .../DeleteTest__test_delete_not_found__2.yml | 24 +- .../DeleteTest__test_delete_ref__1.yml | 22 +- .../DeleteTest__test_validate_etag__2.yml | 22 +- .../UpdateTest__test_any_etag__2.yml | 28 +- .../UpdateTest__test_any_if_none_match__2.yml | 28 +- ...ateTest__test_any_if_none_match_any__2.yml | 28 +- ...Test__test_any_if_none_match_failed__2.yml | 28 +- .../UpdateTest__test_multiple_etag__2.yml | 28 +- .../UpdateTest__test_update__2.yml | 28 +- .../UpdateTest__test_update__3.yml | 28 +- ...eTest__test_update_invalid_property__2.yml | 28 +- .../UpdateTest__test_update_post__2.yml | 28 +- ...teTest__test_update_post_via_tunnel__2.yml | 28 +- .../UpdateTest__test_update_put__2.yml | 28 +- .../UpdateTest__test_update_ref__2.yml | 28 +- .../UpdateTest__test_update_related__2.yml | 28 +- ...teTest__test_update_related_missing__3.yml | 28 +- ...teTest__test_update_removed_changed__3.yml | 28 +- ...ateTest__test_update_return_minimal__2.yml | 28 +- .../UpdateTest__test_validate_etag__4.yml | 28 +- tests/Unit/Operation/ActionTest.php | 580 ++++- tests/Unit/Operation/DiscoveryTest.php | 90 + tests/Unit/Operation/FunctionTest.php | 632 ++++-- tests/Unit/Operation/NamespaceTest.php | 35 + tests/Unit/Operation/OperationTest.php | 229 +- tests/Unit/Operation/Repository73Test.php | 50 + tests/Unit/Operation/RepositoryTest.php | 50 + ...onTest__test_bound_with_parameters__1.json | 4 + .../ActionTest__test_date_argument__1.xml | 67 + .../ActionTest__test_date_argument__2.yml | 6 + .../ActionTest__test_date_argument__3.json | 79 + .../ActionTest__test_date_argument__4.json | 394 ++++ .../ActionTest__test_date_argument__5.json | 4 + ...ionTest__test_odata_binary_argument__1.xml | 67 + ...ionTest__test_odata_binary_argument__2.yml | 6 + ...onTest__test_odata_binary_argument__3.json | 79 + ...onTest__test_odata_binary_argument__4.json | 394 ++++ ...onTest__test_odata_binary_argument__5.json | 4 + ...onTest__test_odata_boolean_argument__1.xml | 67 + ...onTest__test_odata_boolean_argument__2.yml | 6 + ...nTest__test_odata_boolean_argument__3.json | 79 + ...nTest__test_odata_boolean_argument__4.json | 392 ++++ ...nTest__test_odata_boolean_argument__5.json | 4 + ...ctionTest__test_odata_byte_argument__1.xml | 67 + ...ctionTest__test_odata_byte_argument__2.yml | 6 + ...tionTest__test_odata_byte_argument__3.json | 79 + ...tionTest__test_odata_byte_argument__4.json | 395 ++++ ...tionTest__test_odata_byte_argument__5.json | 4 + ...ctionTest__test_odata_date_argument__1.xml | 67 + ...ctionTest__test_odata_date_argument__2.yml | 6 + ...tionTest__test_odata_date_argument__3.json | 79 + ...tionTest__test_odata_date_argument__4.json | 394 ++++ ...tionTest__test_odata_date_argument__5.json | 4 + ..._test_odata_datetimeoffset_argument__1.xml | 67 + ..._test_odata_datetimeoffset_argument__2.yml | 6 + ...test_odata_datetimeoffset_argument__3.json | 79 + ...test_odata_datetimeoffset_argument__4.json | 394 ++++ ...test_odata_datetimeoffset_argument__5.json | 4 + ...onTest__test_odata_decimal_argument__1.xml | 67 + ...onTest__test_odata_decimal_argument__2.yml | 6 + ...nTest__test_odata_decimal_argument__3.json | 79 + ...nTest__test_odata_decimal_argument__4.json | 404 ++++ ...nTest__test_odata_decimal_argument__5.json | 4 + ...ionTest__test_odata_double_argument__1.xml | 67 + ...ionTest__test_odata_double_argument__2.yml | 6 + ...onTest__test_odata_double_argument__3.json | 79 + ...onTest__test_odata_double_argument__4.json | 404 ++++ ...onTest__test_odata_double_argument__5.json | 4 + ...nTest__test_odata_duration_argument__1.xml | 67 + ...nTest__test_odata_duration_argument__2.yml | 6 + ...Test__test_odata_duration_argument__3.json | 79 + ...Test__test_odata_duration_argument__4.json | 394 ++++ ...Test__test_odata_duration_argument__5.json | 4 + ...ctionTest__test_odata_guid_argument__1.xml | 67 + ...ctionTest__test_odata_guid_argument__2.yml | 6 + ...tionTest__test_odata_guid_argument__3.json | 79 + ...tionTest__test_odata_guid_argument__4.json | 394 ++++ ...tionTest__test_odata_guid_argument__5.json | 4 + ...tionTest__test_odata_int16_argument__1.xml | 67 + ...tionTest__test_odata_int16_argument__2.yml | 6 + ...ionTest__test_odata_int16_argument__3.json | 79 + ...ionTest__test_odata_int16_argument__4.json | 395 ++++ ...ionTest__test_odata_int16_argument__5.json | 4 + ...tionTest__test_odata_int32_argument__1.xml | 67 + ...tionTest__test_odata_int32_argument__2.yml | 6 + ...ionTest__test_odata_int32_argument__3.json | 79 + ...ionTest__test_odata_int32_argument__4.json | 395 ++++ ...ionTest__test_odata_int32_argument__5.json | 4 + ...tionTest__test_odata_int64_argument__1.xml | 67 + ...tionTest__test_odata_int64_argument__2.yml | 6 + ...ionTest__test_odata_int64_argument__3.json | 79 + ...ionTest__test_odata_int64_argument__4.json | 395 ++++ ...ionTest__test_odata_int64_argument__5.json | 4 + ...tionTest__test_odata_sbyte_argument__1.xml | 67 + ...tionTest__test_odata_sbyte_argument__2.yml | 6 + ...ionTest__test_odata_sbyte_argument__3.json | 79 + ...ionTest__test_odata_sbyte_argument__4.json | 395 ++++ ...ionTest__test_odata_sbyte_argument__5.json | 4 + ...ionTest__test_odata_single_argument__1.xml | 67 + ...ionTest__test_odata_single_argument__2.yml | 6 + ...onTest__test_odata_single_argument__3.json | 79 + ...onTest__test_odata_single_argument__4.json | 404 ++++ ...onTest__test_odata_single_argument__5.json | 4 + ...ionTest__test_odata_string_argument__1.xml | 67 + ...ionTest__test_odata_string_argument__2.yml | 6 + ...onTest__test_odata_string_argument__3.json | 79 + ...onTest__test_odata_string_argument__4.json | 392 ++++ ...onTest__test_odata_string_argument__5.json | 4 + ...Test__test_odata_timeofday_argument__1.xml | 67 + ...Test__test_odata_timeofday_argument__2.yml | 6 + ...est__test_odata_timeofday_argument__3.json | 79 + ...est__test_odata_timeofday_argument__4.json | 394 ++++ ...est__test_odata_timeofday_argument__5.json | 4 + ...ionTest__test_odata_uint16_argument__1.xml | 67 + ...ionTest__test_odata_uint16_argument__2.yml | 6 + ...onTest__test_odata_uint16_argument__3.json | 79 + ...onTest__test_odata_uint16_argument__4.json | 395 ++++ ...onTest__test_odata_uint16_argument__5.json | 4 + ...ionTest__test_odata_uint32_argument__1.xml | 67 + ...ionTest__test_odata_uint32_argument__2.yml | 6 + ...onTest__test_odata_uint32_argument__3.json | 79 + ...onTest__test_odata_uint32_argument__4.json | 395 ++++ ...onTest__test_odata_uint32_argument__5.json | 4 + ...ionTest__test_odata_uint64_argument__1.xml | 67 + ...ionTest__test_odata_uint64_argument__2.yml | 6 + ...onTest__test_odata_uint64_argument__3.json | 79 + ...onTest__test_odata_uint64_argument__4.json | 395 ++++ ...onTest__test_odata_uint64_argument__5.json | 4 + .../DiscoveryTest__test_bind__1.json | 4 + .../DiscoveryTest__test_identity__1.json | 4 + .../DiscoveryTest__test_instance__1.json | 4 + .../DiscoveryTest__test_metadata__1.xml | 326 +++ .../DiscoveryTest__test_metadata__2.yml | 6 + .../DiscoveryTest__test_metadata__3.json | 416 ++++ .../DiscoveryTest__test_metadata__4.json | 1884 +++++++++++++++++ .../DiscoveryTest__test_simple__1.json | 4 + ..._test_callback_bound_internal_type__1.json | 4 + ...ionTest__test_odata_binary_argument__1.xml | 67 + ...ionTest__test_odata_binary_argument__2.yml | 6 + ...onTest__test_odata_binary_argument__3.json | 79 + ...onTest__test_odata_binary_argument__4.json | 394 ++++ ...onTest__test_odata_binary_argument__5.json | 4 + ...onTest__test_odata_boolean_argument__1.xml | 67 + ...onTest__test_odata_boolean_argument__2.yml | 6 + ...nTest__test_odata_boolean_argument__3.json | 79 + ...nTest__test_odata_boolean_argument__4.json | 392 ++++ ...nTest__test_odata_boolean_argument__5.json | 4 + ...ctionTest__test_odata_byte_argument__1.xml | 67 + ...ctionTest__test_odata_byte_argument__2.yml | 6 + ...tionTest__test_odata_byte_argument__3.json | 79 + ...tionTest__test_odata_byte_argument__4.json | 395 ++++ ...tionTest__test_odata_byte_argument__5.json | 4 + ...ctionTest__test_odata_date_argument__1.xml | 67 + ...ctionTest__test_odata_date_argument__2.yml | 6 + ...tionTest__test_odata_date_argument__3.json | 79 + ...tionTest__test_odata_date_argument__4.json | 394 ++++ ...tionTest__test_odata_date_argument__5.json | 4 + ..._test_odata_datetimeoffset_argument__1.xml | 67 + ..._test_odata_datetimeoffset_argument__2.yml | 6 + ...test_odata_datetimeoffset_argument__3.json | 79 + ...test_odata_datetimeoffset_argument__4.json | 394 ++++ ...test_odata_datetimeoffset_argument__5.json | 4 + ...onTest__test_odata_decimal_argument__1.xml | 67 + ...onTest__test_odata_decimal_argument__2.yml | 6 + ...nTest__test_odata_decimal_argument__3.json | 79 + ...nTest__test_odata_decimal_argument__4.json | 404 ++++ ...nTest__test_odata_decimal_argument__5.json | 4 + ...ionTest__test_odata_double_argument__1.xml | 67 + ...ionTest__test_odata_double_argument__2.yml | 6 + ...onTest__test_odata_double_argument__3.json | 79 + ...onTest__test_odata_double_argument__4.json | 404 ++++ ...onTest__test_odata_double_argument__5.json | 4 + ...nTest__test_odata_duration_argument__1.xml | 67 + ...nTest__test_odata_duration_argument__2.yml | 6 + ...Test__test_odata_duration_argument__3.json | 79 + ...Test__test_odata_duration_argument__4.json | 394 ++++ ...Test__test_odata_duration_argument__5.json | 4 + ...ctionTest__test_odata_guid_argument__1.xml | 67 + ...ctionTest__test_odata_guid_argument__2.yml | 6 + ...tionTest__test_odata_guid_argument__3.json | 79 + ...tionTest__test_odata_guid_argument__4.json | 394 ++++ ...tionTest__test_odata_guid_argument__5.json | 4 + ...tionTest__test_odata_int16_argument__1.xml | 67 + ...tionTest__test_odata_int16_argument__2.yml | 6 + ...ionTest__test_odata_int16_argument__3.json | 79 + ...ionTest__test_odata_int16_argument__4.json | 395 ++++ ...ionTest__test_odata_int16_argument__5.json | 4 + ...tionTest__test_odata_int32_argument__1.xml | 67 + ...tionTest__test_odata_int32_argument__2.yml | 6 + ...ionTest__test_odata_int32_argument__3.json | 79 + ...ionTest__test_odata_int32_argument__4.json | 395 ++++ ...ionTest__test_odata_int32_argument__5.json | 4 + ...tionTest__test_odata_int64_argument__1.xml | 67 + ...tionTest__test_odata_int64_argument__2.yml | 6 + ...ionTest__test_odata_int64_argument__3.json | 79 + ...ionTest__test_odata_int64_argument__4.json | 395 ++++ ...ionTest__test_odata_int64_argument__5.json | 4 + ...tionTest__test_odata_sbyte_argument__1.xml | 67 + ...tionTest__test_odata_sbyte_argument__2.yml | 6 + ...ionTest__test_odata_sbyte_argument__3.json | 79 + ...ionTest__test_odata_sbyte_argument__4.json | 395 ++++ ...ionTest__test_odata_sbyte_argument__5.json | 4 + ...ionTest__test_odata_single_argument__1.xml | 67 + ...ionTest__test_odata_single_argument__2.yml | 6 + ...onTest__test_odata_single_argument__3.json | 79 + ...onTest__test_odata_single_argument__4.json | 404 ++++ ...onTest__test_odata_single_argument__5.json | 4 + ...ionTest__test_odata_string_argument__1.xml | 67 + ...ionTest__test_odata_string_argument__2.yml | 6 + ...onTest__test_odata_string_argument__3.json | 79 + ...onTest__test_odata_string_argument__4.json | 392 ++++ ...onTest__test_odata_string_argument__5.json | 4 + ...Test__test_odata_timeofday_argument__1.xml | 67 + ...Test__test_odata_timeofday_argument__2.yml | 6 + ...est__test_odata_timeofday_argument__3.json | 79 + ...est__test_odata_timeofday_argument__4.json | 394 ++++ ...est__test_odata_timeofday_argument__5.json | 4 + ...ionTest__test_odata_uint16_argument__1.xml | 67 + ...ionTest__test_odata_uint16_argument__2.yml | 6 + ...onTest__test_odata_uint16_argument__3.json | 79 + ...onTest__test_odata_uint16_argument__4.json | 395 ++++ ...onTest__test_odata_uint16_argument__5.json | 4 + ...ionTest__test_odata_uint32_argument__1.xml | 67 + ...ionTest__test_odata_uint32_argument__2.yml | 6 + ...onTest__test_odata_uint32_argument__3.json | 79 + ...onTest__test_odata_uint32_argument__4.json | 395 ++++ ...onTest__test_odata_uint32_argument__5.json | 4 + ...ionTest__test_odata_uint64_argument__1.xml | 67 + ...ionTest__test_odata_uint64_argument__2.yml | 6 + ...onTest__test_odata_uint64_argument__3.json | 79 + ...onTest__test_odata_uint64_argument__4.json | 395 ++++ ...onTest__test_odata_uint64_argument__5.json | 4 + ...onTest__test_with_invalid_argument__1.json | 9 + ...st_with_missing_indirect_arguments__1.json | 2 +- .../NamespaceTest__test_add__1.json | 4 + .../NamespaceTest__test_metadata__1.xml | 68 + .../NamespaceTest__test_metadata__2.yml | 6 + .../NamespaceTest__test_metadata__3.json | 84 + .../NamespaceTest__test_metadata__4.json | 408 ++++ ...onTest__test_binding_did_not_exist__1.json | 9 + ...ionTest__test_binding_did_not_exist__1.yml | 3 - .../OperationTest__test_callback__1.json | 4 + ...rationTest__test_instance_callback__1.json | 4 + ...OperationTest__test_malformed_args__1.json | 9 + ...OperationTest__test_missing_invoke__1.json | 9 + .../OperationTest__test_missing_invoke__1.yml | 3 - .../OperationTest__test_namespaced__1.json | 4 + .../OperationTest__test_namespaced__2.json | 9 + .../OperationTest__test_namespaced__3.json | 9 + .../OperationTest__test_namespaced__4.json | 9 + ...perationTest__test_object_callback__1.json | 4 + ...parameter_bound_binding_wrong_type__1.json | 4 +- ...st_parameter_bound_missing_binding__1.json | 2 +- ...nTest__test_parameter_bound_modify__4.json | 2 +- ...est__test_parameter_bound_passthru__4.json | 2 +- ...onTest__test_parameter_order_bound__4.json | 63 - .../Repository73Test__test_code__1.json | 4 + .../Repository73Test__test_code_args__1.json | 4 + .../Repository73Test__test_metadata__1.xml | 145 ++ .../Repository73Test__test_metadata__2.yml | 6 + .../Repository73Test__test_metadata__3.json | 166 ++ .../Repository73Test__test_metadata__4.json | 791 +++++++ .../RepositoryTest__test_code__1.json | 4 + .../RepositoryTest__test_code_args__1.json | 4 + .../RepositoryTest__test_metadata__1.xml | 154 ++ .../RepositoryTest__test_metadata__2.yml | 6 + .../RepositoryTest__test_metadata__3.json | 198 ++ .../RepositoryTest__test_metadata__4.json | 856 ++++++++ .../__snapshots__/FilterTest__test_43__3.yml | 2 +- .../__snapshots__/FilterTest__test_43__5.yml | 2 +- .../__snapshots__/FilterTest__test_43__7.yml | 2 +- .../__snapshots__/FilterTest__test_43__9.yml | 2 +- .../__snapshots__/FilterTest__test_44__3.yml | 2 +- .../__snapshots__/FilterTest__test_44__5.yml | 2 +- .../__snapshots__/FilterTest__test_44__7.yml | 2 +- .../__snapshots__/FilterTest__test_44__9.yml | 2 +- .../__snapshots__/FilterTest__test_45__3.yml | 2 +- .../__snapshots__/FilterTest__test_45__5.yml | 2 +- .../__snapshots__/FilterTest__test_45__7.yml | 2 +- .../__snapshots__/FilterTest__test_45__9.yml | 2 +- .../__snapshots__/FilterTest__test_5f__3.yml | 2 +- .../__snapshots__/FilterTest__test_5f__5.yml | 2 +- .../__snapshots__/FilterTest__test_5f__7.yml | 2 +- .../__snapshots__/FilterTest__test_5f__9.yml | 2 +- tests/Unit/Protocol/BatchJSONTest.php | 20 +- tests/Unit/Protocol/BatchMultipartTest.php | 20 +- tests/Unit/Protocol/ContentTest.php | 54 +- tests/Unit/Protocol/ContextResourceTest.php | 13 +- tests/Unit/Protocol/TypeResponsesTest.php | 118 +- .../BatchJSONTest__test_batch__3.yml | 26 +- ...BatchJSONTest__test_partial_failure__3.yml | 26 +- .../BatchJSONTest__test_prefer_minimal__3.yml | 26 +- ...entTest__test_get_content_encoding__1.json | 4 + ...entTest__test_get_content_language__1.json | 4 + ...rAliasTest__test_nonexistent_alias__1.json | 2 +- .../NestingTest__test_schema__1.xml | 1 + .../NestingTest__test_schema__3.json | 3 +- ...test_delete_an_entity_set_primitive__1.yml | 24 +- .../Queries/EntitySet/CaseSensitivityTest.php | 29 + ...eSensitivityTest__test_name_change__1.json | 9 + ...CaseSensitivityTest__test_property__1.json | 9 + 429 files changed, 34301 insertions(+), 2835 deletions(-) delete mode 100644 phpdoc.xml create mode 100644 src/Annotation/Core/V1/PositionalInsert.php create mode 100644 src/Attributes/LodataAction.php create mode 100644 src/Attributes/LodataFunction.php create mode 100644 src/Attributes/LodataNamespace.php create mode 100644 src/Attributes/LodataOperation.php create mode 100644 src/Attributes/LodataRelationship.php delete mode 100644 src/Console/ActionCommand.php delete mode 100644 src/Console/ClassCreator.php delete mode 100644 src/Console/FunctionCommand.php delete mode 100644 src/Console/_stubs_/action.php.stub delete mode 100644 src/Console/_stubs_/function.php.stub create mode 100644 src/Exception/Protocol/ConfigurationException.php create mode 100644 src/Helper/Discovery.php delete mode 100644 src/Interfaces/Operation/ActionInterface.php delete mode 100644 src/Interfaces/Operation/ArgumentInterface.php delete mode 100644 src/Interfaces/Operation/FunctionInterface.php create mode 100644 src/Interfaces/RepositoryInterface.php create mode 100644 src/Operation/Action.php create mode 100644 src/Operation/EntityFunction.php create mode 100644 src/Operation/Function_.php create mode 100644 src/Operation/Repository.php delete mode 100644 src/Operation/TypeArgument.php create mode 100644 src/Operation/ValueArgument.php create mode 100644 src/Transaction/Option/Index.php delete mode 100644 tests/Command/CommandTest.php delete mode 100644 tests/Command/__snapshots__/files/CommandTest__test_action__1.php delete mode 100644 tests/Command/__snapshots__/files/CommandTest__test_function__1.php create mode 100644 tests/Data/TestOperations.php create mode 100644 tests/Models/Repository.php create mode 100644 tests/Operations/Instance.php create mode 100644 tests/Operations/Math.php create mode 100644 tests/Operations/Service.php create mode 100644 tests/Unit/Collection/__snapshots__/NumericCollectionTest__test_create_positional__1.json create mode 100644 tests/Unit/Collection/__snapshots__/NumericCollectionTest__test_create_positional__2.yml create mode 100644 tests/Unit/Collection/__snapshots__/NumericCollectionTest__test_create_positional__3.json create mode 100644 tests/Unit/Collection/__snapshots__/NumericCollectionTest__test_create_positional__4.json create mode 100644 tests/Unit/Collection/__snapshots__/NumericCollectionTest__test_metadata__1.xml create mode 100644 tests/Unit/Collection/__snapshots__/NumericCollectionTest__test_metadata__2.yml create mode 100644 tests/Unit/Collection/__snapshots__/NumericCollectionTest__test_metadata__3.json create mode 100644 tests/Unit/Collection/__snapshots__/NumericCollectionTest__test_metadata__4.json create mode 100644 tests/Unit/Eloquent/OperationTest.php create mode 100644 tests/Unit/Eloquent/__snapshots__/OperationTest__test_op1__1.json create mode 100644 tests/Unit/Eloquent/__snapshots__/OperationTest__test_op2__1.json create mode 100644 tests/Unit/Operation/DiscoveryTest.php create mode 100644 tests/Unit/Operation/NamespaceTest.php create mode 100644 tests/Unit/Operation/Repository73Test.php create mode 100644 tests/Unit/Operation/RepositoryTest.php create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_bound_with_parameters__1.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_date_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_date_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_date_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_date_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_date_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_binary_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_binary_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_binary_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_binary_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_binary_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_boolean_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_boolean_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_boolean_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_boolean_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_boolean_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_byte_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_byte_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_byte_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_byte_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_byte_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_date_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_date_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_date_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_date_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_date_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_datetimeoffset_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_datetimeoffset_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_datetimeoffset_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_datetimeoffset_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_datetimeoffset_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_decimal_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_decimal_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_decimal_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_decimal_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_decimal_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_double_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_double_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_double_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_double_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_double_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_duration_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_duration_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_duration_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_duration_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_duration_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_guid_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_guid_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_guid_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_guid_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_guid_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int16_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int16_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int16_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int16_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int16_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int32_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int32_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int32_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int32_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int32_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int64_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int64_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int64_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int64_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int64_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_sbyte_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_sbyte_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_sbyte_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_sbyte_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_sbyte_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_single_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_single_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_single_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_single_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_single_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_string_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_string_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_string_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_string_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_string_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_timeofday_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_timeofday_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_timeofday_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_timeofday_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_timeofday_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint16_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint16_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint16_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint16_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint16_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint32_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint32_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint32_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint32_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint32_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint64_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint64_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint64_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint64_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint64_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/DiscoveryTest__test_bind__1.json create mode 100644 tests/Unit/Operation/__snapshots__/DiscoveryTest__test_identity__1.json create mode 100644 tests/Unit/Operation/__snapshots__/DiscoveryTest__test_instance__1.json create mode 100644 tests/Unit/Operation/__snapshots__/DiscoveryTest__test_metadata__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/DiscoveryTest__test_metadata__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/DiscoveryTest__test_metadata__3.json create mode 100644 tests/Unit/Operation/__snapshots__/DiscoveryTest__test_metadata__4.json create mode 100644 tests/Unit/Operation/__snapshots__/DiscoveryTest__test_simple__1.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_callback_bound_internal_type__1.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_binary_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_binary_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_binary_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_binary_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_binary_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_boolean_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_boolean_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_boolean_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_boolean_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_boolean_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_byte_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_byte_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_byte_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_byte_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_byte_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_date_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_date_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_date_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_date_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_date_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_datetimeoffset_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_datetimeoffset_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_datetimeoffset_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_datetimeoffset_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_datetimeoffset_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_decimal_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_decimal_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_decimal_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_decimal_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_decimal_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_double_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_double_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_double_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_double_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_double_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_duration_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_duration_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_duration_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_duration_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_duration_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_guid_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_guid_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_guid_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_guid_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_guid_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int16_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int16_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int16_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int16_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int16_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int32_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int32_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int32_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int32_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int32_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int64_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int64_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int64_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int64_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int64_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_sbyte_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_sbyte_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_sbyte_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_sbyte_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_sbyte_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_single_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_single_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_single_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_single_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_single_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_string_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_string_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_string_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_string_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_string_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_timeofday_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_timeofday_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_timeofday_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_timeofday_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_timeofday_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint16_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint16_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint16_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint16_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint16_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint32_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint32_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint32_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint32_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint32_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint64_argument__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint64_argument__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint64_argument__3.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint64_argument__4.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint64_argument__5.json create mode 100644 tests/Unit/Operation/__snapshots__/FunctionTest__test_with_invalid_argument__1.json create mode 100644 tests/Unit/Operation/__snapshots__/NamespaceTest__test_add__1.json create mode 100644 tests/Unit/Operation/__snapshots__/NamespaceTest__test_metadata__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/NamespaceTest__test_metadata__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/NamespaceTest__test_metadata__3.json create mode 100644 tests/Unit/Operation/__snapshots__/NamespaceTest__test_metadata__4.json create mode 100644 tests/Unit/Operation/__snapshots__/OperationTest__test_binding_did_not_exist__1.json delete mode 100644 tests/Unit/Operation/__snapshots__/OperationTest__test_binding_did_not_exist__1.yml create mode 100644 tests/Unit/Operation/__snapshots__/OperationTest__test_callback__1.json create mode 100644 tests/Unit/Operation/__snapshots__/OperationTest__test_instance_callback__1.json create mode 100644 tests/Unit/Operation/__snapshots__/OperationTest__test_malformed_args__1.json create mode 100644 tests/Unit/Operation/__snapshots__/OperationTest__test_missing_invoke__1.json delete mode 100644 tests/Unit/Operation/__snapshots__/OperationTest__test_missing_invoke__1.yml create mode 100644 tests/Unit/Operation/__snapshots__/OperationTest__test_namespaced__1.json create mode 100644 tests/Unit/Operation/__snapshots__/OperationTest__test_namespaced__2.json create mode 100644 tests/Unit/Operation/__snapshots__/OperationTest__test_namespaced__3.json create mode 100644 tests/Unit/Operation/__snapshots__/OperationTest__test_namespaced__4.json create mode 100644 tests/Unit/Operation/__snapshots__/OperationTest__test_object_callback__1.json create mode 100644 tests/Unit/Operation/__snapshots__/Repository73Test__test_code__1.json create mode 100644 tests/Unit/Operation/__snapshots__/Repository73Test__test_code_args__1.json create mode 100644 tests/Unit/Operation/__snapshots__/Repository73Test__test_metadata__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/Repository73Test__test_metadata__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/Repository73Test__test_metadata__3.json create mode 100644 tests/Unit/Operation/__snapshots__/Repository73Test__test_metadata__4.json create mode 100644 tests/Unit/Operation/__snapshots__/RepositoryTest__test_code__1.json create mode 100644 tests/Unit/Operation/__snapshots__/RepositoryTest__test_code_args__1.json create mode 100644 tests/Unit/Operation/__snapshots__/RepositoryTest__test_metadata__1.xml create mode 100644 tests/Unit/Operation/__snapshots__/RepositoryTest__test_metadata__2.yml create mode 100644 tests/Unit/Operation/__snapshots__/RepositoryTest__test_metadata__3.json create mode 100644 tests/Unit/Operation/__snapshots__/RepositoryTest__test_metadata__4.json create mode 100644 tests/Unit/Protocol/__snapshots__/ContentTest__test_get_content_encoding__1.json create mode 100644 tests/Unit/Protocol/__snapshots__/ContentTest__test_get_content_language__1.json create mode 100644 tests/Unit/Queries/EntitySet/__snapshots__/CaseSensitivityTest__test_name_change__1.json create mode 100644 tests/Unit/Queries/EntitySet/__snapshots__/CaseSensitivityTest__test_property__1.json diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 03d9b691d..605f1a487 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -2,7 +2,7 @@ name: Documentation on: push: branches: - - 3.x + - 4.x jobs: docs: runs-on: ubuntu-latest diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 328e14047..f1ff858a5 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,7 +13,7 @@ jobs: strategy: fail-fast: true matrix: - php: [ 7.3, 7.4, 8.0 ] + php: [ 7.3, 7.4, 8.0, 8.1 ] laravel: [ 8 ] dependency-version: [ prefer-stable ] @@ -64,7 +64,7 @@ jobs: - name: Setup PHP, with composer and extensions uses: shivammathur/setup-php@v2 with: - php-version: 8.0 + php-version: 8.1 extensions: simplexml, dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick tools: composer:v2 coverage: xdebug diff --git a/composer.lock b/composer.lock index 8b0d4a1a8..aeedafc48 100644 --- a/composer.lock +++ b/composer.lock @@ -139,6 +139,81 @@ ], "time": "2021-09-13T08:41:34+00:00" }, + { + "name": "dflydev/dot-access-data", + "version": "v3.0.1", + "source": { + "type": "git", + "url": "https://github.com/dflydev/dflydev-dot-access-data.git", + "reference": "0992cc19268b259a39e86f296da5f0677841f42c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/0992cc19268b259a39e86f296da5f0677841f42c", + "reference": "0992cc19268b259a39e86f296da5f0677841f42c", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.42", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.3", + "scrutinizer/ocular": "1.6.0", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^3.14" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Dflydev\\DotAccessData\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dragonfly Development Inc.", + "email": "info@dflydev.com", + "homepage": "http://dflydev.com" + }, + { + "name": "Beau Simensen", + "email": "beau@dflydev.com", + "homepage": "http://beausimensen.com" + }, + { + "name": "Carlos Frutos", + "email": "carlos@kiwing.it", + "homepage": "https://github.com/cfrutos" + }, + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com" + } + ], + "description": "Given a deep data structure, access data by dot notation.", + "homepage": "https://github.com/dflydev/dflydev-dot-access-data", + "keywords": [ + "access", + "data", + "dot", + "notation" + ], + "support": { + "issues": "https://github.com/dflydev/dflydev-dot-access-data/issues", + "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.1" + }, + "time": "2021-08-13T13:06:58+00:00" + }, { "name": "doctrine/cache", "version": "2.1.1", @@ -240,36 +315,38 @@ }, { "name": "doctrine/dbal", - "version": "3.1.3", + "version": "3.2.0", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "96b0053775a544b4a6ab47654dac0621be8b4cf8" + "reference": "5d54f63541d7bed1156cb5c9b79274ced61890e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/96b0053775a544b4a6ab47654dac0621be8b4cf8", - "reference": "96b0053775a544b4a6ab47654dac0621be8b4cf8", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/5d54f63541d7bed1156cb5c9b79274ced61890e4", + "reference": "5d54f63541d7bed1156cb5c9b79274ced61890e4", "shasum": "" }, "require": { "composer/package-versions-deprecated": "^1.11.99", - "doctrine/cache": "^1.0|^2.0", + "doctrine/cache": "^1.11|^2.0", "doctrine/deprecations": "^0.5.3", "doctrine/event-manager": "^1.0", - "php": "^7.3 || ^8.0" + "php": "^7.3 || ^8.0", + "psr/cache": "^1|^2|^3", + "psr/log": "^1|^2|^3" }, "require-dev": { "doctrine/coding-standard": "9.0.0", "jetbrains/phpstorm-stubs": "2021.1", - "phpstan/phpstan": "0.12.99", - "phpstan/phpstan-strict-rules": "^0.12.11", + "phpstan/phpstan": "1.2.0", + "phpstan/phpstan-strict-rules": "^1.1", "phpunit/phpunit": "9.5.10", "psalm/plugin-phpunit": "0.16.1", - "squizlabs/php_codesniffer": "3.6.0", + "squizlabs/php_codesniffer": "3.6.1", "symfony/cache": "^5.2|^6.0", "symfony/console": "^2.0.5|^3.0|^4.0|^5.0|^6.0", - "vimeo/psalm": "4.10.0" + "vimeo/psalm": "4.13.0" }, "suggest": { "symfony/console": "For helpful console commands such as SQL execution and import of files." @@ -329,7 +406,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.1.3" + "source": "https://github.com/doctrine/dbal/tree/3.2.0" }, "funding": [ { @@ -345,7 +422,7 @@ "type": "tidelift" } ], - "time": "2021-10-02T16:15:05+00:00" + "time": "2021-11-26T21:00:12+00:00" }, { "name": "doctrine/deprecations", @@ -786,16 +863,16 @@ }, { "name": "graham-campbell/result-type", - "version": "v1.0.3", + "version": "v1.0.4", "source": { "type": "git", "url": "https://github.com/GrahamCampbell/Result-Type.git", - "reference": "296c015dc30ec4322168c5ad3ee5cc11dae827ac" + "reference": "0690bde05318336c7221785f2a932467f98b64ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/296c015dc30ec4322168c5ad3ee5cc11dae827ac", - "reference": "296c015dc30ec4322168c5ad3ee5cc11dae827ac", + "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/0690bde05318336c7221785f2a932467f98b64ca", + "reference": "0690bde05318336c7221785f2a932467f98b64ca", "shasum": "" }, "require": { @@ -818,7 +895,8 @@ "authors": [ { "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk" + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" } ], "description": "An Implementation Of The Result Type", @@ -831,7 +909,7 @@ ], "support": { "issues": "https://github.com/GrahamCampbell/Result-Type/issues", - "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.0.3" + "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.0.4" }, "funding": [ { @@ -843,20 +921,20 @@ "type": "tidelift" } ], - "time": "2021-10-17T19:48:54+00:00" + "time": "2021-11-21T21:41:47+00:00" }, { "name": "guzzlehttp/guzzle", - "version": "7.4.0", + "version": "7.4.1", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "868b3571a039f0ebc11ac8f344f4080babe2cb94" + "reference": "ee0a041b1760e6a53d2a39c8c34115adc2af2c79" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/868b3571a039f0ebc11ac8f344f4080babe2cb94", - "reference": "868b3571a039f0ebc11ac8f344f4080babe2cb94", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/ee0a041b1760e6a53d2a39c8c34115adc2af2c79", + "reference": "ee0a041b1760e6a53d2a39c8c34115adc2af2c79", "shasum": "" }, "require": { @@ -865,7 +943,7 @@ "guzzlehttp/psr7": "^1.8.3 || ^2.1", "php": "^7.2.5 || ^8.0", "psr/http-client": "^1.0", - "symfony/deprecation-contracts": "^2.2" + "symfony/deprecation-contracts": "^2.2 || ^3.0" }, "provide": { "psr/http-client-implementation": "1.0" @@ -951,7 +1029,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.4.0" + "source": "https://github.com/guzzle/guzzle/tree/7.4.1" }, "funding": [ { @@ -967,20 +1045,20 @@ "type": "tidelift" } ], - "time": "2021-10-18T09:52:00+00:00" + "time": "2021-12-06T18:43:05+00:00" }, { "name": "guzzlehttp/promises", - "version": "1.5.0", + "version": "1.5.1", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "136a635e2b4a49b9d79e9c8fee267ffb257fdba0" + "reference": "fe752aedc9fd8fcca3fe7ad05d419d32998a06da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/136a635e2b4a49b9d79e9c8fee267ffb257fdba0", - "reference": "136a635e2b4a49b9d79e9c8fee267ffb257fdba0", + "url": "https://api.github.com/repos/guzzle/promises/zipball/fe752aedc9fd8fcca3fe7ad05d419d32998a06da", + "reference": "fe752aedc9fd8fcca3fe7ad05d419d32998a06da", "shasum": "" }, "require": { @@ -1035,7 +1113,7 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/1.5.0" + "source": "https://github.com/guzzle/promises/tree/1.5.1" }, "funding": [ { @@ -1051,7 +1129,7 @@ "type": "tidelift" } ], - "time": "2021-10-07T13:05:22+00:00" + "time": "2021-10-22T20:56:57+00:00" }, { "name": "guzzlehttp/psr7", @@ -1170,16 +1248,16 @@ }, { "name": "laravel/framework", - "version": "v8.70.2", + "version": "v8.76.2", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "dec9524cd0f9fa35a6eb8e25d0b40f8bbc8ec225" + "reference": "c67acfdc968f487b6235435080eef62a7e2ed055" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/dec9524cd0f9fa35a6eb8e25d0b40f8bbc8ec225", - "reference": "dec9524cd0f9fa35a6eb8e25d0b40f8bbc8ec225", + "url": "https://api.github.com/repos/laravel/framework/zipball/c67acfdc968f487b6235435080eef62a7e2ed055", + "reference": "c67acfdc968f487b6235435080eef62a7e2ed055", "shasum": "" }, "require": { @@ -1201,15 +1279,15 @@ "psr/simple-cache": "^1.0", "ramsey/uuid": "^4.2.2", "swiftmailer/swiftmailer": "^6.3", - "symfony/console": "^5.1.4", - "symfony/error-handler": "^5.1.4", - "symfony/finder": "^5.1.4", - "symfony/http-foundation": "^5.1.4", - "symfony/http-kernel": "^5.1.4", - "symfony/mime": "^5.1.4", - "symfony/process": "^5.1.4", - "symfony/routing": "^5.1.4", - "symfony/var-dumper": "^5.1.4", + "symfony/console": "^5.4", + "symfony/error-handler": "^5.4", + "symfony/finder": "^5.4", + "symfony/http-foundation": "^5.4", + "symfony/http-kernel": "^5.4", + "symfony/mime": "^5.4", + "symfony/process": "^5.4", + "symfony/routing": "^5.4", + "symfony/var-dumper": "^5.4", "tijsverkoyen/css-to-inline-styles": "^2.2.2", "vlucas/phpdotenv": "^5.2", "voku/portable-ascii": "^1.4.8" @@ -1256,21 +1334,21 @@ }, "require-dev": { "aws/aws-sdk-php": "^3.198.1", - "doctrine/dbal": "^2.13.3|^3.1.2", + "doctrine/dbal": "^2.13.3|^3.1.4", "filp/whoops": "^2.14.3", "guzzlehttp/guzzle": "^6.5.5|^7.0.1", "league/flysystem-cached-adapter": "^1.0", "mockery/mockery": "^1.4.4", - "orchestra/testbench-core": "^6.23", + "orchestra/testbench-core": "^6.27", "pda/pheanstalk": "^4.0", "phpunit/phpunit": "^8.5.19|^9.5.8", "predis/predis": "^1.1.9", - "symfony/cache": "^5.1.4" + "symfony/cache": "^5.4" }, "suggest": { "aws/aws-sdk-php": "Required to use the SQS queue driver, DynamoDb failed job storage and SES mail driver (^3.198.1).", "brianium/paratest": "Required to run tests in parallel (^6.0).", - "doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.13.3|^3.1.2).", + "doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.13.3|^3.1.4).", "ext-bcmath": "Required to use the multiple_of validation rule.", "ext-ftp": "Required to use the Flysystem FTP driver.", "ext-gd": "Required to use Illuminate\\Http\\Testing\\FileFactory::image().", @@ -1291,9 +1369,9 @@ "phpunit/phpunit": "Required to use assertions and run tests (^8.5.19|^9.5.8).", "predis/predis": "Required to use the predis connector (^1.1.9).", "psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).", - "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^4.0|^5.0|^6.0).", - "symfony/cache": "Required to PSR-6 cache bridge (^5.1.4).", - "symfony/filesystem": "Required to enable support for relative symbolic links (^5.1.4).", + "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^4.0|^5.0|^6.0|^7.0).", + "symfony/cache": "Required to PSR-6 cache bridge (^5.4).", + "symfony/filesystem": "Required to enable support for relative symbolic links (^5.4).", "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^2.0).", "wildbit/swiftmailer-postmark": "Required to use Postmark mail driver (^3.0)." }, @@ -1338,20 +1416,20 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2021-11-09T22:48:33+00:00" + "time": "2021-12-15T14:02:14+00:00" }, { "name": "laravel/serializable-closure", - "version": "v1.0.3", + "version": "v1.0.5", "source": { "type": "git", "url": "https://github.com/laravel/serializable-closure.git", - "reference": "6cfc678735f22ccedad761b8cae2bab14c3d8e5b" + "reference": "25de3be1bca1b17d52ff0dc02b646c667ac7266c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/6cfc678735f22ccedad761b8cae2bab14c3d8e5b", - "reference": "6cfc678735f22ccedad761b8cae2bab14c3d8e5b", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/25de3be1bca1b17d52ff0dc02b646c667ac7266c", + "reference": "25de3be1bca1b17d52ff0dc02b646c667ac7266c", "shasum": "" }, "require": { @@ -1397,46 +1475,55 @@ "issues": "https://github.com/laravel/serializable-closure/issues", "source": "https://github.com/laravel/serializable-closure" }, - "time": "2021-10-07T14:00:57+00:00" + "time": "2021-11-30T15:53:04+00:00" }, { "name": "league/commonmark", - "version": "1.6.6", + "version": "2.1.0", "source": { "type": "git", "url": "https://github.com/thephpleague/commonmark.git", - "reference": "c4228d11e30d7493c6836d20872f9582d8ba6dcf" + "reference": "819276bc54e83c160617d3ac0a436c239e479928" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/c4228d11e30d7493c6836d20872f9582d8ba6dcf", - "reference": "c4228d11e30d7493c6836d20872f9582d8ba6dcf", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/819276bc54e83c160617d3ac0a436c239e479928", + "reference": "819276bc54e83c160617d3ac0a436c239e479928", "shasum": "" }, "require": { "ext-mbstring": "*", - "php": "^7.1 || ^8.0" - }, - "conflict": { - "scrutinizer/ocular": "1.7.*" + "league/config": "^1.1.1", + "php": "^7.4 || ^8.0", + "psr/event-dispatcher": "^1.0", + "symfony/polyfill-php80": "^1.15" }, "require-dev": { - "cebe/markdown": "~1.0", - "commonmark/commonmark.js": "0.29.2", - "erusev/parsedown": "~1.0", + "cebe/markdown": "^1.0", + "commonmark/cmark": "0.30.0", + "commonmark/commonmark.js": "0.30.0", + "composer/package-versions-deprecated": "^1.8", + "erusev/parsedown": "^1.0", "ext-json": "*", "github/gfm": "0.29.0", - "michelf/php-markdown": "~1.4", - "mikehaertl/php-shellcommand": "^1.4", - "phpstan/phpstan": "^0.12.90", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.2", - "scrutinizer/ocular": "^1.5", - "symfony/finder": "^4.2" + "michelf/php-markdown": "^1.4", + "phpstan/phpstan": "^0.12.88 || ^1.0.0", + "phpunit/phpunit": "^9.5.5", + "scrutinizer/ocular": "^1.8.1", + "symfony/finder": "^5.3", + "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0", + "unleashedtech/php-coding-standard": "^3.1", + "vimeo/psalm": "^4.7.3" + }, + "suggest": { + "symfony/yaml": "v2.3+ required if using the Front Matter extension" }, - "bin": [ - "bin/commonmark" - ], "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.2-dev" + } + }, "autoload": { "psr-4": { "League\\CommonMark\\": "src" @@ -1454,7 +1541,7 @@ "role": "Lead Developer" } ], - "description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and Github-Flavored Markdown (GFM)", + "description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and GitHub-Flavored Markdown (GFM)", "homepage": "https://commonmark.thephpleague.com", "keywords": [ "commonmark", @@ -1468,15 +1555,12 @@ ], "support": { "docs": "https://commonmark.thephpleague.com/", + "forum": "https://github.com/thephpleague/commonmark/discussions", "issues": "https://github.com/thephpleague/commonmark/issues", "rss": "https://github.com/thephpleague/commonmark/releases.atom", "source": "https://github.com/thephpleague/commonmark" }, "funding": [ - { - "url": "https://enjoy.gitstore.app/repositories/thephpleague/commonmark", - "type": "custom" - }, { "url": "https://www.colinodell.com/sponsor", "type": "custom" @@ -1489,29 +1573,107 @@ "url": "https://github.com/colinodell", "type": "github" }, - { - "url": "https://www.patreon.com/colinodell", - "type": "patreon" - }, { "url": "https://tidelift.com/funding/github/packagist/league/commonmark", "type": "tidelift" } ], - "time": "2021-07-17T17:13:23+00:00" + "time": "2021-12-05T18:25:20+00:00" + }, + { + "name": "league/config", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/config.git", + "reference": "a9d39eeeb6cc49d10a6e6c36f22c4c1f4a767f3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/config/zipball/a9d39eeeb6cc49d10a6e6c36f22c4c1f4a767f3e", + "reference": "a9d39eeeb6cc49d10a6e6c36f22c4c1f4a767f3e", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^3.0.1", + "nette/schema": "^1.2", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.90", + "phpunit/phpunit": "^9.5.5", + "scrutinizer/ocular": "^1.8.1", + "unleashedtech/php-coding-standard": "^3.1", + "vimeo/psalm": "^4.7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Config\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" + } + ], + "description": "Define configuration arrays with strict schemas and access values with dot notation", + "homepage": "https://config.thephpleague.com", + "keywords": [ + "array", + "config", + "configuration", + "dot", + "dot-access", + "nested", + "schema" + ], + "support": { + "docs": "https://config.thephpleague.com/", + "issues": "https://github.com/thephpleague/config/issues", + "rss": "https://github.com/thephpleague/config/releases.atom", + "source": "https://github.com/thephpleague/config" + }, + "funding": [ + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + } + ], + "time": "2021-08-14T12:15:32+00:00" }, { "name": "league/flysystem", - "version": "1.1.5", + "version": "1.1.9", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "18634df356bfd4119fe3d6156bdb990c414c14ea" + "reference": "094defdb4a7001845300334e7c1ee2335925ef99" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/18634df356bfd4119fe3d6156bdb990c414c14ea", - "reference": "18634df356bfd4119fe3d6156bdb990c414c14ea", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/094defdb4a7001845300334e7c1ee2335925ef99", + "reference": "094defdb4a7001845300334e7c1ee2335925ef99", "shasum": "" }, "require": { @@ -1584,7 +1746,7 @@ ], "support": { "issues": "https://github.com/thephpleague/flysystem/issues", - "source": "https://github.com/thephpleague/flysystem/tree/1.1.5" + "source": "https://github.com/thephpleague/flysystem/tree/1.1.9" }, "funding": [ { @@ -1592,20 +1754,20 @@ "type": "other" } ], - "time": "2021-08-17T13:49:42+00:00" + "time": "2021-12-09T09:40:50+00:00" }, { "name": "league/mime-type-detection", - "version": "1.8.0", + "version": "1.9.0", "source": { "type": "git", "url": "https://github.com/thephpleague/mime-type-detection.git", - "reference": "b38b25d7b372e9fddb00335400467b223349fd7e" + "reference": "aa70e813a6ad3d1558fc927863d47309b4c23e69" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/b38b25d7b372e9fddb00335400467b223349fd7e", - "reference": "b38b25d7b372e9fddb00335400467b223349fd7e", + "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/aa70e813a6ad3d1558fc927863d47309b4c23e69", + "reference": "aa70e813a6ad3d1558fc927863d47309b4c23e69", "shasum": "" }, "require": { @@ -1613,7 +1775,7 @@ "php": "^7.2 || ^8.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^2.18", + "friendsofphp/php-cs-fixer": "^3.2", "phpstan/phpstan": "^0.12.68", "phpunit/phpunit": "^8.5.8 || ^9.3" }, @@ -1636,7 +1798,7 @@ "description": "Mime-type detection for Flysystem", "support": { "issues": "https://github.com/thephpleague/mime-type-detection/issues", - "source": "https://github.com/thephpleague/mime-type-detection/tree/1.8.0" + "source": "https://github.com/thephpleague/mime-type-detection/tree/1.9.0" }, "funding": [ { @@ -1648,7 +1810,7 @@ "type": "tidelift" } ], - "time": "2021-09-25T08:23:19+00:00" + "time": "2021-11-21T11:48:40+00:00" }, { "name": "monolog/monolog", @@ -1751,16 +1913,16 @@ }, { "name": "nesbot/carbon", - "version": "2.54.0", + "version": "2.55.2", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "eed83939f1aed3eee517d03a33f5ec587ac529b5" + "reference": "8c2a18ce3e67c34efc1b29f64fe61304368259a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/eed83939f1aed3eee517d03a33f5ec587ac529b5", - "reference": "eed83939f1aed3eee517d03a33f5ec587ac529b5", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/8c2a18ce3e67c34efc1b29f64fe61304368259a2", + "reference": "8c2a18ce3e67c34efc1b29f64fe61304368259a2", "shasum": "" }, "require": { @@ -1768,7 +1930,7 @@ "php": "^7.1.8 || ^8.0", "symfony/polyfill-mbstring": "^1.0", "symfony/polyfill-php80": "^1.16", - "symfony/translation": "^3.4 || ^4.0 || ^5.0" + "symfony/translation": "^3.4 || ^4.0 || ^5.0 || ^6.0" }, "require-dev": { "doctrine/dbal": "^2.0 || ^3.0", @@ -1829,6 +1991,7 @@ "time" ], "support": { + "docs": "https://carbon.nesbot.com/docs", "issues": "https://github.com/briannesbitt/Carbon/issues", "source": "https://github.com/briannesbitt/Carbon" }, @@ -1842,7 +2005,154 @@ "type": "tidelift" } ], - "time": "2021-11-01T21:22:20+00:00" + "time": "2021-12-03T14:59:52+00:00" + }, + { + "name": "nette/schema", + "version": "v1.2.2", + "source": { + "type": "git", + "url": "https://github.com/nette/schema.git", + "reference": "9a39cef03a5b34c7de64f551538cbba05c2be5df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/schema/zipball/9a39cef03a5b34c7de64f551538cbba05c2be5df", + "reference": "9a39cef03a5b34c7de64f551538cbba05c2be5df", + "shasum": "" + }, + "require": { + "nette/utils": "^2.5.7 || ^3.1.5 || ^4.0", + "php": ">=7.1 <8.2" + }, + "require-dev": { + "nette/tester": "^2.3 || ^2.4", + "phpstan/phpstan-nette": "^0.12", + "tracy/tracy": "^2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📐 Nette Schema: validating data structures against a given Schema.", + "homepage": "https://nette.org", + "keywords": [ + "config", + "nette" + ], + "support": { + "issues": "https://github.com/nette/schema/issues", + "source": "https://github.com/nette/schema/tree/v1.2.2" + }, + "time": "2021-10-15T11:40:02+00:00" + }, + { + "name": "nette/utils", + "version": "v3.2.6", + "source": { + "type": "git", + "url": "https://github.com/nette/utils.git", + "reference": "2f261e55bd6a12057442045bf2c249806abc1d02" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/utils/zipball/2f261e55bd6a12057442045bf2c249806abc1d02", + "reference": "2f261e55bd6a12057442045bf2c249806abc1d02", + "shasum": "" + }, + "require": { + "php": ">=7.2 <8.2" + }, + "conflict": { + "nette/di": "<3.0.6" + }, + "require-dev": { + "nette/tester": "~2.0", + "phpstan/phpstan": "^1.0", + "tracy/tracy": "^2.3" + }, + "suggest": { + "ext-gd": "to use Image", + "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()", + "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()", + "ext-xml": "to use Strings::length() etc. when mbstring is not available" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", + "homepage": "https://nette.org", + "keywords": [ + "array", + "core", + "datetime", + "images", + "json", + "nette", + "paginator", + "password", + "slugify", + "string", + "unicode", + "utf-8", + "utility", + "validation" + ], + "support": { + "issues": "https://github.com/nette/utils/issues", + "source": "https://github.com/nette/utils/tree/v3.2.6" + }, + "time": "2021-11-24T15:47:23+00:00" }, { "name": "opis/closure", @@ -1911,16 +2221,16 @@ }, { "name": "phpoption/phpoption", - "version": "1.8.0", + "version": "1.8.1", "source": { "type": "git", "url": "https://github.com/schmittjoh/php-option.git", - "reference": "5455cb38aed4523f99977c4a12ef19da4bfe2a28" + "reference": "eab7a0df01fe2344d172bff4cd6dbd3f8b84ad15" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/5455cb38aed4523f99977c4a12ef19da4bfe2a28", - "reference": "5455cb38aed4523f99977c4a12ef19da4bfe2a28", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/eab7a0df01fe2344d172bff4cd6dbd3f8b84ad15", + "reference": "eab7a0df01fe2344d172bff4cd6dbd3f8b84ad15", "shasum": "" }, "require": { @@ -1928,7 +2238,7 @@ }, "require-dev": { "bamarni/composer-bin-plugin": "^1.4.1", - "phpunit/phpunit": "^6.5.14 || ^7.0.20 || ^8.5.19 || ^9.5.8" + "phpunit/phpunit": "^6.5.14 || ^7.5.20 || ^8.5.19 || ^9.5.8" }, "type": "library", "extra": { @@ -1948,11 +2258,13 @@ "authors": [ { "name": "Johannes M. Schmitt", - "email": "schmittjoh@gmail.com" + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh" }, { "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk" + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" } ], "description": "Option Type for PHP", @@ -1964,7 +2276,7 @@ ], "support": { "issues": "https://github.com/schmittjoh/php-option/issues", - "source": "https://github.com/schmittjoh/php-option/tree/1.8.0" + "source": "https://github.com/schmittjoh/php-option/tree/1.8.1" }, "funding": [ { @@ -1976,24 +2288,73 @@ "type": "tidelift" } ], - "time": "2021-08-28T21:27:29+00:00" + "time": "2021-12-04T23:24:31+00:00" + }, + { + "name": "psr/cache", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "support": { + "source": "https://github.com/php-fig/cache/tree/master" + }, + "time": "2016-08-06T20:24:11+00:00" }, { "name": "psr/container", - "version": "1.1.1", + "version": "1.1.2", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf" + "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf", - "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf", + "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", + "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", "shasum": "" }, "require": { - "php": ">=7.2.0" + "php": ">=7.4.0" }, "type": "library", "autoload": { @@ -2022,9 +2383,9 @@ ], "support": { "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/1.1.1" + "source": "https://github.com/php-fig/container/tree/1.1.2" }, - "time": "2021-03-05T17:36:06+00:00" + "time": "2021-11-05T16:50:12+00:00" }, { "name": "psr/event-dispatcher", @@ -2631,30 +2992,31 @@ "type": "tidelift" } ], + "abandoned": "symfony/mailer", "time": "2021-10-18T15:26:12+00:00" }, { "name": "symfony/console", - "version": "v5.3.10", + "version": "v5.4.1", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "d4e409d9fbcfbf71af0e5a940abb7b0b4bad0bd3" + "reference": "9130e1a0fc93cb0faadca4ee917171bd2ca9e5f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/d4e409d9fbcfbf71af0e5a940abb7b0b4bad0bd3", - "reference": "d4e409d9fbcfbf71af0e5a940abb7b0b4bad0bd3", + "url": "https://api.github.com/repos/symfony/console/zipball/9130e1a0fc93cb0faadca4ee917171bd2ca9e5f4", + "reference": "9130e1a0fc93cb0faadca4ee917171bd2ca9e5f4", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php73": "^1.8", + "symfony/polyfill-php73": "^1.9", "symfony/polyfill-php80": "^1.16", - "symfony/service-contracts": "^1.1|^2", - "symfony/string": "^5.1" + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/string": "^5.1|^6.0" }, "conflict": { "psr/log": ">=3", @@ -2669,12 +3031,12 @@ }, "require-dev": { "psr/log": "^1|^2", - "symfony/config": "^4.4|^5.0", - "symfony/dependency-injection": "^4.4|^5.0", - "symfony/event-dispatcher": "^4.4|^5.0", - "symfony/lock": "^4.4|^5.0", - "symfony/process": "^4.4|^5.0", - "symfony/var-dumper": "^4.4|^5.0" + "symfony/config": "^4.4|^5.0|^6.0", + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/event-dispatcher": "^4.4|^5.0|^6.0", + "symfony/lock": "^4.4|^5.0|^6.0", + "symfony/process": "^4.4|^5.0|^6.0", + "symfony/var-dumper": "^4.4|^5.0|^6.0" }, "suggest": { "psr/log": "For using the console logger", @@ -2714,7 +3076,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.3.10" + "source": "https://github.com/symfony/console/tree/v5.4.1" }, "funding": [ { @@ -2730,20 +3092,20 @@ "type": "tidelift" } ], - "time": "2021-10-26T09:30:15+00:00" + "time": "2021-12-09T11:22:43+00:00" }, { "name": "symfony/css-selector", - "version": "v5.3.4", + "version": "v5.4.0", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "7fb120adc7f600a59027775b224c13a33530dd90" + "reference": "44b933f98bb4b5220d10bed9ce5662f8c2d13dcc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/7fb120adc7f600a59027775b224c13a33530dd90", - "reference": "7fb120adc7f600a59027775b224c13a33530dd90", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/44b933f98bb4b5220d10bed9ce5662f8c2d13dcc", + "reference": "44b933f98bb4b5220d10bed9ce5662f8c2d13dcc", "shasum": "" }, "require": { @@ -2780,7 +3142,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v5.3.4" + "source": "https://github.com/symfony/css-selector/tree/v5.4.0" }, "funding": [ { @@ -2796,20 +3158,20 @@ "type": "tidelift" } ], - "time": "2021-07-21T12:38:00+00:00" + "time": "2021-09-09T08:06:01+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v2.4.0", + "version": "v2.5.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627" + "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5f38c8804a9e97d23e0c8d63341088cd8a22d627", - "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/6f981ee24cf69ee7ce9736146d1c57c2780598a8", + "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8", "shasum": "" }, "require": { @@ -2818,7 +3180,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.4-dev" + "dev-main": "2.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -2847,7 +3209,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v2.4.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.0" }, "funding": [ { @@ -2863,32 +3225,35 @@ "type": "tidelift" } ], - "time": "2021-03-23T23:28:01+00:00" + "time": "2021-07-12T14:48:14+00:00" }, { "name": "symfony/error-handler", - "version": "v5.3.7", + "version": "v5.4.1", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "3bc60d0fba00ae8d1eaa9eb5ab11a2bbdd1fc321" + "reference": "1e3cb3565af49cd5f93e5787500134500a29f0d9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/3bc60d0fba00ae8d1eaa9eb5ab11a2bbdd1fc321", - "reference": "3bc60d0fba00ae8d1eaa9eb5ab11a2bbdd1fc321", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/1e3cb3565af49cd5f93e5787500134500a29f0d9", + "reference": "1e3cb3565af49cd5f93e5787500134500a29f0d9", "shasum": "" }, "require": { "php": ">=7.2.5", "psr/log": "^1|^2|^3", - "symfony/var-dumper": "^4.4|^5.0" + "symfony/var-dumper": "^4.4|^5.0|^6.0" }, "require-dev": { - "symfony/deprecation-contracts": "^2.1", - "symfony/http-kernel": "^4.4|^5.0", - "symfony/serializer": "^4.4|^5.0" + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/http-kernel": "^4.4|^5.0|^6.0", + "symfony/serializer": "^4.4|^5.0|^6.0" }, + "bin": [ + "Resources/bin/patch-type-declarations" + ], "type": "library", "autoload": { "psr-4": { @@ -2915,7 +3280,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v5.3.7" + "source": "https://github.com/symfony/error-handler/tree/v5.4.1" }, "funding": [ { @@ -2931,26 +3296,26 @@ "type": "tidelift" } ], - "time": "2021-08-28T15:07:08+00:00" + "time": "2021-12-01T15:04:08+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v5.3.7", + "version": "v5.4.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "ce7b20d69c66a20939d8952b617506a44d102130" + "reference": "27d39ae126352b9fa3be5e196ccf4617897be3eb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/ce7b20d69c66a20939d8952b617506a44d102130", - "reference": "ce7b20d69c66a20939d8952b617506a44d102130", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/27d39ae126352b9fa3be5e196ccf4617897be3eb", + "reference": "27d39ae126352b9fa3be5e196ccf4617897be3eb", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", - "symfony/event-dispatcher-contracts": "^2", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/event-dispatcher-contracts": "^2|^3", "symfony/polyfill-php80": "^1.16" }, "conflict": { @@ -2962,13 +3327,13 @@ }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^4.4|^5.0", - "symfony/dependency-injection": "^4.4|^5.0", - "symfony/error-handler": "^4.4|^5.0", - "symfony/expression-language": "^4.4|^5.0", - "symfony/http-foundation": "^4.4|^5.0", - "symfony/service-contracts": "^1.1|^2", - "symfony/stopwatch": "^4.4|^5.0" + "symfony/config": "^4.4|^5.0|^6.0", + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/error-handler": "^4.4|^5.0|^6.0", + "symfony/expression-language": "^4.4|^5.0|^6.0", + "symfony/http-foundation": "^4.4|^5.0|^6.0", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/stopwatch": "^4.4|^5.0|^6.0" }, "suggest": { "symfony/dependency-injection": "", @@ -3000,7 +3365,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v5.3.7" + "source": "https://github.com/symfony/event-dispatcher/tree/v5.4.0" }, "funding": [ { @@ -3016,20 +3381,20 @@ "type": "tidelift" } ], - "time": "2021-08-04T21:20:46+00:00" + "time": "2021-11-23T10:19:22+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v2.4.0", + "version": "v2.5.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "69fee1ad2332a7cbab3aca13591953da9cdb7a11" + "reference": "66bea3b09be61613cd3b4043a65a8ec48cfa6d2a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/69fee1ad2332a7cbab3aca13591953da9cdb7a11", - "reference": "69fee1ad2332a7cbab3aca13591953da9cdb7a11", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/66bea3b09be61613cd3b4043a65a8ec48cfa6d2a", + "reference": "66bea3b09be61613cd3b4043a65a8ec48cfa6d2a", "shasum": "" }, "require": { @@ -3042,7 +3407,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.4-dev" + "dev-main": "2.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -3079,7 +3444,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.4.0" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.5.0" }, "funding": [ { @@ -3095,24 +3460,25 @@ "type": "tidelift" } ], - "time": "2021-03-23T23:28:01+00:00" + "time": "2021-07-12T14:48:14+00:00" }, { "name": "symfony/finder", - "version": "v5.3.7", + "version": "v5.4.0", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "a10000ada1e600d109a6c7632e9ac42e8bf2fb93" + "reference": "d2f29dac98e96a98be467627bd49c2efb1bc2590" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/a10000ada1e600d109a6c7632e9ac42e8bf2fb93", - "reference": "a10000ada1e600d109a6c7632e9ac42e8bf2fb93", + "url": "https://api.github.com/repos/symfony/finder/zipball/d2f29dac98e96a98be467627bd49c2efb1bc2590", + "reference": "d2f29dac98e96a98be467627bd49c2efb1bc2590", "shasum": "" }, "require": { "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-php80": "^1.16" }, "type": "library", @@ -3141,7 +3507,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v5.3.7" + "source": "https://github.com/symfony/finder/tree/v5.4.0" }, "funding": [ { @@ -3157,111 +3523,33 @@ "type": "tidelift" } ], - "time": "2021-08-04T21:20:46+00:00" - }, - { - "name": "symfony/http-client-contracts", - "version": "v2.4.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "7e82f6084d7cae521a75ef2cb5c9457bbda785f4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/7e82f6084d7cae521a75ef2cb5c9457bbda785f4", - "reference": "7e82f6084d7cae521a75ef2cb5c9457bbda785f4", - "shasum": "" - }, - "require": { - "php": ">=7.2.5" - }, - "suggest": { - "symfony/http-client-implementation": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.4-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\HttpClient\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Generic abstractions related to HTTP clients", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "support": { - "source": "https://github.com/symfony/http-client-contracts/tree/v2.4.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-04-11T23:07:08+00:00" + "time": "2021-11-28T15:25:38+00:00" }, { "name": "symfony/http-foundation", - "version": "v5.3.10", + "version": "v5.4.1", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "9f34f02e8a5fdc7a56bafe011cea1ce97300e54c" + "reference": "5dad3780023a707f4c24beac7d57aead85c1ce3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/9f34f02e8a5fdc7a56bafe011cea1ce97300e54c", - "reference": "9f34f02e8a5fdc7a56bafe011cea1ce97300e54c", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/5dad3780023a707f4c24beac7d57aead85c1ce3c", + "reference": "5dad3780023a707f4c24beac7d57aead85c1ce3c", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-mbstring": "~1.1", "symfony/polyfill-php80": "^1.16" }, "require-dev": { "predis/predis": "~1.0", - "symfony/cache": "^4.4|^5.0", - "symfony/expression-language": "^4.4|^5.0", - "symfony/mime": "^4.4|^5.0" + "symfony/cache": "^4.4|^5.0|^6.0", + "symfony/expression-language": "^4.4|^5.0|^6.0", + "symfony/mime": "^4.4|^5.0|^6.0" }, "suggest": { "symfony/mime": "To use the file extension guesser" @@ -3292,7 +3580,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v5.3.10" + "source": "https://github.com/symfony/http-foundation/tree/v5.4.1" }, "funding": [ { @@ -3308,36 +3596,35 @@ "type": "tidelift" } ], - "time": "2021-10-11T15:41:55+00:00" + "time": "2021-12-09T12:46:57+00:00" }, { "name": "symfony/http-kernel", - "version": "v5.3.10", + "version": "v5.4.1", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "703e4079920468e9522b72cf47fd76ce8d795e86" + "reference": "2bdace75c9d6a6eec7e318801b7dc87a72375052" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/703e4079920468e9522b72cf47fd76ce8d795e86", - "reference": "703e4079920468e9522b72cf47fd76ce8d795e86", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/2bdace75c9d6a6eec7e318801b7dc87a72375052", + "reference": "2bdace75c9d6a6eec7e318801b7dc87a72375052", "shasum": "" }, "require": { "php": ">=7.2.5", "psr/log": "^1|^2", - "symfony/deprecation-contracts": "^2.1", - "symfony/error-handler": "^4.4|^5.0", - "symfony/event-dispatcher": "^5.0", - "symfony/http-client-contracts": "^1.1|^2", - "symfony/http-foundation": "^5.3.7", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/error-handler": "^4.4|^5.0|^6.0", + "symfony/event-dispatcher": "^5.0|^6.0", + "symfony/http-foundation": "^5.3.7|^6.0", "symfony/polyfill-ctype": "^1.8", "symfony/polyfill-php73": "^1.9", "symfony/polyfill-php80": "^1.16" }, "conflict": { - "symfony/browser-kit": "<4.4", + "symfony/browser-kit": "<5.4", "symfony/cache": "<5.0", "symfony/config": "<5.0", "symfony/console": "<4.4", @@ -3357,19 +3644,20 @@ }, "require-dev": { "psr/cache": "^1.0|^2.0|^3.0", - "symfony/browser-kit": "^4.4|^5.0", - "symfony/config": "^5.0", - "symfony/console": "^4.4|^5.0", - "symfony/css-selector": "^4.4|^5.0", - "symfony/dependency-injection": "^5.3", - "symfony/dom-crawler": "^4.4|^5.0", - "symfony/expression-language": "^4.4|^5.0", - "symfony/finder": "^4.4|^5.0", - "symfony/process": "^4.4|^5.0", - "symfony/routing": "^4.4|^5.0", - "symfony/stopwatch": "^4.4|^5.0", - "symfony/translation": "^4.4|^5.0", - "symfony/translation-contracts": "^1.1|^2", + "symfony/browser-kit": "^5.4|^6.0", + "symfony/config": "^5.0|^6.0", + "symfony/console": "^4.4|^5.0|^6.0", + "symfony/css-selector": "^4.4|^5.0|^6.0", + "symfony/dependency-injection": "^5.3|^6.0", + "symfony/dom-crawler": "^4.4|^5.0|^6.0", + "symfony/expression-language": "^4.4|^5.0|^6.0", + "symfony/finder": "^4.4|^5.0|^6.0", + "symfony/http-client-contracts": "^1.1|^2|^3", + "symfony/process": "^4.4|^5.0|^6.0", + "symfony/routing": "^4.4|^5.0|^6.0", + "symfony/stopwatch": "^4.4|^5.0|^6.0", + "symfony/translation": "^4.4|^5.0|^6.0", + "symfony/translation-contracts": "^1.1|^2|^3", "twig/twig": "^2.13|^3.0.4" }, "suggest": { @@ -3404,7 +3692,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v5.3.10" + "source": "https://github.com/symfony/http-kernel/tree/v5.4.1" }, "funding": [ { @@ -3420,25 +3708,25 @@ "type": "tidelift" } ], - "time": "2021-10-29T08:36:48+00:00" + "time": "2021-12-09T13:36:09+00:00" }, { "name": "symfony/mime", - "version": "v5.3.8", + "version": "v5.4.0", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "a756033d0a7e53db389618653ae991eba5a19a11" + "reference": "d4365000217b67c01acff407573906ff91bcfb34" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/a756033d0a7e53db389618653ae991eba5a19a11", - "reference": "a756033d0a7e53db389618653ae991eba5a19a11", + "url": "https://api.github.com/repos/symfony/mime/zipball/d4365000217b67c01acff407573906ff91bcfb34", + "reference": "d4365000217b67c01acff407573906ff91bcfb34", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-intl-idn": "^1.10", "symfony/polyfill-mbstring": "^1.0", "symfony/polyfill-php80": "^1.16" @@ -3452,10 +3740,10 @@ "require-dev": { "egulias/email-validator": "^2.1.10|^3.1", "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", - "symfony/dependency-injection": "^4.4|^5.0", - "symfony/property-access": "^4.4|^5.1", - "symfony/property-info": "^4.4|^5.1", - "symfony/serializer": "^5.2" + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/property-access": "^4.4|^5.1|^6.0", + "symfony/property-info": "^4.4|^5.1|^6.0", + "symfony/serializer": "^5.2|^6.0" }, "type": "library", "autoload": { @@ -3487,7 +3775,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v5.3.8" + "source": "https://github.com/symfony/mime/tree/v5.4.0" }, "funding": [ { @@ -3503,7 +3791,7 @@ "type": "tidelift" } ], - "time": "2021-09-10T12:30:38+00:00" + "time": "2021-11-23T10:19:22+00:00" }, { "name": "symfony/polyfill-ctype", @@ -4315,16 +4603,16 @@ }, { "name": "symfony/process", - "version": "v5.3.7", + "version": "v5.4.0", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "38f26c7d6ed535217ea393e05634cb0b244a1967" + "reference": "5be20b3830f726e019162b26223110c8f47cf274" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/38f26c7d6ed535217ea393e05634cb0b244a1967", - "reference": "38f26c7d6ed535217ea393e05634cb0b244a1967", + "url": "https://api.github.com/repos/symfony/process/zipball/5be20b3830f726e019162b26223110c8f47cf274", + "reference": "5be20b3830f726e019162b26223110c8f47cf274", "shasum": "" }, "require": { @@ -4357,7 +4645,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v5.3.7" + "source": "https://github.com/symfony/process/tree/v5.4.0" }, "funding": [ { @@ -4373,25 +4661,25 @@ "type": "tidelift" } ], - "time": "2021-08-04T21:20:46+00:00" + "time": "2021-11-28T15:25:38+00:00" }, { "name": "symfony/routing", - "version": "v5.3.7", + "version": "v5.4.0", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "be865017746fe869007d94220ad3f5297951811b" + "reference": "9eeae93c32ca86746e5d38f3679e9569981038b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/be865017746fe869007d94220ad3f5297951811b", - "reference": "be865017746fe869007d94220ad3f5297951811b", + "url": "https://api.github.com/repos/symfony/routing/zipball/9eeae93c32ca86746e5d38f3679e9569981038b1", + "reference": "9eeae93c32ca86746e5d38f3679e9569981038b1", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-php80": "^1.16" }, "conflict": { @@ -4403,11 +4691,11 @@ "require-dev": { "doctrine/annotations": "^1.12", "psr/log": "^1|^2|^3", - "symfony/config": "^5.3", - "symfony/dependency-injection": "^4.4|^5.0", - "symfony/expression-language": "^4.4|^5.0", - "symfony/http-foundation": "^4.4|^5.0", - "symfony/yaml": "^4.4|^5.0" + "symfony/config": "^5.3|^6.0", + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/expression-language": "^4.4|^5.0|^6.0", + "symfony/http-foundation": "^4.4|^5.0|^6.0", + "symfony/yaml": "^4.4|^5.0|^6.0" }, "suggest": { "symfony/config": "For using the all-in-one router or any loader", @@ -4447,7 +4735,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v5.3.7" + "source": "https://github.com/symfony/routing/tree/v5.4.0" }, "funding": [ { @@ -4463,25 +4751,29 @@ "type": "tidelift" } ], - "time": "2021-08-04T21:42:42+00:00" + "time": "2021-11-23T10:19:22+00:00" }, { "name": "symfony/service-contracts", - "version": "v2.4.0", + "version": "v2.5.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb" + "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb", - "reference": "f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", + "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", "shasum": "" }, "require": { "php": ">=7.2.5", - "psr/container": "^1.1" + "psr/container": "^1.1", + "symfony/deprecation-contracts": "^2.1" + }, + "conflict": { + "ext-psr": "<1.1|>=2" }, "suggest": { "symfony/service-implementation": "" @@ -4489,7 +4781,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.4-dev" + "dev-main": "2.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -4526,7 +4818,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v2.4.0" + "source": "https://github.com/symfony/service-contracts/tree/v2.5.0" }, "funding": [ { @@ -4542,20 +4834,20 @@ "type": "tidelift" } ], - "time": "2021-04-01T10:43:52+00:00" + "time": "2021-11-04T16:48:04+00:00" }, { "name": "symfony/string", - "version": "v5.3.10", + "version": "v5.4.0", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "d70c35bb20bbca71fc4ab7921e3c6bda1a82a60c" + "reference": "9ffaaba53c61ba75a3c7a3a779051d1e9ec4fd2d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/d70c35bb20bbca71fc4ab7921e3c6bda1a82a60c", - "reference": "d70c35bb20bbca71fc4ab7921e3c6bda1a82a60c", + "url": "https://api.github.com/repos/symfony/string/zipball/9ffaaba53c61ba75a3c7a3a779051d1e9ec4fd2d", + "reference": "9ffaaba53c61ba75a3c7a3a779051d1e9ec4fd2d", "shasum": "" }, "require": { @@ -4566,11 +4858,14 @@ "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php80": "~1.15" }, + "conflict": { + "symfony/translation-contracts": ">=3.0" + }, "require-dev": { - "symfony/error-handler": "^4.4|^5.0", - "symfony/http-client": "^4.4|^5.0", + "symfony/error-handler": "^4.4|^5.0|^6.0", + "symfony/http-client": "^4.4|^5.0|^6.0", "symfony/translation-contracts": "^1.1|^2", - "symfony/var-exporter": "^4.4|^5.0" + "symfony/var-exporter": "^4.4|^5.0|^6.0" }, "type": "library", "autoload": { @@ -4609,7 +4904,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.3.10" + "source": "https://github.com/symfony/string/tree/v5.4.0" }, "funding": [ { @@ -4625,31 +4920,32 @@ "type": "tidelift" } ], - "time": "2021-10-27T18:21:46+00:00" + "time": "2021-11-24T10:02:00+00:00" }, { "name": "symfony/translation", - "version": "v5.3.10", + "version": "v5.4.1", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "6ef197aea2ac8b9cd63e0da7522b3771714035aa" + "reference": "8c82cd35ed861236138d5ae1c78c0c7ebcd62107" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/6ef197aea2ac8b9cd63e0da7522b3771714035aa", - "reference": "6ef197aea2ac8b9cd63e0da7522b3771714035aa", + "url": "https://api.github.com/repos/symfony/translation/zipball/8c82cd35ed861236138d5ae1c78c0c7ebcd62107", + "reference": "8c82cd35ed861236138d5ae1c78c0c7ebcd62107", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php80": "^1.16", "symfony/translation-contracts": "^2.3" }, "conflict": { "symfony/config": "<4.4", + "symfony/console": "<5.3", "symfony/dependency-injection": "<5.0", "symfony/http-kernel": "<5.0", "symfony/twig-bundle": "<5.0", @@ -4660,15 +4956,16 @@ }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^4.4|^5.0", - "symfony/console": "^4.4|^5.0", - "symfony/dependency-injection": "^5.0", - "symfony/finder": "^4.4|^5.0", - "symfony/http-kernel": "^5.0", - "symfony/intl": "^4.4|^5.0", + "symfony/config": "^4.4|^5.0|^6.0", + "symfony/console": "^5.4|^6.0", + "symfony/dependency-injection": "^5.0|^6.0", + "symfony/finder": "^4.4|^5.0|^6.0", + "symfony/http-client-contracts": "^1.1|^2.0|^3.0", + "symfony/http-kernel": "^5.0|^6.0", + "symfony/intl": "^4.4|^5.0|^6.0", "symfony/polyfill-intl-icu": "^1.21", - "symfony/service-contracts": "^1.1.2|^2", - "symfony/yaml": "^4.4|^5.0" + "symfony/service-contracts": "^1.1.2|^2|^3", + "symfony/yaml": "^4.4|^5.0|^6.0" }, "suggest": { "psr/log-implementation": "To use logging capability in translator", @@ -4704,7 +5001,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v5.3.10" + "source": "https://github.com/symfony/translation/tree/v5.4.1" }, "funding": [ { @@ -4720,20 +5017,20 @@ "type": "tidelift" } ], - "time": "2021-10-10T06:43:24+00:00" + "time": "2021-12-05T20:33:52+00:00" }, { "name": "symfony/translation-contracts", - "version": "v2.4.0", + "version": "v2.5.0", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "95c812666f3e91db75385749fe219c5e494c7f95" + "reference": "d28150f0f44ce854e942b671fc2620a98aae1b1e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/95c812666f3e91db75385749fe219c5e494c7f95", - "reference": "95c812666f3e91db75385749fe219c5e494c7f95", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/d28150f0f44ce854e942b671fc2620a98aae1b1e", + "reference": "d28150f0f44ce854e942b671fc2620a98aae1b1e", "shasum": "" }, "require": { @@ -4745,7 +5042,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.4-dev" + "dev-main": "2.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -4782,7 +5079,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v2.4.0" + "source": "https://github.com/symfony/translation-contracts/tree/v2.5.0" }, "funding": [ { @@ -4798,20 +5095,20 @@ "type": "tidelift" } ], - "time": "2021-03-23T23:28:01+00:00" + "time": "2021-08-17T14:20:01+00:00" }, { "name": "symfony/var-dumper", - "version": "v5.3.10", + "version": "v5.4.1", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "875432adb5f5570fff21036fd22aee244636b7d1" + "reference": "2366ac8d8abe0c077844613c1a4f0c0a9f522dcc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/875432adb5f5570fff21036fd22aee244636b7d1", - "reference": "875432adb5f5570fff21036fd22aee244636b7d1", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/2366ac8d8abe0c077844613c1a4f0c0a9f522dcc", + "reference": "2366ac8d8abe0c077844613c1a4f0c0a9f522dcc", "shasum": "" }, "require": { @@ -4825,8 +5122,9 @@ }, "require-dev": { "ext-iconv": "*", - "symfony/console": "^4.4|^5.0", - "symfony/process": "^4.4|^5.0", + "symfony/console": "^4.4|^5.0|^6.0", + "symfony/process": "^4.4|^5.0|^6.0", + "symfony/uid": "^5.1|^6.0", "twig/twig": "^2.13|^3.0.4" }, "suggest": { @@ -4870,7 +5168,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v5.3.10" + "source": "https://github.com/symfony/var-dumper/tree/v5.4.1" }, "funding": [ { @@ -4886,30 +5184,30 @@ "type": "tidelift" } ], - "time": "2021-10-26T09:30:15+00:00" + "time": "2021-12-01T15:04:08+00:00" }, { "name": "tijsverkoyen/css-to-inline-styles", - "version": "2.2.3", + "version": "2.2.4", "source": { "type": "git", "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git", - "reference": "b43b05cf43c1b6d849478965062b6ef73e223bb5" + "reference": "da444caae6aca7a19c0c140f68c6182e337d5b1c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/b43b05cf43c1b6d849478965062b6ef73e223bb5", - "reference": "b43b05cf43c1b6d849478965062b6ef73e223bb5", + "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/da444caae6aca7a19c0c140f68c6182e337d5b1c", + "reference": "da444caae6aca7a19c0c140f68c6182e337d5b1c", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "php": "^5.5 || ^7.0 || ^8.0", - "symfony/css-selector": "^2.7 || ^3.0 || ^4.0 || ^5.0" + "symfony/css-selector": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^7.5" + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^7.5 || ^8.5.21 || ^9.5.10" }, "type": "library", "extra": { @@ -4937,22 +5235,22 @@ "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles", "support": { "issues": "https://github.com/tijsverkoyen/CssToInlineStyles/issues", - "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/2.2.3" + "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/2.2.4" }, - "time": "2020-07-13T06:12:54+00:00" + "time": "2021-12-08T09:12:39+00:00" }, { "name": "vlucas/phpdotenv", - "version": "v5.4.0", + "version": "v5.4.1", "source": { "type": "git", "url": "https://github.com/vlucas/phpdotenv.git", - "reference": "d4394d044ed69a8f244f3445bcedf8a0d7fe2403" + "reference": "264dce589e7ce37a7ba99cb901eed8249fbec92f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/d4394d044ed69a8f244f3445bcedf8a0d7fe2403", - "reference": "d4394d044ed69a8f244f3445bcedf8a0d7fe2403", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/264dce589e7ce37a7ba99cb901eed8249fbec92f", + "reference": "264dce589e7ce37a7ba99cb901eed8249fbec92f", "shasum": "" }, "require": { @@ -4990,11 +5288,13 @@ "authors": [ { "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk" + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" }, { "name": "Vance Lucas", - "email": "vance@vancelucas.com" + "email": "vance@vancelucas.com", + "homepage": "https://github.com/vlucas" } ], "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", @@ -5005,7 +5305,7 @@ ], "support": { "issues": "https://github.com/vlucas/phpdotenv/issues", - "source": "https://github.com/vlucas/phpdotenv/tree/v5.4.0" + "source": "https://github.com/vlucas/phpdotenv/tree/v5.4.1" }, "funding": [ { @@ -5017,7 +5317,7 @@ "type": "tidelift" } ], - "time": "2021-11-10T01:08:39+00:00" + "time": "2021-12-12T23:22:04+00:00" }, { "name": "voku/portable-ascii", @@ -5153,16 +5453,16 @@ }, { "name": "zbateson/mb-wrapper", - "version": "1.1.0", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/zbateson/mb-wrapper.git", - "reference": "547d73a04912728cf0bb772d43e5a17e63cdf168" + "reference": "bfd45fb3e2a8cf4c496b2c3ebd63b5f815721498" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zbateson/mb-wrapper/zipball/547d73a04912728cf0bb772d43e5a17e63cdf168", - "reference": "547d73a04912728cf0bb772d43e5a17e63cdf168", + "url": "https://api.github.com/repos/zbateson/mb-wrapper/zipball/bfd45fb3e2a8cf4c496b2c3ebd63b5f815721498", + "reference": "bfd45fb3e2a8cf4c496b2c3ebd63b5f815721498", "shasum": "" }, "require": { @@ -5208,7 +5508,7 @@ ], "support": { "issues": "https://github.com/zbateson/mb-wrapper/issues", - "source": "https://github.com/zbateson/mb-wrapper/tree/1.1.0" + "source": "https://github.com/zbateson/mb-wrapper/tree/1.1.1" }, "funding": [ { @@ -5216,7 +5516,7 @@ "type": "github" } ], - "time": "2021-11-09T18:05:07+00:00" + "time": "2021-11-22T21:59:45+00:00" }, { "name": "zbateson/stream-decorators", @@ -5283,16 +5583,16 @@ "packages-dev": [ { "name": "brianium/paratest", - "version": "v6.3.2", + "version": "v6.4.1", "source": { "type": "git", "url": "https://github.com/paratestphp/paratest.git", - "reference": "5843dced0fb11c67fa3863e9ad40cfc319c32f33" + "reference": "c32a5c4fc2ff339202437d25d19a5f496f880d61" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paratestphp/paratest/zipball/5843dced0fb11c67fa3863e9ad40cfc319c32f33", - "reference": "5843dced0fb11c67fa3863e9ad40cfc319c32f33", + "url": "https://api.github.com/repos/paratestphp/paratest/zipball/c32a5c4fc2ff339202437d25d19a5f496f880d61", + "reference": "c32a5c4fc2ff339202437d25d19a5f496f880d61", "shasum": "" }, "require": { @@ -5301,13 +5601,13 @@ "ext-reflection": "*", "ext-simplexml": "*", "php": "^7.3 || ^8.0", - "phpunit/php-code-coverage": "^9.2.7", + "phpunit/php-code-coverage": "^9.2.9", "phpunit/php-file-iterator": "^3.0.5", "phpunit/php-timer": "^5.0.3", "phpunit/phpunit": "^9.5.10", "sebastian/environment": "^5.1.3", - "symfony/console": "^4.4.30 || ^5.3.7", - "symfony/process": "^4.4.30 || ^5.3.7" + "symfony/console": "^5.4.0 || ^6.0.0", + "symfony/process": "^5.4.0 || ^6.0.0" }, "require-dev": { "doctrine/coding-standard": "^9.0.0", @@ -5315,14 +5615,15 @@ "ergebnis/phpstan-rules": "^0.15.3", "ext-posix": "*", "infection/infection": "^0.25.3", + "malukenho/mcbumpface": "^1.1.5", "phpstan/phpstan": "^0.12.99", "phpstan/phpstan-deprecation-rules": "^0.12.6", "phpstan/phpstan-phpunit": "^0.12.22", "phpstan/phpstan-strict-rules": "^0.12.11", - "squizlabs/php_codesniffer": "^3.6.0", - "symfony/filesystem": "^5.3.4", - "thecodingmachine/phpstan-strict-rules": "^0.12.1", - "vimeo/psalm": "^4.10.0" + "squizlabs/php_codesniffer": "^3.6.1", + "symfony/filesystem": "^v5.4.0", + "thecodingmachine/phpstan-strict-rules": "^v0.12.2", + "vimeo/psalm": "^4.13.1" }, "bin": [ "bin/paratest" @@ -5361,7 +5662,7 @@ ], "support": { "issues": "https://github.com/paratestphp/paratest/issues", - "source": "https://github.com/paratestphp/paratest/tree/v6.3.2" + "source": "https://github.com/paratestphp/paratest/tree/v6.4.1" }, "funding": [ { @@ -5373,7 +5674,7 @@ "type": "paypal" } ], - "time": "2021-11-03T10:16:06+00:00" + "time": "2021-12-02T09:12:23+00:00" }, { "name": "doctrine/instantiator", @@ -5552,22 +5853,22 @@ }, { "name": "fakerphp/faker", - "version": "v1.16.0", + "version": "v1.17.0", "source": { "type": "git", "url": "https://github.com/FakerPHP/Faker.git", - "reference": "271d384d216e5e5c468a6b28feedf95d49f83b35" + "reference": "b85e9d44eae8c52cca7aa0939483611f7232b669" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/271d384d216e5e5c468a6b28feedf95d49f83b35", - "reference": "271d384d216e5e5c468a6b28feedf95d49f83b35", + "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/b85e9d44eae8c52cca7aa0939483611f7232b669", + "reference": "b85e9d44eae8c52cca7aa0939483611f7232b669", "shasum": "" }, "require": { "php": "^7.1 || ^8.0", "psr/container": "^1.0 || ^2.0", - "symfony/deprecation-contracts": "^2.2" + "symfony/deprecation-contracts": "^2.2 || ^3.0" }, "conflict": { "fzaninotto/faker": "*" @@ -5586,7 +5887,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "v1.16-dev" + "dev-main": "v1.17-dev" } }, "autoload": { @@ -5611,27 +5912,27 @@ ], "support": { "issues": "https://github.com/FakerPHP/Faker/issues", - "source": "https://github.com/FakerPHP/Faker/tree/v1.16.0" + "source": "https://github.com/FakerPHP/Faker/tree/v1.17.0" }, - "time": "2021-09-06T14:53:37+00:00" + "time": "2021-12-05T17:14:47+00:00" }, { "name": "filp/whoops", - "version": "2.14.3", + "version": "2.14.4", "source": { "type": "git", "url": "https://github.com/filp/whoops.git", - "reference": "89584ce67dd32307f1063cc43846674f4679feda" + "reference": "f056f1fe935d9ed86e698905a957334029899895" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/89584ce67dd32307f1063cc43846674f4679feda", - "reference": "89584ce67dd32307f1063cc43846674f4679feda", + "url": "https://api.github.com/repos/filp/whoops/zipball/f056f1fe935d9ed86e698905a957334029899895", + "reference": "f056f1fe935d9ed86e698905a957334029899895", "shasum": "" }, "require": { "php": "^5.5.9 || ^7.0 || ^8.0", - "psr/log": "^1.0.1" + "psr/log": "^1.0.1 || ^2.0 || ^3.0" }, "require-dev": { "mockery/mockery": "^0.9 || ^1.0", @@ -5676,7 +5977,7 @@ ], "support": { "issues": "https://github.com/filp/whoops/issues", - "source": "https://github.com/filp/whoops/tree/2.14.3" + "source": "https://github.com/filp/whoops/tree/2.14.4" }, "funding": [ { @@ -5684,7 +5985,7 @@ "type": "github" } ], - "time": "2021-09-19T12:00:00+00:00" + "time": "2021-10-03T12:00:00+00:00" }, { "name": "hamcrest/hamcrest-php", @@ -5800,16 +6101,16 @@ }, { "name": "league/csv", - "version": "9.72", + "version": "9.7.4", "source": { "type": "git", "url": "https://github.com/thephpleague/csv.git", - "reference": "8544655c460fd01eed0ad258e514488d4b388645" + "reference": "002f55f649e7511710dc7154ff44c7be32c8195c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/csv/zipball/8544655c460fd01eed0ad258e514488d4b388645", - "reference": "8544655c460fd01eed0ad258e514488d4b388645", + "url": "https://api.github.com/repos/thephpleague/csv/zipball/002f55f649e7511710dc7154ff44c7be32c8195c", + "reference": "002f55f649e7511710dc7154ff44c7be32c8195c", "shasum": "" }, "require": { @@ -5821,9 +6122,9 @@ "ext-curl": "*", "ext-dom": "*", "friendsofphp/php-cs-fixer": "^3.0", - "phpstan/phpstan": "^0.12.99", - "phpstan/phpstan-phpunit": "^0.12.22", - "phpstan/phpstan-strict-rules": "^0.12.11", + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-phpunit": "^1.0.0", + "phpstan/phpstan-strict-rules": "^1.0", "phpunit/phpunit": "^9.5" }, "suggest": { @@ -5880,7 +6181,7 @@ "type": "github" } ], - "time": "2021-10-05T19:41:46+00:00" + "time": "2021-11-30T07:09:34+00:00" }, { "name": "league/flysystem-vfs", @@ -5937,12 +6238,12 @@ "version": "v4.7.0", "source": { "type": "git", - "url": "https://github.com/M6Web/RedisMock.git", + "url": "https://github.com/BedrockStreaming/RedisMock.git", "reference": "057ad8e1bea903aee54642e310d900bdb794372c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/M6Web/RedisMock/zipball/057ad8e1bea903aee54642e310d900bdb794372c", + "url": "https://api.github.com/repos/BedrockStreaming/RedisMock/zipball/057ad8e1bea903aee54642e310d900bdb794372c", "reference": "057ad8e1bea903aee54642e310d900bdb794372c", "shasum": "" }, @@ -5976,8 +6277,8 @@ "redis" ], "support": { - "issues": "https://github.com/M6Web/RedisMock/issues", - "source": "https://github.com/M6Web/RedisMock/tree/v4.7.0" + "issues": "https://github.com/BedrockStreaming/RedisMock/issues", + "source": "https://github.com/BedrockStreaming/RedisMock/tree/v4.7.0" }, "time": "2019-11-04T09:03:23+00:00" }, @@ -6113,16 +6414,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.13.1", + "version": "v4.13.2", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "63a79e8daa781cac14e5195e63ed8ae231dd10fd" + "reference": "210577fe3cf7badcc5814d99455df46564f3c077" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/63a79e8daa781cac14e5195e63ed8ae231dd10fd", - "reference": "63a79e8daa781cac14e5195e63ed8ae231dd10fd", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/210577fe3cf7badcc5814d99455df46564f3c077", + "reference": "210577fe3cf7badcc5814d99455df46564f3c077", "shasum": "" }, "require": { @@ -6163,9 +6464,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.1" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.2" }, - "time": "2021-11-03T20:52:16+00:00" + "time": "2021-11-30T19:35:32+00:00" }, { "name": "nunomaduro/collision", @@ -6256,25 +6557,25 @@ }, { "name": "orchestra/testbench", - "version": "v6.23.0", + "version": "v6.23.1", "source": { "type": "git", "url": "https://github.com/orchestral/testbench.git", - "reference": "94cf6e34cd3fbab07d02f6171bc7a350821c48c2" + "reference": "c4c1e420ec0fd60ab149aca0ced194911a46b928" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/orchestral/testbench/zipball/94cf6e34cd3fbab07d02f6171bc7a350821c48c2", - "reference": "94cf6e34cd3fbab07d02f6171bc7a350821c48c2", + "url": "https://api.github.com/repos/orchestral/testbench/zipball/c4c1e420ec0fd60ab149aca0ced194911a46b928", + "reference": "c4c1e420ec0fd60ab149aca0ced194911a46b928", "shasum": "" }, "require": { - "laravel/framework": "^8.67", + "laravel/framework": "^8.71", "mockery/mockery": "^1.4.4", - "orchestra/testbench-core": "^6.27", + "orchestra/testbench-core": "^6.27.3", "php": "^7.3 || ^8.0", "phpunit/phpunit": "^8.5.21 || ^9.5.10", - "spatie/laravel-ray": "^1.18" + "spatie/laravel-ray": "^1.26.2" }, "type": "library", "extra": { @@ -6305,7 +6606,7 @@ ], "support": { "issues": "https://github.com/orchestral/testbench/issues", - "source": "https://github.com/orchestral/testbench/tree/v6.23.0" + "source": "https://github.com/orchestral/testbench/tree/v6.23.1" }, "funding": [ { @@ -6317,20 +6618,20 @@ "type": "liberapay" } ], - "time": "2021-11-09T23:05:41+00:00" + "time": "2021-12-03T22:47:04+00:00" }, { "name": "orchestra/testbench-core", - "version": "v6.27.0", + "version": "v6.27.3", "source": { "type": "git", "url": "https://github.com/orchestral/testbench-core.git", - "reference": "5e2c6211090d49e24c292edd2eb4138b7409160e" + "reference": "86867f7853e49a8f516951aa4e303230ebce40ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/orchestral/testbench-core/zipball/5e2c6211090d49e24c292edd2eb4138b7409160e", - "reference": "5e2c6211090d49e24c292edd2eb4138b7409160e", + "url": "https://api.github.com/repos/orchestral/testbench-core/zipball/86867f7853e49a8f516951aa4e303230ebce40ac", + "reference": "86867f7853e49a8f516951aa4e303230ebce40ac", "shasum": "" }, "require": { @@ -6340,7 +6641,7 @@ "vlucas/phpdotenv": "^5.1" }, "require-dev": { - "laravel/framework": "^8.67", + "laravel/framework": "^8.71", "laravel/laravel": "8.x-dev", "mockery/mockery": "^1.4.4", "orchestra/canvas": "^6.1", @@ -6349,7 +6650,7 @@ "symfony/process": "^5.0" }, "suggest": { - "laravel/framework": "Required for testing (^8.67).", + "laravel/framework": "Required for testing (^8.71).", "mockery/mockery": "Allow using Mockery for testing (^1.4.4).", "orchestra/testbench-browser-kit": "Allow using legacy Laravel BrowserKit for testing (^6.0).", "orchestra/testbench-dusk": "Allow using Laravel Dusk for testing (^6.0).", @@ -6407,7 +6708,7 @@ "type": "liberapay" } ], - "time": "2021-11-09T22:53:16+00:00" + "time": "2021-12-03T22:38:19+00:00" }, { "name": "phar-io/manifest", @@ -6738,16 +7039,16 @@ }, { "name": "phpspec/prophecy", - "version": "1.14.0", + "version": "v1.15.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e" + "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e", - "reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13", + "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13", "shasum": "" }, "require": { @@ -6799,22 +7100,22 @@ ], "support": { "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/1.14.0" + "source": "https://github.com/phpspec/prophecy/tree/v1.15.0" }, - "time": "2021-09-10T09:02:12+00:00" + "time": "2021-12-08T12:19:24+00:00" }, { "name": "phpstan/phpstan", - "version": "1.1.2", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "bcea0ae85868a89d5789c75f012c93129f842934" + "reference": "cbe085f9fdead5b6d62e4c022ca52dc9427a10ee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/bcea0ae85868a89d5789c75f012c93129f842934", - "reference": "bcea0ae85868a89d5789c75f012c93129f842934", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/cbe085f9fdead5b6d62e4c022ca52dc9427a10ee", + "reference": "cbe085f9fdead5b6d62e4c022ca52dc9427a10ee", "shasum": "" }, "require": { @@ -6830,7 +7131,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "1.2-dev" } }, "autoload": { @@ -6845,7 +7146,7 @@ "description": "PHPStan - PHP Static Analysis Tool", "support": { "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/1.1.2" + "source": "https://github.com/phpstan/phpstan/tree/1.2.0" }, "funding": [ { @@ -6865,20 +7166,20 @@ "type": "tidelift" } ], - "time": "2021-11-09T12:41:09+00:00" + "time": "2021-11-18T14:09:01+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.8", + "version": "9.2.10", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "cf04e88a2e3c56fc1a65488afd493325b4c1bc3e" + "reference": "d5850aaf931743067f4bfc1ae4cbd06468400687" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/cf04e88a2e3c56fc1a65488afd493325b4c1bc3e", - "reference": "cf04e88a2e3c56fc1a65488afd493325b4c1bc3e", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/d5850aaf931743067f4bfc1ae4cbd06468400687", + "reference": "d5850aaf931743067f4bfc1ae4cbd06468400687", "shasum": "" }, "require": { @@ -6934,7 +7235,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.8" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.10" }, "funding": [ { @@ -6942,20 +7243,20 @@ "type": "github" } ], - "time": "2021-10-30T08:01:38+00:00" + "time": "2021-12-05T09:12:13+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "3.0.5", + "version": "3.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8" + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/aa4be8575f26070b100fccb67faabb28f21f66f8", - "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", "shasum": "" }, "require": { @@ -6994,7 +7295,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.5" + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" }, "funding": [ { @@ -7002,7 +7303,7 @@ "type": "github" } ], - "time": "2020-09-28T05:57:25+00:00" + "time": "2021-12-02T12:48:52+00:00" }, { "name": "phpunit/php-invoker", @@ -7343,16 +7644,16 @@ }, { "name": "predis/predis", - "version": "v1.1.7", + "version": "v1.1.9", "source": { "type": "git", "url": "https://github.com/predis/predis.git", - "reference": "b240daa106d4e02f0c5b7079b41e31ddf66fddf8" + "reference": "c50c3393bb9f47fa012d0cdfb727a266b0818259" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/predis/predis/zipball/b240daa106d4e02f0c5b7079b41e31ddf66fddf8", - "reference": "b240daa106d4e02f0c5b7079b41e31ddf66fddf8", + "url": "https://api.github.com/repos/predis/predis/zipball/c50c3393bb9f47fa012d0cdfb727a266b0818259", + "reference": "c50c3393bb9f47fa012d0cdfb727a266b0818259", "shasum": "" }, "require": { @@ -7397,7 +7698,7 @@ ], "support": { "issues": "https://github.com/predis/predis/issues", - "source": "https://github.com/predis/predis/tree/v1.1.7" + "source": "https://github.com/predis/predis/tree/v1.1.9" }, "funding": [ { @@ -7405,7 +7706,7 @@ "type": "github" } ], - "time": "2021-04-04T19:34:46+00:00" + "time": "2021-10-05T19:02:38+00:00" }, { "name": "sebastian/cli-parser", @@ -7836,16 +8137,16 @@ }, { "name": "sebastian/exporter", - "version": "4.0.3", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65" + "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/d89cc98761b8cb5a1a235a6b703ae50d34080e65", - "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9", + "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9", "shasum": "" }, "require": { @@ -7894,14 +8195,14 @@ } ], "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", + "homepage": "https://www.github.com/sebastianbergmann/exporter", "keywords": [ "export", "exporter" ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.3" + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4" }, "funding": [ { @@ -7909,7 +8210,7 @@ "type": "github" } ], - "time": "2020-09-28T05:24:23+00:00" + "time": "2021-11-11T14:18:36+00:00" }, { "name": "sebastian/global-state", @@ -8435,16 +8736,16 @@ }, { "name": "spatie/laravel-ray", - "version": "1.26.1", + "version": "1.26.4", "source": { "type": "git", "url": "https://github.com/spatie/laravel-ray.git", - "reference": "5ecc2ebbdad8ae3ec31274596d922495cff69184" + "reference": "eebd571834d3940b1d8314950198b4ae71789a82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-ray/zipball/5ecc2ebbdad8ae3ec31274596d922495cff69184", - "reference": "5ecc2ebbdad8ae3ec31274596d922495cff69184", + "url": "https://api.github.com/repos/spatie/laravel-ray/zipball/eebd571834d3940b1d8314950198b4ae71789a82", + "reference": "eebd571834d3940b1d8314950198b4ae71789a82", "shasum": "" }, "require": { @@ -8501,7 +8802,7 @@ ], "support": { "issues": "https://github.com/spatie/laravel-ray/issues", - "source": "https://github.com/spatie/laravel-ray/tree/1.26.1" + "source": "https://github.com/spatie/laravel-ray/tree/1.26.4" }, "funding": [ { @@ -8513,7 +8814,7 @@ "type": "other" } ], - "time": "2021-10-01T13:08:05+00:00" + "time": "2021-12-10T12:10:14+00:00" }, { "name": "spatie/macroable", @@ -8567,26 +8868,27 @@ }, { "name": "spatie/phpunit-snapshot-assertions", - "version": "4.2.7", + "version": "4.2.9", "source": { "type": "git", "url": "https://github.com/spatie/phpunit-snapshot-assertions.git", - "reference": "981fa0e0a432315064db00b6b97a4f11f3b0c0fd" + "reference": "a259df1bb5ccf272bacafcee7fdb0eb703d9b1cc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/phpunit-snapshot-assertions/zipball/981fa0e0a432315064db00b6b97a4f11f3b0c0fd", - "reference": "981fa0e0a432315064db00b6b97a4f11f3b0c0fd", + "url": "https://api.github.com/repos/spatie/phpunit-snapshot-assertions/zipball/a259df1bb5ccf272bacafcee7fdb0eb703d9b1cc", + "reference": "a259df1bb5ccf272bacafcee7fdb0eb703d9b1cc", "shasum": "" }, "require": { + "composer-runtime-api": "^2.0", "ext-dom": "*", "ext-json": "*", "php": "^7.3|^7.4|^8.0", "phpunit/phpunit": "^8.3|^9.0", - "symfony/property-access": "^4.0|^5.0", - "symfony/serializer": "^4.0|^5.0", - "symfony/yaml": "^4.0|^5.0" + "symfony/property-access": "^4.0|^5.0|^6.0", + "symfony/serializer": "^4.0|^5.0|^6.0", + "symfony/yaml": "^4.0|^5.0|^6.0" }, "require-dev": { "phpunit/phpunit": "^9.1.0" @@ -8621,7 +8923,7 @@ ], "support": { "issues": "https://github.com/spatie/phpunit-snapshot-assertions/issues", - "source": "https://github.com/spatie/phpunit-snapshot-assertions/tree/4.2.7" + "source": "https://github.com/spatie/phpunit-snapshot-assertions/tree/4.2.9" }, "funding": [ { @@ -8629,20 +8931,20 @@ "type": "custom" } ], - "time": "2021-07-09T08:38:04+00:00" + "time": "2021-12-03T19:21:19+00:00" }, { "name": "spatie/ray", - "version": "1.30.3", + "version": "1.32.1", "source": { "type": "git", "url": "https://github.com/spatie/ray.git", - "reference": "5ec8449def9735d58b66d8024776becb3b020288" + "reference": "73baa5d216865480f0c67cac5cb4dedd1a00f4f1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/ray/zipball/5ec8449def9735d58b66d8024776becb3b020288", - "reference": "5ec8449def9735d58b66d8024776becb3b020288", + "url": "https://api.github.com/repos/spatie/ray/zipball/73baa5d216865480f0c67cac5cb4dedd1a00f4f1", + "reference": "73baa5d216865480f0c67cac5cb4dedd1a00f4f1", "shasum": "" }, "require": { @@ -8692,7 +8994,7 @@ ], "support": { "issues": "https://github.com/spatie/ray/issues", - "source": "https://github.com/spatie/ray/tree/1.30.3" + "source": "https://github.com/spatie/ray/tree/1.32.1" }, "funding": [ { @@ -8704,30 +9006,30 @@ "type": "other" } ], - "time": "2021-10-07T22:07:04+00:00" + "time": "2021-11-30T15:52:12+00:00" }, { "name": "symfony/property-access", - "version": "v5.3.8", + "version": "v5.4.0", "source": { "type": "git", "url": "https://github.com/symfony/property-access.git", - "reference": "2fbab5f95ddb6b8e85f38a6a8a04a17c0acc4d66" + "reference": "07db4e9d1f0bf4b8a0c60a25b2672f20ab8f3562" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-access/zipball/2fbab5f95ddb6b8e85f38a6a8a04a17c0acc4d66", - "reference": "2fbab5f95ddb6b8e85f38a6a8a04a17c0acc4d66", + "url": "https://api.github.com/repos/symfony/property-access/zipball/07db4e9d1f0bf4b8a0c60a25b2672f20ab8f3562", + "reference": "07db4e9d1f0bf4b8a0c60a25b2672f20ab8f3562", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-php80": "^1.16", - "symfony/property-info": "^5.2" + "symfony/property-info": "^5.2|^6.0" }, "require-dev": { - "symfony/cache": "^4.4|^5.0" + "symfony/cache": "^4.4|^5.0|^6.0" }, "suggest": { "psr/cache-implementation": "To cache access methods." @@ -8769,7 +9071,7 @@ "reflection" ], "support": { - "source": "https://github.com/symfony/property-access/tree/v5.3.8" + "source": "https://github.com/symfony/property-access/tree/v5.4.0" }, "funding": [ { @@ -8785,27 +9087,27 @@ "type": "tidelift" } ], - "time": "2021-09-10T11:55:24+00:00" + "time": "2021-11-28T15:25:38+00:00" }, { "name": "symfony/property-info", - "version": "v5.3.8", + "version": "v5.4.0", "source": { "type": "git", "url": "https://github.com/symfony/property-info.git", - "reference": "39de5bed8c036f76ec0457ec52908e45d5497947" + "reference": "c21b4221522779537e9693d51536d8174579b1fd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-info/zipball/39de5bed8c036f76ec0457ec52908e45d5497947", - "reference": "39de5bed8c036f76ec0457ec52908e45d5497947", + "url": "https://api.github.com/repos/symfony/property-info/zipball/c21b4221522779537e9693d51536d8174579b1fd", + "reference": "c21b4221522779537e9693d51536d8174579b1fd", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-php80": "^1.16", - "symfony/string": "^5.1" + "symfony/string": "^5.1|^6.0" }, "conflict": { "phpdocumentor/reflection-docblock": "<3.2.2", @@ -8815,9 +9117,10 @@ "require-dev": { "doctrine/annotations": "^1.10.4", "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", - "symfony/cache": "^4.4|^5.0", - "symfony/dependency-injection": "^4.4|^5.0", - "symfony/serializer": "^4.4|^5.0" + "phpstan/phpdoc-parser": "^1.0", + "symfony/cache": "^4.4|^5.0|^6.0", + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/serializer": "^4.4|^5.0|^6.0" }, "suggest": { "phpdocumentor/reflection-docblock": "To use the PHPDoc", @@ -8859,7 +9162,7 @@ "validator" ], "support": { - "source": "https://github.com/symfony/property-info/tree/v5.3.8" + "source": "https://github.com/symfony/property-info/tree/v5.4.0" }, "funding": [ { @@ -8875,25 +9178,25 @@ "type": "tidelift" } ], - "time": "2021-09-07T07:41:40+00:00" + "time": "2021-11-23T10:19:22+00:00" }, { "name": "symfony/serializer", - "version": "v5.3.10", + "version": "v5.4.0", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "5d7f068253ac3e7c62964ebdda491b06d401059a" + "reference": "66942cf6bf412ca72c39353596f4d37ee0f9059b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/5d7f068253ac3e7c62964ebdda491b06d401059a", - "reference": "5d7f068253ac3e7c62964ebdda491b06d401059a", + "url": "https://api.github.com/repos/symfony/serializer/zipball/66942cf6bf412ca72c39353596f4d37ee0f9059b", + "reference": "66942cf6bf412ca72c39353596f4d37ee0f9059b", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-php80": "^1.16" }, @@ -8902,29 +9205,29 @@ "phpdocumentor/reflection-docblock": "<3.2.2", "phpdocumentor/type-resolver": "<1.4.0", "symfony/dependency-injection": "<4.4", - "symfony/property-access": "<4.4", + "symfony/property-access": "<5.4", "symfony/property-info": "<5.3", "symfony/yaml": "<4.4" }, "require-dev": { "doctrine/annotations": "^1.12", "phpdocumentor/reflection-docblock": "^3.2|^4.0|^5.0", - "symfony/cache": "^4.4|^5.0", - "symfony/config": "^4.4|^5.0", - "symfony/dependency-injection": "^4.4|^5.0", - "symfony/error-handler": "^4.4|^5.0", - "symfony/filesystem": "^4.4|^5.0", - "symfony/form": "^4.4|^5.0", - "symfony/http-foundation": "^4.4|^5.0", - "symfony/http-kernel": "^4.4|^5.0", - "symfony/mime": "^4.4|^5.0", - "symfony/property-access": "^4.4.9|^5.0.9", - "symfony/property-info": "^5.3", - "symfony/uid": "^5.1", - "symfony/validator": "^4.4|^5.0", - "symfony/var-dumper": "^4.4|^5.0", - "symfony/var-exporter": "^4.4|^5.0", - "symfony/yaml": "^4.4|^5.0" + "symfony/cache": "^4.4|^5.0|^6.0", + "symfony/config": "^4.4|^5.0|^6.0", + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/error-handler": "^4.4|^5.0|^6.0", + "symfony/filesystem": "^4.4|^5.0|^6.0", + "symfony/form": "^4.4|^5.0|^6.0", + "symfony/http-foundation": "^4.4|^5.0|^6.0", + "symfony/http-kernel": "^4.4|^5.0|^6.0", + "symfony/mime": "^4.4|^5.0|^6.0", + "symfony/property-access": "^5.4|^6.0", + "symfony/property-info": "^5.3|^6.0", + "symfony/uid": "^5.1|^6.0", + "symfony/validator": "^4.4|^5.0|^6.0", + "symfony/var-dumper": "^4.4|^5.0|^6.0", + "symfony/var-exporter": "^4.4|^5.0|^6.0", + "symfony/yaml": "^4.4|^5.0|^6.0" }, "suggest": { "psr/cache-implementation": "For using the metadata cache.", @@ -8961,7 +9264,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/serializer/tree/v5.3.10" + "source": "https://github.com/symfony/serializer/tree/v5.4.0" }, "funding": [ { @@ -8977,25 +9280,25 @@ "type": "tidelift" } ], - "time": "2021-09-29T17:19:25+00:00" + "time": "2021-11-28T15:25:38+00:00" }, { "name": "symfony/stopwatch", - "version": "v5.3.4", + "version": "v5.4.0", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "b24c6a92c6db316fee69e38c80591e080e41536c" + "reference": "208ef96122bfed82a8f3a61458a07113a08bdcfe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/b24c6a92c6db316fee69e38c80591e080e41536c", - "reference": "b24c6a92c6db316fee69e38c80591e080e41536c", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/208ef96122bfed82a8f3a61458a07113a08bdcfe", + "reference": "208ef96122bfed82a8f3a61458a07113a08bdcfe", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/service-contracts": "^1.0|^2" + "symfony/service-contracts": "^1|^2|^3" }, "type": "library", "autoload": { @@ -9023,7 +9326,7 @@ "description": "Provides a way to profile code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/stopwatch/tree/v5.3.4" + "source": "https://github.com/symfony/stopwatch/tree/v5.4.0" }, "funding": [ { @@ -9039,32 +9342,32 @@ "type": "tidelift" } ], - "time": "2021-07-10T08:58:57+00:00" + "time": "2021-11-23T10:19:22+00:00" }, { "name": "symfony/yaml", - "version": "v5.3.6", + "version": "v5.4.0", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "4500fe63dc9c6ffc32d3b1cb0448c329f9c814b7" + "reference": "034ccc0994f1ae3f7499fa5b1f2e75d5e7a94efc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/4500fe63dc9c6ffc32d3b1cb0448c329f9c814b7", - "reference": "4500fe63dc9c6ffc32d3b1cb0448c329f9c814b7", + "url": "https://api.github.com/repos/symfony/yaml/zipball/034ccc0994f1ae3f7499fa5b1f2e75d5e7a94efc", + "reference": "034ccc0994f1ae3f7499fa5b1f2e75d5e7a94efc", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", - "symfony/polyfill-ctype": "~1.8" + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-ctype": "^1.8" }, "conflict": { - "symfony/console": "<4.4" + "symfony/console": "<5.3" }, "require-dev": { - "symfony/console": "^4.4|^5.0" + "symfony/console": "^5.3|^6.0" }, "suggest": { "symfony/console": "For validating YAML files using the lint command" @@ -9098,7 +9401,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v5.3.6" + "source": "https://github.com/symfony/yaml/tree/v5.4.0" }, "funding": [ { @@ -9114,7 +9417,7 @@ "type": "tidelift" } ], - "time": "2021-07-29T06:20:01+00:00" + "time": "2021-11-28T15:25:38+00:00" }, { "name": "theseer/tokenizer", @@ -9168,16 +9471,16 @@ }, { "name": "zbateson/mail-mime-parser", - "version": "2.1.0", + "version": "2.1.1", "source": { "type": "git", "url": "https://github.com/zbateson/mail-mime-parser.git", - "reference": "0ef2d7de2577ea0a339d34720451c8ba8cd9dbb4" + "reference": "b969a8a72106dcdaa9ac4b19bb2e6b22d3fc5584" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zbateson/mail-mime-parser/zipball/0ef2d7de2577ea0a339d34720451c8ba8cd9dbb4", - "reference": "0ef2d7de2577ea0a339d34720451c8ba8cd9dbb4", + "url": "https://api.github.com/repos/zbateson/mail-mime-parser/zipball/b969a8a72106dcdaa9ac4b19bb2e6b22d3fc5584", + "reference": "b969a8a72106dcdaa9ac4b19bb2e6b22d3fc5584", "shasum": "" }, "require": { @@ -9237,7 +9540,7 @@ "type": "github" } ], - "time": "2021-11-09T18:24:41+00:00" + "time": "2021-12-08T20:21:28+00:00" } ], "aliases": [], @@ -9253,5 +9556,5 @@ "ext-pdo": "*" }, "platform-dev": [], - "plugin-api-version": "2.1.0" + "plugin-api-version": "2.0.0" } diff --git a/doc/getting-started/README.md b/doc/getting-started/README.md index 0bd777240..11f28509b 100644 --- a/doc/getting-started/README.md +++ b/doc/getting-started/README.md @@ -32,7 +32,7 @@ As we're just starting out we'll use the existing service provider at `app/Provi Open this file and add the following to the `boot()` method. ```php -\Lodata::discoverEloquentModel(\App\Models\User::class) +\Lodata::discover(\App\Models\User::class) ``` You can now access [`http://127.0.0.1:8000/odata/Users`](http://127.0.0.1:8000/odata/Users) and see the users in your database. diff --git a/doc/introduction/compliance.md b/doc/introduction/compliance.md index d05dcc2ca..ce6d89cc8 100644 --- a/doc/introduction/compliance.md +++ b/doc/introduction/compliance.md @@ -21,6 +21,7 @@ Lodata supports many sections of the OData specification, these are the major ar * The [$search](https://docs.oasis-open.org/odata/odata/v4.01/os/part1-protocol/odata-v4.01-os-part1-protocol.html#_Toc31358956) system query option * The [$value](https://docs.oasis-open.org/odata/odata/v4.01/os/part1-protocol/odata-v4.01-os-part1-protocol.html#_Toc31358940) path segment * The [$filter](https://docs.oasis-open.org/odata/odata/v4.01/os/part1-protocol/odata-v4.01-os-part1-protocol.html#_Toc31358948) system query option, with all expressions, functions, operators, and supports query parameter aliases +* The [$index](https://docs.oasis-open.org/odata/odata/v4.01/os/part1-protocol/odata-v4.01-os-part1-protocol.html#sec_PositionalInserts) system query option * [Asynchronous requests](https://docs.oasis-open.org/odata/odata/v4.01/os/part1-protocol/odata-v4.01-os-part1-protocol.html#sec_AsynchronousRequests) using Laravel jobs, with monitoring, cancellation and callbacks * [Batch requests](https://docs.oasis-open.org/odata/odata/v4.01/os/part1-protocol/odata-v4.01-os-part1-protocol.html#sec_BatchRequests) in both multipart and JSON formats, including entity back-references and asynchronous batch requests * [Deep insert](https://docs.oasis-open.org/odata/odata/v4.01/os/part1-protocol/odata-v4.01-os-part1-protocol.html#sec_CreateRelatedEntitiesWhenCreatinganE) support at any depth diff --git a/doc/introduction/reporting-issues.md b/doc/introduction/reporting-issues.md index 7ed0dd4d6..b98c1db0d 100644 --- a/doc/introduction/reporting-issues.md +++ b/doc/introduction/reporting-issues.md @@ -7,7 +7,7 @@ When reporting an issue please include any configuration of entity sets or opera Ideally to reproduce an issue you can generate a test case. Lodata uses [snapshot tests](https://github.com/spatie/phpunit-snapshot-assertions) extensively to capture the entire output of the API. -Many examples exist in the test folder, for example [https://github.com/flat3/lodata/blob/develop/tests/Unit/Eloquent/EloquentTest.php](https://github.com/flat3/lodata/blob/develop/tests/Unit/Eloquent/EloquentTest.php) +Many examples exist in the test folder, for example [https://github.com/flat3/lodata/blob/main/tests/Unit/Eloquent/EloquentTest.php](https://github.com/flat3/lodata/blob/main/tests/Unit/Eloquent/EloquentTest.php) Test cases that generate snapshots can use the provided assertions and the `Request` object to generate and configure a request. diff --git a/doc/making-requests/querying-data.md b/doc/making-requests/querying-data.md index d109970ba..254eed09a 100644 --- a/doc/making-requests/querying-data.md +++ b/doc/making-requests/querying-data.md @@ -5,7 +5,7 @@ scenarios for these query options. ## $filter -The $filter system query option allows clients to filter a collection of resources that are addressed by a request URL. +The `$filter` system query option allows clients to filter a collection of resources that are addressed by a request URL. The expression specified with `$filter` is evaluated for each resource in the collection, and only items where the expression evaluates to true are included in the response. @@ -45,7 +45,7 @@ GET http://localhost:8000/odata/People?$filter=FirstName eq 'Scott' ## $orderby -The $orderby system query option allows clients to request resources in either ascending order using asc or descending +The `$orderby` system query option allows clients to request resources in either ascending order using asc or descending order using desc. If asc or desc not specified, then the resources will be ordered in ascending order. The request below orders People on property LastName in descending order. @@ -87,8 +87,8 @@ GET http://localhost:8000/odata/People?$orderby=LastName ## $top and $skip -The $top system query option requests the number of items in the queried collection to be included in the result. -The $skip query option requests the number of items in the queried collection that are to be skipped and not included +The `$top` system query option requests the number of items in the queried collection to be included in the result. +The `$skip` query option requests the number of items in the queried collection that are to be skipped and not included in the result. The request below returns the first two people of the People entity set. @@ -157,7 +157,7 @@ GET http://localhost:8000/odata/People?$skip=1 ## $count -The $count system query option allows clients to request a count of the matching resources included with the +The `$count` system query option allows clients to request a count of the matching resources included with the resources in the response. The request below returns the total number of people in the collection. @@ -200,7 +200,7 @@ GET http://localhost:8000/odata/People?$count=true ## $expand -The $expand system query option specifies the related resources to be included in line with retrieved resources. +The `$expand` system query option specifies the related resources to be included in line with retrieved resources. The request below returns people with navigation property Passengers of a Flight @@ -275,7 +275,7 @@ GET http://localhost:8000/odata/flights?$expand=passengers ## $select -The $select system query option allows the clients to requests a limited set of properties for each entity or +The `$select` system query option allows the clients to requests a limited set of properties for each entity or complex type. The request below returns origin and destination of all flights: @@ -310,7 +310,7 @@ GET http://localhost:8000/odata/flights?$select=origin,destination ## $search -The $search system query option restricts the result to include only those entities matching the specified search +The `$search` system query option restricts the result to include only those entities matching the specified search expression. The definition of what it means to match is dependent upon the implementation. The request below gets all airports that have 'fo' or 'lh' in their code. @@ -342,6 +342,36 @@ GET http://localhost:8000/odata/flights?$search=fo OR lh +## $index + +The value of the `$index` system query option is the zero-based ordinal position where an +item is to be inserted. This option is supported on entity sets that can be numerically indexed. + +The ordinal positions of items within the collection greater than or equal to the inserted +position are increased by one. A negative ordinal number indexes from the end of the collection, with -1 representing +an insert as the last item in the collection. + + + +```uri +POST http://localhost:8000/odata/examples?$index=1 +{ + "name": "Zeta" +} +``` + + + +```json +{ + "@context": "http://localhost/odata/$metadata#examples/$entity", + "name": "Zeta", + "id": 1 +} +``` + + + ## Lambda Operators OData defines two operators `any` and `all` that evaluate a Boolean expression on a collection. diff --git a/doc/modelling/drivers/database.md b/doc/modelling/drivers/database.md index 58aa8eeb2..0f5c8332a 100644 --- a/doc/modelling/drivers/database.md +++ b/doc/modelling/drivers/database.md @@ -28,4 +28,4 @@ types discovered by the entity set. Almost all the available `$filter` capabilities are mapped into SQL expressions, supporting all the same database backends that Laravel does. -This driver supports `$search` by passing the provided search term into `field LIKE %param%` requests. +This driver supports `$search` by passing the provided search term into `field LIKE %param%` requests. \ No newline at end of file diff --git a/doc/modelling/drivers/eloquent.md b/doc/modelling/drivers/eloquent.md index b9902485d..cc04138fb 100644 --- a/doc/modelling/drivers/eloquent.md +++ b/doc/modelling/drivers/eloquent.md @@ -1,40 +1,59 @@ # Eloquent -Lodata can 'discover' Eloquent models, and the relationships between the models. +Lodata can 'discover' Eloquent models, the relationships between the models, and expose methods as operations on the +models. ::: tip The Eloquent driver extends the SQL driver, so the same `$filter` capabilities exist in both. ::: -Discovery is +## Data model + +Discovery of the data model is performed first using [DBAL](https://www.doctrine-project.org/projects/doctrine-dbal/en/2.12/index.html) to introspect the database table, then [Eloquent casts](https://laravel.com/docs/8.x/eloquent-mutators#custom-casts) are used for further type specification. During requests, the Eloquent model getter/setter functions are used to refer to the properties, so any additional field processing being performed by the model will be preserved. -To discover a model the `Lodata` facade that exists in the root namespace can be used. For example to discover -two models: +To discover a model the `Lodata` facade can be used. For example to discover the `Flight` model: ```php class LodataServiceProvider extends ServiceProvider { public function boot() { - \Lodata::discoverEloquentModel(\App\Models\Flight::class); - \Lodata::discoverEloquentModel(\App\Models\Passenger::class); + \Lodata::discover(\App\Models\Flight::class); } } ``` -If model `Flight` has a method `passengers` that returns a [relationship](https://laravel.com/docs/8.x/eloquent-relationships) -to `Passenger` such as hasOne, hasMany, hasManyThrough, this can be discovered by Lodata as a navigation property on the `Flights` entity set. +## Relationships + +If model `Flight` has a method `passengers` that returns a +[relationship](https://laravel.com/docs/8.x/eloquent-relationships) to `Passenger` such as hasOne, hasMany, +hasManyThrough, this can be discovered by Lodata as a navigation property on the `Flights` entity set. This method +can be tagged using an attribute that will be picked up during discovery. ::: tip The same as Laravel itself, Lodata typically refers to 'entity types' in the singular form and 'entity sets' in -the plural form. An entity set and its related entity set must both be defined through discovery before a -relationship can be created. +the plural form. ::: +```php +use Illuminate\Database\Eloquent\Model; + +class Flight extends Model +{ + #[LodataRelationship] + public function passengers() + { + return $this->hasMany(Passenger::class); + } +} +``` + +Alternatively for PHP versions that do not support attributes: + ```php \Lodata::getEntitySet('Flights') ->discoverRelationship('passengers') @@ -48,3 +67,100 @@ also be used in `$expand` requests. If Lodata is able to determine the relationship cardinality it will be represented in the service metadata document. + +## Operations + +Lodata can also expose model methods as operations. The method will be called on the specific instance of the entity +referenced in the URL. + + + +```php +use Carbon\Carbon; +use Flat3\Lodata\Attributes\LodataFunction; + +class Person extends Model { + #[LodataFunction] + public function age(): float { + return Carbon::parse($this->birthdate)->age; + } +} + +class LodataServiceProvider extends ServiceProvider +{ + public function boot() + { + Lodata::discover(Person::class); + } +} +``` + + + +``` +http://localhost:8000/odata/Person(1)/age() +``` + + + +```json +{ + "@context": "http://localhost:8000/odata/$metadata#Edm.Double", + "value": 52.2 +} +``` + + + +## Repository + +Some Laravel applications implement a [repository](https://www.twilio.com/blog/repository-pattern-in-laravel-application) +pattern for handling data access. Lodata can support this technique if the repository implements the +`RepositoryInterface` so that it can retrieve the correct model class name using the `getClass` method. For +invocation Lodata will pass the model instance as the bound parameter. + + + +```php +use Flat3\Lodata\Attributes\LodataFunction; +use Flat3\Lodata\Interfaces\RepositoryInterface; + +class Repository implements RepositoryInterface +{ + public function getClass(): string + { + return Airport::class; + } + + #[LodataFunction (bind: "airport")] + public function code(Airport $airport, ?string $suffix): string + { + return $airport->code.($suffix ?: ''); + } +} + +class LodataServiceProvider extends ServiceProvider +{ + public function boot() + { + Lodata::discover(Repository::class); + } +} +``` + + + +``` +http://localhost:8000/odata/Airports(1)/code(suffix='abc') +``` + + + +```json +{ + "@context": "http://localhost:8000/odata/$metadata#Edm.String", + "value": "lhrabc" +} +``` + + diff --git a/doc/modelling/operations.md b/doc/modelling/operations.md index 966a27b91..85678682d 100644 --- a/doc/modelling/operations.md +++ b/doc/modelling/operations.md @@ -10,38 +10,65 @@ convention operations that define themselves as Functions MUST return data and M MAY have side effects when invoked and MAY return data. Lodata does not enforce the side effect restriction, but does enforce the return data requirement. +Lodata can expose operations on uninstantiated classes, class instances and anonymous functions. +If a class name is provided, the class will be resolved to an instance via the +Laravel [service container](https://laravel.com/docs/8.x/container) for every operation call. If an instance is +provided, it will be re-used for each invocation of the operation. + +The simplest way to expose a method on a resolvable class is to decorate it with the `LodataFunction` or `LodataAction` +attribute, and then to use auto-discovery on the class. If using a version of PHP that does not support attributes, +or operations containing anonymous functions then operations can be created manually. + ::: tip As you implement these examples in your own application it is useful to observe changes to the model in the CSDL [metadata documents](./README.md). ::: -In the examples that follow each has the code, the request in cURL format, and the expected response. All of these -examples can be used with the same syntax for actions, but should implement the `ActionInterface`. +In the examples that follow each has the code provided by a class using attributes, an alternative using manual setup +or an anonymous function, the request in cURL format, and the expected response. +All of these examples can be used with the same syntax for actions. ## Hello World! -Here is the 'Hello world!' example. It is a class that extends `Operation`, and defines as a `Function` by implementing the `FunctionInterface`. -It implements the required `invoke()` method. The class uses the identifier `hello` when being added to the model. +Here is the simple 'Hello world!' example. We create a class with a method, decorate the method with the +`LodataFunction` attribute, and pass the class into discovery. The OData identifier is taken from the method name. The +inline example shows the same functionality by creating an `Operation` and attaching an anonymous function. - + ```php -use Flat3\Lodata\Interfaces\Operation\FunctionInterface; -use Flat3\Lodata\Operation; +use Flat3\Lodata\Attributes\LodataFunction; -class HelloWorld extends Operation implements FunctionInterface +class Example { + #[LodataFunction] + public function hello() { + return 'Hello world!'; + } +} + +class LodataServiceProvider extends ServiceProvider { - public function invoke() + public function boot() { - return 'Hello world!'; + Lodata::discover(Example::class); } } +``` + + + +```php +use Flat3\Lodata\Operation; class LodataServiceProvider extends ServiceProvider { public function boot() { - \Lodata::add(new HelloWorld('hello')); + $hello = new Operation\Function_('hello'); + $hello->setCallable(function () { + return 'Hello world!'; + }); + Lodata::add($hello); } } ``` @@ -65,33 +92,47 @@ http://localhost:8000/odata/hello ## Return types -If the return type of the `invoke()` method is void then Lodata assumes an `Edm.String` response. +If the return type of the method is void then Lodata assumes an `Edm.String` response. To properly type a string response you can add the PHP return type `string`. This method also works with `int` (converted to `Edm.Int64`), `float` (converted to `Edm.Double`) and `bool` (converted to `Edm.Boolean`): - + ```php -use Carbon\Carbon; -use Flat3\Lodata\Interfaces\Operation\FunctionInterface; -use Flat3\Lodata\Operation; -use Flat3\Lodata\Type\DateTimeOffset; +use Flat3\Lodata\Attributes\LodataFunction; -class MeaningOfLife extends Operation implements FunctionInterface +class Example { + #[LodataFunction] + public function mol(): int { + return 42; + } +} + +class LodataServiceProvider extends ServiceProvider { - public function invoke(): int + public function boot() { - return 42; + Lodata::discover(Example::class); } } +``` + + + +```php +use Flat3\Lodata\Operation; class LodataServiceProvider extends ServiceProvider { public function boot() { - \Lodata::add(new MeaningOfLife('mol')); + $mol = new Operation\Function_('mol'); + $mol->setCallable(function (): int { + return 42; + }); + Lodata::add($mol); } } ``` @@ -118,26 +159,42 @@ http://localhost:8000/odata/mol To use more specific OData types such as `Edm.DateTimeOffset` you can use Lodata's `Type` objects as return types: - + ```php -use Carbon\Carbon; -use Flat3\Lodata\Interfaces\Operation\FunctionInterface; -use Flat3\Lodata\Operation; -use Flat3\Lodata\Type\DateTimeOffset; +use Flat3\Lodata\Attributes\LodataFunction; -class CurrentTime extends Operation implements FunctionInterface +class Example { + #[LodataFunction] + public function now(): Type\DateTimeOffset { + return new Type\DateTimeOffset( Carbon::now() ); + } +} + +class LodataServiceProvider extends ServiceProvider { - public function invoke(): DateTimeOffset + public function boot() { - return new DateTimeOffset( Carbon::now() ); + Lodata::discover(Example::class); } } +``` + + + +```php +use Carbon\Carbon; +use Flat3\Lodata\Operation; +use Flat3\Lodata\Type; class LodataServiceProvider extends ServiceProvider { public function boot() { - \Lodata::add(new CurrentTime('now')); + $now = new Operation\Function_('now'); + $now->setCallable(function (): Type\DateTimeOffset { + return new Type\DateTimeOffset( Carbon::now() ); + }); + Lodata::add($now); } } ``` @@ -161,27 +218,43 @@ http://localhost:8000/odata/now ## Arguments -Arguments can be specified in the definition of `invoke()`, and then supplied as key/value pairs in the URL: +Arguments can be specified for the callback, and then supplied as key/value pairs in the URL (or the body for actions). - + ```php -use Flat3\Lodata\Interfaces\Operation\FunctionInterface; -use Flat3\Lodata\Operation; +use Flat3\Lodata\Attributes\LodataFunction; -class Add extends Operation implements FunctionInterface +class Example { + #[LodataFunction] + public function add(int $a, int $b): int { + return $a + $b; + } +} + +class LodataServiceProvider extends ServiceProvider { - public function invoke(int $a, int $b): int + public function boot() { - return $a + $b; + Lodata::discover(Example::class); } } +``` + + + +```php +use Flat3\Lodata\Operation; class LodataServiceProvider extends ServiceProvider { public function boot() { - \Lodata::add(new Add('add')); + $add = new Operation\Function_('add'); + $add->setCallable(function (int $a, int $b): int { + return $a + $b; + }); + Lodata::add($add); } } ``` @@ -215,26 +288,44 @@ is used to return the `Carbon` object contained within the `DateTimeOffset`, and ::: - + ```php -use Flat3\Lodata\Interfaces\Operation\FunctionInterface; -use Flat3\Lodata\Operation; +use Flat3\Lodata\Attributes\LodataFunction; use Flat3\Lodata\Type\DateTimeOffset; use Flat3\Lodata\Type\Duration; -class Add extends Operation implements FunctionInterface +class Example { + #[LodataFunction] + public function add(DateTimeOffset $timestamp, Duration $increment): DateTimeOffset { + return new DateTimeOffset($timestamp->get()->addSeconds($increment->get())); + } +} + +class LodataServiceProvider extends ServiceProvider { - public function invoke(DateTimeOffset $timestamp, Duration $increment): DateTimeOffset + public function boot() { - return new DateTimeOffset($timestamp->get()->addSeconds($increment->get())); + Lodata::discover(Example::class); } } +``` + + + +```php +use Flat3\Lodata\Operation; +use Flat3\Lodata\Type\DateTimeOffset; +use Flat3\Lodata\Type\Duration; class LodataServiceProvider extends ServiceProvider { public function boot() { - \Lodata::add(new Add('add')); + $add = new Operation\Function_('add'); + $add->setCallable(function (DateTimeOffset $timestamp, Duration $increment): DateTimeOffset { + return new DateTimeOffset($timestamp->get()->addSeconds($increment->get())); + }); + Lodata::add($add); } } ``` @@ -262,24 +353,40 @@ In the previous examples none of the arguments or the return types supported bei an argument can be null. For `Action` operations, the return type can be nullable. - + ```php -use Flat3\Lodata\Interfaces\Operation\FunctionInterface; -use Flat3\Lodata\Operation; +use Flat3\Lodata\Attributes\LodataFunction; -class Add extends Operation implements FunctionInterface +class Example { + #[LodataFunction] + public function add(?int $a, ?int $b): int { + return (null === $a || null === $b) ? 0 : $a + $b; + } +} + +class LodataServiceProvider extends ServiceProvider { - public function invoke(?int $a, ?int $b): int + public function boot() { - return (null === $a || null === $b) ? 0 : $a + $b; + Lodata::discover(Example::class); } } +``` + + + +```php +use Flat3\Lodata\Operation; class LodataServiceProvider extends ServiceProvider { public function boot() { - \Lodata::add(new Add('add')); + $add = new Operation\Function_('add'); + $add->setCallable(function (?int $a, ?int $b): int { + return (null === $a || null === $b) ? 0 : $a + $b; + }); + Lodata::add($add); } } ``` @@ -311,38 +418,57 @@ In this example, the `DateTimeOffset` generated by the first function call is au parameter of the second function call. - + ```php -use Flat3\Lodata\Interfaces\Operation\FunctionInterface; -use Flat3\Lodata\Operation; +use Carbon\Carbon; +use Flat3\Lodata\Attributes\LodataFunction; use Flat3\Lodata\Type\DateTimeOffset; use Flat3\Lodata\Type\Duration; -use Carbon\Carbon; -class Now extends Operation implements FunctionInterface -{ - public function invoke(): DateTimeOffset - { - return new DateTimeOffset(Carbon::now()); +class Example { + #[LodataFunction] + public function now(): DateTimeOffset { + return new DateTimeOffset(Carbon::now()); + } + + #[LodataFunction(bind: "timestamp")] + public function add(DateTimeOffset $timestamp, Duration $increment): DateTimeOffset { + return new DateTimeOffset($timestamp->get()->addSeconds($increment->get())); } } -class Add extends Operation implements FunctionInterface +class LodataServiceProvider extends ServiceProvider { - protected $bindingParameterName = 'timestamp'; - - public function invoke(DateTimeOffset $timestamp, Duration $increment): DateTimeOffset - { - return new DateTimeOffset($timestamp->get()->addSeconds($increment->get())); + public function boot() + { + Lodata::discover(Example::class); } } +``` + + + +```php +use Carbon\Carbon; +use Flat3\Lodata\Operation; +use Flat3\Lodata\Type\DateTimeOffset; +use Flat3\Lodata\Type\Duration; class LodataServiceProvider extends ServiceProvider { public function boot() { - \Lodata::add(new Add('add')); - \Lodata::add(new Now('now')); + $add = new Operation\Function_('add'); + $add->setCallable(function (DateTimeOffset $timestamp, Duration $increment): DateTimeOffset { + return new DateTimeOffset($timestamp->get()->addSeconds($increment->get())); + })->setBindingParameterName('timestamp'); + Lodata::add($add); + + $now = new Operation\Function_('now'); + $now->setCallable(function (): DateTimeOffset { + return new DateTimeOffset(Carbon::now()); + }); + Lodata::add($now); } } ``` @@ -375,25 +501,22 @@ collection is defined, and the URL picks the first one by its entity ID and pass its binding parameter. - + ```php use Carbon\Carbon; +use Flat3\Lodata\Attributes\LodataFunction; use Flat3\Lodata\DeclaredProperty; use Flat3\Lodata\Drivers\CollectionEntitySet; use Flat3\Lodata\Entity; use Flat3\Lodata\EntityType; use Flat3\Lodata\Facades\Lodata; -use Flat3\Lodata\Interfaces\Operation\FunctionInterface; -use Flat3\Lodata\Operation; use Flat3\Lodata\Type; -use Flat3\Lodata\Type\Duration; use Illuminate\Support\ServiceProvider; -class NextBirthday extends Operation implements FunctionInterface +class NextBirthday { - protected $bindingParameterName = 'person'; - - public function invoke( Entity $person ): Duration + #[LodataFunction(bind: "person")] + public function nb( Entity $person ): Type\Duration { /** @var Carbon $dob */ $dob = $person['dob']->getPrimitiveValue(); @@ -403,12 +526,48 @@ class NextBirthday extends Operation implements FunctionInterface $diff = $now->diffInSeconds( $dob->year( date( 'Y' ) ), false ); if ( $diff > 0 ) { - return new Duration( $diff ); + return new Type\Duration( $diff ); } - return new Duration( $now->diffInSeconds( $dob->year( date( 'Y' ) + 1 ), false ) ); + return new Type\Duration( $now->diffInSeconds( $dob->year( date( 'Y' ) + 1 ), false ) ); + } +} + +class AppServiceProvider extends ServiceProvider +{ + public function boot() + { + $person = new EntityType( 'person' ); + $person->setKey( new DeclaredProperty( 'id', Type::int64() ) ); + $person->addDeclaredProperty( 'name', Type::string() ); + $person->addDeclaredProperty( 'dob', Type::date() ); + + $people = new CollectionEntitySet( 'people', $person ); + $people->setCollection( collect( [ + [ + 'name' => 'Michael Caine', + 'dob' => '1933-03-14', + ] + ] ) ); + + Lodata::add( $people ); + Lodata::discover( NextBirthday::class ); } } +``` + + + +```php +use Carbon\Carbon; +use Flat3\Lodata\DeclaredProperty; +use Flat3\Lodata\Drivers\CollectionEntitySet; +use Flat3\Lodata\Entity; +use Flat3\Lodata\EntityType; +use Flat3\Lodata\Facades\Lodata; +use Flat3\Lodata\Operation; +use Flat3\Lodata\Type; +use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { @@ -428,7 +587,24 @@ class AppServiceProvider extends ServiceProvider ] ) ); Lodata::add( $people ); - Lodata::add( new NextBirthday( 'nb' ) ); + + $nb = new Operation\Function_('nb'); + $nb->setCallback(function( Entity $person ): Type\Duration { + /** @var Carbon $dob */ + $dob = $person['dob']->getPrimitiveValue(); + + $now = Carbon::now(); + + $diff = $now->diffInSeconds( $dob->year( date( 'Y' ) ), false ); + + if ( $diff > 0 ) { + return new Type\Duration( $diff ); + } + + return new Type\Duration( $now->diffInSeconds( $dob->year( date( 'Y' ) + 1 ), false ) ); + })->setBindingParameterName('person'); + + Lodata::add( $nb ); } } ``` @@ -458,24 +634,18 @@ in the constructor of the `Operation`. In this example a random person entity is example also shows the identifier of the operation being configured in the constructor. - + ```php use Flat3\Lodata\DeclaredProperty; use Flat3\Lodata\Entity; use Flat3\Lodata\EntityType; -use Flat3\Lodata\Interfaces\Operation\FunctionInterface; -use Flat3\Lodata\Operation; use Flat3\Lodata\Type; use Illuminate\Support\ServiceProvider; -class PersonGenerator extends Operation implements FunctionInterface +class PersonGenerator { - public function __construct() { - parent::__construct( 'randomperson' ); - $this->setReturnType( \Lodata::getEntityType( 'person' ) ); - } - - public function invoke(): Entity + #[LodataFunction(return: "person")] + public function randomperson(): Entity { $person = \Lodata::getEntityType( 'person' ); $entity = new Entity(); @@ -499,7 +669,45 @@ class AppServiceProvider extends ServiceProvider $person->addDeclaredProperty( 'dob', Type::date() ); \Lodata::add( $person ); - \Lodata::add( new PersonGenerator() ); + \Lodata::discover( PersonGenerator::class ); + } +} +``` + + + +```php +use Flat3\Lodata\DeclaredProperty; +use Flat3\Lodata\Entity; +use Flat3\Lodata\EntityType; +use Flat3\Lodata\Operation; +use Flat3\Lodata\Type; +use Illuminate\Support\ServiceProvider; + +class AppServiceProvider extends ServiceProvider +{ + public function boot() + { + $person = new EntityType( 'person' ); + $person->setKey( new DeclaredProperty( 'id', Type::int64() ) ); + $person->addDeclaredProperty( 'name', Type::string() ); + $person->addDeclaredProperty( 'dob', Type::date() ); + \Lodata::add( $person ); + + $generator = new Operation\Function_('randomperson'); + $generator->setCallback(function(): Entity { + $person = \Lodata::getEntityType( 'person' ); + $entity = new Entity(); + $entity->setType( $person ); + + $faker = \Faker\Factory::create(); + $entity['name'] = $faker->name(); + $entity['dob'] = $faker->date(); + + return $entity; + })->setReturnType( $person ); + + \Lodata::add( $generator ); } } ``` @@ -533,17 +741,94 @@ For example via the function import EmployeesByManager, passing 3 for the Manage http://localhost:8000/odata/EmployeesByManager(ManagerID=@p1)?@p1=3 ``` -## Creating using artisan +## Class instances + +A class instance can be provided for the operation, and the same instance will be called with each invocation. + + + +```php +use Flat3\Lodata\Attributes\LodataFunction; -Actions and Function classes can be generated through `artisan` commands, and can be added to Lodata in the `boot()` -method of a service provider: +class Example { + protected $value = 0; -```sh -php artisan lodata:function Add + #[LodataFunction] + public function incr(): int { + return ++$this->value; + } +} + +class LodataServiceProvider extends ServiceProvider +{ + public function boot() + { + $example = new Example(); + Lodata::discover($example); + } +} +``` + + + ``` -```sh -php artisan lodata:action Subtract +http://localhost:8000/odata/incr() ``` + + + +```json +{ + "@context": "http://localhost:8000/odata/$metadata#Edm.Int64", + "value": 1 +} +``` + + + +## Namespacing + +Operations can be namespaced to provide more organization for unbound functions and actions on the model. + + + +```php +use Flat3\Lodata\Attributes\LodataFunction; +use Flat3\Lodata\Attributes\LodataNamespace; + +#[LodataNamespace(name: "com.example.math")] +class Math { + #[LodataFunction] + public function add(int $a, int $b): int { + return $a + $b; + } +} + +class LodataServiceProvider extends ServiceProvider +{ + public function boot() + { + Lodata::discover(Math::class); + } +} +``` + + + +``` +http://localhost:8000/odata/com.example.math.add(a=1,b=2) +``` + + + +```json +{ + "@context": "http://localhost:8000/odata/$metadata#Edm.Int64", + "value": 3 +} +``` + + ## Transaction @@ -553,10 +838,85 @@ parameter. The transaction contains all the available context for the request, a query options. ```php -public class MethodResponder extends Operation implements FunctionInterface { - public function invoke(Transaction $transaction): string +public class MethodResponder { + #[LodataFunction] + public function example(Transaction $transaction): string { return $transaction->getRequest()->getMethod(); } } -``` \ No newline at end of file +``` + +## Upgrading from 3.x + +Lodata 3 had a completely different way of describing operations, this section briefly describes a previous example +and the more simplified layout of the new example. + + + +```php +use Flat3\Lodata\Interfaces\Operation\FunctionInterface; +use Flat3\Lodata\Operation; +use Flat3\Lodata\Type\DateTimeOffset; +use Flat3\Lodata\Type\Duration; +use Carbon\Carbon; + +class Now extends Operation implements FunctionInterface +{ + public function invoke(): DateTimeOffset + { + return new DateTimeOffset(Carbon::now()); + } +} + +class Add extends Operation implements FunctionInterface +{ + protected $bindingParameterName = 'timestamp'; + + public function invoke(DateTimeOffset $timestamp, Duration $increment): DateTimeOffset + { + return new DateTimeOffset($timestamp->get()->addSeconds($increment->get())); + } +} + +class LodataServiceProvider extends ServiceProvider +{ + public function boot() + { + \Lodata::add(new Add('add')); + \Lodata::add(new Now('now')); + } +} +``` + + + +```php +use Flat3\Lodata\Type\DateTimeOffset; +use Flat3\Lodata\Type\Duration; +use Carbon\Carbon; + +class TimeCalculation { + #[LodataFunction] + public function now(): DateTimeOffset + { + return new DateTimeOffset(Carbon::now()); + } + + #[LodataFunction(bind: "timestamp")] + public function add(DateTimeOffset $timestamp, Duration $increment): DateTimeOffset + { + return new DateTimeOffset($timestamp->get()->addSeconds($increment->get())); + } +} + +class LodataServiceProvider extends ServiceProvider +{ + public function boot() + { + \Lodata::discover(TimeCalculation::class); + } +} +``` + + \ No newline at end of file diff --git a/phpdoc.xml b/phpdoc.xml deleted file mode 100644 index 1e65b785e..000000000 --- a/phpdoc.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - Lodata - - docs - - - - - src - - api - - - - doc - - guide - - - diff --git a/src/Annotation/Core/V1/PositionalInsert.php b/src/Annotation/Core/V1/PositionalInsert.php new file mode 100644 index 000000000..d7b3a83bc --- /dev/null +++ b/src/Annotation/Core/V1/PositionalInsert.php @@ -0,0 +1,22 @@ +value = new Boolean(true); + } +} \ No newline at end of file diff --git a/src/Attributes/LodataAction.php b/src/Attributes/LodataAction.php new file mode 100644 index 000000000..7ba982584 --- /dev/null +++ b/src/Attributes/LodataAction.php @@ -0,0 +1,14 @@ +name = $name; + } + + public function getName(): string + { + return $this->name; + } +} \ No newline at end of file diff --git a/src/Attributes/LodataOperation.php b/src/Attributes/LodataOperation.php new file mode 100644 index 000000000..80a865ce2 --- /dev/null +++ b/src/Attributes/LodataOperation.php @@ -0,0 +1,54 @@ +name = $name; + $this->bind = $bind; + if ($return) { + $this->return = Lodata::getEntityType($return); + } + } + + public function getName(): ?string + { + return $this->name; + } + + public function hasBindingParameterName(): bool + { + return $this->bind !== null; + } + + public function getBindingParameterName(): string + { + return $this->bind; + } + + public function hasReturnType(): bool + { + return $this->return !== null; + } + + public function getReturnType(): Type + { + return $this->return; + } +} \ No newline at end of file diff --git a/src/Attributes/LodataRelationship.php b/src/Attributes/LodataRelationship.php new file mode 100644 index 000000000..4bff686f0 --- /dev/null +++ b/src/Attributes/LodataRelationship.php @@ -0,0 +1,12 @@ +propertyValues->exists($offset); } @@ -160,7 +159,7 @@ public function offsetGet($offset) * @param mixed $offset Property name * @param mixed $value Property value */ - public function offsetSet($offset, $value) + public function offsetSet($offset, $value): void { if (Str::startsWith($offset, '@')) { return; @@ -168,7 +167,7 @@ public function offsetSet($offset, $value) $property = $this->getType()->getProperty($offset); if ($property === null) { - $property = new DynamicProperty($offset, Type::castInternalType(gettype($value))); + $property = new DynamicProperty($offset, Type::fromInternalValue($value)); } $propertyType = $property->getType(); @@ -213,7 +212,7 @@ public function offsetSet($offset, $value) * Remove a property value from this complex value * @param mixed $offset Property name */ - public function offsetUnset($offset) + public function offsetUnset($offset): void { $this->propertyValues->drop($offset); } diff --git a/src/Console/ActionCommand.php b/src/Console/ActionCommand.php deleted file mode 100644 index d98b4f97b..000000000 --- a/src/Console/ActionCommand.php +++ /dev/null @@ -1,16 +0,0 @@ -stub; - } - - protected function getDefaultNamespace($rootNamespace): string - { - return $rootNamespace.'\\Lodata'; - } - - public function handle(): bool - { - if ($this->isReservedName($this->getNameInput())) { - $this->error(sprintf('The name "%s" is reserved by PHP.', $this->getNameInput())); - - return false; - } - - $name = $this->qualifyClass($this->getNameInput()); - - if ( - !$this->hasOption('force' || !$this->option('force')) - && $this->alreadyExists($this->getNameInput()) - ) { - $this->error("{$name} already exists!"); - - return false; - } - - $path = $this->getPath($name); - $this->makeDirectory($path); - $this->files->put($path, $this->sortImports($this->buildClass($name))); - $this->info("{$name} created successfully at {$path}"); - - return true; - } -} \ No newline at end of file diff --git a/src/Console/FunctionCommand.php b/src/Console/FunctionCommand.php deleted file mode 100644 index 2b99eb4b5..000000000 --- a/src/Console/FunctionCommand.php +++ /dev/null @@ -1,16 +0,0 @@ -header('content-type', self::contentType); + $response->header(Constants::contentType, self::contentType); $htmlDoc = new DOMDocument(); diff --git a/src/Controller/PBIDS.php b/src/Controller/PBIDS.php index b08c9cb9a..f559c8de4 100644 --- a/src/Controller/PBIDS.php +++ b/src/Controller/PBIDS.php @@ -4,6 +4,7 @@ namespace Flat3\Lodata\Controller; +use Flat3\Lodata\Helper\Constants; use Flat3\Lodata\ServiceProvider; use Flat3\Lodata\Transaction\MediaType; use Illuminate\Http\Response; @@ -24,7 +25,7 @@ class PBIDS extends Controller public function get(): Response { $response = new Response(); - $response->header('content-type', MediaType::json); + $response->header(Constants::contentType, MediaType::json); $disposition = $response->headers->makeDisposition( ResponseHeaderBag::DISPOSITION_ATTACHMENT, diff --git a/src/Controller/Response.php b/src/Controller/Response.php index f81aee655..78b86f470 100644 --- a/src/Controller/Response.php +++ b/src/Controller/Response.php @@ -155,7 +155,7 @@ public function getStatusText(): string */ public function getContentType(): ?MediaType { - return (new MediaType)->parse($this->headers->get('content-type')); + return (new MediaType)->parse($this->headers->get(Constants::contentType)); } /** diff --git a/src/Controller/Transaction.php b/src/Controller/Transaction.php index bc178e081..2c193e06a 100644 --- a/src/Controller/Transaction.php +++ b/src/Controller/Transaction.php @@ -27,7 +27,6 @@ use Flat3\Lodata\Helper\ObjectArray; use Flat3\Lodata\Helper\PropertyValue; use Flat3\Lodata\Interfaces\JsonInterface; -use Flat3\Lodata\Interfaces\Operation\ArgumentInterface; use Flat3\Lodata\Interfaces\PipeInterface; use Flat3\Lodata\Interfaces\RequestInterface; use Flat3\Lodata\Interfaces\ResponseInterface; @@ -47,6 +46,7 @@ use Flat3\Lodata\Transaction\Option\Filter; use Flat3\Lodata\Transaction\Option\Format; use Flat3\Lodata\Transaction\Option\Id; +use Flat3\Lodata\Transaction\Option\Index; use Flat3\Lodata\Transaction\Option\OrderBy; use Flat3\Lodata\Transaction\Option\SchemaVersion; use Flat3\Lodata\Transaction\Option\Search; @@ -67,7 +67,7 @@ * Transaction * @package Flat3\Lodata */ -class Transaction implements ArgumentInterface +class Transaction { /** * Transaction ID @@ -177,6 +177,12 @@ class Transaction implements ArgumentInterface */ private $idOption; + /** + * Index system query option + * @var Index $index + */ + private $index; + /** * Schema version system query option * @var SchemaVersion $schemaVersion @@ -234,6 +240,7 @@ public function __construct() $this->skiptoken = new SkipToken(); $this->top = new Top(); $this->idOption = new Id(); + $this->index = new Index(); } /** @@ -252,7 +259,7 @@ public function initialize(RequestInterface $request): self ); $this->preferences = new ParameterList(); - $this->preferences->parse($this->getRequestHeader('prefer')); + $this->preferences->parse($this->getRequestHeader(Constants::prefer)); foreach ($this->request->query->keys() as $param) { if (Str::startsWith($param, '$') && !in_array($param, $this->getSystemQueryOptions())) { @@ -307,6 +314,7 @@ public function setRequest(RequestInterface $request): self $this->skiptoken = (new SkipToken)->setTransaction($this); $this->top = (new Top)->setTransaction($this); $this->idOption = (new Id)->setTransaction($this); + $this->index = (new Index)->setTransaction($this); return $this; } @@ -491,6 +499,15 @@ public function getIdOption(): Id return $this->idOption; } + /** + * Get the $index system query option + * @return Index Index + */ + public function getIndex(): Index + { + return $this->index; + } + /** * Mark as requested preference as having been applied to the response object * @param string $key Preference @@ -499,8 +516,8 @@ public function getIdOption(): Id */ public function preferenceApplied(string $key, string $value): self { - $this->response->headers->set('preference-applied', sprintf('%s=%s', $key, $value)); - $this->response->headers->set('vary', 'prefer', true); + $this->response->headers->set(Constants::preferenceApplied, sprintf('%s=%s', $key, $value)); + $this->response->headers->set(Constants::vary, Constants::prefer, true); return $this; } @@ -552,7 +569,7 @@ public function getPreferenceValue(string $preference): ?string */ public function getCharset(): ?string { - return $this->getRequestHeader('accept-charset') ?: (new MediaType)->parse($this->getResponseHeader('content-type'))->getParameter('charset'); + return $this->getRequestHeader('accept-charset') ?: (new MediaType)->parse($this->getResponseHeader(Constants::contentType))->getParameter('charset'); } /** @@ -561,7 +578,7 @@ public function getCharset(): ?string */ public function getProvidedContentType(): MediaType { - return (new MediaType)->parse($this->getRequestHeader('content-type') ?? ''); + return (new MediaType)->parse($this->getRequestHeader(Constants::contentType) ?? ''); } /** @@ -620,6 +637,24 @@ public function getAcceptedContentType(): MediaType return (new MediaType)->parse('*/*'); } + /** + * Get the content encoding requested by the client + * @return string Content encoding + */ + public function getContentEncoding(): string + { + return $this->getRequestHeader(Constants::contentEncoding); + } + + /** + * Get the content language requested by the client + * @return string Content language + */ + public function getContentLanguage(): string + { + return $this->getRequestHeader(Constants::contentLanguage); + } + /** * Set the content encoding response header * @param string $encoding Encoding @@ -627,7 +662,7 @@ public function getAcceptedContentType(): MediaType */ public function setContentEncoding(string $encoding): self { - $this->sendHeader('content-encoding', $encoding); + $this->sendHeader(Constants::contentEncoding, $encoding); return $this; } @@ -639,7 +674,7 @@ public function setContentEncoding(string $encoding): self */ public function setContentLanguage(string $language): self { - $this->sendHeader('content-language', $language); + $this->sendHeader(Constants::contentLanguage, $language); return $this; } @@ -660,7 +695,7 @@ public function getFormat(): Format */ public function sendContentType(MediaType $contentType): self { - $this->sendHeader('content-type', (string) $contentType); + $this->sendHeader(Constants::contentType, (string) $contentType); return $this; } @@ -737,7 +772,7 @@ public function getParameterAlias(string $key): ?string if (null === $value) { throw new BadRequestException( 'reference_value_missing', - sprintf('The requested reference value %s did not exist', $key) + sprintf('The requested reference (%s) did not exist', $key) ); } @@ -849,7 +884,7 @@ private function getSystemQueryOptions(bool $prefixed = true): array { $options = [ 'apply', 'count', 'compute', 'expand', 'format', 'filter', 'orderby', 'search', 'select', 'skip', - 'skiptoken', 'top', 'schemaversion', 'id', + 'skiptoken', 'top', 'schemaversion', 'id', 'index', ]; if ($prefixed) { diff --git a/src/Drivers/CollectionEntitySet.php b/src/Drivers/CollectionEntitySet.php index 509625c17..185866b5b 100644 --- a/src/Drivers/CollectionEntitySet.php +++ b/src/Drivers/CollectionEntitySet.php @@ -4,14 +4,17 @@ namespace Flat3\Lodata\Drivers; +use Flat3\Lodata\Annotation\Core\V1\PositionalInsert; use Flat3\Lodata\ComplexValue; use Flat3\Lodata\Entity; +use Flat3\Lodata\Helper\Annotations; use Flat3\Lodata\Helper\PropertyValue; use Flat3\Lodata\Helper\PropertyValues; use Flat3\Lodata\Interfaces\EntitySet\CreateInterface; use Flat3\Lodata\Interfaces\EntitySet\DeleteInterface; use Flat3\Lodata\Interfaces\EntitySet\UpdateInterface; use Flat3\Lodata\Primitive; +use Flat3\Lodata\Type\Numeric; use Illuminate\Support\Collection; /** @@ -41,6 +44,15 @@ public function getCollection(): Collection return $this->enumerable; } + /** + * Return whether this collection is numerically indexed + * @return bool + */ + public function isNumericallyIndexed(): bool + { + return $this->getType()->getKey()->getType()->instance() instanceof Numeric; + } + /** * Create a new entity * @param PropertyValues $propertyValues Property values @@ -55,13 +67,25 @@ public function create(PropertyValues $propertyValues): Entity } $entityId = $entity->getEntityId(); + $index = $this->getIndex(); + + $item = $entity->toArray(); - if ($entityId) { - $key = $entityId->getPrimitiveValue(); - $this->enumerable[$key] = $entity->toArray(); - } else { - $this->enumerable[] = $entity->toArray(); - $entity->setEntityId($this->enumerable->count() - 1); + switch (true) { + case !!$entityId: + $key = $entityId->getPrimitiveValue(); + $this->enumerable[$key] = $item; + break; + + case $index->hasValue() && $this->isNumericallyIndexed(): + $this->enumerable->splice($index->getValue(), 0, [$item]); + $entity->setEntityId($index->getValue()); + break; + + default: + $this->enumerable[] = $item; + $entity->setEntityId($this->enumerable->count() - 1); + break; } return $entity; @@ -109,4 +133,15 @@ public function update(PropertyValue $key, PropertyValues $propertyValues): Enti return $this->read($key); } + + public function getAnnotations(): Annotations + { + $annotations = parent::getAnnotations(); + + if ($this->isNumericallyIndexed()) { + $annotations->set(new PositionalInsert()); + } + + return $annotations; + } } \ No newline at end of file diff --git a/src/Drivers/EloquentEntitySet.php b/src/Drivers/EloquentEntitySet.php index 8cef7390b..47dfa843c 100644 --- a/src/Drivers/EloquentEntitySet.php +++ b/src/Drivers/EloquentEntitySet.php @@ -6,6 +6,7 @@ use Doctrine\DBAL\Schema\Column; use Exception; +use Flat3\Lodata\Annotation\Capabilities\V1\DeepInsertSupport; use Flat3\Lodata\DeclaredProperty; use Flat3\Lodata\Drivers\SQL\SQLConnection; use Flat3\Lodata\Drivers\SQL\SQLFilter; @@ -15,8 +16,10 @@ use Flat3\Lodata\Entity; use Flat3\Lodata\EntitySet; use Flat3\Lodata\EntityType; +use Flat3\Lodata\Exception\Protocol\ConfigurationException; use Flat3\Lodata\Exception\Protocol\InternalServerErrorException; use Flat3\Lodata\Facades\Lodata; +use Flat3\Lodata\Helper\Discovery; use Flat3\Lodata\Helper\PropertyValue; use Flat3\Lodata\Helper\PropertyValues; use Flat3\Lodata\Interfaces\EntitySet\CountInterface; @@ -47,7 +50,6 @@ use Illuminate\Database\Eloquent\Relations\Relation; use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\DB; -use Illuminate\Support\Str; use ReflectionException; use ReflectionMethod; @@ -74,7 +76,7 @@ class EloquentEntitySet extends EntitySet implements CountInterface, CreateInter public function __construct(string $model) { if (!is_a($model, Model::class, true)) { - throw new InternalServerErrorException( + throw new ConfigurationException( 'not_eloquent_model', 'An eloquent model class name must be provided' ); @@ -82,10 +84,11 @@ public function __construct(string $model) $this->model = $model; - $name = $this->getSetName($model); - $type = new EntityType(EloquentEntitySet::getTypeName($model)); + $name = self::convertClassName($model); + $type = new EntityType(EntityType::convertClassName($model)); parent::__construct($name, $type); + $this->addAnnotation(new DeepInsertSupport()); } /** @@ -99,26 +102,6 @@ public function setModel(string $model): self return $this; } - /** - * Get the OData entity type name for this Eloquent model - * @param string $model Eloquent model class name - * @return string OData identifier - */ - public static function getTypeName(string $model): string - { - return Str::studly(class_basename($model)); - } - - /** - * Get the OData entity set name for this Eloquent model - * @param string $model Eloquent model class name - * @return string OData identifier - */ - public function getSetName(string $model): string - { - return Str::pluralStudly(class_basename($model)); - } - /** * Return an instance of the Eloquent model using the provided key * @param PropertyValue $key Key @@ -329,10 +312,10 @@ public function discoverRelationship(string $method): self /** @var Relation $r */ $r = $model->$method(); - $esn = $this->getSetName(get_class($r->getRelated())); + $esn = self::convertClassName(get_class($r->getRelated())); $right = Lodata::getEntitySet($esn); if (!$right) { - throw new InternalServerErrorException('no_related_set', 'Could not find the related entity set '.$esn); + $right = (new Discovery)->discoverEloquentModel(get_class($r->getRelated())); } $nav = (new NavigationProperty($method, $right->getType())) @@ -343,7 +326,7 @@ public function discoverRelationship(string $method): self $foreignProperty = $right->getType()->getProperty($r->getForeignKeyName()); if (!$localProperty || !$foreignProperty) { - throw new InternalServerErrorException( + throw new ConfigurationException( 'missing_properties', 'The properties referenced for the relationship could not be found on the models' ); @@ -362,7 +345,7 @@ public function discoverRelationship(string $method): self $this->getType()->addProperty($nav); $this->addNavigationBinding($binding); } catch (ReflectionException $e) { - throw new InternalServerErrorException( + throw new ConfigurationException( 'cannot_add_constraint', 'The constraint method did not exist on the model: '.get_class($model) ); @@ -371,20 +354,6 @@ public function discoverRelationship(string $method): self return $this; } - /** - * Create an entity set from the provided Eloquent model class and add it to the model - * @param string $class Eloquent model class - * @return static - */ - public static function discover(string $class): self - { - $set = new self($class); - Lodata::add($set); - $set->discoverProperties(); - - return $set; - } - public function startTransaction() { DB::beginTransaction(); diff --git a/src/Drivers/SQL/SQLConnection.php b/src/Drivers/SQL/SQLConnection.php index 41ed548e3..6e53816c0 100644 --- a/src/Drivers/SQL/SQLConnection.php +++ b/src/Drivers/SQL/SQLConnection.php @@ -8,7 +8,7 @@ use Doctrine\DBAL\Platforms\PostgreSQL94Platform; use Doctrine\DBAL\Platforms\SqlitePlatform; use Doctrine\DBAL\Platforms\SQLServer2012Platform; -use Flat3\Lodata\Exception\Protocol\InternalServerErrorException; +use Flat3\Lodata\Exception\Protocol\ConfigurationException; use Illuminate\Database\Connection; use Illuminate\Database\ConnectionInterface; use Illuminate\Support\Facades\DB; @@ -94,6 +94,6 @@ public function quote(string $param): string return (new MySQLPlatform())->quoteSingleIdentifier($param); } - throw new InternalServerErrorException('invalid_driver', 'An invalid driver was used'); + throw new ConfigurationException('invalid_driver', 'An invalid driver was used'); } } diff --git a/src/Drivers/SQLEntitySet.php b/src/Drivers/SQLEntitySet.php index 94ef5335c..ad839efe6 100644 --- a/src/Drivers/SQLEntitySet.php +++ b/src/Drivers/SQLEntitySet.php @@ -120,6 +120,19 @@ public function getPropertySourceName(Property $property): string return $this->sourceMap[$property] ?? $property->getName(); } + /** + * Set an underlying database field name for the given entity type property + * @param Property $property Property + * @param string $sourceName Field name + * @return $this + */ + public function setPropertySourceName(Property $property, string $sourceName): self + { + $this->sourceMap[$property] = $sourceName; + + return $this; + } + /** * Read an SQL record * @param PropertyValue $key Key diff --git a/src/Drivers/StaticEntitySet.php b/src/Drivers/StaticEntitySet.php index 4bafebfe0..56bd5cdbb 100644 --- a/src/Drivers/StaticEntitySet.php +++ b/src/Drivers/StaticEntitySet.php @@ -41,7 +41,7 @@ public function query(): Generator } } - public function offsetExists($offset) + public function offsetExists($offset): bool { return array_key_exists($offset, $this->results); } @@ -51,7 +51,7 @@ public function offsetGet($offset) return $this->results[$offset]; } - public function offsetSet($offset, $value) + public function offsetSet($offset, $value): void { if ($offset) { $this->results[$offset] = $value; @@ -60,7 +60,7 @@ public function offsetSet($offset, $value) } } - public function offsetUnset($offset) + public function offsetUnset($offset): void { unset ($this->results[$offset]); } diff --git a/src/Entity.php b/src/Entity.php index 304c72769..35d208a37 100644 --- a/src/Entity.php +++ b/src/Entity.php @@ -142,7 +142,7 @@ public function setSource($source): self * @param mixed $offset Property name * @param mixed $value Property value */ - public function offsetSet($offset, $value) + public function offsetSet($offset, $value): void { parent::offsetSet($offset, $value); diff --git a/src/EntitySet.php b/src/EntitySet.php index 38c80e07e..4bf7fa48a 100644 --- a/src/EntitySet.php +++ b/src/EntitySet.php @@ -10,7 +10,7 @@ use Flat3\Lodata\Exception\Internal\LexerException; use Flat3\Lodata\Exception\Internal\PathNotHandledException; use Flat3\Lodata\Exception\Protocol\BadRequestException; -use Flat3\Lodata\Exception\Protocol\InternalServerErrorException; +use Flat3\Lodata\Exception\Protocol\ConfigurationException; use Flat3\Lodata\Exception\Protocol\MethodNotAllowedException; use Flat3\Lodata\Exception\Protocol\NoContentException; use Flat3\Lodata\Exception\Protocol\NotFoundException; @@ -42,7 +42,6 @@ use Flat3\Lodata\Interfaces\EntityTypeInterface; use Flat3\Lodata\Interfaces\IdentifierInterface; use Flat3\Lodata\Interfaces\JsonInterface; -use Flat3\Lodata\Interfaces\Operation\ArgumentInterface; use Flat3\Lodata\Interfaces\PipeInterface; use Flat3\Lodata\Interfaces\ReferenceInterface; use Flat3\Lodata\Interfaces\ResourceInterface; @@ -68,7 +67,7 @@ * @link https://docs.oasis-open.org/odata/odata-csdl-xml/v4.01/odata-csdl-xml-v4.01.html#_Toc38530394 * @package Flat3\Lodata */ -abstract class EntitySet implements EntityTypeInterface, ReferenceInterface, IdentifierInterface, ResourceInterface, ServiceInterface, ContextInterface, JsonInterface, PipeInterface, ArgumentInterface, AnnotationInterface, ResponseInterface +abstract class EntitySet implements EntityTypeInterface, ReferenceInterface, IdentifierInterface, ResourceInterface, ServiceInterface, ContextInterface, JsonInterface, PipeInterface, AnnotationInterface, ResponseInterface { use HasIdentifier; use UseReferences; @@ -360,7 +359,7 @@ public function arrayToPropertyValues(array $values): PropertyValues } if (!$property) { - $property = new DynamicProperty($key, Type::castInternalType(gettype($value))); + $property = new DynamicProperty($key, Type::fromInternalValue($value)); } $propertyValue->setProperty($property); @@ -463,13 +462,16 @@ public static function pipe( ?PipeInterface $argument = null ): ?PipeInterface { $lexer = new Lexer($currentSegment); + try { - $entitySet = Lodata::getEntitySet($lexer->qualifiedIdentifier()); + $identifier = $lexer->qualifiedIdentifier(); } catch (LexerException $e) { throw new PathNotHandledException(); } - if (!$entitySet instanceof EntitySet) { + $entitySet = Lodata::getEntitySet($identifier); + + if (!$entitySet instanceof EntitySet || !$entitySet->getIdentifier()->matchesNamespace($identifier)) { throw new PathNotHandledException(); } @@ -501,7 +503,7 @@ public static function pipe( $keyProperty = $entitySet->getType()->getKey(); if (!$keyProperty) { - throw new InternalServerErrorException( + throw new ConfigurationException( 'invalid_key_property', 'The key property defined on this entity type is not valid' ); @@ -673,6 +675,15 @@ public function getSelect(): Option\Select return $this->applyQueryOptions ? $this->transaction->getSelect() : new Option\Select(); } + /** + * Return this index option that applies to this entity set + * @return Option\Index + */ + public function getIndex(): Option\Index + { + return $this->applyQueryOptions ? $this->transaction->getIndex() : new Option\Index(); + } + /** * Generate trailing metadata for this entity set * @param Transaction $transaction @@ -887,4 +898,14 @@ public function getAnnotations(): Annotations return $annotations; } + + /** + * Get the OData entity set name for this class + * @param string $class Class name + * @return string OData identifier + */ + public static function convertClassName(string $class): string + { + return Str::pluralStudly(class_basename($class)); + } } \ No newline at end of file diff --git a/src/EntityType.php b/src/EntityType.php index 75408842a..43f91f1b6 100644 --- a/src/EntityType.php +++ b/src/EntityType.php @@ -13,6 +13,7 @@ use Flat3\Lodata\Helper\Constants; use Flat3\Lodata\Helper\Identifier; use Flat3\Lodata\Interfaces\PipeInterface; +use Illuminate\Support\Str; /** * Entity Type @@ -119,4 +120,14 @@ public function toOpenAPIUpdateSchema(): array }) ]; } + + /** + * Get the OData entity type name for this class + * @param string $class Class name + * @return string OData identifier + */ + public static function convertClassName(string $class): string + { + return Str::studly(class_basename($class)); + } } diff --git a/src/EnumerationType.php b/src/EnumerationType.php index e32dbf77e..ce8f8f2bd 100644 --- a/src/EnumerationType.php +++ b/src/EnumerationType.php @@ -87,7 +87,7 @@ public function getMembers(): ObjectArray * @return bool * @codeCoverageIgnore */ - public function offsetExists($offset) + public function offsetExists($offset): bool { return $this->members->exists($offset); } @@ -107,7 +107,7 @@ public function offsetGet($offset) * @param mixed $offset Member name * @param mixed $member Member value */ - public function offsetSet($offset, $member) + public function offsetSet($offset, $member): void { if (!is_object($offset) || !$this->underlyingType->is(get_class($offset))) { $offset = $this->underlyingType->instance($offset ?: count($this->members) + 1); @@ -125,7 +125,7 @@ public function offsetSet($offset, $member) * @param mixed $offset Member name * @codeCoverageIgnore */ - public function offsetUnset($offset) + public function offsetUnset($offset): void { $this->members->drop($offset); } diff --git a/src/Exception/Protocol/ConfigurationException.php b/src/Exception/Protocol/ConfigurationException.php new file mode 100644 index 000000000..0dead03b4 --- /dev/null +++ b/src/Exception/Protocol/ConfigurationException.php @@ -0,0 +1,15 @@ +setProtocolVersion('1.1'); $response->setStatusCode($this->httpCode); $response->headers->replace($this->headers); - $response->headers->set('content-type', MediaType::json); + $response->headers->set(Constants::contentType, MediaType::json); return $response; } diff --git a/src/Facades/Lodata.php b/src/Facades/Lodata.php index 40c706d4f..873e3153b 100644 --- a/src/Facades/Lodata.php +++ b/src/Facades/Lodata.php @@ -16,8 +16,6 @@ use Flat3\Lodata\Helper\ObjectArray; use Flat3\Lodata\Helper\References; use Flat3\Lodata\Interfaces\IdentifierInterface; -use Flat3\Lodata\Interfaces\Operation\ActionInterface; -use Flat3\Lodata\Interfaces\Operation\FunctionInterface; use Flat3\Lodata\Interfaces\ResourceInterface; use Flat3\Lodata\Interfaces\ServiceInterface; use Flat3\Lodata\Model; @@ -39,8 +37,8 @@ * @method static ResourceInterface getResource(Identifier|string $name) Get a resource from the model * @method static EntitySet getEntitySet(Identifier|string $name) Get an entity set from the model * @method static Operation getOperation(Identifier|string $name) Get an operation from the model - * @method static FunctionInterface getFunction(Identifier|string $name) Get a function from the model - * @method static ActionInterface getAction(Identifier|string $name) Get an action from the model + * @method static Operation getFunction(Identifier|string $name) Get a function from the model + * @method static Operation getAction(Identifier|string $name) Get an action from the model * @method static PrimitiveType getTypeDefinition(Identifier|string $name) Get a type definition from the model * @method static EntityType getEntityType(Identifier|string $name) Get an entity type from the model * @method static ComplexType getComplexType(Identifier|string $name) Get a complex type from the model @@ -49,6 +47,7 @@ * @method static Model drop(Identifier|string $key) Drop a named resource or type from the model * @method static string getNamespace() Get the namespace of this model * @method static EloquentEntitySet discoverEloquentModel(string $class) Discover the Eloquent model provided as a class name + * @method static Model discover($discoverable) Discover sets and operations on the provided class name or object instance * @method static string getEndpoint() Get the REST endpoint of this model * @method static string getOdcUrl(Identifier|string $set) Get the Office Data Connection URL of the provided entity set * @method static string getPbidsUrl() Get the PowerBI discovery URL of this service diff --git a/src/GeneratedProperty.php b/src/GeneratedProperty.php index 5efe95d8d..eca1a38ac 100644 --- a/src/GeneratedProperty.php +++ b/src/GeneratedProperty.php @@ -34,7 +34,7 @@ public function generatePropertyValue(ComplexValue $value): PropertyValue $result = $this->invoke($value); if (!is_a($result, Primitive::class, true)) { - $result = PrimitiveType::castInternalType(gettype($result))->instance($result); + $result = Type::fromInternalValue($result)->instance($result); } if ( diff --git a/src/Helper/Constants.php b/src/Helper/Constants.php index d14b4cff1..56da76016 100644 --- a/src/Helper/Constants.php +++ b/src/Helper/Constants.php @@ -12,6 +12,9 @@ class Constants { public const cacheControl = 'cache-control'; public const charset = 'charset'; + public const contentEncoding = 'content-encoding'; + public const contentLanguage = 'content-language'; + public const contentType = 'content-type'; public const date = 'date'; public const etag = 'etag'; public const false = 'false'; @@ -39,6 +42,7 @@ class Constants public const odataStreaming = 'odata.streaming'; public const odataVersion = 'odata-version'; public const omitValues = 'omit-values'; + public const prefer = 'prefer'; public const preferenceApplied = 'preference-applied'; public const q = 'q'; public const respondAsync = 'respond-async'; @@ -46,4 +50,5 @@ class Constants public const streaming = 'streaming'; public const trailer = 'trailer'; public const true = 'true'; + public const vary = 'vary'; } \ No newline at end of file diff --git a/src/Helper/Discovery.php b/src/Helper/Discovery.php new file mode 100644 index 000000000..19c9abcb6 --- /dev/null +++ b/src/Helper/Discovery.php @@ -0,0 +1,135 @@ +discoverEloquentModel($discoverable); + } + + $this->discoverOperations($discoverable); + } + + public function discoverEloquentModel(string $model): EloquentEntitySet + { + $set = new EloquentEntitySet($model); + Lodata::add($set); + $set->discoverProperties(); + + if (!Discovery::supportsAttributes()) { + return $set; + } + + foreach (Discovery::getReflectedMethods($model) as $reflectionMethod) { + if (!$reflectionMethod->getAttributes(LodataRelationship::class, ReflectionAttribute::IS_INSTANCEOF)) { + continue; + } + + $relationshipMethod = $reflectionMethod->getName(); + + try { + $set->discoverRelationship($relationshipMethod); + } catch (ConfigurationException $e) { + } + } + + return $set; + } + + public function discoverOperations($discoverable) + { + if (!Discovery::supportsAttributes()) { + return; + } + + $namespace = null; + $reflectionClass = new ReflectionClass($discoverable); + + /** @var ReflectionAttribute $namespaceAttribute */ + $namespaceAttribute = Arr::first($reflectionClass->getAttributes(LodataNamespace::class)); + if ($namespaceAttribute) { + $namespace = $namespaceAttribute->newInstance()->getName(); + } + + foreach (Discovery::getReflectedMethods($discoverable) as $reflectionMethod) { + foreach ($reflectionMethod->getAttributes( + LodataOperation::class, + ReflectionAttribute::IS_INSTANCEOF + ) as $operationAttribute) { + /** @var LodataOperation $attributeInstance */ + $attributeInstance = $operationAttribute->newInstance(); + + $operationName = $attributeInstance->getName() ?: $reflectionMethod->getName(); + + switch (true) { + case is_a($discoverable, EloquentModel::class, true): + $operation = new EntityFunction($operationName); + break; + + case is_a($discoverable, RepositoryInterface::class, true): + $operation = new Repository($operationName); + break; + + default: + $operation = new Operation($operationName); + break; + } + + $operation->setKind($attributeInstance::operationType); + $operation->setCallable([$discoverable, $reflectionMethod->getName()]); + + if ($namespace) { + $operation->getIdentifier()->setNamespace($namespace); + } + + if ($attributeInstance->hasBindingParameterName()) { + $operation->setBindingParameterName($attributeInstance->getBindingParameterName()); + } + + if ($attributeInstance->hasReturnType()) { + $operation->setReturnType($attributeInstance->getReturnType()); + } + + Lodata::add($operation); + } + } + } + + public static function getReflectedMethods($class): array + { + $reflectionClass = new ReflectionClass($class); + + return $reflectionClass->getMethods(ReflectionMethod::IS_PUBLIC); + } + + public static function supportsAttributes(): bool + { + return PHP_VERSION_ID > 80000; + } +} \ No newline at end of file diff --git a/src/Helper/Gate.php b/src/Helper/Gate.php index 1f7c96233..68edcc8f8 100644 --- a/src/Helper/Gate.php +++ b/src/Helper/Gate.php @@ -5,14 +5,20 @@ namespace Flat3\Lodata\Helper; use Flat3\Lodata\Controller\Transaction; +use Flat3\Lodata\Exception\Protocol\ConfigurationException; use Flat3\Lodata\Exception\Protocol\ForbiddenException; -use Flat3\Lodata\Exception\Protocol\InternalServerErrorException; use Flat3\Lodata\Interfaces\ResourceInterface; use Illuminate\Support\Facades\Gate as LaravelGate; /** * Gate * @package Flat3\Lodata\Helper + * @method static Gate read(ResourceInterface $resource, Transaction $transaction) + * @method static Gate create(ResourceInterface $resource, Transaction $transaction) + * @method static Gate delete(ResourceInterface $resource, Transaction $transaction) + * @method static Gate update(ResourceInterface $resource, Transaction $transaction) + * @method static Gate query(ResourceInterface $resource, Transaction $transaction) + * @method static Gate execute(ResourceInterface $resource, Transaction $transaction) */ final class Gate { @@ -25,7 +31,6 @@ final class Gate protected $access; protected $resource; - protected $arguments; protected $transaction; public function __construct(ResourceInterface $resource, Transaction $transaction) @@ -34,34 +39,11 @@ public function __construct(ResourceInterface $resource, Transaction $transactio $this->transaction = $transaction; } - public static function read(ResourceInterface $resource, Transaction $transaction): Gate + public static function __callStatic(string $name, array $arguments) { - return (new self($resource, $transaction))->setAccess(self::read); - } - - public static function create(ResourceInterface $resource, Transaction $transaction): Gate - { - return (new self($resource, $transaction))->setAccess(self::create); - } - - public static function delete(ResourceInterface $resource, Transaction $transaction): Gate - { - return (new self($resource, $transaction))->setAccess(self::delete); - } + list ($resource, $transaction) = $arguments; - public static function update(ResourceInterface $resource, Transaction $transaction): Gate - { - return (new self($resource, $transaction))->setAccess(self::update); - } - - public static function query(ResourceInterface $resource, Transaction $transaction): Gate - { - return (new self($resource, $transaction))->setAccess(self::query); - } - - public static function execute(ResourceInterface $resource, Transaction $transaction, array $arguments): Gate - { - return (new self($resource, $transaction))->setAccess(self::execute)->setArguments($arguments); + return (new self($resource, $transaction))->setAccess(constant(self::class.'::'.$name)); } /** @@ -99,7 +81,7 @@ public function setAccess(string $access): self $access, [self::read, self::create, self::update, self::delete, self::query, self::execute] )) { - throw new InternalServerErrorException('invalid_access', 'The access type requested is not valid'); + throw new ConfigurationException('invalid_access', 'The access type requested is not valid'); } $this->access = $access; @@ -107,18 +89,6 @@ public function setAccess(string $access): self return $this; } - /** - * Set the operation arguments - * @param array $arguments - * @return $this - */ - public function setArguments(array $arguments): self - { - $this->arguments = $arguments; - - return $this; - } - /** * Get the transaction attached to this gate * @return Transaction @@ -146,15 +116,6 @@ public function getAccess(): string return $this->access; } - /** - * Get the operation arguments attached to this gate - * @return array - */ - public function getArguments(): array - { - return $this->arguments; - } - /** * Check if this gate is allowed, returning the response * @return bool diff --git a/src/Helper/Identifier.php b/src/Helper/Identifier.php index 7eb07d0b9..0328d1601 100644 --- a/src/Helper/Identifier.php +++ b/src/Helper/Identifier.php @@ -49,6 +49,18 @@ public function getName(): string return $this->name; } + /** + * Set the identifier name + * @param string $name Name + * @return $this + */ + public function setName(string $name): self + { + $this->name = $name; + + return $this; + } + /** * Get the identifier namespace * @return string @@ -59,10 +71,55 @@ public function getNamespace(): string } /** + * Set the identifier namespace + * @param string $namespace Namespace + * @return $this + */ + public function setNamespace(string $namespace): self + { + $this->namespace = $namespace; + + return $this; + } + + /** + * Get the fully qualified name for this identifier * @return string */ - public function __toString(): string + public function getQualifiedName(): string { return $this->namespace.'.'.$this->name; } + + /** + * Get the resolved name of this item based on the provided namespace + * @param string $namespace Namespace + * @return string + */ + public function getResolvedName(string $namespace): string + { + if ($this->getNamespace() === $namespace) { + return $this->getName(); + } + + return $this->getQualifiedName(); + } + + /** + * Return whether this identifier has the same namespace as the provided identifier + * @param string $identifier + * @return bool + */ + public function matchesNamespace(string $identifier): bool + { + return $this->namespace === (new Identifier($identifier))->getNamespace(); + } + + /** + * @return string + */ + public function __toString(): string + { + return $this->getQualifiedName(); + } } diff --git a/src/Helper/Name.php b/src/Helper/Name.php index 2abff38e8..46da0ebcf 100644 --- a/src/Helper/Name.php +++ b/src/Helper/Name.php @@ -4,7 +4,7 @@ namespace Flat3\Lodata\Helper; -use Flat3\Lodata\Exception\Protocol\InternalServerErrorException; +use Flat3\Lodata\Exception\Protocol\ConfigurationException; use Flat3\Lodata\Expression\Lexer; /** @@ -22,7 +22,7 @@ final class Name public function __construct(string $name) { if (!Lexer::patternCheck(Lexer::identifier, $name)) { - throw new InternalServerErrorException('invalid_name', 'The provided name was invalid: '.$name); + throw new ConfigurationException('invalid_name', 'The provided name was invalid: '.$name); } $this->name = $name; diff --git a/src/Helper/ObjectArray.php b/src/Helper/ObjectArray.php index 53426225b..fd48c31e7 100644 --- a/src/Helper/ObjectArray.php +++ b/src/Helper/ObjectArray.php @@ -6,7 +6,6 @@ use ArrayAccess; use Countable; -use Flat3\Lodata\Exception\Protocol\InternalServerErrorException; use Flat3\Lodata\Interfaces\IdentifierInterface; use Illuminate\Support\Arr; use Iterator; @@ -41,22 +40,32 @@ public static function merge(ObjectArray $map_a, ObjectArray $map_b): ObjectArra $map = new self(); foreach ($map_a as $a) { - $map->replace($a); + $map->set($a); } foreach ($map_b as $b) { - $map->replace($b); + $map->set($b); } return $map; } + /** + * Alias for set + * @param mixed $key + * @param mixed|null $value + */ + public function add($key, $value = null): void + { + $this->set($key, $value); + } + /** * Replace a value in the array * @param mixed $key - * @param null $value + * @param mixed|null $value */ - public function replace($key, $value = null): void + public function set($key, $value = null): void { if (!$key) { $key = $value; @@ -79,28 +88,11 @@ public function replace($key, $value = null): void $this->array[(string) $key] = $value; } - /** - * Add a value to the array - * @param mixed $key - * @param null $value - */ - public function add($key, $value = null): void - { - if ($this->exists($key)) { - throw new InternalServerErrorException( - 'cannot_add_existing_key', - 'Attempted to add an item that already exists' - ); - } - - $this->replace($key, $value); - } - /** * Count values in the array * @return int */ - public function count() + public function count(): int { return count($this->array); } @@ -128,9 +120,9 @@ public function current() * Move to the next value in the array * @return mixed|void */ - public function next() + public function next(): void { - return next($this->array); + next($this->array); } /** @@ -146,7 +138,7 @@ public function key() * Check if the current value in the array is valid * @return bool */ - public function valid() + public function valid(): bool { $key = key($this->array); @@ -156,7 +148,7 @@ public function valid() /** * Rewind the array */ - public function rewind() + public function rewind(): void { reset($this->array); } @@ -166,7 +158,7 @@ public function rewind() * @param mixed $offset * @return bool */ - public function offsetExists($offset) + public function offsetExists($offset): bool { return !!$this->get($offset); } @@ -213,16 +205,16 @@ public function offsetGet($offset) * @param mixed $offset * @param mixed $value */ - public function offsetSet($offset, $value) + public function offsetSet($offset, $value): void { - $this->replace($offset, $value); + $this->set($offset, $value); } /** * Unset an object in the array * @param mixed $offset */ - public function offsetUnset($offset) + public function offsetUnset($offset): void { $this->drop($offset); } diff --git a/src/Interfaces/IdentifierInterface.php b/src/Interfaces/IdentifierInterface.php index e225de1d5..b352a7885 100644 --- a/src/Interfaces/IdentifierInterface.php +++ b/src/Interfaces/IdentifierInterface.php @@ -4,6 +4,8 @@ namespace Flat3\Lodata\Interfaces; +use Flat3\Lodata\Helper\Identifier; + /** * Identifier Interface * @package Flat3\Lodata\Interfaces @@ -12,20 +14,7 @@ interface IdentifierInterface extends NameInterface { /** * Get the fully qualified name of this nominal item - * @return string Qualified name - */ - public function getIdentifier(): string; - - /** - * Get the namespace of this nominal item - * @return string Namespace - */ - public function getNamespace(): string; - - /** - * Get the name of this item, qualified if required based on the provided namespace - * @param string $namespace Namespace - * @return string Name + * @return Identifier Qualified name */ - public function getResolvedName(string $namespace): string; + public function getIdentifier(): Identifier; } \ No newline at end of file diff --git a/src/Interfaces/Operation/ActionInterface.php b/src/Interfaces/Operation/ActionInterface.php deleted file mode 100644 index c51866ae2..000000000 --- a/src/Interfaces/Operation/ActionInterface.php +++ /dev/null @@ -1,13 +0,0 @@ -getResource($name); - return $resource instanceof FunctionInterface ? $resource : null; + return $resource && $resource->isFunction() ? $resource : null; } /** * Get an action from the model * @param string $name Action name - * @return ActionInterface|null Action + * @return Operation|null Action */ - public function getAction(string $name): ?ActionInterface + public function getAction(string $name): ?Operation { + /** @var Operation $resource */ $resource = $this->getResource($name); - return $resource instanceof ActionInterface ? $resource : null; + return $resource && $resource->isAction() ? $resource : null; } /** @@ -278,12 +279,24 @@ public function addTypeDefinition(PrimitiveType $typeDefinition): self /** * Discover the Eloquent model provided as a class name - * @param string $class Eloquent model class name + * @param string $model Eloquent model class name * @return EloquentEntitySet Eloquent entity set */ - public function discoverEloquentModel(string $class): EloquentEntitySet + public function discoverEloquentModel(string $model): EloquentEntitySet { - return EloquentEntitySet::discover($class); + return (new Discovery)->discoverEloquentModel($model); + } + + /** + * Perform discovery on the provided class name or instance + * @param string|object $discoverable + * @return $this + */ + public function discover($discoverable): self + { + (new Discovery)->discover($discoverable); + + return $this; } /** diff --git a/src/NavigationProperty.php b/src/NavigationProperty.php index 5dcd43ffe..d1f0091a5 100644 --- a/src/NavigationProperty.php +++ b/src/NavigationProperty.php @@ -5,7 +5,7 @@ namespace Flat3\Lodata; use Flat3\Lodata\Controller\Transaction; -use Flat3\Lodata\Exception\Protocol\InternalServerErrorException; +use Flat3\Lodata\Exception\Protocol\ConfigurationException; use Flat3\Lodata\Helper\ObjectArray; use Flat3\Lodata\Helper\PropertyValue; use Flat3\Lodata\Interfaces\IdentifierInterface; @@ -47,7 +47,7 @@ class NavigationProperty extends Property public function __construct($name, EntityType $entityType) { if (!$entityType->hasKey()) { - throw new InternalServerErrorException( + throw new ConfigurationException( 'missing_entity_type_key', 'The specified entity type must have a key defined' ); diff --git a/src/Operation.php b/src/Operation.php index 64f964f59..8d610afd6 100644 --- a/src/Operation.php +++ b/src/Operation.php @@ -8,6 +8,7 @@ use Flat3\Lodata\Exception\Internal\LexerException; use Flat3\Lodata\Exception\Internal\PathNotHandledException; use Flat3\Lodata\Exception\Protocol\BadRequestException; +use Flat3\Lodata\Exception\Protocol\ConfigurationException; use Flat3\Lodata\Exception\Protocol\InternalServerErrorException; use Flat3\Lodata\Exception\Protocol\NoContentException; use Flat3\Lodata\Expression\Lexer; @@ -18,8 +19,6 @@ use Flat3\Lodata\Helper\PropertyValue; use Flat3\Lodata\Interfaces\AnnotationInterface; use Flat3\Lodata\Interfaces\IdentifierInterface; -use Flat3\Lodata\Interfaces\Operation\ActionInterface; -use Flat3\Lodata\Interfaces\Operation\FunctionInterface; use Flat3\Lodata\Interfaces\PipeInterface; use Flat3\Lodata\Interfaces\ResourceInterface; use Flat3\Lodata\Interfaces\ServiceInterface; @@ -28,14 +27,16 @@ use Flat3\Lodata\Operation\EntitySetArgument; use Flat3\Lodata\Operation\PrimitiveArgument; use Flat3\Lodata\Operation\TransactionArgument; -use Flat3\Lodata\Operation\TypeArgument; +use Flat3\Lodata\Operation\ValueArgument; use Flat3\Lodata\Traits\HasAnnotations; use Flat3\Lodata\Traits\HasIdentifier; use Flat3\Lodata\Traits\HasTitle; use Flat3\Lodata\Traits\HasTransaction; use Illuminate\Http\Request; -use Illuminate\Support\Arr; -use ReflectionException; +use Illuminate\Support\Collection; +use Illuminate\Support\Facades\App; +use ReflectionFunction; +use ReflectionFunctionAbstract; use ReflectionMethod; use ReflectionNamedType; use TypeError; @@ -45,13 +46,16 @@ * @link https://docs.oasis-open.org/odata/odata-csdl-xml/v4.01/odata-csdl-xml-v4.01.html#_Toc38530382 * @package Flat3\Lodata */ -abstract class Operation implements ServiceInterface, ResourceInterface, IdentifierInterface, PipeInterface, AnnotationInterface +class Operation implements ServiceInterface, ResourceInterface, IdentifierInterface, PipeInterface, AnnotationInterface { use HasIdentifier; use HasTitle; use HasTransaction; use HasAnnotations; + /** @var callable $callable */ + protected $callable; + /** * The name of the binding parameter used in the invocation function * @var string $bindingParameterName @@ -59,89 +63,151 @@ abstract class Operation implements ServiceInterface, ResourceInterface, Identif protected $bindingParameterName; /** - * The instance of the bound parameter provided to the instance of the operation - * @var ?PipeInterface $boundParameter + * The OData return type from this operation + * @var Type $returnType */ - protected $boundParameter; + protected $returnType; /** - * The URL inline parameters being provided to this operation - * @var array $inlineParameters + * The OData kind of this operation + * @var string Kind */ - protected $inlineParameters = []; + protected $kind = self::function; /** - * The OData return type from this operation - * @var Type $returnType + * OData operation types */ - protected $returnType; + const function = 'Function'; + const action = 'Action'; + + /** + * The instance of the bound parameter provided to this operation instance + * @var ?PipeInterface $boundParameter + */ + private $boundParameter; + + /** + * The parameters provided by the client for this operation instance + * @var string $clientParameters + */ + private $clientParameters = null; public function __construct($identifier) { - if (!$this instanceof FunctionInterface && !$this instanceof ActionInterface) { - throw new InternalServerErrorException( - sprintf('An operation must implement either %s or %s', FunctionInterface::class, ActionInterface::class) + $this->setIdentifier($identifier); + } + + /** + * Get the OData kind of this operation + * @return string Kind + */ + public function getKind(): string + { + return $this->kind; + } + + /** + * Set the OData kind of this operation + * @param string $kind Kind + * @return $this + */ + public function setKind(string $kind): self + { + if (!in_array($kind, [self::function, self::action])) { + throw new ConfigurationException( + 'invalid_operation_type', + 'An operation must be type Function or Action' ); } - try { - new ReflectionMethod($this, 'invoke'); - } catch (ReflectionException $e) { - throw new InternalServerErrorException('An operation must implement the invoke method'); - } + $this->kind = $kind; - $this->setIdentifier($identifier); + return $this; } /** - * Get the OData return type of this operation - * @return Type|null Return type + * Return whether this operation is a function + * @return bool */ - public function getReturnType(): ?Type + public function isFunction(): bool { - if ($this->returnType) { - return $this->returnType; - } + return $this->kind == self::function; + } + + /** + * Return whether this operation as an action + * @return bool + */ + public function isAction(): bool + { + return $this->kind === self::action; + } - $rrt = $this->getReflectedReturnType(); + /** + * Return the attached callable + * @return callable + */ + public function getCallable() + { + $callable = $this->callable; - if (is_a($rrt, Primitive::class, true)) { - return new PrimitiveType($this->getReflectedReturnType()); + if (is_callable($callable)) { + return $callable; } - try { - return Type::castInternalType($rrt); - } catch (TypeError $e) { + if (is_array($callable)) { + list($instance, $method) = $callable; + + if (is_string($instance) && class_exists($instance)) { + $instance = App::make($instance); + } + + return [$instance, $method]; } - return null; + return $callable; } /** - * Get the OData return type of this operation, based on reflection of the invocation method - * @return string Return type + * Set the operation callable + * @param callable|array $callable + * @return $this */ - public function getReflectedReturnType(): string + public function setCallable($callable): self { - try { - $rfc = new ReflectionMethod($this, 'invoke'); + $this->callable = $callable; - /** @var ReflectionNamedType $rt */ - $rt = $rfc->getReturnType(); + return $this; + } - if ('void' === $rt && $this instanceof FunctionInterface) { - throw new InternalServerErrorException('missing_return_type', 'Functions must have a return type'); - } + /** + * Get the method parameter name of the binding parameter used on the invocation method + * @return string|null Binding parameter name + */ + public function getBindingParameterName(): ?string + { + return $this->bindingParameterName; + } - if (null === $rt) { - return 'void'; - } + /** + * Set the name of the invocation method parameter used to receive the binding parameter + * @param string $bindingParameterName Binding parameter name + * @return $this + */ + public function setBindingParameterName(string $bindingParameterName): self + { + $this->bindingParameterName = $bindingParameterName; - return $rt->getName(); - } catch (ReflectionException $e) { - } + return $this; + } - throw new InternalServerErrorException('invalid_return_type', 'Invalid return type'); + /** + * Return whether this operation expects a bound parameter + * @return bool + */ + public function isBound(): bool + { + return $this->bindingParameterName !== null; } /** @@ -150,15 +216,9 @@ public function getReflectedReturnType(): string */ public function returnsCollection(): bool { - $returnType = $this->getReflectedReturnType(); - - switch (true) { - case $returnType === 'array': - case is_a($returnType, EntitySet::class, true); - return true; - } + $returnType = $this->getCallableReturnType(); - return false; + return $returnType === 'array' || is_a($returnType, EntitySet::class, true); } /** @@ -167,70 +227,57 @@ public function returnsCollection(): bool */ public function isNullable(): bool { - try { - $rfn = new ReflectionMethod($this, 'invoke'); - return !$rfn->hasReturnType() || $rfn->getReturnType()->allowsNull() || $rfn->getReturnType()->getName() === 'void'; - } catch (ReflectionException $e) { - return false; - } + $rfn = $this->getCallableMethod(); + + return !$rfn->hasReturnType() || $rfn->getReturnType()->allowsNull() || $rfn->getReturnType()->getName() === 'void'; } /** - * Get the reflected arguments of the invocation of this operation - * @return Argument[]|Arguments Arguments + * Get the OData return type of this operation + * @return Type|null Return type */ - public function getArguments(): Arguments + public function getReturnType(): ?Type { - try { - $rfn = new ReflectionMethod($this, 'invoke'); - $args = new Arguments(); + if ($this->returnType) { + return $this->returnType; + } - foreach ($rfn->getParameters() as $parameter) { - $args[] = Argument::factory($parameter); - } + $returnType = $this->getCallableReturnType(); - return $args; - } catch (ReflectionException $e) { + if (is_a($returnType, Primitive::class, true)) { + return new PrimitiveType($returnType); } - throw new InternalServerErrorException('invalid_arguments', 'Invalid arguments'); + return Type::fromInternalType($returnType); } /** - * Set the name of the invocation method parameter used to receive the binding parameter - * @param string $bindingParameterName Binding parameter name + * Set the OData type that will be returned by this operation + * @param Type $type Return type * @return $this */ - public function setBindingParameterName(string $bindingParameterName): self + public function setReturnType(Type $type): self { - $arguments = $this->getArguments(); - - if (!$arguments->get($bindingParameterName)) { - throw new InternalServerErrorException( - 'cannot_find_binding_parameter', - 'The requested binding parameter did not exist on the invoke method' - ); - } + $this->returnType = $type; - $this->bindingParameterName = $bindingParameterName; return $this; } /** - * Get the method parameter name of the binding parameter used on the invocation method - * @return string|null Binding parameter name + * Retrieve the bound parameter attached to this operation + * @return PipeInterface|null */ - public function getBindingParameterName(): ?string + public function getBoundParameter(): ?PipeInterface { - return $this->bindingParameterName; + return $this->boundParameter; } /** * Set the bound parameter on an instance of this operation - * @param PipeInterface|null $parameter Binding parameter + * @param mixed $parameter Binding parameter * @return $this */ - public function setBoundParameter(?PipeInterface $parameter): self + public function setBoundParameter($parameter): self { $this->assertTransaction(); @@ -239,298 +286,447 @@ public function setBoundParameter(?PipeInterface $parameter): self } $this->boundParameter = $parameter; + + return $this; + } + + public function setClientParameters(?string $parameters): self + { + $this->assertTransaction(); + + $this->clientParameters = $parameters; + return $this; } /** - * Set the URL inline parameters on an instance of this operation - * @param array $inlineParameters Inline parameters - * @return $this + * Get the resource URL of this operation instance + * @param Transaction $transaction Related transaction + * @return string Resource URL */ - public function setInlineParameters(array $inlineParameters): self + public function getResourceUrl(Transaction $transaction): string { - $this->inlineParameters = $inlineParameters; - return $this; + return $transaction->getResourceUrl().$this->getName(); } /** - * Get the OData kind of this operation - * @return string Kind + * Get the reflected function or method attached to this operation + * @return ReflectionFunction|ReflectionMethod */ - public function getKind(): string + public function getCallableMethod(): ReflectionFunctionAbstract { - switch (true) { - case $this instanceof ActionInterface: - return 'Action'; + $callable = $this->getCallable(); + + if (!$callable) { + throw new ConfigurationException( + 'missing_callable', + 'The operation has no callable', + ); + } - case $this instanceof FunctionInterface: - return 'Function'; + if (is_array($callable)) { + list($instance, $method) = $callable; + return new ReflectionMethod($instance, $method); } - throw new InternalServerErrorException('invalid_operation', 'Operations must implement as Function or Action'); + return new ReflectionFunction($callable); } /** - * Get the arguments being provided by the transaction attached to this operation instance - * @return array Arguments + * Get the return type of this operation, based on reflection of the invocation method + * @return string Return type */ - public function getTransactionArguments(): array + public function getCallableReturnType(): string { - switch (true) { - case $this instanceof ActionInterface: - $body = $this->transaction->getBody(); - - if ($body && !is_array($body)) { - throw new BadRequestException( - 'invalid_action_arguments', - 'The arguments to the action were not correctly formed as an array' - ); - } + $callableMethod = $this->getCallableMethod(); - return $body ?: []; + /** @var ReflectionNamedType $returnType */ + $returnType = $callableMethod->getReturnType(); - case $this instanceof FunctionInterface: - return $this->inlineParameters; + if (null === $returnType) { + return 'void'; } - throw new InternalServerErrorException('invalid_operation', 'Operations must implement as Function or Action'); + return $returnType->getName(); } - public static function pipe( - Transaction $transaction, - string $currentSegment, - ?string $nextSegment, - ?PipeInterface $argument - ): ?PipeInterface { - $lexer = new Lexer($currentSegment); + /** + * Extract operation arguments for metadata + * Ensure the binding parameter is first, if it exists. Filter out non-odata arguments. + * @return Arguments|Argument[] + */ + public function getMetadataArguments() + { + return $this->getCallableArguments()->sort(function (Argument $a, Argument $b) { + if ($a->getName() === $this->getBindingParameterName()) { + return -1; + } - try { - $operationIdentifier = $lexer->identifier(); - } catch (LexerException $e) { - throw new PathNotHandledException(); + if ($b->getName() === $this->getBindingParameterName()) { + return 1; + } + + return 0; + })->filter(function ($argument) { + if ($argument instanceof PrimitiveArgument || $argument instanceof ValueArgument) { + return true; + } + + if (($argument instanceof EntitySetArgument || $argument instanceof EntityArgument) && $this->getBindingParameterName() === $argument->getName()) { + return true; + } + + return false; + }); + } + + /** + * Get the reflected arguments of the invocation of this operation + * @return Argument[]|Arguments Arguments + */ + public function getCallableArguments(): Arguments + { + $reflectionMethod = $this->getCallableMethod(); + $arguments = new Arguments(); + + foreach ($reflectionMethod->getParameters() as $parameter) { + $type = $parameter->getType()->getName(); + + switch (true) { + case is_a($type, EntitySet::class, true): + $arguments[] = new EntitySetArgument($this, $parameter); + break; + + case is_a($type, Transaction::class, true): + $arguments[] = new TransactionArgument($this, $parameter); + break; + + case is_a($type, Entity::class, true): + $arguments[] = new EntityArgument($this, $parameter); + break; + + case is_a($type, Primitive::class, true): + $arguments[] = new PrimitiveArgument($this, $parameter); + break; + + default: + $arguments[] = new ValueArgument($this, $parameter); + break; + } } - $operation = Lodata::getOperation($operationIdentifier); + return $arguments; + } - if (!$operation instanceof Operation) { - throw new PathNotHandledException(); + /** + * Parse and return arguments from the client that can be passed to the callable + * @return array Arguments + */ + public function resolveParameters(): array + { + if ($this->isFunction()) { + $clientParameters = $this->parseFunctionParameters(); } - if ($nextSegment && $operation instanceof ActionInterface) { - throw new BadRequestException( - 'cannot_compose_action', - 'It is not permitted to further compose the result of an action' - ); + if ($this->isAction()) { + $clientParameters = $this->parseActionParameters(); } - if (!$argument && $operation->getBindingParameterName()) { - throw new BadRequestException( - 'missing_bound_argument', - 'This operation is bound, but no bound argument was provided' + if ($this->isBound()) { + $clientParameters[$this->getBindingParameterName()] = $this->boundParameter; + } + + $callableParameters = []; + + foreach ($this->getCallableArguments() as $argument) { + $argumentName = $argument->getName(); + $clientParameter = $clientParameters[$argumentName] ?? null; + $callableParameters[$argumentName] = $this->resolveParameter($argument, $clientParameter); + } + + if ($this->isBound() && ($callableParameters[$this->getBindingParameterName()] ?? null) === null) { + throw new ConfigurationException( + 'missing_callable_binding_parameter', + 'The provided callable did not have a argument named '.$this->getBindingParameterName() ); } - $operation = clone $operation; - $operation->setTransaction($transaction); - $operation->setBoundParameter($argument); + return array_values($callableParameters); + } - $inlineParameters = []; + /** + * Resolve a single parameter into the correct type for the callable + * @param Argument $argument Internal argument + * @param mixed $parameter Client-provided parameter + * @return mixed Callable parameter + */ + public function resolveParameter(Argument $argument, $parameter) + { + if ($alias = $this->transaction->getImplicitParameterAlias($argument->getName())) { + $parameter = $argument->getType()->instance($alias); + } try { - $inlineParameters = array_filter(explode(',', $lexer->matchingParenthesis())); + $result = $argument->resolveParameter($parameter); + } catch (TypeError $e) { + throw new BadRequestException( + 'invalid_argument_type', + sprintf( + 'The provided argument (%s) was not of the correct type for this function', + $argument->getName() + ) + ); + } - $inlineParameters = Arr::collapse(array_map(function ($pair) use ($transaction) { - $pair = trim($pair); + if (null === $result && !$argument->isNullable()) { + throw new BadRequestException( + 'non_null_argument_missing', + sprintf('A non-null argument (%s) is missing', $argument->getName()) + ); + } - $kv = array_map('trim', explode('=', $pair)); + return $result; + } - if (count($kv) !== 2) { - throw new BadRequestException( - 'invalid_arguments', - 'The arguments provided to the operation were not valid' - ); - } + /** + * Parse the arguments provided to this function + * @return Collection + */ + protected function parseFunctionParameters(): Collection + { + $arguments = collect(); - list($key, $value) = $kv; + if (!$this->clientParameters) { + return $arguments; + } - if (strpos($value, '@') === 0) { - $value = $transaction->getParameterAlias($value); - } + $lexer = new Lexer($this->clientParameters); + $callableArguments = $this->getCallableArguments(); - return [$key => $value]; - }, $inlineParameters)); - } catch (LexerException $e) { - if (!$nextSegment) { - /** @var Argument $argument */ - foreach ($operation->getArguments() as $argument) { - $value = $transaction->getImplicitParameterAlias($argument->getName()); + while (!$lexer->finished()) { + $key = $lexer->identifier(); + $lexer->char('='); - if (!$value) { - continue; - } + $argument = $callableArguments[$key]; - $inlineParameters[$argument->getName()] = $value; - } + if (!$argument) { + throw new BadRequestException( + 'invalid_argument', + 'The parameters provided an argument that was not known' + ); } - } - - $operation->setInlineParameters($inlineParameters); - if ($operation instanceof ActionInterface) { - $transaction->assertMethod(Request::METHOD_POST, - 'This operation must be addressed with a POST request'); + /** @var PrimitiveType $type */ + $type = $argument->getType(); + + if ($lexer->maybeChar('@')) { + $parameterAlias = $lexer->identifier(); + $arguments[$key] = $type->instance($this->transaction->getParameterAlias($parameterAlias)); + } else { + /** @var Primitive $factory */ + $factory = $type->getFactory(); + + try { + $result = $factory::fromLexer($lexer); + } catch (LexerException $e) { + throw new BadRequestException('invalid_argument_type', sprintf( + 'The provided argument %s was not of type %s', + $key, + $type->getIdentifier() + )); + } - if ($transaction->getBody()) { - $transaction->assertContentTypeJson(); + $arguments[$key] = $result; } - } - - if ($operation instanceof FunctionInterface) { - $transaction->assertMethod(Request::METHOD_GET, - 'This operation must be addressed with a GET request'); - $operation->getReflectedReturnType(); + $lexer->maybeChar(','); } - $bindingParameter = $operation->getBindingParameterName(); - $transactionArguments = $operation->getTransactionArguments(); + return $arguments; + } - $arguments = []; + /** + * Parse the arguments provided to this action + * @return Collection + */ + protected function parseActionParameters(): Collection + { + $callableArguments = $this->getCallableArguments(); + $arguments = collect(); - /** @var Argument $argumentDefinition */ - foreach ($operation->getArguments() as $argumentDefinition) { - $argumentName = $argumentDefinition->getName(); - if ($bindingParameter === $argumentName) { - switch (true) { - case $argumentDefinition instanceof EntityArgument && !$operation->boundParameter instanceof Entity: - case $argumentDefinition instanceof EntitySetArgument && !$operation->boundParameter instanceof EntitySet: - case $argumentDefinition instanceof PrimitiveArgument && !$operation->boundParameter instanceof Primitive && !$operation->boundParameter instanceof PropertyValue: - throw new BadRequestException( - 'invalid_bound_argument_type', - 'The provided bound argument was not of the correct type for this function' - ); - } + $body = $this->transaction->getBody(); - $arguments[] = $operation->boundParameter; - continue; - } + if (!$body) { + return $arguments; + } - switch (true) { - case $argumentDefinition instanceof TransactionArgument: - case $argumentDefinition instanceof EntitySetArgument: - $arguments[] = $argumentDefinition->generate($transaction); - break; + $this->transaction->assertContentTypeJson(); - case $argumentDefinition instanceof EntityArgument: - $arguments[] = $argumentDefinition->generate(); - break; + if (!is_array($body)) { + throw new BadRequestException( + 'invalid_action_arguments', + 'The arguments to the action were not correctly formed as an array' + ); + } - case $argumentDefinition instanceof TypeArgument: - $arguments[] = $argumentDefinition->generate($transactionArguments[$argumentName] ?? null)->get(); - break; + foreach ($body as $key => $value) { + $argument = $callableArguments[$key]; - case $argumentDefinition instanceof PrimitiveArgument: - $arguments[] = $argumentDefinition->generate($transactionArguments[$argumentName] ?? null); - break; + if (!$argument) { + throw new BadRequestException( + 'invalid_argument', + 'The action body provided an argument that was not known' + ); } + + $arguments[$key] = $argument->getType()->instance($value); } - Gate::execute($operation, $transaction, $arguments)->ensure(); + return $arguments; + } - $result = call_user_func_array([$operation, 'invoke'], array_values($arguments)); + public static function pipe( + Transaction $transaction, + string $currentSegment, + ?string $nextSegment, + ?PipeInterface $argument + ): ?PipeInterface { + $lexer = new Lexer($currentSegment); + + try { + $identifier = $lexer->qualifiedIdentifier(); + } catch (LexerException $e) { + throw new PathNotHandledException(); + } - if ($operation instanceof ActionInterface) { - $returnPreference = $transaction->getPreferenceValue(Constants::return); + $operation = Lodata::getOperation($identifier); - if ($returnPreference === Constants::minimal) { - throw (new NoContentException) - ->header(Constants::preferenceApplied, Constants::return.'='.Constants::minimal); - } + if (!$operation instanceof Operation || !$operation->getIdentifier()->matchesNamespace($identifier)) { + throw new PathNotHandledException(); } - if ($operation instanceof FunctionInterface && null === $result) { - throw new InternalServerErrorException( - 'missing_function_result', - 'Function is required to return a result' + if ($nextSegment && $operation->isAction()) { + throw new BadRequestException( + 'cannot_compose_action', + 'It is not permitted to further compose the result of an action' ); } - $returnType = $operation->getReturnType(); - $transaction->getRequest()->setMethod(Request::METHOD_GET); - - switch (true) { - case $result === null && $operation->isNullable(): - case $returnType instanceof EntityType && $result->getType() instanceof $returnType: - case $returnType instanceof PrimitiveType && $result instanceof Primitive: - return $result; + if (!$argument && $operation->isBound()) { + throw new BadRequestException( + 'missing_bound_argument', + 'This operation is bound, but no argument was provided' + ); + } - case $returnType instanceof PrimitiveType: - return $returnType->instance($result); + $operation = clone $operation; + $operation->setTransaction($transaction); + $operation->setBoundParameter($argument); + if (!$lexer->finished()) { + try { + $operation->setClientParameters($lexer->matchingParenthesis()); + } catch (LexerException $e) { + throw new BadRequestException('malformed_parameters', 'The provided parameters were not well formed'); + } } - throw new InternalServerErrorException( - 'invalid_return_type', - 'The operation returned an type that did not match its defined return type' - ); + return $operation->isFunction() ? $operation->executeFunction() : $operation->executeAction(); } /** - * Get the resource URL of this operation instance - * @param Transaction $transaction Related transaction - * @return string Resource URL + * Execute this operation as a function + * @return PipeInterface|null */ - public function getResourceUrl(Transaction $transaction): string + public function executeFunction(): ?PipeInterface { - return $transaction->getResourceUrl().$this->getName(); + $this->transaction->assertMethod( + Request::METHOD_GET, + 'This operation must be addressed with a GET request' + ); + + Gate::execute($this, $this->transaction)->ensure(); + + $result = $this->invoke($this->getCallable(), $this->resolveParameters()); + + if ($result === null) { + throw new InternalServerErrorException( + 'missing_function_result', + 'Function is required to return a result' + ); + } + + $this->transaction->getRequest()->setMethod(Request::METHOD_GET); + + return $this->ensureResult($result); } /** - * Set the OData type that will be returned by this operation - * @param Type $type Return type - * @return $this + * Execute this operation as an action + * @return PipeInterface|null */ - public function setReturnType(Type $type): self + public function executeAction(): ?PipeInterface { - $this->returnType = $type; - return $this; + $this->transaction->assertMethod( + Request::METHOD_POST, + 'This operation must be addressed with a POST request' + ); + + if ($this->transaction->getBody()) { + $this->transaction->assertContentTypeJson(); + } + + Gate::execute($this, $this->transaction)->ensure(); + + $result = $this->invoke($this->getCallable(), $this->resolveParameters()); + + $returnPreference = $this->transaction->getPreferenceValue(Constants::return); + + if ($returnPreference === Constants::minimal) { + throw (new NoContentException) + ->header(Constants::preferenceApplied, Constants::return.'='.Constants::minimal); + } + + $this->transaction->getRequest()->setMethod(Request::METHOD_GET); + + return $this->ensureResult($result); } /** - * Retrieve the bound parameter attached to this operation - * @return PipeInterface|null + * Invoke the provided callable + * @return mixed */ - public function getBoundParameter(): ?PipeInterface + public function invoke(callable $callable, array $arguments) { - return $this->boundParameter; + return call_user_func_array($callable, $arguments); } /** - * Extract operation arguments for metadata - * Ensure the binding parameter is first, if it exists. Filter out non-odata arguments. - * @return Arguments|Argument[] + * Ensure the returned operation result is properly formed + * @param $result + * @return PipeInterface|null */ - public function getExternalArguments() + public function ensureResult($result): ?PipeInterface { - return $this->getArguments()->sort(function (Argument $a, Argument $b) { - if ($a->getName() === $this->getBindingParameterName()) { - return -1; - } + $returnType = $this->getReturnType(); - if ($b->getName() === $this->getBindingParameterName()) { - return 1; - } + if ($result === null && !$this->isNullable()) { + throw new InternalServerErrorException( + 'invalid_null_returned', + 'The operation returned null but the result is not nullable' + ); + } - return 0; - })->filter(function ($argument) { - if ($argument instanceof PrimitiveArgument) { - return true; - } + if ($returnType instanceof EntityType && !$result->getType() instanceof $returnType) { + throw new InternalServerErrorException( + 'invalid_entity_type_returned', + 'The operation returned an entity type that did not match its defined type', + ); + } - if (($argument instanceof EntitySetArgument || $argument instanceof EntityArgument) && $this->getBindingParameterName() === $argument->getName()) { - return true; - } + if ($returnType instanceof PrimitiveType && !$result instanceof Primitive) { + return $returnType->instance($result); + } - return false; - }); + return $result; } } diff --git a/src/Operation/Action.php b/src/Operation/Action.php new file mode 100644 index 000000000..385edb4eb --- /dev/null +++ b/src/Operation/Action.php @@ -0,0 +1,12 @@ +operation = $operation; $this->parameter = $parameter; + $this->setName($parameter->getName()); } /** - * Whether this argument can be null - * @return bool + * Get the type of the argument + * @return Type */ - public function isNullable(): bool + public function getType(): Type { - return false; + return $this->type; } /** - * Generate an instance of the correct type to provide to this argument - * @param ReflectionParameter $parameter Parameter - * @return static + * Set the type of the argument + * @param Type $type + * @return $this */ - public static function factory(ReflectionParameter $parameter): self + public function setType(Type $type): self { - /** @var ReflectionNamedType $namedType */ - $namedType = $parameter->getType(); - $typeName = $namedType->getName(); + $this->type = $type; - switch (true) { - case is_a($typeName, EntitySet::class, true): - return new EntitySetArgument($parameter); - - case is_a($typeName, Transaction::class, true): - return new TransactionArgument($parameter); - - case is_a($typeName, Entity::class, true): - return new EntityArgument($parameter); + return $this; + } - case is_a($typeName, Primitive::class, true): - return new PrimitiveArgument($parameter); + /** + * Whether this argument can be null + * @return bool + */ + public function isNullable(): bool + { + return $this->parameter && $this->parameter->allowsNull(); + } - default: - return new TypeArgument($parameter); - } + /** + * Get this argument's attached operation + * @return Operation + */ + public function getOperation(): Operation + { + return $this->operation; } /** - * Generate an instance of this argument with the value of the provided source - * @param null $source - * @return ArgumentInterface + * Get the parameter this argument was derived from + * @return ReflectionParameter */ - abstract public function generate($source = null): ArgumentInterface; + public function getParameter(): ReflectionParameter + { + return $this->parameter; + } } diff --git a/src/Operation/EntityArgument.php b/src/Operation/EntityArgument.php index 72de9fe20..9663b7a81 100644 --- a/src/Operation/EntityArgument.php +++ b/src/Operation/EntityArgument.php @@ -4,11 +4,10 @@ namespace Flat3\Lodata\Operation; +use Flat3\Lodata\ComplexType; use Flat3\Lodata\Entity; -use Flat3\Lodata\EntityType; -use Flat3\Lodata\Exception\Protocol\InternalServerErrorException; use Flat3\Lodata\Facades\Lodata; -use Flat3\Lodata\Interfaces\Operation\ArgumentInterface; +use Flat3\Lodata\Type; /** * Entity Argument @@ -17,32 +16,29 @@ class EntityArgument extends Argument { /** - * Generate an Entity argument - * @param null $source - * @return ArgumentInterface + * Get the entity type + * + * @return ComplexType */ - public function generate($source = null): ArgumentInterface + public function getType(): Type { - $entityType = Lodata::getEntityType($this->getName()); - - if (!$entityType) { - throw new InternalServerErrorException('invalid_entity_type', 'Entity of this type could not be generated'); + if ($this->type) { + return $this->type; } - $entity = new Entity(); - $entity->setType($entityType); - - return $entity; + $parameterName = $this->parameter->getName(); + return Lodata::getEntityType($parameterName); } - /** - * Get the entity type - * - * @return EntityType - */ - public function getType(): EntityType + public function resolveParameter(?Entity $parameter): Entity { - $reflectedType = $this->parameter->getName(); - return Lodata::getEntityType($reflectedType); + if ($parameter) { + return $parameter; + } + + $parameter = new Entity(); + $parameter->setType($this->getType()); + + return $parameter; } } diff --git a/src/Operation/EntityFunction.php b/src/Operation/EntityFunction.php new file mode 100644 index 000000000..5b93c19a1 --- /dev/null +++ b/src/Operation/EntityFunction.php @@ -0,0 +1,26 @@ +getBoundParameter(); + + /** @var object $instance */ + $instance = $entity->getSource(); + + list (, $method) = $callable; + + return call_user_func_array([$instance, $method], $arguments); + } +} \ No newline at end of file diff --git a/src/Operation/EntitySetArgument.php b/src/Operation/EntitySetArgument.php index 31c4292a3..d828f88df 100644 --- a/src/Operation/EntitySetArgument.php +++ b/src/Operation/EntitySetArgument.php @@ -4,12 +4,10 @@ namespace Flat3\Lodata\Operation; -use Flat3\Lodata\Controller\Transaction; use Flat3\Lodata\EntitySet; use Flat3\Lodata\EntityType; -use Flat3\Lodata\Exception\Protocol\InternalServerErrorException; use Flat3\Lodata\Facades\Lodata; -use Flat3\Lodata\Interfaces\Operation\ArgumentInterface; +use Flat3\Lodata\Type; /** * Entity Set Argument @@ -18,40 +16,29 @@ class EntitySetArgument extends Argument { /** - * Generate an entity set argument - * @param null $source - * @return ArgumentInterface + * Get the entity set type + * @return EntityType */ - public function generate($source = null): ArgumentInterface + public function getType(): Type { - if (!$source instanceof Transaction) { - throw new InternalServerErrorException( - 'invalid_transaction', - 'The source of an entity set is expected to be a transaction' - ); + if ($this->type) { + return $this->type; } - $entitySet = Lodata::getEntitySet($this->getName()); + $parameterName = $this->parameter->getName(); + return Lodata::getEntitySet($parameterName)->getType(); + } - if (!$entitySet instanceof EntitySet) { - throw new InternalServerErrorException( - 'invalid_entity_set', - 'Could not find entity set: '.$this->getName() - ); + public function resolveParameter(?EntitySet $parameter): EntitySet + { + if ($parameter) { + return $parameter; } - $entitySet = clone $entitySet; - $entitySet->setTransaction($source); - return $entitySet; - } + $entitySet = Lodata::getEntitySet($this->getName()); + $parameter = clone $entitySet; + $parameter->setTransaction($this->operation->getTransaction()); - /** - * Get the entity set type - * @return EntityType - */ - public function getType(): EntityType - { - $reflectedSet = $this->parameter->getName(); - return Lodata::getEntitySet($reflectedSet)->getType(); + return $parameter; } } diff --git a/src/Operation/Function_.php b/src/Operation/Function_.php new file mode 100644 index 000000000..570adc686 --- /dev/null +++ b/src/Operation/Function_.php @@ -0,0 +1,12 @@ +getType(); - - if (null === $source) { - if (!$this->isNullable()) { - throw new BadRequestException( - 'non_null_argument_missing', - sprintf('A non-null argument (%s) is missing', $this->getName()) - ); - } - - return $type->instance(); - } - - try { - return $lexer->type($type); - } catch (LexerException $e) { - throw new BadRequestException( - 'invalid_argument_type', - sprintf( - 'The provided argument %s was not of type %s', - $this->getName(), - $type->getIdentifier() - ) - ); - } - } - - /** - * Whether this primitive can represent a null value - * @return bool - */ - public function isNullable(): bool - { - return $this->parameter->allowsNull(); - } - /** * Get the type of this primitive * @return PrimitiveType */ - public function getType(): PrimitiveType + public function getType(): Type { /** @var ReflectionNamedType $type */ $type = $this->parameter->getType(); + return new PrimitiveType($type->getName()); } + + public function resolveParameter(?Primitive $parameter): ?Primitive + { + return $parameter; + } } diff --git a/src/Operation/Repository.php b/src/Operation/Repository.php new file mode 100644 index 000000000..d430ba8a0 --- /dev/null +++ b/src/Operation/Repository.php @@ -0,0 +1,62 @@ +getBindingParameterName()) { + throw new InternalServerErrorException( + 'missing_binding_parameter', + 'A binding parameter name must be provided for this operation' + ); + } + + return parent::resolveParameters(); + } + + public function getMetadataArguments() + { + $args = parent::getMetadataArguments(); + $bindingParameter = $args[$this->getBindingParameterName()]; + list ($repositoryClass) = $this->getCallable(); + + /** @var RepositoryInterface $repository */ + $repository = new $repositoryClass; + + $entityType = Lodata::getEntityType(EntityType::convertClassName($repository->getClass())); + + if (!$entityType instanceof EntityType) { + throw new ConfigurationException( + 'invalid_entity_type', + 'The entity type used by this repository has not been registered' + ); + } + + $args[$this->getBindingParameterName()] = (new EntityArgument($this, $bindingParameter->getParameter())) + ->setType($entityType); + + return $args; + } + + public function resolveParameter(Argument $argument, $parameter) + { + if ($argument->getName() === $this->getBindingParameterName()) { + return $parameter->getSource(); + } + + return parent::resolveParameter($argument, $parameter); + } +} \ No newline at end of file diff --git a/src/Operation/TransactionArgument.php b/src/Operation/TransactionArgument.php index 4da545f5f..af39ed754 100644 --- a/src/Operation/TransactionArgument.php +++ b/src/Operation/TransactionArgument.php @@ -5,8 +5,6 @@ namespace Flat3\Lodata\Operation; use Flat3\Lodata\Controller\Transaction; -use Flat3\Lodata\Exception\Protocol\InternalServerErrorException; -use Flat3\Lodata\Interfaces\Operation\ArgumentInterface; /** * Transaction Argument @@ -14,20 +12,8 @@ */ class TransactionArgument extends Argument { - /** - * Provide the current transaction as an invocation argument - * @param null $source - * @return ArgumentInterface - */ - public function generate($source = null): ArgumentInterface + public function resolveParameter(): Transaction { - if (!$source instanceof Transaction) { - throw new InternalServerErrorException( - 'invalid_transaction', - 'The source of the transaction type argument was not a Transaction' - ); - } - - return $source; + return $this->operation->getTransaction(); } } diff --git a/src/Operation/TypeArgument.php b/src/Operation/TypeArgument.php deleted file mode 100644 index 7bbb92ef5..000000000 --- a/src/Operation/TypeArgument.php +++ /dev/null @@ -1,35 +0,0 @@ -parameter->getType(); - - $result = Type::castInternalType($type->getName()); - - if (!$result instanceof PrimitiveType) { - throw new TypeError('invalid_type', 'The provided argument was not a primitive type'); - } - - return $result; - } -} diff --git a/src/Operation/ValueArgument.php b/src/Operation/ValueArgument.php new file mode 100644 index 000000000..faefd3dd8 --- /dev/null +++ b/src/Operation/ValueArgument.php @@ -0,0 +1,29 @@ +parameter->getType()->getName()); + } + + public function resolveParameter(?Primitive $parameter) + { + return $parameter ? $parameter->get() : null; + } +} diff --git a/src/PathSegment/Batch/JSON.php b/src/PathSegment/Batch/JSON.php index 0886be291..39f6410ab 100644 --- a/src/PathSegment/Batch/JSON.php +++ b/src/PathSegment/Batch/JSON.php @@ -10,6 +10,7 @@ use Flat3\Lodata\Exception\Protocol\BadRequestException; use Flat3\Lodata\Exception\Protocol\NotImplementedException; use Flat3\Lodata\Exception\Protocol\ProtocolException; +use Flat3\Lodata\Helper\Constants; use Flat3\Lodata\Helper\Url; use Flat3\Lodata\Interfaces\ContextInterface; use Flat3\Lodata\Interfaces\JsonInterface; @@ -89,8 +90,8 @@ public function emitJson(Transaction $transaction): void $headers = array_change_key_case($requestData['headers'] ?? [], CASE_LOWER); - if (!array_key_exists('content-type', $headers)) { - $headers['content-type'] = MediaType::json; + if (!array_key_exists(Constants::contentType, $headers)) { + $headers[Constants::contentType] = MediaType::json; } $request->headers->replace($headers); diff --git a/src/PathSegment/Metadata/JSON.php b/src/PathSegment/Metadata/JSON.php index 66cffb199..da603c080 100644 --- a/src/PathSegment/Metadata/JSON.php +++ b/src/PathSegment/Metadata/JSON.php @@ -14,7 +14,6 @@ use Flat3\Lodata\Interfaces\AnnotationInterface; use Flat3\Lodata\Interfaces\ContextInterface; use Flat3\Lodata\Interfaces\JsonInterface; -use Flat3\Lodata\Interfaces\Operation\ActionInterface; use Flat3\Lodata\Interfaces\ResponseInterface; use Flat3\Lodata\Model; use Flat3\Lodata\Operation; @@ -71,8 +70,8 @@ public function emitJson(Transaction $transaction): void break; } - $typeDefinitionElement->{'$UnderlyingType'} = $typeDefinition->getUnderlyingType()->getResolvedName($namespace); - $schema->{$typeDefinition->getResolvedName($namespace)} = $typeDefinitionElement; + $typeDefinitionElement->{'$UnderlyingType'} = $typeDefinition->getUnderlyingType()->getIdentifier()->getResolvedName($namespace); + $schema->{$typeDefinition->getIdentifier()->getResolvedName($namespace)} = $typeDefinitionElement; } foreach (Lodata::getComplexTypes() as $complexType) { @@ -96,7 +95,7 @@ public function emitJson(Transaction $transaction): void ) as $property) { $complexTypeProperty = (object) []; $complexTypeElement->{$property->getName()} = $complexTypeProperty; - $complexTypeProperty->{'$Type'} = $property->getType()->getIdentifier(); + $complexTypeProperty->{'$Type'} = $property->getType()->getIdentifier()->getQualifiedName(); $complexTypeProperty->{'$Nullable'} = $property->isNullable(); foreach ($property->getAnnotations() as $annotation) { @@ -116,7 +115,7 @@ public function emitJson(Transaction $transaction): void $navigationPropertyElement->{'$Partner'} = $navigationPropertyPartner->getName(); } - $navigationPropertyElement->{'$Type'} = $targetComplexType->getIdentifier(); + $navigationPropertyElement->{'$Type'} = $targetComplexType->getIdentifier()->getQualifiedName(); $navigationPropertyElement->{'$Nullable'} = $navigationProperty->isNullable(); $constraints = $navigationProperty->getConstraints(); @@ -135,13 +134,13 @@ public function emitJson(Transaction $transaction): void switch (true) { case $resource instanceof Singleton: - $entityContainer->{$resource->getResolvedName($namespace)} = $resourceElement; - $resourceElement->{'$Type'} = $resource->getType()->getIdentifier(); + $entityContainer->{$resource->getIdentifier()->getResolvedName($namespace)} = $resourceElement; + $resourceElement->{'$Type'} = $resource->getType()->getIdentifier()->getQualifiedName(); break; case $resource instanceof EntitySet: - $entityContainer->{$resource->getResolvedName($namespace)} = $resourceElement; - $resourceElement->{'$EntityType'} = $resource->getType()->getIdentifier(); + $entityContainer->{$resource->getIdentifier()->getResolvedName($namespace)} = $resourceElement; + $resourceElement->{'$EntityType'} = $resource->getType()->getIdentifier()->getQualifiedName(); $navigationBindings = $resource->getNavigationBindings(); if ($navigationBindings) { @@ -149,19 +148,19 @@ public function emitJson(Transaction $transaction): void $resourceElement->{'$NavigationPropertyBinding'} = $navigationPropertyBindingElement; foreach ($resource->getNavigationBindings() as $binding) { - $navigationPropertyBindingElement->{$binding->getPath()->getName()} = $binding->getTarget()->getResolvedName($namespace); + $navigationPropertyBindingElement->{$binding->getPath()->getName()} = $binding->getTarget()->getIdentifier()->getResolvedName($namespace); } } break; case $resource instanceof Operation: - $isBound = null !== $resource->getBindingParameterName(); + $isBound = $resource->isBound(); - $schema->{$resource->getResolvedName($namespace)} = $resourceElement; + $schema->{$resource->getIdentifier()->getResolvedName($namespace)} = $resourceElement; $resourceElement->{'$Kind'} = $resource->getKind(); $resourceElement->{'$IsBound'} = $isBound; - $arguments = $resource->getExternalArguments(); + $arguments = $resource->getMetadataArguments(); if ($arguments) { $argumentsElement = []; @@ -169,7 +168,7 @@ public function emitJson(Transaction $transaction): void $argumentsElement[] = [ '$Name' => $argument->getName(), '$Nullable' => $argument->isNullable(), - '$Type' => $argument->getType()->getIdentifier(), + '$Type' => $argument->getType()->getIdentifier()->getQualifiedName(), ]; } $resourceElement->{'$Parameter'} = $argumentsElement; @@ -181,14 +180,14 @@ public function emitJson(Transaction $transaction): void $returnTypeElement = (object) []; $resourceElement->{'$ReturnType'} = $returnTypeElement; $returnTypeElement->{'$Collection'} = $resource->returnsCollection(); - $returnTypeElement->{'$Type'} = $returnType->getIdentifier(); + $returnTypeElement->{'$Type'} = $returnType->getIdentifier()->getQualifiedName(); $returnTypeElement->{'$Nullable'} = $resource->isNullable(); } if (!$isBound) { $operationImportElement = (object) []; - $entityContainer->{$resource->getResolvedName($namespace).'Import'} = $operationImportElement; - $operationImportElement->{$resource instanceof ActionInterface ? '$Action' : '$Function'} = $resource->getIdentifier(); + $entityContainer->{$resource->getIdentifier()->getResolvedName($namespace).'Import'} = $operationImportElement; + $operationImportElement->{$resource->isAction() ? '$Action' : '$Function'} = $resource->getIdentifier()->getQualifiedName(); if (null !== $returnType && $returnType instanceof EntitySet) { $operationImportElement->{'$EntitySet'} = $returnType->getName(); diff --git a/src/PathSegment/Metadata/XML.php b/src/PathSegment/Metadata/XML.php index ce024d8df..c8569f1f8 100644 --- a/src/PathSegment/Metadata/XML.php +++ b/src/PathSegment/Metadata/XML.php @@ -64,11 +64,14 @@ public function emitStream(Transaction $transaction): void switch (true) { case $typeDefinition instanceof EnumerationType: $typeDefinitionElement = $schema->addChild('EnumType'); - $typeDefinitionElement->addAttribute('Name', $typeDefinition->getResolvedName($namespace)); + $typeDefinitionElement->addAttribute( + 'Name', + $typeDefinition->getIdentifier()->getResolvedName($namespace) + ); $typeDefinitionElement->addAttribute( 'UnderlyingType', - $typeDefinition->getUnderlyingType()->getResolvedName($namespace) + $typeDefinition->getUnderlyingType()->getIdentifier()->getResolvedName($namespace) ); $typeDefinitionElement->addAttribute( @@ -86,11 +89,14 @@ public function emitStream(Transaction $transaction): void case $typeDefinition instanceof PrimitiveType: $typeDefinitionElement = $schema->addChild('TypeDefinition'); - $typeDefinitionElement->addAttribute('Name', $typeDefinition->getResolvedName($namespace)); + $typeDefinitionElement->addAttribute( + 'Name', + $typeDefinition->getIdentifier()->getResolvedName($namespace) + ); $typeDefinitionElement->addAttribute( 'UnderlyingType', - $typeDefinition->getUnderlyingType()->getResolvedName($namespace) + $typeDefinition->getUnderlyingType()->getIdentifier()->getResolvedName($namespace) ); break; } @@ -99,7 +105,7 @@ public function emitStream(Transaction $transaction): void // https://docs.oasis-open.org/odata/odata-csdl-xml/v4.01/odata-csdl-xml-v4.01.html#sec_EntityType foreach (Lodata::getComplexTypes() as $complexType) { $complexTypeElement = $schema->addChild($complexType instanceof EntityType ? 'EntityType' : 'ComplexType'); - $complexTypeElement->addAttribute('Name', $complexType->getResolvedName($namespace)); + $complexTypeElement->addAttribute('Name', $complexType->getIdentifier()->getResolvedName($namespace)); if ($complexType instanceof EntityType) { // https://docs.oasis-open.org/odata/odata-csdl-xml/v4.01/odata-csdl-xml-v4.01.html#sec_Key @@ -121,7 +127,7 @@ public function emitStream(Transaction $transaction): void $entityTypeProperty->addAttribute('Name', $property->getName()); // https://docs.oasis-open.org/odata/odata-csdl-xml/v4.01/odata-csdl-xml-v4.01.html#sec_Type - $entityTypeProperty->addAttribute('Type', $property->getType()->getIdentifier()); + $entityTypeProperty->addAttribute('Type', $property->getType()->getIdentifier()->getQualifiedName()); // https://docs.oasis-open.org/odata/odata-csdl-xml/v4.01/odata-csdl-xml-v4.01.html#sec_TypeFacets $entityTypeProperty->addAttribute( @@ -142,7 +148,7 @@ public function emitStream(Transaction $transaction): void $navigationPropertyElement = $complexTypeElement->addChild('NavigationProperty'); $navigationPropertyElement->addAttribute('Name', $navigationProperty->getName()); - $navigationPropertyType = $targetComplexType->getIdentifier(); + $navigationPropertyType = $targetComplexType->getIdentifier()->getQualifiedName(); if ($navigationProperty->isCollection()) { $navigationPropertyType = 'Collection('.$navigationPropertyType.')'; } @@ -180,17 +186,17 @@ public function emitStream(Transaction $transaction): void case $resource instanceof Singleton: // https://docs.oasis-open.org/odata/odata-csdl-xml/v4.01/odata-csdl-xml-v4.01.html#_Toc38530395 $resourceElement = $entityContainer->addChild('Singleton'); - $resourceElement->addAttribute('Name', $resource->getResolvedName($namespace)); - $resourceElement->addAttribute('Type', $resource->getType()->getIdentifier()); + $resourceElement->addAttribute('Name', $resource->getIdentifier()->getResolvedName($namespace)); + $resourceElement->addAttribute('Type', $resource->getType()->getIdentifier()->getQualifiedName()); break; case $resource instanceof EntitySet: // https://docs.oasis-open.org/odata/odata-csdl-xml/v4.01/odata-csdl-xml-v4.01.html#sec_EntitySet $resourceElement = $entityContainer->addChild('EntitySet'); - $resourceElement->addAttribute('Name', $resource->getResolvedName($namespace)); + $resourceElement->addAttribute('Name', $resource->getIdentifier()->getResolvedName($namespace)); $resourceElement->addAttribute( 'EntityType', - $resource->getType()->getIdentifier() + $resource->getType()->getIdentifier()->getQualifiedName() ); // https://docs.oasis-open.org/odata/odata-csdl-xml/v4.01/odata-csdl-xml-v4.01.html#sec_NavigationPropertyBinding @@ -203,23 +209,26 @@ public function emitStream(Transaction $transaction): void ); $navigationPropertyBindingElement->addAttribute( 'Target', - $binding->getTarget()->getResolvedName($namespace) + $binding->getTarget()->getIdentifier()->getResolvedName($namespace) ); } break; /** @var Operation $resource */ case $resource instanceof Operation: - $isBound = null !== $resource->getBindingParameterName(); + $isBound = $resource->isBound(); $resourceElement = $schema->addChild($resource->getKind()); - $resourceElement->addAttribute('Name', $resource->getResolvedName($namespace)); + $resourceElement->addAttribute('Name', $resource->getIdentifier()->getName()); $resourceElement->addAttribute('IsBound', (new Boolean($isBound))->toUrl()); - foreach ($resource->getExternalArguments() as $argument) { + foreach ($resource->getMetadataArguments() as $argument) { $parameterElement = $resourceElement->addChild('Parameter'); $parameterElement->addAttribute('Name', $argument->getName()); - $parameterElement->addAttribute('Type', $argument->getType()->getIdentifier()); + $parameterElement->addAttribute( + 'Type', + $argument->getType()->getIdentifier()->getQualifiedName() + ); $parameterElement->addAttribute( 'Nullable', (new Boolean($argument->isNullable()))->toUrl() @@ -232,9 +241,9 @@ public function emitStream(Transaction $transaction): void if ($resource->returnsCollection()) { $returnTypeElement->addAttribute('Type', - 'Collection('.$returnType->getIdentifier().')'); + 'Collection('.$returnType->getIdentifier()->getQualifiedName().')'); } else { - $returnTypeElement->addAttribute('Type', $returnType->getIdentifier()); + $returnTypeElement->addAttribute('Type', $returnType->getIdentifier()->getQualifiedName()); } $returnTypeElement->addAttribute( @@ -246,7 +255,10 @@ public function emitStream(Transaction $transaction): void if (!$isBound) { $operationImportElement = $entityContainer->addChild($resource->getKind().'Import'); $operationImportElement->addAttribute('Name', $resource->getName()); - $operationImportElement->addAttribute($resource->getKind(), $resource->getIdentifier()); + $operationImportElement->addAttribute( + $resource->getKind(), + $resource->getIdentifier()->getQualifiedName() + ); if (null !== $returnType && $returnType instanceof EntitySet) { $operationImportElement->addAttribute('EntitySet', $returnType->getName()); diff --git a/src/PathSegment/OpenAPI.php b/src/PathSegment/OpenAPI.php index afb995cea..45f9ddaad 100644 --- a/src/PathSegment/OpenAPI.php +++ b/src/PathSegment/OpenAPI.php @@ -27,7 +27,6 @@ use Flat3\Lodata\Interfaces\EntitySet\TokenPaginationInterface; use Flat3\Lodata\Interfaces\EntitySet\UpdateInterface; use Flat3\Lodata\Interfaces\JsonInterface; -use Flat3\Lodata\Interfaces\Operation\FunctionInterface; use Flat3\Lodata\Interfaces\PipeInterface; use Flat3\Lodata\Interfaces\ResourceInterface; use Flat3\Lodata\Interfaces\ResponseInterface; @@ -290,7 +289,8 @@ public function emitJson(Transaction $transaction): void * @var Operation $operation */ foreach (Lodata::getResources()->sliceByClass(Operation::class) as $operation) { - $boundParameter = $operation->getBoundParameter(); + $boundParameterName = $operation->getBindingParameterName(); + $boundParameter = $operation->getCallableArguments()[$boundParameterName] ?? null; $pathItemObject = (object) []; switch (true) { @@ -298,13 +298,13 @@ public function emitJson(Transaction $transaction): void $paths->{'/'.$operation->getName()} = $pathItemObject; break; - case $boundParameter instanceof EntitySet: - $paths->{"/{$boundParameter->getName()}/{$operation->getName()}()"} = $pathItemObject; + case $boundParameter instanceof Operation\EntitySetArgument: + $paths->{"/{$boundParameterName}/{$operation->getName()}()"} = $pathItemObject; break; } $queryObject = (object) []; - $pathItemObject->{$operation instanceof FunctionInterface ? 'get' : 'post'} = $queryObject; + $pathItemObject->{$operation->isFunction() ? 'get' : 'post'} = $queryObject; $summary = $operation->getAnnotations()->sliceByClass(Description::class)->first(); @@ -313,7 +313,7 @@ public function emitJson(Transaction $transaction): void } else { $__args = ['name' => $operation->getName()]; - $tag['summary'] = $operation instanceof FunctionInterface + $tag['summary'] = $operation->isFunction() ? __('Invoke function :name', $__args) : __('Invoke action :name', $__args); } @@ -322,15 +322,15 @@ public function emitJson(Transaction $transaction): void $tags[] = __('Service Operations'); $tags[] = $operation->getName(); - if ($boundParameter) { - $tags[] = $boundParameter->getName(); + if ($boundParameterName) { + $tags[] = $boundParameterName; } $parameters = []; $returnType = $operation->getReturnType(); - foreach ($operation->getExternalArguments() as $argument) { + foreach ($operation->getMetadataArguments() as $argument) { $tags[] = $argument->getName(); $parameters[] = [ @@ -341,7 +341,7 @@ public function emitJson(Transaction $transaction): void ]; } - $queryObject->tags = $tags; + $queryObject->tags = $this->uniqueTags($tags); $queryObject->parameters = $parameters; $responses = []; @@ -762,7 +762,7 @@ protected function generateQueryRoutes( $queryObject->summary = __('Get entities from :name', ['name' => $entitySet->getName()]); } - $queryObject->tags = $tags; + $queryObject->tags = $this->uniqueTags($tags); $parameters = []; @@ -857,7 +857,7 @@ protected function generateCreateRoutes( $operationObject->summary = __('Add new entity to :name', ['name' => $entitySet->getName()]); } - $operationObject->tags = $tags; + $operationObject->tags = $this->uniqueTags($tags); $requestBody = [ 'required' => true, @@ -996,4 +996,9 @@ protected function generateKeyParameter(EntitySet $entitySet): array 'schema' => $key->getType()->toOpenAPISchema(), ]; } + + protected function uniqueTags(array $tags): array + { + return collect($tags)->unique()->values()->toArray(); + } } \ No newline at end of file diff --git a/src/Primitive.php b/src/Primitive.php index fd1e4fa36..8aae716d9 100644 --- a/src/Primitive.php +++ b/src/Primitive.php @@ -14,19 +14,20 @@ use Flat3\Lodata\Interfaces\ETagInterface; use Flat3\Lodata\Interfaces\IdentifierInterface; use Flat3\Lodata\Interfaces\JsonInterface; -use Flat3\Lodata\Interfaces\Operation\ArgumentInterface; use Flat3\Lodata\Interfaces\PipeInterface; use Flat3\Lodata\Interfaces\ResourceInterface; use Flat3\Lodata\Interfaces\ResponseInterface; -use Illuminate\Support\Str; +use Flat3\Lodata\Traits\HasIdentifier; /** * Primitive * @link https://docs.oasis-open.org/odata/odata-csdl-xml/v4.01/odata-csdl-xml-v4.01.html#_Toc38530338 * @package Flat3\Lodata */ -abstract class Primitive implements ResourceInterface, ContextInterface, IdentifierInterface, ArgumentInterface, ResponseInterface, JsonInterface, PipeInterface, ETagInterface +abstract class Primitive implements ResourceInterface, ContextInterface, IdentifierInterface, ResponseInterface, JsonInterface, PipeInterface, ETagInterface { + use HasIdentifier; + /** * The OData name of this primitive type * @type string identifier @@ -154,38 +155,6 @@ protected function getEmpty() return ''; } - /** - * Get the name of this primitive type - * @return string Name - */ - public function getName(): string - { - return Str::afterLast($this->getIdentifier(), '.'); - } - - /** - * Get the namespace of this primitive type - * @return string Namespace - */ - public function getNamespace(): string - { - return Str::beforeLast($this->getIdentifier(), '.'); - } - - /** - * Get the resolved name of this primitive type - * @param string $namespace Namespace - * @return string Name - */ - public function getResolvedName(string $namespace): string - { - if ($this->getNamespace() === $namespace) { - return $this->getName(); - } - - return $this->getIdentifier(); - } - /** * Get the resource URL of this primitive type * @param Transaction $transaction Related transaction @@ -200,9 +169,9 @@ public function getResourceUrl(Transaction $transaction): string * Get the fully qualified identifier of this primitive type * @return string Identifier */ - public function getIdentifier(): string + public function getIdentifier(): Identifier { - return (string) new Identifier($this::identifier); + return new Identifier($this::identifier); } /** @@ -270,7 +239,7 @@ public static function pipe( /** * @return string */ - public function __toString() + public function __toString(): string { return (string) $this->value; } diff --git a/src/PrimitiveType.php b/src/PrimitiveType.php index d7405527c..d59ac0d14 100644 --- a/src/PrimitiveType.php +++ b/src/PrimitiveType.php @@ -4,7 +4,9 @@ namespace Flat3\Lodata; +use Flat3\Lodata\Helper\Identifier; use Flat3\Lodata\Interfaces\IdentifierInterface; +use Flat3\Lodata\Traits\HasIdentifier; use RuntimeException; /** @@ -14,6 +16,8 @@ */ class PrimitiveType extends Type implements IdentifierInterface { + use HasIdentifier; + const identifier = 'Edm.PrimitiveType'; /** @@ -84,39 +88,11 @@ public function instance($value = null): Primitive * Get the fully qualified name of this primitive type * @return string Identifier */ - public function getIdentifier(): string + public function getIdentifier(): Identifier { return $this->instance()->getIdentifier(); } - /** - * Get the name of this primitive type - * @return string Name - */ - public function getName(): string - { - return $this->instance()->getName(); - } - - /** - * Get the namespace of this primitive typee - * @return string Namespace - */ - public function getNamespace(): string - { - return $this->instance()->getNamespace(); - } - - /** - * Get the resolved name of this primitive type based on the provided namespace - * @param string $namespace Namespace - * @return string Name - */ - public function getResolvedName(string $namespace): string - { - return $this->instance()->getResolvedName($namespace); - } - /** * Render this type as an OpenAPI schema * @return array @@ -142,6 +118,6 @@ public function getUnderlyingType(): ?PrimitiveType */ public function __toString(): string { - return (string) $this->getIdentifier(); + return $this->getIdentifier()->getQualifiedName(); } } \ No newline at end of file diff --git a/src/ServiceProvider.php b/src/ServiceProvider.php index 1e1d914e8..3584c3c77 100644 --- a/src/ServiceProvider.php +++ b/src/ServiceProvider.php @@ -4,8 +4,6 @@ namespace Flat3\Lodata; -use Flat3\Lodata\Console\ActionCommand; -use Flat3\Lodata\Console\FunctionCommand; use Flat3\Lodata\Controller\Monitor; use Flat3\Lodata\Controller\OData; use Flat3\Lodata\Controller\ODCFF; @@ -52,11 +50,6 @@ public function boot() { if ($this->app->runningInConsole()) { $this->publishes([__DIR__.'/../config.php' => config_path('lodata.php')], 'config'); - - $this->commands([ - FunctionCommand::class, - ActionCommand::class, - ]); } $this->app->singleton(Model::class, function () { diff --git a/src/Singleton.php b/src/Singleton.php index 3bc2074f4..2dc1696ca 100644 --- a/src/Singleton.php +++ b/src/Singleton.php @@ -5,7 +5,9 @@ namespace Flat3\Lodata; use Flat3\Lodata\Controller\Transaction; +use Flat3\Lodata\Exception\Internal\LexerException; use Flat3\Lodata\Exception\Internal\PathNotHandledException; +use Flat3\Lodata\Expression\Lexer; use Flat3\Lodata\Facades\Lodata; use Flat3\Lodata\Helper\Gate; use Flat3\Lodata\Interfaces\AnnotationInterface; @@ -93,9 +95,17 @@ public static function pipe( ?string $nextSegment, ?PipeInterface $argument ): ?PipeInterface { - $singleton = Lodata::getSingleton($currentSegment); + $lexer = new Lexer($currentSegment); - if (!$singleton instanceof Singleton) { + try { + $identifier = $lexer->qualifiedIdentifier(); + } catch (LexerException $e) { + throw new PathNotHandledException(); + } + + $singleton = Lodata::getSingleton($identifier); + + if (!$singleton instanceof Singleton || !$singleton->getIdentifier()->matchesNamespace($identifier)) { throw new PathNotHandledException(); } diff --git a/src/Traits/HasIdentifier.php b/src/Traits/HasIdentifier.php index 5f65beb27..ee45845af 100644 --- a/src/Traits/HasIdentifier.php +++ b/src/Traits/HasIdentifier.php @@ -20,19 +20,11 @@ trait HasIdentifier /** * Get the identifier - * @return string Identifier + * @return Identifier Identifier */ - public function getIdentifier(): string + public function getIdentifier(): Identifier { - return (string) $this->identifier; - } - - /** - * @return string - */ - public function __toString(): string - { - return (string) $this->identifier; + return $this->identifier; } /** @@ -41,30 +33,7 @@ public function __toString(): string */ public function getName(): string { - return $this->identifier->getName(); - } - - /** - * Get the namespace - * @return string Namespace - */ - public function getNamespace(): string - { - return $this->identifier->getNamespace(); - } - - /** - * Get the resolved name of this item based on the provided namespace - * @param string $namespace Namespace - * @return string - */ - public function getResolvedName(string $namespace): string - { - if ($this->identifier->getNamespace() === $namespace) { - return $this->getName(); - } - - return $this->getIdentifier(); + return $this->getIdentifier()->getName(); } /** @@ -78,4 +47,12 @@ public function setIdentifier($identifier) return $this; } + + /** + * @return string + */ + public function __toString(): string + { + return $this->identifier->getQualifiedName(); + } } diff --git a/src/Traits/HasNavigation.php b/src/Traits/HasNavigation.php index 581e75f89..d642102dd 100644 --- a/src/Traits/HasNavigation.php +++ b/src/Traits/HasNavigation.php @@ -5,7 +5,7 @@ namespace Flat3\Lodata\Traits; use Flat3\Lodata\Exception\Protocol\BadRequestException; -use Flat3\Lodata\Exception\Protocol\InternalServerErrorException; +use Flat3\Lodata\Exception\Protocol\ConfigurationException; use Flat3\Lodata\Helper\ObjectArray; use Flat3\Lodata\Helper\PropertyValue; use Flat3\Lodata\NavigationBinding; @@ -109,7 +109,7 @@ public function resolveExpansionKey(): PropertyValue /** @var PropertyValue $keyPropertyValue */ $keyPropertyValue = $sourceEntity->getPropertyValues()->get($targetConstraint->getProperty()); if ($keyPropertyValue->getPrimitiveValue() === null) { - throw new InternalServerErrorException('missing_expansion_key', 'The target constraint key is null'); + throw new ConfigurationException('missing_expansion_key', 'The target constraint key is null'); } $referencedProperty = $targetConstraint->getReferencedProperty(); diff --git a/src/Transaction/MetadataContainer.php b/src/Transaction/MetadataContainer.php index 7da438838..b3a8cc75a 100644 --- a/src/Transaction/MetadataContainer.php +++ b/src/Transaction/MetadataContainer.php @@ -131,7 +131,7 @@ public function hasProperties(): bool return !!$this->getProperties(); } - public function offsetExists($offset) + public function offsetExists($offset): bool { return array_key_exists($offset, $this->properties); } @@ -141,12 +141,12 @@ public function offsetGet($offset) return $this->properties[$offset]; } - public function offsetSet($offset, $value) + public function offsetSet($offset, $value): void { $this->properties[$offset] = $value; } - public function offsetUnset($offset) + public function offsetUnset($offset): void { unset($this->properties[$offset]); } diff --git a/src/Transaction/MultipartDocument.php b/src/Transaction/MultipartDocument.php index 2b7f12e28..cafbc500b 100644 --- a/src/Transaction/MultipartDocument.php +++ b/src/Transaction/MultipartDocument.php @@ -4,6 +4,7 @@ namespace Flat3\Lodata\Transaction; +use Flat3\Lodata\Helper\Constants; use Flat3\Lodata\Helper\Url; use Flat3\Lodata\ServiceProvider; use Illuminate\Http\Request; @@ -39,13 +40,13 @@ public function getContentType(): ?MediaType { $contentType = new MediaType(); - if (!array_key_exists('content-type', $this->headers)) { + if (!array_key_exists(Constants::contentType, $this->headers)) { $contentType->parse(MediaType::text); return $contentType; } - $contentType->parse($this->headers['content-type'][0]); + $contentType->parse($this->headers[Constants::contentType][0]); return $contentType; } diff --git a/src/Transaction/Option/Index.php b/src/Transaction/Option/Index.php new file mode 100644 index 000000000..de664fb51 --- /dev/null +++ b/src/Transaction/Option/Index.php @@ -0,0 +1,16 @@ +toOpenAPISchema(); } + /** + * Return a type object based on the provided value + * @param mixed $value PHP value + * @return Type OData type representation + */ + public static function fromInternalValue($value): Type + { + if (is_object($value)) { + return self::fromInternalType(get_class($value)); + } + + return self::fromInternalType(gettype($value)); + } + /** * Cast a PHP type to an OData type * @param string $type PHP type * @return Type OData type representation */ - public static function castInternalType(string $type): Type + public static function fromInternalType(string $type): Type { switch ($type) { case 'void': case 'string': - return new PrimitiveType(String_::class); + return self::string(); case 'float': case 'double': - return new PrimitiveType(Double::class); + return self::double(); case 'int': case 'integer': - return new PrimitiveType(Int64::class); + return self::int64(); case 'bool': case 'boolean': - return new PrimitiveType(Boolean::class); + return self::boolean(); + + case is_a($type, DateTime::class, true): + return self::datetimeoffset(); case 'array': - case 'object': + case 'stdClass': return new Untyped(); + + case CarbonImmutable::class: + return new PrimitiveType(DateTimeOffset::class); } throw new TypeError('Could not cast the provided internal type'); diff --git a/src/Type/Collection.php b/src/Type/Collection.php index fbffb39cc..4c5c08b74 100644 --- a/src/Type/Collection.php +++ b/src/Type/Collection.php @@ -42,7 +42,7 @@ public function toJson() }, $this->value); } - public function offsetExists($offset) + public function offsetExists($offset): bool { return isset($this->value[$offset]); } @@ -52,12 +52,12 @@ public function offsetGet($offset) return $this->value[$offset]; } - public function offsetSet($offset, $value) + public function offsetSet($offset, $value): void { $this->value[$offset] = $value; } - public function offsetUnset($offset) + public function offsetUnset($offset): void { unset($this->value[$offset]); } diff --git a/src/Type/Enum.php b/src/Type/Enum.php index bec554573..8d9fa6fbf 100644 --- a/src/Type/Enum.php +++ b/src/Type/Enum.php @@ -6,6 +6,7 @@ use Flat3\Lodata\EnumerationType; use Flat3\Lodata\Exception\Protocol\InternalServerErrorException; +use Flat3\Lodata\Helper\Identifier; use Flat3\Lodata\Helper\ObjectArray; use Flat3\Lodata\Primitive; @@ -70,14 +71,13 @@ public function add($value): self $member = $this->type[$value]; if ($member) { - $this->value->add($member); + $this->value->set($member); continue; } foreach ($this->type->getMembers() as $member) { if ($member->getValue()->get() === $value) { - $this->value->add($member); - continue; + $this->value->set($member); } } @@ -104,7 +104,7 @@ public function clear(): self return $this; } - public function getIdentifier(): string + public function getIdentifier(): Identifier { return $this->type->getIdentifier(); } diff --git a/src/Type/Untyped.php b/src/Type/Untyped.php index 04ae2d3cf..d36029a50 100644 --- a/src/Type/Untyped.php +++ b/src/Type/Untyped.php @@ -4,6 +4,7 @@ use Flat3\Lodata\ComplexType; use Flat3\Lodata\Helper\Constants; +use Flat3\Lodata\Helper\Identifier; class Untyped extends ComplexType { @@ -14,9 +15,9 @@ public function __construct() parent::__construct($this::identifier); } - public function getIdentifier(): string + public function getIdentifier(): Identifier { - return $this::identifier; + return new Identifier($this::identifier); } public function toOpenAPISchema(): array diff --git a/tests/Command/CommandTest.php b/tests/Command/CommandTest.php deleted file mode 100644 index 27a9562b1..000000000 --- a/tests/Command/CommandTest.php +++ /dev/null @@ -1,21 +0,0 @@ -assertMatchesFileSnapshot(app_path('Lodata/Example.php')); - } - - function test_action() - { - Artisan::call('lodata:action Example'); - $this->assertMatchesFileSnapshot(app_path('Lodata/Example.php')); - } -} \ No newline at end of file diff --git a/tests/Command/__snapshots__/files/CommandTest__test_action__1.php b/tests/Command/__snapshots__/files/CommandTest__test_action__1.php deleted file mode 100644 index 28d1db740..000000000 --- a/tests/Command/__snapshots__/files/CommandTest__test_action__1.php +++ /dev/null @@ -1,13 +0,0 @@ -get() + $b->get()); - } + $add = new Operation\Function_('add'); + $add->setCallable(function (Int32 $a, Int32 $b): Int32 { + return new Int32($a->get() + $b->get()); }); + Lodata::add($add); - Lodata::add(new class('div') extends Operation implements FunctionInterface { - public function invoke(Int32 $a, Int32 $b): Decimal - { - return new Decimal($a->get() / $b->get()); - } + $div = new Operation\Function_('div'); + $div->setCallable(function (Int32 $a, Int32 $b): Decimal { + return new Decimal($a->get() / $b->get()); }); + Lodata::add($div); } public function withTextModel() diff --git a/tests/Data/TestOperations.php b/tests/Data/TestOperations.php new file mode 100644 index 000000000..b69a38190 --- /dev/null +++ b/tests/Data/TestOperations.php @@ -0,0 +1,19 @@ +setCallable(function (): int { + return 42; + }); + + Lodata::add($number); + } +} \ No newline at end of file diff --git a/tests/Models/Airport.php b/tests/Models/Airport.php index fde2719cc..d64dda2a8 100644 --- a/tests/Models/Airport.php +++ b/tests/Models/Airport.php @@ -2,8 +2,13 @@ namespace Flat3\Lodata\Tests\Models; +use Flat3\Lodata\Attributes\LodataFunction; use Illuminate\Database\Eloquent\Model; +/** + * @property string $name + * @property string $code + */ class Airport extends Model { public $timestamps = false; @@ -30,4 +35,16 @@ public function scopeModern($query) { return $query->where('construction_date', '>', '1940-01-01'); } + + #[LodataFunction] + public function op1(): ?string + { + return $this->name; + } + + #[LodataFunction] + public function op2(string $prefix): string + { + return $prefix.$this->code; + } } diff --git a/tests/Models/Passenger.php b/tests/Models/Passenger.php index 19feb63f1..d3341f8de 100644 --- a/tests/Models/Passenger.php +++ b/tests/Models/Passenger.php @@ -2,6 +2,7 @@ namespace Flat3\Lodata\Tests\Models; +use Flat3\Lodata\Attributes\LodataRelationship; use Illuminate\Database\Eloquent\Model; class Passenger extends Model @@ -24,6 +25,7 @@ public function destinationAirport() return $this->hasOneThrough(Airport::class, Flight::class, 'id', 'code', 'flight_id', 'destination'); } + #[LodataRelationship] public function pets() { return $this->hasMany(Pet::class); diff --git a/tests/Models/Pet.php b/tests/Models/Pet.php index e0c5c1f1f..6b557eb64 100644 --- a/tests/Models/Pet.php +++ b/tests/Models/Pet.php @@ -2,6 +2,7 @@ namespace Flat3\Lodata\Tests\Models; +use Flat3\Lodata\Attributes\LodataRelationship; use Illuminate\Database\Eloquent\Model; class Pet extends Model @@ -9,6 +10,7 @@ class Pet extends Model public $timestamps = false; protected $guarded = []; + #[LodataRelationship] public function passenger() { return $this->belongsTo(Passenger::class); diff --git a/tests/Models/Repository.php b/tests/Models/Repository.php new file mode 100644 index 000000000..00a4f9f53 --- /dev/null +++ b/tests/Models/Repository.php @@ -0,0 +1,22 @@ +code.($suffix ?: ''); + } +} \ No newline at end of file diff --git a/tests/Operations/Instance.php b/tests/Operations/Instance.php new file mode 100644 index 000000000..b7e68c84b --- /dev/null +++ b/tests/Operations/Instance.php @@ -0,0 +1,18 @@ +a; + } +} \ No newline at end of file diff --git a/tests/Operations/Math.php b/tests/Operations/Math.php new file mode 100644 index 000000000..8daa926c7 --- /dev/null +++ b/tests/Operations/Math.php @@ -0,0 +1,18 @@ +getSource()->name; + } + + #[LodataFunction(bind: "Flight", return: "Flight")] + public function i1(Entity $Flight): Entity + { + $Flight['name'] = 'test'; + + return $Flight; + } + + #[LodataFunction] + public function add(int $a, int $b): int + { + return $a + $b; + } + + #[LodataFunction(bind: "a")] + public function increment(int $a): int + { + return $a + 1; + } + + #[LodataAction] + public function exec(): void + { + } + + #[LodataAction(name: "exec2")] + public function exec1(): void + { + } +} \ No newline at end of file diff --git a/tests/TestCase.php b/tests/TestCase.php index 53313a271..5af3b8cbf 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -14,6 +14,7 @@ use Flat3\Lodata\Exception\Protocol\ProtocolException; use Flat3\Lodata\ServiceProvider; use Flat3\Lodata\Tests\Data\TestModels; +use Flat3\Lodata\Tests\Data\TestOperations; use Flat3\Lodata\Type\Guid; use Illuminate\Contracts\Filesystem\Filesystem as FilesystemContract; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -39,6 +40,7 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase use MatchesSnapshots; use RefreshDatabase; use TestModels; + use TestOperations; use WithoutMiddleware; /** @var Expectation $gateMock */ @@ -198,8 +200,8 @@ protected function assertODataError(Request $request, int $code): TestResponse { $emptyCodes = [Response::HTTP_NO_CONTENT, Response::HTTP_FOUND, Response::HTTP_NOT_MODIFIED]; $response = $this->req($request); - $this->assertEquals($code, $response->getStatusCode()); $content = $this->responseContent($response); + $this->assertEquals($code, $response->getStatusCode()); if (!$content) { $this->assertContains($code, $emptyCodes); @@ -379,7 +381,13 @@ protected function snapshotDatabase(): array continue; } - $db[$table] = DB::table($table)->select('*')->get(); + $db[$table] = DB::table($table) + ->select('*') + ->get() + ->map(function ($record) { + return json_decode(json_encode($record, JSON_NUMERIC_CHECK), true); + }) + ->toArray(); } return $db; diff --git a/tests/Unit/Collection/NumericCollectionTest.php b/tests/Unit/Collection/NumericCollectionTest.php index 569541288..99aff5f0e 100644 --- a/tests/Unit/Collection/NumericCollectionTest.php +++ b/tests/Unit/Collection/NumericCollectionTest.php @@ -41,6 +41,11 @@ public function setUp(): void Lodata::add($entitySet); } + public function test_metadata() + { + $this->assertMetadataDocuments(); + } + public function test_count() { $this->assertTextResponse( @@ -89,6 +94,29 @@ public function test_create() ); } + public function test_create_positional() + { + $this->assertJsonMetadataResponse( + (new Request) + ->post() + ->path('/examples') + ->query('$index', 1) + ->body([ + 'name' => 'Zeta', + ]) + ); + + $this->assertJsonResponse( + (new Request) + ->path('/examples') + ); + + $this->assertJsonResponse( + (new Request) + ->path('/examples/1') + ); + } + public function test_read() { $this->assertJsonResponse( diff --git a/tests/Unit/Collection/__snapshots__/NumericCollectionTest__test_create_positional__1.json b/tests/Unit/Collection/__snapshots__/NumericCollectionTest__test_create_positional__1.json new file mode 100644 index 000000000..03d7626a3 --- /dev/null +++ b/tests/Unit/Collection/__snapshots__/NumericCollectionTest__test_create_positional__1.json @@ -0,0 +1,5 @@ +{ + "@context": "http://localhost/odata/$metadata#examples/$entity", + "name": "Zeta", + "id": 1 +} diff --git a/tests/Unit/Collection/__snapshots__/NumericCollectionTest__test_create_positional__2.yml b/tests/Unit/Collection/__snapshots__/NumericCollectionTest__test_create_positional__2.yml new file mode 100644 index 000000000..3657ad76d --- /dev/null +++ b/tests/Unit/Collection/__snapshots__/NumericCollectionTest__test_create_positional__2.yml @@ -0,0 +1,8 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/json] + odata-version: ['4.01'] + location: ['http://localhost/odata/examples(1)'] + etag: ['W/"af4b328625a1be385a6d7dfb08c79e0f3903513da5422014f013d7e5913f92ff"'] + trailer: [odata-error] +status: 201 diff --git a/tests/Unit/Collection/__snapshots__/NumericCollectionTest__test_create_positional__3.json b/tests/Unit/Collection/__snapshots__/NumericCollectionTest__test_create_positional__3.json new file mode 100644 index 000000000..1a9975de9 --- /dev/null +++ b/tests/Unit/Collection/__snapshots__/NumericCollectionTest__test_create_positional__3.json @@ -0,0 +1,25 @@ +{ + "@context": "http://localhost/odata/$metadata#examples", + "value": [ + { + "id": 0, + "name": "Alpha" + }, + { + "id": 1, + "name": "Zeta" + }, + { + "id": 2, + "name": "Beta" + }, + { + "id": 3, + "name": "Gamma" + }, + { + "id": 4, + "name": "Delta" + } + ] +} diff --git a/tests/Unit/Collection/__snapshots__/NumericCollectionTest__test_create_positional__4.json b/tests/Unit/Collection/__snapshots__/NumericCollectionTest__test_create_positional__4.json new file mode 100644 index 000000000..30c118021 --- /dev/null +++ b/tests/Unit/Collection/__snapshots__/NumericCollectionTest__test_create_positional__4.json @@ -0,0 +1,5 @@ +{ + "@context": "http://localhost/odata/$metadata#examples/$entity", + "id": 1, + "name": "Zeta" +} diff --git a/tests/Unit/Collection/__snapshots__/NumericCollectionTest__test_metadata__1.xml b/tests/Unit/Collection/__snapshots__/NumericCollectionTest__test_metadata__1.xml new file mode 100644 index 000000000..4976e49a2 --- /dev/null +++ b/tests/Unit/Collection/__snapshots__/NumericCollectionTest__test_metadata__1.xml @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Collection/__snapshots__/NumericCollectionTest__test_metadata__2.yml b/tests/Unit/Collection/__snapshots__/NumericCollectionTest__test_metadata__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Collection/__snapshots__/NumericCollectionTest__test_metadata__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Collection/__snapshots__/NumericCollectionTest__test_metadata__3.json b/tests/Unit/Collection/__snapshots__/NumericCollectionTest__test_metadata__3.json new file mode 100644 index 000000000..9bc83426a --- /dev/null +++ b/tests/Unit/Collection/__snapshots__/NumericCollectionTest__test_metadata__3.json @@ -0,0 +1,113 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "examples": { + "$EntityType": "com.example.odata.example", + "$NavigationPropertyBinding": {}, + "@Org.OData.Capabilities.V1.CountRestrictions": { + "Countable": true + }, + "@Org.OData.Capabilities.V1.TopSupported": true, + "@Org.OData.Capabilities.V1.SkipSupported": true, + "@Org.OData.Capabilities.V1.FilterRestrictions": { + "Filterable": true + }, + "@Org.OData.Capabilities.V1.SortRestrictions": { + "Sortable": true + }, + "@Org.OData.Capabilities.V1.ExpandRestrictions": { + "Expandable": false + }, + "@Org.OData.Capabilities.V1.SearchRestrictions": { + "Searchable": true + }, + "@Org.OData.Capabilities.V1.InsertRestrictions": { + "Insertable": true + }, + "@Org.OData.Capabilities.V1.UpdateRestrictions": { + "Updatable": true, + "DeltaUpdateSupported": true + }, + "@Org.OData.Capabilities.V1.DeleteRestrictions": { + "Deletable": true + }, + "@Org.OData.Capabilities.V1.ReadRestrictions": { + "Readable": true + }, + "@Org.OData.Capabilities.V1.IndexableByKey": true, + "@Org.OData.Capabilities.V1.SelectSupport": { + "Supported": true + }, + "@Org.OData.Core.V1.PositionalInsert": true + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "example": { + "$Kind": "EntityType", + "$Key": [ + "id" + ], + "id": { + "$Type": "Edm.Int64", + "$Nullable": false + }, + "name": { + "$Type": "Edm.String", + "$Nullable": true + } + } +} diff --git a/tests/Unit/Collection/__snapshots__/NumericCollectionTest__test_metadata__4.json b/tests/Unit/Collection/__snapshots__/NumericCollectionTest__test_metadata__4.json new file mode 100644 index 000000000..7cc3d70da --- /dev/null +++ b/tests/Unit/Collection/__snapshots__/NumericCollectionTest__test_metadata__4.json @@ -0,0 +1,623 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [ + { + "name": "examples" + } + ], + "paths": { + "/examples": { + "get": { + "summary": "Get entities from examples", + "tags": [ + "examples" + ], + "parameters": [ + { + "name": "select", + "in": "query", + "description": "Select properties to be returned, see [OData Select](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionselect)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "*", + "id", + "name" + ] + } + } + }, + { + "$ref": "#/components/parameters/count" + }, + { + "$ref": "#/components/parameters/filter" + }, + { + "$ref": "#/components/parameters/search" + }, + { + "$ref": "#/components/parameters/top" + }, + { + "$ref": "#/components/parameters/skip" + }, + { + "name": "orderby", + "in": "query", + "description": "Order items by property values, see [OData Sorting](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionorderby)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "id", + "id desc", + "name", + "name desc" + ] + } + } + } + ], + "responses": { + "200": { + "description": "Retrieved entities", + "content": { + "application/json": { + "schema": { + "type": "object", + "title": "Collection of examples", + "properties": { + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/com.example.odata.example" + } + }, + "@count": { + "$ref": "#/components/schemas/count" + } + } + } + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + }, + "post": { + "summary": "Add new entity to examples", + "tags": [ + "examples" + ], + "requestBody": { + "required": true, + "description": "New entity", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.example~create" + } + } + } + }, + "responses": { + "201": { + "description": "Created entity", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.example" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/examples/{id}": { + "parameters": [ + { + "description": "Key: id", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807, + "nullable": false + } + } + ], + "get": { + "summary": "Get entity from examples by key", + "tags": [ + "examples" + ], + "parameters": [ + { + "name": "select", + "in": "query", + "description": "Select properties to be returned, see [OData Select](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionselect)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "*", + "id", + "name" + ] + } + } + } + ], + "responses": { + "200": { + "description": "Retrieved entity", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.example" + } + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + }, + "patch": { + "summary": "Update entity in examples", + "tags": [ + "examples" + ], + "requestBody": { + "description": "New property values", + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.example~update" + } + } + } + }, + "responses": { + "200": { + "$ref": "#/components/schemas/com.example.odata.example" + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + }, + "delete": { + "summary": "Delete entity from examples", + "tags": [ + "examples" + ], + "responses": { + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "com.example.odata.example": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807, + "nullable": false + }, + "name": { + "type": "string", + "nullable": true + } + } + }, + "com.example.odata.example~create": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807, + "nullable": false + }, + "name": { + "type": "string", + "nullable": true + } + } + }, + "com.example.odata.example~update": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true + } + } + }, + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Eloquent/CastingTest.php b/tests/Unit/Eloquent/CastingTest.php index 7778cf974..9e42e851b 100644 --- a/tests/Unit/Eloquent/CastingTest.php +++ b/tests/Unit/Eloquent/CastingTest.php @@ -24,7 +24,7 @@ public function setUp(): void 'id' => '5', ]))->save(); - Lodata::discoverEloquentModel(Cast::class); + Lodata::discover(Cast::class); } public function testPrimaryKeyCast() diff --git a/tests/Unit/Eloquent/EloquentTest.php b/tests/Unit/Eloquent/EloquentTest.php index 4c10da5c6..899b0c09f 100644 --- a/tests/Unit/Eloquent/EloquentTest.php +++ b/tests/Unit/Eloquent/EloquentTest.php @@ -4,12 +4,13 @@ use Flat3\Lodata\Controller\Response; use Flat3\Lodata\Drivers\EloquentEntitySet; -use Flat3\Lodata\Exception\Protocol\InternalServerErrorException; +use Flat3\Lodata\Exception\Protocol\ConfigurationException; use Flat3\Lodata\Facades\Lodata; use Flat3\Lodata\Tests\Models\Airport; use Flat3\Lodata\Tests\Models\Country; use Flat3\Lodata\Tests\Models\Flight; use Flat3\Lodata\Tests\Models\Passenger; +use Flat3\Lodata\Tests\Models\Pet; use Flat3\Lodata\Tests\Request; use Flat3\Lodata\Tests\TestCase; use Flat3\Lodata\Transaction\MetadataType; @@ -27,17 +28,20 @@ public function setUp(): void $flights = Lodata::discoverEloquentModel(Flight::class); $countries = Lodata::discoverEloquentModel(Country::class); $passengers = Lodata::discoverEloquentModel(Passenger::class); + $pets = Lodata::discoverEloquentModel(Pet::class); Lodata::getEntityType('Flight')->getProperty('duration')->setType(Type::duration()); $airports->discoverRelationship('flights'); $airports->discoverRelationship('country'); $flights->discoverRelationship('passengers'); + $passengers->discoverRelationship('pets'); $passengers->discoverRelationship('flight'); $countries->discoverRelationship('airports'); $passengers->discoverRelationship('originAirport'); $passengers->discoverRelationship('destinationAirport'); $flights->discoverRelationship('originAirport'); $flights->discoverRelationship('destinationAirport'); + $pets->discoverRelationship('passenger'); $airport = Lodata::getEntityType('Airport'); $airport->getDeclaredProperty('code')->setAlternativeKey(); @@ -53,7 +57,7 @@ public function test_failed_relationship() try { $countries->discoverRelationship('airport'); - } catch (InternalServerErrorException $e) { + } catch (ConfigurationException $e) { $this->assertProtocolExceptionSnapshot($e); } } diff --git a/tests/Unit/Eloquent/InvalidModelTest.php b/tests/Unit/Eloquent/InvalidModelTest.php index 008f468d5..9bbd942c9 100644 --- a/tests/Unit/Eloquent/InvalidModelTest.php +++ b/tests/Unit/Eloquent/InvalidModelTest.php @@ -2,7 +2,7 @@ namespace Flat3\Lodata\Tests\Unit\Eloquent; -use Flat3\Lodata\Exception\Protocol\InternalServerErrorException; +use Flat3\Lodata\Exception\Protocol\ConfigurationException; use Flat3\Lodata\Facades\Lodata; use Flat3\Lodata\Tests\Models\Cast; use Flat3\Lodata\Tests\TestCase; @@ -19,7 +19,7 @@ public function testMissingPrimaryKey() try { Lodata::discoverEloquentModel(Cast::class); - } catch (InternalServerErrorException $e) { + } catch (ConfigurationException $e) { $this->assertProtocolExceptionSnapshot($e); } } diff --git a/tests/Unit/Eloquent/OperationTest.php b/tests/Unit/Eloquent/OperationTest.php new file mode 100644 index 000000000..46a9e3737 --- /dev/null +++ b/tests/Unit/Eloquent/OperationTest.php @@ -0,0 +1,43 @@ +markTestSkipped(); + } + + $this->withFlightDatabase(); + Lodata::discover(Airport::class); + } + + public function test_op1() + { + $this->withFlightData(); + + $this->assertJsonResponse( + (new Request) + ->path('/Airports/1/op1') + ); + } + + public function test_op2() + { + $this->withFlightData(); + + $this->assertJsonResponse( + (new Request) + ->path("/Airports/1/op2(prefix='o')") + ); + } +} \ No newline at end of file diff --git a/tests/Unit/Eloquent/__snapshots__/EloquentTest__test_create__3.yml b/tests/Unit/Eloquent/__snapshots__/EloquentTest__test_create__3.yml index e6223c240..ee26a8df9 100644 --- a/tests/Unit/Eloquent/__snapshots__/EloquentTest__test_create__3.yml +++ b/tests/Unit/Eloquent/__snapshots__/EloquentTest__test_create__3.yml @@ -1,5 +1,5 @@ airports: - - { id: '1', name: Eloquent, code: efo, construction_date: null, sam_datetime: null, open_time: null, review_score: null, is_big: null, country_id: null } + - { id: 1, name: Eloquent, code: efo, construction_date: null, sam_datetime: null, open_time: null, review_score: null, is_big: null, country_id: null } countries: { } flights: { } passengers: { } diff --git a/tests/Unit/Eloquent/__snapshots__/EloquentTest__test_create_deep__2.yml b/tests/Unit/Eloquent/__snapshots__/EloquentTest__test_create_deep__2.yml index 677bf2918..ca66d62a2 100644 --- a/tests/Unit/Eloquent/__snapshots__/EloquentTest__test_create_deep__2.yml +++ b/tests/Unit/Eloquent/__snapshots__/EloquentTest__test_create_deep__2.yml @@ -1,8 +1,8 @@ airports: { } countries: { } flights: - - { id: '1', origin: lhr, destination: sfo, gate: null, duration: '28800.0' } + - { id: 1, origin: lhr, destination: sfo, gate: null, duration: 28800 } passengers: - - { id: '1', flight_id: '1', name: Alice } - - { id: '2', flight_id: '1', name: Bob } + - { id: 1, flight_id: 1, name: Alice } + - { id: 2, flight_id: 1, name: Bob } pets: { } diff --git a/tests/Unit/Eloquent/__snapshots__/EloquentTest__test_create_navigation_property__3.yml b/tests/Unit/Eloquent/__snapshots__/EloquentTest__test_create_navigation_property__3.yml index c844c39f4..dd8696ad7 100644 --- a/tests/Unit/Eloquent/__snapshots__/EloquentTest__test_create_navigation_property__3.yml +++ b/tests/Unit/Eloquent/__snapshots__/EloquentTest__test_create_navigation_property__3.yml @@ -1,18 +1,18 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } countries: { } flights: - - { id: '1', origin: lhr, destination: lax, gate: null, duration: '41100.0' } - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } + - { id: 1, origin: lhr, destination: lax, gate: null, duration: 41100 } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } - - { id: '6', flight_id: '1', name: 'Harry Horse' } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } + - { id: 6, flight_id: 1, name: 'Harry Horse' } pets: { } diff --git a/tests/Unit/Eloquent/__snapshots__/EloquentTest__test_metadata__1.xml b/tests/Unit/Eloquent/__snapshots__/EloquentTest__test_metadata__1.xml index e5bfcd0a4..0bfc03013 100644 --- a/tests/Unit/Eloquent/__snapshots__/EloquentTest__test_metadata__1.xml +++ b/tests/Unit/Eloquent/__snapshots__/EloquentTest__test_metadata__1.xml @@ -66,6 +66,12 @@ + + + + + + @@ -125,6 +131,12 @@ + + + + + + @@ -182,8 +194,15 @@ + + + + + + + @@ -241,6 +260,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -305,10 +393,25 @@ + + + + + + + + + + + + + + + diff --git a/tests/Unit/Eloquent/__snapshots__/EloquentTest__test_metadata__3.json b/tests/Unit/Eloquent/__snapshots__/EloquentTest__test_metadata__3.json index e4b7e262b..4d5847723 100644 --- a/tests/Unit/Eloquent/__snapshots__/EloquentTest__test_metadata__3.json +++ b/tests/Unit/Eloquent/__snapshots__/EloquentTest__test_metadata__3.json @@ -58,6 +58,10 @@ "@Org.OData.Capabilities.V1.IndexableByKey": true, "@Org.OData.Capabilities.V1.SelectSupport": { "Supported": true + }, + "@Org.OData.Capabilities.V1.DeepInsertSupport": { + "Supported": true, + "ContentIDSupported": true } }, "Flights": { @@ -100,6 +104,10 @@ "@Org.OData.Capabilities.V1.IndexableByKey": true, "@Org.OData.Capabilities.V1.SelectSupport": { "Supported": true + }, + "@Org.OData.Capabilities.V1.DeepInsertSupport": { + "Supported": true, + "ContentIDSupported": true } }, "Countries": { @@ -140,11 +148,16 @@ "@Org.OData.Capabilities.V1.IndexableByKey": true, "@Org.OData.Capabilities.V1.SelectSupport": { "Supported": true + }, + "@Org.OData.Capabilities.V1.DeepInsertSupport": { + "Supported": true, + "ContentIDSupported": true } }, "Passengers": { "$EntityType": "com.example.odata.Passenger", "$NavigationPropertyBinding": { + "pets": "Pets", "flight": "Flights", "originAirport": "Airports", "destinationAirport": "Airports" @@ -182,6 +195,54 @@ "@Org.OData.Capabilities.V1.IndexableByKey": true, "@Org.OData.Capabilities.V1.SelectSupport": { "Supported": true + }, + "@Org.OData.Capabilities.V1.DeepInsertSupport": { + "Supported": true, + "ContentIDSupported": true + } + }, + "Pets": { + "$EntityType": "com.example.odata.Pet", + "$NavigationPropertyBinding": { + "passenger": "Passengers" + }, + "@Org.OData.Capabilities.V1.CountRestrictions": { + "Countable": true + }, + "@Org.OData.Capabilities.V1.TopSupported": true, + "@Org.OData.Capabilities.V1.SkipSupported": true, + "@Org.OData.Capabilities.V1.FilterRestrictions": { + "Filterable": true + }, + "@Org.OData.Capabilities.V1.SortRestrictions": { + "Sortable": true + }, + "@Org.OData.Capabilities.V1.ExpandRestrictions": { + "Expandable": true + }, + "@Org.OData.Capabilities.V1.SearchRestrictions": { + "Searchable": true + }, + "@Org.OData.Capabilities.V1.InsertRestrictions": { + "Insertable": true + }, + "@Org.OData.Capabilities.V1.UpdateRestrictions": { + "Updatable": true, + "DeltaUpdateSupported": true + }, + "@Org.OData.Capabilities.V1.DeleteRestrictions": { + "Deletable": true + }, + "@Org.OData.Capabilities.V1.ReadRestrictions": { + "Readable": true + }, + "@Org.OData.Capabilities.V1.IndexableByKey": true, + "@Org.OData.Capabilities.V1.SelectSupport": { + "Supported": true + }, + "@Org.OData.Capabilities.V1.DeepInsertSupport": { + "Supported": true, + "ContentIDSupported": true } }, "$Annotations": { @@ -371,6 +432,14 @@ "$Type": "Edm.String", "$Nullable": false }, + "pets": { + "$Collection": true, + "$Type": "com.example.odata.Pet", + "$Nullable": true, + "$ReferentialConstraint": { + "id": "passenger_id" + } + }, "flight": { "$Collection": false, "$Type": "com.example.odata.Flight", @@ -389,5 +458,34 @@ "$Nullable": true, "$ReferentialConstraint": {} } + }, + "Pet": { + "$Kind": "EntityType", + "$Key": [ + "id" + ], + "id": { + "$Type": "Edm.Int64", + "$Nullable": false, + "@Org.OData.Core.V1.Computed": true + }, + "passenger_id": { + "$Type": "Edm.Int32", + "$Nullable": true + }, + "name": { + "$Type": "Edm.String", + "$Nullable": true + }, + "type": { + "$Type": "Edm.String", + "$Nullable": true + }, + "passenger": { + "$Collection": false, + "$Type": "com.example.odata.Passenger", + "$Nullable": true, + "$ReferentialConstraint": {} + } } } diff --git a/tests/Unit/Eloquent/__snapshots__/EloquentTest__test_metadata__4.json b/tests/Unit/Eloquent/__snapshots__/EloquentTest__test_metadata__4.json index b09923669..4a7c0254f 100644 --- a/tests/Unit/Eloquent/__snapshots__/EloquentTest__test_metadata__4.json +++ b/tests/Unit/Eloquent/__snapshots__/EloquentTest__test_metadata__4.json @@ -22,6 +22,9 @@ }, { "name": "Passengers" + }, + { + "name": "Pets" } ], "paths": { @@ -964,6 +967,7 @@ "items": { "type": "string", "enum": [ + "pets", "flight", "originAirport", "destinationAirport" @@ -1903,6 +1907,7 @@ "items": { "type": "string", "enum": [ + "pets", "flight", "originAirport", "destinationAirport" @@ -2060,6 +2065,7 @@ "items": { "type": "string", "enum": [ + "pets", "flight", "originAirport", "destinationAirport" @@ -2127,6 +2133,169 @@ } } }, + "/Passengers/{id}/pets": { + "parameters": [ + { + "description": "Key: id", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807, + "nullable": false + } + } + ], + "get": { + "summary": "Get entities from related Pets", + "tags": [ + "Pets", + "Passengers" + ], + "parameters": [ + { + "name": "select", + "in": "query", + "description": "Select properties to be returned, see [OData Select](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionselect)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "*", + "id", + "passenger_id", + "name", + "type" + ] + } + } + }, + { + "$ref": "#/components/parameters/count" + }, + { + "name": "expand", + "in": "query", + "description": "Expand related entities, see [OData Expand](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionexpand)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "passenger" + ] + } + } + }, + { + "$ref": "#/components/parameters/filter" + }, + { + "$ref": "#/components/parameters/search" + }, + { + "$ref": "#/components/parameters/top" + }, + { + "$ref": "#/components/parameters/skip" + }, + { + "name": "orderby", + "in": "query", + "description": "Order items by property values, see [OData Sorting](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionorderby)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "id", + "id desc", + "passenger_id", + "passenger_id desc", + "name", + "name desc", + "type", + "type desc" + ] + } + } + } + ], + "responses": { + "200": { + "description": "Retrieved entities", + "content": { + "application/json": { + "schema": { + "type": "object", + "title": "Collection of Pets", + "properties": { + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/com.example.odata.Pet" + } + }, + "@count": { + "$ref": "#/components/schemas/count" + } + } + } + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + }, + "post": { + "summary": "Add new entity to related Pets", + "tags": [ + "Pets", + "Passengers" + ], + "requestBody": { + "required": true, + "description": "New entity", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.Pet~create" + } + } + } + }, + "responses": { + "201": { + "description": "Created entity", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.Pet" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, "/Passengers/{id}/flight": { "parameters": [ { @@ -2653,57 +2822,484 @@ } } }, - "/$batch": { - "post": { - "summary": "Send a group of requests", - "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "/Pets": { + "get": { + "summary": "Get entities from Pets", "tags": [ - "Batch Requests" + "Pets" ], - "requestBody": { - "required": true, - "description": "Batch Request", - "content": { - "application/json": { - "schema": { - "type": "string" - }, - "example": { - "requests": [ - { - "id": "0", - "method": "get", - "url": "/odata/resource(1)" - }, - { - "id": "1", - "method": "patch", - "url": "/odata/resource(2)", - "headers": { - "Prefer": "return=minimal" - }, - "body": "" - } + "parameters": [ + { + "name": "select", + "in": "query", + "description": "Select properties to be returned, see [OData Select](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionselect)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "*", + "id", + "passenger_id", + "name", + "type" + ] + } + } + }, + { + "$ref": "#/components/parameters/count" + }, + { + "name": "expand", + "in": "query", + "description": "Expand related entities, see [OData Expand](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionexpand)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "passenger" + ] + } + } + }, + { + "$ref": "#/components/parameters/filter" + }, + { + "$ref": "#/components/parameters/search" + }, + { + "$ref": "#/components/parameters/top" + }, + { + "$ref": "#/components/parameters/skip" + }, + { + "name": "orderby", + "in": "query", + "description": "Order items by property values, see [OData Sorting](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionorderby)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "id", + "id desc", + "passenger_id", + "passenger_id desc", + "name", + "name desc", + "type", + "type desc" ] } - }, - "multipart/mixed;boundary=request-separator": { - "schema": { - "type": "string" - }, - "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" } } - }, + ], "responses": { "200": { - "description": "Batch response", + "description": "Retrieved entities", "content": { "application/json": { "schema": { - "type": "string" - }, - "example": { + "type": "object", + "title": "Collection of Pets", + "properties": { + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/com.example.odata.Pet" + } + }, + "@count": { + "$ref": "#/components/schemas/count" + } + } + } + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + }, + "post": { + "summary": "Add new entity to Pets", + "tags": [ + "Pets" + ], + "requestBody": { + "required": true, + "description": "New entity", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.Pet~create" + } + } + } + }, + "responses": { + "201": { + "description": "Created entity", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.Pet" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/Pets/{id}": { + "parameters": [ + { + "description": "Key: id", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807, + "nullable": false + } + } + ], + "get": { + "summary": "Get entity from Pets by key", + "tags": [ + "Pets" + ], + "parameters": [ + { + "name": "select", + "in": "query", + "description": "Select properties to be returned, see [OData Select](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionselect)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "*", + "id", + "passenger_id", + "name", + "type" + ] + } + } + }, + { + "name": "expand", + "in": "query", + "description": "Expand related entities, see [OData Expand](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionexpand)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "passenger" + ] + } + } + } + ], + "responses": { + "200": { + "description": "Retrieved entity", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.Pet" + } + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + }, + "patch": { + "summary": "Update entity in Pets", + "tags": [ + "Pets" + ], + "requestBody": { + "description": "New property values", + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.Pet~update" + } + } + } + }, + "responses": { + "200": { + "$ref": "#/components/schemas/com.example.odata.Pet" + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + }, + "delete": { + "summary": "Delete entity from Pets", + "tags": [ + "Pets" + ], + "responses": { + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/Pets/{id}/passenger": { + "parameters": [ + { + "description": "Key: id", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807, + "nullable": false + } + } + ], + "get": { + "summary": "Get entities from related Passengers", + "tags": [ + "Passengers", + "Pets" + ], + "parameters": [ + { + "name": "select", + "in": "query", + "description": "Select properties to be returned, see [OData Select](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionselect)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "*", + "id", + "flight_id", + "name" + ] + } + } + }, + { + "$ref": "#/components/parameters/count" + }, + { + "name": "expand", + "in": "query", + "description": "Expand related entities, see [OData Expand](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionexpand)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "pets", + "flight", + "originAirport", + "destinationAirport" + ] + } + } + }, + { + "$ref": "#/components/parameters/filter" + }, + { + "$ref": "#/components/parameters/search" + }, + { + "$ref": "#/components/parameters/top" + }, + { + "$ref": "#/components/parameters/skip" + }, + { + "name": "orderby", + "in": "query", + "description": "Order items by property values, see [OData Sorting](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionorderby)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "id", + "id desc", + "flight_id", + "flight_id desc", + "name", + "name desc" + ] + } + } + } + ], + "responses": { + "200": { + "description": "Retrieved entities", + "content": { + "application/json": { + "schema": { + "type": "object", + "title": "Collection of Passengers", + "properties": { + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/com.example.odata.Passenger" + } + }, + "@count": { + "$ref": "#/components/schemas/count" + } + } + } + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + }, + "post": { + "summary": "Add new entity to related Passengers", + "tags": [ + "Passengers", + "Pets" + ], + "requestBody": { + "required": true, + "description": "New entity", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.Passenger~create" + } + } + } + }, + "responses": { + "201": { + "description": "Created entity", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.Passenger" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { "responses": [ { "id": "0", @@ -3089,6 +3685,73 @@ } } }, + "com.example.odata.Pet": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807, + "nullable": false + }, + "passenger_id": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647, + "nullable": true + }, + "name": { + "type": "string", + "nullable": true + }, + "type": { + "type": "string", + "nullable": true + } + } + }, + "com.example.odata.Pet~create": { + "type": "object", + "properties": { + "passenger_id": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647, + "nullable": true + }, + "name": { + "type": "string", + "nullable": true + }, + "type": { + "type": "string", + "nullable": true + } + } + }, + "com.example.odata.Pet~update": { + "type": "object", + "properties": { + "passenger_id": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647, + "nullable": true + }, + "name": { + "type": "string", + "nullable": true + }, + "type": { + "type": "string", + "nullable": true + } + } + }, "Edm.ComplexType": { "type": "object" }, diff --git a/tests/Unit/Eloquent/__snapshots__/EloquentTest__test_update__3.yml b/tests/Unit/Eloquent/__snapshots__/EloquentTest__test_update__3.yml index e6223c240..ee26a8df9 100644 --- a/tests/Unit/Eloquent/__snapshots__/EloquentTest__test_update__3.yml +++ b/tests/Unit/Eloquent/__snapshots__/EloquentTest__test_update__3.yml @@ -1,5 +1,5 @@ airports: - - { id: '1', name: Eloquent, code: efo, construction_date: null, sam_datetime: null, open_time: null, review_score: null, is_big: null, country_id: null } + - { id: 1, name: Eloquent, code: efo, construction_date: null, sam_datetime: null, open_time: null, review_score: null, is_big: null, country_id: null } countries: { } flights: { } passengers: { } diff --git a/tests/Unit/Eloquent/__snapshots__/OperationTest__test_op1__1.json b/tests/Unit/Eloquent/__snapshots__/OperationTest__test_op1__1.json new file mode 100644 index 000000000..fe3f343d5 --- /dev/null +++ b/tests/Unit/Eloquent/__snapshots__/OperationTest__test_op1__1.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.String", + "value": "Heathrow" +} diff --git a/tests/Unit/Eloquent/__snapshots__/OperationTest__test_op2__1.json b/tests/Unit/Eloquent/__snapshots__/OperationTest__test_op2__1.json new file mode 100644 index 000000000..38778dd9d --- /dev/null +++ b/tests/Unit/Eloquent/__snapshots__/OperationTest__test_op2__1.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.String", + "value": "olhr" +} diff --git a/tests/Unit/Modify/__snapshots__/CreateTest__test_create__3.yml b/tests/Unit/Modify/__snapshots__/CreateTest__test_create__3.yml index d9ca80f77..ae5124281 100644 --- a/tests/Unit/Modify/__snapshots__/CreateTest__test_create__3.yml +++ b/tests/Unit/Modify/__snapshots__/CreateTest__test_create__3.yml @@ -1,18 +1,18 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } countries: { } flights: - - { id: '1', origin: lhr, destination: lax, gate: null, duration: '41100.0' } - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } - - { id: '4', origin: lhr, destination: null, gate: null, duration: null } + - { id: 1, origin: lhr, destination: lax, gate: null, duration: 41100 } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } + - { id: 4, origin: lhr, destination: null, gate: null, duration: null } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } pets: { } diff --git a/tests/Unit/Modify/__snapshots__/CreateTest__test_create_content_type_error__2.yml b/tests/Unit/Modify/__snapshots__/CreateTest__test_create_content_type_error__2.yml index 762cf2c16..7aabfee2d 100644 --- a/tests/Unit/Modify/__snapshots__/CreateTest__test_create_content_type_error__2.yml +++ b/tests/Unit/Modify/__snapshots__/CreateTest__test_create_content_type_error__2.yml @@ -1,17 +1,17 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } countries: { } flights: - - { id: '1', origin: lhr, destination: lax, gate: null, duration: '41100.0' } - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } + - { id: 1, origin: lhr, destination: lax, gate: null, duration: 41100 } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } pets: { } diff --git a/tests/Unit/Modify/__snapshots__/CreateTest__test_create_deep__3.yml b/tests/Unit/Modify/__snapshots__/CreateTest__test_create_deep__3.yml index 429a7f20a..70cbb7bb5 100644 --- a/tests/Unit/Modify/__snapshots__/CreateTest__test_create_deep__3.yml +++ b/tests/Unit/Modify/__snapshots__/CreateTest__test_create_deep__3.yml @@ -1,21 +1,21 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } countries: { } flights: - - { id: '1', origin: lhr, destination: lax, gate: null, duration: '41100.0' } - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } - - { id: '4', origin: lhr, destination: sfo, gate: null, duration: null } + - { id: 1, origin: lhr, destination: lax, gate: null, duration: 41100 } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } + - { id: 4, origin: lhr, destination: sfo, gate: null, duration: null } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } - - { id: '6', flight_id: '4', name: Alice } - - { id: '7', flight_id: '4', name: Bob } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } + - { id: 6, flight_id: 4, name: Alice } + - { id: 7, flight_id: 4, name: Bob } pets: - - { id: '1', passenger_id: '6', name: Sparkles, type: dog } + - { id: 1, passenger_id: 6, name: Sparkles, type: dog } diff --git a/tests/Unit/Modify/__snapshots__/CreateTest__test_create_deep_metadata__6.yml b/tests/Unit/Modify/__snapshots__/CreateTest__test_create_deep_metadata__6.yml index 429a7f20a..70cbb7bb5 100644 --- a/tests/Unit/Modify/__snapshots__/CreateTest__test_create_deep_metadata__6.yml +++ b/tests/Unit/Modify/__snapshots__/CreateTest__test_create_deep_metadata__6.yml @@ -1,21 +1,21 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } countries: { } flights: - - { id: '1', origin: lhr, destination: lax, gate: null, duration: '41100.0' } - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } - - { id: '4', origin: lhr, destination: sfo, gate: null, duration: null } + - { id: 1, origin: lhr, destination: lax, gate: null, duration: 41100 } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } + - { id: 4, origin: lhr, destination: sfo, gate: null, duration: null } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } - - { id: '6', flight_id: '4', name: Alice } - - { id: '7', flight_id: '4', name: Bob } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } + - { id: 6, flight_id: 4, name: Alice } + - { id: 7, flight_id: 4, name: Bob } pets: - - { id: '1', passenger_id: '6', name: Sparkles, type: dog } + - { id: 1, passenger_id: 6, name: Sparkles, type: dog } diff --git a/tests/Unit/Modify/__snapshots__/CreateTest__test_create_entity_cannot_modify_existing_related_entities__2.yml b/tests/Unit/Modify/__snapshots__/CreateTest__test_create_entity_cannot_modify_existing_related_entities__2.yml index 762cf2c16..7aabfee2d 100644 --- a/tests/Unit/Modify/__snapshots__/CreateTest__test_create_entity_cannot_modify_existing_related_entities__2.yml +++ b/tests/Unit/Modify/__snapshots__/CreateTest__test_create_entity_cannot_modify_existing_related_entities__2.yml @@ -1,17 +1,17 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } countries: { } flights: - - { id: '1', origin: lhr, destination: lax, gate: null, duration: '41100.0' } - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } + - { id: 1, origin: lhr, destination: lax, gate: null, duration: 41100 } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } pets: { } diff --git a/tests/Unit/Modify/__snapshots__/CreateTest__test_create_entity_with_existing_related_entities__3.yml b/tests/Unit/Modify/__snapshots__/CreateTest__test_create_entity_with_existing_related_entities__3.yml index b47de6a6c..8a06f37ad 100644 --- a/tests/Unit/Modify/__snapshots__/CreateTest__test_create_entity_with_existing_related_entities__3.yml +++ b/tests/Unit/Modify/__snapshots__/CreateTest__test_create_entity_with_existing_related_entities__3.yml @@ -1,18 +1,18 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } countries: { } flights: - - { id: '1', origin: lhr, destination: lax, gate: null, duration: '41100.0' } - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } - - { id: '4', origin: sfo, destination: lhr, gate: null, duration: null } + - { id: 1, origin: lhr, destination: lax, gate: null, duration: 41100 } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } + - { id: 4, origin: sfo, destination: lhr, gate: null, duration: null } passengers: - - { id: '1', flight_id: '4', name: 'Anne Arbor' } - - { id: '2', flight_id: '4', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } + - { id: 1, flight_id: 4, name: 'Anne Arbor' } + - { id: 2, flight_id: 4, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } pets: { } diff --git a/tests/Unit/Modify/__snapshots__/CreateTest__test_create_ref__3.yml b/tests/Unit/Modify/__snapshots__/CreateTest__test_create_ref__3.yml index d9ca80f77..ae5124281 100644 --- a/tests/Unit/Modify/__snapshots__/CreateTest__test_create_ref__3.yml +++ b/tests/Unit/Modify/__snapshots__/CreateTest__test_create_ref__3.yml @@ -1,18 +1,18 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } countries: { } flights: - - { id: '1', origin: lhr, destination: lax, gate: null, duration: '41100.0' } - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } - - { id: '4', origin: lhr, destination: null, gate: null, duration: null } + - { id: 1, origin: lhr, destination: lax, gate: null, duration: 41100 } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } + - { id: 4, origin: lhr, destination: null, gate: null, duration: null } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } pets: { } diff --git a/tests/Unit/Modify/__snapshots__/CreateTest__test_create_related_entity__4.yml b/tests/Unit/Modify/__snapshots__/CreateTest__test_create_related_entity__4.yml index c1782140b..b726b43d1 100644 --- a/tests/Unit/Modify/__snapshots__/CreateTest__test_create_related_entity__4.yml +++ b/tests/Unit/Modify/__snapshots__/CreateTest__test_create_related_entity__4.yml @@ -1,18 +1,18 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } countries: { } flights: - - { id: '1', origin: lhr, destination: lax, gate: null, duration: '41100.0' } - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } + - { id: 1, origin: lhr, destination: lax, gate: null, duration: 41100 } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } - - { id: '6', flight_id: '1', name: 'Henry Horse' } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } + - { id: 6, flight_id: 1, name: 'Henry Horse' } pets: { } diff --git a/tests/Unit/Modify/__snapshots__/CreateTest__test_create_return_minimal__2.yml b/tests/Unit/Modify/__snapshots__/CreateTest__test_create_return_minimal__2.yml index 2c0842ee3..2169be93e 100644 --- a/tests/Unit/Modify/__snapshots__/CreateTest__test_create_return_minimal__2.yml +++ b/tests/Unit/Modify/__snapshots__/CreateTest__test_create_return_minimal__2.yml @@ -1,18 +1,18 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } countries: { } flights: - - { id: '1', origin: lhr, destination: lax, gate: null, duration: '41100.0' } - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } - - { id: '4', origin: lhr, destination: lax, gate: null, duration: null } + - { id: 1, origin: lhr, destination: lax, gate: null, duration: 41100 } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } + - { id: 4, origin: lhr, destination: lax, gate: null, duration: null } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } pets: { } diff --git a/tests/Unit/Modify/__snapshots__/DeleteTest__test_delete__1.yml b/tests/Unit/Modify/__snapshots__/DeleteTest__test_delete__1.yml index bb3d126f2..fb2b72e44 100644 --- a/tests/Unit/Modify/__snapshots__/DeleteTest__test_delete__1.yml +++ b/tests/Unit/Modify/__snapshots__/DeleteTest__test_delete__1.yml @@ -1,16 +1,16 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } countries: { } flights: - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } pets: { } diff --git a/tests/Unit/Modify/__snapshots__/DeleteTest__test_delete_not_found__2.yml b/tests/Unit/Modify/__snapshots__/DeleteTest__test_delete_not_found__2.yml index 762cf2c16..7aabfee2d 100644 --- a/tests/Unit/Modify/__snapshots__/DeleteTest__test_delete_not_found__2.yml +++ b/tests/Unit/Modify/__snapshots__/DeleteTest__test_delete_not_found__2.yml @@ -1,17 +1,17 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } countries: { } flights: - - { id: '1', origin: lhr, destination: lax, gate: null, duration: '41100.0' } - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } + - { id: 1, origin: lhr, destination: lax, gate: null, duration: 41100 } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } pets: { } diff --git a/tests/Unit/Modify/__snapshots__/DeleteTest__test_delete_ref__1.yml b/tests/Unit/Modify/__snapshots__/DeleteTest__test_delete_ref__1.yml index bb3d126f2..fb2b72e44 100644 --- a/tests/Unit/Modify/__snapshots__/DeleteTest__test_delete_ref__1.yml +++ b/tests/Unit/Modify/__snapshots__/DeleteTest__test_delete_ref__1.yml @@ -1,16 +1,16 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } countries: { } flights: - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } pets: { } diff --git a/tests/Unit/Modify/__snapshots__/DeleteTest__test_validate_etag__2.yml b/tests/Unit/Modify/__snapshots__/DeleteTest__test_validate_etag__2.yml index bb3d126f2..fb2b72e44 100644 --- a/tests/Unit/Modify/__snapshots__/DeleteTest__test_validate_etag__2.yml +++ b/tests/Unit/Modify/__snapshots__/DeleteTest__test_validate_etag__2.yml @@ -1,16 +1,16 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } countries: { } flights: - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } pets: { } diff --git a/tests/Unit/Modify/__snapshots__/UpdateTest__test_any_etag__2.yml b/tests/Unit/Modify/__snapshots__/UpdateTest__test_any_etag__2.yml index 453b57a38..b3711d5fa 100644 --- a/tests/Unit/Modify/__snapshots__/UpdateTest__test_any_etag__2.yml +++ b/tests/Unit/Modify/__snapshots__/UpdateTest__test_any_etag__2.yml @@ -1,19 +1,19 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } countries: { } flights: - - { id: '1', origin: ooo, destination: lax, gate: null, duration: '41100.0' } - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } + - { id: 1, origin: ooo, destination: lax, gate: null, duration: 41100 } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } pets: - - { id: '1', passenger_id: null, name: Alice, type: null } - - { id: '2', passenger_id: null, name: Bob, type: null } + - { id: 1, passenger_id: null, name: Alice, type: null } + - { id: 2, passenger_id: null, name: Bob, type: null } diff --git a/tests/Unit/Modify/__snapshots__/UpdateTest__test_any_if_none_match__2.yml b/tests/Unit/Modify/__snapshots__/UpdateTest__test_any_if_none_match__2.yml index 8b83c417c..75b67210c 100644 --- a/tests/Unit/Modify/__snapshots__/UpdateTest__test_any_if_none_match__2.yml +++ b/tests/Unit/Modify/__snapshots__/UpdateTest__test_any_if_none_match__2.yml @@ -1,19 +1,19 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } countries: { } flights: - - { id: '1', origin: lhr, destination: lax, gate: null, duration: '41100.0' } - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } + - { id: 1, origin: lhr, destination: lax, gate: null, duration: 41100 } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } pets: - - { id: '1', passenger_id: null, name: Alice, type: null } - - { id: '2', passenger_id: null, name: Bob, type: null } + - { id: 1, passenger_id: null, name: Alice, type: null } + - { id: 2, passenger_id: null, name: Bob, type: null } diff --git a/tests/Unit/Modify/__snapshots__/UpdateTest__test_any_if_none_match_any__2.yml b/tests/Unit/Modify/__snapshots__/UpdateTest__test_any_if_none_match_any__2.yml index 453b57a38..b3711d5fa 100644 --- a/tests/Unit/Modify/__snapshots__/UpdateTest__test_any_if_none_match_any__2.yml +++ b/tests/Unit/Modify/__snapshots__/UpdateTest__test_any_if_none_match_any__2.yml @@ -1,19 +1,19 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } countries: { } flights: - - { id: '1', origin: ooo, destination: lax, gate: null, duration: '41100.0' } - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } + - { id: 1, origin: ooo, destination: lax, gate: null, duration: 41100 } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } pets: - - { id: '1', passenger_id: null, name: Alice, type: null } - - { id: '2', passenger_id: null, name: Bob, type: null } + - { id: 1, passenger_id: null, name: Alice, type: null } + - { id: 2, passenger_id: null, name: Bob, type: null } diff --git a/tests/Unit/Modify/__snapshots__/UpdateTest__test_any_if_none_match_failed__2.yml b/tests/Unit/Modify/__snapshots__/UpdateTest__test_any_if_none_match_failed__2.yml index 453b57a38..b3711d5fa 100644 --- a/tests/Unit/Modify/__snapshots__/UpdateTest__test_any_if_none_match_failed__2.yml +++ b/tests/Unit/Modify/__snapshots__/UpdateTest__test_any_if_none_match_failed__2.yml @@ -1,19 +1,19 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } countries: { } flights: - - { id: '1', origin: ooo, destination: lax, gate: null, duration: '41100.0' } - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } + - { id: 1, origin: ooo, destination: lax, gate: null, duration: 41100 } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } pets: - - { id: '1', passenger_id: null, name: Alice, type: null } - - { id: '2', passenger_id: null, name: Bob, type: null } + - { id: 1, passenger_id: null, name: Alice, type: null } + - { id: 2, passenger_id: null, name: Bob, type: null } diff --git a/tests/Unit/Modify/__snapshots__/UpdateTest__test_multiple_etag__2.yml b/tests/Unit/Modify/__snapshots__/UpdateTest__test_multiple_etag__2.yml index 453b57a38..b3711d5fa 100644 --- a/tests/Unit/Modify/__snapshots__/UpdateTest__test_multiple_etag__2.yml +++ b/tests/Unit/Modify/__snapshots__/UpdateTest__test_multiple_etag__2.yml @@ -1,19 +1,19 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } countries: { } flights: - - { id: '1', origin: ooo, destination: lax, gate: null, duration: '41100.0' } - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } + - { id: 1, origin: ooo, destination: lax, gate: null, duration: 41100 } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } pets: - - { id: '1', passenger_id: null, name: Alice, type: null } - - { id: '2', passenger_id: null, name: Bob, type: null } + - { id: 1, passenger_id: null, name: Alice, type: null } + - { id: 2, passenger_id: null, name: Bob, type: null } diff --git a/tests/Unit/Modify/__snapshots__/UpdateTest__test_update__2.yml b/tests/Unit/Modify/__snapshots__/UpdateTest__test_update__2.yml index 453b57a38..b3711d5fa 100644 --- a/tests/Unit/Modify/__snapshots__/UpdateTest__test_update__2.yml +++ b/tests/Unit/Modify/__snapshots__/UpdateTest__test_update__2.yml @@ -1,19 +1,19 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } countries: { } flights: - - { id: '1', origin: ooo, destination: lax, gate: null, duration: '41100.0' } - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } + - { id: 1, origin: ooo, destination: lax, gate: null, duration: 41100 } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } pets: - - { id: '1', passenger_id: null, name: Alice, type: null } - - { id: '2', passenger_id: null, name: Bob, type: null } + - { id: 1, passenger_id: null, name: Alice, type: null } + - { id: 2, passenger_id: null, name: Bob, type: null } diff --git a/tests/Unit/Modify/__snapshots__/UpdateTest__test_update__3.yml b/tests/Unit/Modify/__snapshots__/UpdateTest__test_update__3.yml index 453b57a38..b3711d5fa 100644 --- a/tests/Unit/Modify/__snapshots__/UpdateTest__test_update__3.yml +++ b/tests/Unit/Modify/__snapshots__/UpdateTest__test_update__3.yml @@ -1,19 +1,19 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } countries: { } flights: - - { id: '1', origin: ooo, destination: lax, gate: null, duration: '41100.0' } - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } + - { id: 1, origin: ooo, destination: lax, gate: null, duration: 41100 } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } pets: - - { id: '1', passenger_id: null, name: Alice, type: null } - - { id: '2', passenger_id: null, name: Bob, type: null } + - { id: 1, passenger_id: null, name: Alice, type: null } + - { id: 2, passenger_id: null, name: Bob, type: null } diff --git a/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_invalid_property__2.yml b/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_invalid_property__2.yml index 8b83c417c..75b67210c 100644 --- a/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_invalid_property__2.yml +++ b/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_invalid_property__2.yml @@ -1,19 +1,19 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } countries: { } flights: - - { id: '1', origin: lhr, destination: lax, gate: null, duration: '41100.0' } - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } + - { id: 1, origin: lhr, destination: lax, gate: null, duration: 41100 } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } pets: - - { id: '1', passenger_id: null, name: Alice, type: null } - - { id: '2', passenger_id: null, name: Bob, type: null } + - { id: 1, passenger_id: null, name: Alice, type: null } + - { id: 2, passenger_id: null, name: Bob, type: null } diff --git a/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_post__2.yml b/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_post__2.yml index 8b83c417c..75b67210c 100644 --- a/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_post__2.yml +++ b/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_post__2.yml @@ -1,19 +1,19 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } countries: { } flights: - - { id: '1', origin: lhr, destination: lax, gate: null, duration: '41100.0' } - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } + - { id: 1, origin: lhr, destination: lax, gate: null, duration: 41100 } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } pets: - - { id: '1', passenger_id: null, name: Alice, type: null } - - { id: '2', passenger_id: null, name: Bob, type: null } + - { id: 1, passenger_id: null, name: Alice, type: null } + - { id: 2, passenger_id: null, name: Bob, type: null } diff --git a/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_post_via_tunnel__2.yml b/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_post_via_tunnel__2.yml index 453b57a38..b3711d5fa 100644 --- a/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_post_via_tunnel__2.yml +++ b/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_post_via_tunnel__2.yml @@ -1,19 +1,19 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } countries: { } flights: - - { id: '1', origin: ooo, destination: lax, gate: null, duration: '41100.0' } - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } + - { id: 1, origin: ooo, destination: lax, gate: null, duration: 41100 } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } pets: - - { id: '1', passenger_id: null, name: Alice, type: null } - - { id: '2', passenger_id: null, name: Bob, type: null } + - { id: 1, passenger_id: null, name: Alice, type: null } + - { id: 2, passenger_id: null, name: Bob, type: null } diff --git a/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_put__2.yml b/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_put__2.yml index 453b57a38..b3711d5fa 100644 --- a/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_put__2.yml +++ b/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_put__2.yml @@ -1,19 +1,19 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } countries: { } flights: - - { id: '1', origin: ooo, destination: lax, gate: null, duration: '41100.0' } - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } + - { id: 1, origin: ooo, destination: lax, gate: null, duration: 41100 } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } pets: - - { id: '1', passenger_id: null, name: Alice, type: null } - - { id: '2', passenger_id: null, name: Bob, type: null } + - { id: 1, passenger_id: null, name: Alice, type: null } + - { id: 2, passenger_id: null, name: Bob, type: null } diff --git a/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_ref__2.yml b/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_ref__2.yml index 453b57a38..b3711d5fa 100644 --- a/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_ref__2.yml +++ b/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_ref__2.yml @@ -1,19 +1,19 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } countries: { } flights: - - { id: '1', origin: ooo, destination: lax, gate: null, duration: '41100.0' } - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } + - { id: 1, origin: ooo, destination: lax, gate: null, duration: 41100 } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } pets: - - { id: '1', passenger_id: null, name: Alice, type: null } - - { id: '2', passenger_id: null, name: Bob, type: null } + - { id: 1, passenger_id: null, name: Alice, type: null } + - { id: 2, passenger_id: null, name: Bob, type: null } diff --git a/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_related__2.yml b/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_related__2.yml index faf181d0d..6c95de80a 100644 --- a/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_related__2.yml +++ b/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_related__2.yml @@ -1,19 +1,19 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } countries: { } flights: - - { id: '1', origin: lhr, destination: lax, gate: null, duration: '41100.0' } - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } + - { id: 1, origin: lhr, destination: lax, gate: null, duration: 41100 } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } passengers: - - { id: '1', flight_id: '1', name: 'Zooey Zamblo' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } + - { id: 1, flight_id: 1, name: 'Zooey Zamblo' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } pets: - - { id: '1', passenger_id: '1', name: Alice, type: null } - - { id: '3', passenger_id: '1', name: Delta, type: null } + - { id: 1, passenger_id: 1, name: Alice, type: null } + - { id: 3, passenger_id: 1, name: Delta, type: null } diff --git a/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_related_missing__3.yml b/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_related_missing__3.yml index 8b83c417c..75b67210c 100644 --- a/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_related_missing__3.yml +++ b/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_related_missing__3.yml @@ -1,19 +1,19 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } countries: { } flights: - - { id: '1', origin: lhr, destination: lax, gate: null, duration: '41100.0' } - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } + - { id: 1, origin: lhr, destination: lax, gate: null, duration: 41100 } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } pets: - - { id: '1', passenger_id: null, name: Alice, type: null } - - { id: '2', passenger_id: null, name: Bob, type: null } + - { id: 1, passenger_id: null, name: Alice, type: null } + - { id: 2, passenger_id: null, name: Bob, type: null } diff --git a/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_removed_changed__3.yml b/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_removed_changed__3.yml index 8b83c417c..75b67210c 100644 --- a/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_removed_changed__3.yml +++ b/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_removed_changed__3.yml @@ -1,19 +1,19 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } countries: { } flights: - - { id: '1', origin: lhr, destination: lax, gate: null, duration: '41100.0' } - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } + - { id: 1, origin: lhr, destination: lax, gate: null, duration: 41100 } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } pets: - - { id: '1', passenger_id: null, name: Alice, type: null } - - { id: '2', passenger_id: null, name: Bob, type: null } + - { id: 1, passenger_id: null, name: Alice, type: null } + - { id: 2, passenger_id: null, name: Bob, type: null } diff --git a/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_return_minimal__2.yml b/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_return_minimal__2.yml index 453b57a38..b3711d5fa 100644 --- a/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_return_minimal__2.yml +++ b/tests/Unit/Modify/__snapshots__/UpdateTest__test_update_return_minimal__2.yml @@ -1,19 +1,19 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } countries: { } flights: - - { id: '1', origin: ooo, destination: lax, gate: null, duration: '41100.0' } - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } + - { id: 1, origin: ooo, destination: lax, gate: null, duration: 41100 } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } pets: - - { id: '1', passenger_id: null, name: Alice, type: null } - - { id: '2', passenger_id: null, name: Bob, type: null } + - { id: 1, passenger_id: null, name: Alice, type: null } + - { id: 2, passenger_id: null, name: Bob, type: null } diff --git a/tests/Unit/Modify/__snapshots__/UpdateTest__test_validate_etag__4.yml b/tests/Unit/Modify/__snapshots__/UpdateTest__test_validate_etag__4.yml index 453b57a38..b3711d5fa 100644 --- a/tests/Unit/Modify/__snapshots__/UpdateTest__test_validate_etag__4.yml +++ b/tests/Unit/Modify/__snapshots__/UpdateTest__test_validate_etag__4.yml @@ -1,19 +1,19 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } countries: { } flights: - - { id: '1', origin: ooo, destination: lax, gate: null, duration: '41100.0' } - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } + - { id: 1, origin: ooo, destination: lax, gate: null, duration: 41100 } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } pets: - - { id: '1', passenger_id: null, name: Alice, type: null } - - { id: '2', passenger_id: null, name: Bob, type: null } + - { id: 1, passenger_id: null, name: Alice, type: null } + - { id: 2, passenger_id: null, name: Bob, type: null } diff --git a/tests/Unit/Operation/ActionTest.php b/tests/Unit/Operation/ActionTest.php index 3228a0a57..8d3705157 100644 --- a/tests/Unit/Operation/ActionTest.php +++ b/tests/Unit/Operation/ActionTest.php @@ -2,28 +2,44 @@ namespace Flat3\Lodata\Tests\Unit\Operation; +use Carbon\CarbonImmutable; use Flat3\Lodata\Controller\Response; use Flat3\Lodata\Controller\Transaction; use Flat3\Lodata\Entity; use Flat3\Lodata\EntitySet; use Flat3\Lodata\Facades\Lodata; -use Flat3\Lodata\Interfaces\Operation\ActionInterface; use Flat3\Lodata\Operation; use Flat3\Lodata\Tests\Request; use Flat3\Lodata\Tests\TestCase; +use Flat3\Lodata\Type\Binary; +use Flat3\Lodata\Type\Boolean; +use Flat3\Lodata\Type\Byte; +use Flat3\Lodata\Type\Date; +use Flat3\Lodata\Type\DateTimeOffset; +use Flat3\Lodata\Type\Decimal; +use Flat3\Lodata\Type\Double; +use Flat3\Lodata\Type\Duration; +use Flat3\Lodata\Type\Guid; +use Flat3\Lodata\Type\Int16; use Flat3\Lodata\Type\Int32; +use Flat3\Lodata\Type\Int64; +use Flat3\Lodata\Type\SByte; +use Flat3\Lodata\Type\Single; use Flat3\Lodata\Type\String_; +use Flat3\Lodata\Type\TimeOfDay; +use Flat3\Lodata\Type\UInt16; +use Flat3\Lodata\Type\UInt32; +use Flat3\Lodata\Type\UInt64; class ActionTest extends TestCase { public function test_get_not_allowed() { - Lodata::add(new class('exa1') extends Operation implements ActionInterface { - public function invoke(): String_ - { - return new String_('hello'); - } + $exa1 = new Operation\Action('exa1'); + $exa1->setCallable(function (): String_ { + return new String_('hello'); }); + Lodata::add($exa1); $this->assertMethodNotAllowed( (new Request) @@ -33,12 +49,11 @@ public function invoke(): String_ public function test_callback() { - Lodata::add(new class('exa1') extends Operation implements ActionInterface { - public function invoke(): String_ - { - return new String_('hello'); - } + $exa1 = new Operation\Action('exa1'); + $exa1->setCallable(function (): String_ { + return new String_('hello'); }); + Lodata::add($exa1); $this->assertJsonResponse( (new Request) @@ -49,12 +64,11 @@ public function invoke(): String_ public function test_service_document() { - Lodata::add(new class('exa1') extends Operation implements ActionInterface { - public function invoke(): String_ - { - return new String_('hello'); - } + $exa1 = new Operation\Action('exa1'); + $exa1->setCallable(function (): String_ { + return new String_('hello'); }); + Lodata::add($exa1); $this->assertJsonResponse( (new Request) @@ -71,12 +85,11 @@ public function test_callback_entity() public function test_no_composition() { - Lodata::add(new class('textv1') extends Operation implements ActionInterface { - public function invoke(): Int32 - { - return new Int32(3); - } + $textv1 = new Operation\Action('textv1'); + $textv1->setCallable(function (): Int32 { + return new Int32(3); }); + Lodata::add($textv1); $this->assertBadRequest( (new Request) @@ -87,12 +100,10 @@ public function invoke(): Int32 public function test_void_callback() { - Lodata::add(new class('textv1') extends Operation implements ActionInterface { - public function invoke(): void - { - - } + $textv1 = new Operation\Action('textv1'); + $textv1->setCallable(function (): void { }); + Lodata::add($textv1); $this->assertNoContent( (new Request) @@ -103,13 +114,10 @@ public function invoke(): void public function test_default_null_callback() { - Lodata::add(new class('textv1') extends Operation implements ActionInterface { - public function invoke() - { - - } + $textv1 = new Operation\Action('textv1'); + $textv1->setCallable(function () { }); - + Lodata::add($textv1); $this->assertNoContent( (new Request) @@ -120,12 +128,11 @@ public function invoke() public function test_explicit_null_callback() { - Lodata::add(new class('textv1') extends Operation implements ActionInterface { - public function invoke() - { - return null; - } + $textv1 = new Operation\Action('textv1'); + $textv1->setCallable(function () { + return null; }); + Lodata::add($textv1); $this->assertNoContent( (new Request) @@ -138,16 +145,40 @@ public function test_bound() { $this->withFlightModel(); - Lodata::add((new class('aa1') extends Operation implements ActionInterface { - public function invoke(Entity $airport): Entity - { - return $airport; - } - })->setBindingParameterName('airport')->setReturnType(Lodata::getEntityType('airport'))); + $aa1 = new Operation\Action('aa1'); + $aa1->setCallable(function (Entity $airport): Entity { + return $airport; + }); + $aa1->setBindingParameterName('airport'); + $aa1->setReturnType(Lodata::getEntityType('airport')); + Lodata::add($aa1); + + $this->assertJsonResponse( + (new Request) + ->post() + ->path('/airports(1)/aa1') + ); + } + + public function test_bound_with_parameters() + { + $this->withFlightModel(); + + $aa1 = new Operation\Action('aa1'); + $aa1->setCallable(function (Entity $airport, string $a): string { + return $airport['code']->getPrimitiveValue().$a; + }); + $aa1->setBindingParameterName('airport'); + Lodata::add($aa1); $this->assertJsonResponse( (new Request) ->post() + ->body( + [ + 'a' => 'world' + ] + ) ->path('/airports(1)/aa1') ); } @@ -156,17 +187,17 @@ public function test_create() { $this->withFlightModel(); - Lodata::add((new class('aa1') extends Operation implements ActionInterface { - public function invoke(EntitySet $airports, Transaction $transaction): Entity - { - $transaction->getResponse()->setStatusCode(Response::HTTP_CREATED); + $aa1 = new Operation\Action('aa1'); + $aa1->setCallable(function (EntitySet $airports, Transaction $transaction): Entity { + $transaction->getResponse()->setStatusCode(Response::HTTP_CREATED); - $entity = $airports->newEntity(); - $entity->setEntityId(4); + $entity = $airports->newEntity(); + $entity->setEntityId(4); - return $entity; - } - })->setReturnType(Lodata::getEntityType('airport'))); + return $entity; + }); + $aa1->setReturnType(Lodata::getEntityType('airport')); + Lodata::add($aa1); $this->assertJsonResponse( (new Request) @@ -178,12 +209,11 @@ public function invoke(EntitySet $airports, Transaction $transaction): Entity public function test_parameters() { - Lodata::add(new class('aa1') extends Operation implements ActionInterface { - public function invoke(Int32 $a, Int32 $b): Int32 - { - return new Int32($a->get() + $b->get()); - } + $aa1 = new Operation\Action('aa1'); + $aa1->setCallable(function (Int32 $a, Int32 $b): Int32 { + return new Int32($a->get() + $b->get()); }); + Lodata::add($aa1); $this->assertJsonResponse( (new Request) @@ -198,12 +228,11 @@ public function invoke(Int32 $a, Int32 $b): Int32 public function test_prefers_no_results() { - Lodata::add(new class('aa1') extends Operation implements ActionInterface { - public function invoke(): Int32 - { - return new Int32(99); - } + $aa1 = new Operation\Action('aa1'); + $aa1->setCallable(function (int $a, int $b): Int32 { + return new Int32(99); }); + Lodata::add($aa1); $this->assertNoContent( (new Request) @@ -219,12 +248,11 @@ public function invoke(): Int32 public function test_parameters_invalid_body_string() { - Lodata::add(new class('aa1') extends Operation implements ActionInterface { - public function invoke(Int32 $a, Int32 $b): Int32 - { - return new Int32($a->get() + $b->get()); - } + $aa1 = new Operation\Action('aa1'); + $aa1->setCallable(function (Int32 $a, Int32 $b): Int32 { + return new Int32($a->get() + $b->get()); }); + Lodata::add($aa1); $this->assertNotAcceptable( (new Request) @@ -238,12 +266,11 @@ public function test_parameters_invalid_body_array() { $this->withFlightModel(); - Lodata::add(new class('aa1') extends Operation implements ActionInterface { - public function invoke(Int32 $a, Int32 $b): Int32 - { - return new Int32($a->get() + $b->get()); - } + $aa1 = new Operation\Action('aa1'); + $aa1->setCallable(function (Int32 $a, Int32 $b): Int32 { + return new Int32($a->get() + $b->get()); }); + Lodata::add($aa1); $this->assertBadRequest( (new Request) @@ -256,12 +283,11 @@ public function invoke(Int32 $a, Int32 $b): Int32 public function test_null_typed_callback() { - Lodata::add(new class('booleanv1') extends Operation implements ActionInterface { - public function invoke(): ?bool - { - return null; - } + $booleanv1 = new Operation\Action('booleanv1'); + $booleanv1->setCallable(function (): ?bool { + return null; }); + Lodata::add($booleanv1); $this->assertMetadataDocuments(); @@ -271,4 +297,404 @@ public function invoke(): ?bool ->path('/booleanv1()') ); } + + public function test_date_argument() + { + $datev1 = new Operation\Action('datev1'); + $datev1->setCallable(function (CarbonImmutable $dt): string { + return $dt->dayName; + }); + Lodata::add($datev1); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->post() + ->body([ + 'dt' => '2020-01-01T23:23:23+00:01' + ]) + ->path("/datev1") + ); + } + + public function test_odata_binary_argument() + { + $op = new Operation\Action('op'); + $op->setCallable(function (Binary $arg): Binary { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->post() + ->body([ + 'arg' => 'aGVsbG8gd29ybGQ=', + ]) + ->path("/op") + ); + } + + public function test_odata_boolean_argument() + { + $op = new Operation\Action('op'); + $op->setCallable(function (Boolean $arg): Boolean { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->post() + ->body([ + 'arg' => false, + ]) + ->path("/op") + ); + } + + public function test_odata_byte_argument() + { + $op = new Operation\Action('op'); + $op->setCallable(function (Byte $arg): Byte { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->post() + ->body([ + 'arg' => 4, + ]) + ->path("/op") + ); + } + + public function test_odata_date_argument() + { + $op = new Operation\Action('op'); + $op->setCallable(function (Date $arg): Date { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->post() + ->body([ + 'arg' => '2020-01-01', + ]) + ->path("/op") + ); + } + + public function test_odata_datetimeoffset_argument() + { + $op = new Operation\Action('op'); + $op->setCallable(function (DateTimeOffset $arg): DateTimeOffset { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->post() + ->body([ + 'arg' => '2020-01-01T23:23:23+00:01', + ]) + ->path("/op") + ); + } + + public function test_odata_decimal_argument() + { + $op = new Operation\Action('op'); + $op->setCallable(function (Decimal $arg): Decimal { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->post() + ->body([ + 'arg' => 3.14, + ]) + ->path("/op") + ); + } + + public function test_odata_double_argument() + { + $op = new Operation\Action('op'); + $op->setCallable(function (Double $arg): Double { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->post() + ->body([ + 'arg' => 3.14, + ]) + ->path("/op") + ); + } + + public function test_odata_duration_argument() + { + $op = new Operation\Action('op'); + $op->setCallable(function (Duration $arg): Duration { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->post() + ->body([ + 'arg' => 'P4DT6H4M45.121999999974S', + ]) + ->path("/op") + ); + } + + public function test_odata_guid_argument() + { + $op = new Operation\Action('op'); + $op->setCallable(function (Guid $arg): Guid { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->post() + ->body([ + 'arg' => '2D1B80E8-0DAD-4EE7-AB6F-AE9FEC896290', + ]) + ->path("/op") + ); + } + + public function test_odata_int16_argument() + { + $op = new Operation\Action('op'); + $op->setCallable(function (Int16 $arg): Int16 { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->post() + ->body([ + 'arg' => -32767, + ]) + ->path("/op") + ); + } + + public function test_odata_uint16_argument() + { + $op = new Operation\Action('op'); + $op->setCallable(function (UInt16 $arg): UInt16 { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->post() + ->body([ + 'arg' => 32767, + ]) + ->path("/op") + ); + } + + public function test_odata_int32_argument() + { + $op = new Operation\Action('op'); + $op->setCallable(function (Int32 $arg): Int32 { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->post() + ->body([ + 'arg' => -2147483647, + ]) + ->path("/op") + ); + } + + public function test_odata_uint32_argument() + { + $op = new Operation\Action('op'); + $op->setCallable(function (UInt32 $arg): UInt32 { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->post() + ->body([ + 'arg' => 2147483647, + ]) + ->path("/op") + ); + } + + public function test_odata_int64_argument() + { + $op = new Operation\Action('op'); + $op->setCallable(function (Int64 $arg): Int64 { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->post() + ->body([ + 'arg' => -9223372036854775807, + ]) + ->path("/op") + ); + } + + public function test_odata_uint64_argument() + { + $op = new Operation\Action('op'); + $op->setCallable(function (UInt64 $arg): UInt64 { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->post() + ->body([ + 'arg' => 9223372036854775807, + ]) + ->path("/op") + ); + } + + public function test_odata_sbyte_argument() + { + $op = new Operation\Action('op'); + $op->setCallable(function (SByte $arg): SByte { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->post() + ->body([ + 'arg' => 64, + ]) + ->path("/op") + ); + } + + public function test_odata_single_argument() + { + $op = new Operation\Action('op'); + $op->setCallable(function (Single $arg): Single { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->post() + ->body([ + 'arg' => -3.14, + ]) + ->path("/op") + ); + } + + public function test_odata_string_argument() + { + $op = new Operation\Action('op'); + $op->setCallable(function (String_ $arg): String_ { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->post() + ->body([ + 'arg' => 'hello, world!', + ]) + ->path("/op") + ); + } + + public function test_odata_timeofday_argument() + { + $op = new Operation\Action('op'); + $op->setCallable(function (TimeOfDay $arg): TimeOfDay { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->post() + ->body([ + 'arg' => '23:23:23', + ]) + ->path("/op") + ); + } } \ No newline at end of file diff --git a/tests/Unit/Operation/DiscoveryTest.php b/tests/Unit/Operation/DiscoveryTest.php new file mode 100644 index 000000000..3057ce430 --- /dev/null +++ b/tests/Unit/Operation/DiscoveryTest.php @@ -0,0 +1,90 @@ +markTestSkipped(); + } + + $this->withFlightDatabase(); + + Lodata::discover(Flight::class); + Lodata::discover(Service::class); + Lodata::discover(Passenger::class); + Lodata::discover(Pet::class); + + $instance = new Instance(); + $instance->a = 'c'; + Lodata::discover($instance); + } + + public function test_metadata() + { + $this->assertMetadataDocuments(); + } + + public function test_simple() + { + $this->assertJsonResponse( + (new Request) + ->path('/hello()') + ); + } + + public function test_identity() + { + $this->assertJsonResponse( + (new Request) + ->path("/identity(arg='hello')") + ); + } + + public function test_bind() + { + $this->assertJsonResponse( + (new Request) + ->path("/add(a=1,b=1)/increment") + ); + } + + public function test_action() + { + $this->assertNoContent( + (new Request) + ->post() + ->path('/exec()') + ); + } + + public function test_new_name() + { + $this->assertNoContent( + (new Request) + ->post() + ->path('/exec2()') + ); + } + + public function test_instance() + { + $this->assertJsonResponse( + (new Request) + ->path('/insarg()') + ); + } +} \ No newline at end of file diff --git a/tests/Unit/Operation/FunctionTest.php b/tests/Unit/Operation/FunctionTest.php index 7830268c1..c5d22fbe5 100644 --- a/tests/Unit/Operation/FunctionTest.php +++ b/tests/Unit/Operation/FunctionTest.php @@ -7,24 +7,39 @@ use Flat3\Lodata\Entity; use Flat3\Lodata\EntitySet; use Flat3\Lodata\Facades\Lodata; -use Flat3\Lodata\Interfaces\Operation\FunctionInterface; use Flat3\Lodata\Operation; use Flat3\Lodata\Tests\Data\Airport; use Flat3\Lodata\Tests\Request; use Flat3\Lodata\Tests\TestCase; +use Flat3\Lodata\Type\Binary; +use Flat3\Lodata\Type\Boolean; +use Flat3\Lodata\Type\Byte; +use Flat3\Lodata\Type\Date; +use Flat3\Lodata\Type\DateTimeOffset; +use Flat3\Lodata\Type\Decimal; +use Flat3\Lodata\Type\Double; +use Flat3\Lodata\Type\Duration; +use Flat3\Lodata\Type\Guid; +use Flat3\Lodata\Type\Int16; use Flat3\Lodata\Type\Int32; +use Flat3\Lodata\Type\Int64; +use Flat3\Lodata\Type\SByte; +use Flat3\Lodata\Type\Single; use Flat3\Lodata\Type\String_; +use Flat3\Lodata\Type\TimeOfDay; +use Flat3\Lodata\Type\UInt16; +use Flat3\Lodata\Type\UInt32; +use Flat3\Lodata\Type\UInt64; class FunctionTest extends TestCase { public function test_callback() { - Lodata::add(new class('exf1') extends Operation implements FunctionInterface { - function invoke(): String_ - { - return new String_('hello'); - } + $op = new Operation\Function_('exf1'); + $op->setCallable(function (): String_ { + return new String_('hello'); }); + Lodata::add($op); $this->assertJsonResponse( (new Request) @@ -34,12 +49,11 @@ function invoke(): String_ public function test_callback_no_parentheses() { - Lodata::add(new class('exf1') extends Operation implements FunctionInterface { - function invoke(): String_ - { - return new String_('hello'); - } + $op = new Operation\Function_('exf1'); + $op->setCallable(function (): String_ { + return new String_('hello'); }); + Lodata::add($op); $this->assertJsonResponse( (new Request) @@ -49,12 +63,11 @@ function invoke(): String_ public function test_service_document() { - Lodata::add(new class('exf1') extends Operation implements FunctionInterface { - function invoke(): String_ - { - return new String_('hello'); - } + $op = new Operation\Function_('exf1'); + $op->setCallable(function (): String_ { + return new String_('hello'); }); + Lodata::add($op); $this->assertJsonResponse( (new Request) @@ -64,16 +77,15 @@ function invoke(): String_ public function test_callback_entity() { $this->withFlightModel(); - - Lodata::add((new class('exf3') extends Operation implements FunctionInterface { - function invoke(String_ $code): Entity - { - $airport = new Airport(); - $airport->setType(Lodata::getEntityType('airport')); - $airport['code'] = $code->get(); - return $airport; - } - })->setReturnType(Lodata::getEntityType('airport'))); + $op = new Operation\Function_('exf3'); + $op->setCallable(function (String_ $code): Entity { + $airport = new Airport(); + $airport->setType(Lodata::getEntityType('airport')); + $airport['code'] = $code->get(); + return $airport; + }); + $op->setReturnType(Lodata::getEntityType('airport')); + Lodata::add($op); $this->assertJsonResponse( (new Request) @@ -85,12 +97,12 @@ public function test_callback_entity_set() { $this->withTextModel(); - Lodata::add((new class('textf1') extends Operation implements FunctionInterface { - public function invoke(EntitySet $texts): EntitySet - { - return $texts; - } - })->setReturnType(Lodata::getEntityType('text'))); + $op = new Operation\Function_('textf1'); + $op->setCallable(function (EntitySet $texts): EntitySet { + return $texts; + }); + $op->setReturnType(Lodata::getEntityType('text')); + Lodata::add($op); $this->assertJsonResponse( (new Request) @@ -108,6 +120,16 @@ public function test_with_arguments() ); } + public function test_with_invalid_argument() + { + $this->withMathFunctions(); + + $this->assertBadRequest( + (new Request) + ->path('/add(a=3,b=4,c=5)') + ); + } + public function test_with_argument_order() { $this->withMathFunctions(); @@ -172,12 +194,11 @@ public function test_with_implicit_parameter_aliases() public function test_with_implicit_parameter_alias_matching_system_query_option() { - Lodata::add(new class('add') extends Operation implements FunctionInterface { - public function invoke(Int32 $apply, Int32 $compute): Int32 - { - return new Int32($apply->get() + $compute->get()); - } + $add = new Operation\Function_('add'); + $add->setCallable(function (Int32 $apply, Int32 $compute): Int32 { + return new Int32($apply->get() + $compute->get()); }); + Lodata::add($add); $this->assertJsonResponse( (new Request) @@ -189,19 +210,18 @@ public function invoke(Int32 $apply, Int32 $compute): Int32 public function test_function_composition() { - Lodata::add(new class('identity') extends Operation implements FunctionInterface { - public function invoke(Int32 $i): Int32 - { - return new Int32($i->get()); - } + $identity = new Operation\Function_('identity'); + $identity->setCallable(function (Int32 $i): Int32 { + return new Int32($i->get()); }); + Lodata::add($identity); - Lodata::add((new class('increment') extends Operation implements FunctionInterface { - public function invoke(Int32 $i): Int32 - { - return new Int32($i->get() + 1); - } - })->setBindingParameterName('i')); + $increment = new Operation\Function_('increment'); + $increment->setCallable(function (Int32 $i): Int32 { + return new Int32($i->get() + 1); + }); + $increment->setBindingParameterName('i'); + Lodata::add($increment); $this->assertJsonResponse( (new Request) @@ -213,13 +233,13 @@ public function test_callback_modified_flight_entity_set() { $this->withFlightModel(); - Lodata::add((new class('ffn1') extends Operation implements FunctionInterface { - public function invoke(Transaction $transaction, EntitySet $flights): EntitySet - { - $transaction->getSelect()->setValue('origin'); - return $flights; - } - })->setReturnType(Lodata::getEntityType('flight'))); + $ffn1 = new Operation\Function_('ffn1'); + $ffn1->setCallable(function (Transaction $transaction, EntitySet $flights): EntitySet { + $transaction->getSelect()->setValue('origin'); + return $flights; + }); + $ffn1->setReturnType(Lodata::getEntityType('flight')); + Lodata::add($ffn1); $this->assertJsonResponse( (new Request) @@ -231,12 +251,13 @@ public function test_callback_bound_entity_set() { $this->withFlightModel(); - Lodata::add((new class('ffb1') extends Operation implements FunctionInterface { - public function invoke(EntitySet $flights): EntitySet - { - return $flights; - } - })->setBindingParameterName('flights')->setReturnType(Lodata::getEntityType('flight'))); + $ffb1 = new Operation\Function_('ffb1'); + $ffb1->setCallable(function (EntitySet $flights): EntitySet { + return $flights; + }); + $ffb1->setBindingParameterName('flights'); + $ffb1->setReturnType(Lodata::getEntityType('flight')); + Lodata::add($ffb1); $this->assertJsonResponse( (new Request) @@ -248,23 +269,25 @@ public function test_callback_bound_entity_set_with_filter() { $this->withFlightModel(); - Lodata::add((new class('sorter') extends Operation implements FunctionInterface { - public function invoke(String_ $field, EntitySet $airports): EntitySet - { - $result = new StaticEntitySet($airports->getType()); - $result->setIdentifier($airports->getIdentifier()); + $sorter = new Operation\Function_('sorter'); + $sorter->setCallable(function (String_ $field, EntitySet $airports): EntitySet { + $result = new StaticEntitySet($airports->getType()); + $result->setIdentifier($airports->getIdentifier()); - foreach ($airports->query() as $airport) { - $result[] = $airport; - } + foreach ($airports->query() as $airport) { + $result[] = $airport; + } - $result->sort(function (Entity $a1, Entity $a2) use ($field) { - return $a1[$field->get()]->getPrimitiveValue() <=> $a2[$field->get()]->getPrimitiveValue(); - }); + $result->sort(function (Entity $a1, Entity $a2) use ($field) { + return $a1[$field->get()]->getPrimitiveValue() <=> $a2[$field->get()]->getPrimitiveValue(); + }); - return $result; - } - })->setBindingParameterName('airports')->setReturnType(Lodata::getEntityType('airport'))); + return $result; + }); + + $sorter->setBindingParameterName('airports'); + $sorter->setReturnType(Lodata::getEntityType('airport')); + Lodata::add($sorter); $this->assertJsonResponse( (new Request) @@ -276,12 +299,13 @@ public function test_callback_bound_entity() { $this->withFlightModel(); - Lodata::add((new class('ffb1') extends Operation implements FunctionInterface { - public function invoke(Entity $flight): Entity - { - return $flight; - } - })->setBindingParameterName('flight')->setReturnType(Lodata::getEntityType('flight'))); + $ffb1 = new Operation\Function_('ffb1'); + $ffb1->setCallable(function (Entity $flight): Entity { + return $flight; + }); + $ffb1->setBindingParameterName('flight'); + $ffb1->setReturnType(Lodata::getEntityType('flight')); + Lodata::add($ffb1); $this->assertJsonResponse( (new Request) @@ -293,12 +317,12 @@ public function test_callback_bound_primitive() { $this->withFlightModel(); - Lodata::add((new class('ffb1') extends Operation implements FunctionInterface { - public function invoke(String_ $origin): String_ - { - return new String_(strtoupper($origin->get())); - } - })->setBindingParameterName('origin')); + $ffb1 = new Operation\Function_('ffb1'); + $ffb1->setCallable(function (String_ $origin): String_ { + return new String_(strtoupper($origin->get())); + }); + $ffb1->setBindingParameterName('origin'); + Lodata::add($ffb1); $this->assertJsonResponse( (new Request) @@ -306,13 +330,33 @@ public function invoke(String_ $origin): String_ ); } + public function test_callback_bound_internal_type() + { + $identity = new Operation\Function_('id'); + $identity->setCallable(function (int $i): int { + return $i; + }); + Lodata::add($identity); + + $increment = new Operation\Function_('incr'); + $increment->setCallable(function (int $a): int { + return $a + 1; + }); + $increment->setBindingParameterName('a'); + Lodata::add($increment); + + $this->assertJsonResponse( + (new Request) + ->path('/id(i=1)/incr') + ); + } + public function test_void_callback() { - Lodata::add(new class('textv1') extends Operation implements FunctionInterface { - public function invoke(): void - { - } + $textv1 = new Operation\Function_('textv1'); + $textv1->setCallable(function (): void { }); + Lodata::add($textv1); $this->assertInternalServerError( (new Request) @@ -322,11 +366,10 @@ public function invoke(): void public function test_default_null_callback() { - Lodata::add(new class('textv1') extends Operation implements FunctionInterface { - public function invoke() - { - } + $textv1 = new Operation\Function_('textv1'); + $textv1->setCallable(function () { }); + Lodata::add($textv1); $this->assertInternalServerError( (new Request) @@ -336,12 +379,11 @@ public function invoke() public function test_string_callback() { - Lodata::add(new class('stringv1') extends Operation implements FunctionInterface { - public function invoke(): string - { - return 'hello world'; - } + $stringv1 = new Operation\Function_('stringv1'); + $stringv1->setCallable(function (): string { + return 'hello world'; }); + Lodata::add($stringv1); $this->assertMetadataDocuments(); @@ -353,12 +395,11 @@ public function invoke(): string public function test_int_callback() { - Lodata::add(new class('intv1') extends Operation implements FunctionInterface { - public function invoke(): int - { - return 4; - } + $intv1 = new Operation\Function_('intv1'); + $intv1->setCallable(function (): int { + return 4; }); + Lodata::add($intv1); $this->assertMetadataDocuments(); @@ -370,12 +411,11 @@ public function invoke(): int public function test_float_callback() { - Lodata::add(new class('floatv1') extends Operation implements FunctionInterface { - public function invoke(): float - { - return 0.1; - } + $floatv1 = new Operation\Function_('floatv1'); + $floatv1->setCallable(function (): float { + return 0.1; }); + Lodata::add($floatv1); $this->assertMetadataDocuments(); @@ -387,12 +427,11 @@ public function invoke(): float public function test_boolean_callback() { - Lodata::add(new class('booleanv1') extends Operation implements FunctionInterface { - public function invoke(): bool - { - return true; - } + $booleanv1 = new Operation\Function_('booleanv1'); + $booleanv1->setCallable(function (): bool { + return true; }); + Lodata::add($booleanv1); $this->assertMetadataDocuments(); @@ -404,11 +443,10 @@ public function invoke(): bool public function test_bad_null_argument() { - Lodata::add(new class('textv1') extends Operation implements FunctionInterface { - public function invoke(String_ $a) - { - } + $textv1 = new Operation\Function_('textv1'); + $textv1->setCallable(function (String_ $a) { }); + Lodata::add($textv1); $this->assertBadRequest( (new Request) @@ -418,11 +456,10 @@ public function invoke(String_ $a) public function test_bad_argument_type() { - Lodata::add(new class('textv1') extends Operation implements FunctionInterface { - public function invoke(String_ $a) - { - } + $textv1 = new Operation\Function_('textv1'); + $textv1->setCallable(function (String_ $a) { }); + Lodata::add($textv1); $this->assertBadRequest( (new Request) @@ -432,12 +469,11 @@ public function invoke(String_ $a) public function test_string_argument() { - Lodata::add(new class('stringv1') extends Operation implements FunctionInterface { - public function invoke(string $arg): string - { - return $arg; - } + $stringv1 = new Operation\Function_('stringv1'); + $stringv1->setCallable(function (string $arg): string { + return $arg; }); + Lodata::add($stringv1); $this->assertMetadataDocuments(); @@ -449,12 +485,11 @@ public function invoke(string $arg): string public function test_int_argument() { - Lodata::add(new class('intv1') extends Operation implements FunctionInterface { - public function invoke(int $arg): int - { - return $arg; - } + $intv1 = new Operation\Function_('intv1'); + $intv1->setCallable(function (int $arg): int { + return $arg; }); + Lodata::add($intv1); $this->assertMetadataDocuments(); @@ -466,12 +501,11 @@ public function invoke(int $arg): int public function test_float_argument() { - Lodata::add(new class('floatv1') extends Operation implements FunctionInterface { - public function invoke(float $arg): float - { - return $arg; - } + $floatv1 = new Operation\Function_('floatv1'); + $floatv1->setCallable(function (float $arg): float { + return $arg; }); + Lodata::add($floatv1); $this->assertMetadataDocuments(); @@ -483,12 +517,11 @@ public function invoke(float $arg): float public function test_boolean_argument() { - Lodata::add(new class('booleanv1') extends Operation implements FunctionInterface { - public function invoke(bool $arg): bool - { - return $arg; - } + $booleanv1 = new Operation\Function_('booleanv1'); + $booleanv1->setCallable(function (bool $arg): bool { + return $arg; }); + Lodata::add($booleanv1); $this->assertMetadataDocuments(); @@ -500,12 +533,11 @@ public function invoke(bool $arg): bool public function test_null_argument() { - Lodata::add(new class('booleanv1') extends Operation implements FunctionInterface { - public function invoke(string $a, ?bool $arg, string $b): string - { - return $a.$b; - } + $booleanv1 = new Operation\Function_('booleanv1'); + $booleanv1->setCallable(function (string $a, ?bool $arg, string $b): string { + return $a.$b; }); + Lodata::add($booleanv1); $this->assertMetadataDocuments(); @@ -514,4 +546,308 @@ public function invoke(string $a, ?bool $arg, string $b): string ->path("/booleanv1(a='a',b='b')") ); } + + public function test_odata_binary_argument() + { + $op = new Operation\Function_('op'); + $op->setCallable(function (Binary $arg): Binary { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->path("/op(arg=aGVsbG8gd29ybGQ=)") + ); + } + + public function test_odata_boolean_argument() + { + $op = new Operation\Function_('op'); + $op->setCallable(function (Boolean $arg): Boolean { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->path("/op(arg=false)") + ); + } + + public function test_odata_byte_argument() + { + $op = new Operation\Function_('op'); + $op->setCallable(function (Byte $arg): Byte { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->path("/op(arg=4)") + ); + } + + public function test_odata_date_argument() + { + $op = new Operation\Function_('op'); + $op->setCallable(function (Date $arg): Date { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->path("/op(arg=2020-01-01)") + ); + } + + public function test_odata_datetimeoffset_argument() + { + $op = new Operation\Function_('op'); + $op->setCallable(function (DateTimeOffset $arg): DateTimeOffset { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->path("/op(arg=2020-01-01T23:23:23+00:01)") + ); + } + + public function test_odata_decimal_argument() + { + $op = new Operation\Function_('op'); + $op->setCallable(function (Decimal $arg): Decimal { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->path("/op(arg=3.14)") + ); + } + + public function test_odata_double_argument() + { + $op = new Operation\Function_('op'); + $op->setCallable(function (Double $arg): Double { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->path("/op(arg=3.14)") + ); + } + + public function test_odata_duration_argument() + { + $op = new Operation\Function_('op'); + $op->setCallable(function (Duration $arg): Duration { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->path("/op(arg=P4DT6H4M45.121999999974S)") + ); + } + + public function test_odata_guid_argument() + { + $op = new Operation\Function_('op'); + $op->setCallable(function (Guid $arg): Guid { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->path("/op(arg=2D1B80E8-0DAD-4EE7-AB6F-AE9FEC896290)") + ); + } + + public function test_odata_int16_argument() + { + $op = new Operation\Function_('op'); + $op->setCallable(function (Int16 $arg): Int16 { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->path("/op(arg=-32767)") + ); + } + + public function test_odata_uint16_argument() + { + $op = new Operation\Function_('op'); + $op->setCallable(function (UInt16 $arg): UInt16 { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->path("/op(arg=32767)") + ); + } + + public function test_odata_int32_argument() + { + $op = new Operation\Function_('op'); + $op->setCallable(function (Int32 $arg): Int32 { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->path("/op(arg=-2147483647)") + ); + } + + public function test_odata_uint32_argument() + { + $op = new Operation\Function_('op'); + $op->setCallable(function (UInt32 $arg): UInt32 { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->path("/op(arg=2147483647)") + ); + } + + public function test_odata_int64_argument() + { + $op = new Operation\Function_('op'); + $op->setCallable(function (Int64 $arg): Int64 { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->path("/op(arg=-9223372036854775807)") + ); + } + + public function test_odata_uint64_argument() + { + $op = new Operation\Function_('op'); + $op->setCallable(function (UInt64 $arg): UInt64 { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->path("/op(arg=9223372036854775807)") + ); + } + + public function test_odata_sbyte_argument() + { + $op = new Operation\Function_('op'); + $op->setCallable(function (SByte $arg): SByte { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->path("/op(arg=64)") + ); + } + + public function test_odata_single_argument() + { + $op = new Operation\Function_('op'); + $op->setCallable(function (Single $arg): Single { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->path("/op(arg=-3.14)") + ); + } + + public function test_odata_string_argument() + { + $op = new Operation\Function_('op'); + $op->setCallable(function (String_ $arg): String_ { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->path("/op(arg='hello, world!')") + ); + } + + public function test_odata_timeofday_argument() + { + $op = new Operation\Function_('op'); + $op->setCallable(function (TimeOfDay $arg): TimeOfDay { + return $arg; + }); + Lodata::add($op); + + $this->assertMetadataDocuments(); + + $this->assertJsonResponse( + (new Request) + ->path("/op(arg=23:23:23)") + ); + } } \ No newline at end of file diff --git a/tests/Unit/Operation/NamespaceTest.php b/tests/Unit/Operation/NamespaceTest.php new file mode 100644 index 000000000..784224d2e --- /dev/null +++ b/tests/Unit/Operation/NamespaceTest.php @@ -0,0 +1,35 @@ +markTestSkipped(); + } + + Lodata::discover(Math::class); + } + + public function test_metadata() + { + $this->assertMetadataDocuments(); + } + + public function test_add() + { + $this->assertJsonResponse( + (new Request) + ->path('/com.example.math.add(a=1,b=2)') + ); + } +} \ No newline at end of file diff --git a/tests/Unit/Operation/OperationTest.php b/tests/Unit/Operation/OperationTest.php index f7f38c78e..2565b83b9 100644 --- a/tests/Unit/Operation/OperationTest.php +++ b/tests/Unit/Operation/OperationTest.php @@ -3,10 +3,9 @@ namespace Flat3\Lodata\Tests\Unit\Operation; use Flat3\Lodata\EntitySet; -use Flat3\Lodata\Exception\Protocol\ProtocolException; use Flat3\Lodata\Facades\Lodata; -use Flat3\Lodata\Interfaces\Operation\FunctionInterface; use Flat3\Lodata\Operation; +use Flat3\Lodata\Tests\Operations\Service; use Flat3\Lodata\Tests\Request; use Flat3\Lodata\Tests\TestCase; use Flat3\Lodata\Type\Decimal; @@ -16,61 +15,130 @@ class OperationTest extends TestCase { + public function test_callback() + { + $op = new Operation\Function_('exf1'); + $op->setCallable(function (): String_ { + return new String_('hello'); + }); + Lodata::add($op); + + $this->assertJsonResponse( + (new Request) + ->path('/exf1()') + ); + } + + public function test_object_callback() + { + $op = new Operation\Function_('exf1'); + $op->setCallable([Service::class, 'hello']); + Lodata::add($op); + + $this->assertJsonResponse( + (new Request) + ->path('/exf1()') + ); + } + + public function test_instance_callback() + { + $op = new Operation\Function_('exf1'); + $c = new Service(); + $op->setCallable([$c, 'hello']); + Lodata::add($op); + + $this->assertJsonResponse( + (new Request) + ->path('/exf1()') + ); + } + + public function test_namespaced() + { + $op = new Operation\Function_('com.example.odata1.exf1'); + $op->setCallable(function (): String_ { + return new String_('hello'); + }); + Lodata::add($op); + + $this->assertJsonResponse( + (new Request) + ->path('/com.example.odata1.exf1()') + ); + + $this->assertNotFound( + (new Request) + ->path('/com.example.odata.exf1()') + ); + + $this->assertNotFound( + (new Request) + ->path('/exf1()') + ); + + $this->assertNotFound( + (new Request) + ->path('/com.example.odata2.exf1()') + ); + } + public function test_missing_invoke() { - try { - Lodata::add((new class('f1') extends Operation implements FunctionInterface { - })->setBindingParameterName('texts')); - } catch (ProtocolException $e) { - $this->assertProtocolExceptionSnapshot($e); - } + $op = new Operation\Function_('f1'); + Lodata::add($op); + + $this->assertInternalServerError( + (new Request) + ->path('/f1()') + ); } public function test_void_uses_string() { - Lodata::add((new class('f1') extends Operation implements FunctionInterface { - public function invoke() - { - return 'hello'; - } - })); + $op = new Operation\Function_('f1'); + $op->setCallable(function () { + return 'hello'; + }); + Lodata::add($op); $this->assertMetadataDocuments(); } public function test_binding_did_not_exist() { - try { - Lodata::add((new class('f1') extends Operation implements FunctionInterface { - function invoke(Int32 $taxts) - { - } - })->setBindingParameterName('texts')); - } catch (ProtocolException $e) { - $this->assertProtocolExceptionSnapshot($e); - } + $this->withNumberFunction(); + $op = new Operation\Function_('f1'); + $op->setCallable(function (?Int32 $taxts) { + return 42; + }); + $op->setBindingParameterName('texts'); + Lodata::add($op); + + $this->assertInternalServerError( + (new Request) + ->path('/number()/f1()') + ); } public function test_parameter_order_unbound() { - Lodata::add((new class('f1') extends Operation implements FunctionInterface { - function invoke(Int32 $a, Decimal $b): Int32 - { - return new Int32(0); - } - })); + $op = new Operation\Function_('f1'); + $op->setCallable(function (Int32 $a, Decimal $b): Int32 { + return new Int32(0); + }); + Lodata::add($op); $this->assertMetadataDocuments(); } public function test_parameter_order_bound() { - Lodata::add((new class('f1') extends Operation implements FunctionInterface { - function invoke(Int32 $a, Decimal $b): Int32 - { - return new Int32(0); - } - })->setBindingParameterName('b')); + $op = new Operation\Function_('f1'); + $op->setCallable(function (Int32 $a, Decimal $b): Int32 { + return new Int32(0); + })->setBindingParameterName('b'); + Lodata::add($op); $this->assertMetadataDocuments(); } @@ -79,12 +147,13 @@ public function test_parameter_bound_passthru() { $this->withFlightModel(); - Lodata::add((new class('f1') extends Operation implements FunctionInterface { - public function invoke(?Decimal $b, EntitySet $flights): EntitySet - { - return $flights; - } - })->setBindingParameterName('flights')->setReturnType(Lodata::getEntityType('flight'))); + $op = new Operation\Function_('f1'); + $op->setCallable(function (?Decimal $b, EntitySet $flights): EntitySet { + return $flights; + }) + ->setBindingParameterName('flights') + ->setReturnType(Lodata::getEntityType('flight')); + Lodata::add($op); $this->assertMetadataDocuments(); @@ -98,14 +167,15 @@ public function test_parameter_bound_modify() { $this->withFlightModel(); - Lodata::add((new class('f1') extends Operation implements FunctionInterface { - public function invoke(?Decimal $b, EntitySet $flights): Duration - { - $entity = $flights->query()->current(); - $duration = $entity['duration']; - return $duration->getValue(); - } - })->setBindingParameterName('flights')); + $op = new Operation\Function_('f1'); + $op->setCallable(function (?Decimal $b, EntitySet $flights): Duration { + $entity = $flights->query()->current(); + $duration = $entity['duration']; + return $duration->getValue(); + }); + $op->setBindingParameterName('flights'); + + Lodata::add($op); $this->assertMetadataDocuments(); @@ -119,12 +189,13 @@ public function test_parameter_bound_missing_binding() { $this->withFlightModel(); - Lodata::add((new class('f1') extends Operation implements FunctionInterface { - public function invoke(?Decimal $b, EntitySet $flights) - { - return $flights; - } - })->setBindingParameterName('flights')->setReturnType(Lodata::getEntityType('flight'))); + $op = new Operation\Function_('f1'); + $op->setCallable(function (?Decimal $b, EntitySet $flights) { + return $flights; + }); + $op->setBindingParameterName('flights'); + $op->setReturnType(Lodata::getEntityType('flight')); + Lodata::add($op); $this->assertBadRequest( (new Request) @@ -136,12 +207,13 @@ public function test_parameter_bound_binding_wrong_type() { $this->withFlightModel(); - Lodata::add((new class('f1') extends Operation implements FunctionInterface { - public function invoke(?Decimal $b, EntitySet $flights): EntitySet - { - return $flights; - } - })->setBindingParameterName('flights')->setReturnType(Lodata::getEntityType('flight'))); + $op = new Operation\Function_('f1'); + $op->setCallable(function (?Decimal $b, EntitySet $flights): EntitySet { + return $flights; + }); + $op->setBindingParameterName('flights'); + $op->setReturnType(Lodata::getEntityType('flight')); + Lodata::add($op); $this->assertBadRequest( (new Request) @@ -151,23 +223,36 @@ public function invoke(?Decimal $b, EntitySet $flights): EntitySet public function test_function_pipe() { - Lodata::add(new class('hello') extends Operation implements FunctionInterface { - public function invoke(): String_ - { - return new String_('hello'); - } + $hello = new Operation\Function_('hello'); + $hello->setCallable(function (): String_ { + return new String_('hello'); }); + Lodata::add($hello); - Lodata::add((new class('world') extends Operation implements FunctionInterface { - public function invoke(String_ $second): String_ - { - return new String_($second->get().' world'); - } - })->setBindingParameterName('second')); + $world = new Operation\Function_('world'); + $world->setCallable(function (String_ $second): String_ { + return new String_($second->get().' world'); + }); + $world->setBindingParameterName('second'); + Lodata::add($world); $this->assertJsonResponse( (new Request) ->path('hello()/world()') ); } + + public function test_malformed_args() + { + $op = new Operation\Function_('exf1'); + $op->setCallable(function (string $a): string { + return $a; + }); + Lodata::add($op); + + $this->assertBadRequest( + (new Request) + ->path('/exf1(a=') + ); + } } diff --git a/tests/Unit/Operation/Repository73Test.php b/tests/Unit/Operation/Repository73Test.php new file mode 100644 index 000000000..762d3be4d --- /dev/null +++ b/tests/Unit/Operation/Repository73Test.php @@ -0,0 +1,50 @@ +withFlightDatabase(); + $this->withFlightData(); + + Lodata::discoverEloquentModel(Airport::class); + $code = new Repository('code'); + $code->setCallable([RepositoryModel::class, 'code']); + $code->setBindingParameterName('airport'); + Lodata::add($code); + } + + public function test_metadata() + { + $this->assertMetadataDocuments(); + } + + public function test_code() + { + $this->assertJsonResponse( + (new Request) + ->path('/Airports/1/code') + ); + } + + public function test_code_args() + { + $this->assertJsonResponse( + (new Request) + ->path("/Airports/1/code(suffix='here')") + ); + } +} \ No newline at end of file diff --git a/tests/Unit/Operation/RepositoryTest.php b/tests/Unit/Operation/RepositoryTest.php new file mode 100644 index 000000000..84fd5c232 --- /dev/null +++ b/tests/Unit/Operation/RepositoryTest.php @@ -0,0 +1,50 @@ +markTestSkipped(); + } + + $this->withFlightDatabase(); + $this->withFlightData(); + + Lodata::discover(Airport::class); + Lodata::discover(Repository::class); + } + + public function test_metadata() + { + $this->assertMetadataDocuments(); + } + + public function test_code() + { + $this->assertJsonResponse( + (new Request) + ->path('/Airports/1/code') + ); + } + + public function test_code_args() + { + $this->assertJsonResponse( + (new Request) + ->path("/Airports/1/code(suffix='here')") + ); + } +} \ No newline at end of file diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_bound_with_parameters__1.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_bound_with_parameters__1.json new file mode 100644 index 000000000..4e944f86b --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_bound_with_parameters__1.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.String", + "value": "lhrworld" +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_date_argument__1.xml b/tests/Unit/Operation/__snapshots__/ActionTest__test_date_argument__1.xml new file mode 100644 index 000000000..a7b91d372 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_date_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_date_argument__2.yml b/tests/Unit/Operation/__snapshots__/ActionTest__test_date_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_date_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_date_argument__3.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_date_argument__3.json new file mode 100644 index 000000000..923f587b8 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_date_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "datev1Import": { + "$Action": "com.example.odata.datev1" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "datev1": { + "$Kind": "Action", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "dt", + "$Nullable": false, + "$Type": "Edm.DateTimeOffset" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.String", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_date_argument__4.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_date_argument__4.json new file mode 100644 index 000000000..3eca41ab6 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_date_argument__4.json @@ -0,0 +1,394 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/datev1": { + "post": { + "tags": [ + "Service Operations", + "datev1", + "dt" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "dt", + "schema": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$", + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.String" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_date_argument__5.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_date_argument__5.json new file mode 100644 index 000000000..41664d87b --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_date_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.String", + "value": "Wednesday" +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_binary_argument__1.xml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_binary_argument__1.xml new file mode 100644 index 000000000..f61afab9a --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_binary_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_binary_argument__2.yml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_binary_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_binary_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_binary_argument__3.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_binary_argument__3.json new file mode 100644 index 000000000..0ad10994a --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_binary_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Action": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Action", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.Binary" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.Binary", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_binary_argument__4.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_binary_argument__4.json new file mode 100644 index 000000000..b3875484b --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_binary_argument__4.json @@ -0,0 +1,394 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "post": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$", + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.Binary" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_binary_argument__5.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_binary_argument__5.json new file mode 100644 index 000000000..b8c7203ce --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_binary_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.Binary", + "value": "aGVsbG8gd29ybGQ=" +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_boolean_argument__1.xml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_boolean_argument__1.xml new file mode 100644 index 000000000..ffb98a1f5 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_boolean_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_boolean_argument__2.yml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_boolean_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_boolean_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_boolean_argument__3.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_boolean_argument__3.json new file mode 100644 index 000000000..0cf8a4ee0 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_boolean_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Action": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Action", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.Boolean" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.Boolean", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_boolean_argument__4.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_boolean_argument__4.json new file mode 100644 index 000000000..55d417c25 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_boolean_argument__4.json @@ -0,0 +1,392 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "post": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "boolean", + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.Boolean" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_boolean_argument__5.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_boolean_argument__5.json new file mode 100644 index 000000000..d823b92f8 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_boolean_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.Boolean", + "value": false +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_byte_argument__1.xml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_byte_argument__1.xml new file mode 100644 index 000000000..18cd8d960 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_byte_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_byte_argument__2.yml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_byte_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_byte_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_byte_argument__3.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_byte_argument__3.json new file mode 100644 index 000000000..81d700c03 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_byte_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Action": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Action", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.Byte" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.Byte", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_byte_argument__4.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_byte_argument__4.json new file mode 100644 index 000000000..c413e1f5c --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_byte_argument__4.json @@ -0,0 +1,395 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "post": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255, + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.Byte" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_byte_argument__5.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_byte_argument__5.json new file mode 100644 index 000000000..47713688c --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_byte_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.Byte", + "value": 4 +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_date_argument__1.xml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_date_argument__1.xml new file mode 100644 index 000000000..427782c83 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_date_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_date_argument__2.yml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_date_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_date_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_date_argument__3.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_date_argument__3.json new file mode 100644 index 000000000..128cdd66f --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_date_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Action": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Action", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.Date" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.Date", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_date_argument__4.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_date_argument__4.json new file mode 100644 index 000000000..d928472c2 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_date_argument__4.json @@ -0,0 +1,394 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "post": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$", + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.Date" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_date_argument__5.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_date_argument__5.json new file mode 100644 index 000000000..249938304 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_date_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.Date", + "value": "2020-01-01" +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_datetimeoffset_argument__1.xml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_datetimeoffset_argument__1.xml new file mode 100644 index 000000000..0ef15d7c7 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_datetimeoffset_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_datetimeoffset_argument__2.yml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_datetimeoffset_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_datetimeoffset_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_datetimeoffset_argument__3.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_datetimeoffset_argument__3.json new file mode 100644 index 000000000..c5e4e26e6 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_datetimeoffset_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Action": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Action", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.DateTimeOffset" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.DateTimeOffset", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_datetimeoffset_argument__4.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_datetimeoffset_argument__4.json new file mode 100644 index 000000000..8b004ac02 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_datetimeoffset_argument__4.json @@ -0,0 +1,394 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "post": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$", + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.DateTimeOffset" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_datetimeoffset_argument__5.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_datetimeoffset_argument__5.json new file mode 100644 index 000000000..5c1e5e191 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_datetimeoffset_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.DateTimeOffset", + "value": "2020-01-01T23:23:23+00:01" +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_decimal_argument__1.xml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_decimal_argument__1.xml new file mode 100644 index 000000000..271d5ffc8 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_decimal_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_decimal_argument__2.yml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_decimal_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_decimal_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_decimal_argument__3.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_decimal_argument__3.json new file mode 100644 index 000000000..d342a8fa1 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_decimal_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Action": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Action", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.Decimal" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.Decimal", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_decimal_argument__4.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_decimal_argument__4.json new file mode 100644 index 000000000..d9ff5bb68 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_decimal_argument__4.json @@ -0,0 +1,404 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "post": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ], + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.Decimal" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_decimal_argument__5.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_decimal_argument__5.json new file mode 100644 index 000000000..2982af6d5 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_decimal_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.Decimal", + "value": 3.14 +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_double_argument__1.xml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_double_argument__1.xml new file mode 100644 index 000000000..ea9114567 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_double_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_double_argument__2.yml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_double_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_double_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_double_argument__3.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_double_argument__3.json new file mode 100644 index 000000000..58e550dbd --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_double_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Action": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Action", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.Double" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.Double", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_double_argument__4.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_double_argument__4.json new file mode 100644 index 000000000..5d4264585 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_double_argument__4.json @@ -0,0 +1,404 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "post": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ], + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.Double" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_double_argument__5.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_double_argument__5.json new file mode 100644 index 000000000..1517e6040 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_double_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.Double", + "value": 3.14 +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_duration_argument__1.xml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_duration_argument__1.xml new file mode 100644 index 000000000..716bc3235 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_duration_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_duration_argument__2.yml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_duration_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_duration_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_duration_argument__3.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_duration_argument__3.json new file mode 100644 index 000000000..81c47e107 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_duration_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Action": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Action", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.Duration" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.Duration", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_duration_argument__4.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_duration_argument__4.json new file mode 100644 index 000000000..9d212da59 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_duration_argument__4.json @@ -0,0 +1,394 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "post": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$", + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.Duration" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_duration_argument__5.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_duration_argument__5.json new file mode 100644 index 000000000..9957ad020 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_duration_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.Duration", + "value": "P4DT6H4M45.121999999974S" +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_guid_argument__1.xml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_guid_argument__1.xml new file mode 100644 index 000000000..7553c3939 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_guid_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_guid_argument__2.yml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_guid_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_guid_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_guid_argument__3.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_guid_argument__3.json new file mode 100644 index 000000000..70ae2e674 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_guid_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Action": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Action", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.Guid" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.Guid", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_guid_argument__4.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_guid_argument__4.json new file mode 100644 index 000000000..66034647b --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_guid_argument__4.json @@ -0,0 +1,394 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "post": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.Guid" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_guid_argument__5.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_guid_argument__5.json new file mode 100644 index 000000000..bbd191648 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_guid_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.Guid", + "value": "2D1B80E8-0DAD-4EE7-AB6F-AE9FEC896290" +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int16_argument__1.xml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int16_argument__1.xml new file mode 100644 index 000000000..02050b4cc --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int16_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int16_argument__2.yml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int16_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int16_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int16_argument__3.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int16_argument__3.json new file mode 100644 index 000000000..3c127c15e --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int16_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Action": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Action", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.Int16" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.Int16", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int16_argument__4.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int16_argument__4.json new file mode 100644 index 000000000..bdcbd1e52 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int16_argument__4.json @@ -0,0 +1,395 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "post": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767, + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.Int16" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int16_argument__5.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int16_argument__5.json new file mode 100644 index 000000000..ca232e6af --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int16_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.Int16", + "value": -32767 +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int32_argument__1.xml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int32_argument__1.xml new file mode 100644 index 000000000..30f30600d --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int32_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int32_argument__2.yml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int32_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int32_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int32_argument__3.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int32_argument__3.json new file mode 100644 index 000000000..ab962f8c9 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int32_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Action": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Action", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.Int32" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.Int32", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int32_argument__4.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int32_argument__4.json new file mode 100644 index 000000000..c02c9f5a4 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int32_argument__4.json @@ -0,0 +1,395 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "post": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647, + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.Int32" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int32_argument__5.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int32_argument__5.json new file mode 100644 index 000000000..b2f1ad5a1 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int32_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.Int32", + "value": -2147483647 +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int64_argument__1.xml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int64_argument__1.xml new file mode 100644 index 000000000..b47e78d8e --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int64_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int64_argument__2.yml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int64_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int64_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int64_argument__3.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int64_argument__3.json new file mode 100644 index 000000000..ebea0d7b0 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int64_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Action": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Action", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.Int64" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.Int64", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int64_argument__4.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int64_argument__4.json new file mode 100644 index 000000000..ee5bff94f --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int64_argument__4.json @@ -0,0 +1,395 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "post": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807, + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.Int64" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int64_argument__5.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int64_argument__5.json new file mode 100644 index 000000000..8e45b68cd --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_int64_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.Int64", + "value": -9223372036854775807 +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_sbyte_argument__1.xml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_sbyte_argument__1.xml new file mode 100644 index 000000000..96704d3d6 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_sbyte_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_sbyte_argument__2.yml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_sbyte_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_sbyte_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_sbyte_argument__3.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_sbyte_argument__3.json new file mode 100644 index 000000000..35e557a11 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_sbyte_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Action": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Action", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.SByte" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.SByte", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_sbyte_argument__4.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_sbyte_argument__4.json new file mode 100644 index 000000000..be83a5b56 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_sbyte_argument__4.json @@ -0,0 +1,395 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "post": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127, + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.SByte" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_sbyte_argument__5.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_sbyte_argument__5.json new file mode 100644 index 000000000..8efd139c2 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_sbyte_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.SByte", + "value": 64 +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_single_argument__1.xml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_single_argument__1.xml new file mode 100644 index 000000000..36c8284ab --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_single_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_single_argument__2.yml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_single_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_single_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_single_argument__3.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_single_argument__3.json new file mode 100644 index 000000000..f62f9e83a --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_single_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Action": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Action", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.Single" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.Single", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_single_argument__4.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_single_argument__4.json new file mode 100644 index 000000000..dcddf3f26 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_single_argument__4.json @@ -0,0 +1,404 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "post": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ], + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.Single" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_single_argument__5.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_single_argument__5.json new file mode 100644 index 000000000..23cda3d54 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_single_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.Single", + "value": -3.14 +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_string_argument__1.xml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_string_argument__1.xml new file mode 100644 index 000000000..c0fe1fc1a --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_string_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_string_argument__2.yml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_string_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_string_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_string_argument__3.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_string_argument__3.json new file mode 100644 index 000000000..1cc7dc679 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_string_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Action": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Action", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.String" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.String", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_string_argument__4.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_string_argument__4.json new file mode 100644 index 000000000..73cce0513 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_string_argument__4.json @@ -0,0 +1,392 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "post": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "string", + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.String" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_string_argument__5.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_string_argument__5.json new file mode 100644 index 000000000..f3df69d74 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_string_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.String", + "value": "hello, world!" +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_timeofday_argument__1.xml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_timeofday_argument__1.xml new file mode 100644 index 000000000..ada61f22d --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_timeofday_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_timeofday_argument__2.yml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_timeofday_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_timeofday_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_timeofday_argument__3.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_timeofday_argument__3.json new file mode 100644 index 000000000..5788b7d0c --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_timeofday_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Action": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Action", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.TimeOfDay" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.TimeOfDay", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_timeofday_argument__4.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_timeofday_argument__4.json new file mode 100644 index 000000000..946da7f4d --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_timeofday_argument__4.json @@ -0,0 +1,394 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "post": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$", + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.TimeOfDay" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_timeofday_argument__5.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_timeofday_argument__5.json new file mode 100644 index 000000000..51b87cb57 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_timeofday_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.TimeOfDay", + "value": "23:23:23.000000" +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint16_argument__1.xml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint16_argument__1.xml new file mode 100644 index 000000000..98aed99db --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint16_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint16_argument__2.yml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint16_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint16_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint16_argument__3.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint16_argument__3.json new file mode 100644 index 000000000..fdf416040 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint16_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Action": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Action", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "com.example.odata.UInt16" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "com.example.odata.UInt16", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint16_argument__4.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint16_argument__4.json new file mode 100644 index 000000000..ccd38955b --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint16_argument__4.json @@ -0,0 +1,395 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "post": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "integer", + "format": "int16", + "minimum": 0, + "maximum": 32767, + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.UInt16" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint16_argument__5.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint16_argument__5.json new file mode 100644 index 000000000..286cb45bd --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint16_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#com.example.odata.UInt16", + "value": 32767 +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint32_argument__1.xml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint32_argument__1.xml new file mode 100644 index 000000000..f24e8e987 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint32_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint32_argument__2.yml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint32_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint32_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint32_argument__3.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint32_argument__3.json new file mode 100644 index 000000000..738b50227 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint32_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Action": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Action", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "com.example.odata.UInt32" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "com.example.odata.UInt32", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint32_argument__4.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint32_argument__4.json new file mode 100644 index 000000000..a39a143ae --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint32_argument__4.json @@ -0,0 +1,395 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "post": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "integer", + "format": "int32", + "minimum": 0, + "maximum": 2147483647, + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.UInt32" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint32_argument__5.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint32_argument__5.json new file mode 100644 index 000000000..f35014548 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint32_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#com.example.odata.UInt32", + "value": 2147483647 +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint64_argument__1.xml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint64_argument__1.xml new file mode 100644 index 000000000..1c249148e --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint64_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint64_argument__2.yml b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint64_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint64_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint64_argument__3.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint64_argument__3.json new file mode 100644 index 000000000..0199da645 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint64_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Action": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Action", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "com.example.odata.UInt64" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "com.example.odata.UInt64", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint64_argument__4.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint64_argument__4.json new file mode 100644 index 000000000..4c3472eb4 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint64_argument__4.json @@ -0,0 +1,395 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "post": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "integer", + "format": "int64", + "minimum": 0, + "maximum": 9223372036854775807, + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.UInt64" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint64_argument__5.json b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint64_argument__5.json new file mode 100644 index 000000000..eb94380f4 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/ActionTest__test_odata_uint64_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#com.example.odata.UInt64", + "value": 9223372036854775807 +} diff --git a/tests/Unit/Operation/__snapshots__/DiscoveryTest__test_bind__1.json b/tests/Unit/Operation/__snapshots__/DiscoveryTest__test_bind__1.json new file mode 100644 index 000000000..01c346db2 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/DiscoveryTest__test_bind__1.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.Int64", + "value": 3 +} diff --git a/tests/Unit/Operation/__snapshots__/DiscoveryTest__test_identity__1.json b/tests/Unit/Operation/__snapshots__/DiscoveryTest__test_identity__1.json new file mode 100644 index 000000000..397c82ea1 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/DiscoveryTest__test_identity__1.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.String", + "value": "hello" +} diff --git a/tests/Unit/Operation/__snapshots__/DiscoveryTest__test_instance__1.json b/tests/Unit/Operation/__snapshots__/DiscoveryTest__test_instance__1.json new file mode 100644 index 000000000..9bc2b02ed --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/DiscoveryTest__test_instance__1.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.String", + "value": "c" +} diff --git a/tests/Unit/Operation/__snapshots__/DiscoveryTest__test_metadata__1.xml b/tests/Unit/Operation/__snapshots__/DiscoveryTest__test_metadata__1.xml new file mode 100644 index 000000000..8a3ece412 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/DiscoveryTest__test_metadata__1.xml @@ -0,0 +1,326 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/DiscoveryTest__test_metadata__2.yml b/tests/Unit/Operation/__snapshots__/DiscoveryTest__test_metadata__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/DiscoveryTest__test_metadata__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/DiscoveryTest__test_metadata__3.json b/tests/Unit/Operation/__snapshots__/DiscoveryTest__test_metadata__3.json new file mode 100644 index 000000000..d9f68b61d --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/DiscoveryTest__test_metadata__3.json @@ -0,0 +1,416 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "Flights": { + "$EntityType": "com.example.odata.Flight", + "$NavigationPropertyBinding": {}, + "@Org.OData.Capabilities.V1.CountRestrictions": { + "Countable": true + }, + "@Org.OData.Capabilities.V1.TopSupported": true, + "@Org.OData.Capabilities.V1.SkipSupported": true, + "@Org.OData.Capabilities.V1.FilterRestrictions": { + "Filterable": true + }, + "@Org.OData.Capabilities.V1.SortRestrictions": { + "Sortable": true + }, + "@Org.OData.Capabilities.V1.ExpandRestrictions": { + "Expandable": true + }, + "@Org.OData.Capabilities.V1.SearchRestrictions": { + "Searchable": true + }, + "@Org.OData.Capabilities.V1.InsertRestrictions": { + "Insertable": true + }, + "@Org.OData.Capabilities.V1.UpdateRestrictions": { + "Updatable": true, + "DeltaUpdateSupported": true + }, + "@Org.OData.Capabilities.V1.DeleteRestrictions": { + "Deletable": true + }, + "@Org.OData.Capabilities.V1.ReadRestrictions": { + "Readable": true + }, + "@Org.OData.Capabilities.V1.IndexableByKey": true, + "@Org.OData.Capabilities.V1.SelectSupport": { + "Supported": true + }, + "@Org.OData.Capabilities.V1.DeepInsertSupport": { + "Supported": true, + "ContentIDSupported": true + } + }, + "helloImport": { + "$Function": "com.example.odata.hello" + }, + "identityImport": { + "$Function": "com.example.odata.identity" + }, + "addImport": { + "$Function": "com.example.odata.add" + }, + "execImport": { + "$Action": "com.example.odata.exec" + }, + "exec2Import": { + "$Action": "com.example.odata.exec2" + }, + "Passengers": { + "$EntityType": "com.example.odata.Passenger", + "$NavigationPropertyBinding": { + "pets": "Pets" + }, + "@Org.OData.Capabilities.V1.CountRestrictions": { + "Countable": true + }, + "@Org.OData.Capabilities.V1.TopSupported": true, + "@Org.OData.Capabilities.V1.SkipSupported": true, + "@Org.OData.Capabilities.V1.FilterRestrictions": { + "Filterable": true + }, + "@Org.OData.Capabilities.V1.SortRestrictions": { + "Sortable": true + }, + "@Org.OData.Capabilities.V1.ExpandRestrictions": { + "Expandable": true + }, + "@Org.OData.Capabilities.V1.SearchRestrictions": { + "Searchable": true + }, + "@Org.OData.Capabilities.V1.InsertRestrictions": { + "Insertable": true + }, + "@Org.OData.Capabilities.V1.UpdateRestrictions": { + "Updatable": true, + "DeltaUpdateSupported": true + }, + "@Org.OData.Capabilities.V1.DeleteRestrictions": { + "Deletable": true + }, + "@Org.OData.Capabilities.V1.ReadRestrictions": { + "Readable": true + }, + "@Org.OData.Capabilities.V1.IndexableByKey": true, + "@Org.OData.Capabilities.V1.SelectSupport": { + "Supported": true + }, + "@Org.OData.Capabilities.V1.DeepInsertSupport": { + "Supported": true, + "ContentIDSupported": true + } + }, + "Pets": { + "$EntityType": "com.example.odata.Pet", + "$NavigationPropertyBinding": { + "passenger": "Passengers" + }, + "@Org.OData.Capabilities.V1.CountRestrictions": { + "Countable": true + }, + "@Org.OData.Capabilities.V1.TopSupported": true, + "@Org.OData.Capabilities.V1.SkipSupported": true, + "@Org.OData.Capabilities.V1.FilterRestrictions": { + "Filterable": true + }, + "@Org.OData.Capabilities.V1.SortRestrictions": { + "Sortable": true + }, + "@Org.OData.Capabilities.V1.ExpandRestrictions": { + "Expandable": true + }, + "@Org.OData.Capabilities.V1.SearchRestrictions": { + "Searchable": true + }, + "@Org.OData.Capabilities.V1.InsertRestrictions": { + "Insertable": true + }, + "@Org.OData.Capabilities.V1.UpdateRestrictions": { + "Updatable": true, + "DeltaUpdateSupported": true + }, + "@Org.OData.Capabilities.V1.DeleteRestrictions": { + "Deletable": true + }, + "@Org.OData.Capabilities.V1.ReadRestrictions": { + "Readable": true + }, + "@Org.OData.Capabilities.V1.IndexableByKey": true, + "@Org.OData.Capabilities.V1.SelectSupport": { + "Supported": true + }, + "@Org.OData.Capabilities.V1.DeepInsertSupport": { + "Supported": true, + "ContentIDSupported": true + } + }, + "insargImport": { + "$Function": "com.example.odata.insarg" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "Flight": { + "$Kind": "EntityType", + "$Key": [ + "id" + ], + "id": { + "$Type": "Edm.Int64", + "$Nullable": false, + "@Org.OData.Core.V1.Computed": true + }, + "origin": { + "$Type": "Edm.String", + "$Nullable": true + }, + "destination": { + "$Type": "Edm.String", + "$Nullable": true + }, + "gate": { + "$Type": "Edm.Int32", + "$Nullable": true + }, + "duration": { + "$Type": "Edm.Decimal", + "$Nullable": true + } + }, + "Passenger": { + "$Kind": "EntityType", + "$Key": [ + "id" + ], + "id": { + "$Type": "Edm.Int64", + "$Nullable": false, + "@Org.OData.Core.V1.Computed": true + }, + "flight_id": { + "$Type": "Edm.Int32", + "$Nullable": false + }, + "name": { + "$Type": "Edm.String", + "$Nullable": false + }, + "pets": { + "$Collection": true, + "$Type": "com.example.odata.Pet", + "$Nullable": true, + "$ReferentialConstraint": { + "id": "passenger_id" + } + } + }, + "Pet": { + "$Kind": "EntityType", + "$Key": [ + "id" + ], + "id": { + "$Type": "Edm.Int64", + "$Nullable": false, + "@Org.OData.Core.V1.Computed": true + }, + "passenger_id": { + "$Type": "Edm.Int32", + "$Nullable": true + }, + "name": { + "$Type": "Edm.String", + "$Nullable": true + }, + "type": { + "$Type": "Edm.String", + "$Nullable": true + }, + "passenger": { + "$Collection": false, + "$Type": "com.example.odata.Passenger", + "$Nullable": true, + "$ReferentialConstraint": {} + } + }, + "hello": { + "$Kind": "Function", + "$IsBound": false, + "$Parameter": [], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.String", + "$Nullable": false + } + }, + "identity": { + "$Kind": "Function", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.String" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.String", + "$Nullable": false + } + }, + "name": { + "$Kind": "Function", + "$IsBound": true, + "$Parameter": [ + { + "$Name": "Flight", + "$Nullable": false, + "$Type": "com.example.odata.Flight" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.String", + "$Nullable": false + } + }, + "i1": { + "$Kind": "Function", + "$IsBound": true, + "$Parameter": [ + { + "$Name": "Flight", + "$Nullable": false, + "$Type": "com.example.odata.Flight" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "com.example.odata.Flight", + "$Nullable": false + } + }, + "add": { + "$Kind": "Function", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "a", + "$Nullable": false, + "$Type": "Edm.Int64" + }, + { + "$Name": "b", + "$Nullable": false, + "$Type": "Edm.Int64" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.Int64", + "$Nullable": false + } + }, + "increment": { + "$Kind": "Function", + "$IsBound": true, + "$Parameter": [ + { + "$Name": "a", + "$Nullable": false, + "$Type": "Edm.Int64" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.Int64", + "$Nullable": false + } + }, + "exec": { + "$Kind": "Action", + "$IsBound": false, + "$Parameter": [], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.String", + "$Nullable": true + } + }, + "exec2": { + "$Kind": "Action", + "$IsBound": false, + "$Parameter": [], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.String", + "$Nullable": true + } + }, + "insarg": { + "$Kind": "Function", + "$IsBound": false, + "$Parameter": [], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.String", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/DiscoveryTest__test_metadata__4.json b/tests/Unit/Operation/__snapshots__/DiscoveryTest__test_metadata__4.json new file mode 100644 index 000000000..d501a1c91 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/DiscoveryTest__test_metadata__4.json @@ -0,0 +1,1884 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [ + { + "name": "Flights" + }, + { + "name": "Passengers" + }, + { + "name": "Pets" + } + ], + "paths": { + "/Flights": { + "get": { + "summary": "Get entities from Flights", + "tags": [ + "Flights" + ], + "parameters": [ + { + "name": "select", + "in": "query", + "description": "Select properties to be returned, see [OData Select](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionselect)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "*", + "id", + "origin", + "destination", + "gate", + "duration" + ] + } + } + }, + { + "$ref": "#/components/parameters/count" + }, + { + "$ref": "#/components/parameters/filter" + }, + { + "$ref": "#/components/parameters/search" + }, + { + "$ref": "#/components/parameters/top" + }, + { + "$ref": "#/components/parameters/skip" + }, + { + "name": "orderby", + "in": "query", + "description": "Order items by property values, see [OData Sorting](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionorderby)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "id", + "id desc", + "origin", + "origin desc", + "destination", + "destination desc", + "gate", + "gate desc", + "duration", + "duration desc" + ] + } + } + } + ], + "responses": { + "200": { + "description": "Retrieved entities", + "content": { + "application/json": { + "schema": { + "type": "object", + "title": "Collection of Flights", + "properties": { + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/com.example.odata.Flight" + } + }, + "@count": { + "$ref": "#/components/schemas/count" + } + } + } + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + }, + "post": { + "summary": "Add new entity to Flights", + "tags": [ + "Flights" + ], + "requestBody": { + "required": true, + "description": "New entity", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.Flight~create" + } + } + } + }, + "responses": { + "201": { + "description": "Created entity", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.Flight" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/Flights/{id}": { + "parameters": [ + { + "description": "Key: id", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807, + "nullable": false + } + } + ], + "get": { + "summary": "Get entity from Flights by key", + "tags": [ + "Flights" + ], + "parameters": [ + { + "name": "select", + "in": "query", + "description": "Select properties to be returned, see [OData Select](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionselect)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "*", + "id", + "origin", + "destination", + "gate", + "duration" + ] + } + } + } + ], + "responses": { + "200": { + "description": "Retrieved entity", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.Flight" + } + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + }, + "patch": { + "summary": "Update entity in Flights", + "tags": [ + "Flights" + ], + "requestBody": { + "description": "New property values", + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.Flight~update" + } + } + } + }, + "responses": { + "200": { + "$ref": "#/components/schemas/com.example.odata.Flight" + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + }, + "delete": { + "summary": "Delete entity from Flights", + "tags": [ + "Flights" + ], + "responses": { + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/Passengers": { + "get": { + "summary": "Get entities from Passengers", + "tags": [ + "Passengers" + ], + "parameters": [ + { + "name": "select", + "in": "query", + "description": "Select properties to be returned, see [OData Select](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionselect)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "*", + "id", + "flight_id", + "name" + ] + } + } + }, + { + "$ref": "#/components/parameters/count" + }, + { + "name": "expand", + "in": "query", + "description": "Expand related entities, see [OData Expand](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionexpand)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "pets" + ] + } + } + }, + { + "$ref": "#/components/parameters/filter" + }, + { + "$ref": "#/components/parameters/search" + }, + { + "$ref": "#/components/parameters/top" + }, + { + "$ref": "#/components/parameters/skip" + }, + { + "name": "orderby", + "in": "query", + "description": "Order items by property values, see [OData Sorting](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionorderby)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "id", + "id desc", + "flight_id", + "flight_id desc", + "name", + "name desc" + ] + } + } + } + ], + "responses": { + "200": { + "description": "Retrieved entities", + "content": { + "application/json": { + "schema": { + "type": "object", + "title": "Collection of Passengers", + "properties": { + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/com.example.odata.Passenger" + } + }, + "@count": { + "$ref": "#/components/schemas/count" + } + } + } + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + }, + "post": { + "summary": "Add new entity to Passengers", + "tags": [ + "Passengers" + ], + "requestBody": { + "required": true, + "description": "New entity", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.Passenger~create" + } + } + } + }, + "responses": { + "201": { + "description": "Created entity", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.Passenger" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/Passengers/{id}": { + "parameters": [ + { + "description": "Key: id", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807, + "nullable": false + } + } + ], + "get": { + "summary": "Get entity from Passengers by key", + "tags": [ + "Passengers" + ], + "parameters": [ + { + "name": "select", + "in": "query", + "description": "Select properties to be returned, see [OData Select](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionselect)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "*", + "id", + "flight_id", + "name" + ] + } + } + }, + { + "name": "expand", + "in": "query", + "description": "Expand related entities, see [OData Expand](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionexpand)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "pets" + ] + } + } + } + ], + "responses": { + "200": { + "description": "Retrieved entity", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.Passenger" + } + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + }, + "patch": { + "summary": "Update entity in Passengers", + "tags": [ + "Passengers" + ], + "requestBody": { + "description": "New property values", + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.Passenger~update" + } + } + } + }, + "responses": { + "200": { + "$ref": "#/components/schemas/com.example.odata.Passenger" + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + }, + "delete": { + "summary": "Delete entity from Passengers", + "tags": [ + "Passengers" + ], + "responses": { + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/Passengers/{id}/pets": { + "parameters": [ + { + "description": "Key: id", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807, + "nullable": false + } + } + ], + "get": { + "summary": "Get entities from related Pets", + "tags": [ + "Pets", + "Passengers" + ], + "parameters": [ + { + "name": "select", + "in": "query", + "description": "Select properties to be returned, see [OData Select](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionselect)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "*", + "id", + "passenger_id", + "name", + "type" + ] + } + } + }, + { + "$ref": "#/components/parameters/count" + }, + { + "name": "expand", + "in": "query", + "description": "Expand related entities, see [OData Expand](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionexpand)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "passenger" + ] + } + } + }, + { + "$ref": "#/components/parameters/filter" + }, + { + "$ref": "#/components/parameters/search" + }, + { + "$ref": "#/components/parameters/top" + }, + { + "$ref": "#/components/parameters/skip" + }, + { + "name": "orderby", + "in": "query", + "description": "Order items by property values, see [OData Sorting](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionorderby)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "id", + "id desc", + "passenger_id", + "passenger_id desc", + "name", + "name desc", + "type", + "type desc" + ] + } + } + } + ], + "responses": { + "200": { + "description": "Retrieved entities", + "content": { + "application/json": { + "schema": { + "type": "object", + "title": "Collection of Pets", + "properties": { + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/com.example.odata.Pet" + } + }, + "@count": { + "$ref": "#/components/schemas/count" + } + } + } + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + }, + "post": { + "summary": "Add new entity to related Pets", + "tags": [ + "Pets", + "Passengers" + ], + "requestBody": { + "required": true, + "description": "New entity", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.Pet~create" + } + } + } + }, + "responses": { + "201": { + "description": "Created entity", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.Pet" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/Pets": { + "get": { + "summary": "Get entities from Pets", + "tags": [ + "Pets" + ], + "parameters": [ + { + "name": "select", + "in": "query", + "description": "Select properties to be returned, see [OData Select](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionselect)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "*", + "id", + "passenger_id", + "name", + "type" + ] + } + } + }, + { + "$ref": "#/components/parameters/count" + }, + { + "name": "expand", + "in": "query", + "description": "Expand related entities, see [OData Expand](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionexpand)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "passenger" + ] + } + } + }, + { + "$ref": "#/components/parameters/filter" + }, + { + "$ref": "#/components/parameters/search" + }, + { + "$ref": "#/components/parameters/top" + }, + { + "$ref": "#/components/parameters/skip" + }, + { + "name": "orderby", + "in": "query", + "description": "Order items by property values, see [OData Sorting](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionorderby)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "id", + "id desc", + "passenger_id", + "passenger_id desc", + "name", + "name desc", + "type", + "type desc" + ] + } + } + } + ], + "responses": { + "200": { + "description": "Retrieved entities", + "content": { + "application/json": { + "schema": { + "type": "object", + "title": "Collection of Pets", + "properties": { + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/com.example.odata.Pet" + } + }, + "@count": { + "$ref": "#/components/schemas/count" + } + } + } + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + }, + "post": { + "summary": "Add new entity to Pets", + "tags": [ + "Pets" + ], + "requestBody": { + "required": true, + "description": "New entity", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.Pet~create" + } + } + } + }, + "responses": { + "201": { + "description": "Created entity", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.Pet" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/Pets/{id}": { + "parameters": [ + { + "description": "Key: id", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807, + "nullable": false + } + } + ], + "get": { + "summary": "Get entity from Pets by key", + "tags": [ + "Pets" + ], + "parameters": [ + { + "name": "select", + "in": "query", + "description": "Select properties to be returned, see [OData Select](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionselect)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "*", + "id", + "passenger_id", + "name", + "type" + ] + } + } + }, + { + "name": "expand", + "in": "query", + "description": "Expand related entities, see [OData Expand](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionexpand)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "passenger" + ] + } + } + } + ], + "responses": { + "200": { + "description": "Retrieved entity", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.Pet" + } + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + }, + "patch": { + "summary": "Update entity in Pets", + "tags": [ + "Pets" + ], + "requestBody": { + "description": "New property values", + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.Pet~update" + } + } + } + }, + "responses": { + "200": { + "$ref": "#/components/schemas/com.example.odata.Pet" + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + }, + "delete": { + "summary": "Delete entity from Pets", + "tags": [ + "Pets" + ], + "responses": { + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/Pets/{id}/passenger": { + "parameters": [ + { + "description": "Key: id", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807, + "nullable": false + } + } + ], + "get": { + "summary": "Get entities from related Passengers", + "tags": [ + "Passengers", + "Pets" + ], + "parameters": [ + { + "name": "select", + "in": "query", + "description": "Select properties to be returned, see [OData Select](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionselect)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "*", + "id", + "flight_id", + "name" + ] + } + } + }, + { + "$ref": "#/components/parameters/count" + }, + { + "name": "expand", + "in": "query", + "description": "Expand related entities, see [OData Expand](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionexpand)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "pets" + ] + } + } + }, + { + "$ref": "#/components/parameters/filter" + }, + { + "$ref": "#/components/parameters/search" + }, + { + "$ref": "#/components/parameters/top" + }, + { + "$ref": "#/components/parameters/skip" + }, + { + "name": "orderby", + "in": "query", + "description": "Order items by property values, see [OData Sorting](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionorderby)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "id", + "id desc", + "flight_id", + "flight_id desc", + "name", + "name desc" + ] + } + } + } + ], + "responses": { + "200": { + "description": "Retrieved entities", + "content": { + "application/json": { + "schema": { + "type": "object", + "title": "Collection of Passengers", + "properties": { + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/com.example.odata.Passenger" + } + }, + "@count": { + "$ref": "#/components/schemas/count" + } + } + } + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + }, + "post": { + "summary": "Add new entity to related Passengers", + "tags": [ + "Passengers", + "Pets" + ], + "requestBody": { + "required": true, + "description": "New entity", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.Passenger~create" + } + } + } + }, + "responses": { + "201": { + "description": "Created entity", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.Passenger" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/hello": { + "get": { + "tags": [ + "Service Operations", + "hello" + ], + "parameters": [], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.String" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/identity": { + "get": { + "tags": [ + "Service Operations", + "identity", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "string", + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.String" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/add": { + "get": { + "tags": [ + "Service Operations", + "add", + "a", + "b" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "a", + "schema": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807, + "nullable": true + } + }, + { + "required": false, + "in": "query", + "name": "b", + "schema": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807, + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.Int64" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/exec": { + "post": { + "tags": [ + "Service Operations", + "exec" + ], + "parameters": [], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.String" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/exec2": { + "post": { + "tags": [ + "Service Operations", + "exec2" + ], + "parameters": [], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.String" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/insarg": { + "get": { + "tags": [ + "Service Operations", + "insarg" + ], + "parameters": [], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.String" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "com.example.odata.Flight": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807, + "nullable": false + }, + "origin": { + "type": "string", + "nullable": true + }, + "destination": { + "type": "string", + "nullable": true + }, + "gate": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647, + "nullable": true + }, + "duration": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ], + "nullable": true + } + } + }, + "com.example.odata.Flight~create": { + "type": "object", + "properties": { + "origin": { + "type": "string", + "nullable": true + }, + "destination": { + "type": "string", + "nullable": true + }, + "gate": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647, + "nullable": true + }, + "duration": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ], + "nullable": true + } + } + }, + "com.example.odata.Flight~update": { + "type": "object", + "properties": { + "origin": { + "type": "string", + "nullable": true + }, + "destination": { + "type": "string", + "nullable": true + }, + "gate": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647, + "nullable": true + }, + "duration": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ], + "nullable": true + } + } + }, + "com.example.odata.Passenger": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807, + "nullable": false + }, + "flight_id": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647, + "nullable": false + }, + "name": { + "type": "string", + "nullable": false + } + } + }, + "com.example.odata.Passenger~create": { + "type": "object", + "properties": { + "flight_id": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647, + "nullable": false + }, + "name": { + "type": "string", + "nullable": false + } + } + }, + "com.example.odata.Passenger~update": { + "type": "object", + "properties": { + "flight_id": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647, + "nullable": false + }, + "name": { + "type": "string", + "nullable": false + } + } + }, + "com.example.odata.Pet": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807, + "nullable": false + }, + "passenger_id": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647, + "nullable": true + }, + "name": { + "type": "string", + "nullable": true + }, + "type": { + "type": "string", + "nullable": true + } + } + }, + "com.example.odata.Pet~create": { + "type": "object", + "properties": { + "passenger_id": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647, + "nullable": true + }, + "name": { + "type": "string", + "nullable": true + }, + "type": { + "type": "string", + "nullable": true + } + } + }, + "com.example.odata.Pet~update": { + "type": "object", + "properties": { + "passenger_id": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647, + "nullable": true + }, + "name": { + "type": "string", + "nullable": true + }, + "type": { + "type": "string", + "nullable": true + } + } + }, + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/DiscoveryTest__test_simple__1.json b/tests/Unit/Operation/__snapshots__/DiscoveryTest__test_simple__1.json new file mode 100644 index 000000000..8901a25b6 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/DiscoveryTest__test_simple__1.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.String", + "value": "hello world!" +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_callback_bound_internal_type__1.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_callback_bound_internal_type__1.json new file mode 100644 index 000000000..850446c6a --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_callback_bound_internal_type__1.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.Int64", + "value": 2 +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_binary_argument__1.xml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_binary_argument__1.xml new file mode 100644 index 000000000..1db85b415 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_binary_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_binary_argument__2.yml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_binary_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_binary_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_binary_argument__3.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_binary_argument__3.json new file mode 100644 index 000000000..f2ea1f074 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_binary_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Function": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Function", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.Binary" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.Binary", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_binary_argument__4.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_binary_argument__4.json new file mode 100644 index 000000000..1bcca44c5 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_binary_argument__4.json @@ -0,0 +1,394 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "get": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$", + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.Binary" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_binary_argument__5.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_binary_argument__5.json new file mode 100644 index 000000000..b8c7203ce --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_binary_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.Binary", + "value": "aGVsbG8gd29ybGQ=" +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_boolean_argument__1.xml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_boolean_argument__1.xml new file mode 100644 index 000000000..983d5e08d --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_boolean_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_boolean_argument__2.yml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_boolean_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_boolean_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_boolean_argument__3.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_boolean_argument__3.json new file mode 100644 index 000000000..c3400faf7 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_boolean_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Function": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Function", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.Boolean" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.Boolean", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_boolean_argument__4.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_boolean_argument__4.json new file mode 100644 index 000000000..781cae206 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_boolean_argument__4.json @@ -0,0 +1,392 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "get": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "boolean", + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.Boolean" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_boolean_argument__5.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_boolean_argument__5.json new file mode 100644 index 000000000..d823b92f8 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_boolean_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.Boolean", + "value": false +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_byte_argument__1.xml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_byte_argument__1.xml new file mode 100644 index 000000000..799656b46 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_byte_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_byte_argument__2.yml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_byte_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_byte_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_byte_argument__3.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_byte_argument__3.json new file mode 100644 index 000000000..9d04bff2e --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_byte_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Function": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Function", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.Byte" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.Byte", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_byte_argument__4.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_byte_argument__4.json new file mode 100644 index 000000000..5c652088c --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_byte_argument__4.json @@ -0,0 +1,395 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "get": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255, + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.Byte" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_byte_argument__5.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_byte_argument__5.json new file mode 100644 index 000000000..47713688c --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_byte_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.Byte", + "value": 4 +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_date_argument__1.xml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_date_argument__1.xml new file mode 100644 index 000000000..960aff24e --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_date_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_date_argument__2.yml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_date_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_date_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_date_argument__3.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_date_argument__3.json new file mode 100644 index 000000000..7099e9a04 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_date_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Function": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Function", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.Date" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.Date", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_date_argument__4.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_date_argument__4.json new file mode 100644 index 000000000..23895b295 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_date_argument__4.json @@ -0,0 +1,394 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "get": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$", + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.Date" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_date_argument__5.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_date_argument__5.json new file mode 100644 index 000000000..249938304 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_date_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.Date", + "value": "2020-01-01" +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_datetimeoffset_argument__1.xml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_datetimeoffset_argument__1.xml new file mode 100644 index 000000000..e3be4376a --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_datetimeoffset_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_datetimeoffset_argument__2.yml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_datetimeoffset_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_datetimeoffset_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_datetimeoffset_argument__3.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_datetimeoffset_argument__3.json new file mode 100644 index 000000000..3ff14c20e --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_datetimeoffset_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Function": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Function", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.DateTimeOffset" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.DateTimeOffset", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_datetimeoffset_argument__4.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_datetimeoffset_argument__4.json new file mode 100644 index 000000000..273c26157 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_datetimeoffset_argument__4.json @@ -0,0 +1,394 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "get": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$", + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.DateTimeOffset" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_datetimeoffset_argument__5.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_datetimeoffset_argument__5.json new file mode 100644 index 000000000..5c1e5e191 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_datetimeoffset_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.DateTimeOffset", + "value": "2020-01-01T23:23:23+00:01" +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_decimal_argument__1.xml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_decimal_argument__1.xml new file mode 100644 index 000000000..a252b2552 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_decimal_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_decimal_argument__2.yml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_decimal_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_decimal_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_decimal_argument__3.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_decimal_argument__3.json new file mode 100644 index 000000000..5dfb4ad76 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_decimal_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Function": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Function", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.Decimal" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.Decimal", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_decimal_argument__4.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_decimal_argument__4.json new file mode 100644 index 000000000..da8f3266d --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_decimal_argument__4.json @@ -0,0 +1,404 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "get": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ], + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.Decimal" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_decimal_argument__5.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_decimal_argument__5.json new file mode 100644 index 000000000..2982af6d5 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_decimal_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.Decimal", + "value": 3.14 +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_double_argument__1.xml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_double_argument__1.xml new file mode 100644 index 000000000..0ec78ce2a --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_double_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_double_argument__2.yml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_double_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_double_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_double_argument__3.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_double_argument__3.json new file mode 100644 index 000000000..25139212a --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_double_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Function": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Function", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.Double" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.Double", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_double_argument__4.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_double_argument__4.json new file mode 100644 index 000000000..f4a1fbcee --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_double_argument__4.json @@ -0,0 +1,404 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "get": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ], + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.Double" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_double_argument__5.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_double_argument__5.json new file mode 100644 index 000000000..1517e6040 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_double_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.Double", + "value": 3.14 +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_duration_argument__1.xml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_duration_argument__1.xml new file mode 100644 index 000000000..5b66f712d --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_duration_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_duration_argument__2.yml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_duration_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_duration_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_duration_argument__3.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_duration_argument__3.json new file mode 100644 index 000000000..7ca8e7736 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_duration_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Function": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Function", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.Duration" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.Duration", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_duration_argument__4.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_duration_argument__4.json new file mode 100644 index 000000000..5ef4d9136 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_duration_argument__4.json @@ -0,0 +1,394 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "get": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$", + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.Duration" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_duration_argument__5.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_duration_argument__5.json new file mode 100644 index 000000000..9957ad020 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_duration_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.Duration", + "value": "P4DT6H4M45.121999999974S" +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_guid_argument__1.xml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_guid_argument__1.xml new file mode 100644 index 000000000..d9d0af675 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_guid_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_guid_argument__2.yml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_guid_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_guid_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_guid_argument__3.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_guid_argument__3.json new file mode 100644 index 000000000..0d4534370 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_guid_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Function": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Function", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.Guid" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.Guid", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_guid_argument__4.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_guid_argument__4.json new file mode 100644 index 000000000..8db121a79 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_guid_argument__4.json @@ -0,0 +1,394 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "get": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.Guid" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_guid_argument__5.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_guid_argument__5.json new file mode 100644 index 000000000..bbd191648 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_guid_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.Guid", + "value": "2D1B80E8-0DAD-4EE7-AB6F-AE9FEC896290" +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int16_argument__1.xml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int16_argument__1.xml new file mode 100644 index 000000000..336604e22 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int16_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int16_argument__2.yml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int16_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int16_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int16_argument__3.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int16_argument__3.json new file mode 100644 index 000000000..d69ef500c --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int16_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Function": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Function", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.Int16" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.Int16", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int16_argument__4.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int16_argument__4.json new file mode 100644 index 000000000..0ca2fe94a --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int16_argument__4.json @@ -0,0 +1,395 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "get": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767, + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.Int16" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int16_argument__5.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int16_argument__5.json new file mode 100644 index 000000000..ca232e6af --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int16_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.Int16", + "value": -32767 +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int32_argument__1.xml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int32_argument__1.xml new file mode 100644 index 000000000..2ecc80ebd --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int32_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int32_argument__2.yml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int32_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int32_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int32_argument__3.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int32_argument__3.json new file mode 100644 index 000000000..44de56157 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int32_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Function": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Function", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.Int32" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.Int32", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int32_argument__4.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int32_argument__4.json new file mode 100644 index 000000000..c43089ff4 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int32_argument__4.json @@ -0,0 +1,395 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "get": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647, + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.Int32" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int32_argument__5.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int32_argument__5.json new file mode 100644 index 000000000..b2f1ad5a1 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int32_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.Int32", + "value": -2147483647 +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int64_argument__1.xml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int64_argument__1.xml new file mode 100644 index 000000000..39bacae62 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int64_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int64_argument__2.yml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int64_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int64_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int64_argument__3.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int64_argument__3.json new file mode 100644 index 000000000..d725f96a1 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int64_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Function": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Function", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.Int64" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.Int64", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int64_argument__4.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int64_argument__4.json new file mode 100644 index 000000000..365ae9cad --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int64_argument__4.json @@ -0,0 +1,395 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "get": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807, + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.Int64" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int64_argument__5.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int64_argument__5.json new file mode 100644 index 000000000..8e45b68cd --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_int64_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.Int64", + "value": -9223372036854775807 +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_sbyte_argument__1.xml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_sbyte_argument__1.xml new file mode 100644 index 000000000..753718a53 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_sbyte_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_sbyte_argument__2.yml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_sbyte_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_sbyte_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_sbyte_argument__3.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_sbyte_argument__3.json new file mode 100644 index 000000000..3d2b264f8 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_sbyte_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Function": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Function", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.SByte" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.SByte", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_sbyte_argument__4.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_sbyte_argument__4.json new file mode 100644 index 000000000..296699aa9 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_sbyte_argument__4.json @@ -0,0 +1,395 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "get": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127, + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.SByte" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_sbyte_argument__5.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_sbyte_argument__5.json new file mode 100644 index 000000000..8efd139c2 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_sbyte_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.SByte", + "value": 64 +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_single_argument__1.xml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_single_argument__1.xml new file mode 100644 index 000000000..5bdd0ebe8 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_single_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_single_argument__2.yml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_single_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_single_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_single_argument__3.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_single_argument__3.json new file mode 100644 index 000000000..9cbf58e37 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_single_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Function": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Function", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.Single" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.Single", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_single_argument__4.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_single_argument__4.json new file mode 100644 index 000000000..629a14417 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_single_argument__4.json @@ -0,0 +1,404 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "get": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ], + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.Single" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_single_argument__5.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_single_argument__5.json new file mode 100644 index 000000000..23cda3d54 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_single_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.Single", + "value": -3.14 +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_string_argument__1.xml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_string_argument__1.xml new file mode 100644 index 000000000..4f4dba11f --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_string_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_string_argument__2.yml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_string_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_string_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_string_argument__3.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_string_argument__3.json new file mode 100644 index 000000000..69fef6cf8 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_string_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Function": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Function", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.String" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.String", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_string_argument__4.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_string_argument__4.json new file mode 100644 index 000000000..fff5b6803 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_string_argument__4.json @@ -0,0 +1,392 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "get": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "string", + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.String" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_string_argument__5.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_string_argument__5.json new file mode 100644 index 000000000..f3df69d74 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_string_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.String", + "value": "hello, world!" +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_timeofday_argument__1.xml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_timeofday_argument__1.xml new file mode 100644 index 000000000..e4a7f9644 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_timeofday_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_timeofday_argument__2.yml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_timeofday_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_timeofday_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_timeofday_argument__3.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_timeofday_argument__3.json new file mode 100644 index 000000000..594398ca9 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_timeofday_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Function": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Function", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "Edm.TimeOfDay" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.TimeOfDay", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_timeofday_argument__4.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_timeofday_argument__4.json new file mode 100644 index 000000000..0e242d090 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_timeofday_argument__4.json @@ -0,0 +1,394 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "get": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$", + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.TimeOfDay" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_timeofday_argument__5.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_timeofday_argument__5.json new file mode 100644 index 000000000..51b87cb57 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_timeofday_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.TimeOfDay", + "value": "23:23:23.000000" +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint16_argument__1.xml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint16_argument__1.xml new file mode 100644 index 000000000..4b079fa2d --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint16_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint16_argument__2.yml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint16_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint16_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint16_argument__3.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint16_argument__3.json new file mode 100644 index 000000000..d8576d445 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint16_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Function": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Function", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "com.example.odata.UInt16" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "com.example.odata.UInt16", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint16_argument__4.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint16_argument__4.json new file mode 100644 index 000000000..51b0de6a2 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint16_argument__4.json @@ -0,0 +1,395 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "get": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "integer", + "format": "int16", + "minimum": 0, + "maximum": 32767, + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.UInt16" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint16_argument__5.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint16_argument__5.json new file mode 100644 index 000000000..286cb45bd --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint16_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#com.example.odata.UInt16", + "value": 32767 +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint32_argument__1.xml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint32_argument__1.xml new file mode 100644 index 000000000..2c6b6d8f4 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint32_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint32_argument__2.yml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint32_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint32_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint32_argument__3.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint32_argument__3.json new file mode 100644 index 000000000..9f6e5be77 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint32_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Function": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Function", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "com.example.odata.UInt32" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "com.example.odata.UInt32", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint32_argument__4.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint32_argument__4.json new file mode 100644 index 000000000..34f3abfa0 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint32_argument__4.json @@ -0,0 +1,395 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "get": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "integer", + "format": "int32", + "minimum": 0, + "maximum": 2147483647, + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.UInt32" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint32_argument__5.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint32_argument__5.json new file mode 100644 index 000000000..f35014548 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint32_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#com.example.odata.UInt32", + "value": 2147483647 +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint64_argument__1.xml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint64_argument__1.xml new file mode 100644 index 000000000..bf7c68538 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint64_argument__1.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint64_argument__2.yml b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint64_argument__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint64_argument__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint64_argument__3.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint64_argument__3.json new file mode 100644 index 000000000..cd6c01a2b --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint64_argument__3.json @@ -0,0 +1,79 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "opImport": { + "$Function": "com.example.odata.op" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "op": { + "$Kind": "Function", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "arg", + "$Nullable": false, + "$Type": "com.example.odata.UInt64" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "com.example.odata.UInt64", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint64_argument__4.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint64_argument__4.json new file mode 100644 index 000000000..d2c62f25d --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint64_argument__4.json @@ -0,0 +1,395 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/op": { + "get": { + "tags": [ + "Service Operations", + "op", + "arg" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "arg", + "schema": { + "type": "integer", + "format": "int64", + "minimum": 0, + "maximum": 9223372036854775807, + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.UInt64" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint64_argument__5.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint64_argument__5.json new file mode 100644 index 000000000..eb94380f4 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_odata_uint64_argument__5.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#com.example.odata.UInt64", + "value": 9223372036854775807 +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_with_invalid_argument__1.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_with_invalid_argument__1.json new file mode 100644 index 000000000..821cc9317 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_with_invalid_argument__1.json @@ -0,0 +1,9 @@ +{ + "error": { + "code": "invalid_argument", + "message": "The parameters provided an argument that was not known", + "target": null, + "details": [], + "innererror": {} + } +} diff --git a/tests/Unit/Operation/__snapshots__/FunctionTest__test_with_missing_indirect_arguments__1.json b/tests/Unit/Operation/__snapshots__/FunctionTest__test_with_missing_indirect_arguments__1.json index 5d113a421..85671cce1 100644 --- a/tests/Unit/Operation/__snapshots__/FunctionTest__test_with_missing_indirect_arguments__1.json +++ b/tests/Unit/Operation/__snapshots__/FunctionTest__test_with_missing_indirect_arguments__1.json @@ -1,7 +1,7 @@ { "error": { "code": "reference_value_missing", - "message": "The requested reference value @e did not exist", + "message": "The requested reference (e) did not exist", "target": null, "details": [], "innererror": {} diff --git a/tests/Unit/Operation/__snapshots__/NamespaceTest__test_add__1.json b/tests/Unit/Operation/__snapshots__/NamespaceTest__test_add__1.json new file mode 100644 index 000000000..01c346db2 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/NamespaceTest__test_add__1.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.Int64", + "value": 3 +} diff --git a/tests/Unit/Operation/__snapshots__/NamespaceTest__test_metadata__1.xml b/tests/Unit/Operation/__snapshots__/NamespaceTest__test_metadata__1.xml new file mode 100644 index 000000000..728e52884 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/NamespaceTest__test_metadata__1.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/NamespaceTest__test_metadata__2.yml b/tests/Unit/Operation/__snapshots__/NamespaceTest__test_metadata__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/NamespaceTest__test_metadata__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/NamespaceTest__test_metadata__3.json b/tests/Unit/Operation/__snapshots__/NamespaceTest__test_metadata__3.json new file mode 100644 index 000000000..21b916371 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/NamespaceTest__test_metadata__3.json @@ -0,0 +1,84 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "com.example.math.addImport": { + "$Function": "com.example.math.add" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "com.example.math.add": { + "$Kind": "Function", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "a", + "$Nullable": false, + "$Type": "Edm.Int64" + }, + { + "$Name": "b", + "$Nullable": false, + "$Type": "Edm.Int64" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.Int64", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/NamespaceTest__test_metadata__4.json b/tests/Unit/Operation/__snapshots__/NamespaceTest__test_metadata__4.json new file mode 100644 index 000000000..eda06eca2 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/NamespaceTest__test_metadata__4.json @@ -0,0 +1,408 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [], + "paths": { + "/add": { + "get": { + "tags": [ + "Service Operations", + "add", + "a", + "b" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "a", + "schema": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807, + "nullable": true + } + }, + { + "required": false, + "in": "query", + "name": "b", + "schema": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807, + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.Int64" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/OperationTest__test_binding_did_not_exist__1.json b/tests/Unit/Operation/__snapshots__/OperationTest__test_binding_did_not_exist__1.json new file mode 100644 index 000000000..478e8f573 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/OperationTest__test_binding_did_not_exist__1.json @@ -0,0 +1,9 @@ +{ + "error": { + "code": "missing_callable_binding_parameter", + "message": "The provided callable did not have a argument named texts", + "target": null, + "details": [], + "innererror": {} + } +} diff --git a/tests/Unit/Operation/__snapshots__/OperationTest__test_binding_did_not_exist__1.yml b/tests/Unit/Operation/__snapshots__/OperationTest__test_binding_did_not_exist__1.yml deleted file mode 100644 index fe528079d..000000000 --- a/tests/Unit/Operation/__snapshots__/OperationTest__test_binding_did_not_exist__1.yml +++ /dev/null @@ -1,3 +0,0 @@ -httpCode: 500 -odataCode: cannot_find_binding_parameter -message: 'The requested binding parameter did not exist on the invoke method' diff --git a/tests/Unit/Operation/__snapshots__/OperationTest__test_callback__1.json b/tests/Unit/Operation/__snapshots__/OperationTest__test_callback__1.json new file mode 100644 index 000000000..397c82ea1 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/OperationTest__test_callback__1.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.String", + "value": "hello" +} diff --git a/tests/Unit/Operation/__snapshots__/OperationTest__test_instance_callback__1.json b/tests/Unit/Operation/__snapshots__/OperationTest__test_instance_callback__1.json new file mode 100644 index 000000000..8901a25b6 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/OperationTest__test_instance_callback__1.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.String", + "value": "hello world!" +} diff --git a/tests/Unit/Operation/__snapshots__/OperationTest__test_malformed_args__1.json b/tests/Unit/Operation/__snapshots__/OperationTest__test_malformed_args__1.json new file mode 100644 index 000000000..360969739 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/OperationTest__test_malformed_args__1.json @@ -0,0 +1,9 @@ +{ + "error": { + "code": "malformed_parameters", + "message": "The provided parameters were not well formed", + "target": null, + "details": [], + "innererror": {} + } +} diff --git a/tests/Unit/Operation/__snapshots__/OperationTest__test_missing_invoke__1.json b/tests/Unit/Operation/__snapshots__/OperationTest__test_missing_invoke__1.json new file mode 100644 index 000000000..621fc83b8 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/OperationTest__test_missing_invoke__1.json @@ -0,0 +1,9 @@ +{ + "error": { + "code": "missing_callable", + "message": "The operation has no callable", + "target": null, + "details": [], + "innererror": {} + } +} diff --git a/tests/Unit/Operation/__snapshots__/OperationTest__test_missing_invoke__1.yml b/tests/Unit/Operation/__snapshots__/OperationTest__test_missing_invoke__1.yml deleted file mode 100644 index c014b1bf1..000000000 --- a/tests/Unit/Operation/__snapshots__/OperationTest__test_missing_invoke__1.yml +++ /dev/null @@ -1,3 +0,0 @@ -httpCode: 500 -odataCode: 'An operation must implement the invoke method' -message: 'Internal server error' diff --git a/tests/Unit/Operation/__snapshots__/OperationTest__test_namespaced__1.json b/tests/Unit/Operation/__snapshots__/OperationTest__test_namespaced__1.json new file mode 100644 index 000000000..397c82ea1 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/OperationTest__test_namespaced__1.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.String", + "value": "hello" +} diff --git a/tests/Unit/Operation/__snapshots__/OperationTest__test_namespaced__2.json b/tests/Unit/Operation/__snapshots__/OperationTest__test_namespaced__2.json new file mode 100644 index 000000000..d685a2e49 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/OperationTest__test_namespaced__2.json @@ -0,0 +1,9 @@ +{ + "error": { + "code": "no_handler", + "message": "No route handler was able to process this request", + "target": null, + "details": [], + "innererror": {} + } +} diff --git a/tests/Unit/Operation/__snapshots__/OperationTest__test_namespaced__3.json b/tests/Unit/Operation/__snapshots__/OperationTest__test_namespaced__3.json new file mode 100644 index 000000000..d685a2e49 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/OperationTest__test_namespaced__3.json @@ -0,0 +1,9 @@ +{ + "error": { + "code": "no_handler", + "message": "No route handler was able to process this request", + "target": null, + "details": [], + "innererror": {} + } +} diff --git a/tests/Unit/Operation/__snapshots__/OperationTest__test_namespaced__4.json b/tests/Unit/Operation/__snapshots__/OperationTest__test_namespaced__4.json new file mode 100644 index 000000000..d685a2e49 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/OperationTest__test_namespaced__4.json @@ -0,0 +1,9 @@ +{ + "error": { + "code": "no_handler", + "message": "No route handler was able to process this request", + "target": null, + "details": [], + "innererror": {} + } +} diff --git a/tests/Unit/Operation/__snapshots__/OperationTest__test_object_callback__1.json b/tests/Unit/Operation/__snapshots__/OperationTest__test_object_callback__1.json new file mode 100644 index 000000000..8901a25b6 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/OperationTest__test_object_callback__1.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.String", + "value": "hello world!" +} diff --git a/tests/Unit/Operation/__snapshots__/OperationTest__test_parameter_bound_binding_wrong_type__1.json b/tests/Unit/Operation/__snapshots__/OperationTest__test_parameter_bound_binding_wrong_type__1.json index bd08108f3..5c9395c3b 100644 --- a/tests/Unit/Operation/__snapshots__/OperationTest__test_parameter_bound_binding_wrong_type__1.json +++ b/tests/Unit/Operation/__snapshots__/OperationTest__test_parameter_bound_binding_wrong_type__1.json @@ -1,7 +1,7 @@ { "error": { - "code": "invalid_bound_argument_type", - "message": "The provided bound argument was not of the correct type for this function", + "code": "invalid_argument_type", + "message": "The provided argument (flights) was not of the correct type for this function", "target": null, "details": [], "innererror": {} diff --git a/tests/Unit/Operation/__snapshots__/OperationTest__test_parameter_bound_missing_binding__1.json b/tests/Unit/Operation/__snapshots__/OperationTest__test_parameter_bound_missing_binding__1.json index 7b42d6bef..062c47661 100644 --- a/tests/Unit/Operation/__snapshots__/OperationTest__test_parameter_bound_missing_binding__1.json +++ b/tests/Unit/Operation/__snapshots__/OperationTest__test_parameter_bound_missing_binding__1.json @@ -1,7 +1,7 @@ { "error": { "code": "missing_bound_argument", - "message": "This operation is bound, but no bound argument was provided", + "message": "This operation is bound, but no argument was provided", "target": null, "details": [], "innererror": {} diff --git a/tests/Unit/Operation/__snapshots__/OperationTest__test_parameter_bound_modify__4.json b/tests/Unit/Operation/__snapshots__/OperationTest__test_parameter_bound_modify__4.json index b3745fab8..157976629 100644 --- a/tests/Unit/Operation/__snapshots__/OperationTest__test_parameter_bound_modify__4.json +++ b/tests/Unit/Operation/__snapshots__/OperationTest__test_parameter_bound_modify__4.json @@ -1501,7 +1501,7 @@ } } }, - "/f1": { + "/flights/f1()": { "get": { "tags": [ "Service Operations", diff --git a/tests/Unit/Operation/__snapshots__/OperationTest__test_parameter_bound_passthru__4.json b/tests/Unit/Operation/__snapshots__/OperationTest__test_parameter_bound_passthru__4.json index 66de5bc7e..5c7d1f616 100644 --- a/tests/Unit/Operation/__snapshots__/OperationTest__test_parameter_bound_passthru__4.json +++ b/tests/Unit/Operation/__snapshots__/OperationTest__test_parameter_bound_passthru__4.json @@ -1501,7 +1501,7 @@ } } }, - "/f1": { + "/flights/f1()": { "get": { "tags": [ "Service Operations", diff --git a/tests/Unit/Operation/__snapshots__/OperationTest__test_parameter_order_bound__4.json b/tests/Unit/Operation/__snapshots__/OperationTest__test_parameter_order_bound__4.json index ef97de042..ce6fba1fe 100644 --- a/tests/Unit/Operation/__snapshots__/OperationTest__test_parameter_order_bound__4.json +++ b/tests/Unit/Operation/__snapshots__/OperationTest__test_parameter_order_bound__4.json @@ -12,69 +12,6 @@ ], "tags": [], "paths": { - "/f1": { - "get": { - "tags": [ - "Service Operations", - "f1", - "b", - "a" - ], - "parameters": [ - { - "required": false, - "in": "query", - "name": "b", - "schema": { - "anyOf": [ - { - "type": "number", - "format": "decimal" - }, - { - "enum": [ - "-INF", - "INF", - "NaN" - ] - } - ], - "nullable": true - } - }, - { - "required": false, - "in": "query", - "name": "a", - "schema": { - "type": "integer", - "format": "int32", - "minimum": -2147483648, - "maximum": 2147483647, - "nullable": true - } - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Edm.Int32" - } - } - } - }, - "204": { - "description": "Success" - }, - "4XX": { - "$ref": "#/components/responses/error" - } - } - } - }, "/$batch": { "post": { "summary": "Send a group of requests", diff --git a/tests/Unit/Operation/__snapshots__/Repository73Test__test_code__1.json b/tests/Unit/Operation/__snapshots__/Repository73Test__test_code__1.json new file mode 100644 index 000000000..5a7f606f6 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/Repository73Test__test_code__1.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.String", + "value": "lhr" +} diff --git a/tests/Unit/Operation/__snapshots__/Repository73Test__test_code_args__1.json b/tests/Unit/Operation/__snapshots__/Repository73Test__test_code_args__1.json new file mode 100644 index 000000000..6b45683d8 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/Repository73Test__test_code_args__1.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.String", + "value": "lhrhere" +} diff --git a/tests/Unit/Operation/__snapshots__/Repository73Test__test_metadata__1.xml b/tests/Unit/Operation/__snapshots__/Repository73Test__test_metadata__1.xml new file mode 100644 index 000000000..06ab7c35e --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/Repository73Test__test_metadata__1.xml @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/Repository73Test__test_metadata__2.yml b/tests/Unit/Operation/__snapshots__/Repository73Test__test_metadata__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/Repository73Test__test_metadata__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/Repository73Test__test_metadata__3.json b/tests/Unit/Operation/__snapshots__/Repository73Test__test_metadata__3.json new file mode 100644 index 000000000..26cbad9c7 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/Repository73Test__test_metadata__3.json @@ -0,0 +1,166 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "Airports": { + "$EntityType": "com.example.odata.Airport", + "$NavigationPropertyBinding": {}, + "@Org.OData.Capabilities.V1.CountRestrictions": { + "Countable": true + }, + "@Org.OData.Capabilities.V1.TopSupported": true, + "@Org.OData.Capabilities.V1.SkipSupported": true, + "@Org.OData.Capabilities.V1.FilterRestrictions": { + "Filterable": true + }, + "@Org.OData.Capabilities.V1.SortRestrictions": { + "Sortable": true + }, + "@Org.OData.Capabilities.V1.ExpandRestrictions": { + "Expandable": true + }, + "@Org.OData.Capabilities.V1.SearchRestrictions": { + "Searchable": true + }, + "@Org.OData.Capabilities.V1.InsertRestrictions": { + "Insertable": true + }, + "@Org.OData.Capabilities.V1.UpdateRestrictions": { + "Updatable": true, + "DeltaUpdateSupported": true + }, + "@Org.OData.Capabilities.V1.DeleteRestrictions": { + "Deletable": true + }, + "@Org.OData.Capabilities.V1.ReadRestrictions": { + "Readable": true + }, + "@Org.OData.Capabilities.V1.IndexableByKey": true, + "@Org.OData.Capabilities.V1.SelectSupport": { + "Supported": true + }, + "@Org.OData.Capabilities.V1.DeepInsertSupport": { + "Supported": true, + "ContentIDSupported": true + } + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "Airport": { + "$Kind": "EntityType", + "$Key": [ + "id" + ], + "id": { + "$Type": "Edm.Int64", + "$Nullable": false, + "@Org.OData.Core.V1.Computed": true + }, + "name": { + "$Type": "Edm.String", + "$Nullable": false + }, + "code": { + "$Type": "Edm.String", + "$Nullable": false + }, + "construction_date": { + "$Type": "Edm.Date", + "$Nullable": true + }, + "sam_datetime": { + "$Type": "Edm.DateTimeOffset", + "$Nullable": true + }, + "open_time": { + "$Type": "Edm.TimeOfDay", + "$Nullable": true + }, + "review_score": { + "$Type": "Edm.Decimal", + "$Nullable": true + }, + "is_big": { + "$Type": "Edm.Boolean", + "$Nullable": true + }, + "country_id": { + "$Type": "Edm.Int32", + "$Nullable": true + } + }, + "code": { + "$Kind": "Function", + "$IsBound": true, + "$Parameter": [ + { + "$Name": "airport", + "$Nullable": false, + "$Type": "com.example.odata.Airport" + }, + { + "$Name": "suffix", + "$Nullable": true, + "$Type": "Edm.String" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.String", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/Repository73Test__test_metadata__4.json b/tests/Unit/Operation/__snapshots__/Repository73Test__test_metadata__4.json new file mode 100644 index 000000000..fad3239cb --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/Repository73Test__test_metadata__4.json @@ -0,0 +1,791 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [ + { + "name": "Airports" + } + ], + "paths": { + "/Airports": { + "get": { + "summary": "Get entities from Airports", + "tags": [ + "Airports" + ], + "parameters": [ + { + "name": "select", + "in": "query", + "description": "Select properties to be returned, see [OData Select](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionselect)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "*", + "id", + "name", + "code", + "construction_date", + "sam_datetime", + "open_time", + "review_score", + "is_big", + "country_id" + ] + } + } + }, + { + "$ref": "#/components/parameters/count" + }, + { + "$ref": "#/components/parameters/filter" + }, + { + "$ref": "#/components/parameters/search" + }, + { + "$ref": "#/components/parameters/top" + }, + { + "$ref": "#/components/parameters/skip" + }, + { + "name": "orderby", + "in": "query", + "description": "Order items by property values, see [OData Sorting](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionorderby)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "id", + "id desc", + "name", + "name desc", + "code", + "code desc", + "construction_date", + "construction_date desc", + "sam_datetime", + "sam_datetime desc", + "open_time", + "open_time desc", + "review_score", + "review_score desc", + "is_big", + "is_big desc", + "country_id", + "country_id desc" + ] + } + } + } + ], + "responses": { + "200": { + "description": "Retrieved entities", + "content": { + "application/json": { + "schema": { + "type": "object", + "title": "Collection of Airports", + "properties": { + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/com.example.odata.Airport" + } + }, + "@count": { + "$ref": "#/components/schemas/count" + } + } + } + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + }, + "post": { + "summary": "Add new entity to Airports", + "tags": [ + "Airports" + ], + "requestBody": { + "required": true, + "description": "New entity", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.Airport~create" + } + } + } + }, + "responses": { + "201": { + "description": "Created entity", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.Airport" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/Airports/{id}": { + "parameters": [ + { + "description": "Key: id", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807, + "nullable": false + } + } + ], + "get": { + "summary": "Get entity from Airports by key", + "tags": [ + "Airports" + ], + "parameters": [ + { + "name": "select", + "in": "query", + "description": "Select properties to be returned, see [OData Select](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionselect)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "*", + "id", + "name", + "code", + "construction_date", + "sam_datetime", + "open_time", + "review_score", + "is_big", + "country_id" + ] + } + } + } + ], + "responses": { + "200": { + "description": "Retrieved entity", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.Airport" + } + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + }, + "patch": { + "summary": "Update entity in Airports", + "tags": [ + "Airports" + ], + "requestBody": { + "description": "New property values", + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.Airport~update" + } + } + } + }, + "responses": { + "200": { + "$ref": "#/components/schemas/com.example.odata.Airport" + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + }, + "delete": { + "summary": "Delete entity from Airports", + "tags": [ + "Airports" + ], + "responses": { + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "com.example.odata.Airport": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807, + "nullable": false + }, + "name": { + "type": "string", + "nullable": false + }, + "code": { + "type": "string", + "nullable": false + }, + "construction_date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$", + "nullable": true + }, + "sam_datetime": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$", + "nullable": true + }, + "open_time": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$", + "nullable": true + }, + "review_score": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ], + "nullable": true + }, + "is_big": { + "type": "boolean", + "nullable": true + }, + "country_id": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647, + "nullable": true + } + } + }, + "com.example.odata.Airport~create": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": false + }, + "code": { + "type": "string", + "nullable": false + }, + "construction_date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$", + "nullable": true + }, + "sam_datetime": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$", + "nullable": true + }, + "open_time": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$", + "nullable": true + }, + "review_score": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ], + "nullable": true + }, + "is_big": { + "type": "boolean", + "nullable": true + }, + "country_id": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647, + "nullable": true + } + } + }, + "com.example.odata.Airport~update": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": false + }, + "code": { + "type": "string", + "nullable": false + }, + "construction_date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$", + "nullable": true + }, + "sam_datetime": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$", + "nullable": true + }, + "open_time": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$", + "nullable": true + }, + "review_score": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ], + "nullable": true + }, + "is_big": { + "type": "boolean", + "nullable": true + }, + "country_id": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647, + "nullable": true + } + } + }, + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/RepositoryTest__test_code__1.json b/tests/Unit/Operation/__snapshots__/RepositoryTest__test_code__1.json new file mode 100644 index 000000000..5a7f606f6 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/RepositoryTest__test_code__1.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.String", + "value": "lhr" +} diff --git a/tests/Unit/Operation/__snapshots__/RepositoryTest__test_code_args__1.json b/tests/Unit/Operation/__snapshots__/RepositoryTest__test_code_args__1.json new file mode 100644 index 000000000..6b45683d8 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/RepositoryTest__test_code_args__1.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.String", + "value": "lhrhere" +} diff --git a/tests/Unit/Operation/__snapshots__/RepositoryTest__test_metadata__1.xml b/tests/Unit/Operation/__snapshots__/RepositoryTest__test_metadata__1.xml new file mode 100644 index 000000000..141f4f103 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/RepositoryTest__test_metadata__1.xml @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + multipart/mixed + + + + + + + + + + + + + + + + + + + + + application/json;metadata=full;IEEE754Compatible=true;streaming=true + application/json;metadata=minimal;IEEE754Compatible=true;streaming=true + application/json;metadata=none;IEEE754Compatible=true;streaming=true + + + + + application/json + application/xml + + + + + + diff --git a/tests/Unit/Operation/__snapshots__/RepositoryTest__test_metadata__2.yml b/tests/Unit/Operation/__snapshots__/RepositoryTest__test_metadata__2.yml new file mode 100644 index 000000000..c89daea65 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/RepositoryTest__test_metadata__2.yml @@ -0,0 +1,6 @@ +headers: + cache-control: ['no-cache, private'] + content-type: [application/xml] + odata-version: ['4.01'] + trailer: [odata-error] +status: 200 diff --git a/tests/Unit/Operation/__snapshots__/RepositoryTest__test_metadata__3.json b/tests/Unit/Operation/__snapshots__/RepositoryTest__test_metadata__3.json new file mode 100644 index 000000000..4d6b3a566 --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/RepositoryTest__test_metadata__3.json @@ -0,0 +1,198 @@ +{ + "$Version": "4.01", + "$EntityContainer": "com.example.odata.DefaultContainer", + "$Reference": { + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Core.V1" + } + ] + }, + "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": { + "$Include": [ + { + "$Namespace": "Org.OData.Capabilities.V1" + } + ] + } + }, + "com.example.odata": { + "$Kind": "EntityContainer", + "Airports": { + "$EntityType": "com.example.odata.Airport", + "$NavigationPropertyBinding": {}, + "@Org.OData.Capabilities.V1.CountRestrictions": { + "Countable": true + }, + "@Org.OData.Capabilities.V1.TopSupported": true, + "@Org.OData.Capabilities.V1.SkipSupported": true, + "@Org.OData.Capabilities.V1.FilterRestrictions": { + "Filterable": true + }, + "@Org.OData.Capabilities.V1.SortRestrictions": { + "Sortable": true + }, + "@Org.OData.Capabilities.V1.ExpandRestrictions": { + "Expandable": true + }, + "@Org.OData.Capabilities.V1.SearchRestrictions": { + "Searchable": true + }, + "@Org.OData.Capabilities.V1.InsertRestrictions": { + "Insertable": true + }, + "@Org.OData.Capabilities.V1.UpdateRestrictions": { + "Updatable": true, + "DeltaUpdateSupported": true + }, + "@Org.OData.Capabilities.V1.DeleteRestrictions": { + "Deletable": true + }, + "@Org.OData.Capabilities.V1.ReadRestrictions": { + "Readable": true + }, + "@Org.OData.Capabilities.V1.IndexableByKey": true, + "@Org.OData.Capabilities.V1.SelectSupport": { + "Supported": true + }, + "@Org.OData.Capabilities.V1.DeepInsertSupport": { + "Supported": true, + "ContentIDSupported": true + } + }, + "op1Import": { + "$Function": "com.example.odata.op1" + }, + "op2Import": { + "$Function": "com.example.odata.op2" + }, + "$Annotations": { + "com.example.odata.DefaultContainer": { + "@Org.OData.Core.V1.ConventionalIDs": true, + "@Org.OData.Core.V1.DefaultNamespace": true, + "@Org.OData.Core.V1.DereferencableIDs": true, + "@Org.OData.Core.V1.ODataVersions": "4.01", + "@Org.OData.Capabilities.V1.AsynchronousRequestsSupported": true, + "@Org.OData.Capabilities.V1.BatchSupported": true, + "@Org.OData.Capabilities.V1.BatchSupport": { + "Supported": true, + "EtagReferencesSupported": true, + "SupportedFormats": [ + "application/json", + "multipart/mixed" + ] + }, + "@Org.OData.Capabilities.V1.CallbackSupported": { + "CallbackProtocols": [ + { + "Id": "http" + } + ] + }, + "@Org.OData.Capabilities.V1.ConformanceLevel": "Org.OData.Capabilities.V1.ConformanceLevelType/Advanced", + "@Org.OData.Capabilities.V1.KeyAsSegmentSupported": true, + "@Org.OData.Capabilities.V1.QuerySegmentSupported": true, + "@Org.OData.Capabilities.V1.SupportedFormats": [ + "application/json;metadata=full;IEEE754Compatible=true;streaming=true", + "application/json;metadata=minimal;IEEE754Compatible=true;streaming=true", + "application/json;metadata=none;IEEE754Compatible=true;streaming=true" + ], + "@Org.OData.Capabilities.V1.SupportedMetadataFormats": [ + "application/json", + "application/xml" + ] + } + } + }, + "Airport": { + "$Kind": "EntityType", + "$Key": [ + "id" + ], + "id": { + "$Type": "Edm.Int64", + "$Nullable": false, + "@Org.OData.Core.V1.Computed": true + }, + "name": { + "$Type": "Edm.String", + "$Nullable": false + }, + "code": { + "$Type": "Edm.String", + "$Nullable": false + }, + "construction_date": { + "$Type": "Edm.Date", + "$Nullable": true + }, + "sam_datetime": { + "$Type": "Edm.DateTimeOffset", + "$Nullable": true + }, + "open_time": { + "$Type": "Edm.TimeOfDay", + "$Nullable": true + }, + "review_score": { + "$Type": "Edm.Decimal", + "$Nullable": true + }, + "is_big": { + "$Type": "Edm.Boolean", + "$Nullable": true + }, + "country_id": { + "$Type": "Edm.Int32", + "$Nullable": true + } + }, + "op1": { + "$Kind": "Function", + "$IsBound": false, + "$Parameter": [], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.String", + "$Nullable": true + } + }, + "op2": { + "$Kind": "Function", + "$IsBound": false, + "$Parameter": [ + { + "$Name": "prefix", + "$Nullable": false, + "$Type": "Edm.String" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.String", + "$Nullable": false + } + }, + "code": { + "$Kind": "Function", + "$IsBound": true, + "$Parameter": [ + { + "$Name": "airport", + "$Nullable": false, + "$Type": "com.example.odata.Airport" + }, + { + "$Name": "suffix", + "$Nullable": true, + "$Type": "Edm.String" + } + ], + "$ReturnType": { + "$Collection": false, + "$Type": "Edm.String", + "$Nullable": false + } + } +} diff --git a/tests/Unit/Operation/__snapshots__/RepositoryTest__test_metadata__4.json b/tests/Unit/Operation/__snapshots__/RepositoryTest__test_metadata__4.json new file mode 100644 index 000000000..ea266a40d --- /dev/null +++ b/tests/Unit/Operation/__snapshots__/RepositoryTest__test_metadata__4.json @@ -0,0 +1,856 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OData Service for namespace com.example.odata", + "version": "1.0.0", + "description": "This OData service is located at [http://localhost/odata](http://localhost/odata)\n\n## References\n- [Org.OData.Core.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md)\n- [Org.OData.Measures.V1](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Measures.V1.md)" + }, + "servers": [ + { + "url": "http://localhost/odata" + } + ], + "tags": [ + { + "name": "Airports" + } + ], + "paths": { + "/Airports": { + "get": { + "summary": "Get entities from Airports", + "tags": [ + "Airports" + ], + "parameters": [ + { + "name": "select", + "in": "query", + "description": "Select properties to be returned, see [OData Select](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionselect)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "*", + "id", + "name", + "code", + "construction_date", + "sam_datetime", + "open_time", + "review_score", + "is_big", + "country_id" + ] + } + } + }, + { + "$ref": "#/components/parameters/count" + }, + { + "$ref": "#/components/parameters/filter" + }, + { + "$ref": "#/components/parameters/search" + }, + { + "$ref": "#/components/parameters/top" + }, + { + "$ref": "#/components/parameters/skip" + }, + { + "name": "orderby", + "in": "query", + "description": "Order items by property values, see [OData Sorting](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionorderby)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "id", + "id desc", + "name", + "name desc", + "code", + "code desc", + "construction_date", + "construction_date desc", + "sam_datetime", + "sam_datetime desc", + "open_time", + "open_time desc", + "review_score", + "review_score desc", + "is_big", + "is_big desc", + "country_id", + "country_id desc" + ] + } + } + } + ], + "responses": { + "200": { + "description": "Retrieved entities", + "content": { + "application/json": { + "schema": { + "type": "object", + "title": "Collection of Airports", + "properties": { + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/com.example.odata.Airport" + } + }, + "@count": { + "$ref": "#/components/schemas/count" + } + } + } + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + }, + "post": { + "summary": "Add new entity to Airports", + "tags": [ + "Airports" + ], + "requestBody": { + "required": true, + "description": "New entity", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.Airport~create" + } + } + } + }, + "responses": { + "201": { + "description": "Created entity", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.Airport" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/Airports/{id}": { + "parameters": [ + { + "description": "Key: id", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807, + "nullable": false + } + } + ], + "get": { + "summary": "Get entity from Airports by key", + "tags": [ + "Airports" + ], + "parameters": [ + { + "name": "select", + "in": "query", + "description": "Select properties to be returned, see [OData Select](https://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_SystemQueryOptionselect)", + "explode": false, + "schema": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "*", + "id", + "name", + "code", + "construction_date", + "sam_datetime", + "open_time", + "review_score", + "is_big", + "country_id" + ] + } + } + } + ], + "responses": { + "200": { + "description": "Retrieved entity", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.Airport" + } + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + }, + "patch": { + "summary": "Update entity in Airports", + "tags": [ + "Airports" + ], + "requestBody": { + "description": "New property values", + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.example.odata.Airport~update" + } + } + } + }, + "responses": { + "200": { + "$ref": "#/components/schemas/com.example.odata.Airport" + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + }, + "delete": { + "summary": "Delete entity from Airports", + "tags": [ + "Airports" + ], + "responses": { + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/op1": { + "get": { + "tags": [ + "Service Operations", + "op1" + ], + "parameters": [], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.String" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/op2": { + "get": { + "tags": [ + "Service Operations", + "op2", + "prefix" + ], + "parameters": [ + { + "required": false, + "in": "query", + "name": "prefix", + "schema": { + "type": "string", + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Edm.String" + } + } + } + }, + "204": { + "description": "Success" + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + }, + "/$batch": { + "post": { + "summary": "Send a group of requests", + "description": "Group multiple requests into a single request payload, see [Batch Requests](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_BatchRequests)", + "tags": [ + "Batch Requests" + ], + "requestBody": { + "required": true, + "description": "Batch Request", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "requests": [ + { + "id": "0", + "method": "get", + "url": "/odata/resource(1)" + }, + { + "id": "1", + "method": "patch", + "url": "/odata/resource(2)", + "headers": { + "Prefer": "return=minimal" + }, + "body": "" + } + ] + } + }, + "multipart/mixed;boundary=request-separator": { + "schema": { + "type": "string" + }, + "example": "--request-separator\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\nGET odata/resource HTTP/1.1\nAccept: application/json\n\n\n-request-separator--" + } + } + }, + "responses": { + "200": { + "description": "Batch response", + "content": { + "application/json": { + "schema": { + "type": "string" + }, + "example": { + "responses": [ + { + "id": "0", + "status": 200, + "body": "" + }, + { + "id": "1", + "status": 204 + } + ] + } + }, + "multipart/mixed": { + "schema": { + "type": "string" + }, + "example": "--response-separator\nContent-Type: application/http\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{...}\n--response-separator--" + } + } + }, + "4XX": { + "$ref": "#/components/responses/error" + } + } + } + } + }, + "components": { + "schemas": { + "com.example.odata.Airport": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807, + "nullable": false + }, + "name": { + "type": "string", + "nullable": false + }, + "code": { + "type": "string", + "nullable": false + }, + "construction_date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$", + "nullable": true + }, + "sam_datetime": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$", + "nullable": true + }, + "open_time": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$", + "nullable": true + }, + "review_score": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ], + "nullable": true + }, + "is_big": { + "type": "boolean", + "nullable": true + }, + "country_id": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647, + "nullable": true + } + } + }, + "com.example.odata.Airport~create": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": false + }, + "code": { + "type": "string", + "nullable": false + }, + "construction_date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$", + "nullable": true + }, + "sam_datetime": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$", + "nullable": true + }, + "open_time": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$", + "nullable": true + }, + "review_score": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ], + "nullable": true + }, + "is_big": { + "type": "boolean", + "nullable": true + }, + "country_id": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647, + "nullable": true + } + } + }, + "com.example.odata.Airport~update": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": false + }, + "code": { + "type": "string", + "nullable": false + }, + "construction_date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$", + "nullable": true + }, + "sam_datetime": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$", + "nullable": true + }, + "open_time": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$", + "nullable": true + }, + "review_score": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ], + "nullable": true + }, + "is_big": { + "type": "boolean", + "nullable": true + }, + "country_id": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647, + "nullable": true + } + } + }, + "Edm.ComplexType": { + "type": "object" + }, + "Edm.EntityType": { + "type": "object" + }, + "Edm.PrimitiveType": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "Edm.AnnotationPath": { + "type": "string" + }, + "Edm.NavigationPropertyPath": { + "type": "string" + }, + "Edm.PropertyPath": { + "type": "string" + }, + "Edm.Binary": { + "type": "string", + "format": "base64url", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{3}[A-Za-z0-9_-]|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=?|[A-Za-z0-9_-][AQgw](==)?)?$" + }, + "Edm.Byte": { + "type": "integer", + "format": "uint8", + "minimum": 0, + "maximum": 255 + }, + "Edm.Date": { + "type": "string", + "format": "date", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" + }, + "Edm.DateTimeOffset": { + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$" + }, + "Edm.Double": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Duration": { + "type": "string", + "format": "duration", + "pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$" + }, + "Edm.Guid": { + "type": "string", + "format": "uuid", + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + }, + "Edm.Int16": { + "type": "integer", + "format": "int16", + "minimum": -32768, + "maximum": 32767 + }, + "Edm.Int32": { + "type": "integer", + "format": "int32", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "Edm.Int64": { + "type": "integer", + "format": "int64", + "minimum": -9223372036854775808, + "maximum": 9223372036854775807 + }, + "Edm.String": { + "type": "string" + }, + "Edm.Boolean": { + "type": "boolean" + }, + "Edm.SByte": { + "type": "integer", + "format": "int8", + "minimum": -128, + "maximum": 127 + }, + "Edm.Single": { + "anyOf": [ + { + "type": "number", + "format": "single" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Decimal": { + "anyOf": [ + { + "type": "number", + "format": "decimal" + }, + { + "enum": [ + "-INF", + "INF", + "NaN" + ] + } + ] + }, + "Edm.Stream": { + "type": "string", + "format": "base64url" + }, + "Edm.TimeOfDay": { + "type": "string", + "format": "time", + "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$" + }, + "count": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string" + } + ], + "description": "The number of entities in the collection. Available when using the [$count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount) query option" + } + }, + "responses": { + "error": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "target": { + "type": "string" + } + } + } + }, + "innererror": { + "type": "object", + "description": "The structure of this object is service-specific" + } + } + } + } + } + } + } + } + }, + "parameters": { + "top": { + "name": "top", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Show only the first n items, see [OData Paging \u2013 Top](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptiontop)" + }, + "skip": { + "name": "skip", + "schema": { + "type": "integer", + "minimum": 0 + }, + "in": "query", + "description": "Skip the first n items, see [OData Paging - Skip](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionskip)" + }, + "skiptoken": { + "name": "skiptoken", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Skip using a skip token, see [OData Server Driven Paging](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging)" + }, + "count": { + "name": "count", + "schema": { + "type": "boolean" + }, + "in": "query", + "description": "Include count of items, see [OData Count](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptioncount)" + }, + "filter": { + "name": "filter", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Filter items by property values, see [OData Filtering](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionfilter)" + }, + "search": { + "name": "search", + "schema": { + "type": "string" + }, + "in": "query", + "description": "Search items by search phrases, see [OData Searching](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_SystemQueryOptionsearch)" + } + } + } +} diff --git a/tests/Unit/Parser/__snapshots__/FilterTest__test_43__3.yml b/tests/Unit/Parser/__snapshots__/FilterTest__test_43__3.yml index 10f716e29..71f7d3b5c 100644 --- a/tests/Unit/Parser/__snapshots__/FilterTest__test_43__3.yml +++ b/tests/Unit/Parser/__snapshots__/FilterTest__test_43__3.yml @@ -1 +1 @@ -- !!float 60 +- 60.0 diff --git a/tests/Unit/Parser/__snapshots__/FilterTest__test_43__5.yml b/tests/Unit/Parser/__snapshots__/FilterTest__test_43__5.yml index 10f716e29..71f7d3b5c 100644 --- a/tests/Unit/Parser/__snapshots__/FilterTest__test_43__5.yml +++ b/tests/Unit/Parser/__snapshots__/FilterTest__test_43__5.yml @@ -1 +1 @@ -- !!float 60 +- 60.0 diff --git a/tests/Unit/Parser/__snapshots__/FilterTest__test_43__7.yml b/tests/Unit/Parser/__snapshots__/FilterTest__test_43__7.yml index 10f716e29..71f7d3b5c 100644 --- a/tests/Unit/Parser/__snapshots__/FilterTest__test_43__7.yml +++ b/tests/Unit/Parser/__snapshots__/FilterTest__test_43__7.yml @@ -1 +1 @@ -- !!float 60 +- 60.0 diff --git a/tests/Unit/Parser/__snapshots__/FilterTest__test_43__9.yml b/tests/Unit/Parser/__snapshots__/FilterTest__test_43__9.yml index 10f716e29..71f7d3b5c 100644 --- a/tests/Unit/Parser/__snapshots__/FilterTest__test_43__9.yml +++ b/tests/Unit/Parser/__snapshots__/FilterTest__test_43__9.yml @@ -1 +1 @@ -- !!float 60 +- 60.0 diff --git a/tests/Unit/Parser/__snapshots__/FilterTest__test_44__3.yml b/tests/Unit/Parser/__snapshots__/FilterTest__test_44__3.yml index b2b1a5f7a..f81534e7a 100644 --- a/tests/Unit/Parser/__snapshots__/FilterTest__test_44__3.yml +++ b/tests/Unit/Parser/__snapshots__/FilterTest__test_44__3.yml @@ -1 +1 @@ -- !!float 129600 +- 129600.0 diff --git a/tests/Unit/Parser/__snapshots__/FilterTest__test_44__5.yml b/tests/Unit/Parser/__snapshots__/FilterTest__test_44__5.yml index b2b1a5f7a..f81534e7a 100644 --- a/tests/Unit/Parser/__snapshots__/FilterTest__test_44__5.yml +++ b/tests/Unit/Parser/__snapshots__/FilterTest__test_44__5.yml @@ -1 +1 @@ -- !!float 129600 +- 129600.0 diff --git a/tests/Unit/Parser/__snapshots__/FilterTest__test_44__7.yml b/tests/Unit/Parser/__snapshots__/FilterTest__test_44__7.yml index b2b1a5f7a..f81534e7a 100644 --- a/tests/Unit/Parser/__snapshots__/FilterTest__test_44__7.yml +++ b/tests/Unit/Parser/__snapshots__/FilterTest__test_44__7.yml @@ -1 +1 @@ -- !!float 129600 +- 129600.0 diff --git a/tests/Unit/Parser/__snapshots__/FilterTest__test_44__9.yml b/tests/Unit/Parser/__snapshots__/FilterTest__test_44__9.yml index b2b1a5f7a..f81534e7a 100644 --- a/tests/Unit/Parser/__snapshots__/FilterTest__test_44__9.yml +++ b/tests/Unit/Parser/__snapshots__/FilterTest__test_44__9.yml @@ -1 +1 @@ -- !!float 129600 +- 129600.0 diff --git a/tests/Unit/Parser/__snapshots__/FilterTest__test_45__3.yml b/tests/Unit/Parser/__snapshots__/FilterTest__test_45__3.yml index 9b28a7f28..0ba673e19 100644 --- a/tests/Unit/Parser/__snapshots__/FilterTest__test_45__3.yml +++ b/tests/Unit/Parser/__snapshots__/FilterTest__test_45__3.yml @@ -1 +1 @@ -- !!float 873000 +- 873000.0 diff --git a/tests/Unit/Parser/__snapshots__/FilterTest__test_45__5.yml b/tests/Unit/Parser/__snapshots__/FilterTest__test_45__5.yml index 9b28a7f28..0ba673e19 100644 --- a/tests/Unit/Parser/__snapshots__/FilterTest__test_45__5.yml +++ b/tests/Unit/Parser/__snapshots__/FilterTest__test_45__5.yml @@ -1 +1 @@ -- !!float 873000 +- 873000.0 diff --git a/tests/Unit/Parser/__snapshots__/FilterTest__test_45__7.yml b/tests/Unit/Parser/__snapshots__/FilterTest__test_45__7.yml index 9b28a7f28..0ba673e19 100644 --- a/tests/Unit/Parser/__snapshots__/FilterTest__test_45__7.yml +++ b/tests/Unit/Parser/__snapshots__/FilterTest__test_45__7.yml @@ -1 +1 @@ -- !!float 873000 +- 873000.0 diff --git a/tests/Unit/Parser/__snapshots__/FilterTest__test_45__9.yml b/tests/Unit/Parser/__snapshots__/FilterTest__test_45__9.yml index 9b28a7f28..0ba673e19 100644 --- a/tests/Unit/Parser/__snapshots__/FilterTest__test_45__9.yml +++ b/tests/Unit/Parser/__snapshots__/FilterTest__test_45__9.yml @@ -1 +1 @@ -- !!float 873000 +- 873000.0 diff --git a/tests/Unit/Parser/__snapshots__/FilterTest__test_5f__3.yml b/tests/Unit/Parser/__snapshots__/FilterTest__test_5f__3.yml index 9ade1fb9b..7a3508a7b 100644 --- a/tests/Unit/Parser/__snapshots__/FilterTest__test_5f__3.yml +++ b/tests/Unit/Parser/__snapshots__/FilterTest__test_5f__3.yml @@ -1 +1 @@ -- !!float 180 +- 180.0 diff --git a/tests/Unit/Parser/__snapshots__/FilterTest__test_5f__5.yml b/tests/Unit/Parser/__snapshots__/FilterTest__test_5f__5.yml index 9ade1fb9b..7a3508a7b 100644 --- a/tests/Unit/Parser/__snapshots__/FilterTest__test_5f__5.yml +++ b/tests/Unit/Parser/__snapshots__/FilterTest__test_5f__5.yml @@ -1 +1 @@ -- !!float 180 +- 180.0 diff --git a/tests/Unit/Parser/__snapshots__/FilterTest__test_5f__7.yml b/tests/Unit/Parser/__snapshots__/FilterTest__test_5f__7.yml index 9ade1fb9b..7a3508a7b 100644 --- a/tests/Unit/Parser/__snapshots__/FilterTest__test_5f__7.yml +++ b/tests/Unit/Parser/__snapshots__/FilterTest__test_5f__7.yml @@ -1 +1 @@ -- !!float 180 +- 180.0 diff --git a/tests/Unit/Parser/__snapshots__/FilterTest__test_5f__9.yml b/tests/Unit/Parser/__snapshots__/FilterTest__test_5f__9.yml index 9ade1fb9b..7a3508a7b 100644 --- a/tests/Unit/Parser/__snapshots__/FilterTest__test_5f__9.yml +++ b/tests/Unit/Parser/__snapshots__/FilterTest__test_5f__9.yml @@ -1 +1 @@ -- !!float 180 +- 180.0 diff --git a/tests/Unit/Protocol/BatchJSONTest.php b/tests/Unit/Protocol/BatchJSONTest.php index 562000b01..5df707342 100644 --- a/tests/Unit/Protocol/BatchJSONTest.php +++ b/tests/Unit/Protocol/BatchJSONTest.php @@ -3,8 +3,6 @@ namespace Flat3\Lodata\Tests\Unit\Protocol; use Flat3\Lodata\Facades\Lodata; -use Flat3\Lodata\Interfaces\Operation\ActionInterface; -use Flat3\Lodata\Interfaces\Operation\FunctionInterface; use Flat3\Lodata\Operation; use Flat3\Lodata\Tests\Request; use Flat3\Lodata\Tests\TestCase; @@ -150,12 +148,11 @@ public function test_metadata_document() public function test_action_invocation() { - Lodata::add(new class('aa1') extends Operation implements ActionInterface { - public function invoke(Int32 $a, Int32 $b): Int32 - { - return new Int32($a->get() + $b->get()); - } + $aa1 = new Operation\Action('aa1'); + $aa1->setCallable(function (Int32 $a, Int32 $b): Int32 { + return new Int32($a->get() + $b->get()); }); + Lodata::add($aa1); $this->assertJsonMetadataResponse( (new Request) @@ -180,12 +177,11 @@ public function invoke(Int32 $a, Int32 $b): Int32 public function test_function_invocation() { - Lodata::add(new class('aa1') extends Operation implements FunctionInterface { - public function invoke(Int32 $a, Int32 $b): Int32 - { - return new Int32($a->get() + $b->get()); - } + $aa1 = new Operation\Function_('aa1'); + $aa1->setCallable(function (Int32 $a, Int32 $b): Int32 { + return new Int32($a->get() + $b->get()); }); + Lodata::add($aa1); $this->assertJsonMetadataResponse( (new Request) diff --git a/tests/Unit/Protocol/BatchMultipartTest.php b/tests/Unit/Protocol/BatchMultipartTest.php index 87a447aed..3d91fdc6c 100644 --- a/tests/Unit/Protocol/BatchMultipartTest.php +++ b/tests/Unit/Protocol/BatchMultipartTest.php @@ -3,8 +3,6 @@ namespace Flat3\Lodata\Tests\Unit\Protocol; use Flat3\Lodata\Facades\Lodata; -use Flat3\Lodata\Interfaces\Operation\ActionInterface; -use Flat3\Lodata\Interfaces\Operation\FunctionInterface; use Flat3\Lodata\Operation; use Flat3\Lodata\Tests\Request; use Flat3\Lodata\Tests\TestCase; @@ -170,12 +168,11 @@ public function test_metadata_document() public function test_action_invocation() { - Lodata::add(new class('aa1') extends Operation implements ActionInterface { - public function invoke(Int32 $a, Int32 $b): Int32 - { - return new Int32($a->get() + $b->get()); - } + $aa1 = new Operation\Action('aa1'); + $aa1->setCallable(function (Int32 $a, Int32 $b): Int32 { + return new Int32($a->get() + $b->get()); }); + Lodata::add($aa1); $this->assertTextMetadataResponse( (new Request) @@ -203,12 +200,11 @@ public function invoke(Int32 $a, Int32 $b): Int32 public function test_function_invocation() { - Lodata::add(new class('aa1') extends Operation implements FunctionInterface { - public function invoke(Int32 $a, Int32 $b): Int32 - { - return new Int32($a->get() + $b->get()); - } + $aa1 = new Operation\Function_('aa1'); + $aa1->setCallable(function (Int32 $a, Int32 $b): Int32 { + return new Int32($a->get() + $b->get()); }); + Lodata::add($aa1); $this->assertTextMetadataResponse( (new Request) diff --git a/tests/Unit/Protocol/ContentTest.php b/tests/Unit/Protocol/ContentTest.php index 4333f84ac..4256efebd 100644 --- a/tests/Unit/Protocol/ContentTest.php +++ b/tests/Unit/Protocol/ContentTest.php @@ -4,7 +4,7 @@ use Flat3\Lodata\Controller\Transaction; use Flat3\Lodata\Facades\Lodata; -use Flat3\Lodata\Interfaces\Operation\FunctionInterface; +use Flat3\Lodata\Helper\Constants; use Flat3\Lodata\Operation; use Flat3\Lodata\Tests\Request; use Flat3\Lodata\Tests\TestCase; @@ -14,13 +14,12 @@ class ContentTest extends TestCase { public function test_content_encoding() { - Lodata::add(new class('exf1') extends Operation implements FunctionInterface { - function invoke(Transaction $transaction): String_ - { - $transaction->setContentEncoding('identity'); - return new String_('hello'); - } + $exf1 = new Operation\Function_('exf1'); + $exf1->setCallable(function (Transaction $transaction): String_ { + $transaction->setContentEncoding('identity'); + return new String_('hello'); }); + Lodata::add($exf1); $this->assertMetadataResponse( (new Request) @@ -30,17 +29,46 @@ function invoke(Transaction $transaction): String_ public function test_content_language() { - Lodata::add(new class('exf1') extends Operation implements FunctionInterface { - function invoke(Transaction $transaction): String_ - { - $transaction->setContentLanguage('fr'); - return new String_('bonjour'); - } + $exf1 = new Operation\Function_('exf1'); + $exf1->setCallable(function (Transaction $transaction): String_ { + $transaction->setContentLanguage('fr'); + return new String_('hello'); }); + Lodata::add($exf1); $this->assertMetadataResponse( (new Request) ->path('/exf1()') ); } + + public function test_get_content_language() + { + $op = new Operation\Function_('op'); + $op->setCallable(function (Transaction $transaction): string { + return $transaction->getContentLanguage(); + }); + Lodata::add($op); + + $this->assertJsonResponse( + (new Request) + ->header(Constants::contentLanguage, 'tr') + ->path('/op()') + ); + } + + public function test_get_content_encoding() + { + $op = new Operation\Function_('op'); + $op->setCallable(function (Transaction $transaction): string { + return $transaction->getContentEncoding(); + }); + Lodata::add($op); + + $this->assertJsonResponse( + (new Request) + ->header(Constants::contentEncoding, 'utf-16') + ->path('/op()') + ); + } } diff --git a/tests/Unit/Protocol/ContextResourceTest.php b/tests/Unit/Protocol/ContextResourceTest.php index 4a666d864..00a4eb731 100644 --- a/tests/Unit/Protocol/ContextResourceTest.php +++ b/tests/Unit/Protocol/ContextResourceTest.php @@ -6,7 +6,6 @@ use Flat3\Lodata\EntitySet; use Flat3\Lodata\Facades\Lodata; -use Flat3\Lodata\Interfaces\Operation\FunctionInterface; use Flat3\Lodata\Operation; use Flat3\Lodata\Tests\Request; use Flat3\Lodata\Tests\TestCase; @@ -130,12 +129,12 @@ public function test_property_value() public function test_operation_result() { - Lodata::add((new class('textf1') extends Operation implements FunctionInterface { - public function invoke(EntitySet $texts): EntitySet - { - return $texts; - } - })->setReturnType(Lodata::getEntityType('text'))); + $textf1 = new Operation\Function_('textf1'); + $textf1->setCallable(function (EntitySet $texts): EntitySet { + return $texts; + }); + $textf1->setReturnType(Lodata::getEntityType('text')); + Lodata::add($textf1); $this->assertJsonResponse( (new Request) diff --git a/tests/Unit/Protocol/TypeResponsesTest.php b/tests/Unit/Protocol/TypeResponsesTest.php index c381fa77e..51cd2a65b 100644 --- a/tests/Unit/Protocol/TypeResponsesTest.php +++ b/tests/Unit/Protocol/TypeResponsesTest.php @@ -3,7 +3,6 @@ namespace Flat3\Lodata\Tests\Unit\Protocol; use Flat3\Lodata\Facades\Lodata; -use Flat3\Lodata\Interfaces\Operation\FunctionInterface; use Flat3\Lodata\Operation; use Flat3\Lodata\Tests\Request; use Flat3\Lodata\Tests\TestCase; @@ -19,12 +18,11 @@ class TypeResponsesTest extends TestCase { public function test_inf() { - Lodata::add(new class('exf1') extends Operation implements FunctionInterface { - function invoke(): Double - { - return new Double(INF); - } + $exf1 = new Operation\Function_('exf1'); + $exf1->setCallable(function (): Double { + return new Double(INF); }); + Lodata::add($exf1); $this->assertJsonResponse( (new Request) @@ -34,12 +32,11 @@ function invoke(): Double public function test_negative_inf() { - Lodata::add(new class('exf1') extends Operation implements FunctionInterface { - function invoke(): Double - { - return new Double(-INF); - } + $exf1 = new Operation\Function_('exf1'); + $exf1->setCallable(function (): Double { + return new Double(-INF); }); + Lodata::add($exf1); $this->assertJsonResponse( (new Request) @@ -49,12 +46,11 @@ function invoke(): Double public function test_nan() { - Lodata::add(new class('exf1') extends Operation implements FunctionInterface { - function invoke(): Double - { - return new Double(NAN); - } + $exf1 = new Operation\Function_('exf1'); + $exf1->setCallable(function (): Double { + return new Double(NAN); }); + Lodata::add($exf1); $this->assertJsonResponse( (new Request) @@ -64,12 +60,11 @@ function invoke(): Double public function test_true() { - Lodata::add(new class('exf1') extends Operation implements FunctionInterface { - function invoke(): Boolean - { - return new Boolean(true); - } + $exf1 = new Operation\Function_('exf1'); + $exf1->setCallable(function (): Boolean { + return new Boolean(true); }); + Lodata::add($exf1); $this->assertJsonResponse( (new Request) @@ -79,12 +74,11 @@ function invoke(): Boolean public function test_false() { - Lodata::add(new class('exf1') extends Operation implements FunctionInterface { - function invoke(): Boolean - { - return new Boolean(false); - } + $exf1 = new Operation\Function_('exf1'); + $exf1->setCallable(function (): Boolean { + return new Boolean(false); }); + Lodata::add($exf1); $this->assertJsonResponse( (new Request) @@ -94,12 +88,11 @@ function invoke(): Boolean public function test_int64() { - Lodata::add(new class('exf1') extends Operation implements FunctionInterface { - function invoke(): Int64 - { - return new Int64(PHP_INT_MAX); - } + $exf1 = new Operation\Function_('exf1'); + $exf1->setCallable(function (): Int64 { + return new Int64(PHP_INT_MAX); }); + Lodata::add($exf1); $this->assertJsonResponse( (new Request) @@ -109,12 +102,11 @@ function invoke(): Int64 public function test_int32() { - Lodata::add(new class('exf1') extends Operation implements FunctionInterface { - function invoke(): Int32 - { - return new Int32((2 ** 31) - 1); - } + $exf1 = new Operation\Function_('exf1'); + $exf1->setCallable(function (): Int32 { + return new Int32((2 ** 31) - 1); }); + Lodata::add($exf1); $this->assertJsonResponse( (new Request) @@ -124,12 +116,11 @@ function invoke(): Int32 public function test_int16() { - Lodata::add(new class('exf1') extends Operation implements FunctionInterface { - function invoke(): Int16 - { - return new Int16((2 ** 15) - 1); - } + $exf1 = new Operation\Function_('exf1'); + $exf1->setCallable(function (): Int16 { + return new Int16((2 ** 15) - 1); }); + Lodata::add($exf1); $this->assertJsonResponse( (new Request) @@ -139,12 +130,11 @@ function invoke(): Int16 public function test_int64_overflow() { - Lodata::add(new class('exf1') extends Operation implements FunctionInterface { - function invoke(): Int64 - { - return new Int64(PHP_INT_MAX + 1); - } + $exf1 = new Operation\Function_('exf1'); + $exf1->setCallable(function (): Int64 { + return new Int64(PHP_INT_MAX + 1); }); + Lodata::add($exf1); $this->assertJsonResponse( (new Request) @@ -154,12 +144,11 @@ function invoke(): Int64 public function test_int32_overflow() { - Lodata::add(new class('exf1') extends Operation implements FunctionInterface { - function invoke(): Int32 - { - return new Int32(2 ** 31); - } + $exf1 = new Operation\Function_('exf1'); + $exf1->setCallable(function (): Int32 { + return new Int32(2 ** 31); }); + Lodata::add($exf1); $this->assertJsonResponse( (new Request) @@ -169,12 +158,11 @@ function invoke(): Int32 public function test_int16_overflow() { - Lodata::add(new class('exf1') extends Operation implements FunctionInterface { - function invoke(): Int16 - { - return new Int16(2 ** 15); - } + $exf1 = new Operation\Function_('exf1'); + $exf1->setCallable(function (): Int16 { + return new Int16(2 ** 15); }); + Lodata::add($exf1); $this->assertJsonResponse( (new Request) @@ -184,12 +172,11 @@ function invoke(): Int16 public function test_binary() { - Lodata::add(new class('exf1') extends Operation implements FunctionInterface { - function invoke(): Binary - { - return new Binary('R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=='); - } + $exf1 = new Operation\Function_('exf1'); + $exf1->setCallable(function (): Binary { + return new Binary('R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=='); }); + Lodata::add($exf1); $this->assertJsonResponse( (new Request) @@ -199,12 +186,11 @@ function invoke(): Binary public function test_guid() { - Lodata::add(new class('exf1') extends Operation implements FunctionInterface { - function invoke(): Guid - { - return new Guid('00000000-1111-2222-3333-444455556666'); - } + $exf1 = new Operation\Function_('exf1'); + $exf1->setCallable(function (): Guid { + return new Guid('00000000-1111-2222-3333-444455556666'); }); + Lodata::add($exf1); $this->assertJsonResponse( (new Request) diff --git a/tests/Unit/Protocol/__snapshots__/BatchJSONTest__test_batch__3.yml b/tests/Unit/Protocol/__snapshots__/BatchJSONTest__test_batch__3.yml index 5d2fd1085..bed0f38ff 100644 --- a/tests/Unit/Protocol/__snapshots__/BatchJSONTest__test_batch__3.yml +++ b/tests/Unit/Protocol/__snapshots__/BatchJSONTest__test_batch__3.yml @@ -1,18 +1,18 @@ airports: - - { id: '1', name: Heathrow, code: xyz, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '5', name: One, code: one, construction_date: null, sam_datetime: null, open_time: null, review_score: null, is_big: null, country_id: null } + - { id: 1, name: Heathrow, code: xyz, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 5, name: One, code: one, construction_date: null, sam_datetime: null, open_time: null, review_score: null, is_big: null, country_id: null } countries: { } flights: - - { id: '1', origin: lhr, destination: lax, gate: null, duration: '41100.0' } - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } + - { id: 1, origin: lhr, destination: lax, gate: null, duration: 41100 } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } pets: { } diff --git a/tests/Unit/Protocol/__snapshots__/BatchJSONTest__test_partial_failure__3.yml b/tests/Unit/Protocol/__snapshots__/BatchJSONTest__test_partial_failure__3.yml index f1a340b64..9999f03a8 100644 --- a/tests/Unit/Protocol/__snapshots__/BatchJSONTest__test_partial_failure__3.yml +++ b/tests/Unit/Protocol/__snapshots__/BatchJSONTest__test_partial_failure__3.yml @@ -1,18 +1,18 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '5', name: a, code: xyy, construction_date: null, sam_datetime: null, open_time: null, review_score: null, is_big: null, country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 5, name: a, code: xyy, construction_date: null, sam_datetime: null, open_time: null, review_score: null, is_big: null, country_id: null } countries: { } flights: - - { id: '1', origin: lhr, destination: lax, gate: null, duration: '41100.0' } - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } + - { id: 1, origin: lhr, destination: lax, gate: null, duration: 41100 } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } pets: { } diff --git a/tests/Unit/Protocol/__snapshots__/BatchJSONTest__test_prefer_minimal__3.yml b/tests/Unit/Protocol/__snapshots__/BatchJSONTest__test_prefer_minimal__3.yml index 5d2fd1085..bed0f38ff 100644 --- a/tests/Unit/Protocol/__snapshots__/BatchJSONTest__test_prefer_minimal__3.yml +++ b/tests/Unit/Protocol/__snapshots__/BatchJSONTest__test_prefer_minimal__3.yml @@ -1,18 +1,18 @@ airports: - - { id: '1', name: Heathrow, code: xyz, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '5', name: One, code: one, construction_date: null, sam_datetime: null, open_time: null, review_score: null, is_big: null, country_id: null } + - { id: 1, name: Heathrow, code: xyz, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 5, name: One, code: one, construction_date: null, sam_datetime: null, open_time: null, review_score: null, is_big: null, country_id: null } countries: { } flights: - - { id: '1', origin: lhr, destination: lax, gate: null, duration: '41100.0' } - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } + - { id: 1, origin: lhr, destination: lax, gate: null, duration: 41100 } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } pets: { } diff --git a/tests/Unit/Protocol/__snapshots__/ContentTest__test_get_content_encoding__1.json b/tests/Unit/Protocol/__snapshots__/ContentTest__test_get_content_encoding__1.json new file mode 100644 index 000000000..4fa0b34ea --- /dev/null +++ b/tests/Unit/Protocol/__snapshots__/ContentTest__test_get_content_encoding__1.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.String", + "value": "utf-16" +} diff --git a/tests/Unit/Protocol/__snapshots__/ContentTest__test_get_content_language__1.json b/tests/Unit/Protocol/__snapshots__/ContentTest__test_get_content_language__1.json new file mode 100644 index 000000000..97a2004ac --- /dev/null +++ b/tests/Unit/Protocol/__snapshots__/ContentTest__test_get_content_language__1.json @@ -0,0 +1,4 @@ +{ + "@context": "http://localhost/odata/$metadata#Edm.String", + "value": "tr" +} diff --git a/tests/Unit/Protocol/__snapshots__/ParameterAliasTest__test_nonexistent_alias__1.json b/tests/Unit/Protocol/__snapshots__/ParameterAliasTest__test_nonexistent_alias__1.json index 1f98c046c..7710761c0 100644 --- a/tests/Unit/Protocol/__snapshots__/ParameterAliasTest__test_nonexistent_alias__1.json +++ b/tests/Unit/Protocol/__snapshots__/ParameterAliasTest__test_nonexistent_alias__1.json @@ -1,7 +1,7 @@ { "error": { "code": "reference_value_missing", - "message": "The requested reference value @code did not exist", + "message": "The requested reference (@code) did not exist", "target": null, "details": [], "innererror": {} diff --git a/tests/Unit/Queries/Entity/__snapshots__/NestingTest__test_schema__1.xml b/tests/Unit/Queries/Entity/__snapshots__/NestingTest__test_schema__1.xml index 244ee2f72..a40718bd6 100644 --- a/tests/Unit/Queries/Entity/__snapshots__/NestingTest__test_schema__1.xml +++ b/tests/Unit/Queries/Entity/__snapshots__/NestingTest__test_schema__1.xml @@ -64,6 +64,7 @@ + diff --git a/tests/Unit/Queries/Entity/__snapshots__/NestingTest__test_schema__3.json b/tests/Unit/Queries/Entity/__snapshots__/NestingTest__test_schema__3.json index 927f4215b..68fce0b6f 100644 --- a/tests/Unit/Queries/Entity/__snapshots__/NestingTest__test_schema__3.json +++ b/tests/Unit/Queries/Entity/__snapshots__/NestingTest__test_schema__3.json @@ -55,7 +55,8 @@ "@Org.OData.Capabilities.V1.IndexableByKey": true, "@Org.OData.Capabilities.V1.SelectSupport": { "Supported": true - } + }, + "@Org.OData.Core.V1.PositionalInsert": true }, "$Annotations": { "com.example.odata.DefaultContainer": { diff --git a/tests/Unit/Queries/EntityPrimitive/__snapshots__/EntityPrimitiveTest__test_delete_an_entity_set_primitive__1.yml b/tests/Unit/Queries/EntityPrimitive/__snapshots__/EntityPrimitiveTest__test_delete_an_entity_set_primitive__1.yml index 2f2b7cd0d..0118bf981 100644 --- a/tests/Unit/Queries/EntityPrimitive/__snapshots__/EntityPrimitiveTest__test_delete_an_entity_set_primitive__1.yml +++ b/tests/Unit/Queries/EntityPrimitive/__snapshots__/EntityPrimitiveTest__test_delete_an_entity_set_primitive__1.yml @@ -1,17 +1,17 @@ airports: - - { id: '1', name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: '1', country_id: null } - - { id: '2', name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: '0', country_id: null } - - { id: '3', name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } - - { id: '4', name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: '1', country_id: null } + - { id: 1, name: Heathrow, code: lhr, construction_date: '1946-03-25 00:00:00', sam_datetime: '2001-11-10 14:00:00', open_time: '09:00:00', review_score: null, is_big: 1, country_id: null } + - { id: 2, name: 'Los Angeles', code: lax, construction_date: '1930-01-01 00:00:00', sam_datetime: '2000-11-10 14:00:00', open_time: '08:00:00', review_score: null, is_big: 0, country_id: null } + - { id: 3, name: 'San Francisco', code: sfo, construction_date: '1930-01-01 00:00:00', sam_datetime: '2001-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: null, country_id: null } + - { id: 4, name: 'O''Hare', code: ohr, construction_date: '1930-01-01 00:00:00', sam_datetime: '1999-11-10 14:00:01', open_time: '15:00:00', review_score: null, is_big: 1, country_id: null } countries: { } flights: - - { id: '1', origin: null, destination: lax, gate: null, duration: '41100.0' } - - { id: '2', origin: sam, destination: rgr, gate: null, duration: '2384.0' } - - { id: '3', origin: sfo, destination: lax, gate: null, duration: '2133.0' } + - { id: 1, origin: null, destination: lax, gate: null, duration: 41100 } + - { id: 2, origin: sam, destination: rgr, gate: null, duration: 2384 } + - { id: 3, origin: sfo, destination: lax, gate: null, duration: 2133 } passengers: - - { id: '1', flight_id: '1', name: 'Anne Arbor' } - - { id: '2', flight_id: '1', name: 'Bob Barry' } - - { id: '3', flight_id: '1', name: 'Charlie Carrot' } - - { id: '4', flight_id: '2', name: 'Fox Flipper' } - - { id: '5', flight_id: '3', name: 'Grace Gumbo' } + - { id: 1, flight_id: 1, name: 'Anne Arbor' } + - { id: 2, flight_id: 1, name: 'Bob Barry' } + - { id: 3, flight_id: 1, name: 'Charlie Carrot' } + - { id: 4, flight_id: 2, name: 'Fox Flipper' } + - { id: 5, flight_id: 3, name: 'Grace Gumbo' } pets: { } diff --git a/tests/Unit/Queries/EntitySet/CaseSensitivityTest.php b/tests/Unit/Queries/EntitySet/CaseSensitivityTest.php index d653b4ed0..76291c9a9 100644 --- a/tests/Unit/Queries/EntitySet/CaseSensitivityTest.php +++ b/tests/Unit/Queries/EntitySet/CaseSensitivityTest.php @@ -39,4 +39,33 @@ public function test_query() ->path('/cI_tTESTs') ); } + + public function test_name_change() + { + $set = (new SQLEntitySet('cI_tTESTs', new EntityType('cI_tTEST')))->setTable('cI_tTEST'); + $set->discoverProperties(); + Lodata::add($set); + + $set->getIdentifier()->setName('Blammo'); + + $this->assertJsonResponse( + (new Request) + ->path('/Blammo') + ); + } + + public function test_property() + { + $set = (new SQLEntitySet('cI_tTESTs', new EntityType('cI_tTEST')))->setTable('cI_tTEST'); + $set->discoverProperties(); + Lodata::add($set); + $property = $set->getType()->getProperty('FiRst_N1m3'); + $property->setName('first_n1m3'); + $set->setPropertySourceName($property, 'FiRst_N1m3'); + + $this->assertJsonResponse( + (new Request) + ->path('/cI_tTESTs') + ); + } } \ No newline at end of file diff --git a/tests/Unit/Queries/EntitySet/__snapshots__/CaseSensitivityTest__test_name_change__1.json b/tests/Unit/Queries/EntitySet/__snapshots__/CaseSensitivityTest__test_name_change__1.json new file mode 100644 index 000000000..0ef7f71b8 --- /dev/null +++ b/tests/Unit/Queries/EntitySet/__snapshots__/CaseSensitivityTest__test_name_change__1.json @@ -0,0 +1,9 @@ +{ + "@context": "http://localhost/odata/$metadata#Blammo", + "value": [ + { + "FiRst_N1m3": "first", + "laSt_N1m3": "last" + } + ] +} diff --git a/tests/Unit/Queries/EntitySet/__snapshots__/CaseSensitivityTest__test_property__1.json b/tests/Unit/Queries/EntitySet/__snapshots__/CaseSensitivityTest__test_property__1.json new file mode 100644 index 000000000..21854dbd4 --- /dev/null +++ b/tests/Unit/Queries/EntitySet/__snapshots__/CaseSensitivityTest__test_property__1.json @@ -0,0 +1,9 @@ +{ + "@context": "http://localhost/odata/$metadata#cI_tTESTs", + "value": [ + { + "first_n1m3": "first", + "laSt_N1m3": "last" + } + ] +}