Repository: 9tigerio/db2rest
Branch: master
Commit: 68c8efac62ba
Files: 556
Total size: 8.0 MB
Directory structure:
gitextract_rp34tsh_/
├── .gitattributes
├── .github/
│ ├── FUNDING.yml
│ ├── RELEASING.md
│ └── workflows/
│ ├── build-verify.yml
│ ├── dockerhub-publish.yml
│ ├── maven-central-publish.yml
│ ├── oracle9i-central-publish.yml
│ └── snapshot.yml
├── .gitignore
├── .mvn/
│ └── wrapper/
│ └── maven-wrapper.properties
├── CONTRIBUTING.md
├── Dockerfile
├── LICENSE
├── README.md
├── db2rest-api/
│ ├── api-rest/
│ │ ├── pom-oracle9i.xml
│ │ ├── pom.xml
│ │ ├── sample-config/
│ │ │ ├── application-db.yml
│ │ │ ├── application-local.yml
│ │ │ ├── application-mongo.yml
│ │ │ ├── application-pg15.yml
│ │ │ └── application-pg16.yml
│ │ └── src/
│ │ ├── main/
│ │ │ ├── java/
│ │ │ │ └── com/
│ │ │ │ └── homihq/
│ │ │ │ └── db2rest/
│ │ │ │ ├── Db2restApplication.java
│ │ │ │ ├── config/
│ │ │ │ │ ├── CorsFilterConfiguration.java
│ │ │ │ │ ├── DbServiceConfiguration.java
│ │ │ │ │ ├── RestApiConfiguration.java
│ │ │ │ │ ├── WebMvcConfiguration.java
│ │ │ │ │ └── jinjava/
│ │ │ │ │ └── DisabledExpressionTokenScannerSymbols.java
│ │ │ │ ├── interceptor/
│ │ │ │ │ └── DatabaseContextRequestInterceptor.java
│ │ │ │ └── rest/
│ │ │ │ ├── RdbmsRestApi.java
│ │ │ │ ├── admin/
│ │ │ │ │ └── AdminController.java
│ │ │ │ ├── create/
│ │ │ │ │ ├── BulkCreateController.java
│ │ │ │ │ ├── BulkCreateRestApi.java
│ │ │ │ │ ├── CreateController.java
│ │ │ │ │ └── CreateRestApi.java
│ │ │ │ ├── delete/
│ │ │ │ │ ├── DeleteController.java
│ │ │ │ │ └── DeleteRestApi.java
│ │ │ │ ├── meta/
│ │ │ │ │ ├── db/
│ │ │ │ │ │ ├── DbInfoController.java
│ │ │ │ │ │ ├── DbInfoObject.java
│ │ │ │ │ │ └── DbInfoRestApi.java
│ │ │ │ │ └── schema/
│ │ │ │ │ ├── ColumnObject.java
│ │ │ │ │ ├── SchemaController.java
│ │ │ │ │ ├── SchemaRestApi.java
│ │ │ │ │ ├── TableObject.java
│ │ │ │ │ └── TableWithColumnsObject.java
│ │ │ │ ├── read/
│ │ │ │ │ ├── CountQueryController.java
│ │ │ │ │ ├── ExistsQueryController.java
│ │ │ │ │ ├── FindOneController.java
│ │ │ │ │ └── ReadController.java
│ │ │ │ ├── rpc/
│ │ │ │ │ ├── FunctionController.java
│ │ │ │ │ └── ProcedureController.java
│ │ │ │ ├── sql/
│ │ │ │ │ └── SQLTemplateController.java
│ │ │ │ └── update/
│ │ │ │ └── UpdateController.java
│ │ │ └── resources/
│ │ │ ├── application.yml
│ │ │ ├── banner.txt
│ │ │ └── sql-templates/
│ │ │ ├── count.jte
│ │ │ ├── delete-mssql.jte
│ │ │ ├── delete.jte
│ │ │ ├── exists-mssql.jte
│ │ │ ├── exists.jte
│ │ │ ├── find-one.jte
│ │ │ ├── insert.jte
│ │ │ ├── read-mssql.jte
│ │ │ ├── read-ora-12.jte
│ │ │ ├── read-ora-9.jte
│ │ │ ├── read.jte
│ │ │ ├── update-mssql.jte
│ │ │ └── update.jte
│ │ └── test/
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── homihq/
│ │ │ └── db2rest/
│ │ │ ├── BaseIntegrationTest.java
│ │ │ ├── DB2BaseIntegrationTest.java
│ │ │ ├── DB2ContainerConfiguration.java
│ │ │ ├── MariaDBBaseIntegrationTest.java
│ │ │ ├── MariaDBContainerConfiguration.java
│ │ │ ├── MsSQLServerContainerConfiguration.java
│ │ │ ├── MySQLBaseIntegrationTest.java
│ │ │ ├── MySQLContainerConfiguration.java
│ │ │ ├── OracleBaseIntegrationTest.java
│ │ │ ├── OracleContainerConfiguration.java
│ │ │ ├── PostgreSQLBaseIntegrationTest.java
│ │ │ ├── PostgreSQLContainerConfiguration.java
│ │ │ ├── SQLiteBaseIntegrationTest.java
│ │ │ ├── SQLiteContainerConfiguration.java
│ │ │ ├── jdbc/
│ │ │ │ └── rest/
│ │ │ │ └── meta/
│ │ │ │ ├── db/
│ │ │ │ │ ├── DbInfoControllerIntegrationTest.java
│ │ │ │ │ └── DbInfoControllerTest.java
│ │ │ │ └── schema/
│ │ │ │ ├── SchemaControllerIntegrationTest.java
│ │ │ │ └── SchemaControllerTest.java
│ │ │ └── rest/
│ │ │ ├── DateTimeUtil.java
│ │ │ ├── cors/
│ │ │ │ └── CorsTest.java
│ │ │ ├── db2/
│ │ │ │ ├── Db2BulkCreateControllerTest.java
│ │ │ │ ├── Db2CountControllerTest.java
│ │ │ │ ├── Db2CreateControllerTest.java
│ │ │ │ ├── Db2DeleteAllTest.java
│ │ │ │ ├── Db2DeleteControllerTest.java
│ │ │ │ ├── Db2JsonFileCreateControllerTest.java
│ │ │ │ ├── Db2ProcedureControllerTest.java
│ │ │ │ ├── Db2RSqlOperatorReadControllerTest.java
│ │ │ │ ├── Db2ReadControllerDefaultFetchLimitTest.java
│ │ │ │ ├── Db2ReadControllerTest.java
│ │ │ │ ├── Db2TemplateControllerTest.java
│ │ │ │ └── Db2UpdateControllerTest.java
│ │ │ ├── docsSwagger/
│ │ │ │ ├── OpenApiSpecificationNoSecurityTest.java
│ │ │ │ └── OpenApiSpecificationWithSecurityTest.java
│ │ │ ├── mariadb/
│ │ │ │ ├── MariaDBBasicJoinControllerTest.java
│ │ │ │ ├── MariaDBBulkCreateControllerTest.java
│ │ │ │ ├── MariaDBCountControllerTest.java
│ │ │ │ ├── MariaDBCreateControllerTest.java
│ │ │ │ ├── MariaDBCrossJoinControllerTest.java
│ │ │ │ ├── MariaDBDeleteAllTest.java
│ │ │ │ ├── MariaDBDeleteControllerTest.java
│ │ │ │ ├── MariaDBFunctionControllerTest.java
│ │ │ │ ├── MariaDBInnerJoinControllerTest.java
│ │ │ │ ├── MariaDBInnerJoinMultiTableControllerTest.java
│ │ │ │ ├── MariaDBInnerSelfJoinControllerTest.java
│ │ │ │ ├── MariaDBJsonFileCreateControllerTest.java
│ │ │ │ ├── MariaDBProcedureControllerTest.java
│ │ │ │ ├── MariaDBRSqlOperatorReadControllerTest.java
│ │ │ │ ├── MariaDBReadControllerDefaultFetchLimitTest.java
│ │ │ │ ├── MariaDBReadControllerTest.java
│ │ │ │ ├── MariaDBTemplateControllerTest.java
│ │ │ │ ├── MariaDBUpdateControllerTest.java
│ │ │ │ └── MariadbDateTimeAllTest.java
│ │ │ ├── mssql/
│ │ │ │ ├── MsSQLBaseIntegrationTest.java
│ │ │ │ ├── MsSQLBasicJoinControllerTest.java
│ │ │ │ ├── MsSQLBulkCreateControllerTest.java
│ │ │ │ ├── MsSQLCountControllerTest.java
│ │ │ │ ├── MsSQLCreateControllerTest.java
│ │ │ │ ├── MsSQLCrossJoinControllerTest.java
│ │ │ │ ├── MsSQLDateTimeAllTest.java
│ │ │ │ ├── MsSQLDeleteControllerTest.java
│ │ │ │ ├── MsSQLDeleteWithNotAllowedSafeDeleteControllerTest.java
│ │ │ │ ├── MsSQLExistsControllerTest.java
│ │ │ │ ├── MsSQLFindOneControllerTest.java
│ │ │ │ ├── MsSQLFunctionControllerTest.java
│ │ │ │ ├── MsSQLInnerJoinControllerTest.java
│ │ │ │ ├── MsSQLInnerJoinMultiTableControllerTest.java
│ │ │ │ ├── MsSQLInnerSelfJoinControllerTest.java
│ │ │ │ ├── MsSQLJsonFileCreateControllerTest.java
│ │ │ │ ├── MsSQLProcedureControllerTest.java
│ │ │ │ ├── MsSQLRSqlOperatorReadControllerTest.java
│ │ │ │ ├── MsSQLReadControllerDefaultFetchLimitTest.java
│ │ │ │ ├── MsSQLReadControllerTest.java
│ │ │ │ └── MsSQLUpdateControllerTest.java
│ │ │ ├── mysql/
│ │ │ │ ├── CountTwoTablesSameNameDiffSchemaTest.java
│ │ │ │ ├── CreateTwoTablesSameNameDiffSchemaTest.java
│ │ │ │ ├── DeleteTwoTablesSameNameDiffSchemaTest.java
│ │ │ │ ├── MySQLBasicJoinControllerTest.java
│ │ │ │ ├── MySQLBulkCreateControllerTest.java
│ │ │ │ ├── MySQLCountControllerTest.java
│ │ │ │ ├── MySQLCreateControllerTest.java
│ │ │ │ ├── MySQLCrossJoinControllerTest.java
│ │ │ │ ├── MySQLDateTimeAllTest.java
│ │ │ │ ├── MySQLDeleteAllTest.java
│ │ │ │ ├── MySQLDeleteControllerTest.java
│ │ │ │ ├── MySQLFunctionControllerTest.java
│ │ │ │ ├── MySQLInnerJoinControllerTest.java
│ │ │ │ ├── MySQLInnerJoinMultiTableControllerTest.java
│ │ │ │ ├── MySQLInnerSelfJoinControllerTest.java
│ │ │ │ ├── MySQLJsonFileCreateControllerTest.java
│ │ │ │ ├── MySQLProcedureControllerTest.java
│ │ │ │ ├── MySQLRSqlOperatorReadControllerTest.java
│ │ │ │ ├── MySQLReadControllerDefaultFetchLimitTest.java
│ │ │ │ ├── MySQLReadControllerTest.java
│ │ │ │ ├── MySQLTemplateControllerTest.java
│ │ │ │ ├── MySQLUpdateControllerTest.java
│ │ │ │ ├── ReadTwoTablesSameNameDiffSchemaTest.java
│ │ │ │ └── UpdateTwoTablesSameNameDiffSchemaTest.java
│ │ │ ├── oracle/
│ │ │ │ ├── OracleBasicJoinControllerTest.java
│ │ │ │ ├── OracleBulkCreateControllerTest.java
│ │ │ │ ├── OracleCountControllerTest.java
│ │ │ │ ├── OracleCreateControllerTest.java
│ │ │ │ ├── OracleCrossJoinControllerTest.java
│ │ │ │ ├── OracleDateTimeAllTest.java
│ │ │ │ ├── OracleDeleteAllTest.java
│ │ │ │ ├── OracleDeleteControllerTest.java
│ │ │ │ ├── OracleInnerJoinControllerTest.java
│ │ │ │ ├── OracleInnerJoinMultiTableControllerTest.java
│ │ │ │ ├── OracleInnerSelfJoinControllerTest.java
│ │ │ │ ├── OracleJsonFileCreateControllerTest.java
│ │ │ │ ├── OracleProcedureControllerTest.java
│ │ │ │ ├── OracleRSqlOperatorReadControllerTest.java
│ │ │ │ ├── OracleReadControllerDefaultFetchLimitTest.java
│ │ │ │ ├── OracleReadControllerTest.java
│ │ │ │ ├── OracleTemplateControllerTest.java
│ │ │ │ └── OracleUpdateControllerTest.java
│ │ │ ├── pg/
│ │ │ │ ├── PGDateTimeAllTest.java
│ │ │ │ ├── PgBasicJoinControllerTest.java
│ │ │ │ ├── PgBulkCreateControllerTest.java
│ │ │ │ ├── PgCountControllerTest.java
│ │ │ │ ├── PgCreateControllerTest.java
│ │ │ │ ├── PgCrossJoinControllerTest.java
│ │ │ │ ├── PgDeleteAllTest.java
│ │ │ │ ├── PgDeleteControllerTest.java
│ │ │ │ ├── PgExtraFunctionControllerTest.java
│ │ │ │ ├── PgFunctionControllerTest.java
│ │ │ │ ├── PgInnerJoinControllerTest.java
│ │ │ │ ├── PgInnerJoinMultiTableControllerTest.java
│ │ │ │ ├── PgInnerSelfJoinControllerTest.java
│ │ │ │ ├── PgJsonFileCreateControllerTest.java
│ │ │ │ ├── PgMultiTenancyTest.java
│ │ │ │ ├── PgProcedureControllerTest.java
│ │ │ │ ├── PgRSqlOperatorReadControllerTest.java
│ │ │ │ ├── PgReadControllerDefaultFetchLimitTest.java
│ │ │ │ ├── PgReadControllerTest.java
│ │ │ │ ├── PgTemplateControllerTest.java
│ │ │ │ └── PgUpdateControllerTest.java
│ │ │ └── sqlite/
│ │ │ ├── SQLiteBulkCreateControllerTest.java
│ │ │ ├── SQLiteCountControllerTest.java
│ │ │ ├── SQLiteCreateControllerTest.java
│ │ │ ├── SQLiteCrossJoinControllerTest.java
│ │ │ ├── SQLiteDateTimeAllTest.java
│ │ │ ├── SQLiteDeleteControllerTest.java
│ │ │ ├── SQLiteInnerJoinControllerTest.java
│ │ │ ├── SQLiteJsonFileCreateControllerTest.java
│ │ │ ├── SQLiteRSqlOperatorReadControllerTest.java
│ │ │ ├── SQLiteReadControllerTest.java
│ │ │ ├── SQLiteTemplateControllerTest.java
│ │ │ └── SQLiteUpdateControllerTest.java
│ │ └── resources/
│ │ ├── application-it-db2.yaml
│ │ ├── application-it-mariadb.yaml
│ │ ├── application-it-mssql.yaml
│ │ ├── application-it-mysql.yaml
│ │ ├── application-it-oracle.yaml
│ │ ├── application-it-pg-mutlitenancy.yaml
│ │ ├── application-it-pg.yaml
│ │ ├── application-it-sqlite.yaml
│ │ ├── auth-apiKey-test.yaml
│ │ ├── auth-basic.yaml
│ │ ├── db2/
│ │ │ ├── db2-sakila-data.sql
│ │ │ └── db2-sakila.sql
│ │ ├── junit-platform.properties
│ │ ├── mariadb/
│ │ │ ├── mariadb-sakila-data.sql
│ │ │ └── mariadb-sakila.sql
│ │ ├── mssql/
│ │ │ ├── mssql-sakila-data.sql
│ │ │ └── mssql-sakila.sql
│ │ ├── mysql/
│ │ │ ├── mysql-sakila-data.sql
│ │ │ ├── mysql-sakila.sql
│ │ │ └── mysql-wakila-all.sql
│ │ ├── oracle/
│ │ │ ├── oracle-sakila-data.sql
│ │ │ └── oracle-sakila.sql
│ │ ├── pg/
│ │ │ ├── pg-sakila-functions.sql
│ │ │ ├── postgres-sakila-data.sql
│ │ │ └── postgres-sakila.sql
│ │ ├── sqlite/
│ │ │ ├── sqlite-sakila-data.sql
│ │ │ └── sqlite-sakila.sql
│ │ └── testdata/
│ │ ├── BULK_CREATE_ACTOR_REQUEST.json
│ │ ├── BULK_CREATE_DIRECTOR_BAD_REQUEST.json
│ │ ├── BULK_CREATE_DIRECTOR_REQUEST.json
│ │ ├── BULK_CREATE_FILM_BAD_REQUEST.json
│ │ ├── BULK_CREATE_FILM_REQUEST.json
│ │ ├── BULK_CREATE_REVIEW_REQUEST.json
│ │ ├── BULK_RESULT_ACTOR_QUERY.json
│ │ ├── CREATE_ACTOR_REQUEST.json
│ │ ├── CREATE_DIRECTOR_REQUEST.json
│ │ ├── CREATE_EMP_REQUEST.json
│ │ ├── CREATE_FILM_BAD_REQUEST_CSV.csv
│ │ ├── CREATE_FILM_REQUEST.json
│ │ ├── CREATE_FILM_REQUEST_CSV.csv
│ │ ├── CREATE_FILM_REQUEST_ERROR.json
│ │ ├── CREATE_FILM_REQUEST_MISSING_PAYLOAD.json
│ │ ├── CREATE_USER_REQUEST.json
│ │ ├── CREATE_VANITY_VAN_REQUEST.json
│ │ ├── CROSS_JOIN_TOPS.json
│ │ ├── CROSS_JOIN_TOPS_MSSQL.json
│ │ ├── CROSS_JOIN_TOPS_ORACLE.json
│ │ ├── CROSS_JOIN_TOPS_PG.json
│ │ ├── CROSS_JOIN_USERS.json
│ │ ├── CROSS_JOIN_USERS_MSSQL.json
│ │ ├── CROSS_JOIN_USERS_ORACLE.json
│ │ ├── CROSS_JOIN_USERS_PG.json
│ │ ├── EMPTY_ACTOR_QUERY.json
│ │ ├── INNER_JOIN.json
│ │ ├── INNER_JOIN_MULTI_TABLE.json
│ │ ├── INNER_JOIN_MULTI_TABLE_ORACLE.json
│ │ ├── INNER_JOIN_ORACLE.json
│ │ ├── INNER_SELF_JOIN.json
│ │ ├── INNER_SELF_JOIN_ORACLE.json
│ │ ├── LEFT_JOIN.json
│ │ ├── LEFT_JOIN_ORACLE.json
│ │ ├── RIGHT_JOIN.json
│ │ ├── RIGHT_JOIN_ORACLE.json
│ │ ├── SINGLE_RESULT_ACTOR_QUERY.json
│ │ ├── UPDATE_ACTOR_REQUEST.json
│ │ ├── UPDATE_EMPLOYEE_REQUEST.json
│ │ ├── UPDATE_FILMS_REQUEST.json
│ │ ├── UPDATE_FILM_REQUEST.json
│ │ ├── UPDATE_NON_EXISTING_FILM_REQUEST.json
│ │ ├── UPDATE_NON_EXISTING_TABLE.json
│ │ ├── actor.json
│ │ ├── actor5mb.json
│ │ ├── director.json
│ │ ├── sql-db2/
│ │ │ ├── conditional_render_and_op.sql
│ │ │ ├── conditional_render_join.sql
│ │ │ ├── select_all.sql
│ │ │ ├── select_by_id.sql
│ │ │ └── select_by_id_is_required.sql
│ │ ├── sql-mariadb/
│ │ │ ├── conditional_render_and_op.sql
│ │ │ ├── conditional_render_join.sql
│ │ │ ├── select_all.sql
│ │ │ ├── select_by_id.sql
│ │ │ └── select_by_id_is_required.sql
│ │ ├── sql-mysql/
│ │ │ ├── conditional_render_and_op.sql
│ │ │ ├── conditional_render_join.sql
│ │ │ ├── select_all.sql
│ │ │ ├── select_by_id.sql
│ │ │ └── select_by_id_is_required.sql
│ │ ├── sql-oracle/
│ │ │ ├── conditional_render_and_op.sql
│ │ │ ├── conditional_render_join.sql
│ │ │ ├── select_all.sql
│ │ │ ├── select_by_id.sql
│ │ │ └── select_by_id_is_required.sql
│ │ ├── sql-pg/
│ │ │ ├── conditional_render_and_op.sql
│ │ │ ├── conditional_render_join.sql
│ │ │ ├── delete_from_content.sql
│ │ │ ├── insert_from_content.sql
│ │ │ ├── select_all.sql
│ │ │ ├── select_by_id.sql
│ │ │ ├── select_by_id_from_content.sql
│ │ │ ├── select_by_id_is_required.sql
│ │ │ └── update_by_id_from_content.sql
│ │ └── sql-sqlite/
│ │ ├── conditional_render_and_op.sql
│ │ ├── conditional_render_join.sql
│ │ ├── select_all.sql
│ │ └── select_by_id.sql
│ ├── pom.xml
│ └── rest-common/
│ ├── pom.xml
│ └── src/
│ └── main/
│ └── java/
│ └── com/
│ └── homihq/
│ └── db2rest/
│ ├── bulk/
│ │ ├── CSVDataProcessor.java
│ │ ├── DataProcessor.java
│ │ ├── FileStreamObserver.java
│ │ ├── FileSubject.java
│ │ ├── JSONDataProcessor.java
│ │ └── JsonFileDataProcessor.java
│ ├── config/
│ │ ├── CorsConfigProperties.java
│ │ ├── DateTimeConfigProperties.java
│ │ ├── DateTimeConfiguration.java
│ │ ├── Db2RestConfigProperties.java
│ │ ├── MultiTenancy.java
│ │ └── OpenAPIConfiguration.java
│ ├── dtos/
│ │ └── BulkContext.java
│ ├── exception/
│ │ └── GlobalExceptionHandler.java
│ └── multidb/
│ ├── DatabaseConnectionDetail.java
│ ├── DatabaseProperties.java
│ └── EnvironmentProperties.java
├── db2rest-auth/
│ ├── pom.xml
│ └── src/
│ └── main/
│ ├── java/
│ │ └── com/
│ │ └── homihq/
│ │ └── db2rest/
│ │ └── auth/
│ │ ├── AuthConfiguration.java
│ │ ├── AuthFilter.java
│ │ ├── data/
│ │ │ ├── ApiExcludedResource.java
│ │ │ ├── ApiKey.java
│ │ │ ├── ApiResource.java
│ │ │ ├── AuthData.java
│ │ │ ├── ResourceRole.java
│ │ │ ├── RoleDataFilter.java
│ │ │ ├── User.java
│ │ │ └── UserDetail.java
│ │ ├── datalookup/
│ │ │ ├── ApiAuthDataLookup.java
│ │ │ ├── AuthDataLookup.java
│ │ │ ├── AuthDataProperties.java
│ │ │ ├── FileAuthDataLookup.java
│ │ │ └── NoAuthdataLookup.java
│ │ ├── exception/
│ │ │ └── AuthException.java
│ │ ├── provider/
│ │ │ ├── AbstractAuthProvider.java
│ │ │ ├── apikey/
│ │ │ │ └── ApiKeyAuthProvider.java
│ │ │ ├── basic/
│ │ │ │ └── BasicAuthProvider.java
│ │ │ └── jwt/
│ │ │ ├── JwtAuthProvider.java
│ │ │ └── JwtProperties.java
│ │ └── unkey/
│ │ ├── UnKeyAuthConfiguration.java
│ │ ├── UnKeyAuthFilter.java
│ │ ├── service/
│ │ │ └── UnKeyAuthService.java
│ │ └── to/
│ │ ├── UnKeyVerifyRequest.java
│ │ └── UnKeyVerifyResponse.java
│ └── resources/
│ ├── auth-sample-api-key.yml
│ ├── auth-sample.json
│ └── auth-sample.yml
├── db2rest-core/
│ ├── db2rest-common/
│ │ ├── pom.xml
│ │ └── src/
│ │ └── main/
│ │ └── java/
│ │ └── com/
│ │ └── homihq/
│ │ └── db2rest/
│ │ ├── core/
│ │ │ ├── dto/
│ │ │ │ ├── CountResponse.java
│ │ │ │ ├── CreateBulkResponse.java
│ │ │ │ ├── CreateResponse.java
│ │ │ │ ├── DeleteResponse.java
│ │ │ │ ├── ExistsResponse.java
│ │ │ │ └── UpdateResponse.java
│ │ │ └── exception/
│ │ │ ├── AuthenticationFailedException.java
│ │ │ ├── DeleteOpNotAllowedException.java
│ │ │ ├── GenericDataAccessException.java
│ │ │ ├── InvalidColumnException.java
│ │ │ ├── InvalidOperatorException.java
│ │ │ ├── InvalidTableException.java
│ │ │ ├── PathVariableNamesMissingException.java
│ │ │ ├── PathVariableValuesMissingException.java
│ │ │ ├── PlaceholderConstraintException.java
│ │ │ ├── RpcException.java
│ │ │ ├── SqlTemplateNotFoundException.java
│ │ │ ├── SqlTemplateReadException.java
│ │ │ └── UnsupportedConstraintException.java
│ │ └── multidb/
│ │ └── DatabaseContextHolder.java
│ ├── pom.xml
│ ├── rdbms-common/
│ │ ├── pom.xml
│ │ └── src/
│ │ └── main/
│ │ └── java/
│ │ └── com/
│ │ └── db2rest/
│ │ └── jdbc/
│ │ └── dialect/
│ │ ├── Dialect.java
│ │ └── model/
│ │ ├── ArrayTypeValueHolder.java
│ │ ├── Database.java
│ │ ├── DbAlias.java
│ │ ├── DbColumn.java
│ │ ├── DbJoin.java
│ │ ├── DbSort.java
│ │ ├── DbTable.java
│ │ └── DbWhere.java
│ └── rdbms-support/
│ ├── pom.xml
│ └── src/
│ ├── main/
│ │ └── java/
│ │ └── com/
│ │ └── homihq/
│ │ └── db2rest/
│ │ └── jdbc/
│ │ ├── JdbcManager.java
│ │ ├── JdbcOperationService.java
│ │ ├── core/
│ │ │ ├── DbOperationService.java
│ │ │ ├── SimpleRowMapper.java
│ │ │ └── service/
│ │ │ ├── BulkCreateService.java
│ │ │ ├── CountQueryService.java
│ │ │ ├── CreateService.java
│ │ │ ├── DeleteService.java
│ │ │ ├── ExistsQueryService.java
│ │ │ ├── FindOneService.java
│ │ │ ├── FunctionService.java
│ │ │ ├── JdbcBulkCreateService.java
│ │ │ ├── JdbcCountQueryService.java
│ │ │ ├── JdbcCreateService.java
│ │ │ ├── JdbcDeleteService.java
│ │ │ ├── JdbcExistsQueryService.java
│ │ │ ├── JdbcFindOneService.java
│ │ │ ├── JdbcFunctionService.java
│ │ │ ├── JdbcProcedureService.java
│ │ │ ├── JdbcReadService.java
│ │ │ ├── JdbcUpdateService.java
│ │ │ ├── JinJavaTemplateExecutorService.java
│ │ │ ├── ProcedureService.java
│ │ │ ├── ReadService.java
│ │ │ ├── SQLTemplateExecutorService.java
│ │ │ ├── SubRoutine.java
│ │ │ └── UpdateService.java
│ │ ├── dto/
│ │ │ ├── BindVariable.java
│ │ │ ├── CreateContext.java
│ │ │ ├── DeleteContext.java
│ │ │ ├── FnUtil.java
│ │ │ ├── InsertableColumn.java
│ │ │ ├── JoinDetail.java
│ │ │ ├── Placeholder.java
│ │ │ ├── QueryRequest.java
│ │ │ ├── ReadContext.java
│ │ │ └── UpdateContext.java
│ │ ├── multidb/
│ │ │ ├── DbDetailHolder.java
│ │ │ └── RoutingDataSource.java
│ │ ├── processor/
│ │ │ ├── JoinProcessor.java
│ │ │ ├── OrderByProcessor.java
│ │ │ ├── ReadProcessor.java
│ │ │ ├── RootTableFieldProcessor.java
│ │ │ ├── RootTableProcessor.java
│ │ │ └── RootWhereProcessor.java
│ │ ├── rsql/
│ │ │ ├── operator/
│ │ │ │ ├── CustomRSQLOperators.java
│ │ │ │ ├── OperatorHandler.java
│ │ │ │ ├── OperatorMap.java
│ │ │ │ ├── RSQLOperatorHandlers.java
│ │ │ │ └── handler/
│ │ │ │ ├── EndWithOperatorHandler.java
│ │ │ │ ├── EqualToOperatorHandler.java
│ │ │ │ ├── GreaterThanEqualToOperatorHandler.java
│ │ │ │ ├── GreaterThanOperatorHandler.java
│ │ │ │ ├── InOperatorHandler.java
│ │ │ │ ├── IsNotNullOperatorHandler.java
│ │ │ │ ├── IsNullOperatorHandler.java
│ │ │ │ ├── JsonContainInArrayOperatorHandler.java
│ │ │ │ ├── JsonContainOperatorHandler.java
│ │ │ │ ├── JsonbContainOperatorHandler.java
│ │ │ │ ├── JsonbEqualToOperatorHandler.java
│ │ │ │ ├── JsonbKeyExistsOperatorHandler.java
│ │ │ │ ├── LessThanEqualToOperatorHandler.java
│ │ │ │ ├── LessThanOperatorHandler.java
│ │ │ │ ├── LikeOperatorHandler.java
│ │ │ │ ├── NotEqualToOperatorHandler.java
│ │ │ │ ├── NotInOperatorHandler.java
│ │ │ │ ├── NotLikeOperatorHandler.java
│ │ │ │ └── StartWithOperatorHandler.java
│ │ │ ├── parser/
│ │ │ │ └── RSQLParserBuilder.java
│ │ │ ├── resolver/
│ │ │ │ └── CrossTableColumnResolver.java
│ │ │ └── visitor/
│ │ │ └── BaseRSQLVisitor.java
│ │ ├── sql/
│ │ │ ├── ColumnLabel.java
│ │ │ ├── DB2DataExtraction.java
│ │ │ ├── DbMeta.java
│ │ │ ├── JdbcMetaDataProvider.java
│ │ │ ├── JdbcTypeJavaClassMappings.java
│ │ │ ├── MariaDBDataExtraction.java
│ │ │ ├── MetaDataExtraction.java
│ │ │ ├── MetaDataTable.java
│ │ │ ├── MsSQLServerMetaDataExtraction.java
│ │ │ ├── MySQLDataExtraction.java
│ │ │ ├── OracleMetaDataExtraction.java
│ │ │ ├── PostgreSQLDataExclusion.java
│ │ │ ├── SQLiteDataExtraction.java
│ │ │ ├── SqlCreatorTemplate.java
│ │ │ └── SqlTypes.java
│ │ ├── tsid/
│ │ │ └── TSIDProcessor.java
│ │ ├── util/
│ │ │ └── AliasGenerator.java
│ │ └── validator/
│ │ ├── ConstraintValidator.java
│ │ ├── CustomPlaceholderValidators.java
│ │ └── impl/
│ │ ├── IsRequiredValidator.java
│ │ └── IsUUIDValidator.java
│ └── test/
│ └── java/
│ └── com/
│ └── homihq/
│ └── db2rest/
│ └── jdbc/
│ ├── core/
│ │ └── service/
│ │ └── JdbcCreateServiceTest.java
│ ├── dto/
│ │ └── FnUtilTest.java
│ ├── util/
│ │ └── AliasGeneratorTest.java
│ └── validator/
│ ├── CustomPlaceholderValidatorsTest.java
│ └── impl/
│ ├── IsRequiredValidatorTest.java
│ └── IsUUIDValidatorTest.java
├── db2rest-dialects/
│ ├── db2-dialect/
│ │ ├── README.md
│ │ ├── pom.xml
│ │ └── src/
│ │ ├── main/
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── db2rest/
│ │ │ └── jdbc/
│ │ │ └── dialect/
│ │ │ └── DB2RestDB2Dialect.java
│ │ └── test/
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── db2rest/
│ │ │ └── jdbc/
│ │ │ └── dialect/
│ │ │ ├── DB2RestDB2DialectTest.java
│ │ │ └── TestConfiguration.java
│ │ └── resources/
│ │ └── application-test.yml
│ ├── mariadb-dialect/
│ │ ├── pom.xml
│ │ └── src/
│ │ └── main/
│ │ └── java/
│ │ └── com/
│ │ └── db2rest/
│ │ └── jdbc/
│ │ └── dialect/
│ │ └── MariaDBDialect.java
│ ├── mssql-dialect/
│ │ ├── pom.xml
│ │ └── src/
│ │ └── main/
│ │ └── java/
│ │ └── com/
│ │ └── db2rest/
│ │ └── jdbc/
│ │ └── dialect/
│ │ └── MsSQLServerDialect.java
│ ├── mysql-dialect/
│ │ ├── pom.xml
│ │ └── src/
│ │ └── main/
│ │ └── java/
│ │ └── com/
│ │ └── db2rest/
│ │ └── jdbc/
│ │ └── dialect/
│ │ └── DB2RestMySQLDialect.java
│ ├── oracle-dialect/
│ │ ├── pom.xml
│ │ └── src/
│ │ └── main/
│ │ └── java/
│ │ └── com/
│ │ └── db2rest/
│ │ └── jdbc/
│ │ └── dialect/
│ │ └── OracleDialect.java
│ ├── oracle9i-dialect/
│ │ ├── pom.xml
│ │ └── src/
│ │ └── main/
│ │ └── java/
│ │ └── com/
│ │ └── db2rest/
│ │ └── jdbc/
│ │ └── dialect/
│ │ └── OracleDialect.java
│ ├── pg-dialect/
│ │ ├── pom.xml
│ │ └── src/
│ │ └── main/
│ │ └── java/
│ │ └── com/
│ │ └── db2rest/
│ │ └── jdbc/
│ │ └── dialect/
│ │ ├── PostGreSQLDialect.java
│ │ └── driver/
│ │ ├── EnvVarSSLSocketFactory.java
│ │ └── PgSingleCertValidatingFactory.java
│ ├── pom.xml
│ └── sqlite-dialect/
│ ├── pom.xml
│ └── src/
│ └── main/
│ └── java/
│ └── com/
│ └── db2rest/
│ └── jdbc/
│ └── dialect/
│ └── SQLiteDialect.java
├── db2rest-oas3.json
├── design/
│ └── insert.md
├── docker-compose/
│ ├── db2/
│ │ ├── README.md
│ │ ├── docker-compose.yml
│ │ └── init/
│ │ └── 01-create-schema.sql
│ ├── mariadb/
│ │ ├── api-interaction.sh
│ │ ├── docker-compose.yml
│ │ ├── init/
│ │ │ └── 01-init.sql
│ │ └── run.sh
│ ├── mysql/
│ │ ├── api-interaction.sh
│ │ ├── docker-compose.yml
│ │ ├── init/
│ │ │ └── 01-init.sql
│ │ └── run.sh
│ ├── oracle/
│ │ ├── api-interaction.sh
│ │ ├── docker-compose.yml
│ │ ├── init/
│ │ │ └── 01-init.sql
│ │ └── run.sh
│ ├── postgresql/
│ │ ├── api-interaction.sh
│ │ ├── docker-compose.yml
│ │ ├── init/
│ │ │ └── 01-init.sql
│ │ └── run.sh
│ └── sqlserver/
│ ├── api-interaction.sh
│ ├── docker-compose.yml
│ ├── init/
│ │ └── 01-init.sql
│ └── run.sh
├── fed/
│ └── federation.md
├── funding.json
├── integration-test-guideline.md
├── mvnw
├── mvnw.cmd
└── pom.xml
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitattributes
================================================
src/test/resources/mysql/mysql-sakila.sql linguist-generated=true
src/test/resources/mysql/mysql-sakila-insert-data.sql linguist-generated=true
src/test/resources/pg/postgres-sakila.sql linguist-generated=true
# Always keep shell files with LF endings to avoid issues with runnning scripts in Windows WSL
# that need them to stay with LF endings and not CRLF. WSL is a Linux environment so needs LF endings.
.sh text eol=lf
================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms
github: [9tigerio]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
polar: # Replace with a single Polar username
buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
thanks_dev: # Replace with a single thanks.dev username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
================================================
FILE: .github/RELEASING.md
================================================
# General
We use [semantic versioning](https://semver.org).
We publish our snapshots on [GitHub Packages](https://github.com/orgs/9tigerio/packages?repo_name=db2rest).
We publish our releases on [Maven Central Portal](https://central.sonatype.com/) (Sonatype) under our namespace [io.9tiger](https://central.sonatype.com/namespace/io.9tiger)
We publish a **snapshot** `-SNAPSHOT` version at any time by using the corresponding GitHub Action.
We publish a **release** version to [Maven Central Portal](https://central.sonatype.com/namespace/io.9tiger) at any time by using the corresponding GitHub Action.
After a release, we can also build and publish a Docker container image to our DockerHub (working account for now: [kdhrubo](https://hub.docker.com/r/kdhrubo/db2rest)) via the corresponding GitHub Action.
# GPG Key signing steps
Follow the guide at [Maven Central Portal distributing your public key](https://central.sonatype.org/publish/requirements/gpg/#distributing-your-public-key)
# Snapshots
Using GitHub workflow `.github/workflows/snapshot.yml`
# Make a New Release
Using GitHub workflow `.github/workflows/maven-central-publish.yml`
# Make a Docker image
Using GitHub workflow `.github/workflows/dockerhub-publish.yml` which will download the Maven Central packaged released version and build a Docker image and publish to DockerHub
================================================
FILE: .github/workflows/build-verify.yml
================================================
name: Build & Verify
on:
pull_request:
branches:
- master
push:
branches:
- 'feature/**'
workflow_dispatch:
env:
VERSION: '1.6.6-SNAPSHOT'
permissions: read-all
jobs:
build:
name: Maven Build & Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Set up JDK 21
uses: actions/setup-java@v5
with:
java-version: '21'
distribution: 'liberica'
cache: 'maven'
- name: Build & Test
run: ./mvnw --quiet -Drevision=$VERSION --no-transfer-progress -B verify --file pom.xml
# Optional: Uploads the full dependency graph to GitHub to improve the quality of Dependabot alerts this repository can receive
#- name: Update dependency graph
# uses: advanced-security/maven-dependency-submission-action@571e99aab1055c2e71a1e2309b9691de18d6b7d6
================================================
FILE: .github/workflows/dockerhub-publish.yml
================================================
# This workflow will download the Maven Central package and
# build Docker image and publish to DockerHub
name: Publish to DockerHub
on:
workflow_dispatch:
inputs:
DB2REST_VERSION:
description: 'DB2REST version that is already published in Maven Central'
required: true
default: '1.3.0'
# release:
# types: [created]
jobs:
build_docker_image:
runs-on: ubuntu-latest
env:
DB2REST_VERSION: ${{ github.event.inputs.DB2REST_VERSION }}
permissions:
contents: read
packages: write
steps:
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
# In this following step, we use our Dockerfile
# to build the image (which has a `ADD` line to automatically
# download the versioned JAR file from Central Portal and
# adds it into a layer of the image)
- name: Build and push Docker images
uses: docker/build-push-action@v6
with:
# We use default Git context to build the Docker image,
# instead of PATH context `context: .`
push: true
tags: kdhrubo/db2rest:v${{ github.run_number }}, kdhrubo/db2rest:latest
build-args: DB2REST_VERSION=${{ env.DB2REST_VERSION }}
================================================
FILE: .github/workflows/maven-central-publish.yml
================================================
# This workflow will build a package using Maven and then publish it to Central Portal (Sonatype)
# For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#apache-maven-with-a-settings-path
name: Maven Default Publish
on:
release:
types: [created]
jobs:
build_and_test:
if: "!contains(github.event.head_commit.message, 'skip ci')"
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
name: Checkout code for Tag
with:
ref: ${{ github.event.release.tag_name }}
- name: Echo Tag
run: "echo 'CHECKED OUT TAG: ${{ github.event.release.tag_name }}'"
- name: Set up JDK 21 and maven settings.xml
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'liberica'
cache: 'maven'
server-username: MAVEN_USERNAME
server-password: MAVEN_PASSWORD
server-id: central
# TROUBLESHOOTING: We can temporarily skip upload & publishing to Maven Central in here
# by setting the `run: mvn` line's last -DskipPublishing property to true
- name: Build & Publish package DB2Rest to Central
run: mvn --quiet -Drevision=${{ github.event.release.tag_name }} --no-transfer-progress -B deploy -P release -DskipTests -DskipPublishing=false
# below we use env for passing GPG stuff since the signing type is bouncy castle (bc)
# set in parent pom's maven-gpg-plugin configuration and doesn't need gpg agent.
env:
MAVEN_USERNAME: ${{ secrets.MAVEN_CENTRAL_USERNAME }}
MAVEN_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PASSWORD }}
MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }}
MAVEN_GPG_KEY: ${{ secrets.MAVEN_GPG_KEY }}
# we unzip the central-bundle.zip so that we can access
# the db2rest JAR file path easily for Docker image build
- name: Unzip the central-bundle.zip & output JAR_FILE
id: unzip
run: |
mkdir staging
cp target/central-publishing/central-bundle.zip staging
unzip staging/central-bundle.zip -d staging
echo "JAR_FILE=staging/io/9tiger/api-rest/${{ github.event.release.tag_name }}/api-rest-${{ github.event.release.tag_name}}.jar" >> $GITHUB_ENV
- run: ls staging/io/9tiger/db2rest/${{ github.event.release.tag_name }}
- run: ls ${{ env.JAR_FILE }}
- name: Archive central-bundle JAR artifacts
uses: actions/upload-artifact@v4
with:
path: staging/central-bundle.zip
# - name: Build & Publish package Oracle9i to Central
# run: mvn -Drevision=${{ github.event.release.tag_name }} --no-transfer-progress -B deploy -P release --file api-rest/pom-oracle9i.xml -DskipTests
# env:
# MAVEN_USERNAME: ${{ secrets.MAVEN_CENTRAL_USERNAME }}
# MAVEN_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PASSWORD }}
# MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }}
# MAVEN_GPG_KEY: ${{ secrets.MAVEN_GPG_KEY }}
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: "${{ github.workspace }}"
push: true
tags: kdhrubo/db2rest:v${{ github.event.release.tag_name }}, kdhrubo/db2rest:latest
build-args: |
JAR_FILE=${{ env.JAR_FILE }}
================================================
FILE: .github/workflows/oracle9i-central-publish.yml
================================================
# This workflow will build a package using Maven and then publish it to GitHub packages when a release is created
# For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#apache-maven-with-a-settings-path
name: Oracle 9i Publish to Maven
on:
workflow_dispatch:
inputs:
version:
description: 'Version to publish, such as 1.3.0'
required: true
ref:
description: 'The Branch, Tag or SHA to checkout & publish'
required: true
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
name: Checkout code for Tag
with:
ref: ${{ github.event.inputs.ref }}
- name: Echo Tag
run: "echo 'CHECKED OUT TAG: ${{ github.event.inputs.ref }}'"
- name: Set up JDK 21 and maven settings.xml
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'liberica'
cache: 'maven'
server-username: MAVEN_USERNAME
server-password: MAVEN_PASSWORD
server-id: central
- name: Publish package Oracle9i
run: mvn -Drevision=${{ github.event.inputs.version }} --no-transfer-progress -B deploy -P release --file api-rest/pom-oracle9i.xml -DskipTests
env:
MAVEN_USERNAME: ${{ secrets.MAVEN_CENTRAL_USERNAME }}
MAVEN_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PASSWORD }}
MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }}
MAVEN_GPG_KEY: ${{ secrets.MAVEN_GPG_KEY }}
================================================
FILE: .github/workflows/snapshot.yml
================================================
name: Publish Snapshot to GitHub
on:
workflow_dispatch:
inputs:
version:
description: 'Version to publish, such as 1.3.0-SNAPSHOT'
required: true
default: '1.3.1-SNAPSHOT'
ref:
description: 'The Branch, Tag or SHA to use to publish Snapshot'
required: false
default: 'master'
permissions:
contents: write
packages: write
jobs:
build_snapshot:
name: Build Snapshot
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.ref }}
- name: Set up Java 21 and set GitHub for publishing in settings.xml
uses: actions/setup-java@v4
with:
distribution: 'liberica'
java-version: 21
cache: 'maven'
server-id: github
- name: Compile & Deploy to GitHub Packages
run: mvn -Drevision=${{ github.event.inputs.version }} --no-transfer-progress -B deploy -DdeployAtEnd --file pom.xml
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Update dependency graph
uses: advanced-security/maven-dependency-submission-action@v4.1.1
================================================
FILE: .gitignore
================================================
HELP.md
target/
.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
.flattened-pom.xml
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
.flattened-pom.xml
db2rest.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
## jte ##
/api-rest/jte-classes/**
/jte-classes/**
/env/
================================================
FILE: .mvn/wrapper/maven-wrapper.properties
================================================
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
wrapperVersion=3.3.2
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
================================================
FILE: CONTRIBUTING.md
================================================
Thanks for showing interest to contribute to DB2Rest 💖, you rock!
When it comes to open source, there are different ways you can contribute, all
of which are valuable. Here's a few guidelines that should help you as you
prepare your contribution.
## Setup the Project
The following steps will get you up and running to contribute to DB2Rest:
1. Fork the repo (click the Fork button at the top right of
[this page on our GitHub](https://github.com/9tigerio/db2rest))
2. Clone your fork locally.
Use your IDE's Git features, or a terminal like this:
```sh
git clone https://github.com//db2rest.git
cd db2rest
```
1. Setup all the dependencies and packages by running:
```sh
mvnw compile
```
This command will install dependencies using the [maven wrapper](https://maven.apache.org/wrapper/) script.
> If you run into any issues during this step, kindly reach out to the DB2Rest
> team here: [](https://discord.gg/kqeDatPGwU)
## Development
DB2Rest uses a [monorepo](https://en.wikipedia.org/wiki/Monorepo) structure. To improve our development process, we've set up tooling and systems.
DB2Rest uses a [Maven modular project structure](https://maven.apache.org/guides/mini/guide-multiple-modules-4.html) with a parent `pom.xml` file, and child pom's in subfolders.
### Tooling
- [Maven](https://maven.apache.org/) to manage packages and dependencies.
- [Docker](https://docs.docker.com/) We use Docker for spinning up test containers used in testing.
On Linux, ensure docker is installed.
On Windows, [Docker Desktop](https://www.docker.com/products/docker-desktop/) is needed.
- [Spring Test](https://docs.spring.io/spring-framework/reference/testing/integration.html) for integration testing of our Java components.
### Testing
Database test configurations are found under: `\db2rest\api-rest\src\test\java\com\homihq\db2rest`.
### Commands
**`mvnw build`**: builds and compiles all DB2Rest packages into `/target` folders.
**`mvnw test`**: run tests for all DB2Rest packages.
**`mvnw verify`**: builds and then starts integration testing using test containers on docker.
### Release Process
See [.github/RELEASING.md](https://github.com/9tigerio/db2rest/blob/master/.github/RELEASING.md)
## Think you found a bug?
Create a [New GitHub Issue](https://github.com/9tigerio/db2rest/issues/new/choose) and please conform to the issue template and provide a clear path to reproduction
with a code example.
## Proposing new or changed API?
Please provide thoughtful comments and some sample API code. Proposals that
don't line up with our roadmap or don't have a thoughtful explanation will be
closed.
## Making a Pull Request?
Pull requests need only the :+1: of two or more collaborators to be merged; when
the PR author is a collaborator, that counts as one.
### Commit Convention
Before you create a Pull Request, please check whether your commits comply with
the commit conventions used in this repository.
When you create a commit we kindly ask you to follow the convention
`category(scope or module): message` in your commit message while using one of
the following categories:
- `feature`: all changes that introduce completely new code or new
features
- `fix`: changes that fix a bug (ideally you will additionally reference an
issue if present)
- `refactor`: any code related change that is not a fix nor a feature
- `docs`: changing existing or creating new documentation (i.e. README, Javadocs, code
comments, etc.
- `build`: all changes regarding the build of the software, changes to
dependencies or the addition of new dependencies
- `test`: all changes regarding tests (adding new tests or changing existing
ones)
- `ci`: all changes regarding the configuration of continuous integration (i.e.
github actions, ci system)
- `chore`: all changes to the repository that do not fit into any of the above
categories
If you are interested in the detailed specification you can visit
https://www.conventionalcommits.org/ or check out the
[Angular Commit Message Guidelines](https://github.com/angular/angular/blob/22b96b9/CONTRIBUTING.md#-commit-message-guidelines).
### Steps to PR
1. Fork of the DB2Rest repository and clone your fork
2. Create a new branch out of the `master` branch. We follow the branch name convention
`[type/scope]`. For example `fix/rest-common` or `docs/api-rest`. `type`
can be either `docs`, `fix`, `feat`, `build`, or any other conventional
commit type. `scope` is just a short id that describes the scope of work.
3. Make and commit your changes following the
[commit convention](https://github.com/9tigerio/db2rest/blob/master/CONTRIBUTING.md#commit-convention).
As you develop, you can run `mvnw compile` and
`mvnw test` to make sure everything works as expected. Please
note that you might have to run `mvnw compile` first in order to build all
dependencies for testing.
### Tests
All commits that fix bugs or add features SHOULD add a test.
## Want to write a blog post or tutorial
That would be amazing! Reach out to the core team here:
https://discord.gg/kqeDatPGwU. We would love to support you any way we can.
## Want to help improve the docs?
Our docsite lives in a
[separate repo](https://github.com/9tigerio/db2rest-web). If you're
interested in contributing to the documentation, check out the
[docsite contribution guide](https://github.com/9tigerio/db2rest-web/blob/master/CONTRIBUTING.md).
## License
By contributing your code to the DB2Rest GitHub repository, you agree to
license your contribution under the [Apache-2.0 license](https://github.com/9tigerio/db2rest/blob/master/LICENSE).
================================================
FILE: Dockerfile
================================================
FROM bellsoft/liberica-runtime-container:jre-21-cds-slim-musl
ARG JAR_FILE=db2rest.jar
COPY ${JAR_FILE} /opt/app/db2rest.jar
# cd /opt/app
WORKDIR /opt/app
# uncomment EXPOSE if you wish to automatically expose
# port 8080 (default service port) upon container start
# otherwise you can map the port on docker run with `-p 1234:8080`
# EXPOSE 8080
# java -jar /opt/app/db2rest.jar
ENTRYPOINT ["java","-jar","db2rest.jar"]
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: README.md
================================================
DB2Rest is a modern low code REST DATA API platform that automatically creates a secure REST API endpoint
for your databases making it easy to build intelligent applications 30x faster. No ORM, no code generation = FAST!
It combines existing/new databases and data-sources with language models (LM/LLMs) and vector stores to rapidly
deliver context-aware, reasoning applications without any vendor lock-in. :bulb:
:star: If you find DB2Rest useful, please consider adding a star on GitHub! Your support motivates us to add new exciting features.

[](https://github.com/kdhrubo/db2rest/issues)
[](https://github.com/kdhrubo/db2rest/stargazers)




[](https://github.com/kdhrubo/db2rest)


[](https://twitter.com/db2rest)
# Website
[https://db2rest.com](https://db2rest.com)
# Latest Release
| Release | Download/Docker Pull |
|----------------------|----------------------------------------------------------------------------------|
| 1.6.8 | [DB2Rest-1.6.8](https://download.db2rest.com/db2rest-1.6.8.jar) |
| 1.6.8 (Docker Image) | ` docker pull kdhrubo/db2rest:v1.6.8 ` or ` docker pull kdhrubo/db2rest:latest ` |
# Last Stable Oracle 9i Release
| Release | Download/Docker Pull |
|--------------------------------------------|-----------------------------------------------------------------------------------|
| Oracle9i - 1.2.3 Final | [DB2Rest-Oracle9i-1.2.3](https://download.db2rest.com/db2rest-oracle9i-1.2.3.jar) |
# Quick start guides
[On premise / On Virtual Machines installation guide](https://db2rest.com/docs/intro).
[Docker based installation guide](https://db2rest.com/docs/run-db2rest-on-docker).
# Use Cases
## Accelerate Application Delivery
DB2Rest provides instant REST API(no code generation) to boost development by 30x. No need to write any code and best practices are built-in saving engineering teams
months of effort and cost.
## Faster innovation with Gen AI
DB2Rest works hand in glove with modern vector databases and LLM implementations to provide consistent Web APIs to deliver smart applications.
## Secure Database Gateway
DB2Rest works as a secure database gateway. This helps enterprises to open up data to internal developers and partners in a safe and agile way which was not possible earlier.
## Simplify Integration, Secure data exchange
Often enterprises export data from databases and share large files using SFTP, S3 etc. This process is slow, complex, error-prone and often very costly.
It requires heavy maintenance cost and it is not possible to share data in realtime.
Using DB2Rest, it is possible to simplify the process and allow secure data exchange with other parts of the organization without
writing a single line of code. There is no direct database based point to point integration and data is available to query anytime.
# Supported Databases
- **PostgreSQL**
- **MySQL**
- **SQLLite**
- **MS SQL Server**
- **Oracle** (Including 9i, 10g)
- **IBM DB2** (11.5.8.0+)
- **DigitalOcean PostgreSQL**
- **DigitalOcean MySQL**
- **AWS RDS Postgres**
- **AWS RDS MySQL**
- **MariaDB**
- **CockroachDB**
- **Neon**
- **Amazon Lightsail PostgreSQL**
- **Amazon Lightsail MySQL**
# Planned Database Support
- **Yugabyte**
- **PlanetScale**
- **CrunchyData**
- **MindsDB**
- DuckDB
# Contributing
Feel like contributing? That's awesome! We have a [contributing guide](https://github.com/9tigerio/db2rest/blob/master/CONTRIBUTING.md) to help guide you.
Our docsite lives in a [separate repo](https://github.com/9tigerio/db2rest-web). If you're interested in contributing to the documentation, check out the docsite contribution guide.
# Building
Use `mvn verify` or `mvn clean package` , etc. from repo root folder, and pass in a value for `revision` to override the current default version in POMs:
`mvn -Drevision="1.5.4-SNAPSHOT" clean package -DskipTests`
# Testing
Running tests simply requires a Docker daemon running, where the build will automatically pull and run testcontainers for the database tests.
# Support
*Connect on Discord*
https://discord.gg/kqeDatPGwU
[](https://discord.gg/kqeDatPGwU)
# Contact
# Roadmap
Refer to [open roadmap](https://db2rest.com/roadmap/) items.
# IDE Sponsor

================================================
FILE: db2rest-api/api-rest/pom-oracle9i.xml
================================================
4.0.0
io.9tiger
db2rest-parent
${revision}
../pom.xml
io.9tiger
db2rest-oracle9i
db2rest-oracle9i
db2rest-oracle9i
jar
21
3.0.1
io.9tiger
auth
${project.version}
io.9tiger
rest-common
${project.version}
io.9tiger
mongo-support
${project.version}
io.9tiger
rdbms-support
${project.version}
io.9tiger
pg-dialect
${project.version}
io.9tiger
mysql-dialect
${project.version}
io.9tiger
mariadb-dialect
${project.version}
io.9tiger
mssql-dialect
${project.version}
io.9tiger
oracle9i-dialect
${project.version}
commons-io
commons-io
2.15.1
org.springframework.boot
spring-boot-starter-actuator
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-validation
org.springframework.boot
spring-boot-configuration-processor
true
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-testcontainers
test
org.testcontainers
junit-jupiter
test
org.testcontainers
postgresql
test
org.testcontainers
mysql
test
org.testcontainers
oracle-xe
1.19.7
test
org.testcontainers
mariadb
test
org.testcontainers
mssqlserver
test
org.springframework.restdocs
spring-restdocs-mockmvc
test
org.springframework.boot
spring-boot-test-autoconfigure
test
io.hosuaby
inject-resources-junit-jupiter
0.3.3
test
io.micrometer
micrometer-registry-datadog
runtime
io.micrometer
micrometer-registry-prometheus
runtime
db2rest-oracle9i
src/main/resources
true
org.asciidoctor
asciidoctor-maven-plugin
2.2.4
generate-docs
prepare-package
process-asciidoc
html
book
org.springframework.restdocs
spring-restdocs-asciidoctor
${spring-restdocs.version}
org.springframework.boot
spring-boot-maven-plugin
org.projectlombok
lombok
================================================
FILE: db2rest-api/api-rest/pom.xml
================================================
4.0.0
io.9tiger
db2rest-api
${revision}
../
api-rest
jar
db2rest
db2rest
io.9tiger
db2rest-auth
${project.version}
io.9tiger
db2rest-common
${project.version}
io.9tiger
rest-common
${project.version}
io.9tiger
rdbms-support
${project.version}
io.9tiger
pg-dialect
${project.version}
io.9tiger
mysql-dialect
${project.version}
io.9tiger
mariadb-dialect
${project.version}
io.9tiger
oracle-dialect
${project.version}
io.9tiger
mssql-dialect
${project.version}
io.9tiger
sqlite-dialect
${project.version}
io.9tiger
db2-dialect
${project.version}
commons-io
commons-io
2.15.1
com.hubspot.jinjava
jinjava
2.7.3
org.springframework.boot
spring-boot-starter-actuator
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-validation
org.springframework.boot
spring-boot-configuration-processor
true
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-testcontainers
test
org.testcontainers
junit-jupiter
test
org.testcontainers
postgresql
test
org.testcontainers
mysql
test
org.testcontainers
oracle-xe
1.19.7
test
org.testcontainers
testcontainers-db2
2.0.2
test
org.testcontainers
mariadb
test
org.testcontainers
mssqlserver
test
org.springframework.restdocs
spring-restdocs-mockmvc
test
org.springframework.boot
spring-boot-test-autoconfigure
test
io.hosuaby
inject-resources-junit-jupiter
1.0.0
test
io.micrometer
micrometer-registry-datadog
runtime
io.micrometer
micrometer-registry-prometheus
runtime
db2rest
src/main/resources
true
gg.jte
jte-maven-plugin
${jte.version}
${project.basedir}/src/main/resources/sql-templates
Plain
generate-sources
generate
org.asciidoctor
asciidoctor-maven-plugin
2.2.4
generate-docs
prepare-package
process-asciidoc
html
book
org.springframework.restdocs
spring-restdocs-asciidoctor
${spring-restdocs.version}
org.springframework.boot
spring-boot-maven-plugin
org.projectlombok
lombok
================================================
FILE: db2rest-api/api-rest/sample-config/application-db.yml
================================================
app:
databases:
- id: ${DB_NAME:pgdb}
type: POSTGRESQL
url: jdbc:postgresql://localhost:5432/homidb
username: homi2022
password: homi2022
schemas:
- public
- joinplay
connectionProperties:
ssl: false
envProperties: # Not used yet
enableDatetimeFormatting: ${ENABLE_DATETIME_FORMATTING:false}
timeFormat: ${TIME_FORMAT:HH:mm:ss}
dateFormat: ${DATE_FORMAT:yyyy-MM-dd}
dateTimeFormat: ${DATE_TIME_FORMAT:yyyy-MM-dd HH:mm:ss}
defaultFetchLimit : ${DEFAULT_FETCH_LIMIT:100}
================================================
FILE: db2rest-api/api-rest/sample-config/application-local.yml
================================================
app:
databases:
- id: DB1
type: POSTGRESQL
url: jdbc:postgresql://localhost:5432/homidb
username: homi2022
password: homi2022
- id: DB2
type: MYSQL
url: jdbc:mysql://localhost:3306/sakila
username: root
password: "@Kolkata84"
================================================
FILE: db2rest-api/api-rest/sample-config/application-mongo.yml
================================================
app:
databases:
- id: DB1
type: POSTGRESQL
url: jdbc:postgresql://localhost:5432/homidb
username: homi2022
password: homi2022
connectionProperties:
ssl: false
envProperties: # Not used yet
enableDatetimeFormatting: true
timeFormat: 'HH:mm:ss'
dateFormat: 'dd-MM-yyyy'
dateTimeFormat: 'dd-MM-yyyy HH:mm:ss'
defaultFetchLimit : 100
================================================
FILE: db2rest-api/api-rest/sample-config/application-pg15.yml
================================================
app:
databases:
- id: ${DB_NAME:pgdb}
type: POSTGRESQL
url: jdbc:postgresql://localhost:5432/postgres
username: postgres
password:
================================================
FILE: db2rest-api/api-rest/sample-config/application-pg16.yml
================================================
app:
databases:
- id: ${DB_NAME:pgdb}
type: POSTGRESQL
url: jdbc:postgresql://localhost:5432/postgres
username: postgres
password:
================================================
FILE: db2rest-api/api-rest/src/main/java/com/homihq/db2rest/Db2restApplication.java
================================================
package com.homihq.db2rest;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, MongoAutoConfiguration.class})
@ComponentScan(excludeFilters = @ComponentScan.Filter(RestController.class))
public class Db2restApplication {
public static void main(String[] args) {
SpringApplication.run(Db2restApplication.class, args);
}
}
================================================
FILE: db2rest-api/api-rest/src/main/java/com/homihq/db2rest/config/CorsFilterConfiguration.java
================================================
package com.homihq.db2rest.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@Slf4j
@Configuration
public class CorsFilterConfiguration {
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
@ConditionalOnProperty(name = "cors.enabled", havingValue = "true")
public CorsFilter corsFilter(CorsConfigProperties properties) {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
for (CorsConfigProperties.CorsMapping mapping : properties.getMappings()) {
CorsConfiguration config = new CorsConfiguration();
// Process allowed origins (trim, remove duplicates)
List allowedOrigins = Arrays.stream(mapping.getAllowedOrigins().split(","))
.map(String::trim)
.distinct()
.collect(Collectors.toList());
config.setAllowedOrigins(allowedOrigins);
// Process allowed headers (trim, remove duplicates)
List allowedHeaders = Arrays.stream(mapping.getAllowedHeaders().split(","))
.map(String::trim)
.distinct()
.collect(Collectors.toList());
config.setAllowedHeaders(allowedHeaders);
// Process allowed methods (trim, remove duplicates)
List allowedMethods = Arrays.stream(mapping.getAllowedMethods().split(","))
.map(String::trim)
.distinct()
.collect(Collectors.toList());
config.setAllowedMethods(allowedMethods);
log.info("CORS Config -> Path: {}, Origins: {} , Headers: {}, Methods: {}" ,
mapping.getMapping() , allowedOrigins, allowedHeaders , allowedMethods);
source.registerCorsConfiguration(mapping.getMapping(), config);
}
return new CorsFilter(source);
}
}
================================================
FILE: db2rest-api/api-rest/src/main/java/com/homihq/db2rest/config/DbServiceConfiguration.java
================================================
package com.homihq.db2rest.config;
import com.db2rest.jdbc.dialect.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.homihq.db2rest.bulk.DataProcessor;
import com.homihq.db2rest.bulk.FileSubject;
import com.homihq.db2rest.jdbc.JdbcManager;
import com.homihq.db2rest.jdbc.JdbcOperationService;
import com.homihq.db2rest.config.jinjava.DisabledExpressionTokenScannerSymbols;
import com.homihq.db2rest.jdbc.core.DbOperationService;
import com.homihq.db2rest.jdbc.core.service.*;
import com.homihq.db2rest.jdbc.multidb.RoutingDataSource;
import com.homihq.db2rest.jdbc.processor.*;
import com.homihq.db2rest.jdbc.sql.SqlCreatorTemplate;
import com.homihq.db2rest.jdbc.tsid.TSIDProcessor;
import com.homihq.db2rest.jdbc.validator.CustomPlaceholderValidators;
import com.homihq.db2rest.multidb.DatabaseConnectionDetail;
import com.homihq.db2rest.multidb.DatabaseProperties;
import com.hubspot.jinjava.Jinjava;
import com.hubspot.jinjava.JinjavaConfig;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import gg.jte.CodeResolver;
import gg.jte.ContentType;
import gg.jte.TemplateEngine;
import gg.jte.resolve.ResourceCodeResolver;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
@Configuration
@RequiredArgsConstructor
public class DbServiceConfiguration {
private final DatabaseProperties databaseProperties;
private final ObjectMapper objectMapper;
@Bean
@ConditionalOnMissingBean(DataSource.class)
public DataSource dataSource() {
final Map dataSources = this.buildDataSources();
final RoutingDataSource routingDataSource = new RoutingDataSource();
routingDataSource.setTargetDataSources(dataSources);
return routingDataSource;
}
private Map buildDataSources() {
final Map result = new HashMap<>();
log.debug("Databases - {}", databaseProperties.getDatabases());
if (!databaseProperties.isRdbmsConfigured()) {
log.info("*** No RDBMS configured.");
return result;
}
for (DatabaseConnectionDetail connectionDetail : databaseProperties.getDatabases()) {
if (connectionDetail.isJdbcPresent())
result.put(connectionDetail.id(), this.buildDataSource(connectionDetail));
}
return result;
}
private DataSource buildDataSource(DatabaseConnectionDetail connectionDetail) {
final HikariConfig config = new HikariConfig();
config.setJdbcUrl(connectionDetail.url());
config.setUsername(connectionDetail.username());
config.setPassword(connectionDetail.password());
config.setMaximumPoolSize(connectionDetail.maxConnections());
config.setAutoCommit(false);
return new HikariDataSource(config);
}
@Bean
public JdbcManager jdbcManager() {
List dialects = List.of(
new PostGreSQLDialect(objectMapper),
new DB2RestMySQLDialect(objectMapper),
new MariaDBDialect(objectMapper),
new OracleDialect(objectMapper),
new MsSQLServerDialect(objectMapper),
new SQLiteDialect(objectMapper),
new DB2RestDB2Dialect(objectMapper)
);
return new JdbcManager(dataSource(), dialects, databaseProperties);
}
@Bean
public JdbcOperationService operationService() {
return new JdbcOperationService();
}
@Bean
public SqlCreatorTemplate sqlCreatorTemplate(TemplateEngine templateEngine, JdbcManager jdbcManager) {
return new SqlCreatorTemplate(templateEngine, jdbcManager);
}
@Bean
public TemplateEngine templateEngine() {
CodeResolver codeResolver =
new ResourceCodeResolver("sql-templates");
return TemplateEngine
.createPrecompiled(ContentType.Plain);
}
@Bean
public Jinjava jinjava() {
JinjavaConfig config = JinjavaConfig
.newBuilder()
.withTokenScannerSymbols(new DisabledExpressionTokenScannerSymbols())
.build();
return new Jinjava(config);
}
//START ::: Processors
@Bean
public TSIDProcessor tsidProcessor() {
return new TSIDProcessor();
}
@Bean
public JoinProcessor joinProcessor(JdbcManager jdbcManager) {
return new JoinProcessor(jdbcManager);
}
@Bean
public OrderByProcessor orderByProcessor() {
return new OrderByProcessor();
}
@Bean
public RootTableFieldProcessor rootTableFieldProcessor() {
return new RootTableFieldProcessor();
}
@Bean
public RootTableProcessor rootTableProcessor(JdbcManager jdbcManager) {
return new RootTableProcessor(jdbcManager);
}
@Bean
public RootWhereProcessor rootWhereProcessor(JdbcManager jdbcManager) {
return new RootWhereProcessor(jdbcManager);
}
//END ::: Processors
//START ::: Validator
@Bean
public CustomPlaceholderValidators customPlaceholderValidators() {
return new CustomPlaceholderValidators();
}
//END ::: Validator
//START ::: Service
//CREATE SERVICE
@Bean
public BulkCreateService bulkCreateService(TSIDProcessor tsidProcessor,
SqlCreatorTemplate sqlCreatorTemplate,
JdbcManager jdbcManager,
DbOperationService dbOperationService,
List dataProcessors,
FileSubject fileSubject) {
return new JdbcBulkCreateService(tsidProcessor, sqlCreatorTemplate, jdbcManager, dbOperationService, fileSubject);
}
@Bean
public CreateService createService(TSIDProcessor tsidProcessor,
SqlCreatorTemplate sqlCreatorTemplate,
JdbcManager jdbcManager,
DbOperationService dbOperationService) {
return new JdbcCreateService(tsidProcessor, sqlCreatorTemplate, jdbcManager, dbOperationService);
}
//QUERY SERVICE
@Bean
public CountQueryService countQueryService(
JdbcManager jdbcManager,
SqlCreatorTemplate sqlCreatorTemplate,
List processorList,
DbOperationService dbOperationService) {
return new JdbcCountQueryService(
jdbcManager,
dbOperationService, processorList, sqlCreatorTemplate);
}
@Bean
public ExistsQueryService existsQueryService(
JdbcManager jdbcManager,
SqlCreatorTemplate sqlCreatorTemplate,
List processorList,
DbOperationService dbOperationService) {
return new JdbcExistsQueryService(jdbcManager, dbOperationService, processorList, sqlCreatorTemplate);
}
@Bean
public FindOneService findOneService(
JdbcManager jdbcManager,
SqlCreatorTemplate sqlCreatorTemplate,
List processorList,
DbOperationService dbOperationService) {
return new JdbcFindOneService(jdbcManager, sqlCreatorTemplate, processorList, dbOperationService);
}
@Bean
public ReadService readService(
JdbcManager jdbcManager,
SqlCreatorTemplate sqlCreatorTemplate,
List processorList,
DbOperationService dbOperationService) {
return new JdbcReadService(jdbcManager, dbOperationService, processorList, sqlCreatorTemplate);
}
//UPDATE SERVICE
@Bean
public UpdateService updateService(
JdbcManager jdbcManager,
SqlCreatorTemplate sqlCreatorTemplate,
DbOperationService dbOperationService) {
return new JdbcUpdateService(jdbcManager, sqlCreatorTemplate, dbOperationService);
}
//DELETE SERVICE
@Bean
public DeleteService deleteService(
JdbcManager jdbcManager,
SqlCreatorTemplate sqlCreatorTemplate,
DbOperationService dbOperationService) {
return new JdbcDeleteService(jdbcManager, sqlCreatorTemplate, dbOperationService);
}
//RPC
@Bean
public FunctionService functionService(JdbcManager jdbcManager) {
return new JdbcFunctionService(jdbcManager);
}
@Bean
public ProcedureService procedureService(JdbcManager jdbcManager) {
return new JdbcProcedureService(jdbcManager);
}
@Bean
public SQLTemplateExecutorService templateService(
Jinjava jinjava,
Db2RestConfigProperties db2RestConfigProperties,
DbOperationService dbOperationService,
JdbcManager jdbcManager,
CustomPlaceholderValidators customPlaceholderValidators
) {
return new JinJavaTemplateExecutorService(
jinjava,
db2RestConfigProperties,
dbOperationService,
jdbcManager,
customPlaceholderValidators
);
}
//END ::: Services
}
================================================
FILE: db2rest-api/api-rest/src/main/java/com/homihq/db2rest/config/RestApiConfiguration.java
================================================
package com.homihq.db2rest.config;
import com.homihq.db2rest.bulk.DataProcessor;
import com.homihq.db2rest.jdbc.JdbcManager;
import com.homihq.db2rest.jdbc.core.service.*;
import com.homihq.db2rest.rest.admin.AdminController;
import com.homihq.db2rest.rest.create.BulkCreateController;
import com.homihq.db2rest.rest.create.CreateController;
import com.homihq.db2rest.rest.delete.DeleteController;
import com.homihq.db2rest.rest.meta.db.DbInfoController;
import com.homihq.db2rest.rest.meta.schema.SchemaController;
import com.homihq.db2rest.rest.read.CountQueryController;
import com.homihq.db2rest.rest.read.ExistsQueryController;
import com.homihq.db2rest.rest.read.FindOneController;
import com.homihq.db2rest.rest.read.ReadController;
import com.homihq.db2rest.rest.rpc.FunctionController;
import com.homihq.db2rest.rest.rpc.ProcedureController;
import com.homihq.db2rest.rest.sql.SQLTemplateController;
import com.homihq.db2rest.rest.update.UpdateController;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
@Slf4j
@Configuration
public class RestApiConfiguration {
//START ::: API
//CREATE API
@Bean
@ConditionalOnBean(BulkCreateService.class)
public BulkCreateController bulkCreateController(BulkCreateService bulkCreateService, List dataProcessors) {
return new BulkCreateController(bulkCreateService, dataProcessors);
}
@Bean
@ConditionalOnBean(CreateService.class)
public CreateController createController(CreateService createService) {
return new CreateController(createService);
}
//READ API
@Bean
@ConditionalOnBean(CountQueryService.class)
public CountQueryController countQueryController(CountQueryService countQueryService) {
return new CountQueryController(countQueryService);
}
@Bean
@ConditionalOnBean(ExistsQueryService.class)
public ExistsQueryController existsQueryController(ExistsQueryService existsQueryService) {
return new ExistsQueryController(existsQueryService);
}
@Bean
@ConditionalOnBean(FindOneService.class)
public FindOneController findOneController(FindOneService findOneService) {
return new FindOneController(findOneService);
}
@Bean
@ConditionalOnBean(ReadService.class)
public ReadController readController(ReadService readService, Db2RestConfigProperties configProperties) {
return new ReadController(readService, configProperties);
}
//UPDATE API
@Bean
@ConditionalOnBean(UpdateService.class)
public UpdateController updateController(UpdateService updateService) {
return new UpdateController(updateService);
}
//DELETE API
@Bean
@ConditionalOnBean(DeleteService.class)
public DeleteController deleteController(DeleteService deleteService, Db2RestConfigProperties configProperties) {
return new DeleteController(deleteService, configProperties);
}
//RPC
@Bean
@ConditionalOnBean(FunctionService.class)
public FunctionController functionController(FunctionService functionService) {
return new FunctionController(functionService);
}
@Bean
@ConditionalOnBean(ProcedureService.class)
public ProcedureController procedureController(ProcedureService procedureService) {
return new ProcedureController(procedureService);
}
@Bean
@ConditionalOnBean(JdbcManager.class)
public SchemaController schemaController(JdbcManager jdbcManager) {
return new SchemaController(jdbcManager);
}
@Bean
@ConditionalOnBean(SQLTemplateExecutorService.class)
public SQLTemplateController sqlTemplateController(
SQLTemplateExecutorService sqlTemplateExecutorService
) {
return new SQLTemplateController(sqlTemplateExecutorService);
}
@Bean
@ConditionalOnBean(JdbcManager.class)
public DbInfoController dbInfoController(JdbcManager jdbcManager) {
return new DbInfoController(jdbcManager);
}
@Bean
@ConditionalOnBean(JdbcManager.class)
public AdminController adminController(JdbcManager jdbcManager) {
return new AdminController(jdbcManager);
}
//END ::: API
}
================================================
FILE: db2rest-api/api-rest/src/main/java/com/homihq/db2rest/config/WebMvcConfiguration.java
================================================
package com.homihq.db2rest.config;
import com.homihq.db2rest.interceptor.DatabaseContextRequestInterceptor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@RequiredArgsConstructor
@Slf4j
public class WebMvcConfiguration implements WebMvcConfigurer {
private final DatabaseContextRequestInterceptor databaseContextRequestInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(databaseContextRequestInterceptor);
}
}
================================================
FILE: db2rest-api/api-rest/src/main/java/com/homihq/db2rest/config/jinjava/DisabledExpressionTokenScannerSymbols.java
================================================
package com.homihq.db2rest.config.jinjava;
import com.hubspot.jinjava.tree.parse.DefaultTokenScannerSymbols;
public class DisabledExpressionTokenScannerSymbols extends DefaultTokenScannerSymbols {
@Override
public int getExprStart() {
return 0;
}
@Override
public int getExprEnd() {
return 0;
}
}
================================================
FILE: db2rest-api/api-rest/src/main/java/com/homihq/db2rest/interceptor/DatabaseContextRequestInterceptor.java
================================================
package com.homihq.db2rest.interceptor;
import com.homihq.db2rest.core.exception.GenericDataAccessException;
import com.homihq.db2rest.multidb.DatabaseContextHolder;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.servlet.AsyncHandlerInterceptor;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
@Slf4j
@Component
public class DatabaseContextRequestInterceptor implements AsyncHandlerInterceptor {
private final List whiteList = List.of(
"/error", "/swagger-ui/**", "/v3/api-docs/**", "/actuator/**", "/admin/**",
VERSION + "/$dbs");
private final AntPathMatcher antPathMatcher = new AntPathMatcher();
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
log.info("Pre handle - {}", request.getRequestURI());
if (!isWhileListed(request.getRequestURI())) {
final Map pathVariables = (Map) request
.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
log.info("pathVariables - {}", pathVariables);
if (Objects.isNull(pathVariables)) {
throw new GenericDataAccessException("Database ID not found.");
}
String dbId = pathVariables.get("dbId");
log.debug("Db identifier : {}", dbId);
if (StringUtils.isNotBlank(dbId)) {
this.setTenantContext(dbId);
} else {
log.info("DB could not be determined.");
throw new GenericDataAccessException("Database ID not found.");
}
}
return true;
}
private boolean isWhileListed(String uri) {
return whiteList.stream().anyMatch(w -> antPathMatcher.match(w, uri));
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
DatabaseContextHolder.clear();
}
private void setTenantContext(String tenant) {
DatabaseContextHolder.setCurrentDbId(tenant);
}
}
================================================
FILE: db2rest-api/api-rest/src/main/java/com/homihq/db2rest/rest/RdbmsRestApi.java
================================================
package com.homihq.db2rest.rest;
public interface RdbmsRestApi {
String VERSION = "/v1/rdbms";
}
================================================
FILE: db2rest-api/api-rest/src/main/java/com/homihq/db2rest/rest/admin/AdminController.java
================================================
package com.homihq.db2rest.rest.admin;
import com.homihq.db2rest.jdbc.JdbcManager;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/admin")
@Slf4j
@RequiredArgsConstructor
public class AdminController {
private final JdbcManager jdbcManager;
@PostMapping("/reloadCache")
public void reloadCache(){
log.info("Reload cache request received.");
this.jdbcManager.reload();
}
}
================================================
FILE: db2rest-api/api-rest/src/main/java/com/homihq/db2rest/rest/create/BulkCreateController.java
================================================
package com.homihq.db2rest.rest.create;
import com.homihq.db2rest.auth.data.RoleDataFilter;
import com.homihq.db2rest.bulk.DataProcessor;
import com.homihq.db2rest.core.dto.CreateBulkResponse;
import com.homihq.db2rest.core.dto.CreateResponse;
import com.homihq.db2rest.core.exception.GenericDataAccessException;
import com.homihq.db2rest.dtos.BulkContext;
import com.homihq.db2rest.jdbc.core.service.BulkCreateService;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
@RestController
@Slf4j
@RequiredArgsConstructor
@EnableAsync
public class BulkCreateController implements BulkCreateRestApi {
private final BulkCreateService bulkCreateService;
private final List dataProcessors;
public CreateBulkResponse save(
List roleBasedDataFilters,
String dbId,
String tableName,
String schemaName,
List includeColumns,
List sequences,
boolean tsIdEnabled,
HttpServletRequest request) throws Exception {
DataProcessor dataProcessor = dataProcessors.stream()
.filter(d -> d.handle(request.getContentType()))
.findFirst().orElseThrow(() -> new GenericDataAccessException("Unable to process content type : "
+ request.getContentType()));
List> data = dataProcessor.getData(request.getInputStream());
BulkContext context = new BulkContext(dbId, schemaName, tableName, includeColumns, tsIdEnabled, sequences, 0, roleBasedDataFilters);
return bulkCreateService.saveBulk(context, data);
}
@Override
public CompletableFuture saveMultipartFile(
List roleBasedDataFilters,
String dbId,
String tableName,
String schemaName,
List includeColumns,
List sequences,
boolean tsIdEnabled,
MultipartFile file) {
BulkContext context = new BulkContext(dbId, schemaName, tableName, includeColumns, tsIdEnabled, sequences, 0, roleBasedDataFilters);
return bulkCreateService.saveMultipartFile(context, file);
}
}
================================================
FILE: db2rest-api/api-rest/src/main/java/com/homihq/db2rest/rest/create/BulkCreateRestApi.java
================================================
package com.homihq.db2rest.rest.create;
import com.homihq.db2rest.auth.data.RoleDataFilter;
import com.homihq.db2rest.core.dto.CreateBulkResponse;
import com.homihq.db2rest.core.dto.CreateResponse;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import static com.homihq.db2rest.config.MultiTenancy.ROLEBASEDDATAFILTERS;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
public interface BulkCreateRestApi {
@ResponseStatus(HttpStatus.CREATED)
@PostMapping(value = VERSION + "/{dbId}/{tableName}/bulk", consumes = {"application/json", "text/csv"})
CreateBulkResponse save(
@RequestAttribute(name = ROLEBASEDDATAFILTERS, required = false) List roleBasedDataFilters,
@PathVariable String dbId,
@PathVariable String tableName,
@RequestHeader(name = "Content-Profile", required = false) String schemaName,
@RequestParam(name = "columns", required = false) List includeColumns,
@RequestParam(name = "sequences", required = false) List sequences,
@RequestParam(name = "tsIdEnabled", required = false, defaultValue = "false") boolean tsIdEnabled,
HttpServletRequest request) throws Exception;
@ResponseStatus(HttpStatus.CREATED)
@PostMapping(value = VERSION + "/{dbId}/{tableName}/upload", consumes = {"multipart/form-data", "application/json"})
CompletableFuture saveMultipartFile(
@RequestAttribute(name = ROLEBASEDDATAFILTERS, required = false) List roleBasedDataFilters,
@PathVariable String dbId,
@PathVariable String tableName,
@RequestHeader(name = "Content-Profile", required = false) String schemaName,
@RequestParam(name = "columns", required = false) List includeColumns,
@RequestParam(name = "sequences", required = false) List sequences,
@RequestParam(name = "tsIdEnabled", required = false, defaultValue = "false") boolean tsIdEnabled,
@RequestParam("file") MultipartFile file) throws Exception;
}
================================================
FILE: db2rest-api/api-rest/src/main/java/com/homihq/db2rest/rest/create/CreateController.java
================================================
package com.homihq.db2rest.rest.create;
import java.util.List;
import java.util.Map;
import org.springframework.web.bind.annotation.RestController;
import com.homihq.db2rest.auth.data.RoleDataFilter;
import com.homihq.db2rest.config.MultiTenancy;
import com.homihq.db2rest.core.dto.CreateResponse;
import com.homihq.db2rest.jdbc.core.service.CreateService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@RestController
@Slf4j
@RequiredArgsConstructor
public class CreateController implements CreateRestApi {
private final CreateService createService;
@Override
public CreateResponse save(
List roleBasedDataFilters,
String dbId, String schemaName,
String tableName,
List includeColumns,
List sequences,
Map data,
boolean tsIdEnabled) {
MultiTenancy.addTenantColumns(data, dbId, tableName, roleBasedDataFilters);
return createService.save(dbId, schemaName, tableName, includeColumns, data, tsIdEnabled, sequences);
}
}
================================================
FILE: db2rest-api/api-rest/src/main/java/com/homihq/db2rest/rest/create/CreateRestApi.java
================================================
package com.homihq.db2rest.rest.create;
import static com.homihq.db2rest.config.MultiTenancy.ROLEBASEDDATAFILTERS;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import java.util.List;
import java.util.Map;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import com.homihq.db2rest.auth.data.RoleDataFilter;
import com.homihq.db2rest.core.dto.CreateResponse;
public interface CreateRestApi {
@ResponseStatus(HttpStatus.CREATED)
@PostMapping(VERSION + "/{dbId}/{tableName}")
CreateResponse save(
@RequestAttribute(name = ROLEBASEDDATAFILTERS, required = false) List roleBasedDataFilters,
@PathVariable String dbId,
@RequestHeader(name = "Content-Profile", required = false) String schemaName,
@PathVariable String tableName,
@RequestParam(name = "columns", required = false) List includeColumns,
@RequestParam(name = "sequences", required = false) List sequences,
@RequestBody Map data,
@RequestParam(name = "tsIdEnabled", required = false, defaultValue = "false") boolean tsIdEnabled);
}
================================================
FILE: db2rest-api/api-rest/src/main/java/com/homihq/db2rest/rest/delete/DeleteController.java
================================================
package com.homihq.db2rest.rest.delete;
import java.util.List;
import com.homihq.db2rest.auth.data.RoleDataFilter;
import com.homihq.db2rest.config.Db2RestConfigProperties;
import com.homihq.db2rest.config.MultiTenancy;
import com.homihq.db2rest.core.dto.DeleteResponse;
import com.homihq.db2rest.jdbc.core.service.DeleteService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
@RequiredArgsConstructor
public class DeleteController implements DeleteRestApi {
private final DeleteService deleteService;
private final Db2RestConfigProperties db2RestConfigProperties;
@Override
public DeleteResponse delete(
List roleBasedDataFilters,
String dbId,
String schemaName,
String tableName,
String filter
) {
db2RestConfigProperties.checkDeleteAllowed(filter);
int rows = deleteService.delete(dbId, schemaName, tableName,
MultiTenancy.joinFilters(filter, dbId, tableName, roleBasedDataFilters));
log.debug("Number of rows deleted - {}", rows);
return DeleteResponse.builder().rows(rows).build();
}
}
================================================
FILE: db2rest-api/api-rest/src/main/java/com/homihq/db2rest/rest/delete/DeleteRestApi.java
================================================
package com.homihq.db2rest.rest.delete;
import com.homihq.db2rest.auth.data.RoleDataFilter;
import com.homihq.db2rest.core.dto.DeleteResponse;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import static com.homihq.db2rest.config.MultiTenancy.ROLEBASEDDATAFILTERS;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import java.util.List;
public interface DeleteRestApi {
@ResponseStatus(HttpStatus.OK)
@DeleteMapping(VERSION + "/{dbId}/{tableName}")
DeleteResponse delete(
@RequestAttribute(name = ROLEBASEDDATAFILTERS, required = false) List roleBasedDataFilters,
@PathVariable String dbId,
@RequestHeader(name = "Content-Profile", required = false) String schemaName,
@PathVariable String tableName,
@RequestParam(required = false, defaultValue = "") String filter);
}
================================================
FILE: db2rest-api/api-rest/src/main/java/com/homihq/db2rest/rest/meta/db/DbInfoController.java
================================================
package com.homihq.db2rest.rest.meta.db;
import com.homihq.db2rest.jdbc.JdbcManager;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
@RestController
@Slf4j
@RequiredArgsConstructor
public class DbInfoController implements DbInfoRestApi {
private final JdbcManager jdbcManager;
@Override
public List getObjects() {
List dbInfoObjects = new ArrayList<>();
jdbcManager.getDbMetaMap().forEach(
(k, v) -> dbInfoObjects.add(new DbInfoObject(k, v.productName(), v.majorVersion(), v.driverName(), v.driverVersion()))
);
return dbInfoObjects;
}
}
================================================
FILE: db2rest-api/api-rest/src/main/java/com/homihq/db2rest/rest/meta/db/DbInfoObject.java
================================================
package com.homihq.db2rest.rest.meta.db;
public record DbInfoObject(
String dbId,
String productName,
int majorVersion,
String driverName,
String driverVersion
) {}
================================================
FILE: db2rest-api/api-rest/src/main/java/com/homihq/db2rest/rest/meta/db/DbInfoRestApi.java
================================================
package com.homihq.db2rest.rest.meta.db;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
@RequestMapping(VERSION + "/$dbs")
@Tag(name = "DB Info Objects", description = "Details the databases being managed by this instance of DB2Rest")
public interface DbInfoRestApi {
@Operation(summary = "Get all database info details",
description = "Get all database info details",
tags = {"DB Info Objects"}
)
@GetMapping()
List getObjects();
}
================================================
FILE: db2rest-api/api-rest/src/main/java/com/homihq/db2rest/rest/meta/schema/ColumnObject.java
================================================
package com.homihq.db2rest.rest.meta.schema;
import com.db2rest.jdbc.dialect.model.DbColumn;
public record ColumnObject(String name, Boolean pk, String dataType) {
public ColumnObject(DbColumn dbColumn) {
this(
dbColumn.name(),
dbColumn.pk(),
dbColumn.columnDataTypeName()
);
}
}
================================================
FILE: db2rest-api/api-rest/src/main/java/com/homihq/db2rest/rest/meta/schema/SchemaController.java
================================================
package com.homihq.db2rest.rest.meta.schema;
import com.homihq.db2rest.core.exception.GenericDataAccessException;
import com.homihq.db2rest.jdbc.JdbcManager;
import com.db2rest.jdbc.dialect.model.DbTable;
import com.homihq.db2rest.jdbc.sql.DbMeta;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
/**
* provides methods to filter and retrieve schema objects from a database
*/
@RestController
@Slf4j
@RequiredArgsConstructor
public class SchemaController implements SchemaRestApi {
private final JdbcManager jdbcManager;
/**
* @param dbId database id from which to retrieve the schema objects
* @param filter filter conditions to match against a schema, name, or type
* @param columns include the column information for a table
* @return list of schema objects (schema, name, type) that match the filter conditions
*/
@Override
public List extends TableObject> getObjects(String dbId, String filter, Boolean columns) {
log.debug("Filter - {}", filter);
DbMeta dbMeta = jdbcManager.getDbMetaByDbId(dbId);
if (Objects.isNull(dbMeta)) {
return List.of();
}
SchemaFilter schemaFilter = getSchemaFilter(filter);
List dbTables = dbMeta.dbTables();
Function tableMapper = columns
? TableWithColumnsObject::new
: TableObject::new;
if (Objects.isNull(schemaFilter)) {
return dbTables.stream().map(tableMapper).toList();
} else {
log.info("schemaFilter - {}", schemaFilter);
return dbTables.stream()
.filter(dbTable -> {
if (StringUtils.equals(schemaFilter.field, "schema")
&& StringUtils.containsIgnoreCase(dbTable.schema(), schemaFilter.value)) {
return true;
} else if (StringUtils.equals(schemaFilter.field, "name")
&& StringUtils.containsIgnoreCase(dbTable.name(), schemaFilter.value)) {
return true;
} else {
return StringUtils.equals(schemaFilter.field, "type")
&& StringUtils.containsIgnoreCase(dbTable.type(), schemaFilter.value);
}
})
.map(tableMapper).toList();
}
}
private SchemaFilter getSchemaFilter(String filter) {
if (StringUtils.isBlank(filter)) {
return null;
}
String[] fragments = filter.split("==");
if (fragments.length != 2) {
throw new GenericDataAccessException("Invalid filter condition. Only == supported for schema filter using a single value only.");
}
return new SchemaFilter(fragments[0], fragments[1]);
}
private record SchemaFilter(String field, String value) {
}
}
================================================
FILE: db2rest-api/api-rest/src/main/java/com/homihq/db2rest/rest/meta/schema/SchemaRestApi.java
================================================
package com.homihq.db2rest.rest.meta.schema;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
@RequestMapping(VERSION + "/{dbId}/$schemas")
@Tag(name = "Schema Objects", description = "Details about schemas and tables")
public interface SchemaRestApi {
@Operation(
summary = "Get all database objects for a given dbId",
description = "Get all database objects from all schemas/catalogs, tables, columns",
tags = {"Schema Objects"}
)
@ApiResponses(value = {
@ApiResponse(
responseCode = "200",
description = "Successful operation",
content = {
@Content(mediaType = "application/json",
schema = @Schema(oneOf = {TableObject.class, TableWithColumnsObject.class}))
}
)
})
@GetMapping()
List extends TableObject> getObjects(
@PathVariable String dbId,
@RequestParam(name = "filter", required = false, defaultValue = "") String filter,
@RequestParam(name = "columns", required = false, defaultValue = "false") Boolean columns
);
}
================================================
FILE: db2rest-api/api-rest/src/main/java/com/homihq/db2rest/rest/meta/schema/TableObject.java
================================================
package com.homihq.db2rest.rest.meta.schema;
import com.db2rest.jdbc.dialect.model.DbTable;
import lombok.EqualsAndHashCode;
import lombok.Getter;
@EqualsAndHashCode
@Getter
public class TableObject {
private final String schema;
private final String name;
private final String type;
public TableObject(DbTable dbTable) {
this.schema = dbTable.schema();
this.name = dbTable.name();
this.type = dbTable.type();
}
}
================================================
FILE: db2rest-api/api-rest/src/main/java/com/homihq/db2rest/rest/meta/schema/TableWithColumnsObject.java
================================================
package com.homihq.db2rest.rest.meta.schema;
import com.db2rest.jdbc.dialect.model.DbTable;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import java.util.List;
@EqualsAndHashCode(callSuper = true)
@Getter
public class TableWithColumnsObject extends TableObject {
private final List columns;
public TableWithColumnsObject(DbTable dbTable) {
super(dbTable);
this.columns = dbTable.dbColumns().stream().map(ColumnObject::new).toList();
}
}
================================================
FILE: db2rest-api/api-rest/src/main/java/com/homihq/db2rest/rest/read/CountQueryController.java
================================================
package com.homihq.db2rest.rest.read;
import com.homihq.db2rest.auth.data.RoleDataFilter;
import com.homihq.db2rest.config.MultiTenancy;
import com.homihq.db2rest.core.dto.CountResponse;
import com.homihq.db2rest.jdbc.core.service.CountQueryService;
import com.homihq.db2rest.jdbc.dto.ReadContext;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import static com.homihq.db2rest.config.MultiTenancy.ROLEBASEDDATAFILTERS;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import java.util.List;
@RestController
@Slf4j
@RequiredArgsConstructor
public class CountQueryController {
private final CountQueryService countQueryService;
@GetMapping(VERSION + "/{dbId}/{tableName}/count")
public CountResponse count(
@RequestAttribute(name = ROLEBASEDDATAFILTERS, required = false) List roleBasedDataFilters,
@PathVariable String dbId,
@PathVariable String tableName,
@RequestHeader(name = "Accept-Profile", required = false) String schemaName,
@RequestParam(name = "filter", required = false, defaultValue = "") String filter) {
log.debug("tableName - {}", tableName);
log.debug("filter - {}", filter);
ReadContext readContext = ReadContext.builder()
.dbId(dbId)
.schemaName(schemaName)
.tableName(tableName)
.filter(MultiTenancy.joinFilters(filter, dbId, tableName, roleBasedDataFilters))
.build();
return countQueryService.count(readContext);
}
}
================================================
FILE: db2rest-api/api-rest/src/main/java/com/homihq/db2rest/rest/read/ExistsQueryController.java
================================================
package com.homihq.db2rest.rest.read;
import com.homihq.db2rest.auth.data.RoleDataFilter;
import com.homihq.db2rest.config.MultiTenancy;
import com.homihq.db2rest.core.dto.ExistsResponse;
import com.homihq.db2rest.jdbc.core.service.ExistsQueryService;
import com.homihq.db2rest.jdbc.dto.JoinDetail;
import com.homihq.db2rest.jdbc.dto.ReadContext;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import static com.homihq.db2rest.config.MultiTenancy.ROLEBASEDDATAFILTERS;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
@Slf4j
@RestController
@RequiredArgsConstructor
public class ExistsQueryController {
private final ExistsQueryService existsQueryService;
@GetMapping(value = VERSION + "/{dbId}/{tableName}/exists", produces = "application/json")
public ExistsResponse exists(
@RequestAttribute(name = ROLEBASEDDATAFILTERS, required = false) List roleBasedDataFilters,
@PathVariable String dbId,
@PathVariable String tableName,
@RequestHeader(name = "Accept-Profile", required = false) String schemaName,
@RequestParam(name = "filter", required = false, defaultValue = "") String filter) {
log.debug("tableName - {}", tableName);
log.debug("filter - {}", filter);
ReadContext readContext = ReadContext.builder()
.dbId(dbId)
.schemaName(schemaName)
.tableName(tableName)
.filter(MultiTenancy.joinFilters(filter, dbId, tableName, roleBasedDataFilters))
.build();
return existsQueryService.exists(readContext);
}
@PostMapping(value = VERSION + "/{dbId}/{tableName}/exists/_expand", produces = "application/json")
public ExistsResponse exists(
@RequestAttribute(name = ROLEBASEDDATAFILTERS, required = false) List roleBasedDataFilters,
@PathVariable String dbId,
@PathVariable String tableName,
@RequestHeader(name="Accept-Profile", required = false) String schemaName,
@RequestParam(name = "filter", required = false, defaultValue = "") String filter,
@RequestBody List joins
) {
ReadContext readContext = ReadContext.builder()
.dbId(dbId)
.schemaName(schemaName)
.tableName(tableName)
.fields("*")
.filter(MultiTenancy.joinFilters(filter, dbId, tableName, roleBasedDataFilters))
.joins(joins)
.build();
return existsQueryService.exists(readContext);
}
}
================================================
FILE: db2rest-api/api-rest/src/main/java/com/homihq/db2rest/rest/read/FindOneController.java
================================================
package com.homihq.db2rest.rest.read;
import com.homihq.db2rest.auth.data.RoleDataFilter;
import com.homihq.db2rest.config.MultiTenancy;
import com.homihq.db2rest.jdbc.core.service.FindOneService;
import com.homihq.db2rest.jdbc.dto.ReadContext;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
import static com.homihq.db2rest.config.MultiTenancy.ROLEBASEDDATAFILTERS;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
@RestController
@Slf4j
@RequiredArgsConstructor
public class FindOneController {
private final FindOneService findOneService;
@GetMapping(VERSION + "/{dbId}/{tableName}/one")
public Map findOne(
@RequestAttribute(name = ROLEBASEDDATAFILTERS, required = false) List roleBasedDataFilters,
@PathVariable String dbId,
@PathVariable String tableName,
@RequestHeader(name = "Accept-Profile", required = false) String schemaName,
@RequestParam(name = "fields", required = false, defaultValue = "*") String fields,
@RequestParam(name = "filter", required = false, defaultValue = "") String filter) {
log.debug("tableName - {}", tableName);
log.debug("fields - {}", fields);
log.debug("filter - {}", filter);
ReadContext readContext = ReadContext.builder()
.dbId(dbId)
.defaultFetchLimit(100) //todo update with config
.schemaName(schemaName)
.tableName(tableName)
.filter(MultiTenancy.joinFilters(filter, dbId, tableName, roleBasedDataFilters))
.fields(fields)
.build();
return this.findOneService.findOne(readContext);
}
}
================================================
FILE: db2rest-api/api-rest/src/main/java/com/homihq/db2rest/rest/read/ReadController.java
================================================
package com.homihq.db2rest.rest.read;
import com.homihq.db2rest.auth.data.RoleDataFilter;
import com.homihq.db2rest.config.Db2RestConfigProperties;
import com.homihq.db2rest.config.MultiTenancy;
import com.homihq.db2rest.jdbc.core.service.ReadService;
import com.homihq.db2rest.jdbc.dto.JoinDetail;
import com.homihq.db2rest.jdbc.dto.ReadContext;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import static com.homihq.db2rest.config.MultiTenancy.ROLEBASEDDATAFILTERS;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
@RestController
@Slf4j
@RequiredArgsConstructor
public class ReadController {
private final ReadService readService;
private final Db2RestConfigProperties db2RestConfigProperties;
@GetMapping(value = VERSION + "/{dbId}/{tableName}", produces = "application/json")
public Object findAll(
@RequestAttribute(name = ROLEBASEDDATAFILTERS, required = false) List roleBasedDataFilters,
@PathVariable String dbId,
@PathVariable String tableName,
@RequestHeader(name = "Accept-Profile", required = false) String schemaName,
@RequestParam(required = false, defaultValue = "*") String fields,
@RequestParam(required = false, defaultValue = "") String filter,
@RequestParam(name = "sort", required = false, defaultValue = "") List sorts,
@RequestParam(required = false, defaultValue = "-1") int limit,
@RequestParam(required = false, defaultValue = "-1") long offset) {
log.debug("filter - {}", filter);
ReadContext readContext = ReadContext.builder()
.dbId(dbId)
.schemaName(schemaName)
.tableName(tableName)
.fields(fields)
.filter(MultiTenancy.joinFilters(filter, dbId, tableName, roleBasedDataFilters))
.sorts(sorts)
.limit(limit)
.defaultFetchLimit(db2RestConfigProperties.getDefaultFetchLimit())
.offset(offset)
.build();
return readService.findAll(readContext);
}
@PostMapping(value = VERSION + "/{dbId}/{tableName}/_expand", produces = "application/json")
public Object find(
@RequestAttribute(name = ROLEBASEDDATAFILTERS, required = false) List roleBasedDataFilters,
@PathVariable String dbId,
@PathVariable String tableName,
@RequestHeader(name = "Accept-Profile", required = false) String schemaName,
@RequestParam(required = false, defaultValue = "*") String fields,
@RequestParam(required = false, defaultValue = "") String filter,
@RequestParam(name = "sort", required = false, defaultValue = "") List sorts,
@RequestParam(required = false, defaultValue = "-1") int limit,
@RequestParam(required = false, defaultValue = "-1") long offset,
@RequestBody List joins
) {
ReadContext readContext = ReadContext.builder()
.dbId(dbId)
.schemaName(schemaName)
.tableName(tableName)
.fields(fields)
.filter(MultiTenancy.joinFilters(filter, dbId, tableName, roleBasedDataFilters))
.sorts(sorts)
.limit(limit)
.defaultFetchLimit(db2RestConfigProperties.getDefaultFetchLimit())
.offset(offset)
.joins(joins)
.build();
return readService.findAll(readContext);
}
}
================================================
FILE: db2rest-api/api-rest/src/main/java/com/homihq/db2rest/rest/rpc/FunctionController.java
================================================
package com.homihq.db2rest.rest.rpc;
import com.homihq.db2rest.jdbc.core.service.FunctionService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
@RestController
@RequestMapping(VERSION + "/{dbId}/function")
@Slf4j
@RequiredArgsConstructor
public class FunctionController {
private final FunctionService functionService;
@PostMapping("/{funcName}")
public ResponseEntity> execute(
@PathVariable String dbId,
@PathVariable String funcName,
@RequestBody Map inParams) {
log.debug("Execute function {} with IN params {}", funcName, inParams.entrySet());
return ResponseEntity.ok(functionService.execute(dbId, funcName, inParams));
}
}
================================================
FILE: db2rest-api/api-rest/src/main/java/com/homihq/db2rest/rest/rpc/ProcedureController.java
================================================
package com.homihq.db2rest.rest.rpc;
import com.homihq.db2rest.jdbc.core.service.ProcedureService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
@RestController
@RequestMapping(VERSION + "/{dbId}/procedure")
@Slf4j
@RequiredArgsConstructor
public class ProcedureController {
private final ProcedureService procedureService;
@PostMapping("/{procName}")
public ResponseEntity> execute(
@PathVariable String dbId,
@PathVariable String procName,
@RequestBody Map inParams,
@RequestParam(name = "resultSetKeys", required = false) List resultSetKeys) {
log.debug("Execute stored procedure {} with IN params {}", procName, inParams.entrySet());
log.info("ResultSetKeys: {}", resultSetKeys);
return ResponseEntity.ok(procedureService.execute(dbId, procName, inParams,resultSetKeys));
}
}
================================================
FILE: db2rest-api/api-rest/src/main/java/com/homihq/db2rest/rest/sql/SQLTemplateController.java
================================================
package com.homihq.db2rest.rest.sql;
import com.homihq.db2rest.core.exception.PathVariableNamesMissingException;
import com.homihq.db2rest.core.exception.PathVariableValuesMissingException;
import com.homihq.db2rest.jdbc.core.service.SQLTemplateExecutorService;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
@Slf4j
@RestController
@RequestMapping(VERSION + "/{dbId}/sql")
@RequiredArgsConstructor
@Tag(name = "Parameterized SQL Template ", description = "Details about schemas and tables")
public class SQLTemplateController {
private final SQLTemplateExecutorService sqlTemplateExecutorService;
@GetMapping("/{fileName}/{*userPathVariable}")
public Object sqlTemplate(@PathVariable String dbId,
@PathVariable String fileName,
@PathVariable(name = "userPathVariable") String userPathVariable,
@RequestParam Map requestParams,
@RequestHeader Map requestHeaders,
@MatrixVariable Map matrixVariables
) {
final Map context = createContext(requestParams, requestHeaders, matrixVariables);
Map paths = createPaths(userPathVariable, requestHeaders);
context.put("paths", paths);
log.debug("context - {}", context);
return sqlTemplateExecutorService.execute(dbId, fileName, context);
}
@PostMapping("/{fileName}")
public Object sqlTemplate(@PathVariable String dbId,
@PathVariable String fileName,
@RequestBody Map content,
@RequestParam Map requestParams,
@RequestHeader Map requestHeaders,
@MatrixVariable Map matrixVariables) {
final Map context = createContext(requestParams, requestHeaders, matrixVariables);
context.put("content", content);
log.debug("context - {}", context);
return sqlTemplateExecutorService.execute(dbId, fileName, context);
}
private Map createContext(
Map requestParams,
Map requestHeaders,
Map matrixVariables
) {
final Map context = new HashMap<>();
context.put("params", requestParams);
context.put("headers", requestHeaders);
context.put("matrix", matrixVariables);
return context;
}
private static Map createPaths(String userPathVariable, Map requestHeaders) {
final List userPathVariables = Arrays.stream(userPathVariable.split("/"))
.filter(StringUtils::isNotEmpty)
.toList();
final String headerPaths = requestHeaders.get("paths");
if (!userPathVariables.isEmpty() && StringUtils.isBlank(headerPaths)) {
throw new PathVariableNamesMissingException();
}
Map pathVariables = new HashMap<>();
if (StringUtils.isNotBlank(headerPaths)) {
String[] pathKeys = headerPaths.split(",");
if (pathKeys.length != userPathVariables.size()) {
throw new PathVariableValuesMissingException();
}
for (int i = 0; i < pathKeys.length; i++) {
final String key = pathKeys[i];
final String pathValue = userPathVariables.get(i);
if (StringUtils.isBlank(pathValue)) {
throw new PathVariableValuesMissingException(key);
}
pathVariables.put(key, pathValue);
}
}
return pathVariables;
}
}
================================================
FILE: db2rest-api/api-rest/src/main/java/com/homihq/db2rest/rest/update/UpdateController.java
================================================
package com.homihq.db2rest.rest.update;
import com.homihq.db2rest.auth.data.RoleDataFilter;
import com.homihq.db2rest.config.MultiTenancy;
import com.homihq.db2rest.core.dto.UpdateResponse;
import com.homihq.db2rest.jdbc.core.service.UpdateService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
import static com.homihq.db2rest.config.MultiTenancy.ROLEBASEDDATAFILTERS;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
@RestController
@Slf4j
@RequiredArgsConstructor
public class UpdateController {
private final UpdateService updateService;
@PatchMapping(VERSION + "/{dbId}/{tableName}")
public UpdateResponse save(
@RequestAttribute(name = ROLEBASEDDATAFILTERS, required = false) List roleBasedDataFilters,
@PathVariable String dbId,
@PathVariable String tableName,
@RequestHeader(name = "Content-Profile", required = false) String schemaName,
@RequestBody Map data,
@RequestParam(name = "filter", required = false, defaultValue = "") String filter) {
MultiTenancy.addTenantColumns(data, dbId, tableName, roleBasedDataFilters);
int rows = updateService.patch(dbId, schemaName, tableName, data,
MultiTenancy.joinFilters(filter, dbId, tableName, roleBasedDataFilters));
return new UpdateResponse(rows);
}
}
================================================
FILE: db2rest-api/api-rest/src/main/resources/application.yml
================================================
app:
version: @project.version@
name: @project.name@
databases:
- id: ${DB_ID:db}
url: ${DB_URL:}
username: ${DB_USER}
password: ${DB_PASSWORD}
schemas: ${INCLUDED_SCHEMAS:}
maxConnections: ${MAX_POOL_SIZE:5}
server:
port: ${SERVER_PORT:8080}
forward-headers-strategy: framework
compression:
enabled: ${GZIP_ENABLED:false}
mime-types: application/json
min-response-size: ${GZIP_MIN_RESPONSE_SIZE:1024}
# excluded-user-agents: MSIE 6.0,UCBrowser
spring:
threads:
virtual:
enabled: true
banner:
location: classpath:banner.txt
servlet:
multipart:
enabled: true
max-file-size: 5MB
max-request-size: 5MB
cors:
enabled: ${ENABLE_CORS:false}
mappings: ${CORS_MAPPING:[{}]}
db2rest:
auth:
enabled: ${ENABLE_AUTH:false}
provider: ${AUTH_PROVIDER:basic}
data:
source: ${AUTH_DATA_SOURCE}
dateTime:
enableDataTimeFormatting: ${ENABLE_DATETIME_FORMATTING:false}
timeFormat: ${TIME_FORMAT:HH:mm:ss}
dateFormat: ${DATE_FORMAT:yyyy-MM-dd}
dateTimeFormat: ${DATE_TIME_FORMAT:yyyy-MM-dd HH:mm:ss}
defaultFetchLimit: ${DEFAULT_FETCH_LIMIT:100}
allowSafeDelete : ${ALLOW_SAFE_DELETE:true}
templates: ${SQL_TEMPLATE_PATH}
logging:
level:
com:
homihq:
db2rest:
rest: INFO
jdbc:
core:
service: INFO
org:
springframework:
web: INFO
beans: INFO
jdbc: DEBUG
management:
endpoints:
web:
exposure:
include: "health,info,httpexchanges,prometheus,metrics"
datadog:
metrics:
export:
enabled: ${DATADOG_EXPORT_ENABLED:false}
api-key: ${DATADOG_API_KEY}
application-key: ${DATADOG_APPLICATION_KEY}
uri: ${DATADOG_EXPORT_URI}
step: ${DATADOG_EXPORT_INTERVAL:30s}
prometheus:
metrics:
export:
enabled: ${PROMETHEUS_EXPORT_ENABLED:false}
================================================
FILE: db2rest-api/api-rest/src/main/resources/banner.txt
================================================
${AnsiColor.RED} ____ ____ ____ ____ ____ _____ ____ _____ ____
${AnsiColor.BLUE} / / / | _ \| __ )___ \| _ \| ____/ ___|_ _| \ \ \
${AnsiColor.YELLOW} | | | | | | | _ \ __) | |_) | _| \___ \ | | | | |
${AnsiColor.GREEN} < < < | |_| | |_) / __/| _ <| |___ ___) || | > > >
${AnsiColor.MAGENTA} | | | |____/|____/_____|_| \_\_____|____/ |_| | | |
${AnsiColor.BRIGHT_GREEN} \_\_\ ========================================= /_/_/
${AnsiColor.DEFAULT}+---------------------------------------------------+
|${AnsiColor.GREEN}:: ${app.name} version :: ${AnsiColor.DEFAULT}v${app.version} |
|${AnsiColor.GREEN}:: Spring-Boot version :: ${AnsiColor.DEFAULT}v${spring-boot.version} |
|${AnsiColor.GREEN}:: Visit ${app.name} website :: ${AnsiColor.DEFAULT}[https://db2rest.com/] |
${AnsiColor.DEFAULT}+---------------------------------------------------+
================================================
FILE: db2rest-api/api-rest/src/main/resources/sql-templates/count.jte
================================================
@param String rootTable
@param String rootWhere
SELECT
COUNT(*)
FROM
${rootTable}
@if(rootWhere != null)
WHERE ${rootWhere}
@endif
================================================
FILE: db2rest-api/api-rest/src/main/resources/sql-templates/delete-mssql.jte
================================================
@param String rootTable
@param String rootWhere
@param String rootTableAlias
DELETE FROM ${rootTableAlias}
FROM ${rootTable}
@if(rootWhere != null)
WHERE ${rootWhere}
@endif
================================================
FILE: db2rest-api/api-rest/src/main/resources/sql-templates/delete.jte
================================================
@param String rootTable
@param String rootWhere
DELETE FROM
${rootTable}
@if(rootWhere != null)
WHERE ${rootWhere}
@endif
================================================
FILE: db2rest-api/api-rest/src/main/resources/sql-templates/exists-mssql.jte
================================================
@import com.db2rest.jdbc.dialect.model.DbJoin
@import java.util.List
@param String rootTable
@param String rootWhere
@param List joins
SELECT TOP 1 1
FROM ${rootTable}
@if(joins != null)
@for(DbJoin join : joins)
${join.render()}
@endfor
@endif
@if(rootWhere != null)
WHERE ${rootWhere}
@endif
================================================
FILE: db2rest-api/api-rest/src/main/resources/sql-templates/exists.jte
================================================
@import com.db2rest.jdbc.dialect.model.DbJoin
@import java.util.List
@param String rootTable
@param String rootWhere
@param List joins
SELECT
1
FROM ${rootTable}
@if(joins != null)
@for(DbJoin join : joins)
${join.render()}
@endfor
@endif
@if(rootWhere != null)
WHERE ${rootWhere}
@endif
LIMIT 1
================================================
FILE: db2rest-api/api-rest/src/main/resources/sql-templates/find-one.jte
================================================
@param String rootTable
@param String rootWhere
@param String columns
SELECT
${columns}
FROM
${rootTable}
@if(rootWhere != null)
WHERE ${rootWhere}
@endif
================================================
FILE: db2rest-api/api-rest/src/main/resources/sql-templates/insert.jte
================================================
@param String columns
@param String table
@param String parameters
INSERT INTO ${table}
(${columns})
VALUES
(${parameters})
================================================
FILE: db2rest-api/api-rest/src/main/resources/sql-templates/read-mssql.jte
================================================
@import com.db2rest.jdbc.dialect.model.DbJoin
@import java.util.List
@param List joins
@param String rootTable
@param String columns
@param String rootWhere
@param String sorts
@param Integer limit
@param Long offset
@if(sorts != null)
SELECT
${columns}
FROM ${rootTable}
@if(joins != null)
@for(DbJoin join : joins)
${join.render()}
@endfor
@endif
@if(rootWhere != null)
WHERE ${rootWhere}
@endif
ORDER BY ${sorts}
@if(limit != null)
OFFSET ${(offset == null ? 0 : offset)} ROWS FETCH NEXT ${limit} ROWS ONLY
@endif
@elseif(limit != null)
@if(offset != null)
SELECT T.* FROM
(
SELECT
${columns},
ROW_NUMBER() OVER(ORDER BY (SELECT 1)) AS rowIndex
FROM ${rootTable}
@if(joins != null)
@for(DbJoin join : joins)
${join.render()}
@endfor
@endif
@if(rootWhere != null)
WHERE ${rootWhere}
@endif
) AS T
WHERE rowIndex > ${offset} AND rowIndex <= ${offset + limit}
@else
SELECT TOP ${limit} ${columns}
FROM ${rootTable}
@if(joins != null)
@for(DbJoin join : joins)
${join.render()}
@endfor
@endif
@if(rootWhere != null)
WHERE ${rootWhere}
@endif
@endif
@else
SELECT
${columns}
FROM ${rootTable}
@if(joins != null)
@for(DbJoin join : joins)
${join.render()}
@endfor
@endif
@if(rootWhere != null)
WHERE ${rootWhere}
@endif
@endif
================================================
FILE: db2rest-api/api-rest/src/main/resources/sql-templates/read-ora-12.jte
================================================
@import com.db2rest.jdbc.dialect.model.DbJoin
@import java.util.List
@param List joins
@param String rootTable
@param String columns
@param String rootWhere
@param String sorts
@param Integer limit
@param Long offset
SELECT
${columns}
FROM
${rootTable}
@if(joins != null)
@for(DbJoin join : joins)
${join.render()}
@endfor
@endif
@if(rootWhere != null)
WHERE ${rootWhere}
@endif
@if(sorts != null)
ORDER BY ${sorts}
@endif
@if(limit != null)
@if(offset != null)
OFFSET ${offset} ROWS
FETCH NEXT ${limit} ROWS ONLY
@else
FETCH FIRST ${limit} ROWS ONLY
@endif
@endif
================================================
FILE: db2rest-api/api-rest/src/main/resources/sql-templates/read-ora-9.jte
================================================
@import com.db2rest.jdbc.dialect.model.DbJoin
@import java.util.List
@param List joins
@param String rootTable
@param String columns
@param String rootWhere
@param String sorts
@param Integer limit
@param Long offset
@if(limit != null)
@if(offset != null)
SELECT T.* FROM
(
SELECT T.*, rownum as rowIndex FROM
(
SELECT
${columns}
FROM
${rootTable}
@if(joins != null)
@for(DbJoin join : joins)
${join.render()}
@endfor
@endif
@if(rootWhere != null)
WHERE ${rootWhere}
@endif
@if(sorts != null)
ORDER BY ${sorts}
@endif
) T
) T
WHERE rowIndex > ${offset} AND rowIndex <= ${offset + limit}
@else
SELECT * FROM (
SELECT
${columns}
FROM
${rootTable}
@if(joins != null)
@for(DbJoin join : joins)
${join.render()}
@endfor
@endif
@if(rootWhere != null)
WHERE ${rootWhere}
@endif
@if(sorts != null)
ORDER BY ${sorts}
@endif
)
WHERE ROWNUM <= ${limit}
@endif
@else
SELECT
${columns}
FROM
${rootTable}
@if(joins != null)
@for(DbJoin join : joins)
${join.render()}
@endfor
@endif
@if(rootWhere != null)
WHERE ${rootWhere}
@endif
@if(sorts != null)
ORDER BY ${sorts}
@endif
@endif
================================================
FILE: db2rest-api/api-rest/src/main/resources/sql-templates/read.jte
================================================
@import com.db2rest.jdbc.dialect.model.DbJoin
@import java.util.List
@param List joins
@param String rootTable
@param String columns
@param String rootWhere
@param String sorts
@param Integer limit
@param Long offset
SELECT
${columns}
FROM
${rootTable}
@if(joins != null)
@for(DbJoin join : joins)
${join.render()}
@endfor
@endif
@if(rootWhere != null)
WHERE ${rootWhere}
@endif
@if(sorts != null)
ORDER BY ${sorts}
@endif
@if(limit != null)
LIMIT ${limit}
@if(offset != null)
OFFSET ${offset}
@endif
@endif
================================================
FILE: db2rest-api/api-rest/src/main/resources/sql-templates/update-mssql.jte
================================================
@param String rootTable
@param String rootWhere
@param String columnSets
@param String rootTableAlias
UPDATE ${rootTableAlias}
SET ${columnSets}
FROM ${rootTable}
@if(rootWhere != null)
WHERE ${rootWhere}
@endif
================================================
FILE: db2rest-api/api-rest/src/main/resources/sql-templates/update.jte
================================================
@param String rootTable
@param String rootWhere
@param String columnSets
UPDATE ${rootTable}
SET ${columnSets}
@if(rootWhere != null)
WHERE ${rootWhere}
@endif
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/BaseIntegrationTest.java
================================================
package com.homihq.db2rest;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.provider.Arguments;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.restdocs.RestDocumentationContextProvider;
import org.springframework.restdocs.RestDocumentationExtension;
import org.springframework.restdocs.templates.TemplateFormats;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import com.homihq.db2rest.config.Db2RestConfigProperties;
import lombok.extern.slf4j.Slf4j;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
@ExtendWith({RestDocumentationExtension.class})
@Slf4j
public abstract class BaseIntegrationTest {
@Autowired
protected MockMvc mockMvc;
@Autowired
protected ApplicationContext applicationContext;
@Autowired
protected Db2RestConfigProperties db2RestConfigProperties;
@BeforeEach
void setUp(WebApplicationContext webApplicationContext, RestDocumentationContextProvider restDocumentation) {
createMockMvc(webApplicationContext, restDocumentation);
setupEnv();
}
protected void createMockMvc(WebApplicationContext webApplicationContext, RestDocumentationContextProvider restDocumentation) {
mockMvc = MockMvcBuilders
.webAppContextSetup(webApplicationContext)
.apply(documentationConfiguration(restDocumentation).snippets().withTemplateFormat(TemplateFormats.markdown()))
.build();
}
void setupEnv() {
var templatesLocation = db2RestConfigProperties.getTemplates();
if (templatesLocation.startsWith(ResourceLoader.CLASSPATH_URL_PREFIX)) {
try {
Resource resource = applicationContext.getResource(templatesLocation);
var resolvedTemplatesLocation = String.valueOf(Paths.get(resource.getFile().getAbsolutePath()));
db2RestConfigProperties.setTemplates(resolvedTemplatesLocation);
} catch (IOException ioe) {
log.debug("Error while resolve _sql templates location for testing", ioe);
}
}
}
static List isoDateTimeFormats() {
return List.of(Arguments.of("2011-12-03T10:15:30"),
Arguments.of("2011-12-03T10:15:30.123"),
Arguments.of("2011-12-03T10:15:30+01:00"),
Arguments.of("2011-12-03T10:15:30-05:00"),
Arguments.of("2011-12-03T10:15:30Z"),
Arguments.of("2011-12-03T10:15:30.123Z"),
Arguments.of("2011-12-03T10:15:30.123+05:30"),
Arguments.of("2011-12-03T10:15:30+01:00[Europe/Paris]"),
Arguments.of("2011-12-03T10:15:30.123+01:00[Europe/Paris]"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/DB2BaseIntegrationTest.java
================================================
package com.homihq.db2rest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Import;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ActiveProfiles;
@Import(DB2ContainerConfiguration.class)
@ActiveProfiles("it-db2")
public class DB2BaseIntegrationTest extends BaseIntegrationTest {
@Autowired
private JdbcTemplate jdbcTemplate;
protected boolean deleteRow(String table, String column, int id) {
var query = "DELETE FROM " + table + " WHERE " + column + " = ?";
return jdbcTemplate.update(query, id) == 1;
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/DB2ContainerConfiguration.java
================================================
package com.homihq.db2rest;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;
import org.testcontainers.db2.Db2Container;
import org.testcontainers.ext.ScriptUtils;
import org.testcontainers.jdbc.JdbcDatabaseDelegate;
import com.homihq.db2rest.jdbc.multidb.RoutingDataSource;
@TestConfiguration(proxyBeanMethods = false)
@Profile("it-db2")
public class DB2ContainerConfiguration {
private static final List db2Scripts = List.of("db2/db2-sakila.sql"
, "db2/db2-sakila-data.sql");
private static final Db2Container db2 = new Db2Container("icr.io/db2_community/db2:11.5.8.0").acceptLicense()
.withDatabaseName("BLUDB")
.withUsername("db2inst1")
.withPassword("password")
.withReuse(true);
static {
db2.start();
var containerDelegate = new JdbcDatabaseDelegate(db2, "");
db2Scripts.forEach(initScript -> ScriptUtils.runInitScript(containerDelegate, initScript));
}
@Bean
public DataSource dataSource() {
var dataSourceBuilder = DataSourceBuilder.create();
dataSourceBuilder.driverClassName("com.ibm.db2.jcc.DB2Driver");
dataSourceBuilder.url(db2.getJdbcUrl());
dataSourceBuilder.username(db2.getUsername());
dataSourceBuilder.password(db2.getPassword());
DataSource dataSource = dataSourceBuilder.build();
final RoutingDataSource routingDataSource = new RoutingDataSource();
routingDataSource.setTargetDataSources(Map.of("db2b", dataSource));
routingDataSource.setDefaultTargetDataSource(dataSource);
return routingDataSource;
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/MariaDBBaseIntegrationTest.java
================================================
package com.homihq.db2rest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Import;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ActiveProfiles;
@Import(MariaDBContainerConfiguration.class)
@ActiveProfiles("it-mariadb")
public class MariaDBBaseIntegrationTest extends BaseIntegrationTest {
@Autowired
private JdbcTemplate jdbcTemplate;
protected boolean deleteRow(String table, String column, int id) {
var query = "DELETE FROM " + table + " WHERE " + column + " = ?";
return jdbcTemplate.update(query, id) == 1;
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/MariaDBContainerConfiguration.java
================================================
package com.homihq.db2rest;
import com.homihq.db2rest.jdbc.multidb.RoutingDataSource;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;
import org.testcontainers.containers.MariaDBContainer;
import org.testcontainers.ext.ScriptUtils;
import org.testcontainers.jdbc.JdbcDatabaseDelegate;
import javax.sql.DataSource;
import java.util.List;
import java.util.Map;
@TestConfiguration(proxyBeanMethods = false)
@Profile("it-mariadb")
public class MariaDBContainerConfiguration {
private static final List mariaDbScripts = List.of("mariadb/mariadb-sakila.sql",
"mariadb/mariadb-sakila-data.sql");
private static final MariaDBContainer mariaDbContainer =
(MariaDBContainer) new MariaDBContainer("mariadb:11.0")
.withDatabaseName("sakila")
.withUsername("maria")
.withPassword("test")
.withReuse(true);
static {
mariaDbContainer.start();
var containerDelegate = new JdbcDatabaseDelegate(mariaDbContainer, "");
mariaDbScripts.forEach(initScript -> ScriptUtils.runInitScript(containerDelegate, initScript));
}
@Bean
public DataSource dataSource() {
var dataSourceBuilder = DataSourceBuilder.create();
dataSourceBuilder.driverClassName("org.mariadb.jdbc.Driver");
dataSourceBuilder.url(mariaDbContainer.getJdbcUrl());
dataSourceBuilder.username(mariaDbContainer.getUsername());
dataSourceBuilder.password(mariaDbContainer.getPassword());
DataSource dataSource = dataSourceBuilder.build();
final RoutingDataSource routingDataSource = new RoutingDataSource();
routingDataSource.setTargetDataSources(Map.of("mariadb", dataSource));
routingDataSource.setDefaultTargetDataSource(dataSource);
return routingDataSource;
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/MsSQLServerContainerConfiguration.java
================================================
package com.homihq.db2rest;
import com.homihq.db2rest.jdbc.multidb.RoutingDataSource;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;
import org.testcontainers.containers.MSSQLServerContainer;
import org.testcontainers.ext.ScriptUtils;
import org.testcontainers.jdbc.JdbcDatabaseDelegate;
import javax.sql.DataSource;
import java.util.List;
import java.util.Map;
@TestConfiguration(proxyBeanMethods = false)
@Profile("it-mssql")
public class MsSQLServerContainerConfiguration {
private static final MSSQLServerContainer> MSSQL_SERVER_CONTAINER =
new MSSQLServerContainer<>("mcr.microsoft.com/mssql/server:2022-latest")
.acceptLicense();
private static final List SCRIPTS = List.of(
"mssql/mssql-sakila.sql",
"mssql/mssql-sakila-data.sql"
);
static {
MSSQL_SERVER_CONTAINER.start();
var containerDelegate = new JdbcDatabaseDelegate(MSSQL_SERVER_CONTAINER, "");
SCRIPTS.forEach(script -> ScriptUtils.runInitScript(containerDelegate, script));
}
@Bean
public DataSource dataSource() {
var dataSourceBuilder = DataSourceBuilder.create();
dataSourceBuilder.url(MSSQL_SERVER_CONTAINER.getJdbcUrl());
dataSourceBuilder.username(MSSQL_SERVER_CONTAINER.getUsername());
dataSourceBuilder.password(MSSQL_SERVER_CONTAINER.getPassword());
DataSource dataSource = dataSourceBuilder.build();
var routingDataSource = new RoutingDataSource();
routingDataSource.setTargetDataSources(Map.of("mssql", dataSource));
routingDataSource.setDefaultTargetDataSource(dataSource);
return routingDataSource;
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/MySQLBaseIntegrationTest.java
================================================
package com.homihq.db2rest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Import;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ActiveProfiles;
@Import(MySQLContainerConfiguration.class)
@ActiveProfiles("it-mysql")
public class MySQLBaseIntegrationTest extends BaseIntegrationTest {
@Autowired
private JdbcTemplate jdbcTemplate;
protected boolean deleteRow(String table, String column, int id) {
var query = "DELETE FROM " + table + " WHERE " + column + " = ?";
return jdbcTemplate.update(query, id) == 1;
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/MySQLContainerConfiguration.java
================================================
package com.homihq.db2rest;
import com.homihq.db2rest.jdbc.multidb.RoutingDataSource;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;
import org.testcontainers.containers.MySQLContainer;
import org.testcontainers.ext.ScriptUtils;
import org.testcontainers.jdbc.JdbcDatabaseDelegate;
import javax.sql.DataSource;
import java.util.List;
import java.util.Map;
@TestConfiguration(proxyBeanMethods = false)
@Profile("it-mysql")
public class MySQLContainerConfiguration {
private static final List mySqlScripts = List.of("mysql/mysql-sakila.sql",
"mysql/mysql-sakila-data.sql", "mysql/mysql-wakila-all.sql");
private static final MySQLContainer mySQLContainer =
(MySQLContainer) new MySQLContainer("mysql:8.2")
.withDatabaseName("sakila")
.withUsername("root")
//.withPassword("mysql")
.withReuse(true);
static {
mySQLContainer.start();
var containerDelegate = new JdbcDatabaseDelegate(mySQLContainer, "");
mySqlScripts.forEach(initScript -> ScriptUtils.runInitScript(containerDelegate, initScript));
}
@Bean
public DataSource dataSource() {
var dataSourceBuilder = DataSourceBuilder.create();
dataSourceBuilder.driverClassName("com.mysql.cj.jdbc.Driver");
dataSourceBuilder.url(mySQLContainer.getJdbcUrl());
dataSourceBuilder.username(mySQLContainer.getUsername());
dataSourceBuilder.password(mySQLContainer.getPassword());
DataSource dataSource = dataSourceBuilder.build();
final RoutingDataSource routingDataSource = new RoutingDataSource();
routingDataSource.setTargetDataSources(Map.of("mysqldb", dataSource));
routingDataSource.setDefaultTargetDataSource(dataSource);
return routingDataSource;
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/OracleBaseIntegrationTest.java
================================================
package com.homihq.db2rest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Import;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ActiveProfiles;
@Import(OracleContainerConfiguration.class)
@ActiveProfiles("it-oracle")
public class OracleBaseIntegrationTest extends BaseIntegrationTest {
@Autowired
private JdbcTemplate jdbcTemplate;
protected boolean deleteRow(String table, String column, int id) {
var query = "DELETE FROM " + table + " WHERE " + column + " = ?";
return jdbcTemplate.update(query, id) == 1;
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/OracleContainerConfiguration.java
================================================
package com.homihq.db2rest;
import com.homihq.db2rest.jdbc.multidb.RoutingDataSource;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;
import org.testcontainers.containers.OracleContainer;
import org.testcontainers.ext.ScriptUtils;
import org.testcontainers.jdbc.JdbcDatabaseDelegate;
import javax.sql.DataSource;
import java.util.List;
import java.util.Map;
@TestConfiguration(proxyBeanMethods = false)
@Profile("it-oracle")
public class OracleContainerConfiguration {
private static final List oracleScripts = List.of("oracle/oracle-sakila.sql"
, "oracle/oracle-sakila-data.sql");
private static final OracleContainer testOracle10g =
new OracleContainer("gvenzl/oracle-xe:21-slim-faststart")
.withDatabaseName("testDB")
.withUsername("testUser")
.withPassword("testPassword")
.withReuse(true);
static {
testOracle10g.start();
var containerDelegate = new JdbcDatabaseDelegate(testOracle10g, "");
oracleScripts.forEach(initScript -> ScriptUtils.runInitScript(containerDelegate, initScript));
}
@Bean
public DataSource dataSource() {
var dataSourceBuilder = DataSourceBuilder.create();
dataSourceBuilder.driverClassName("oracle.jdbc.OracleDriver");
dataSourceBuilder.url(testOracle10g.getJdbcUrl());
dataSourceBuilder.username(testOracle10g.getUsername());
dataSourceBuilder.password(testOracle10g.getPassword());
DataSource dataSource = dataSourceBuilder.build();
final RoutingDataSource routingDataSource = new RoutingDataSource();
routingDataSource.setTargetDataSources(Map.of("oradb", dataSource));
routingDataSource.setDefaultTargetDataSource(dataSource);
return routingDataSource;
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/PostgreSQLBaseIntegrationTest.java
================================================
package com.homihq.db2rest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Import;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ActiveProfiles;
@Import(PostgreSQLContainerConfiguration.class)
@ActiveProfiles("it-pg")
public class PostgreSQLBaseIntegrationTest extends BaseIntegrationTest {
@Autowired
private JdbcTemplate jdbcTemplate;
protected boolean deleteRow(String table, String column, int id) {
var query = "DELETE FROM " + table + " WHERE " + column + " = ?";
return jdbcTemplate.update(query, id) == 1;
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/PostgreSQLContainerConfiguration.java
================================================
package com.homihq.db2rest;
import com.homihq.db2rest.jdbc.multidb.RoutingDataSource;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.ext.ScriptUtils;
import org.testcontainers.jdbc.JdbcDatabaseDelegate;
import javax.sql.DataSource;
import java.util.List;
import java.util.Map;
@TestConfiguration(proxyBeanMethods = false)
@Profile("it-pg")
public class PostgreSQLContainerConfiguration {
private static final List postgresScripts = List.of("pg/postgres-sakila.sql",
"pg/postgres-sakila-data.sql", "pg/pg-sakila-functions.sql");
private static final PostgreSQLContainer testPostgres =
(PostgreSQLContainer) new PostgreSQLContainer("postgres:15.2-alpine")
.withDatabaseName("postgres")
.withUsername("postgres")
.withPassword("postgres")
.withReuse(true);
static {
testPostgres.start();
var containerDelegate = new JdbcDatabaseDelegate(testPostgres, "");
postgresScripts.forEach(initScript -> ScriptUtils.runInitScript(containerDelegate, initScript));
}
@Bean
public DataSource dataSource() {
var dataSourceBuilder = DataSourceBuilder.create();
dataSourceBuilder.driverClassName("org.postgresql.Driver");
dataSourceBuilder.url(testPostgres.getJdbcUrl() + "&escapeSyntaxCallMode=callIfNoReturn");
dataSourceBuilder.username(testPostgres.getUsername());
dataSourceBuilder.password(testPostgres.getPassword());
DataSource dataSource = dataSourceBuilder.build();
final RoutingDataSource routingDataSource = new RoutingDataSource();
routingDataSource.setTargetDataSources(Map.of("pgsqldb", dataSource));
routingDataSource.setDefaultTargetDataSource(dataSource);
return routingDataSource;
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/SQLiteBaseIntegrationTest.java
================================================
package com.homihq.db2rest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Import;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ActiveProfiles;
@Import(SQLiteContainerConfiguration.class)
@ActiveProfiles("it-sqlite")
public class SQLiteBaseIntegrationTest extends BaseIntegrationTest {
@Autowired
private JdbcTemplate jdbcTemplate;
protected boolean deleteRow(String table, String column, int id) {
var query = "DELETE FROM " + table + " WHERE " + column + " = ?";
return jdbcTemplate.update(query, id) == 1;
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/SQLiteContainerConfiguration.java
================================================
package com.homihq.db2rest;
import com.homihq.db2rest.jdbc.multidb.RoutingDataSource;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.datasource.init.ScriptUtils;
import javax.sql.DataSource;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
@TestConfiguration(proxyBeanMethods = false)
@Profile("it-sqlite")
public class SQLiteContainerConfiguration {
private static final List sqliteScripts = List.of("sqlite/sqlite-sakila.sql",
"sqlite/sqlite-sakila-data.sql");
private static final String SQLITE_DB_FILE;
static {
try {
File tempFile = Files.createTempFile("sqlite-test", ".db").toFile();
tempFile.deleteOnExit();
SQLITE_DB_FILE = tempFile.getAbsolutePath();
// Initialize database with scripts
var dataSourceBuilder = DataSourceBuilder.create();
dataSourceBuilder.driverClassName("org.sqlite.JDBC");
dataSourceBuilder.url("jdbc:sqlite:" + SQLITE_DB_FILE);
DataSource initDataSource = dataSourceBuilder.build();
try (Connection connection = initDataSource.getConnection()) {
for (String script : sqliteScripts) {
ScriptUtils.executeSqlScript(connection, new ClassPathResource(script));
}
}
} catch (IOException | SQLException e) {
throw new RuntimeException("Failed to initialize SQLite test database", e);
}
}
@Bean
public DataSource dataSource() {
var dataSourceBuilder = DataSourceBuilder.create();
dataSourceBuilder.driverClassName("org.sqlite.JDBC");
dataSourceBuilder.url("jdbc:sqlite:" + SQLITE_DB_FILE);
DataSource dataSource = dataSourceBuilder.build();
final RoutingDataSource routingDataSource = new RoutingDataSource();
routingDataSource.setTargetDataSources(Map.of("sqlitedb", dataSource));
routingDataSource.setDefaultTargetDataSource(dataSource);
return routingDataSource;
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/jdbc/rest/meta/db/DbInfoControllerIntegrationTest.java
================================================
package com.homihq.db2rest.jdbc.rest.meta.db;
import com.homihq.db2rest.BaseIntegrationTest;
import com.homihq.db2rest.jdbc.JdbcManager;
import com.db2rest.jdbc.dialect.model.DbColumn;
import com.db2rest.jdbc.dialect.model.DbTable;
import com.homihq.db2rest.jdbc.sql.DbMeta;
import com.homihq.db2rest.rest.meta.db.DbInfoController;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.springframework.boot.test.mock.mockito.MockBean;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.mockito.Mockito.when;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@Disabled
class DbInfoControllerIntegrationTest extends BaseIntegrationTest {
Map metadataMap;
@MockBean
JdbcManager jdbcManager;
DbInfoController dbInfoController;
@BeforeEach
void setUp() {
List dbTableList = new ArrayList<>();
List dbColumns = new ArrayList<>();
dbColumns.add(new DbColumn("tableName", "name", "alias",
"tableAlias", true, "columnDataType", false, false,
null, "coverChar", "jsonParts"));
dbTableList.add(new DbTable("schema", "name", "fullName",
"alias", dbColumns, "type", "coverChar"));
metadataMap = new HashMap<>();
metadataMap.put("1", new DbMeta("productName", 2, "driverName",
"driverVersion", dbTableList));
dbInfoController = new DbInfoController(jdbcManager);
when(jdbcManager.getDbMetaMap()).thenReturn(metadataMap);
}
//@Test
void getObjects() throws Exception {
mockMvc.perform(get(VERSION + "/$dbs")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$").isArray())
.andExpect(jsonPath("$[0].dbId").value("1")) // Validate dbId field of the first object
.andExpect(jsonPath("$[0].productName").value("productName")) // Validate productName field
.andExpect(jsonPath("$[0].majorVersion").value(2)) // Validate majorVersion field
.andExpect(jsonPath("$[0].driverName").value("driverName")) // Validate driverName field
.andExpect(jsonPath("$[0].driverVersion").value("driverVersion"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/jdbc/rest/meta/db/DbInfoControllerTest.java
================================================
package com.homihq.db2rest.jdbc.rest.meta.db;
import com.homihq.db2rest.jdbc.JdbcManager;
import com.db2rest.jdbc.dialect.model.DbColumn;
import com.db2rest.jdbc.dialect.model.DbTable;
import com.homihq.db2rest.jdbc.sql.DbMeta;
import com.homihq.db2rest.rest.meta.db.DbInfoController;
import com.homihq.db2rest.rest.meta.db.DbInfoObject;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;
class DbInfoControllerTest {
Map metadataMap;
@BeforeEach
void setUp() {
List dbTableList = new ArrayList<>();
List dbColumns = new ArrayList<>();
dbColumns.add(new DbColumn("tableName", "name", "alias",
"tableAlias", true, "columnDataType", false, false,
null, "coverChar", "jsonParts"));
dbTableList.add(new DbTable("schema", "name", "fullName",
"alias", dbColumns, "type", "coverChar"));
metadataMap = new HashMap<>();
metadataMap.put("key", new DbMeta("productName", 2, "driverName",
"driverVersion", dbTableList));
}
@Test
void testGetObjects() {
JdbcManager jdbcManagerMock = Mockito.mock(JdbcManager.class);
when(jdbcManagerMock.getDbMetaMap()).thenReturn(metadataMap);
DbInfoController dbInfoController = new DbInfoController(jdbcManagerMock);
List actualDbInfoList = dbInfoController.getObjects();
List expectedDbInfoList = new ArrayList<>();
metadataMap.forEach(
(k, v) -> expectedDbInfoList.add(new DbInfoObject(k, v.productName(), v.majorVersion(), v.driverName(), v.driverVersion()))
);
assertEquals(expectedDbInfoList, actualDbInfoList);
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/jdbc/rest/meta/schema/SchemaControllerIntegrationTest.java
================================================
package com.homihq.db2rest.jdbc.rest.meta.schema;
import com.homihq.db2rest.BaseIntegrationTest;
import com.homihq.db2rest.jdbc.JdbcManager;
import com.db2rest.jdbc.dialect.model.DbColumn;
import com.db2rest.jdbc.dialect.model.DbTable;
import com.homihq.db2rest.jdbc.sql.DbMeta;
import com.homihq.db2rest.rest.meta.schema.SchemaController;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.MockBean;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.core.AnyOf.anyOf;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
class SchemaControllerIntegrationTest extends BaseIntegrationTest {
Map metadataMap;
@MockBean
JdbcManager jdbcManager;
SchemaController schemaController;
@BeforeEach
void setUp() {
List dbTableList = new ArrayList<>();
List dbColumns = new ArrayList<>();
dbColumns.add(new DbColumn("tableName", "name", "alias",
"tableAlias", true, "columnDataType", false, false,
null, "coverChar", "jsonParts"));
dbTableList.add(new DbTable("schema", "name", "fullName",
"alias", dbColumns, "type", "coverChar"));
metadataMap = new HashMap<>();
metadataMap.put("key", new DbMeta("productName", 2, "driverName",
"driverVersion", dbTableList));
schemaController = new SchemaController(jdbcManager);
when(jdbcManager.getDbMetaByDbId(anyString())).thenReturn(metadataMap.get("key"));
}
/**
* This test tests the use case where we request for all schemas without
* providing any filter.
*
* @throws Exception
*/
@Test
void testGetObjects() throws Exception {
mockMvc.perform(get(VERSION + "/1/$schemas")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
//.andExpect(jsonPath("$.*", hasSize(4)))
.andExpect(jsonPath("$.*", anyOf(hasSize(1))))
.andExpect(jsonPath("$[0].*", hasSize(3)))
.andDo(document("schema-no-filter"));
}
/**
* This test tests the use case where we request for schema's columns
*
* @throws Exception
*/
@Test
void testGetColumnObjects() throws Exception {
mockMvc.perform(get(VERSION + "/1/$schemas")
.param("columns", "true")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
//.andExpect(jsonPath("$.*", hasSize(4)))
.andExpect(jsonPath("$.*", anyOf(hasSize(1))))
.andExpect(jsonPath("$[0].*", hasSize(4)))
.andExpect(jsonPath("$[0].columns.*", hasSize(1)))
.andExpect(jsonPath("$[0].columns[0].*", hasSize(3)))
.andExpect(jsonPath("$[0].columns[0].name").value("name"))
.andExpect(jsonPath("$[0].columns[0].pk").value(true))
.andExpect(jsonPath("$[0].columns[0].dataType").value("columnDataType"))
.andDo(document("schema-no-filter"));
}
/**
* This test tests the use case where we are sending an invalid filter
* i.e, we are sending a filter which is not valid.
*
* @throws Exception
*/
@Test
void testGetObjectsInvalidFilter() throws Exception {
mockMvc.perform(get(VERSION + "/1/$schemas")
.param("filter", "name=employee")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andDo(print())
.andExpect(jsonPath("$.type").value("https://db2rest.com/error/generic-error"))
.andExpect(jsonPath("$.title").value("Generic Data Access Error"))
.andExpect(jsonPath("$.status").value(400))
.andExpect(jsonPath("$.detail").value("Invalid filter condition. Only == supported for schema filter using a single value only."))
.andExpect(jsonPath("$.instance").value("/v1/rdbms/1/$schemas"))
.andExpect(jsonPath("$.errorCategory").value("Data-access-error"))
.andExpect(jsonPath("$.timestamp").exists())
.andDo(document("schema-invalid-filter"));
}
/**
* Tests response if there is a filter, and it is a valid filter.
* Valid filters include
* 1. == sign in between filter field and filter value
* 2. A string to the left of == and a string value to the right of it.
*
* @throws Exception
*/
@Test
void testGetObjectsValidFilter() throws Exception {
mockMvc.perform(get(VERSION + "/1/$schemas")
.param("filter", "schema==schema")
.contentType("application/json"))
.andExpect(status().isOk()) // Expect 200 OK
.andExpect(jsonPath("$").isArray()) // Ensure it's an array
.andExpect(jsonPath("$[0].schema").value("schema")) // Validate the first object's schema field
.andExpect(jsonPath("$[0].name").value("name")) // Validate the name field
.andExpect(jsonPath("$[0].type").value("type"))
.andDo(document("schema-valid-filter"));
}
/**
* This test checks for the use case where we send a request to /$schemas,
* but we do not have a valid filter field.
* NOTE: In this use case, the filter in itself is valid because it contains ==.
* Currently, we have filters based on schema, type and name.
* This test checks the response and ensures it is empty if the filter argument
* is not in (schema,type, name)
*
* @throws Exception
*/
@Test
void testGetObjectsInvalidFilterField() throws Exception {
mockMvc.perform(get(VERSION + "/1/$schemas")
.param("filter", "someUnknownFilter==schema")
.contentType("application/json"))
.andExpect(status().isOk()) // Expect 200 OK
.andExpect(jsonPath("$").isArray()) // Ensure it's an array
.andExpect(jsonPath("$").isEmpty()) //Ensure it is empty
.andDo(document("schema-unknown-filter"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/jdbc/rest/meta/schema/SchemaControllerTest.java
================================================
package com.homihq.db2rest.jdbc.rest.meta.schema;
import com.homihq.db2rest.core.exception.GenericDataAccessException;
import com.homihq.db2rest.jdbc.JdbcManager;
import com.db2rest.jdbc.dialect.model.DbColumn;
import com.db2rest.jdbc.dialect.model.DbTable;
import com.homihq.db2rest.jdbc.sql.DbMeta;
import com.homihq.db2rest.rest.meta.schema.SchemaController;
import com.homihq.db2rest.rest.meta.schema.TableObject;
import com.homihq.db2rest.rest.meta.schema.TableWithColumnsObject;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.when;
class SchemaControllerTest {
Map metadataMap;
JdbcManager jdbcManager;
SchemaController schemaController;
@BeforeEach
void setUp() {
List dbTableList = new ArrayList<>();
List dbColumns = new ArrayList<>();
dbColumns.add(new DbColumn("tableName", "name", "alias",
"tableAlias", true, "columnDataType", false, false,
null, "coverChar", "jsonParts"));
dbTableList.add(new DbTable("schema", "name", "fullName",
"alias", dbColumns, "type", "coverChar"));
metadataMap = new HashMap<>();
metadataMap.put("key", new DbMeta("productName", 2, "driverName",
"driverVersion", dbTableList));
jdbcManager = Mockito.mock(JdbcManager.class);
schemaController = new SchemaController(jdbcManager);
}
private List getActualTableObject(String filter) {
List actualTableObject = (List) schemaController.getObjects("key", filter, Boolean.FALSE);
return actualTableObject;
}
private void testFilter(String goodFilter, String badFilter) {
when(jdbcManager.getDbMetaByDbId("key")).thenReturn(metadataMap.get("key"));
List expectedTableObject = metadataMap.get("key").dbTables().stream().map(TableObject::new).toList();
List actualTableObject = getActualTableObject(goodFilter);
assertEquals(expectedTableObject, actualTableObject);
actualTableObject = getActualTableObject(badFilter);
assertEquals(0, actualTableObject.size());
}
@Test
void getObjectsNoFilter() {
when(jdbcManager.getDbMetaByDbId("key")).thenReturn(metadataMap.get("key"));
List actualTableObject = getActualTableObject(null);
List expectedTableObject = metadataMap.get("key").dbTables().stream().map(TableObject::new).toList();
assertEquals(expectedTableObject, actualTableObject);
}
@Test
void testGetObjectsFilterInvalid() {
when(jdbcManager.getDbMetaByDbId("key")).thenReturn(metadataMap.get("key"));
Throwable exception = assertThrows(GenericDataAccessException.class, () -> schemaController.getObjects("key", "invalidFilter", Boolean.FALSE));
assertEquals("Invalid filter condition. Only == supported for schema filter using a single value only.", exception.getMessage());
}
@Test
void testGetObjectsValidFilter_schema() {
testFilter("schema==schema", "schema==notPresentInList");
}
@Test
void testGetObjectsValidFilter_name() {
testFilter("name==name", "name==notPresentInList");
}
@Test
void testGetObjectsValidFilter_type() {
testFilter("type==type", "type==notPresentInList");
}
@Test
void testGetObjectsValidFilter_invalidFieldFilter() {
when(jdbcManager.getDbMetaByDbId("key")).thenReturn(metadataMap.get("key"));
List actualTableObject = getActualTableObject("invalidFilterField==notPresentInList");
assertEquals(0, actualTableObject.size());
}
@Test
void testGetObjectsDbIDInvalid() {
when(jdbcManager.getDbMetaByDbId("key")).thenReturn(null);
assertEquals(0, schemaController.getObjects("key", "filter", Boolean.FALSE).size());
}
@Test
void testGetObjectsWithColumns() {
when(jdbcManager.getDbMetaByDbId("key")).thenReturn(metadataMap.get("key"));
List expectedTableObject = metadataMap.get("key").dbTables().stream().map(TableWithColumnsObject::new).toList();
List actualTableObject = (List) schemaController.getObjects("key", null, Boolean.TRUE);
assertEquals(expectedTableObject, actualTableObject);
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/DateTimeUtil.java
================================================
package com.homihq.db2rest.rest;
import com.jayway.jsonpath.JsonPath;
import org.springframework.test.web.servlet.MvcResult;
import java.io.UnsupportedEncodingException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
public class DateTimeUtil {
// Convert UTC time to LocalDateTime string
public static String utcToLocalTimestampString(MvcResult result) throws UnsupportedEncodingException {
String lastUpdateStr = result.getResponse().getContentAsString();
String lastUpdateValue = JsonPath.read(lastUpdateStr, "$[0].last_update");
OffsetDateTime offsetDateTime = OffsetDateTime.parse(lastUpdateValue);
// Convert OffsetDateTime to LocalDateTime in the system's default time zone
LocalDateTime localDateTime = offsetDateTime.toInstant()
.atZone(ZoneId.systemDefault()).toLocalDateTime();
// Format the LocalDateTime into the expected format
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");
return formatter.format(localDateTime);
}
// Convert UTC To LocalDateTime Format, Oracle jsonPath format
public static String utcToLocalTimestampStringOracle(MvcResult result) throws UnsupportedEncodingException {
String lastUpdateStr = result.getResponse().getContentAsString();
String lastUpdateValue = JsonPath.read(lastUpdateStr, "$[0].LAST_UPDATE");
OffsetDateTime offsetDateTime = OffsetDateTime.parse(lastUpdateValue);
LocalDateTime localDateTime = offsetDateTime.toInstant()
.atZone(ZoneId.systemDefault()).toLocalDateTime();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");
return formatter.format(localDateTime);
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/cors/CorsTest.java
================================================
package com.homihq.db2rest.rest.cors;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Profile;
import org.springframework.restdocs.RestDocumentationExtension;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.ext.ScriptUtils;
import org.testcontainers.jdbc.JdbcDatabaseDelegate;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.util.List;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.options;
import com.homihq.db2rest.config.Db2RestConfigProperties;
import lombok.extern.slf4j.Slf4j;
@SpringBootTest
@AutoConfigureMockMvc
@ExtendWith(RestDocumentationExtension.class)
@Slf4j
public class CorsTest {
@Autowired
private MockMvc mockMvc;
@Autowired
protected WebApplicationContext context;
@Autowired
protected ApplicationContext applicationContext;
@Autowired
protected Db2RestConfigProperties db2RestConfigProperties;
private static final List postgresScripts = List.of("pg/postgres-sakila.sql",
"pg/postgres-sakila-data.sql", "pg/pg-sakila-functions.sql");
private static final PostgreSQLContainer testPostgres =
(PostgreSQLContainer) new PostgreSQLContainer("postgres:15.2-alpine")
.withDatabaseName("postgres")
.withUsername("postgres")
.withPassword("postgres")
.withReuse(true);
static {
testPostgres.start();
var containerDelegate = new JdbcDatabaseDelegate(testPostgres, "");
postgresScripts.forEach(initScript -> ScriptUtils.runInitScript(containerDelegate, initScript));
}
// private final String testOrigin = "http://example.com";
@DynamicPropertySource
static void setProperties(DynamicPropertyRegistry registry) {
registry.add("DB_URL", () -> testPostgres.getJdbcUrl());
registry.add("DB_USER", () -> testPostgres.getUsername());
registry.add("DB_PASSWORD", () -> testPostgres.getPassword());
registry.add("ENABLE_CORS", () -> "true");
/*
- mapping: "/actor/**"
allowedOrigin: "http://localhost:3000"
allowedHeader: "*"
allowedMethod: "*"
- mapping: "/v1/rdbms/db/**"
allowedOrigin: "http://localhost:4200, http://localhost:3000"
allowedHeader: "*"
allowedMethod: "GET,POST"
*/
registry.add("cors.mappings[0].mapping", () -> "/actor/**");
registry.add("cors.mappings[0].allowedOrigins", () -> "http://localhost:3000");
registry.add("cors.mappings[0].allowedHeaders", () -> "*");
registry.add("cors.mappings[0].allowedMethods", () -> "*");
registry.add("cors.mappings[1].mapping", () -> "/v1/rdbms/db/**");
registry.add("cors.mappings[1].allowedOrigins", () -> "http://localhost:4200, http://localhost:3000");
registry.add("cors.mappings[1].allowedHeaders", () -> "*");
registry.add("cors.mappings[1].allowedMethods", () -> "GET,POST");
}
@BeforeEach
void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
}
@Test
public void shouldBeSuccessfullForCorrectCORSOrigin() throws Exception {
mockMvc.perform(options("/v2/rdbms/db/employee")
.header("Origin", "http://localhost:4200")
.header("Access-Control-Request-Method", "GET"))
.andExpect(status().isForbidden());
}
@Test
public void shouldBeFaliureForWrongCORSOrigin() throws Exception {
mockMvc.perform(options("/v1/rdbms/db/employee")
.header("Origin", "http://example.com/aws")
.header("Access-Control-Request-Method", "GET"))
.andExpect(status().isForbidden());
}
@Test
public void shouldBeFaliureForWrongCORSMethod() throws Exception {
mockMvc.perform(options("/v1/rdbms/db/employee")
.header("Origin", "http://example.com/aws")
.header("Access-Control-Request-Method", "PATCH"))
.andExpect(status().isForbidden());
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/db2/Db2BulkCreateControllerTest.java
================================================
package com.homihq.db2rest.rest.db2;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.DB2BaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.GivenTextResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import java.util.List;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasSize;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(281)
@TestWithResources
class Db2BulkCreateControllerTest extends DB2BaseIntegrationTest {
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@GivenJsonResource("/testdata/BULK_CREATE_FILM_REQUEST.json")
List> BULK_CREATE_FILM_REQUEST;
@GivenJsonResource("/testdata/BULK_CREATE_FILM_BAD_REQUEST.json")
List> BULK_CREATE_FILM_BAD_REQUEST;
@GivenTextResource("/testdata/CREATE_FILM_REQUEST_CSV.csv")
String CREATE_FILM_REQUEST_CSV;
@GivenTextResource("/testdata/CREATE_FILM_BAD_REQUEST_CSV.csv")
String CREATE_FILM_BAD_REQUEST_CSV;
@GivenJsonResource("/testdata/BULK_CREATE_DIRECTOR_REQUEST.json")
List> BULK_CREATE_DIRECTOR_REQUEST;
@GivenJsonResource("/testdata/BULK_CREATE_DIRECTOR_BAD_REQUEST.json")
List> BULK_CREATE_DIRECTOR_BAD_REQUEST;
@GivenJsonResource("/testdata/BULK_CREATE_REVIEW_REQUEST.json")
List> BULK_CREATE_REVIEW_REQUEST;
@Test
@DisplayName("Create many films.")
void create() throws Exception {
mockMvc.perform(post(VERSION + "/db2b/FILM/bulk")
.queryParam("sequences", "film_id:film_sequence")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(BULK_CREATE_FILM_REQUEST))
)
.andExpect(status().isCreated())
.andExpect(jsonPath("$.rows").isArray())
.andExpect(jsonPath("$.rows", hasSize(2)))
.andExpect(jsonPath("$.rows", hasItem(1)))
.andExpect(jsonPath("$.rows", hasItem(1)))
//.andExpect(jsonPath("$.generated_keys").isArray()) //TODO - push TSID columns
//.andExpect(jsonPath("$.generated_keys", hasSize(2)))
//.andExpect(jsonPath("$.generated_keys", allOf(notNullValue())))
//.andDo(print())
.andDo(document("db2-bulk-create-films"));
}
@Test
@DisplayName("Create many films with CSV type.")
void createCSV() throws Exception {
mockMvc.perform(post(VERSION + "/db2b/FILM/bulk")
.queryParam("sequences", "film_id:film_sequence")
.contentType("text/csv").accept(APPLICATION_JSON)
.content(CREATE_FILM_REQUEST_CSV))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.rows", hasSize(2)))
.andExpect(jsonPath("$.rows", hasItem(1)))
//.andExpect(jsonPath("$.generated_keys", hasSize(2)))
//.andExpect(jsonPath("$.generated_keys", allOf(notNullValue())))
//.andDo(print())
.andDo(document("db2-bulk-create-films-csv"));
}
@Test
@DisplayName("Create many films with CSV type resulting error.")
void createCSVWithError() throws Exception {
mockMvc.perform(post(VERSION + "/db2b/FILM/bulk")
.queryParam("sequences", "film_id:film_sequence")
.contentType("text/csv")
.accept(APPLICATION_JSON)
.content(CREATE_FILM_BAD_REQUEST_CSV))
.andExpect(status().isBadRequest())
//.andDo(print())
.andDo(document("db2-bulk-create-films-csv-error"));
}
@Test
@DisplayName("Create many films with failure.")
void createError() throws Exception {
mockMvc.perform(post(VERSION + "/db2b/FILM/bulk")
.queryParam("sequences", "film_id:film_sequence")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(BULK_CREATE_FILM_BAD_REQUEST)))
.andExpect(status().isBadRequest())
// .andDo(print())
.andDo(document("db2-bulk-create-films-error"));
}
@Test
@DisplayName("Create many directors.")
@Disabled
void createDirector() throws Exception {
mockMvc.perform(post(VERSION + "/db2b/DIRECTOR/bulk")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("tsIdEnabled", "true")
.content(objectMapper.writeValueAsString(BULK_CREATE_DIRECTOR_REQUEST))
)
.andExpect(status().isCreated())
//.andDo(print())
.andDo(document("db2-bulk-create-directors"));
}
@Test
@DisplayName("Create many directors with wrong tsid type.")
void createDirectorWithWrongTsidType() throws Exception {
mockMvc.perform(post(VERSION + "/db2b/DIRECTOR/bulk")
.characterEncoding(UTF_8)
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.param("tsid", "director_id")
.param("tsidType", "string")
.header("Content-Profile", "sakila")
.content(objectMapper.writeValueAsString(BULK_CREATE_DIRECTOR_BAD_REQUEST))
)
.andExpect(status().isBadRequest())
//.andDo(print())
.andDo(document("db2-bulk-create-directors-with-wrong-tsid-type"));
}
@Test
@DisplayName("Create reviews with default tsid type.")
@Disabled
void createReviewWithDefaultTsidType() throws Exception {
mockMvc.perform(post(VERSION + "/db2b/REVIEW/bulk")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("tsIdEnabled", "true")
.content(objectMapper.writeValueAsString(BULK_CREATE_REVIEW_REQUEST))
)
.andExpect(status().isCreated())
//.andDo(print())
.andDo(document("db2-bulk-create-reviews-with-default-tsid-type"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/db2/Db2CountControllerTest.java
================================================
package com.homihq.db2rest.rest.db2;
import com.homihq.db2rest.DB2BaseIntegrationTest;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.springframework.http.MediaType;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(202)
class Db2CountControllerTest extends DB2BaseIntegrationTest {
@Test
@DisplayName("Get count")
void findFilmCount() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/FILM/count")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
//.andDo(print())
.andDo(document("db2-get-film-count"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/db2/Db2CreateControllerTest.java
================================================
package com.homihq.db2rest.rest.db2;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.DB2BaseIntegrationTest;
import com.jayway.jsonpath.JsonPath;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(280)
@TestWithResources
class Db2CreateControllerTest extends DB2BaseIntegrationTest {
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@GivenJsonResource("/testdata/CREATE_FILM_REQUEST.json")
Map CREATE_FILM_REQUEST;
@GivenJsonResource("/testdata/CREATE_FILM_REQUEST_ERROR.json")
Map CREATE_FILM_REQUEST_ERROR;
@GivenJsonResource("/testdata/CREATE_VANITY_VAN_REQUEST.json")
Map CREATE_VANITY_VAN_REQUEST;
@GivenJsonResource("/testdata/CREATE_DIRECTOR_REQUEST.json")
Map CREATE_DIRECTOR_REQUEST;
@GivenJsonResource("/testdata/CREATE_FILM_REQUEST_MISSING_PAYLOAD.json")
Map CREATE_FILM_REQUEST_MISSING_PAYLOAD;
@Test
@DisplayName("Create a film.")
void create() throws Exception {
mockMvc.perform(post(VERSION + "/db2b/FILM")
.queryParam("sequences", "film_id:film_sequence")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST))
)
//.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
//.andExpect(jsonPath("$.keys.GENERATED_KEY").exists())
//.andExpect(jsonPath("$.keys.GENERATED_KEY", equalTo(5)))
.andDo(document("db2-create-a-film"));
}
@Test
@DisplayName("Test Create a film with error.")
void createError() throws Exception {
mockMvc.perform(post(VERSION + "/db2b/FILM")
.queryParam("sequences", "film_id:film_sequence")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST_ERROR)))
//.andDo(print())
.andExpect(status().isBadRequest())
.andDo(document("db2-create-a-film-error"));
}
@Test
@DisplayName("Test create a film - non existent table.")
void createNonExistentTable() throws Exception {
mockMvc.perform(post(VERSION + "/db2b/FILMS")
.queryParam("sequences", "film_id:film_sequence")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST)))
.andExpect(status().isNotFound())
//.andDo(print())
.andDo(document("db2-create-a-film-no-table"));
}
@Test
@DisplayName("Test Create a director - TSID enabled")
@Disabled
void createDirectorWithTSIDEnabled() throws Exception {
mockMvc.perform(post(VERSION + "/db2b/DIRECTOR")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("tsIdEnabled", "true")
.content(objectMapper.writeValueAsString(CREATE_DIRECTOR_REQUEST)))
.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
//.andExpect(jsonPath("$.keys.director_id").exists())
// .andExpect(jsonPath("$.keys.director_id").isNumber())
.andDo(document("db2-create-a-director-tsid-enabled"));
}
@Test
@DisplayName("Create a director - with TSID explicitly OFF")
void createDirectorWithTSIDOff() throws Exception {
mockMvc.perform(post(VERSION + "/db2b/DIRECTOR")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("tsIdEnabled", "false")
.content(objectMapper.writeValueAsString(CREATE_DIRECTOR_REQUEST)))
.andExpect(status().isBadRequest())
//.andDo(print())
.andDo(document("db2-create-a-director-with-tsid-OFF"));
}
@Test
@DisplayName("Test Create a Vanity Van - with varchar tsid type")
void createVanityVanWithVarcharTsIdType() throws Exception {
//TODO - MySQL return keys not working
mockMvc.perform(post(VERSION + "/db2b/VANITY_VAN")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("tsIdEnabled", "true")
.content(objectMapper.writeValueAsString(CREATE_VANITY_VAN_REQUEST)))
//.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
//.andExpect(jsonPath("$.keys.vanity_van_id").exists())
//.andExpect(jsonPath("$.keys.vanity_van_id").isString())
.andDo(document("db2-create-a-vanity-van-tsid-varchar"));
}
@Test
@DisplayName("Create a film with subset of columns")
void createFilmWithSubsetOfColumns() throws Exception {
var result = mockMvc.perform(post(VERSION + "/db2b/FILM")
.queryParam("sequences", "film_id:film_sequence")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.queryParam("columns", "title,description,language_id")
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST)))
.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
.andExpect(jsonPath("$.keys").exists())
//.andExpect(jsonPath("$.keys.GENERATED_KEY", equalTo(5)))
.andExpect(jsonPath("$.keys.FILM_ID").isNumber())
.andDo(document("db2-create-a-film-col-subset"))
.andReturn();
var pk = JsonPath.read(result.getResponse().getContentAsString(), "$.keys.FILM_ID");
mockMvc.perform(get(VERSION + "/db2b/FILM")
.accept(APPLICATION_JSON)
.queryParam("fields", "title,release_year")
.queryParam("filter", String.format("film_id==%s", pk)))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$[0].TITLE", equalTo("Dunki")))
.andExpect(jsonPath("$[0].RELEASE_YEAR").doesNotExist());
// cleanup data
assertTrue(deleteRow("film", "film_id", (int) pk));
}
@Test
@DisplayName("Ignore if columns parameter is blank")
void shouldIgnoreWhenColumnsQueryParamIsEmpty() throws Exception {
var result = mockMvc.perform(post(VERSION + "/db2b/FILM")
.queryParam("sequences", "film_id:film_sequence")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.queryParam("columns", "")
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST)))
.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
.andExpect(jsonPath("$.keys").exists())
.andDo(document("db2-create-a-film-columns-not-specified"))
.andReturn();
var pk = JsonPath.read(result.getResponse().getContentAsString(), "$.keys.FILM_ID");
mockMvc.perform(get(VERSION + "/db2b/FILM")
.accept(APPLICATION_JSON)
.queryParam("fields", "title,release_year")
.queryParam("filter", String.format("film_id==%s", pk)))
.andExpect(status().isOk())
.andExpect(jsonPath("$[0].TITLE", equalTo("Dunki")))
.andExpect(jsonPath("$[0].RELEASE_YEAR", equalTo("2023")))
.andDo(print())
;
// cleanup data
assertTrue(deleteRow("film", "film_id", (int) pk));
}
@Test
@DisplayName("Column is present in columns param but not in payload")
void columnIsPresentInColumnsQueryParamButNotInPayload() throws Exception {
mockMvc.perform(post(VERSION + "/db2b/FILM")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.queryParam("columns", "title,description,language_id")
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST_MISSING_PAYLOAD))) //description is not in payload will be set to null
.andExpect(status().isBadRequest())
//.andDo(print())
.andDo(document("db2-create-a-film-missing-payload-attribute-error"));
}
@Test
@DisplayName("Column violates not-null constraint")
void column_violates_not_null_constraint() throws Exception {
mockMvc.perform(post(VERSION + "/db2b/FILM")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.queryParam("columns", "title,description")
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST)))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.detail",
containsString("SQLCODE=-407")))
.andDo(print())
.andDo(document("db2-create-a-film-not-null-constraint"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/db2/Db2DeleteAllTest.java
================================================
package com.homihq.db2rest.rest.db2;
import com.homihq.db2rest.DB2BaseIntegrationTest;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.springframework.test.context.TestPropertySource;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(291)
@TestPropertySource(properties = {"db2rest.allowSafeDelete=false"})
class Db2DeleteAllTest extends DB2BaseIntegrationTest {
@Test
@DisplayName("Delete all records while allowSafeDelete=false")
void deleteAllWithAllowSafeDeleteFalse() throws Exception {
mockMvc.perform(delete(VERSION + "/db2b/COUNTRY")
.accept(APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", Matchers.equalTo(6)))
.andDo(document("db2-delete-all"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/db2/Db2DeleteControllerTest.java
================================================
package com.homihq.db2rest.rest.db2;
import com.homihq.db2rest.DB2BaseIntegrationTest;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(290)
class Db2DeleteControllerTest extends DB2BaseIntegrationTest {
@Test
@DisplayName("Delete a Director")
@Disabled
void delete_single_record() throws Exception {
mockMvc.perform(delete(VERSION + "/db2b/DIRECTOR")
.accept(APPLICATION_JSON)
.param("filter", "first_name==\"Alex\""))
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", equalTo(1)))
//.andDo(print())
.andDo(document("db2-delete-a-director"));
}
@Test
@DisplayName("Delete all records while allowSafeDelete=true")
void delete_all_records_with_allow_safe_delete_true() throws Exception {
mockMvc.perform(delete(VERSION + "/db2b/DIRECTOR")
.accept(APPLICATION_JSON))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.detail",
containsString("Invalid delete operation , safe set to true")))
//.andDo(print())
.andDo(document("db2-delete-a-director"));
}
@Test
@DisplayName("Column Does Not Exist")
void column_does_not_exist() throws Exception {
mockMvc.perform(delete(VERSION + "/db2b/DIRECTOR")
.accept(APPLICATION_JSON)
.param("filter", "_name==\"Alex\""))
.andExpect(status().isNotFound())
.andDo(print())
.andExpect(jsonPath("$.detail",
containsString("Column not found DIRECTOR._name")))
.andDo(document("db2-delete-a-director"));
}
@Disabled
@Test
@DisplayName("Foreign Key Constraint Violation")
void foreign_key_constraint_violation() throws Exception {
mockMvc.perform(delete(VERSION + "/db2b/LANGUAGE")
.accept(APPLICATION_JSON)
.param("filter", "name==\"English\""))
.andDo(print())
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.detail",
containsString("Cannot delete or update a parent row: a foreign key constraint fails")))
.andDo(document("db2-delete-a-director"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/db2/Db2JsonFileCreateControllerTest.java
================================================
package com.homihq.db2rest.rest.db2;
import com.homihq.db2rest.DB2BaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.web.servlet.MvcResult;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(281)
@TestWithResources
class Db2JsonFileCreateControllerTest extends DB2BaseIntegrationTest {
Path dir = FileSystems.getDefault().getPath("src/test/resources/testdata");
Path actorFile = dir.resolve("actor.json");
Path filmFile = dir.resolve("BULK_CREATE_FILM_REQUEST.json");
Path nonArrayActorFile = dir.resolve("CREATE_ACTOR_REQUEST.json");
Path directorFile = dir.resolve("director.json");
@Test
@DisplayName("Create many actors via JSON file upload.")
void uploadActorsFile() throws Exception {
MockMultipartFile file = new MockMultipartFile("file", "actor.json",
"application/json", Files.readAllBytes(actorFile));
MvcResult mvcResult = mockMvc.perform(multipart(VERSION + "/db2b/ACTOR/upload")
.file(file)
.contentType("multipart/form-data")
.accept(APPLICATION_JSON))
.andDo(print())
.andReturn();
mockMvc.perform(asyncDispatch(mvcResult))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row").isNumber())
.andExpect(jsonPath("$.row").value(10000))
.andExpect(jsonPath("$.keys").value("Bulk insert completed successfully"))
.andDo(document("db2-create-actors-file-upload"));
}
@Test
@DisplayName("Error create actor via JSON file upload.")
void uploadActorFileNonJsonArray() throws Exception {
MockMultipartFile file = new MockMultipartFile("file", nonArrayActorFile.toString(),
"application/json", Files.readAllBytes(nonArrayActorFile));
mockMvc.perform(multipart(VERSION + "/db2b/ACTOR/upload")
.file(file)
.contentType("multipart/form-data")
.accept(APPLICATION_JSON))
.andDo(print())
.andExpect(status().isBadRequest())
.andDo(document("db2-error-create-actors-file-upload"));
}
@Test
@DisplayName("Create many directors via file upload.")
void createDirectorViaUpload() throws Exception {
MockMultipartFile file = new MockMultipartFile("file", "bulkDirector.json",
"application/json", Files.readAllBytes(directorFile));
MvcResult mvcResult = mockMvc.perform(multipart(VERSION + "/db2b/DIRECTOR/upload")
.file(file)
.contentType("multipart/form-data")
.accept(APPLICATION_JSON))
.andDo(print())
.andReturn();
mockMvc.perform(asyncDispatch(mvcResult))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row").isNumber())
.andExpect(jsonPath("$.row").value(600))
.andExpect(jsonPath("$.keys").value("Bulk insert completed successfully"))
.andDo(document("db2-create-directors-file-upload"));
}
@Test
@DisplayName("Create many films via file upload.")
void createFilmsViaUpload() throws Exception {
MockMultipartFile file = new MockMultipartFile("file", "bulkFilm.json",
"application/json", Files.readAllBytes(filmFile));
MvcResult mvcResult = mockMvc.perform(multipart(VERSION + "/db2b/FILM/upload")
.file(file)
.queryParam("sequences", "film_id:film_sequence")
.contentType("multipart/form-data")
.accept(APPLICATION_JSON))
.andDo(print())
.andReturn();
mockMvc.perform(asyncDispatch(mvcResult))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row").isNumber())
.andExpect(jsonPath("$.row").value(2))
.andExpect(jsonPath("$.keys").value("Bulk insert completed successfully"))
.andDo(document("db2-create-films-file-upload"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/db2/Db2ProcedureControllerTest.java
================================================
package com.homihq.db2rest.rest.db2;
import com.homihq.db2rest.DB2BaseIntegrationTest;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.TestClassOrder;
import org.springframework.http.MediaType;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.instanceOf;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(250)
class Db2ProcedureControllerTest extends DB2BaseIntegrationTest {
//@Test
@DisplayName("Execute stored procedure on db2 db")
void execute() throws Exception {
var json = """
{
"movieTitle": "ACADEMY DINOSAUR"
}
""";
mockMvc.perform(post(VERSION + "/db2b/procedure/GetMovieRentalRateProc")
.characterEncoding(UTF_8)
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.content(json))
.andExpect(status().isOk())
.andExpect(jsonPath("$", instanceOf(Map.class)))
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$.P_RENTAL_RATE", equalTo(0.99)))
//.andDo(print())
.andDo(document("db2-execute-procedure"));
}
//@Test
@DisplayName("Execute stored procedure UpdateUserProc on db2 db ")
void executeUpdateUserProc() throws Exception {
var json = """
{
"userId": 1
}
""";
mockMvc.perform(post(VERSION + "/db2b/procedure/UpdateUserProc")
.characterEncoding(UTF_8)
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.content(json))
.andExpect(status().isOk())
.andDo(print())
.andExpect(jsonPath("$", instanceOf(Map.class)))
.andExpect(jsonPath("$.*", hasSize(1)))
.andDo(document("db2-execute-update-user-proc"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/db2/Db2RSqlOperatorReadControllerTest.java
================================================
package com.homihq.db2rest.rest.db2;
import com.homihq.db2rest.DB2BaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.springframework.http.MediaType;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.core.AnyOf.anyOf;
import static org.hamcrest.Matchers.equalTo;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(204)
@TestWithResources
class Db2RSqlOperatorReadControllerTest extends DB2BaseIntegrationTest {
@Test
@DisplayName("Test find with Equals Operator")
void findWithEqualsOperator() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/FILM")
.accept(APPLICATION_JSON)
.param("fields", "TITLE,DESCRIPTION,RELEASE_YEAR")
.param("filter", "FILM_ID==2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1), hasSize(1))))
.andExpect(jsonPath("$[0].TITLE", notNullValue()))
.andExpect(jsonPath("$[0].DESCRIPTION", notNullValue()))
.andExpect(jsonPath("$[0].RELEASE_YEAR", notNullValue()))
.andDo(document("db2-find-films-with-equals-operator"));
}
@Test
@DisplayName("Test find with Not Equals Operator")
void findWithNotEqualsOperator() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/FILM")
.accept(APPLICATION_JSON)
.param("fields", "FILM_ID")
.param("filter", "FILM_ID!=2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(3), hasSize(3))))
.andExpect(jsonPath("$[0].FILM_ID").value(1))
.andExpect(jsonPath("$[1].FILM_ID").value(3))
.andExpect(jsonPath("$[2].FILM_ID").value(4))
.andDo(document("db2-find-films-with-not-equals-operator"));
}
@Test
@DisplayName("Test find with Greater than Operator")
void findWithGreaterThanOperator() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/FILM;desc")
.accept(APPLICATION_JSON)
.param("fields", "FILM_ID")
.param("filter", "FILM_ID=gt=2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(2), hasSize(2))))
.andExpect(jsonPath("$[0].FILM_ID").value(3))
.andExpect(jsonPath("$[1].FILM_ID").value(4))
.andDo(document("db2-find-films-with-greater-operator"));
}
@Test
@DisplayName("Test find with Greater than Equals Operator")
void findWithGreaterThanEqualsOperator() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/FILM;desc")
.accept(APPLICATION_JSON)
.param("fields", "FILM_ID")
.param("filter", "FILM_ID=ge=2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(3), hasSize(3))))
.andExpect(jsonPath("$[0].FILM_ID").value(2))
.andExpect(jsonPath("$[1].FILM_ID").value(3))
.andExpect(jsonPath("$[2].FILM_ID").value(4))
.andDo(document("db2-find-films-with-greater-equals-operator"));
}
@Test
@DisplayName("Test find with Less than Operator")
void findWithLessThanOperator() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/FILM;desc")
.accept(APPLICATION_JSON)
.param("fields", "FILM_ID")
.param("filter", "FILM_ID=lt=2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1), hasSize(1))))
.andExpect(jsonPath("$[0].FILM_ID").value(1))
.andDo(document("db2-find-films-with-less-operator"));
}
@Test
@DisplayName("Test find with Less than Equals Operator")
void findWithLessThanEqualsOperator() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/FILM;desc")
.accept(APPLICATION_JSON)
.param("fields", "FILM_ID")
.param("filter", "FILM_ID=le=2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(2), hasSize(2))))
.andExpect(jsonPath("$[0].FILM_ID").value(1))
.andExpect(jsonPath("$[1].FILM_ID").value(2))
.andDo(document("db2-find-films-with-less-equals-operator"));
}
@Test
@DisplayName("Test find with In Operator")
void findWithInOperator() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/FILM;desc")
.accept(APPLICATION_JSON)
.param("fields", "FILM_ID")
.param("filter", "FILM_ID=in=(2,3,5)")
)
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(2), hasSize(2))))
.andExpect(jsonPath("$[0].FILM_ID").value(2))
.andExpect(jsonPath("$[1].FILM_ID").value(3))
.andDo(document("db2-find-films-with-in-operator"));
}
@Test
@DisplayName("Test find with Not In Operator")
void findWithNotInOperator() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/FILM;desc")
.accept(APPLICATION_JSON)
.param("fields", "FILM_ID")
.param("filter", "FILM_ID=out=(2,3,5)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(2), hasSize(2))))
.andExpect(jsonPath("$[0].FILM_ID").value(1))
.andExpect(jsonPath("$[1].FILM_ID").value(4))
.andDo(document("db2-find-films-with-not-in-operator"));
}
@Test
@DisplayName("Test find with Not In Operator (Ext)")
void findWithNotInOperatorExt() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/FILM;desc")
.accept(APPLICATION_JSON)
.param("fields", "FILM_ID")
.param("filter", "film_id=out=(2,3,5)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(2), hasSize(2))))
.andExpect(jsonPath("$[0].FILM_ID").value(1))
.andExpect(jsonPath("$[1].FILM_ID").value(4))
.andDo(document("db2-find-films-with-not-in-operator-ext"));
}
@Test
@DisplayName("Test find with Like Operator")
void findWithLikeOperator() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/FILM;desc")
.accept(APPLICATION_JSON)
.param("fields", "FILM_ID")
.param("filter", "TITLE=like=ACADEMY")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1), hasSize(1))))
.andExpect(jsonPath("$[0].FILM_ID").value(1))
.andDo(document("db2-find-films-with-like-operator"));
}
@Test
@DisplayName("Test find with Starts With Operator")
void findWithStartsWithOperator() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/FILM;desc")
.accept(APPLICATION_JSON)
.param("fields", "FILM_ID")
.param("filter", "TITLE=startWith=ACAD")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1), hasSize(1))))
.andExpect(jsonPath("$[0].FILM_ID").value(1))
.andDo(document("db2-find-films-starts-with-operator"));
}
@Test
@DisplayName("Test find with Ends With Operator")
void findWithEndsWithOperator() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/FILM;desc")
.accept(APPLICATION_JSON)
.param("fields", "FILM_ID")
.param("filter", "TITLE=endWith=DINOSAUR")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1), hasSize(1))))
.andExpect(jsonPath("$[0].FILM_ID").value(1))
.andDo(document("db2-find-films-ends-with-operator"));
}
@Test
@DisplayName("Should return 4xx when using equals operator with an invalid column")
void findWithEqualsOperator_givenInvalidColumn_shouldReturn4xx() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/FILM")
.accept(APPLICATION_JSON)
.param("filter", "ACTOR_ID==206")
)
.andExpect(status().is4xxClientError())
.andExpect(jsonPath("$.detail").value("Failed to parse RQL - Column not found FILM.ACTOR_ID"));
}
@Test
@DisplayName("Test find with Not Like Operator")
void findWithNotLikeOperator() throws Exception {
mockMvc.perform(get( VERSION+"/db2b/FILM")
.accept(MediaType.APPLICATION_JSON)
.param("fields", "TITLE,FILM_ID")
.param("filter", "TITLE=nk=ACADEMY")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*", hasSize(3)))
.andExpect(jsonPath("$[0].FILM_ID", equalTo(2)))
.andExpect(jsonPath("$[0].TITLE", equalTo("ACE GOLDFINGER")))
.andExpect(jsonPath("$[1].FILM_ID", equalTo(3)))
.andExpect(jsonPath("$[1].TITLE", equalTo("ADAPTATION HOLES")))
.andExpect(jsonPath("$[2].FILM_ID", equalTo(4)))
.andExpect(jsonPath("$[2].TITLE", equalTo("AFFAIR PREJUDICE")))
.andDo(document("db2-find-film-with-not-like-operator"));
}
@Test
@DisplayName("Test find with Equals OR StartWith Operator")
void findWithEqualsAndStartWithCombinationalOperator() throws Exception {
mockMvc.perform(get( VERSION+"/db2b/FILM")
.accept(MediaType.APPLICATION_JSON)
.param("fields", "TITLE,FILM_ID")
.param("filter", "FILM_ID==2")
.param("filter", "TITLE=like=ACADEMY")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*", hasSize(2)))
.andExpect(jsonPath("$[0].FILM_ID", equalTo(1)))
.andExpect(jsonPath("$[0].TITLE", equalTo("ACADEMY DINOSAUR")))
.andExpect(jsonPath("$[1].FILM_ID", equalTo(2)))
.andExpect(jsonPath("$[1].TITLE", equalTo("ACE GOLDFINGER")))
.andDo(document("db2-find-film-with-equals-or-like-operator"));
}
@Test
@DisplayName("Test find with Equals AND Like Operator")
void findWithEqualsAndLikeCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/FILM")
.accept(APPLICATION_JSON)
.param("fields", "TITLE,FILM_ID")
.param("filter", "FILM_ID==2;TITLE=like=ACE")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$[0].FILM_ID", equalTo(2)))
.andExpect(jsonPath("$[0].TITLE", equalTo("ACE GOLDFINGER")))
.andDo(document("db2-find-film-with-equals-and-like-operator"));
}
@Test
@DisplayName("Test find with Equals and Like and In Operator")
void findWithEqualsAndLikeAndInCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/FILM")
.accept(APPLICATION_JSON)
.param("fields", "TITLE,FILM_ID")
.param("filter", "FILM_ID==2;TITLE=like=ACE;rating=in=(G, db2b)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$[0].FILM_ID", equalTo(2)))
.andExpect(jsonPath("$[0].TITLE", equalTo("ACE GOLDFINGER")))
.andDo(document("db2-find-film-with-equals-and-like-and-in-operator"));
}
@Test
@DisplayName("Test find with Equals OR Like OR In Operator")
void findWithEqualsOrLikeOrInCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/FILM")
.accept(APPLICATION_JSON)
.param("fields", "TITLE,FILM_ID")
.param("filter", "FILM_ID==2")
.param("filter", "TITLE=like=ACADEMY")
.param("filter", "rating=in=(G, db2b)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(3)))
.andExpect(jsonPath("$[0].FILM_ID", equalTo(1)))
.andExpect(jsonPath("$[0].TITLE", equalTo("ACADEMY DINOSAUR")))
.andExpect(jsonPath("$[1].FILM_ID", equalTo(2)))
.andExpect(jsonPath("$[1].TITLE", equalTo("ACE GOLDFINGER")))
.andExpect(jsonPath("$[2].FILM_ID", equalTo(4)))
.andExpect(jsonPath("$[2].TITLE", equalTo("AFFAIR PREJUDICE")))
.andDo(document("db2-find-film-with-equals-or-like-or-in-operator"));
}
@Test
@DisplayName("Test find with Equals And Like And Not In Operator")
void findWithEqualsAndLikeAndNotInCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/FILM")
.accept(APPLICATION_JSON)
.param("fields", "TITLE,FILM_ID")
.param("filter", "FILM_ID==2;TITLE=like=ACE;RATING=out=(G, db2b)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isEmpty())
.andDo(document("db2-find-film-with-equals-and-like-and-out-operator"));
}
@Test
@DisplayName("Test find with Equals OR Like OR Not In Operator")
void findWithEqualsOrLikeOrNotInCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/FILM")
.accept(APPLICATION_JSON)
.param("fields", "TITLE,FILM_ID")
.param("filter", "FILM_ID==2")
.param("filter", "TITLE=like=ACADEMY")
.param("filter", "RATING=out=(G, db2b)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(3)))
.andExpect(jsonPath("$[0].FILM_ID", equalTo(1)))
.andExpect(jsonPath("$[0].TITLE", equalTo("ACADEMY DINOSAUR")))
.andExpect(jsonPath("$[1].FILM_ID", equalTo(2)))
.andExpect(jsonPath("$[1].TITLE", equalTo("ACE GOLDFINGER")))
.andExpect(jsonPath("$[2].FILM_ID", equalTo(3)))
.andExpect(jsonPath("$[2].TITLE", equalTo("ADAPTATION HOLES")))
.andDo(document("db2-find-film-with-equals-or-like-or-out-operator"));
}
@Test
@DisplayName("Test find with Equals and Like and In And Greater Than Equals Operator")
void findWithEqualsAndLikeAndInAbdGreaterThanEqualsCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/FILM")
.accept(APPLICATION_JSON)
.param("fields", "TITLE,FILM_ID")
.param("filter", "FILM_ID==2;TITLE=like=ACE;RATING=in=(G, db2b);LANGUAGE_ID=ge=1")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$[0].FILM_ID", equalTo(2)))
.andExpect(jsonPath("$[0].TITLE", equalTo("ACE GOLDFINGER")))
.andDo(document("db2-find-film-with-equals-and-like-and-in-and-greater-equal-operator"));
}
@Test
@DisplayName("Test find with Equals and Like and In And Greater Than Operator")
void findWithEqualsAndLikeAndInAbdGreaterThanCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/FILM")
.accept(APPLICATION_JSON)
.param("fields", "TITLE,FILM_ID")
.param("filter", "FILM_ID==2;TITLE=like=ACE;RATING=in=(G, db2b);LANGUAGE_ID=gt=1")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*", hasSize(0)))
.andDo(document("db2-find-film-with-equals-and-like-and-in-and-greater-operator"));
}
@Test
@DisplayName("Test find with Equals and Like and In And Less Than Equals Operator")
void findWithEqualsAndLikeAndInAndLessThanEqualsCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/FILM")
.accept(APPLICATION_JSON)
.param("fields", "TITLE,FILM_ID")
.param("filter", "FILM_ID==2;TITLE=like=ACE;RATING=in=(G, db2b);LANGUAGE_ID=le=2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$[0].FILM_ID", equalTo(2)))
.andExpect(jsonPath("$[0].TITLE", equalTo("ACE GOLDFINGER")))
.andDo(document("db2-find-film-with-equals-and-like-and-in-and-less-equal-operator"));
}
@Test
@DisplayName("Test find with Equals and Like and In And Less Than Operator")
void findWithEqualsAndLikeAndInAndLessThanCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/FILM")
.accept(APPLICATION_JSON)
.param("fields", "TITLE,FILM_ID")
.param("filter", "FILM_ID==2;TITLE=like=ACE;RATING=in=(G, db2b);LANGUAGE_ID=lt=1")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isEmpty())
.andExpect(jsonPath("$.*", hasSize(0)))
.andDo(document("db2-find-film-with-equals-and-like-and-in-and-less-operator"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/db2/Db2ReadControllerDefaultFetchLimitTest.java
================================================
package com.homihq.db2rest.rest.db2;
import com.homihq.db2rest.DB2BaseIntegrationTest;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.springframework.http.MediaType;
import org.springframework.test.context.TestPropertySource;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.core.AnyOf.anyOf;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
//@Order(203)
@TestPropertySource(properties = {"db2rest.defaultFetchLimit=5"})
class Db2ReadControllerDefaultFetchLimitTest extends DB2BaseIntegrationTest {
@Test
@DisplayName("Get all with default fetch limit set to 5")
void findAllPersonsWithDefaultFetchLimit5() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/PERSON")
.accept(MediaType.APPLICATION_JSON)
)
.andExpect(status().isOk())
.andExpect(jsonPath("$", anyOf(hasSize(5))))
.andDo(document("db2-find-all-persons-with-default-fetch-limit-5"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/db2/Db2ReadControllerTest.java
================================================
package com.homihq.db2rest.rest.db2;
import com.homihq.db2rest.DB2BaseIntegrationTest;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.springframework.http.MediaType;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.core.AnyOf.anyOf;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(201)
class Db2ReadControllerTest extends DB2BaseIntegrationTest {
@Test
@DisplayName("Test find all films - all columns.")
void findAllFilms() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/FILM")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
//.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
//.andExpect(jsonPath("$.*", hasSize(4)))
.andExpect(jsonPath("$.*", anyOf(hasSize(4), hasSize(9), hasSize(8))))
.andExpect(jsonPath("$[0].*", hasSize(14)))
.andDo(document("db-get-all-films-all-columns"));
}
@Test
@DisplayName("Test find all films - 3 columns")
void findAllFilmsWithThreeCols() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/FILM")
.contentType(APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)
.param("fields", "title,description,release_year")
)
//.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(4), hasSize(9), hasSize(8))))
.andExpect(jsonPath("$[0].*", hasSize(3)))
.andDo(document("db-find-all-films-3-columns"));
}
@Test
@DisplayName("Test find all films - with column alias")
void findAllFilmsWithColumnAlias() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/FILM")
.contentType(APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)
.param("fields", "title,description,release_year:releaseYear")
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(4), hasSize(9), hasSize(8))))
.andExpect(jsonPath("$[0].TITLE", notNullValue()))
.andExpect(jsonPath("$[0].DESCRIPTION", notNullValue()))
.andExpect(jsonPath("$[0].releaseYear", notNullValue()))
.andDo(document("db-find-all-films-with-column-alias"));
}
@Test
@DisplayName("Get one")
void findOneFilm() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/FILM/one")
.accept(MediaType.APPLICATION_JSON)
.param("fields", "title")
.param("filter", "film_id==1"))
.andExpect(status().isOk())
//.andDo(print())
.andDo(document("db-get-on-film"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/db2/Db2TemplateControllerTest.java
================================================
package com.homihq.db2rest.rest.db2;
import com.homihq.db2rest.DB2BaseIntegrationTest;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.core.AnyOf.anyOf;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(202)
@DisplayName("Parameterized SQL template")
class Db2TemplateControllerTest extends DB2BaseIntegrationTest {
public final static int ID = 1;
@Test
@DisplayName("Test find all films with sql template")
void findAllFilms() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/sql/select_all")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(4), hasSize(9), hasSize(8))))
.andExpect(jsonPath("$[0].*", hasSize(14)))
.andDo(document("db2-template-get-all-films-all-columns"));
}
@Test
@DisplayName("Find film by id with request param")
void findFilmByID() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/sql/select_by_id")
.param("film_id", String.valueOf(ID))
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(print())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1))))
.andDo(document("db2-template-get-film-by-id-with-params"));
}
@Test
@DisplayName("Find film by id with headers")
void findFilmByIDWithHeader() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/sql/select_by_id")
.header("film_id", String.valueOf(ID))
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(print())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1))))
.andDo(document("db2-template-get-film-by-id-with-headers"));
}
@Test
@DisplayName("Find film by id with custom path")
void findFilmByIDWithPath() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/sql/select_by_id/" + ID)
.header("paths", "film_id")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(print())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1))))
.andDo(document("db2-template-get-film-by-id-with-user-path"));
}
@Test
@DisplayName("Failed to find film by id without provided param")
void findFilmByIDWithRequiredConstraint() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/sql/select_by_id_is_required")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().is4xxClientError())
.andDo(document("db2-template-get-film-by-id-with-required-constraint"));
}
@Test
@DisplayName("Conditional render: select all when no request params")
void selectWithConditionalRenderNoRequestParams() throws Exception {
mockMvc.perform(get(VERSION + "/db2b/sql/conditional_render_and_op")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(4), hasSize(9), hasSize(8))))
.andExpect(jsonPath("$[0].*", hasSize(14)))
.andDo(document("db2-template-conditional-render-no-request-params"));
}
@Test
@DisplayName("Conditional render: select render one condition")
void selectWithConditionalRenderWithID() throws Exception {
var id = 4;
mockMvc.perform(get(VERSION + "/db2b/sql/conditional_render_and_op")
.param("film_id", String.valueOf(id))
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1))))
.andExpect(jsonPath("$[0].FILM_ID").value(id))
.andDo(document("db2-template-conditional-render-with-id-condition"));
}
@Test
@DisplayName("Conditional render: render both and operations")
void selectWithConditionalRenderWithField() throws Exception {
var id = 4;
var rating = "G";
mockMvc.perform(get(VERSION + "/db2b/sql/conditional_render_and_op")
.param("film_id", String.valueOf(id))
.param("rating", rating)
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1))))
.andExpect(jsonPath("$[0].FILM_ID").value(id))
.andExpect(jsonPath("$[0].RATING").value(rating))
.andDo(document("db2-template-conditional-render-render-both-and-operations"));
}
@Test
@DisplayName("Conditional render join: skip render join, select film by id")
void selectWithConditionalRenderJoinWithoutInput() throws Exception {
var film_id = 1;
mockMvc.perform(get(VERSION + "/db2b/sql/conditional_render_join")
.param("film_id", String.valueOf(film_id))
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1))))
.andExpect(jsonPath("$[0].FILM_ID").value(film_id))
.andDo(document("db2-template-conditional-render-join-skip-render"));
}
@Test
@DisplayName("Conditional render join: execute rendered join")
void selectWithConditionalRenderJoin() throws Exception {
var film_id = 1;
var language_id = 1;
mockMvc.perform(get(VERSION + "/db2b/sql/conditional_render_join")
.param("film_id", String.valueOf(film_id))
.param("language_id", String.valueOf(language_id))
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1))))
.andExpect(jsonPath("$[0].FILM_ID").value(film_id))
//.andExpect(jsonPath("$[0].LANGUAGE_NAME").value("English")) //TODO Fix
.andDo(document("db2-template-conditional-render-join"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/db2/Db2UpdateControllerTest.java
================================================
package com.homihq.db2rest.rest.db2;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.DB2BaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.equalTo;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.patch;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(270)
@TestWithResources
class Db2UpdateControllerTest extends DB2BaseIntegrationTest {
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@GivenJsonResource("/testdata/UPDATE_FILM_REQUEST.json")
Map UPDATE_FILM_REQUEST;
@GivenJsonResource("/testdata/UPDATE_NON_EXISTING_FILM_REQUEST.json")
Map UPDATE_NON_EXISTING_FILM_REQUEST;
@GivenJsonResource("/testdata/UPDATE_NON_EXISTING_TABLE.json")
Map UPDATE_NON_EXISTING_TABLE;
@GivenJsonResource("/testdata/UPDATE_FILMS_REQUEST.json")
Map UPDATE_FILMS_REQUEST;
@Test
@DisplayName("Update an existing film")
void updateExistingFilm() throws Exception {
mockMvc.perform(patch(VERSION + "/db2b/FILM")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("filter", "title==\"ACADEMY DINOSAUR\"")
.content(objectMapper.writeValueAsString(UPDATE_FILM_REQUEST))
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", equalTo(1)))
.andDo(document("db2-update-existing-film"));
}
@Test
@DisplayName("Update a non-existing film")
void updateNonExistingFilm() throws Exception {
mockMvc.perform(patch(VERSION + "/db2b/FILM")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("filter", "title==\"BAAHUBALI\"")
.content(objectMapper.writeValueAsString(UPDATE_NON_EXISTING_FILM_REQUEST))
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", equalTo(0)))
//.andDo(print())
.andDo(document("db2-update-non-existing-film"));
}
@Test
@DisplayName("Update non-existing table")
void updateNonExistingTable() throws Exception {
mockMvc.perform(patch(VERSION + "/db2b/unknown_table")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("filter", "sample_col==\"sample value 1\"")
.content(objectMapper.writeValueAsString(UPDATE_NON_EXISTING_TABLE))
)
.andExpect(status().isNotFound())
//.andDo(print())
.andDo(document("mysql-update-non-existing-table"));
}
@Test
@DisplayName("Updating multiple films")
void updateMultipleColumns() throws Exception {
mockMvc.perform(patch(VERSION + "/db2b/FILM")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("filter", "rating==\"G\"")
.content(objectMapper.writeValueAsString(UPDATE_FILMS_REQUEST))
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", equalTo(2)))
//.andDo(print())
.andDo(document("mysql-update-multiple-films"));
}
//TODO - Add a test to update date field.
//TODO - Greater than, less than , equal to , between test for date
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/docsSwagger/OpenApiSpecificationNoSecurityTest.java
================================================
package com.homihq.db2rest.rest.docsSwagger;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Profile;
import org.springframework.restdocs.RestDocumentationExtension;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.ext.ScriptUtils;
import org.testcontainers.jdbc.JdbcDatabaseDelegate;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.util.List;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.options;
import com.homihq.db2rest.config.Db2RestConfigProperties;
import lombok.extern.slf4j.Slf4j;
@SpringBootTest
@AutoConfigureMockMvc
@ExtendWith(RestDocumentationExtension.class)
@Slf4j
public class OpenApiSpecificationNoSecurityTest {
@Autowired
private MockMvc mockMvc;
@Autowired
protected WebApplicationContext context;
@Autowired
protected ApplicationContext applicationContext;
@Autowired
protected Db2RestConfigProperties db2RestConfigProperties;
private static final List postgresScripts = List.of("pg/postgres-sakila.sql",
"pg/postgres-sakila-data.sql", "pg/pg-sakila-functions.sql");
private static final PostgreSQLContainer testPostgres =
(PostgreSQLContainer) new PostgreSQLContainer("postgres:15.2-alpine")
.withDatabaseName("postgres")
.withUsername("postgres")
.withPassword("postgres")
.withReuse(true);
static {
testPostgres.start();
var containerDelegate = new JdbcDatabaseDelegate(testPostgres, "");
postgresScripts.forEach(initScript -> ScriptUtils.runInitScript(containerDelegate, initScript));
}
// private final String testOrigin = "http://example.com";
@DynamicPropertySource
static void setProperties(DynamicPropertyRegistry registry) {
registry.add("DB_URL", () -> testPostgres.getJdbcUrl());
registry.add("DB_USER", () -> testPostgres.getUsername());
registry.add("DB_PASSWORD", () -> testPostgres.getPassword());
registry.add("ENABLE_CORS", () -> "false");
}
@BeforeEach
void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
}
@Test
public void shouldBeSuccessfullForOpeningDocs() throws Exception{
mockMvc.perform(options("/swagger-ui/index.html")).andExpect(status().isOk());
}
@Test
public void shouldBeSuccessfullForDocsJsonData() throws Exception{
mockMvc.perform(options("/v3/api-docs")).andExpect(status().isOk());
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/docsSwagger/OpenApiSpecificationWithSecurityTest.java
================================================
package com.homihq.db2rest.rest.docsSwagger;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Profile;
import org.springframework.restdocs.RestDocumentationExtension;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.ext.ScriptUtils;
import org.testcontainers.jdbc.JdbcDatabaseDelegate;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.util.List;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.options;
import com.homihq.db2rest.config.Db2RestConfigProperties;
import lombok.extern.slf4j.Slf4j;
@SpringBootTest
@AutoConfigureMockMvc
@ExtendWith(RestDocumentationExtension.class)
@Slf4j
public class OpenApiSpecificationWithSecurityTest {
@Autowired
private MockMvc mockMvc;
@Autowired
protected WebApplicationContext context;
@Autowired
protected ApplicationContext applicationContext;
@Autowired
protected Db2RestConfigProperties db2RestConfigProperties;
private static final List postgresScripts = List.of("pg/postgres-sakila.sql",
"pg/postgres-sakila-data.sql", "pg/pg-sakila-functions.sql");
private static final PostgreSQLContainer testPostgres =
(PostgreSQLContainer) new PostgreSQLContainer("postgres:15.2-alpine")
.withDatabaseName("postgres")
.withUsername("postgres")
.withPassword("postgres")
.withReuse(true);
static {
testPostgres.start();
var containerDelegate = new JdbcDatabaseDelegate(testPostgres, "");
postgresScripts.forEach(initScript -> ScriptUtils.runInitScript(containerDelegate, initScript));
}
// private final String testOrigin = "http://example.com";
@DynamicPropertySource
static void setProperties(DynamicPropertyRegistry registry) {
registry.add("DB_URL", () -> testPostgres.getJdbcUrl());
registry.add("DB_USER", () -> testPostgres.getUsername());
registry.add("DB_PASSWORD", () -> testPostgres.getPassword());
registry.add("ENABLE_AUTH", () -> "true");
registry.add("AUTH_PROVIDER", () -> "apiKey");
registry.add("AUTH_DATA_SOURCE" , () -> "classpath:/auth-apiKey-test.yaml");
registry.add("ENABLE_CORS", () -> "true");
/*
- mapping: "/actor/**"
allowedOrigin: "http://localhost:3000"
allowedHeader: "*"
allowedMethod: "*"
- mapping: "/v1/rdbms/db/**"
allowedOrigin: "http://localhost:4200, http://localhost:3000"
allowedHeader: "*"
allowedMethod: "GET,POST"
*/
registry.add("cors.mappings[0].mapping", () -> "/actor/**");
registry.add("cors.mappings[0].allowedOrigins", () -> "http://localhost:3000");
registry.add("cors.mappings[0].allowedHeaders", () -> "*");
registry.add("cors.mappings[0].allowedMethods", () -> "*");
registry.add("cors.mappings[1].mapping", () -> "/v1/rdbms/db/**");
registry.add("cors.mappings[1].allowedOrigins", () -> "http://localhost:4200, http://localhost:3000");
registry.add("cors.mappings[1].allowedHeaders", () -> "*");
registry.add("cors.mappings[1].allowedMethods", () -> "GET,POST");
}
@BeforeEach
void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
}
@Test
public void shouldBeSuccessfullForOpeningDocs() throws Exception{
mockMvc.perform(options("/swagger-ui/index.html")).andExpect(status().isOk());
}
@Test
public void shouldBeSuccessfullForDocsJsonData() throws Exception{
mockMvc.perform(options("/v3/api-docs")).andExpect(status().isOk());
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mariadb/MariaDBBasicJoinControllerTest.java
================================================
package com.homihq.db2rest.rest.mariadb;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.MariaDBBaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.*;
import java.util.List;
import java.util.Map;
import static org.hamcrest.Matchers.*;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(310)
@TestWithResources
class MariaDBBasicJoinControllerTest extends MariaDBBaseIntegrationTest {
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@GivenJsonResource("/testdata/LEFT_JOIN.json")
List> LEFT_JOIN;
@GivenJsonResource("/testdata/RIGHT_JOIN.json")
List> RIGHT_JOIN;
@Test
@DisplayName("Test left Join")
void testLeftJoin() throws Exception {
mockMvc.perform(post(VERSION + "/mariadb/users/_expand")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(LEFT_JOIN))
)
// .andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(4)))
.andExpect(jsonPath("$[0].*", hasSize(10)))
.andExpect(jsonPath("$[0].auid", equalTo(1)))
.andExpect(jsonPath("$[0].apid", equalTo(1)))
.andExpect(jsonPath("$[1].auid", equalTo(2)))
.andExpect(jsonPath("$[1].apid", nullValue()))
.andExpect(jsonPath("$[3].auid", equalTo(6)))
.andExpect(jsonPath("$[3].apid", nullValue()))
.andExpect(jsonPath("$[3].firstname", nullValue()))
.andDo(document("mariadb-left-join"));
}
@Test
@DisplayName("Test right Join")
void testRightJoin() throws Exception {
mockMvc.perform(post(VERSION + "/mariadb/users/_expand")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(RIGHT_JOIN))
)
//.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(4)))
.andExpect(jsonPath("$[0].*", hasSize(10)))
.andExpect(jsonPath("$[0].auid", equalTo(1)))
.andExpect(jsonPath("$[0].apid", equalTo(1)))
.andExpect(jsonPath("$[0].apid", equalTo(1)))
.andExpect(jsonPath("$[0].firstname", equalTo("Jack")))
.andExpect(jsonPath("$[1].auid", equalTo(3)))
.andExpect(jsonPath("$[1].apid", equalTo(2)))
.andExpect(jsonPath("$[1].username", nullValue()))
.andExpect(jsonPath("$[1].firstname", equalTo("Tom")))
.andExpect(jsonPath("$[3].auid", equalTo(7)))
.andExpect(jsonPath("$[3].apid", equalTo(7)))
.andExpect(jsonPath("$[3].username", nullValue()))
.andExpect(jsonPath("$[3].firstname", equalTo("Ivan")))
.andDo(document("mariadb-right-join"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mariadb/MariaDBBulkCreateControllerTest.java
================================================
package com.homihq.db2rest.rest.mariadb;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.MariaDBBaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.GivenTextResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.*;
import java.util.List;
import java.util.Map;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasSize;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(381)
@TestWithResources
class MariaDBBulkCreateControllerTest extends MariaDBBaseIntegrationTest {
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@GivenJsonResource("/testdata/BULK_CREATE_FILM_REQUEST.json")
List> BULK_CREATE_FILM_REQUEST;
@GivenJsonResource("/testdata/BULK_CREATE_FILM_BAD_REQUEST.json")
List> BULK_CREATE_FILM_BAD_REQUEST;
@GivenTextResource("/testdata/CREATE_FILM_REQUEST_CSV.csv")
String CREATE_FILM_REQUEST_CSV;
@GivenTextResource("/testdata/CREATE_FILM_BAD_REQUEST_CSV.csv")
String CREATE_FILM_BAD_REQUEST_CSV;
@GivenJsonResource("/testdata/BULK_CREATE_DIRECTOR_REQUEST.json")
List> BULK_CREATE_DIRECTOR_REQUEST;
@GivenJsonResource("/testdata/BULK_CREATE_DIRECTOR_BAD_REQUEST.json")
List> BULK_CREATE_DIRECTOR_BAD_REQUEST;
@GivenJsonResource("/testdata/BULK_CREATE_REVIEW_REQUEST.json")
List> BULK_CREATE_REVIEW_REQUEST;
@Test
@DisplayName("Create many films.")
void create() throws Exception {
mockMvc.perform(post(VERSION + "/mariadb/film/bulk")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(BULK_CREATE_FILM_REQUEST))
)
.andExpect(status().isCreated())
.andExpect(jsonPath("$.rows").isArray())
.andExpect(jsonPath("$.rows", hasSize(2)))
.andExpect(jsonPath("$.rows", hasItem(1)))
.andExpect(jsonPath("$.rows", hasItem(1)))
//.andExpect(jsonPath("$.generated_keys").isArray()) //TODO - push TSID columns
//.andExpect(jsonPath("$.generated_keys", hasSize(2)))
//.andExpect(jsonPath("$.generated_keys", allOf(notNullValue())))
//.andDo(print())
.andDo(document("mariadb-bulk-create-films"));
}
@Test
@DisplayName("Create many films with CSV type.")
void createCSV() throws Exception {
mockMvc.perform(post(VERSION + "/mariadb/film/bulk")
.contentType("text/csv").accept(APPLICATION_JSON)
.content(CREATE_FILM_REQUEST_CSV))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.rows", hasSize(2)))
.andExpect(jsonPath("$.rows", hasItem(1)))
//.andExpect(jsonPath("$.generated_keys", hasSize(2)))
//.andExpect(jsonPath("$.generated_keys", allOf(notNullValue())))
//.andDo(print())
.andDo(document("mariadb-bulk-create-films-csv"));
}
@Test
@DisplayName("Create many films with CSV type resulting error.")
void createCSVWithError() throws Exception {
mockMvc.perform(post(VERSION + "/mariadb/film/bulk")
.contentType("text/csv")
.accept(APPLICATION_JSON)
.content(CREATE_FILM_BAD_REQUEST_CSV))
.andExpect(status().isBadRequest())
//.andDo(print())
.andDo(document("mariadb-bulk-create-films-csv-error"));
}
@Test
@DisplayName("Create many films with failure.")
void createError() throws Exception {
mockMvc.perform(post(VERSION + "/mariadb/film/bulk")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(BULK_CREATE_FILM_BAD_REQUEST))
)
.andExpect(status().isBadRequest())
// .andDo(print())
.andDo(document("mariadb-bulk-create-films-error"));
}
@Test
@DisplayName("Create many directors.")
void createDirector() throws Exception {
mockMvc.perform(post(VERSION + "/mariadb/director/bulk")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("tsIdEnabled", "true")
.content(objectMapper.writeValueAsString(BULK_CREATE_DIRECTOR_REQUEST))
)
.andExpect(status().isCreated())
//.andDo(print())
.andDo(document("mariadb-bulk-create-directors"));
}
@Test
@DisplayName("Create many directors with wrong tsid type.")
void createDirectorWithWrongTsidType() throws Exception {
mockMvc.perform(post(VERSION + "/mariadb/director/bulk")
.characterEncoding(UTF_8)
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.param("tsid", "director_id")
.param("tsidType", "string")
.header("Content-Profile", "sakila")
.content(objectMapper.writeValueAsString(BULK_CREATE_DIRECTOR_BAD_REQUEST))
)
.andExpect(status().isBadRequest())
//.andDo(print())
.andDo(document("mariadb-bulk-create-directors-with-wrong-tsid-type"));
}
@Test
@DisplayName("Create reviews with default tsid type.")
void createReviewWithDefaultTsidType() throws Exception {
mockMvc.perform(post(VERSION + "/mariadb/review/bulk")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("tsIdEnabled", "true")
.content(objectMapper.writeValueAsString(BULK_CREATE_REVIEW_REQUEST))
)
.andExpect(status().isCreated())
//.andDo(print())
.andDo(document("mariadb-bulk-create-reviews-with-default-tsid-type"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mariadb/MariaDBCountControllerTest.java
================================================
package com.homihq.db2rest.rest.mariadb;
import com.homihq.db2rest.MariaDBBaseIntegrationTest;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.springframework.http.MediaType;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(302)
class MariaDBCountControllerTest extends MariaDBBaseIntegrationTest {
@Test
@DisplayName("test film count")
void testFilmCount() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/film/count")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
//.andDo(print())
.andDo(document("mariadb-get-film-count"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mariadb/MariaDBCreateControllerTest.java
================================================
package com.homihq.db2rest.rest.mariadb;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.MariaDBBaseIntegrationTest;
import com.jayway.jsonpath.JsonPath;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(380)
@TestWithResources
class MariaDBCreateControllerTest extends MariaDBBaseIntegrationTest {
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@GivenJsonResource("/testdata/CREATE_FILM_REQUEST.json")
Map CREATE_FILM_REQUEST;
@GivenJsonResource("/testdata/CREATE_FILM_REQUEST_ERROR.json")
Map CREATE_FILM_REQUEST_ERROR;
@GivenJsonResource("/testdata/CREATE_VANITY_VAN_REQUEST.json")
Map CREATE_VANITY_VAN_REQUEST;
@GivenJsonResource("/testdata/CREATE_DIRECTOR_REQUEST.json")
Map CREATE_DIRECTOR_REQUEST;
@GivenJsonResource("/testdata/CREATE_FILM_REQUEST_MISSING_PAYLOAD.json")
Map CREATE_FILM_REQUEST_MISSING_PAYLOAD;
@Test
@DisplayName("Create a film.")
void create() throws Exception {
mockMvc.perform(post(VERSION + "/mariadb/film")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST))
)
//.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
.andExpect(jsonPath("$.keys.insert_id").exists())
.andExpect(jsonPath("$.keys.insert_id", equalTo(5)))
.andDo(document("mariadb-create-a-film"));
}
@Test
@DisplayName("Test Create a film with error.")
void createError() throws Exception {
mockMvc.perform(post(VERSION + "/mariadb/film")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST_ERROR)))
// .andDo(print())
.andExpect(status().isBadRequest())
.andDo(document("mariadb-create-a-film-error"));
}
@Test
@DisplayName("Test create a film - non existent table.")
void createNonExistentTable() throws Exception {
mockMvc.perform(post(VERSION + "/mariadb/films")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST)))
.andExpect(status().isNotFound())
.andDo(print())
.andDo(document("mariadb-create-a-film-no-table"));
}
@Test
@DisplayName("Test Create a director - TSID enabled")
void createDirectorWithTSIDEnabled() throws Exception {
//TODO - MySQL return keys not working
mockMvc.perform(post(VERSION + "/mariadb/director")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("tsIdEnabled", "true")
.content(objectMapper.writeValueAsString(CREATE_DIRECTOR_REQUEST)))
//.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
.andExpect(jsonPath("$.keys.director_id").exists())
.andExpect(jsonPath("$.keys.director_id").isNumber())
.andDo(document("mariadb-create-a-director-tsid-enabled"));
}
@Test
@DisplayName("Create a director - with TSID explicitly OFF")
void createDirectorWithTSIDOff() throws Exception {
mockMvc.perform(post(VERSION + "/mariadb/director")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("tsIdEnabled", "false")
.content(objectMapper.writeValueAsString(CREATE_DIRECTOR_REQUEST)))
.andExpect(status().isBadRequest())
//.andDo(print())
.andDo(document("mariadb-create-a-director-with-tsid-OFF"));
}
@Test
@DisplayName("Test Create a Vanity Van - with varchar tsid type")
void createVanityVanWithVarcharTsIdType() throws Exception {
//TODO - MySQL return keys not working
mockMvc.perform(post(VERSION + "/mariadb/vanity_van")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("tsIdEnabled", "true")
.content(objectMapper.writeValueAsString(CREATE_VANITY_VAN_REQUEST)))
.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
.andExpect(jsonPath("$.keys.van_id").exists())
.andExpect(jsonPath("$.keys.van_id").isString())
.andDo(document("mariadb-create-a-vanity-van-tsid-varchar"));
}
@Test
@DisplayName("Create a film with subset of columns")
void createFilmWithSubsetOfColumns() throws Exception {
var result = mockMvc.perform(post(VERSION + "/mariadb/film")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.queryParam("columns", "title,description,language_id")
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST)))
.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
.andExpect(jsonPath("$.keys").exists())
//.andExpect(jsonPath("$.keys.insert_id", equalTo(5)))
.andExpect(jsonPath("$.keys.insert_id").isNumber())
.andDo(document("mariadb-create-a-film"))
.andReturn();
var pk = JsonPath.read(result.getResponse().getContentAsString(), "$.keys.insert_id");
mockMvc.perform(get(VERSION + "/mariadb/film")
.accept(APPLICATION_JSON)
.queryParam("fields", "title,release_year")
.queryParam("filter", String.format("film_id==%s", pk)))
//.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$[0].title", equalTo("Dunki")))
.andExpect(jsonPath("$[0].release_year").doesNotExist());
// cleanup data
assertTrue(deleteRow("film", "film_id", (int) pk));
}
@Test
@DisplayName("Ignore if columns parameter is blank")
void shouldIgnoreWhenColumnsQueryParamIsEmpty() throws Exception {
var result = mockMvc.perform(post(VERSION + "/mariadb/film")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.queryParam("columns", "")
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST)))
//.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
.andExpect(jsonPath("$.keys").exists())
.andDo(document("mariadb-create-a-film"))
.andReturn();
var pk = JsonPath.read(result.getResponse().getContentAsString(), "$.keys.insert_id");
mockMvc.perform(get(VERSION + "/mariadb/film")
.accept(APPLICATION_JSON)
.queryParam("select", "title,release_year")
.queryParam("filter", String.format("film_id==%s", pk)))
.andExpect(status().isOk())
.andExpect(jsonPath("$[0].title", equalTo("Dunki")))
.andExpect(jsonPath("$[0].release_year", equalTo("2023-01-01")))
// .andDo(print())
;
// cleanup data
assertTrue(deleteRow("film", "film_id", (int) pk));
}
@Test
@DisplayName("Column is present in columns param but not in payload")
void columnIsPresentInColumnsQueryParamButNotInPayload() throws Exception {
var result = mockMvc.perform(post(VERSION + "/mariadb/film")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.queryParam("columns", "title,description,language_id")
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST_MISSING_PAYLOAD))) //description is not in payload will be set to null
.andExpect(status().isBadRequest())
//.andDo(print())
.andDo(document("mariadb-create-a-film-missing-payload-attribute-error"))
.andReturn();
}
@Test
@DisplayName("Column violates not-null constraint")
void column_violates_not_null_constraint() throws Exception {
mockMvc.perform(post(VERSION + "/mariadb/film")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.queryParam("columns", "title,description")
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST)))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.detail",
containsString("Field 'language_id' doesn't have a default value")))
//.andDo(print())
.andDo(document("mariadb-create-a-film-not-null-constraint"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mariadb/MariaDBCrossJoinControllerTest.java
================================================
package com.homihq.db2rest.rest.mariadb;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.MariaDBBaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.*;
import java.util.List;
import java.util.Map;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(311)
@TestWithResources
class MariaDBCrossJoinControllerTest extends MariaDBBaseIntegrationTest {
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@GivenJsonResource("/testdata/CROSS_JOIN_USERS.json")
List> CROSS_JOIN;
@GivenJsonResource("/testdata/CROSS_JOIN_TOPS.json")
List> CROSS_JOIN_TOPS;
@Test
@DisplayName("Test cross Join - Users")
void testCrossJoin() throws Exception {
mockMvc.perform(post(VERSION + "/mariadb/users/_expand")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(CROSS_JOIN))
)
// .andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(16)))
.andExpect(jsonPath("$[0].*", hasSize(10)))
.andExpect(jsonPath("$[0].auid", equalTo(1)))
.andExpect(jsonPath("$[0].apid", equalTo(1)))
.andExpect(jsonPath("$[0].firstname", equalTo("Jack")))
.andExpect(jsonPath("$[1].auid", equalTo(2)))
.andExpect(jsonPath("$[1].apid", equalTo(1)))
.andExpect(jsonPath("$[1].firstname", equalTo("Jack")))
.andDo(document("mariadb-cross-join-users"));
}
@Test
@DisplayName("Test cross Join - Tops")
void testCrossJoinTops() throws Exception {
mockMvc.perform(post(VERSION + "/mariadb/tops/_expand")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(CROSS_JOIN_TOPS))
)
//.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(9)))
.andExpect(jsonPath("$[0].*", hasSize(6)))
.andExpect(jsonPath("$[0].top_item", equalTo("sweater")))
.andExpect(jsonPath("$[0].bottom_item", equalTo("jeans")))
.andExpect(jsonPath("$[0].color", equalTo("red")))
.andExpect(jsonPath("$[0].botColor", equalTo("blue")))
.andDo(document("mariadb-cross-join-tops"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mariadb/MariaDBDeleteAllTest.java
================================================
package com.homihq.db2rest.rest.mariadb;
import com.homihq.db2rest.MariaDBBaseIntegrationTest;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.springframework.test.context.TestPropertySource;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(391)
@TestPropertySource(properties = {"db2rest.allowSafeDelete=false"})
class MariaDBDeleteAllTest extends MariaDBBaseIntegrationTest {
@Test
@DisplayName("Delete all records while allowSafeDelete=false")
void deleteAllWithAllowSafeDeleteFalse() throws Exception {
mockMvc.perform(delete(VERSION + "/mariadb/country")
.accept(APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", Matchers.equalTo(4)))
.andDo(document("mariadb-delete-a-director"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mariadb/MariaDBDeleteControllerTest.java
================================================
package com.homihq.db2rest.rest.mariadb;
import com.homihq.db2rest.MariaDBBaseIntegrationTest;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(390)
class MariaDBDeleteControllerTest extends MariaDBBaseIntegrationTest {
@Test
@DisplayName("Delete a Director")
void delete_single_record() throws Exception {
mockMvc.perform(delete(VERSION + "/mariadb/director")
.accept(APPLICATION_JSON)
.param("filter", "first_name==\"Alex\""))
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", equalTo(1)))
.andDo(print())
.andDo(document("mariadb-delete-a-director"));
}
@Test
@DisplayName("Delete all records while allowSafeDelete=true")
void delete_all_records_with_allow_safe_delete_true() throws Exception {
mockMvc.perform(delete(VERSION + "/mariadb/director")
.accept(APPLICATION_JSON))
.andDo(print())
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.detail",
containsString("Invalid delete operation , safe set to true")))
//.andDo(print())
.andDo(document("mariadb-delete-all-director"));
}
@Test
@DisplayName("Column Does Not Exist")
void column_does_not_exist() throws Exception {
mockMvc.perform(delete(VERSION + "/mariadb/director")
.accept(APPLICATION_JSON)
.param("filter", "_name==\"Alex\"")).andDo(print())
.andExpect(status().isNotFound())
.andExpect(jsonPath("$.detail",
containsString("Column not found director._name")))
//.andDo(print())
.andDo(document("mariadb-column-not-exists"));
}
@Test
@DisplayName("Foreign Key Constraint Violation")
void foreign_key_constraint_violation() throws Exception {
mockMvc.perform(delete(VERSION + "/mariadb/language")
.accept(APPLICATION_JSON)
.param("filter", "name==\"ENGLISH\""))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.detail",
containsString("Cannot delete or update a parent row: a foreign key constraint fails")))
//.andDo(print())
.andDo(document("mariadb-constraint-violation"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mariadb/MariaDBFunctionControllerTest.java
================================================
package com.homihq.db2rest.rest.mariadb;
import com.homihq.db2rest.MariaDBBaseIntegrationTest;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.springframework.http.MediaType;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.instanceOf;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(351)
class MariaDBFunctionControllerTest extends MariaDBBaseIntegrationTest {
@Test
@DisplayName("Execute function on maria db")
void execute() throws Exception {
var json = """
{
"movieTitle": "ACADEMY DINOSAUR"
}
""";
mockMvc.perform(post(VERSION + "/mariadb/function/GetMovieRentalRateFunc")
.characterEncoding(UTF_8)
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.content(json))
.andExpect(status().isOk())
.andExpect(jsonPath("$", instanceOf(Map.class)))
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$.return", equalTo(0.99)))
//.andDo(print())
.andDo(document("mariadb-execute-function"));
}
@Test
@DisplayName("Execute UpdateUserFunc on MariaDB")
void updateUser() throws Exception {
var json = """
{
"user_id": "2"
}
""";
mockMvc.perform(post(VERSION + "/mariadb/function/UpdateUserFunc")
.characterEncoding(UTF_8)
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.content(json))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$['return']", equalTo(1)));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mariadb/MariaDBInnerJoinControllerTest.java
================================================
package com.homihq.db2rest.rest.mariadb;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.MariaDBBaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.*;
import java.util.List;
import java.util.Map;
import static org.hamcrest.Matchers.anyOf;
import static org.hamcrest.Matchers.hasSize;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(312)
@TestWithResources
class MariaDBInnerJoinControllerTest extends MariaDBBaseIntegrationTest {
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@GivenJsonResource("/testdata/INNER_JOIN.json")
List> INNER_JOIN;
@Test
@DisplayName("Test inner Join")
void testInnerJoin() throws Exception {
mockMvc.perform(post(VERSION + "/mariadb/review/_expand")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(INNER_JOIN))
)
// .andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1), hasSize(3))))
.andExpect(jsonPath("$[0].*", hasSize(7)))
//.andExpect(jsonPath("$[0].review_id", equalTo("ABC123")))
//.andExpect(jsonPath("$[0].film_id", equalTo(1)))
//.andExpect(jsonPath("$[0].title", equalTo("ACADEMY DINOSAUR")))
.andDo(document("mariadb-inner-join"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mariadb/MariaDBInnerJoinMultiTableControllerTest.java
================================================
package com.homihq.db2rest.rest.mariadb;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.MariaDBBaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.*;
import java.util.List;
import java.util.Map;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(313)
@TestWithResources
class MariaDBInnerJoinMultiTableControllerTest extends MariaDBBaseIntegrationTest {
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@GivenJsonResource("/testdata/INNER_JOIN_MULTI_TABLE.json")
List> INNER_JOIN_MULTI_TABLE;
@Test
@DisplayName("Test inner multi-table Join")
void testInnerMultiTable() throws Exception {
mockMvc.perform(post(VERSION + "/mariadb/film/_expand")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(INNER_JOIN_MULTI_TABLE))
)
//.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$[0].*", hasSize(17)))
.andExpect(jsonPath("$[0].film_id", equalTo(1)))
.andExpect(jsonPath("$[0].language_id", equalTo(1)))
.andExpect(jsonPath("$[0].actor_id", equalTo(1)))
.andExpect(jsonPath("$[0].first_name", equalTo("PENELOPE")))
.andExpect(jsonPath("$[0].last_name", equalTo("GUINESS")))
.andDo(document("mariadb-inner-multi-table-join"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mariadb/MariaDBInnerSelfJoinControllerTest.java
================================================
package com.homihq.db2rest.rest.mariadb;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.MariaDBBaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.*;
import java.util.List;
import java.util.Map;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
@TestWithResources
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(314)
class MariaDBInnerSelfJoinControllerTest extends MariaDBBaseIntegrationTest {
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@GivenJsonResource("/testdata/INNER_SELF_JOIN.json")
List> INNER_SELF_JOIN;
@Test
@DisplayName("Test inner self Join")
void testInnerSelfJoin() throws Exception {
mockMvc.perform(post(VERSION + "/mariadb/film/_expand")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(INNER_SELF_JOIN))
)
//.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
//.andExpect(jsonPath("$.*", hasSize(1)))
//.andExpect(jsonPath("$[0].*", hasSize(17)))
//.andExpect(jsonPath("$[0].film_id", equalTo(1)))
//.andExpect(jsonPath("$[0].language_id", equalTo(1)))
//.andExpect(jsonPath("$[0].actor_id", equalTo(1)))
//.andExpect(jsonPath("$[0].first_name", equalTo("PENELOPE")))
//.andExpect(jsonPath("$[0].last_name", equalTo("GUINESS")))
.andDo(document("mariadb-inner-multi-table-join"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mariadb/MariaDBJsonFileCreateControllerTest.java
================================================
package com.homihq.db2rest.rest.mariadb;
import com.homihq.db2rest.MariaDBBaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import org.junit.jupiter.api.*;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.web.servlet.MvcResult;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(381)
@TestWithResources
class MariaDBJsonFileCreateControllerTest extends MariaDBBaseIntegrationTest {
Path dir = FileSystems.getDefault().getPath("src/test/resources/testdata");
Path actorFile = dir.resolve("actor.json");
Path filmFile = dir.resolve("BULK_CREATE_FILM_REQUEST.json");
Path nonArrayActorFile = dir.resolve("CREATE_ACTOR_REQUEST.json");
Path directorFile = dir.resolve("director.json");
@Test
@DisplayName("Create many actors via JSON file upload.")
void uploadActorsFile() throws Exception {
MockMultipartFile file = new MockMultipartFile("file", "actor.json",
"application/json", Files.readAllBytes(actorFile));
MvcResult mvcResult = mockMvc.perform(multipart(VERSION + "/mariadb/actor/upload")
.file(file)
.contentType("multipart/form-data")
.accept(APPLICATION_JSON))
.andDo(print())
.andReturn();
mockMvc.perform(asyncDispatch(mvcResult))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row").isNumber())
.andExpect(jsonPath("$.row").value(10000))
.andExpect(jsonPath("$.keys").value("Bulk insert completed successfully"))
.andDo(document("mariadb-create-actors-file-upload"));
}
@Test
@DisplayName("Error create actor via JSON file upload.")
void uploadActorFileNonJsonArray() throws Exception {
MockMultipartFile file = new MockMultipartFile("file", nonArrayActorFile.toString(),
"application/json", Files.readAllBytes(nonArrayActorFile));
mockMvc.perform(multipart(VERSION + "/mariadb/actor/upload")
.file(file)
.contentType("multipart/form-data")
.accept(APPLICATION_JSON))
.andDo(print())
.andExpect(status().isBadRequest())
.andDo(document("mariadb-error-create-actors-file-upload"));
}
@Test
@DisplayName("Create many directors via file upload.")
void createDirectorViaUpload() throws Exception {
MockMultipartFile file = new MockMultipartFile("file", "bulkDirector.json",
"application/json", Files.readAllBytes(directorFile));
MvcResult mvcResult = mockMvc.perform(multipart(VERSION + "/mariadb/director/upload")
.file(file)
.contentType("multipart/form-data")
.accept(APPLICATION_JSON))
.andDo(print())
.andReturn();
mockMvc.perform(asyncDispatch(mvcResult))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row").isNumber())
.andExpect(jsonPath("$.row").value(600))
.andExpect(jsonPath("$.keys").value("Bulk insert completed successfully"))
.andDo(document("mariadb-create-directors-file-upload"));
}
@Test
@DisplayName("Create many films via file upload.")
void createFilmsViaUpload() throws Exception {
MockMultipartFile file = new MockMultipartFile("file", "bulkFilm.json",
"application/json", Files.readAllBytes(filmFile));
MvcResult mvcResult = mockMvc.perform(multipart(VERSION + "/mariadb/film/upload")
.file(file)
.contentType("multipart/form-data")
.accept(APPLICATION_JSON))
.andDo(print())
.andReturn();
mockMvc.perform(asyncDispatch(mvcResult))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row").isNumber())
.andExpect(jsonPath("$.row").value(2))
.andExpect(jsonPath("$.keys").value("Bulk insert completed successfully"))
.andDo(document("mariadb-create-films-file-upload"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mariadb/MariaDBProcedureControllerTest.java
================================================
package com.homihq.db2rest.rest.mariadb;
import com.homihq.db2rest.MariaDBBaseIntegrationTest;
import org.junit.jupiter.api.*;
import org.springframework.http.MediaType;
import java.util.Map;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.hamcrest.Matchers.*;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(350)
class MariaDBProcedureControllerTest extends MariaDBBaseIntegrationTest {
@Test
@DisplayName("Execute stored procedure on maria db")
void execute() throws Exception {
var json = """
{
"movieTitle": "ACADEMY DINOSAUR"
}
""";
mockMvc.perform(post(VERSION + "/mariadb/procedure/GetMovieRentalRateProc")
.characterEncoding(UTF_8)
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.content(json))
.andExpect(status().isOk())
.andExpect(jsonPath("$", instanceOf(Map.class)))
.andExpect(jsonPath("$.*", hasSize(2)))
.andExpect(jsonPath("$.rentalRate", equalTo(0.99)))
//.andDo(print())
.andDo(document("mariadb-execute-procedure"));
}
@Test
@DisplayName("Execute UpdateUser on MariaDB")
void updateUser() throws Exception {
var json = """
{
"user_id": "1"
}
""";
mockMvc.perform(post(VERSION + "/mariadb/procedure/UpdateUserProc")
.characterEncoding(UTF_8)
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.content(json))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$['#update-count-1']", equalTo(1)));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mariadb/MariaDBRSqlOperatorReadControllerTest.java
================================================
package com.homihq.db2rest.rest.mariadb;
import com.homihq.db2rest.MariaDBBaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.springframework.http.MediaType;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.core.AnyOf.anyOf;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(304)
@TestWithResources
class MariaDBRSqlOperatorReadControllerTest extends MariaDBBaseIntegrationTest {
@Test
@DisplayName("Test find with Equals Operator")
void findWithEqualsOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/film")
.accept(APPLICATION_JSON)
.param("fields", "title,description,release_year")
.param("filter", "film_id==2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1), hasSize(1))))
.andExpect(jsonPath("$[0].title", notNullValue()))
.andExpect(jsonPath("$[0].description", notNullValue()))
.andExpect(jsonPath("$[0].release_year", notNullValue()))
.andDo(document("mariadb-find-films-with-equals-operator"));
}
@Test
@DisplayName("Test find with Not Equals Operator")
void findWithNotEqualsOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/film")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "film_id!=2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(3), hasSize(3))))
.andExpect(jsonPath("$[0].film_id").value(1))
.andExpect(jsonPath("$[1].film_id").value(3))
.andExpect(jsonPath("$[2].film_id").value(4))
.andDo(document("mariadb-find-films-with-not-equals-operator"));
}
@Test
@DisplayName("Test find with Greater than Operator")
void findWithGreaterThanOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/film;desc")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "film_id=gt=2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(2), hasSize(2))))
.andExpect(jsonPath("$[0].film_id").value(3))
.andExpect(jsonPath("$[1].film_id").value(4))
.andDo(document("mariadb-find-films-with-greater-operator"));
}
@Test
@DisplayName("Test find with Greater than Equals Operator")
void findWithGreaterThanEqualsOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/film;desc")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "film_id=ge=2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(3), hasSize(3))))
.andExpect(jsonPath("$[0].film_id").value(2))
.andExpect(jsonPath("$[1].film_id").value(3))
.andExpect(jsonPath("$[2].film_id").value(4))
.andDo(document("mariadb-find-films-with-greater-equals-operator"));
}
@Test
@DisplayName("Test find with Less than Operator")
void findWithLessThanOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/film;desc")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "film_id=lt=2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1), hasSize(1))))
.andExpect(jsonPath("$[0].film_id").value(1))
.andDo(document("mariadb-find-films-with-less-operator"));
}
@Test
@DisplayName("Test find with Less than Equals Operator")
void findWithLessThanEqualsOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/film;desc")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "film_id=le=2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(2), hasSize(2))))
.andExpect(jsonPath("$[0].film_id").value(1))
.andExpect(jsonPath("$[1].film_id").value(2))
.andDo(document("mariadb-find-films-with-less-equals-operator"));
}
@Test
@DisplayName("Test find with In Operator")
void findWithInOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/film;desc")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "film_id=in=(2,3,5)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(2), hasSize(2))))
.andExpect(jsonPath("$[0].film_id").value(2))
.andExpect(jsonPath("$[1].film_id").value(3))
.andDo(document("mariadb-find-films-with-in-operator"));
}
@Test
@DisplayName("Test find with Not In Operator")
void findWithNotInOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/film;desc")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "film_id=out=(2,3,5)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(2), hasSize(2))))
.andExpect(jsonPath("$[0].film_id").value(1))
.andExpect(jsonPath("$[1].film_id").value(4))
.andDo(document("mariadb-find-films-with-not-in-operator"));
}
@Test
@DisplayName("Test find with Not In Operator (Ext)")
void findWithNotInOperatorExt() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/film;desc")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "film_id=out=(2,3,5)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(2), hasSize(2))))
.andExpect(jsonPath("$[0].film_id").value(1))
.andExpect(jsonPath("$[1].film_id").value(4))
.andDo(document("mariadb-find-films-with-not-in-operator-ext"));
}
@Test
@DisplayName("Test find with Like Operator")
void findWithLikeOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/film;desc")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "title=like=ACADEMY")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1), hasSize(1))))
.andExpect(jsonPath("$[0].film_id").value(1))
.andDo(document("mariadb-find-films-with-like-operator"));
}
@Test
@DisplayName("Test find with Starts With Operator")
void findWithStartsWithOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/film;desc")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "title=startWith=ACAD")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1), hasSize(1))))
.andExpect(jsonPath("$[0].film_id").value(1))
.andDo(document("mariadb-find-films-starts-with-operator"));
}
@Test
@DisplayName("Test find with Ends With Operator")
void findWithEndsWithOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/film;desc")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "title=endWith=DINOSAUR")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1), hasSize(1))))
.andExpect(jsonPath("$[0].film_id").value(1))
.andDo(document("mariadb-find-films-ends-with-operator"));
}
@Test
@DisplayName("Should return 4xx when using equals operator with an invalid column")
void findWithEqualsOperator_givenInvalidColumn_shouldReturn4xx() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/film")
.accept(APPLICATION_JSON)
.param("filter", "actor_id==206")
)
.andExpect(status().is4xxClientError())
.andExpect(jsonPath("$.detail").value("Failed to parse RQL - Column not found film.actor_id"))
;
}
@Test
@DisplayName("Test find with Not Like Operator")
void findWithNotLikeOperator() throws Exception {
mockMvc.perform(get( VERSION+"/mariadb/film")
.accept(MediaType.APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "title=nk=ACADEMY")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*", hasSize(3)))
.andExpect(jsonPath("$[0].film_id", equalTo(2)))
.andExpect(jsonPath("$[0].title", equalTo("ACE GOLDFINGER")))
.andExpect(jsonPath("$[1].film_id", equalTo(3)))
.andExpect(jsonPath("$[1].title", equalTo("ADAPTATION HOLES")))
.andExpect(jsonPath("$[2].film_id", equalTo(4)))
.andExpect(jsonPath("$[2].title", equalTo("AFFAIR PREJUDICE")))
.andDo(document("mariadb-find-films-with-not-like-operator"));
}
@Test
@DisplayName("Test find with Equals OR StartWith Operator")
void findWithEqualsAndStartWithCombinationalOperator() throws Exception {
mockMvc.perform(get( VERSION+"/mariadb/film")
.accept(MediaType.APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "film_id==2")
.param("filter", "title=like=ACADEMY")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*", hasSize(2)))
.andExpect(jsonPath("$[0].film_id", equalTo(1)))
.andExpect(jsonPath("$[0].title", equalTo("ACADEMY DINOSAUR")))
.andExpect(jsonPath("$[1].film_id", equalTo(2)))
.andExpect(jsonPath("$[1].title", equalTo("ACE GOLDFINGER")))
.andDo(document("mariadb-find-films-with-equals-or-like-operator"));
}
@Test
@DisplayName("Test find with Equals AND Like Operator")
void findWithEqualsAndLikeCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/film")
.accept(APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "film_id==2;title=like=ACE")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$[0].film_id", equalTo(2)))
.andExpect(jsonPath("$[0].title", equalTo("ACE GOLDFINGER")))
.andDo(document("mariadb-find-films-with-equals-and-like-operator"));
}
@Test
@DisplayName("Test find with Equals and Like and In Operator")
void findWithEqualsAndLikeAndInCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/film")
.accept(APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "film_id==2;title=like=ACE;rating=in=(G, mariadb)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$[0].film_id", equalTo(2)))
.andExpect(jsonPath("$[0].title", equalTo("ACE GOLDFINGER")))
.andDo(document("mariadb-find-films-with-equals-and-like-and-in-operator"));
}
@Test
@DisplayName("Test find with Equals OR Like OR In Operator")
void findWithEqualsOrLikeOrInCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/film")
.accept(APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "film_id==2")
.param("filter", "title=like=ACADEMY")
.param("filter", "rating=in=(G, mariadb)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(3)))
.andExpect(jsonPath("$[0].film_id", equalTo(1)))
.andExpect(jsonPath("$[0].title", equalTo("ACADEMY DINOSAUR")))
.andExpect(jsonPath("$[1].film_id", equalTo(2)))
.andExpect(jsonPath("$[1].title", equalTo("ACE GOLDFINGER")))
.andExpect(jsonPath("$[2].film_id", equalTo(4)))
.andExpect(jsonPath("$[2].title", equalTo("AFFAIR PREJUDICE")))
.andDo(document("mariadb-find-films-with-equals-or-like-or-in-operator"));
}
@Test
@DisplayName("Test find with Equals And Like And Not In Operator")
void findWithEqualsAndLikeAndNotInCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/film")
.accept(APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "film_id==2;title=like=ACE;rating=out=(G, mariadb)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isEmpty())
.andDo(document("mariadb-find-films-with-equals-and-like-and-out-operator"));
}
@Test
@DisplayName("Test find with Equals OR Like OR Not In Operator")
void findWithEqualsOrLikeOrNotInCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/film")
.accept(APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "film_id==2")
.param("filter", "title=like=ACADEMY")
.param("filter", "rating=out=(G, mariadb)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(3)))
.andExpect(jsonPath("$[0].film_id", equalTo(1)))
.andExpect(jsonPath("$[0].title", equalTo("ACADEMY DINOSAUR")))
.andExpect(jsonPath("$[1].film_id", equalTo(2)))
.andExpect(jsonPath("$[1].title", equalTo("ACE GOLDFINGER")))
.andExpect(jsonPath("$[2].film_id", equalTo(3)))
.andExpect(jsonPath("$[2].title", equalTo("ADAPTATION HOLES")))
.andDo(document("mariadb-find-films-with-equals-or-like-or-out-operator"));
}
@Test
@DisplayName("Test find with Equals and Like and In And Greater Than Equals Operator")
void findWithEqualsAndLikeAndInAbdGreaterThanEualsCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/film")
.accept(APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "film_id==2;title=like=ACE;rating=in=(G, mariadb);language_id=ge=1")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$[0].film_id", equalTo(2)))
.andExpect(jsonPath("$[0].title", equalTo("ACE GOLDFINGER")))
.andDo(document("mariadb-find-films-with-equals-and-like-and-in-and-greater-equal-operator"));
}
@Test
@DisplayName("Test find with Equals and Like and In And Greater Than Operator")
void findWithEqualsAndLikeAndInAbdGreaterThanCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/film")
.accept(APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "film_id==2;title=like=ACE;rating=in=(G, mariadb);language_id=gt=1")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*", hasSize(0)))
.andDo(document("mariadb-find-films-with-equals-and-like-and-in-and-greater-operator"));
}
@Test
@DisplayName("Test find with Equals and Like and In And Less Than Equals Operator")
void findWithEqualsAndLikeAndInAndLessThanEqualsCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/film")
.accept(APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "film_id==2;title=like=ACE;rating=in=(G, mariadb);language_id=le=2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$[0].film_id", equalTo(2)))
.andExpect(jsonPath("$[0].title", equalTo("ACE GOLDFINGER")))
.andDo(document("mariadb-find-films-with-equals-and-like-and-in-and-less-equal-operator"));
}
@Test
@DisplayName("Test find with Equals and Like and In And Less Than Operator")
void findWithEqualsAndLikeAndInAndLessThanCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/film")
.accept(APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "film_id==2;title=like=ACE;rating=in=(G, mariadb);language_id=lt=1")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isEmpty())
.andExpect(jsonPath("$.*", hasSize(0)))
.andDo(document("mariadb-find-films-with-equals-and-like-and-in-and-less-operator"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mariadb/MariaDBReadControllerDefaultFetchLimitTest.java
================================================
package com.homihq.db2rest.rest.mariadb;
import com.homihq.db2rest.MariaDBBaseIntegrationTest;
import org.junit.jupiter.api.*;
import org.springframework.http.MediaType;
import org.springframework.test.context.TestPropertySource;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.core.AnyOf.anyOf;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(305)
@TestPropertySource(properties = {"db2rest.defaultFetchLimit=5"})
public class MariaDBReadControllerDefaultFetchLimitTest extends MariaDBBaseIntegrationTest {
@Test
@DisplayName("Get all with default fetch limit set to 5")
void findAllPersonsWithDefaultFetchLimit5() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/person")
.accept(MediaType.APPLICATION_JSON)
)
.andExpect(status().isOk())
.andExpect(jsonPath("$", anyOf(hasSize(5))))
.andDo(document("mariadb-find-all-persons-with-default-fetch-limit-5"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mariadb/MariaDBReadControllerTest.java
================================================
package com.homihq.db2rest.rest.mariadb;
import com.homihq.db2rest.MariaDBBaseIntegrationTest;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.springframework.http.MediaType;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.core.AnyOf.anyOf;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(301)
class MariaDBReadControllerTest extends MariaDBBaseIntegrationTest {
@Test
@DisplayName("Test find all films - all columns.")
void findAllFilms() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/film")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
//.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
//.andExpect(jsonPath("$.*", hasSize(4)))
.andExpect(jsonPath("$.*", anyOf(hasSize(4), hasSize(9), hasSize(8))))
.andExpect(jsonPath("$[0].*", hasSize(14)))
.andDo(document("mariadb-get-all-films-all-columns"));
}
@Test
@DisplayName("Test find all films - 3 columns")
void findAllFilmsWithThreeCols() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/film")
.contentType(APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)
.param("fields", "title,description,release_year")
)
//.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(4), hasSize(9), hasSize(8))))
.andExpect(jsonPath("$[0].*", hasSize(3)))
.andDo(document("mariadb-find-all-films-3-columns"));
}
@Test
@DisplayName("Test find all films - with column alias")
void findAllFilmsWithColumnAlias() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/film")
.contentType(APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)
.param("fields", "title,description,release_year:releaseYear")
)
//.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(4), hasSize(9), hasSize(8))))
.andExpect(jsonPath("$[0].title", notNullValue()))
.andExpect(jsonPath("$[0].description", notNullValue()))
.andExpect(jsonPath("$[0].releaseYear", notNullValue()))
.andDo(document("mariadb-find-all-films-with-column-alias"));
}
@Test
@DisplayName("Get one")
void findOneFilm() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/film/one")
.accept(MediaType.APPLICATION_JSON)
.param("fields", "title")
.param("filter", "film_id==1"))
.andExpect(status().isOk())
//.andDo(print())
.andDo(document("mariadb-get-on-film"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mariadb/MariaDBTemplateControllerTest.java
================================================
package com.homihq.db2rest.rest.mariadb;
import com.homihq.db2rest.MariaDBBaseIntegrationTest;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.core.AnyOf.anyOf;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(309)
@DisplayName("Parameterized SQL template")
class MariaDBTemplateControllerTest extends MariaDBBaseIntegrationTest {
public final static int ID = 1;
@Test
@DisplayName("Test find all films with sql template")
void findAllFilms() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/sql/select_all")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(4), hasSize(9), hasSize(8))))
.andExpect(jsonPath("$[0].*", hasSize(14)))
.andDo(document("mariadb-template-get-all-films-all-columns"));
}
@Test
@DisplayName("Find film by id with request param")
void findFilmByID() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/sql/select_by_id")
.param("film_id", String.valueOf(ID))
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(print())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1))))
.andDo(document("mariadb-template-get-film-by-id-with-params"));
}
@Test
@DisplayName("Find film by id with headers")
void findFilmByIDWithHeader() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/sql/select_by_id")
.header("film_id", String.valueOf(ID))
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(print())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1))))
.andDo(document("mariadb-template-get-film-by-id-with-headers"));
}
@Test
@DisplayName("Find film by id with custom path")
void findFilmByIDWithPath() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/sql/select_by_id/" + ID)
.header("paths", "film_id")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(print())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1))))
.andDo(document("mariadb-template-get-film-by-id-with-user-path"));
}
@Test
@DisplayName("Failed to find film by id without provided param")
void findFilmByIDWithRequiredConstraint() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/sql/select_by_id_is_required")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().is4xxClientError())
.andDo(document("mariadb-template-get-film-by-id-with-required-constraint"));
}
@Test
@DisplayName("Conditional render: select all when no request params")
void selectWithConditionalRenderNoRequestParams() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/sql/conditional_render_and_op")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(4), hasSize(9), hasSize(8))))
.andExpect(jsonPath("$[0].*", hasSize(14)))
.andDo(document("mariadb-template-conditional-render-no-request-params"));
}
@Test
@DisplayName("Conditional render: select render one condition")
void selectWithConditionalRenderWithID() throws Exception {
var id = 4;
mockMvc.perform(get(VERSION + "/mariadb/sql/conditional_render_and_op")
.param("film_id", String.valueOf(id))
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1))))
.andExpect(jsonPath("$[0].film_id").value(id))
.andDo(document("mariadb-template-conditional-render-with-id-condition"));
}
@Test
@DisplayName("Conditional render: render both and operations")
void selectWithConditionalRenderWithField() throws Exception {
var id = 4;
var rating = "G";
mockMvc.perform(get(VERSION + "/mariadb/sql/conditional_render_and_op")
.param("film_id", String.valueOf(id))
.param("rating", rating)
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1))))
.andExpect(jsonPath("$[0].film_id").value(id))
.andExpect(jsonPath("$[0].rating").value(rating))
.andDo(document("mariadb-template-conditional-render-render-both-and-operations"));
}
@Test
@DisplayName("Conditional render join: skip render join, select film by id")
void selectWithConditionalRenderJoinWithoutInput() throws Exception {
var film_id = 1;
mockMvc.perform(get(VERSION + "/mariadb/sql/conditional_render_join")
.param("film_id", String.valueOf(film_id))
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1))))
.andExpect(jsonPath("$[0].film_id").value(film_id))
.andDo(document("mariadb-template-conditional-render-join-skip-render"));
}
@Test
@DisplayName("Conditional render join: execute rendered join")
void selectWithConditionalRenderJoin() throws Exception {
var film_id = 1;
var language_id = 1;
mockMvc.perform(get(VERSION + "/mariadb/sql/conditional_render_join")
.param("film_id", String.valueOf(film_id))
.param("language_id", String.valueOf(language_id))
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1))))
.andExpect(jsonPath("$[0].film_id").value(film_id))
.andExpect(jsonPath("$[0].language_name").value("English"))
.andDo(document("mariadb-template-conditional-render-join"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mariadb/MariaDBUpdateControllerTest.java
================================================
package com.homihq.db2rest.rest.mariadb;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.MariaDBBaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.equalTo;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.patch;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(370)
@TestWithResources
class MariaDBUpdateControllerTest extends MariaDBBaseIntegrationTest {
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@GivenJsonResource("/testdata/UPDATE_FILM_REQUEST.json")
Map UPDATE_FILM_REQUEST;
@GivenJsonResource("/testdata/UPDATE_NON_EXISTING_FILM_REQUEST.json")
Map UPDATE_NON_EXISTING_FILM_REQUEST;
@GivenJsonResource("/testdata/UPDATE_NON_EXISTING_TABLE.json")
Map UPDATE_NON_EXISTING_TABLE;
@GivenJsonResource("/testdata/UPDATE_FILMS_REQUEST.json")
Map UPDATE_FILMS_REQUEST;
@Test
@DisplayName("Update an existing film")
void updateExistingFilm() throws Exception {
mockMvc.perform(patch(VERSION + "/mariadb/film")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("filter", "title==\"ACADEMY DINOSAUR\"")
.content(objectMapper.writeValueAsString(UPDATE_FILM_REQUEST))
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", equalTo(1)))
//.andDo(print())
.andDo(document("mariadb-update-existing-film"));
}
@Test
@DisplayName("Update a non-existing film")
void updateNonExistingFilm() throws Exception {
mockMvc.perform(patch(VERSION + "/mariadb/film")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("filter", "title==\"BAAHUBALI\"")
.content(objectMapper.writeValueAsString(UPDATE_NON_EXISTING_FILM_REQUEST))
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", equalTo(0)))
//.andDo(print())
.andDo(document("mariadb-update-non-existing-film"));
}
@Test
@DisplayName("Update non-existing table")
void updateNonExistingTable() throws Exception {
mockMvc.perform(patch(VERSION + "/mariadb/unknown_table")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("filter", "sample_col==\"sample value 1\"")
.content(objectMapper.writeValueAsString(UPDATE_NON_EXISTING_TABLE))
)
.andExpect(status().isNotFound())
//.andDo(print())
.andDo(document("mariadb-update-non-existing-table"));
}
@Test
@DisplayName("Updating multiple films")
void updateMultipleColumns() throws Exception {
mockMvc.perform(patch(VERSION + "/mariadb/film")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("filter", "rating==\"G\"")
.content(objectMapper.writeValueAsString(UPDATE_FILMS_REQUEST))
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", equalTo(2)))
//.andDo(print())
.andDo(document("mariadb-update-multiple-films"));
}
//TODO - Add a test to update date field.
//TODO - Greater than, less than , equal to , between test for date
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mariadb/MariadbDateTimeAllTest.java
================================================
package com.homihq.db2rest.rest.mariadb;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.MariaDBBaseIntegrationTest;
import com.homihq.db2rest.rest.DateTimeUtil;
import com.jayway.jsonpath.JsonPath;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.HashMap;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.patch;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(392)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class MariadbDateTimeAllTest extends MariaDBBaseIntegrationTest {
private final String dateTime = "2024-03-15T10:30:45.000";
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@Test
@Order(1)
@DisplayName("Test Create a actor with datetime fields")
void createActorWithDateTimeFields() throws Exception {
// Prepare the request with datetime fields
Map actorRequestWithDateTime = new HashMap<>();
actorRequestWithDateTime.put("first_name", "Collective");
actorRequestWithDateTime.put("last_name", "Unconscious");
actorRequestWithDateTime.put("last_update", "2020-03-15T14:30:45.000");
mockMvc.perform(post(VERSION + "/mariadb/actor")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(actorRequestWithDateTime)))
.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
.andDo(document("mariadb-create-an-actor-with-datetime"));
}
@Test
@Order(1)
@DisplayName("Test Create an actor with error timestamp field")
void createActorWithErrorDateTimeField() throws Exception {
Map actorRequestWithErrorDateTime = new HashMap<>();
actorRequestWithErrorDateTime.put("first_name", "Hero");
actorRequestWithErrorDateTime.put("last_name", "shadow");
actorRequestWithErrorDateTime.put("last_update", "2023-15-35T14:75:90");
mockMvc.perform(post(VERSION + "/mariadb/actor")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(actorRequestWithErrorDateTime)))
.andDo(print())
.andExpect(status().isBadRequest())
.andDo(document("mariadb-create-an-actor-with-error-timestamp"));
}
@Test
@Order(2)
@DisplayName("Test update an actor with datetime field")
void updateActorWithDateTimeField() throws Exception {
// Prepare the request with datetime fields
Map updateActorRequestWithDateTime = new HashMap<>();
updateActorRequestWithDateTime.put("last_update", dateTime);
mockMvc.perform(patch(VERSION + "/mariadb/actor")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.param("filter", "last_name == Unconscious")
.content(objectMapper.writeValueAsString(updateActorRequestWithDateTime)))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", equalTo(1)))
.andDo(document("mariadb-update-an-actor-with-datetime"));
}
@Test
@Order(3)
@DisplayName("Test get an actor with datetime fields")
void getActorWithDateTimeFields() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/actor")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.param("filter", "first_name == Collective"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("[0].last_name", equalTo("Unconscious")))
.andDo(result -> assertEquals(dateTime, DateTimeUtil.utcToLocalTimestampString(result)))
.andDo(document("mariadb-get-an-actor-with-datetime"));
}
@Test
@Order(3)
@DisplayName("Test get an actor filter by timestamp")
void getActorFilterByTimeStamp() throws Exception {
mockMvc.perform(get(VERSION + "/mariadb/actor")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.param("filter", "last_update == \"2024-03-15T10:30:45.00Z\""))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("[0].last_name", equalTo("Unconscious")))
.andDo(result -> assertEquals(dateTime, DateTimeUtil.utcToLocalTimestampString(result)))
.andDo(document("mariadb-get-an-actor-filter-by-timestamp"));
}
@Test
@Order(4)
@DisplayName("Test delete an actor by timestamp")
void deleteActorByTimeStamp() throws Exception {
mockMvc.perform(delete(VERSION + "/mariadb/actor")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.param("filter", "last_update == \"2024-03-15T10:30:45.00Z\""))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.rows", equalTo(1)))
.andDo(document("mariadb-delete-an-actor-by-timestamp"));
}
@ParameterizedTest
@MethodSource("isoDateTimeFormats")
@Order(5)
@DisplayName("Test ISO Date Time formats")
void createActorWithIsoDateTimeFormats(String isoDateTime) throws Exception {
// Prepare the request with datetime fields
Map actorRequestWithDateTime = new HashMap<>();
actorRequestWithDateTime.put("first_name", "Graeme");
actorRequestWithDateTime.put("last_name", "Smith");
actorRequestWithDateTime.put("last_update", isoDateTime);
var result = mockMvc.perform(post(VERSION + "/mariadb/actor")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(actorRequestWithDateTime)))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
.andDo(document("mariadb-create-an-actor-with-datetime"))
.andReturn();
var pk = JsonPath.read(result.getResponse().getContentAsString(), "$.keys.insert_id");
assertTrue(deleteRow("actor", "actor_id", (int) pk));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mssql/MsSQLBaseIntegrationTest.java
================================================
package com.homihq.db2rest.rest.mssql;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.BaseIntegrationTest;
import com.homihq.db2rest.MsSQLServerContainerConfiguration;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Import;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ActiveProfiles;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
@Import(MsSQLServerContainerConfiguration.class)
@ActiveProfiles("it-mssql")
class MsSQLBaseIntegrationTest extends BaseIntegrationTest {
protected static final String TEST_JSON_FOLDER = "/testdata";
protected static final String DB_NAME = "mssql";
@Autowired
private JdbcTemplate jdbcTemplate;
@WithJacksonMapper
protected ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule());
protected String getPrefixApiUrl() {
return VERSION + "/" + DB_NAME;
}
protected boolean deleteRow(String table, String column, int id) {
var query = "DELETE FROM " + table + " WHERE " + column + " = ?";
return jdbcTemplate.update(query, id) == 1;
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mssql/MsSQLBasicJoinControllerTest.java
================================================
package com.homihq.db2rest.rest.mssql;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import java.util.List;
import java.util.Map;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.nullValue;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@Order(501)
@TestWithResources
class MsSQLBasicJoinControllerTest extends MsSQLBaseIntegrationTest {
@GivenJsonResource(TEST_JSON_FOLDER + "/LEFT_JOIN.json")
List> LEFT_JOIN;
@GivenJsonResource(TEST_JSON_FOLDER + "/RIGHT_JOIN.json")
List> RIGHT_JOIN;
@Test
@DisplayName("Left Join")
void leftJoin() throws Exception {
mockMvc.perform(post(getPrefixApiUrl() + "/users/_expand")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(LEFT_JOIN))
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(4)))
.andExpect(jsonPath("$[0].*", hasSize(10)))
.andExpect(jsonPath("$[0].auid", equalTo(1)))
.andExpect(jsonPath("$[0].apid", equalTo(1)))
.andExpect(jsonPath("$[1].auid", equalTo(2)))
.andExpect(jsonPath("$[1].apid", nullValue()))
.andExpect(jsonPath("$[3].auid", equalTo(6)))
.andExpect(jsonPath("$[3].apid", nullValue()))
.andExpect(jsonPath("$[3].firstname", nullValue()))
.andDo(document(DB_NAME + "-left-join"));
}
@Test
@DisplayName("Right Join")
void rightJoin() throws Exception {
mockMvc.perform(post(getPrefixApiUrl() + "/users/_expand")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(RIGHT_JOIN))
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(4)))
.andExpect(jsonPath("$[0].*", hasSize(10)))
.andExpect(jsonPath("$[0].auid", equalTo(1)))
.andExpect(jsonPath("$[0].apid", equalTo(1)))
.andExpect(jsonPath("$[0].username", equalTo("admin")))
.andExpect(jsonPath("$[0].firstname", equalTo("Jack")))
.andExpect(jsonPath("$[1].apid", equalTo(2)))
.andExpect(jsonPath("$[1].auid", equalTo(3)))
.andExpect(jsonPath("$[1].username", nullValue()))
.andExpect(jsonPath("$[1].firstname", equalTo("Tom")))
.andExpect(jsonPath("$[2].auid", equalTo(5)))
.andExpect(jsonPath("$[2].apid", equalTo(4)))
.andExpect(jsonPath("$[2].username", nullValue()))
.andExpect(jsonPath("$[2].firstname", equalTo("Bill")))
.andDo(document(DB_NAME + "-right-join"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mssql/MsSQLBulkCreateControllerTest.java
================================================
package com.homihq.db2rest.rest.mssql;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.GivenTextResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import java.util.List;
import java.util.Map;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasSize;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@Order(503)
@TestWithResources
class MsSQLBulkCreateControllerTest extends MsSQLBaseIntegrationTest {
@GivenJsonResource(TEST_JSON_FOLDER + "/BULK_CREATE_FILM_REQUEST.json")
List> BULK_CREATE_FILM_REQUEST;
@GivenJsonResource(TEST_JSON_FOLDER + "/BULK_CREATE_FILM_BAD_REQUEST.json")
List> BULK_CREATE_FILM_BAD_REQUEST;
@GivenTextResource(TEST_JSON_FOLDER + "/CREATE_FILM_REQUEST_CSV.csv")
String CREATE_FILM_REQUEST_CSV;
@GivenTextResource(TEST_JSON_FOLDER + "/CREATE_FILM_BAD_REQUEST_CSV.csv")
String CREATE_FILM_BAD_REQUEST_CSV;
@GivenJsonResource(TEST_JSON_FOLDER + "/BULK_CREATE_DIRECTOR_REQUEST.json")
List> BULK_CREATE_DIRECTOR_REQUEST;
@GivenJsonResource(TEST_JSON_FOLDER + "/BULK_CREATE_DIRECTOR_BAD_REQUEST.json")
List> BULK_CREATE_DIRECTOR_BAD_REQUEST;
@GivenJsonResource(TEST_JSON_FOLDER + "/BULK_CREATE_REVIEW_REQUEST.json")
List> BULK_CREATE_REVIEW_REQUEST;
@Test
@DisplayName("Bulk create films with JSON type.")
void bulkCreateFilmsWithJsonType() throws Exception {
mockMvc.perform(post(getPrefixApiUrl() + "/film/bulk")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(BULK_CREATE_FILM_REQUEST))
)
.andExpect(status().isCreated())
.andDo(print())
.andExpect(jsonPath("$.rows").isArray())
.andExpect(jsonPath("$.rows", hasSize(2)))
.andExpect(jsonPath("$.rows", hasItem(1)))
.andDo(document(DB_NAME + "-bulk-create-films-with-actor.json-type"));
}
@Test
@DisplayName("Bulk create films with CSV type.")
void bulkCreateFilmsWithCsvType() throws Exception {
mockMvc.perform(post(getPrefixApiUrl() + "/film/bulk")
.contentType(new MediaType("text", "csv"))
.content(CREATE_FILM_REQUEST_CSV))
.andExpect(status().isCreated())
.andDo(print())
.andExpect(jsonPath("$.rows").isArray())
.andExpect(jsonPath("$.rows", hasSize(2)))
.andExpect(jsonPath("$.rows", hasItem(1)))
.andDo(document(DB_NAME + "-bulk-create-films-with-csv-type"));
}
@Test
@DisplayName("Failed to bulk create films with CSV type.")
void bulkCreateFilmsWithCsvTypeError() throws Exception {
mockMvc.perform(post(getPrefixApiUrl() + "/film/bulk")
.contentType(new MediaType("text", "csv"))
.accept(APPLICATION_JSON)
.content(CREATE_FILM_BAD_REQUEST_CSV))
.andExpect(status().isBadRequest())
.andDo(print())
.andDo(document(DB_NAME + "-bulk-create-films-with-csv-type-error"));
}
@Test
@DisplayName("Failed to bulk create films with JSON type.")
void bulkCreateFilmsWithJsonTypeError() throws Exception {
mockMvc.perform(post(getPrefixApiUrl() + "/film/bulk")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(BULK_CREATE_FILM_BAD_REQUEST))
)
.andExpect(status().isBadRequest())
.andDo(print())
.andDo(document(DB_NAME + "-bulk-create-films-with-actor.json-type-error"));
}
@Test
@DisplayName("Bulk create directors.")
void bulkCreateDirectors() throws Exception {
mockMvc.perform(post(getPrefixApiUrl() + "/director/bulk")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("tsIdEnabled", "true")
.content(objectMapper.writeValueAsString(BULK_CREATE_DIRECTOR_REQUEST))
)
.andDo(print())
.andExpect(status().isCreated())
.andDo(document(DB_NAME + "-bulk-create-directors"));
}
@Test
@DisplayName("Bulk create directors with the wrong tsid type.")
void bulkCreateDirectorWithWrongTsidType() throws Exception {
mockMvc.perform(post(getPrefixApiUrl() + "/director/bulk")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.param("tsid", "director_id")
.param("tsidType", "string")
.content(objectMapper.writeValueAsString(BULK_CREATE_DIRECTOR_BAD_REQUEST))
)
.andExpect(status().isBadRequest())
.andDo(print())
.andDo(document(DB_NAME + "-bulk-create-directors-with-wrong-tsid-type"));
}
@Test
@DisplayName("Create reviews with default tsid type.")
void bulkCreateReviewWithDefaultTsidType() throws Exception {
mockMvc.perform(post(getPrefixApiUrl() + "/review/bulk")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.param("tsIdEnabled", "true")
.content(objectMapper.writeValueAsString(BULK_CREATE_REVIEW_REQUEST))
)
.andExpect(status().isCreated())
.andDo(print())
.andDo(document(DB_NAME + "-bulk-create-reviews-with-default-tsid-type"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mssql/MsSQLCountControllerTest.java
================================================
package com.homihq.db2rest.rest.mssql;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import static org.hamcrest.Matchers.equalTo;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@Order(501)
class MsSQLCountControllerTest extends MsSQLBaseIntegrationTest {
@Test
@DisplayName("The count of employees")
void employeesCount() throws Exception {
mockMvc.perform(get(getPrefixApiUrl() + "/employee/count")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(print())
.andExpect(jsonPath("$.count", equalTo(2)))
.andDo(document(DB_NAME + "-employees-count"));
}
@Test
@DisplayName("The count of films")
void filmsCount() throws Exception {
mockMvc.perform(get(getPrefixApiUrl() + "/film/count")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(print())
.andExpect(jsonPath("$.count", equalTo(4)))
.andDo(document(DB_NAME + "-films-count"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mssql/MsSQLCreateControllerTest.java
================================================
package com.homihq.db2rest.rest.mssql;
import com.jayway.jsonpath.JsonPath;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.Map;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@Order(502)
@TestWithResources
class MsSQLCreateControllerTest extends MsSQLBaseIntegrationTest {
@GivenJsonResource(TEST_JSON_FOLDER + "/CREATE_FILM_REQUEST.json")
Map CREATE_FILM_REQUEST;
@GivenJsonResource(TEST_JSON_FOLDER + "/CREATE_FILM_REQUEST_ERROR.json")
Map CREATE_FILM_REQUEST_ERROR;
@GivenJsonResource(TEST_JSON_FOLDER + "/CREATE_VANITY_VAN_REQUEST.json")
Map CREATE_VANITY_VAN_REQUEST;
@GivenJsonResource(TEST_JSON_FOLDER + "/CREATE_DIRECTOR_REQUEST.json")
Map CREATE_DIRECTOR_REQUEST;
@GivenJsonResource(TEST_JSON_FOLDER + "/CREATE_FILM_REQUEST_MISSING_PAYLOAD.json")
Map CREATE_FILM_REQUEST_MISSING_PAYLOAD;
@Autowired
private JdbcTemplate jdbcTemplate;
@Test
@DisplayName("Create a film.")
void createFilm() throws Exception {
mockMvc.perform(post(getPrefixApiUrl() + "/film")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST))
)
.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
.andExpect(jsonPath("$.keys.GENERATED_KEYS").exists())
.andExpect(jsonPath("$.keys.GENERATED_KEYS", equalTo(7)))
.andDo(document(DB_NAME + "-create-a-film"));
}
@Test
@DisplayName("Failed to create a film.")
void createFilmError() throws Exception {
mockMvc.perform(post(getPrefixApiUrl() + "/film")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST_ERROR)))
.andDo(print())
.andExpect(status().isBadRequest())
.andDo(document(DB_NAME + "-create-film-error"));
}
@Test
@DisplayName("Create an item in non existent table.")
void createItemNonExistentTable() throws Exception {
mockMvc.perform(post(getPrefixApiUrl() + "/films")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST)))
.andExpect(status().isNotFound())
.andDo(print())
.andDo(document(DB_NAME + "-create-item-in-non-existing-table"));
}
@Test
@DisplayName("Create a director with TSID enabled")
void createDirectorWithTSIDEnabled() throws Exception {
mockMvc.perform(post(getPrefixApiUrl() + "/director")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.param("tsIdEnabled", "true")
.content(objectMapper.writeValueAsString(CREATE_DIRECTOR_REQUEST)))
.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
.andDo(document(DB_NAME + "-create-a-director-tsid-enabled"));
}
@Test
@DisplayName("Create a director with TSID explicitly OFF")
void createDirectorWithTSIDOff() throws Exception {
mockMvc.perform(post(getPrefixApiUrl() + "/director")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.param("tsIdEnabled", "false")
.content(objectMapper.writeValueAsString(CREATE_DIRECTOR_REQUEST)))
.andExpect(status().isBadRequest())
.andDo(print())
.andDo(document(DB_NAME + "-create-a-director-with-tsid-OFF"));
}
@Test
@DisplayName("Test Create a Vanity Van - with varchar tsid type")
void createVanityVanWithVarcharTsIdType() throws Exception {
mockMvc.perform(post(getPrefixApiUrl() + "/vanity_van")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.param("tsIdEnabled", "true")
.content(objectMapper.writeValueAsString(CREATE_VANITY_VAN_REQUEST)))
.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
.andDo(document(DB_NAME + "-create-a-vanity-van-tsid-varchar"));
}
@Test
@DisplayName("Create a film with subset of columns")
void createFilmWithSubsetOfColumns() throws Exception {
var result = mockMvc.perform(post(getPrefixApiUrl() + "/film")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.queryParam("columns", "title,description,language_id")
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST)))
.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
.andExpect(jsonPath("$.keys.GENERATED_KEYS").exists())
.andExpect(jsonPath("$.keys.GENERATED_KEYS").isNumber())
.andDo(document(DB_NAME + "-create-a-film"))
.andReturn();
int pk = JsonPath.read(result.getResponse().getContentAsString(), "$.keys.GENERATED_KEYS");
mockMvc.perform(get(getPrefixApiUrl() + "/film")
.accept(APPLICATION_JSON)
.queryParam("fields", "title,release_year")
.queryParam("filter", String.format("film_id==%s", pk)))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$[0].title", equalTo("Dunki")))
.andExpect(jsonPath("$[0].release_year").doesNotExist());
// cleanup data
assertTrue(deleteRow(pk));
}
@Test
@DisplayName("Ignore if columns parameter is blank")
void shouldIgnoreWhenColumnsQueryParamIsEmpty() throws Exception {
var result = mockMvc.perform(post(getPrefixApiUrl() + "/film")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.queryParam("columns", "")
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST)))
.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
.andExpect(jsonPath("$.keys").exists())
.andDo(document(DB_NAME + "-create-a-film"))
.andReturn();
int pk = JsonPath.read(result.getResponse().getContentAsString(), "$.keys.GENERATED_KEYS");
mockMvc.perform(get(getPrefixApiUrl() + "/film")
.accept(APPLICATION_JSON)
.queryParam("select", "title,release_year")
.queryParam("filter", String.format("film_id==%s", pk)))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$[0].title", equalTo("Dunki")))
.andExpect(jsonPath("$[0].release_year", equalTo("2023")));
// cleanup data
assertTrue(deleteRow(pk));
}
@Test
@DisplayName("Column is present in columns param but not in payload")
void columnIsPresentInColumnsQueryParamButNotInPayload() throws Exception {
mockMvc.perform(post(getPrefixApiUrl() + "/film")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.queryParam("columns", "title,description,language_id")
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST_MISSING_PAYLOAD))) //description is not in payload will be set to null
.andExpect(status().isBadRequest())
.andDo(print())
.andDo(document(DB_NAME + "-create-a-film-missing-payload-attribute-error"))
.andReturn();
}
@Test
@DisplayName("Column violates not-null constraint")
void columnViolatesNotNullConstraint() throws Exception {
mockMvc.perform(post(getPrefixApiUrl() + "/film")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.queryParam("columns", "title,description")
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST)))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.detail",
containsString("Cannot insert the value NULL into column 'language_id'")))
.andDo(print())
.andDo(document(DB_NAME + "-create-a-film-not-null-constraint"));
}
private boolean deleteRow(int id) {
var query = "DELETE FROM film WHERE film_id = ?";
return jdbcTemplate.update(query, id) == 1;
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mssql/MsSQLCrossJoinControllerTest.java
================================================
package com.homihq.db2rest.rest.mssql;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import java.util.List;
import java.util.Map;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@Order(501)
@TestWithResources
class MsSQLCrossJoinControllerTest extends MsSQLBaseIntegrationTest {
@GivenJsonResource(TEST_JSON_FOLDER + "/CROSS_JOIN_USERS_MSSQL.json")
List> CROSS_JOIN_USERS;
@GivenJsonResource(TEST_JSON_FOLDER + "/CROSS_JOIN_TOPS_MSSQL.json")
List> CROSS_JOIN_TOPS;
@Test
@DisplayName("Cross Join Users")
void crossJoinUsers() throws Exception {
mockMvc.perform(post(getPrefixApiUrl() + "/users/_expand")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(CROSS_JOIN_USERS))
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(16)))
.andExpect(jsonPath("$[0].*", hasSize(10)))
.andExpect(jsonPath("$[0].auid", equalTo(1)))
.andExpect(jsonPath("$[0].apid", equalTo(1)))
.andExpect(jsonPath("$[0].firstname", equalTo("Jack")))
.andExpect(jsonPath("$[1].auid", equalTo(2)))
.andExpect(jsonPath("$[1].apid", equalTo(1)))
.andExpect(jsonPath("$[1].firstname", equalTo("Jack")))
.andDo(document(DB_NAME + "-cross-join-users"));
}
@Test
@DisplayName("Cross Join Tops")
void crossJoinTops() throws Exception {
mockMvc.perform(post(getPrefixApiUrl() + "/tops/_expand")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(CROSS_JOIN_TOPS))
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(9)))
.andExpect(jsonPath("$[0].*", hasSize(6)))
.andExpect(jsonPath("$[0].top_item", equalTo("sweater")))
.andExpect(jsonPath("$[0].bottom_item", equalTo("jeans")))
.andExpect(jsonPath("$[0].color", equalTo("red")))
.andExpect(jsonPath("$[0].botColor", equalTo("blue")))
.andDo(document(DB_NAME + "-cross-join-tops"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mssql/MsSQLDateTimeAllTest.java
================================================
package com.homihq.db2rest.rest.mssql;
import com.jayway.jsonpath.JsonPath;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.TestClassOrder;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.HashMap;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(506)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class MsSQLDateTimeAllTest extends MsSQLBaseIntegrationTest {
@ParameterizedTest
@MethodSource("isoDateTimeFormats")
@Order(1)
@DisplayName("Test ISO Date Time formats")
void createActorWithIsoDateTimeFormats(String isoDateTime) throws Exception {
// Prepare the request with datetime fields
Map actorRequestWithDateTime = new HashMap<>();
actorRequestWithDateTime.put("first_name", "Graeme");
actorRequestWithDateTime.put("last_name", "Smith");
actorRequestWithDateTime.put("last_update", isoDateTime);
var result = mockMvc.perform(post(VERSION + "/mssql/actor")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(actorRequestWithDateTime)))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
.andDo(document("mssql-create-an-actor-with-datetime"))
.andReturn();
var pk = JsonPath.read(result.getResponse().getContentAsString(), "$.keys.GENERATED_KEYS");
assertTrue(deleteRow("actor", "actor_id", (int) pk));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mssql/MsSQLDeleteControllerTest.java
================================================
package com.homihq.db2rest.rest.mssql;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@Order(505)
class MsSQLDeleteControllerTest extends MsSQLBaseIntegrationTest {
@Test
@DisplayName("Delete a director")
void deleteSingleRecord() throws Exception {
mockMvc.perform(delete(getPrefixApiUrl() + "/director")
.accept(APPLICATION_JSON)
.param("filter", "first_name==\"Alex\""))
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", equalTo(1)))
.andDo(print())
.andDo(document(DB_NAME + "-delete-a-director"));
}
@Test
@DisplayName("Failed to delete all records while allowSafeDelete=true")
void failedDeleteAllRecordsWithAllowSafeDeleteTrue() throws Exception {
mockMvc.perform(delete(getPrefixApiUrl() + "/director")
.accept(APPLICATION_JSON))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.detail",
containsString("Invalid delete operation , safe set to true")))
.andDo(print())
.andDo(document(DB_NAME + "-delete-all-director"));
}
@Test
@DisplayName("Failed to delete with column does not exist")
void failedDeleteWithInvalidColumnName() throws Exception {
mockMvc.perform(delete(getPrefixApiUrl() + "/director")
.accept(APPLICATION_JSON)
.param("filter", "_name==\"Alex\""))
.andExpect(status().isNotFound())
.andExpect(jsonPath("$.detail",
containsString("Column not found director._name")))
.andDo(print())
.andDo(document(DB_NAME + "-column-not-exists"));
}
@Test
@DisplayName("Failed to delete with foreign key constraint violation")
void failedDeleteWithForeignKeyConstraintViolation() throws Exception {
mockMvc.perform(delete(getPrefixApiUrl() + "/language")
.accept(APPLICATION_JSON)
.param("filter", "name==\"ENGLISH\""))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.detail",
containsString("The DELETE statement conflicted with the REFERENCE constraint")))
.andDo(print())
.andDo(document(DB_NAME + "-constraint-violation"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mssql/MsSQLDeleteWithNotAllowedSafeDeleteControllerTest.java
================================================
package com.homihq.db2rest.rest.mssql;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.springframework.test.context.TestPropertySource;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@Order(505)
@TestPropertySource(properties = {"db2rest.allowSafeDelete=false"})
class MsSQLDeleteWithNotAllowedSafeDeleteControllerTest extends MsSQLBaseIntegrationTest {
@Test
@DisplayName("Delete all records with allowSafeDelete=false")
void deleteAllWithAllowSafeDeleteFalse() throws Exception {
mockMvc.perform(delete(getPrefixApiUrl() + "/country")
.accept(APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", Matchers.equalTo(4)))
.andDo(document(DB_NAME + "-delete-a-director"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mssql/MsSQLExistsControllerTest.java
================================================
package com.homihq.db2rest.rest.mssql;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import java.util.List;
import java.util.Map;
import static org.hamcrest.Matchers.equalTo;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@Order(501)
@TestWithResources
class MsSQLExistsControllerTest extends MsSQLBaseIntegrationTest {
@GivenJsonResource(TEST_JSON_FOLDER + "/INNER_JOIN_MULTI_TABLE.json")
List> INNER_JOIN_MULTI_TABLE;
@Test
@DisplayName("Actor exists by first_name")
void existsActorByFirstName() throws Exception {
mockMvc.perform(get(getPrefixApiUrl() + "/actor/exists")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.param("filter", "first_name==JENNIFER"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.exists", equalTo(true)))
.andDo(document(DB_NAME + "-actor-exists-by-first_name"));
}
@Test
@DisplayName("Actor exists with unknown name")
void existsByUnknownName() throws Exception {
mockMvc.perform(get(getPrefixApiUrl() + "/actor/exists")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.param("filter", "first_name==Unknown"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.exists", equalTo(false)))
.andDo(document(DB_NAME + "-actor-exists-by-unknown-name"));
}
@Test
@DisplayName("Actor exists with inner name")
void existsInnerJoin() throws Exception {
mockMvc.perform(post(getPrefixApiUrl() + "/film/exists/_expand")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(INNER_JOIN_MULTI_TABLE))
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.exists", equalTo(true)))
.andDo(document(DB_NAME + "-exists-inner-join"));
}
@Test
@DisplayName("Actor exists with inner name")
void existsInnerJoinWithFilter() throws Exception {
mockMvc.perform(post(getPrefixApiUrl() + "/film/exists/_expand")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(INNER_JOIN_MULTI_TABLE))
.param("filter", "film_id==2")
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.exists", equalTo(false)))
.andDo(document(DB_NAME + "-exists-inner-join-with-filter"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mssql/MsSQLFindOneControllerTest.java
================================================
package com.homihq.db2rest.rest.mssql;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import static org.hamcrest.Matchers.equalTo;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@Order(501)
@TestWithResources
class MsSQLFindOneControllerTest extends MsSQLBaseIntegrationTest {
@Test
@DisplayName("Find one film")
void findOneFilm() throws Exception {
mockMvc.perform(get(getPrefixApiUrl() + "/film/one")
.accept(MediaType.APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "film_id==1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.film_id", equalTo(1)))
.andExpect(jsonPath("$.title", equalTo("ACADEMY DINOSAUR")))
.andDo(print())
.andDo(document(DB_NAME + "-get-on-film"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mssql/MsSQLFunctionControllerTest.java
================================================
package com.homihq.db2rest.rest.mssql;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import java.util.Map;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.instanceOf;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@Order(501)
class MsSQLFunctionControllerTest extends MsSQLBaseIntegrationTest {
@Test
@DisplayName("Execute function on microsoft sql server")
void execute() throws Exception {
var json = """
{
"movieTitle": "ACADEMY DINOSAUR"
}
""";
mockMvc.perform(post(getPrefixApiUrl() + "/function/GetMovieRentalRateFunc")
.characterEncoding(UTF_8)
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.content(json))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$", instanceOf(Map.class)))
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$.RETURN_VALUE", equalTo(0.99)))
.andDo(document(DB_NAME + "-execute-function"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mssql/MsSQLInnerJoinControllerTest.java
================================================
package com.homihq.db2rest.rest.mssql;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import java.util.List;
import java.util.Map;
import static org.hamcrest.Matchers.anyOf;
import static org.hamcrest.Matchers.hasSize;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@Order(501)
@TestWithResources
class MsSQLInnerJoinControllerTest extends MsSQLBaseIntegrationTest {
@GivenJsonResource(TEST_JSON_FOLDER + "/INNER_JOIN.json")
List> INNER_JOIN;
@Test
@DisplayName("Test inner Join")
void testInnerJoin() throws Exception {
mockMvc.perform(post(getPrefixApiUrl() + "/review/_expand")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(INNER_JOIN))
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1), hasSize(3))))
.andExpect(jsonPath("$[0].*", hasSize(7)))
.andDo(document(DB_NAME + "-inner-join"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mssql/MsSQLInnerJoinMultiTableControllerTest.java
================================================
package com.homihq.db2rest.rest.mssql;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import java.util.List;
import java.util.Map;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@Order(501)
@TestWithResources
class MsSQLInnerJoinMultiTableControllerTest extends MsSQLBaseIntegrationTest {
@GivenJsonResource(TEST_JSON_FOLDER + "/INNER_JOIN_MULTI_TABLE.json")
List> INNER_JOIN_MULTI_TABLE;
@Test
@DisplayName("Inner multi-table Join")
void innerMultiTable() throws Exception {
mockMvc.perform(post(getPrefixApiUrl() + "/film/_expand")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(INNER_JOIN_MULTI_TABLE))
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$[0].*", hasSize(17)))
.andExpect(jsonPath("$[0].film_id", equalTo(1)))
.andExpect(jsonPath("$[0].language_id", equalTo(1)))
.andExpect(jsonPath("$[0].actor_id", equalTo(1)))
.andExpect(jsonPath("$[0].first_name", equalTo("PENELOPE")))
.andExpect(jsonPath("$[0].last_name", equalTo("GUINESS")))
.andDo(document(DB_NAME + "-inner-multi-table-join"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mssql/MsSQLInnerSelfJoinControllerTest.java
================================================
package com.homihq.db2rest.rest.mssql;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import java.util.List;
import java.util.Map;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@Order(501)
@TestWithResources
class MsSQLInnerSelfJoinControllerTest extends MsSQLBaseIntegrationTest {
@GivenJsonResource(TEST_JSON_FOLDER + "/INNER_SELF_JOIN.json")
List> INNER_SELF_JOIN;
@Test
@DisplayName("Inner self Join")
void innerSelfJoin() throws Exception {
mockMvc.perform(post(getPrefixApiUrl() + "/film/_expand")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(INNER_SELF_JOIN))
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$[0].*", hasSize(15)))
.andExpect(jsonPath("$[0].film_id", equalTo(1)))
.andExpect(jsonPath("$[0].language_id", equalTo(1)))
.andDo(document(DB_NAME + "-inner-self-join-table"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mssql/MsSQLJsonFileCreateControllerTest.java
================================================
package com.homihq.db2rest.rest.mssql;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.web.servlet.MvcResult;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(503)
@TestWithResources
class MsSQLJsonFileCreateControllerTest extends MsSQLBaseIntegrationTest {
Path dir = FileSystems.getDefault().getPath("src/test/resources/testdata");
Path actorFile = dir.resolve("actor.json");
Path filmFile = dir.resolve("BULK_CREATE_FILM_REQUEST.json");
Path nonArrayActorFile = dir.resolve("CREATE_ACTOR_REQUEST.json");
Path directorFile = dir.resolve("director.json");
@Autowired
JdbcTemplate jdbcTemplate;
@Test
@DisplayName("Create many actors via JSON file upload.")
void uploadActorsFile() throws Exception {
jdbcTemplate.execute("SET IDENTITY_INSERT dbo.actor ON");
MockMultipartFile file = new MockMultipartFile("file", "actor.json",
"application/json", Files.readAllBytes(actorFile));
MvcResult mvcResult = mockMvc.perform(multipart(VERSION + "/mssql/actor/upload")
.file(file)
.contentType("multipart/form-data")
.accept(APPLICATION_JSON))
.andDo(print())
.andReturn();
mockMvc.perform(asyncDispatch(mvcResult))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row").isNumber())
.andExpect(jsonPath("$.row").value(10000))
.andExpect(jsonPath("$.keys").value("Bulk insert completed successfully"))
.andDo(document("mssql-create-actors-file-upload"));
jdbcTemplate.execute("SET IDENTITY_INSERT dbo.actor OFF");
}
@Test
@DisplayName("Error create actor via JSON file upload.")
void uploadActorFileNonJsonArray() throws Exception {
MockMultipartFile file = new MockMultipartFile("file", nonArrayActorFile.toString(),
"application/json", Files.readAllBytes(nonArrayActorFile));
mockMvc.perform(multipart(VERSION + "/mssql/actor/upload")
.file(file)
.contentType("multipart/form-data")
.accept(APPLICATION_JSON))
.andDo(print())
.andExpect(status().isBadRequest())
.andDo(document("mssql-error-create-actors-file-upload"));
}
@Test
@DisplayName("Create many directors via file upload.")
void createDirectorViaUpload() throws Exception {
MockMultipartFile file = new MockMultipartFile("file", "bulkDirector.json",
"application/json", Files.readAllBytes(directorFile));
MvcResult mvcResult = mockMvc.perform(multipart(VERSION + "/mssql/director/upload")
.file(file)
.contentType("multipart/form-data")
.accept(APPLICATION_JSON))
.andDo(print())
.andReturn();
mockMvc.perform(asyncDispatch(mvcResult))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row").isNumber())
.andExpect(jsonPath("$.row").value(600))
.andExpect(jsonPath("$.keys").value("Bulk insert completed successfully"))
.andDo(document("mssql-create-directors-file-upload"));
}
@Test
@DisplayName("Create many films via file upload.")
void createFilmsViaUpload() throws Exception {
MockMultipartFile file = new MockMultipartFile("file", "bulkFilm.json",
"application/json", Files.readAllBytes(filmFile));
MvcResult mvcResult = mockMvc.perform(multipart(VERSION + "/mssql/film/upload")
.file(file)
.contentType("multipart/form-data")
.accept(APPLICATION_JSON))
.andDo(print())
.andReturn();
mockMvc.perform(asyncDispatch(mvcResult))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row").isNumber())
.andExpect(jsonPath("$.row").value(2))
.andExpect(jsonPath("$.keys").value("Bulk insert completed successfully"))
.andDo(document("mssql-create-films-file-upload"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mssql/MsSQLProcedureControllerTest.java
================================================
package com.homihq.db2rest.rest.mssql;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import java.util.Map;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.instanceOf;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@Order(501)
class MsSQLProcedureControllerTest extends MsSQLBaseIntegrationTest {
@Test
@DisplayName("Execute stored procedure on microsoft sql server")
void execute() throws Exception {
var json = """
{
"movieTitle": "ACADEMY DINOSAUR"
}
""";
mockMvc.perform(post(getPrefixApiUrl() + "/procedure/GetMovieRentalRateProc")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.content(json))
.andExpect(status().isOk())
.andExpect(jsonPath("$", instanceOf(Map.class)))
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$.rentalRate", equalTo(0.99)))
.andDo(print())
.andDo(document(DB_NAME + "-execute-procedure"));
}
@Test
@DisplayName("Execute GetActorByIdProc on MSSQL")
void executeGetActorByIdProc() throws Exception {
var json = """
{
"actorId": 1
}
""";
mockMvc.perform(post(getPrefixApiUrl() + "/procedure/GetActorByIdProc")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.content(json))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$['#result-set-1']", hasSize(1)))
.andExpect(jsonPath("$['#result-set-1'][0].actor_id", equalTo(1)))
.andExpect(jsonPath("$['#result-set-1'][0].first_name").exists())
.andExpect(jsonPath("$['#result-set-1'][0].last_name").exists());
}
@Test
@DisplayName("Execute GetActorByIdProc on MSSQL with resultSetKeys")
void executeGetActorByIdProcWithResultSetKeys() throws Exception {
var json = """
{
"actorId": 1
}
""";
mockMvc.perform(post(getPrefixApiUrl() + "/procedure/GetActorByIdProc?resultSetKeys=actors")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.content(json))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.actors", hasSize(1)))
.andExpect(jsonPath("$.actors[0].actor_id", equalTo(1)))
.andExpect(jsonPath("$.actors[0].first_name").exists())
.andExpect(jsonPath("$.actors[0].last_name").exists());
}
@Test
@DisplayName("Execute GetActorsAndFilmsProc on MSSQL without resultSetKeys")
void executeGetActorsAndFilmsProcWithoutResultSetKeys() throws Exception {
mockMvc.perform(post(getPrefixApiUrl() + "/procedure/GetActorsAndFilmsProc")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.content("{}"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$['#result-set-1']").isArray())
.andExpect(jsonPath("$['#result-set-2']").isArray())
.andExpect(jsonPath("$['#result-set-1'][0].actor_id").exists())
.andExpect(jsonPath("$['#result-set-2'][0].film_id").exists());
}
@Test
@DisplayName("Execute GetActorsAndFilmsProc on MSSQL with resultSetKeys")
void executeGetActorsAndFilmsProcWithResultSetKeys() throws Exception {
mockMvc.perform(post(getPrefixApiUrl() + "/procedure/GetActorsAndFilmsProc?resultSetKeys=actors,films")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.content("{}"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.actors").isArray())
.andExpect(jsonPath("$.films").isArray())
.andExpect(jsonPath("$.actors[0].actor_id").exists())
.andExpect(jsonPath("$.films[0].film_id").exists());
}
@Test
@DisplayName("Execute UpdateUserProc on MSSQL")
void updateUser() throws Exception {
var json = """
{
"user_id": 2
} """;
mockMvc.perform(post(getPrefixApiUrl() + "/procedure/UpdateUserProc")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.content(json))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$['#update-count-1']", equalTo(1)));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mssql/MsSQLRSqlOperatorReadControllerTest.java
================================================
package com.homihq.db2rest.rest.mssql;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.springframework.http.MediaType;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.core.AnyOf.anyOf;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(501)
@TestWithResources
class MsSQLRSqlOperatorReadControllerTest extends MsSQLBaseIntegrationTest {
@Test
@DisplayName("Test find with Equals Operator")
void findWithEqualsOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mssql/film")
.accept(APPLICATION_JSON)
.param("fields", "title,description,release_year")
.param("filter", "film_id==2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1), hasSize(1))))
.andExpect(jsonPath("$[0].title", notNullValue()))
.andExpect(jsonPath("$[0].description", notNullValue()))
.andExpect(jsonPath("$[0].release_year", notNullValue()))
.andDo(document("mssql-find-films-with-equals-operator"));
}
@Test
@DisplayName("Test find with Equals Operator")
void findWithNotEqualsOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mssql/film")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "film_id!=2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(3), hasSize(3))))
.andExpect(jsonPath("$[0].film_id").value(1))
.andExpect(jsonPath("$[1].film_id").value(3))
.andExpect(jsonPath("$[2].film_id").value(4))
.andDo(document("mssql-find-films-with-not-equals-operator"));
}
@Test
@DisplayName("Test find with Greater than Operator")
void findWithGreaterThanOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mssql/film;desc")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "film_id=gt=2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(2), hasSize(2))))
.andExpect(jsonPath("$[0].film_id").value(3))
.andExpect(jsonPath("$[1].film_id").value(4))
.andDo(document("mssql-find-films-with-greater-operator"));
}
@Test
@DisplayName("Test find with Greater than EqualsOperator")
void findWithGreaterThanEqualsOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mssql/film;desc")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "film_id=ge=2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(3), hasSize(3))))
.andExpect(jsonPath("$[0].film_id").value(2))
.andExpect(jsonPath("$[1].film_id").value(3))
.andExpect(jsonPath("$[2].film_id").value(4))
.andDo(document("mssql-find-films-with-greater-equals-operator"));
}
@Test
@DisplayName("Test find with Less than Operator")
void findWithLessThanOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mssql/film;desc")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "film_id=lt=2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1), hasSize(1))))
.andExpect(jsonPath("$[0].film_id").value(1))
.andDo(document("mssql-find-films-with-less-operator"));
}
@Test
@DisplayName("Test find with Less than Equals Operator")
void findWithLessThanEqualsOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mssql/film;desc")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "film_id=le=2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(2), hasSize(2))))
.andExpect(jsonPath("$[0].film_id").value(1))
.andExpect(jsonPath("$[1].film_id").value(2))
.andDo(document("mssql-find-films-with-less-equals-operator"));
}
@Test
@DisplayName("Test find with In Operator")
void findWithInOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mssql/film;desc")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "film_id=in=(2,3,5)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(2), hasSize(2))))
.andExpect(jsonPath("$[0].film_id").value(2))
.andExpect(jsonPath("$[1].film_id").value(3))
.andDo(document("mssql-find-films-with-in-operator"));
}
@Test
@DisplayName("Test find with Not In Operator")
void findWithNotInOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mssql/film;desc")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "film_id=out=(2,3,5)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(2), hasSize(2))))
.andExpect(jsonPath("$[0].film_id").value(1))
.andExpect(jsonPath("$[1].film_id").value(4))
.andDo(document("mssql-find-films-with-not-in-operator"));
}
@Test
@DisplayName("Test find with Not In Operator (Ext)")
void findWithNotInOperatorExt() throws Exception {
mockMvc.perform(get(VERSION + "/mssql/film;desc")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "film_id=out=(2,3,5)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(2), hasSize(2))))
.andExpect(jsonPath("$[0].film_id").value(1))
.andExpect(jsonPath("$[1].film_id").value(4))
.andDo(document("mssql-find-films-with-not-in-operator-ext"));
}
@Test
@DisplayName("Test find with Like Operator")
void findWithLikeOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mssql/film;desc")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "title=like=ACADEMY")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1), hasSize(1))))
.andExpect(jsonPath("$[0].film_id").value(1))
.andDo(document("mssql-find-films-with-like-operator"));
}
@Test
@DisplayName("Test find with Starts With Operator")
void findWithStartsWithOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mssql/film;desc")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "title=startWith=ACAD")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1), hasSize(1))))
.andExpect(jsonPath("$[0].film_id").value(1))
.andDo(document("mssql-find-films-starts-with-operator"));
}
@Test
@DisplayName("Test find with Ends With Operator")
void findWithEndsWithOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mssql/film;desc")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "title=endWith=DINOSAUR")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1), hasSize(1))))
.andExpect(jsonPath("$[0].film_id").value(1))
.andDo(document("mssql-find-films-ends-with-operator"));
}
@Test
@DisplayName("Should return 4xx when using equals operator with an invalid column")
void findWithEqualsOperator_givenInvalidColumn_shouldReturn4xx() throws Exception {
mockMvc.perform(get(VERSION + "/mssql/film")
.accept(APPLICATION_JSON)
.param("filter", "actor_id==206")
)
.andExpect(status().is4xxClientError())
.andExpect(jsonPath("$.detail").value("Failed to parse RQL - Column not found film.actor_id"));
}
@Test
@DisplayName("Test find with Not Like Operator")
void findWithNotLikeOperator() throws Exception {
mockMvc.perform(get( VERSION+"/mssql/film")
.accept(MediaType.APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "title=nk=ACADEMY")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*", hasSize(3)))
.andExpect(jsonPath("$[0].film_id", equalTo(2)))
.andExpect(jsonPath("$[0].title", equalTo("ACE GOLDFINGER")))
.andExpect(jsonPath("$[1].film_id", equalTo(3)))
.andExpect(jsonPath("$[1].title", equalTo("ADAPTATION HOLES")))
.andExpect(jsonPath("$[2].film_id", equalTo(4)))
.andExpect(jsonPath("$[2].title", equalTo("AFFAIR PREJUDICE")))
.andDo(document("mssql-find-films-with-not-like-operator"));
}
@Test
@DisplayName("Test find with Equals OR StartWith Operator")
void findWithEqualsAndStartWithCombinationalOperator() throws Exception {
mockMvc.perform(get( VERSION+"/mssql/film")
.accept(MediaType.APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "film_id==2")
.param("filter", "title=like=ACADEMY")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*", hasSize(2)))
.andExpect(jsonPath("$[0].film_id", equalTo(1)))
.andExpect(jsonPath("$[0].title", equalTo("ACADEMY DINOSAUR")))
.andExpect(jsonPath("$[1].film_id", equalTo(2)))
.andExpect(jsonPath("$[1].title", equalTo("ACE GOLDFINGER")))
.andDo(document("mssql-find-films-with-equals-or-like-operator"));
}
@Test
@DisplayName("Test find with Equals AND Like Operator")
void findWithEqualsAndLikeCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mssql/film")
.accept(APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "film_id==2;title=like=ACE")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$[0].film_id", equalTo(2)))
.andExpect(jsonPath("$[0].title", equalTo("ACE GOLDFINGER")))
.andDo(document("mssql-find-films-with-equals-and-like-operator"));
}
@Test
@DisplayName("Test find with Equals and Like and In Operator")
void findWithEqualsAndLikeAndInCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mssql/film")
.accept(APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "film_id==2;title=like=ACE;rating=in=(G, mssql)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$[0].film_id", equalTo(2)))
.andExpect(jsonPath("$[0].title", equalTo("ACE GOLDFINGER")))
.andDo(document("mssql-find-films-with-equals-and-like-and-in-operator"));
}
@Test
@DisplayName("Test find with Equals OR Like OR In Operator")
void findWithEqualsOrLikeOrInCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mssql/film")
.accept(APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "film_id==2")
.param("filter", "title=like=ACADEMY")
.param("filter", "rating=in=(G, mssql)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(3)))
.andExpect(jsonPath("$[0].film_id", equalTo(1)))
.andExpect(jsonPath("$[0].title", equalTo("ACADEMY DINOSAUR")))
.andExpect(jsonPath("$[1].film_id", equalTo(2)))
.andExpect(jsonPath("$[1].title", equalTo("ACE GOLDFINGER")))
.andExpect(jsonPath("$[2].film_id", equalTo(4)))
.andExpect(jsonPath("$[2].title", equalTo("AFFAIR PREJUDICE")))
.andDo(document("mssql-find-films-with-equals-or-like-or-in-operator"));
}
@Test
@DisplayName("Test find with Equals And Like And Not In Operator")
void findWithEqualsAndLikeAndNotInCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mssql/film")
.accept(APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "film_id==2;title=like=ACE;rating=out=(G, mssql)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isEmpty())
.andDo(document("mssql-find-films-with-equals-and-like-and-out-operator"));
}
@Test
@DisplayName("Test find with Equals OR Like OR Not In Operator")
void findWithEqualsOrLikeOrNotInCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mssql/film")
.accept(APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "film_id==2")
.param("filter", "title=like=ACADEMY")
.param("filter", "rating=out=(G, mssql)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(3)))
.andExpect(jsonPath("$[0].film_id", equalTo(1)))
.andExpect(jsonPath("$[0].title", equalTo("ACADEMY DINOSAUR")))
.andExpect(jsonPath("$[1].film_id", equalTo(2)))
.andExpect(jsonPath("$[1].title", equalTo("ACE GOLDFINGER")))
.andExpect(jsonPath("$[2].film_id", equalTo(3)))
.andExpect(jsonPath("$[2].title", equalTo("ADAPTATION HOLES")))
.andDo(document("mssql-find-films-with-equals-or-like-or-out-operator"));
}
@Test
@DisplayName("Test find with Equals and Like and In And Greater Than Equals Operator")
void findWithEqualsAndLikeAndInAbdGreaterThanEualsCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mssql/film")
.accept(APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "film_id==2;title=like=ACE;rating=in=(G, mssql);language_id=ge=1")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$[0].film_id", equalTo(2)))
.andExpect(jsonPath("$[0].title", equalTo("ACE GOLDFINGER")))
.andDo(document("mssql-find-films-with-equals-and-like-and-in-and-greater-equal-operator"));
}
@Test
@DisplayName("Test find with Equals and Like and In And Greater Than Operator")
void findWithEqualsAndLikeAndInAbdGreaterThanCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mssql/film")
.accept(APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "film_id==2;title=like=ACE;rating=in=(G, mssql);language_id=gt=1")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*", hasSize(0)))
.andDo(document("mssql-find-films-with-equals-and-like-and-in-and-greater-operator"));
}
@Test
@DisplayName("Test find with Equals and Like and In And Less Than Equals Operator")
void findWithEqualsAndLikeAndInAndLessThanEqualsCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mssql/film")
.accept(APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "film_id==2;title=like=ACE;rating=in=(G, mssql);language_id=le=2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$[0].film_id", equalTo(2)))
.andExpect(jsonPath("$[0].title", equalTo("ACE GOLDFINGER")))
.andDo(document("mssql-find-films-with-equals-and-like-and-in-and-less-equal-operator"));
}
@Test
@DisplayName("Test find with Equals and Like and In And Less Than Operator")
void findWithEqualsAndLikeAndInAndLessThanCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mssql/film")
.accept(APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "film_id==2;title=like=ACE;rating=in=(G, mssql);language_id=lt=1")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isEmpty())
.andExpect(jsonPath("$.*", hasSize(0)))
.andDo(document("mssql-find-films-with-equals-and-like-and-in-and-less-operator"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mssql/MsSQLReadControllerDefaultFetchLimitTest.java
================================================
package com.homihq.db2rest.rest.mssql;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import org.springframework.test.context.TestPropertySource;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.core.AnyOf.anyOf;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@Order(306)
@TestPropertySource(properties = {"db2rest.defaultFetchLimit=5"})
public class MsSQLReadControllerDefaultFetchLimitTest extends MsSQLBaseIntegrationTest {
@Test
@DisplayName("Get all with default fetch limit set to 5")
void findAllPersonsWithDefaultFetchLimit5() throws Exception {
mockMvc.perform(get(getPrefixApiUrl() + "/person")
.accept(MediaType.APPLICATION_JSON)
)
.andExpect(status().isOk())
.andExpect(jsonPath("$", anyOf(hasSize(5))))
.andDo(document(DB_NAME + "-find-all-persons-with-default-fetch-limit-5"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mssql/MsSQLReadControllerTest.java
================================================
package com.homihq.db2rest.rest.mssql;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.notNullValue;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@Order(501)
class MsSQLReadControllerTest extends MsSQLBaseIntegrationTest {
@Test
@DisplayName("Find all films - all columns.")
void findAllFilmsWithAllColumns() throws Exception {
mockMvc.perform(get(getPrefixApiUrl() + "/film")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(4)))
.andExpect(jsonPath("$[0].*", hasSize(14)))
.andDo(document(DB_NAME + "-find-all-films-all-columns"));
}
@Test
@DisplayName("Find all films - 3 columns")
void findAllFilmsWithThreeCols() throws Exception {
mockMvc.perform(get(getPrefixApiUrl() + "/film")
.contentType(APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.param("fields", "title,description,release_year")
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(4)))
.andExpect(jsonPath("$[0].*", hasSize(3)))
.andDo(document(DB_NAME + "-find-all-films-3-columns"));
}
@Test
@DisplayName("Find all films - with column alias")
void findAllFilmsWithColumnAlias() throws Exception {
mockMvc.perform(get(getPrefixApiUrl() + "/film")
.contentType(APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.param("fields", "title,description,release_year:releaseYear")
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(4)))
.andExpect(jsonPath("$[0].title", notNullValue()))
.andExpect(jsonPath("$[0].description", notNullValue()))
.andExpect(jsonPath("$[0].releaseYear", notNullValue()))
.andDo(document(DB_NAME + "-find-all-films-with-column-alias"));
}
@Test
@DisplayName("Find all films with sorting")
void findAllFilmsWithSorting() throws Exception {
mockMvc.perform(get(getPrefixApiUrl() + "/film")
.accept(MediaType.APPLICATION_JSON)
.param("fields", "film_id")
.param("sort", "film_id;desc")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andDo(print())
.andExpect(jsonPath("$.*", hasSize(4)))
.andExpect(jsonPath("$[0].film_id", equalTo(4)))
.andExpect(jsonPath("$[1].film_id", equalTo(3)))
.andExpect(jsonPath("$[2].film_id", equalTo(2)))
.andExpect(jsonPath("$[3].film_id", equalTo(1)))
.andDo(document(DB_NAME + "-find-all-films-with-sorting"));
}
@Test
@DisplayName("Find all films with sorting and pagination")
void findAllFilmsWithSortingAndPagination() throws Exception {
mockMvc.perform(get(getPrefixApiUrl() + "/film")
.accept(MediaType.APPLICATION_JSON)
.param("fields", "film_id")
.param("offset", "1")
.param("limit", "3")
.param("sort", "film_id;desc")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andDo(print())
.andExpect(jsonPath("$.*", hasSize(3)))
.andExpect(jsonPath("$[0].film_id", equalTo(3)))
.andExpect(jsonPath("$[1].film_id", equalTo(2)))
.andExpect(jsonPath("$[2].film_id", equalTo(1)))
.andDo(document(DB_NAME + "-find-all-films-with-sorting-and-pagination"));
}
@Test
@DisplayName("Find all films with pagination")
void findAllFilmsWithPagination() throws Exception {
mockMvc.perform(get(getPrefixApiUrl() + "/film")
.accept(MediaType.APPLICATION_JSON)
.param("fields", "film_id,title")
.param("offset", "1")
.param("limit", "3")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andDo(print())
.andExpect(jsonPath("$.*", hasSize(3)))
.andExpect(jsonPath("$[0].film_id", equalTo(2)))
.andExpect(jsonPath("$[1].film_id", equalTo(3)))
.andExpect(jsonPath("$[2].film_id", equalTo(4)))
.andDo(document(DB_NAME + "-find-all-films-with-pagination"));
}
@Test
@DisplayName("Find all films by filter")
void findAllFilmsByFilter() throws Exception {
mockMvc.perform(get(getPrefixApiUrl() + "/film")
.accept(MediaType.APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "title=like=\"ACADEMY%\";release_year==2006")
)
.andExpect(status().isOk())
.andDo(print())
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$[0].film_id", equalTo(1)))
.andExpect(jsonPath("$[0].title", equalTo("ACADEMY DINOSAUR")))
.andDo(document(DB_NAME + "-find-films-by-filter"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mssql/MsSQLUpdateControllerTest.java
================================================
package com.homihq.db2rest.rest.mssql;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import java.util.Map;
import static org.hamcrest.Matchers.equalTo;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.patch;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@Order(503)
@TestWithResources
class MsSQLUpdateControllerTest extends MsSQLBaseIntegrationTest {
@GivenJsonResource(TEST_JSON_FOLDER + "/UPDATE_FILM_REQUEST.json")
Map UPDATE_FILM_REQUEST;
@GivenJsonResource(TEST_JSON_FOLDER + "/UPDATE_NON_EXISTING_FILM_REQUEST.json")
Map UPDATE_NON_EXISTING_FILM_REQUEST;
@GivenJsonResource(TEST_JSON_FOLDER + "/UPDATE_NON_EXISTING_TABLE.json")
Map UPDATE_NON_EXISTING_TABLE;
@GivenJsonResource(TEST_JSON_FOLDER + "/UPDATE_FILMS_REQUEST.json")
Map UPDATE_FILMS_REQUEST;
@Test
@DisplayName("Update an existing film")
void updateExistingFilm() throws Exception {
mockMvc.perform(patch(getPrefixApiUrl() + "/film")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("filter", "title==\"ACADEMY DINOSAUR\"")
.content(objectMapper.writeValueAsString(UPDATE_FILM_REQUEST))
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", equalTo(1)))
.andDo(document(DB_NAME + "-update-existing-film"));
}
@Test
@DisplayName("Update a non-existing film")
void updateNonExistingFilm() throws Exception {
mockMvc.perform(patch(getPrefixApiUrl() + "/film")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.param("filter", "title==\"BAAHUBALI\"")
.content(objectMapper.writeValueAsString(UPDATE_NON_EXISTING_FILM_REQUEST))
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", equalTo(0)))
.andDo(print())
.andDo(document(DB_NAME + "-update-non-existing-film"));
}
@Test
@DisplayName("Update non-existing table")
void updateNonExistingTable() throws Exception {
mockMvc.perform(patch(getPrefixApiUrl() + "/unknown_table")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("filter", "sample_col==\"sample value 1\"")
.content(objectMapper.writeValueAsString(UPDATE_NON_EXISTING_TABLE))
)
.andExpect(status().isNotFound())
.andDo(print())
.andDo(document(DB_NAME + "-update-non-existing-table"));
}
@Test
@DisplayName("Updating multiple films")
void updateMultipleColumns() throws Exception {
mockMvc.perform(patch(getPrefixApiUrl() + "/film")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("filter", "rating==\"G\"")
.content(objectMapper.writeValueAsString(UPDATE_FILMS_REQUEST))
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", equalTo(2)))
.andDo(document(DB_NAME + "-update-multiple-films"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mysql/CountTwoTablesSameNameDiffSchemaTest.java
================================================
package com.homihq.db2rest.rest.mysql;
import com.homihq.db2rest.MySQLBaseIntegrationTest;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.springframework.http.MediaType;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.equalTo;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(6)
class MySQLCountTwoTablesSameNameDiffSchemaTest extends MySQLBaseIntegrationTest {
@Test
@DisplayName("Get count two tables same name diff schema")
void empCount() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/employee/count")
.header("Accept-Profile", "sakila")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(print())
.andExpect(jsonPath("$.count", equalTo(2)))
.andDo(document("mysql-employee-count-sakila"));
mockMvc.perform(get(VERSION + "/mysqldb/employee/count")
.header("Accept-Profile", "wakila")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(print())
.andExpect(jsonPath("$.count", equalTo(2)))
.andDo(document("mysql-employee-count-wakila"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mysql/CreateTwoTablesSameNameDiffSchemaTest.java
================================================
package com.homihq.db2rest.rest.mysql;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.MySQLBaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.equalTo;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(82)
@TestWithResources
class MySQLCreateTwoTablesSameNameDiffSchemaTest extends MySQLBaseIntegrationTest {
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@GivenJsonResource("/testdata/CREATE_EMP_REQUEST.json")
Map CREATE_EMP_REQUEST;
@Test
@DisplayName("Create emp diff schema")
void create() throws Exception {
mockMvc.perform(post(VERSION + "/mysqldb/employee")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.header("Content-Profile", "sakila")
.content(objectMapper.writeValueAsString(CREATE_EMP_REQUEST))
)
.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
.andExpect(jsonPath("$.keys.GENERATED_KEY").exists())
.andExpect(jsonPath("$.keys.GENERATED_KEY", equalTo(3)))
.andDo(document("mysql-create-emp-sakila"));
mockMvc.perform(post(VERSION + "/mysqldb/employee")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.header("Content-Profile", "wakila")
.content(objectMapper.writeValueAsString(CREATE_EMP_REQUEST))
)
.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
.andExpect(jsonPath("$.keys.GENERATED_KEY").exists())
.andExpect(jsonPath("$.keys.GENERATED_KEY", equalTo(3)))
.andDo(document("mysql-create-emp-wakila"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mysql/DeleteTwoTablesSameNameDiffSchemaTest.java
================================================
package com.homihq.db2rest.rest.mysql;
import com.homihq.db2rest.MySQLBaseIntegrationTest;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.equalTo;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(92)
class MySQLDeleteTwoTablesSameNameDiffSchemaTest extends MySQLBaseIntegrationTest {
@Test
@DisplayName("Delete Employee Same table different database")
void deleteFromTableWithSameNameDifferentSchema() throws Exception {
mockMvc.perform(delete(VERSION + "/mysqldb/employee")
.accept(APPLICATION_JSON)
.header("Content-Profile", "sakila")
.param("filter", "emp_id==1"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", equalTo(1)))
.andDo(document("mysql-delete-emp-sakila"));
mockMvc.perform(delete(VERSION + "/mysqldb/employee")
.accept(APPLICATION_JSON)
.header("Content-Profile", "wakila")
.param("filter", "emp_id==1"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", equalTo(1)))
.andDo(document("mysql-delete-emp-wakila"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mysql/MySQLBasicJoinControllerTest.java
================================================
package com.homihq.db2rest.rest.mysql;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.MySQLBaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import java.util.List;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.nullValue;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(10)
@TestWithResources
class MySQLBasicJoinControllerTest extends MySQLBaseIntegrationTest {
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@GivenJsonResource("/testdata/LEFT_JOIN.json")
List> LEFT_JOIN;
@GivenJsonResource("/testdata/RIGHT_JOIN.json")
List> RIGHT_JOIN;
@Disabled
@Test
@DisplayName("Test left Join")
void testLeftJoin() throws Exception {
mockMvc.perform(post(VERSION + "/mysqldb/users/_expand")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(LEFT_JOIN))
)
// .andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(4)))
.andExpect(jsonPath("$[0].*", hasSize(10)))
.andExpect(jsonPath("$[0].auid", equalTo(1)))
.andExpect(jsonPath("$[0].apid", equalTo(1)))
.andExpect(jsonPath("$[1].auid", equalTo(2)))
.andExpect(jsonPath("$[1].apid", nullValue()))
.andExpect(jsonPath("$[3].auid", equalTo(6)))
.andExpect(jsonPath("$[3].apid", nullValue()))
.andExpect(jsonPath("$[3].firstname", nullValue()))
.andDo(document("mysql-left-join"));
}
@Test
@DisplayName("Test right Join")
void testRightJoin() throws Exception {
mockMvc.perform(post(VERSION + "/mysqldb/users/_expand")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(RIGHT_JOIN))
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(4)))
.andExpect(jsonPath("$[0].*", hasSize(10)))
.andExpect(jsonPath("$[0].auid", equalTo(1)))
.andExpect(jsonPath("$[0].apid", equalTo(1)))
.andExpect(jsonPath("$[0].apid", equalTo(1)))
.andExpect(jsonPath("$[0].firstname", equalTo("Jack")))
.andExpect(jsonPath("$[1].auid", equalTo(3)))
.andExpect(jsonPath("$[1].apid", equalTo(2)))
.andExpect(jsonPath("$[1].username", nullValue()))
.andExpect(jsonPath("$[1].firstname", equalTo("Tom")))
.andExpect(jsonPath("$[3].auid", equalTo(7)))
.andExpect(jsonPath("$[3].apid", equalTo(7)))
.andExpect(jsonPath("$[3].username", nullValue()))
.andExpect(jsonPath("$[3].firstname", equalTo("Ivan")))
.andDo(document("mysql-right-join"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mysql/MySQLBulkCreateControllerTest.java
================================================
package com.homihq.db2rest.rest.mysql;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.MySQLBaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.GivenTextResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import java.util.List;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasSize;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(81)
@TestWithResources
class MySQLBulkCreateControllerTest extends MySQLBaseIntegrationTest {
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@GivenJsonResource("/testdata/BULK_CREATE_FILM_REQUEST.json")
List> BULK_CREATE_FILM_REQUEST;
@GivenJsonResource("/testdata/BULK_CREATE_FILM_BAD_REQUEST.json")
List> BULK_CREATE_FILM_BAD_REQUEST;
@GivenTextResource("/testdata/CREATE_FILM_REQUEST_CSV.csv")
String CREATE_FILM_REQUEST_CSV;
@GivenTextResource("/testdata/CREATE_FILM_BAD_REQUEST_CSV.csv")
String CREATE_FILM_BAD_REQUEST_CSV;
@GivenJsonResource("/testdata/BULK_CREATE_DIRECTOR_REQUEST.json")
List> BULK_CREATE_DIRECTOR_REQUEST;
@GivenJsonResource("/testdata/BULK_CREATE_DIRECTOR_BAD_REQUEST.json")
List> BULK_CREATE_DIRECTOR_BAD_REQUEST;
@GivenJsonResource("/testdata/BULK_CREATE_REVIEW_REQUEST.json")
List> BULK_CREATE_REVIEW_REQUEST;
@Test
@DisplayName("Create many films.")
void create() throws Exception {
mockMvc.perform(post(VERSION + "/mysqldb/film/bulk")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(BULK_CREATE_FILM_REQUEST))
)
.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.rows").isArray())
.andExpect(jsonPath("$.rows", hasSize(2)))
.andExpect(jsonPath("$.rows", hasItem(1)))
.andExpect(jsonPath("$.rows", hasItem(1)))
//.andExpect(jsonPath("$.generated_keys").isArray()) //TODO - push TSID columns
//.andExpect(jsonPath("$.generated_keys", hasSize(2)))
//.andExpect(jsonPath("$.generated_keys", allOf(notNullValue())))
.andDo(document("mysql-bulk-create-films"));
}
@Test
@DisplayName("Create many films with CSV type.")
void createCSV() throws Exception {
mockMvc.perform(post(VERSION + "/mysqldb/film/bulk")
.contentType("text/csv").accept(APPLICATION_JSON)
.content(CREATE_FILM_REQUEST_CSV))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.rows", hasSize(2)))
.andExpect(jsonPath("$.rows", hasItem(1)))
//.andExpect(jsonPath("$.generated_keys", hasSize(2)))
//.andExpect(jsonPath("$.generated_keys", allOf(notNullValue())))
//.andDo(print())
.andDo(document("mysql-bulk-create-films-csv"));
}
@Test
@DisplayName("Create many films with CSV type resulting error.")
void createCSVWithError() throws Exception {
mockMvc.perform(post(VERSION + "/mysqldb/film/bulk")
.contentType("text/csv")
.accept(APPLICATION_JSON)
.content(CREATE_FILM_BAD_REQUEST_CSV))
.andExpect(status().isBadRequest())
//.andDo(print())
.andDo(document("mysql-bulk-create-films-csv-error"));
}
@Test
@DisplayName("Create many films with failure.")
void createError() throws Exception {
mockMvc.perform(post(VERSION + "/mysqldb/film/bulk")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(BULK_CREATE_FILM_BAD_REQUEST))
)
.andExpect(status().isBadRequest())
// .andDo(print())
.andDo(document("mysql-bulk-create-films-error"));
}
@Test
@DisplayName("Create many directors.")
void createDirector() throws Exception {
mockMvc.perform(post(VERSION + "/mysqldb/director/bulk")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("tsIdEnabled", "true")
.content(objectMapper.writeValueAsString(BULK_CREATE_DIRECTOR_REQUEST))
)
.andExpect(status().isCreated())
//.andDo(print())
.andDo(document("mysql-bulk-create-directors"));
}
@Test
@DisplayName("Create many directors with wrong tsid type.")
void createDirectorWithWrongTsidType() throws Exception {
mockMvc.perform(post(VERSION + "/mysqldb/director/bulk")
.characterEncoding(UTF_8)
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.param("tsid", "director_id")
.param("tsidType", "string")
.header("Content-Profile", "sakila")
.content(objectMapper.writeValueAsString(BULK_CREATE_DIRECTOR_BAD_REQUEST))
)
.andExpect(status().isBadRequest())
//.andDo(print())
.andDo(document("mysql-bulk-create-directors-with-wrong-tsid-type"));
}
@Test
@DisplayName("Create reviews with default tsid type.")
void createReviewWithDefaultTsidType() throws Exception {
mockMvc.perform(post(VERSION + "/mysqldb/review/bulk")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("tsIdEnabled", "true")
.content(objectMapper.writeValueAsString(BULK_CREATE_REVIEW_REQUEST))
)
.andExpect(status().isCreated())
//.andDo(print())
.andDo(document("mysql-bulk-create-reviews-with-default-tsid-type"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mysql/MySQLCountControllerTest.java
================================================
package com.homihq.db2rest.rest.mysql;
import com.homihq.db2rest.MySQLBaseIntegrationTest;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.springframework.http.MediaType;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(2)
class MySQLCountControllerTest extends MySQLBaseIntegrationTest {
@Test
@DisplayName("Get count")
void findFilmCount() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/film/count")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
//.andDo(print())
.andDo(document("mysql-get-film-count"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mysql/MySQLCreateControllerTest.java
================================================
package com.homihq.db2rest.rest.mysql;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.MySQLBaseIntegrationTest;
import com.jayway.jsonpath.JsonPath;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(80)
@TestWithResources
class MySQLCreateControllerTest extends MySQLBaseIntegrationTest {
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@GivenJsonResource("/testdata/CREATE_FILM_REQUEST.json")
Map CREATE_FILM_REQUEST;
@GivenJsonResource("/testdata/CREATE_FILM_REQUEST_ERROR.json")
Map CREATE_FILM_REQUEST_ERROR;
@GivenJsonResource("/testdata/CREATE_VANITY_VAN_REQUEST.json")
Map CREATE_VANITY_VAN_REQUEST;
@GivenJsonResource("/testdata/CREATE_DIRECTOR_REQUEST.json")
Map CREATE_DIRECTOR_REQUEST;
@GivenJsonResource("/testdata/CREATE_FILM_REQUEST_MISSING_PAYLOAD.json")
Map CREATE_FILM_REQUEST_MISSING_PAYLOAD;
@Test
@DisplayName("Create a film.")
void create() throws Exception {
mockMvc.perform(post(VERSION + "/mysqldb/film")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST))
)
//.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
//.andExpect(jsonPath("$.keys.GENERATED_KEY").exists())
//.andExpect(jsonPath("$.keys.GENERATED_KEY", equalTo(5)))
.andDo(document("mysql-create-a-film"));
}
@Test
@DisplayName("Test Create a film with error.")
void createError() throws Exception {
mockMvc.perform(post(VERSION + "/mysqldb/film")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST_ERROR)))
//.andDo(print())
.andExpect(status().isBadRequest())
.andDo(document("mysql-create-a-film-error"));
}
@Test
@DisplayName("Test create a film - non existent table.")
void createNonExistentTable() throws Exception {
mockMvc.perform(post(VERSION + "/mysqldb/films")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST)))
.andExpect(status().isNotFound())
//.andDo(print())
.andDo(document("mysql-create-a-film-no-table"));
}
@Test
@DisplayName("Test Create a director - TSID enabled")
void createDirectorWithTSIDEnabled() throws Exception {
//TODO - MySQL return keys not working
mockMvc.perform(post(VERSION + "/mysqldb/director")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("tsIdEnabled", "true")
.content(objectMapper.writeValueAsString(CREATE_DIRECTOR_REQUEST)))
//.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
//.andExpect(jsonPath("$.keys.director_id").exists())
// .andExpect(jsonPath("$.keys.director_id").isNumber())
.andDo(document("mysql-create-a-director-tsid-enabled"));
}
@Test
@DisplayName("Create a director - with TSID explicitly OFF")
void createDirectorWithTSIDOff() throws Exception {
mockMvc.perform(post(VERSION + "/mysqldb/director")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("tsIdEnabled", "false")
.content(objectMapper.writeValueAsString(CREATE_DIRECTOR_REQUEST)))
.andExpect(status().isBadRequest())
//.andDo(print())
.andDo(document("mysql-create-a-director-with-tsid-OFF"));
}
@Test
@DisplayName("Test Create a Vanity Van - with varchar tsid type")
void createVanityVanWithVarcharTsIdType() throws Exception {
//TODO - MySQL return keys not working
mockMvc.perform(post(VERSION + "/mysqldb/vanity_van")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("tsIdEnabled", "true")
.content(objectMapper.writeValueAsString(CREATE_VANITY_VAN_REQUEST)))
//.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
//.andExpect(jsonPath("$.keys.vanity_van_id").exists())
//.andExpect(jsonPath("$.keys.vanity_van_id").isString())
.andDo(document("mysql-create-a-vanity-van-tsid-varchar"));
}
@Test
@DisplayName("Create a film with subset of columns")
void createFilmWithSubsetOfColumns() throws Exception {
var result = mockMvc.perform(post(VERSION + "/mysqldb/film")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.queryParam("columns", "title,description,language_id")
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST)))
.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
.andExpect(jsonPath("$.keys").exists())
//.andExpect(jsonPath("$.keys.GENERATED_KEY", equalTo(5)))
.andExpect(jsonPath("$.keys.GENERATED_KEY").isNumber())
.andDo(document("mysql-create-a-film"))
.andReturn();
var pk = JsonPath.read(result.getResponse().getContentAsString(), "$.keys.GENERATED_KEY");
mockMvc.perform(get(VERSION + "/mysqldb/film")
.accept(APPLICATION_JSON)
.queryParam("fields", "title,release_year")
.queryParam("filter", String.format("film_id==%s", pk)))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$[0].title", equalTo("Dunki")))
.andExpect(jsonPath("$[0].release_year").doesNotExist());
// cleanup data
assertTrue(deleteRow("film", "film_id", (int) pk));
}
@Test
@DisplayName("Ignore if columns parameter is blank")
void shouldIgnoreWhenColumnsQueryParamIsEmpty() throws Exception {
var result = mockMvc.perform(post(VERSION + "/mysqldb/film")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.queryParam("columns", "")
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST)))
//.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
.andExpect(jsonPath("$.keys").exists())
.andDo(document("mysql-create-a-film"))
.andReturn();
var pk = JsonPath.read(result.getResponse().getContentAsString(), "$.keys.GENERATED_KEY");
mockMvc.perform(get(VERSION + "/mysqldb/film")
.accept(APPLICATION_JSON)
.queryParam("select", "title,release_year")
.queryParam("filter", String.format("film_id==%s", pk)))
.andExpect(status().isOk())
.andExpect(jsonPath("$[0].title", equalTo("Dunki")))
.andExpect(jsonPath("$[0].release_year", equalTo("2023-01-01")))
// .andDo(print())
;
// cleanup data
assertTrue(deleteRow("film", "film_id", (int) pk));
}
@Test
@DisplayName("Column is present in columns param but not in payload")
void columnIsPresentInColumnsQueryParamButNotInPayload() throws Exception {
mockMvc.perform(post(VERSION + "/mysqldb/film")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.queryParam("columns", "title,description,language_id")
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST_MISSING_PAYLOAD))) //description is not in payload will be set to null
.andExpect(status().isBadRequest())
//.andDo(print())
.andDo(document("mysql-create-a-film-missing-payload-attribute-error"));
}
@Test
@DisplayName("Column violates not-null constraint")
void column_violates_not_null_constraint() throws Exception {
mockMvc.perform(post(VERSION + "/mysqldb/film")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.queryParam("columns", "title,description")
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST)))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.detail",
containsString("Field 'language_id' doesn't have a default value")))
//.andDo(print())
.andDo(document("mysql-create-a-film-not-null-constraint"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mysql/MySQLCrossJoinControllerTest.java
================================================
package com.homihq.db2rest.rest.mysql;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.MySQLBaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import java.util.List;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(11)
@TestWithResources
class MySQLCrossJoinControllerTest extends MySQLBaseIntegrationTest {
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@GivenJsonResource("/testdata/CROSS_JOIN_USERS.json")
List> CROSS_JOIN;
@GivenJsonResource("/testdata/CROSS_JOIN_TOPS.json")
List> CROSS_JOIN_TOPS;
@Test
@DisplayName("Test cross Join - Users")
void testCrossJoin() throws Exception {
mockMvc.perform(post(VERSION + "/mysqldb//users/_expand")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(CROSS_JOIN))
)
// .andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(16)))
.andExpect(jsonPath("$[0].*", hasSize(10)))
.andExpect(jsonPath("$[0].auid", equalTo(6)))
.andExpect(jsonPath("$[0].apid", equalTo(1)))
.andExpect(jsonPath("$[0].firstname", equalTo("Jack")))
.andExpect(jsonPath("$[1].auid", equalTo(4)))
.andExpect(jsonPath("$[1].apid", equalTo(1)))
.andExpect(jsonPath("$[1].firstname", equalTo("Jack")))
.andDo(document("mysql-cross-join-users"));
}
@Test
@DisplayName("Test cross Join - Tops")
void testCrossJoinTops() throws Exception {
mockMvc.perform(post(VERSION + "/mysqldb//tops/_expand")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(CROSS_JOIN_TOPS))
)
//.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(9)))
.andExpect(jsonPath("$[0].*", hasSize(6)))
.andExpect(jsonPath("$[0].top_item", equalTo("tank_top")))
.andExpect(jsonPath("$[0].bottom_item", equalTo("jeans")))
.andExpect(jsonPath("$[0].color", equalTo("white")))
.andExpect(jsonPath("$[0].botColor", equalTo("blue")))
.andDo(document("mysql-cross-join-tops"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mysql/MySQLDateTimeAllTest.java
================================================
package com.homihq.db2rest.rest.mysql;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.MySQLBaseIntegrationTest;
import com.homihq.db2rest.rest.DateTimeUtil;
import com.jayway.jsonpath.JsonPath;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.HashMap;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.patch;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(92)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class MySQLDateTimeAllTest extends MySQLBaseIntegrationTest {
private final String dateTime = "2024-03-15T10:30:45.000";
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@Test
@Order(1)
@DisplayName("Test Create a actor with datetime fields")
void createActorWithDateTimeFields() throws Exception {
// Prepare the request with datetime fields
Map actorRequestWithDateTime = new HashMap<>();
actorRequestWithDateTime.put("first_name", "Collective");
actorRequestWithDateTime.put("last_name", "Unconscious");
actorRequestWithDateTime.put("last_update", "2020-03-15T14:30:45.000");
mockMvc.perform(post(VERSION + "/mysqldb/actor")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(actorRequestWithDateTime)))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
.andDo(document("mysql-create-an-actor-with-datetime"));
}
@Test
@Order(1)
@DisplayName("Test Create an actor with error timestamp field")
void createActorWithErrorDateTimeField() throws Exception {
Map actorRequestWithErrorDateTime = new HashMap<>();
actorRequestWithErrorDateTime.put("first_name", "Hero");
actorRequestWithErrorDateTime.put("last_name", "shadow");
actorRequestWithErrorDateTime.put("last_update", "2023-15-35T14:75:90");
mockMvc.perform(post(VERSION + "/mysqldb/actor")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(actorRequestWithErrorDateTime)))
.andDo(print())
.andExpect(status().isBadRequest())
.andDo(document("mysql-create-an-actor-with-error-timestamp"));
}
@Test
@Order(2)
@DisplayName("Test update an actor with datetime field")
void updateActorWithDateTimeField() throws Exception {
// Prepare the request with datetime fields
Map updateActorRequestWithDateTime = new HashMap<>();
updateActorRequestWithDateTime.put("last_update", dateTime);
mockMvc.perform(patch(VERSION + "/mysqldb/actor")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.param("filter", "last_name == Unconscious")
.content(objectMapper.writeValueAsString(updateActorRequestWithDateTime)))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", equalTo(1)))
.andDo(document("mysql-update-an-actor-with-datetime"));
}
@Test
@Order(3)
@DisplayName("Test get an actor with datetime fields")
void getActorWithDateTimeFields() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/actor")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.param("filter", "first_name == Collective"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andDo(result -> assertEquals(dateTime, DateTimeUtil.utcToLocalTimestampString(result)))
.andDo(document("mysql-get-an-actor-with-datetime"));
}
@Test
@Order(3)
@DisplayName("Test get an actor filter by timestamp")
void getActorFilterByTimeStamp() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/actor")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.param("filter", "last_update == \"2024-03-15T10:30:45.00Z\""))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("[0].last_name", equalTo("Unconscious")))
.andDo(result -> assertEquals(dateTime, DateTimeUtil.utcToLocalTimestampString(result)))
.andDo(document("mysql-get-an-actor-filter-by-timestamp"));
}
@Test
@Order(4)
@DisplayName("Test delete an actor by timestamp")
void deleteActorByTimeStamp() throws Exception {
mockMvc.perform(delete(VERSION + "/mysqldb/actor")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.param("filter", "last_update == \"2024-03-15T10:30:45.00Z\""))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.rows", equalTo(1)))
.andDo(document("mysql-delete-an-actor-by-timestamp"));
}
@ParameterizedTest
@MethodSource("isoDateTimeFormats")
@Order(5)
@DisplayName("Test ISO Date Time formats")
void createActorWithIsoDateTimeFormats(String isoDateTime) throws Exception {
// Prepare the request with datetime fields
Map actorRequestWithDateTime = new HashMap<>();
actorRequestWithDateTime.put("first_name", "Graeme");
actorRequestWithDateTime.put("last_name", "Smith");
actorRequestWithDateTime.put("last_update", isoDateTime);
var result = mockMvc.perform(post(VERSION + "/mysqldb/actor")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(actorRequestWithDateTime)))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
.andDo(document("mysql-create-an-actor-with-datetime"))
.andReturn();
var pk = JsonPath.read(result.getResponse().getContentAsString(), "$.keys.GENERATED_KEY");
assertTrue(deleteRow("actor", "actor_id", (int) pk));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mysql/MySQLDeleteAllTest.java
================================================
package com.homihq.db2rest.rest.mysql;
import com.homihq.db2rest.MySQLBaseIntegrationTest;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.springframework.test.context.TestPropertySource;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(91)
@TestPropertySource(properties = {"db2rest.allowSafeDelete=false"})
class MySQLDeleteAllTest extends MySQLBaseIntegrationTest {
@Test
@DisplayName("Delete all records while allowSafeDelete=false")
void deleteAllWithAllowSafeDeleteFalse() throws Exception {
mockMvc.perform(delete(VERSION + "/mysqldb/country")
.accept(APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", Matchers.equalTo(4)))
.andDo(document("mysql-delete-a-director"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mysql/MySQLDeleteControllerTest.java
================================================
package com.homihq.db2rest.rest.mysql;
import com.homihq.db2rest.MySQLBaseIntegrationTest;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(90)
class MySQLDeleteControllerTest extends MySQLBaseIntegrationTest {
@Test
@DisplayName("Delete a Director")
void delete_single_record() throws Exception {
mockMvc.perform(delete(VERSION + "/mysqldb/director")
.accept(APPLICATION_JSON)
.param("filter", "first_name==\"Alex\""))
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", equalTo(1)))
//.andDo(print())
.andDo(document("mysql-delete-a-director"));
}
@Test
@DisplayName("Delete all records while allowSafeDelete=true")
void delete_all_records_with_allow_safe_delete_true() throws Exception {
mockMvc.perform(delete(VERSION + "/mysqldb/director")
.accept(APPLICATION_JSON))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.detail",
containsString("Invalid delete operation , safe set to true")))
//.andDo(print())
.andDo(document("mysql-delete-a-director"));
}
@Test
@DisplayName("Column Does Not Exist")
void column_does_not_exist() throws Exception {
mockMvc.perform(delete(VERSION + "/mysqldb/director")
.accept(APPLICATION_JSON)
.param("filter", "_name==\"Alex\""))
.andExpect(status().isNotFound())
.andExpect(jsonPath("$.detail",
containsString("Column not found director._name")))
//.andDo(print())
.andDo(document("mysql-delete-a-director"));
}
@Test
@DisplayName("Foreign Key Constraint Violation")
void foreign_key_constraint_violation() throws Exception {
mockMvc.perform(delete(VERSION + "/mysqldb/language")
.accept(APPLICATION_JSON)
.param("filter", "name==\"ENGLISH\""))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.detail",
containsString("Cannot delete or update a parent row: a foreign key constraint fails")))
//.andDo(print())
.andDo(document("mysql-delete-a-director"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mysql/MySQLFunctionControllerTest.java
================================================
package com.homihq.db2rest.rest.mysql;
import com.homihq.db2rest.MySQLBaseIntegrationTest;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.springframework.http.MediaType;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.instanceOf;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(51)
class MySQLFunctionControllerTest extends MySQLBaseIntegrationTest {
@Test
@DisplayName("Execute function on mysql db")
void execute() throws Exception {
var json = """
{
"movieTitle": "ACADEMY DINOSAUR"
}
""";
mockMvc.perform(post(VERSION + "/mysqldb/function/GetMovieRentalRateFunc")
.characterEncoding(UTF_8)
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.content(json))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$", instanceOf(Map.class)))
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$.return", equalTo(0.99)))
.andDo(document("mysql-execute-function"));
}
@Test
@DisplayName("Execute UpdateUserFunc on MySQL")
void updateUser() throws Exception {
var json = """
{
"user_id": "2"
}
""";
mockMvc.perform(post(VERSION + "/mysqldb/function/UpdateUserFunc")
.characterEncoding(UTF_8)
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.content(json))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$['return']", equalTo(1)));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mysql/MySQLInnerJoinControllerTest.java
================================================
package com.homihq.db2rest.rest.mysql;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.MySQLBaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import java.util.List;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.anyOf;
import static org.hamcrest.Matchers.hasSize;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(12)
@TestWithResources
class MySQLInnerJoinControllerTest extends MySQLBaseIntegrationTest {
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@GivenJsonResource("/testdata/INNER_JOIN.json")
List> INNER_JOIN;
@Test
@DisplayName("Test inner Join")
void testInnerJoin() throws Exception {
mockMvc.perform(post(VERSION + "/mysqldb/review/_expand")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(INNER_JOIN))
)
// .andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1), hasSize(3))))
.andExpect(jsonPath("$[0].*", hasSize(7)))
//.andExpect(jsonPath("$[0].review_id", equalTo("ABC123")))
//.andExpect(jsonPath("$[0].film_id", equalTo(1)))
//.andExpect(jsonPath("$[0].title", equalTo("ACADEMY DINOSAUR")))
.andDo(document("mysql-inner-join"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mysql/MySQLInnerJoinMultiTableControllerTest.java
================================================
package com.homihq.db2rest.rest.mysql;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.MySQLBaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import java.util.List;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(13)
@TestWithResources
class MySQLInnerJoinMultiTableControllerTest extends MySQLBaseIntegrationTest {
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@GivenJsonResource("/testdata/INNER_JOIN_MULTI_TABLE.json")
List> INNER_JOIN_MULTI_TABLE;
@Test
@DisplayName("Test inner multi-table Join")
void testInnerMultiTable() throws Exception {
mockMvc.perform(post(VERSION + "/mysqldb/film/_expand")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(INNER_JOIN_MULTI_TABLE))
)
//.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$[0].*", hasSize(17)))
.andExpect(jsonPath("$[0].film_id", equalTo(1)))
.andExpect(jsonPath("$[0].language_id", equalTo(1)))
.andExpect(jsonPath("$[0].actor_id", equalTo(1)))
.andExpect(jsonPath("$[0].first_name", equalTo("PENELOPE")))
.andExpect(jsonPath("$[0].last_name", equalTo("GUINESS")))
.andDo(document("mysql-inner-multi-table-join"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mysql/MySQLInnerSelfJoinControllerTest.java
================================================
package com.homihq.db2rest.rest.mysql;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.MySQLBaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import java.util.List;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestWithResources
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(14)
class MySQLInnerSelfJoinControllerTest extends MySQLBaseIntegrationTest {
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@GivenJsonResource("/testdata/INNER_SELF_JOIN.json")
List> INNER_SELF_JOIN;
@Test
@DisplayName("Test inner self Join")
void testInnerSelfJoin() throws Exception {
mockMvc.perform(post(VERSION + "/mysqldb/film/_expand")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(INNER_SELF_JOIN))
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
//.andExpect(jsonPath("$.*", hasSize(1)))
//.andExpect(jsonPath("$[0].*", hasSize(17)))
//.andExpect(jsonPath("$[0].film_id", equalTo(1)))
//.andExpect(jsonPath("$[0].language_id", equalTo(1)))
//.andExpect(jsonPath("$[0].actor_id", equalTo(1)))
//.andExpect(jsonPath("$[0].first_name", equalTo("PENELOPE")))
//.andExpect(jsonPath("$[0].last_name", equalTo("GUINESS")))
.andDo(document("mysql-inner-multi-table-join"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mysql/MySQLJsonFileCreateControllerTest.java
================================================
package com.homihq.db2rest.rest.mysql;
import com.homihq.db2rest.MySQLBaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.web.servlet.MvcResult;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(81)
@TestWithResources
class MySQLJsonFileCreateControllerTest extends MySQLBaseIntegrationTest {
Path dir = FileSystems.getDefault().getPath("src/test/resources/testdata");
Path actorFile = dir.resolve("actor.json");
Path filmFile = dir.resolve("BULK_CREATE_FILM_REQUEST.json");
Path nonArrayActorFile = dir.resolve("CREATE_ACTOR_REQUEST.json");
Path directorFile = dir.resolve("director.json");
@Test
@DisplayName("Create many actors via JSON file upload.")
void uploadActorsFile() throws Exception {
MockMultipartFile file = new MockMultipartFile("file", "actor.json",
"application/json", Files.readAllBytes(actorFile));
MvcResult mvcResult = mockMvc.perform(multipart(VERSION + "/mysqldb/actor/upload")
.file(file)
.contentType("multipart/form-data")
.accept(APPLICATION_JSON))
.andDo(print())
.andReturn();
mockMvc.perform(asyncDispatch(mvcResult))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row").isNumber())
.andExpect(jsonPath("$.row").value(10000))
.andExpect(jsonPath("$.keys").value("Bulk insert completed successfully"))
.andDo(document("mysql-create-actors-file-upload"));
}
@Test
@DisplayName("Error create actor via JSON file upload.")
void uploadActorFileNonJsonArray() throws Exception {
MockMultipartFile file = new MockMultipartFile("file", nonArrayActorFile.toString(),
"application/json", Files.readAllBytes(nonArrayActorFile));
mockMvc.perform(multipart(VERSION + "/mysqldb/actor/upload")
.file(file)
.contentType("multipart/form-data")
.accept(APPLICATION_JSON))
.andDo(print())
.andExpect(status().isBadRequest())
.andDo(document("mysql-error-create-actors-file-upload"));
}
@Test
@DisplayName("Create many directors via file upload.")
void createDirectorViaUpload() throws Exception {
MockMultipartFile file = new MockMultipartFile("file", "bulkDirector.json",
"application/json", Files.readAllBytes(directorFile));
MvcResult mvcResult = mockMvc.perform(multipart(VERSION + "/mysqldb/director/upload")
.file(file)
.contentType("multipart/form-data")
.accept(APPLICATION_JSON))
.andDo(print())
.andReturn();
mockMvc.perform(asyncDispatch(mvcResult))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row").isNumber())
.andExpect(jsonPath("$.row").value(600))
.andExpect(jsonPath("$.keys").value("Bulk insert completed successfully"))
.andDo(document("mysql-create-directors-file-upload"));
}
@Test
@DisplayName("Create many films via file upload.")
void createFilmsViaUpload() throws Exception {
MockMultipartFile file = new MockMultipartFile("file", "bulkFilm.json",
"application/json", Files.readAllBytes(filmFile));
MvcResult mvcResult = mockMvc.perform(multipart(VERSION + "/mysqldb/film/upload")
.file(file)
.contentType("multipart/form-data")
.accept(APPLICATION_JSON))
.andDo(print())
.andReturn();
mockMvc.perform(asyncDispatch(mvcResult))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row").isNumber())
.andExpect(jsonPath("$.row").value(2))
.andExpect(jsonPath("$.keys").value("Bulk insert completed successfully"))
.andDo(document("mysql-create-films-file-upload"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mysql/MySQLProcedureControllerTest.java
================================================
package com.homihq.db2rest.rest.mysql;
import com.homihq.db2rest.MySQLBaseIntegrationTest;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.springframework.http.MediaType;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.instanceOf;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(50)
class MySQLProcedureControllerTest extends MySQLBaseIntegrationTest {
@Test
@DisplayName("Execute stored procedure on mysql db")
void execute() throws Exception {
var json = """
{
"movieTitle": "ACADEMY DINOSAUR"
}
""";
mockMvc.perform(post(VERSION + "/mysqldb/procedure/GetMovieRentalRateProc")
.characterEncoding(UTF_8)
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.content(json))
.andExpect(status().isOk())
.andExpect(jsonPath("$", instanceOf(Map.class)))
.andExpect(jsonPath("$.*", hasSize(2)))
.andExpect(jsonPath("$.rentalRate", equalTo(0.99)))
//.andDo(print())
.andDo(document("mysql-execute-procedure"));
}
@Test
@DisplayName("Execute UpdateUser on MySQL")
void updateUser() throws Exception {
var json = """
{
"user_id": "1"
}
""";
mockMvc.perform(post(VERSION + "/mysqldb/procedure/UpdateUserProc")
.characterEncoding(UTF_8)
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.content(json))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$['#update-count-1']", equalTo(1)));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mysql/MySQLRSqlOperatorReadControllerTest.java
================================================
package com.homihq.db2rest.rest.mysql;
import com.homihq.db2rest.MySQLBaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.springframework.http.MediaType;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.core.AnyOf.anyOf;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(1)
@TestWithResources
class MySQLRSqlOperatorReadControllerTest extends MySQLBaseIntegrationTest {
@Test
@DisplayName("Test find with Equals Operator")
void findWithEqualsOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/film")
.accept(APPLICATION_JSON)
.param("fields", "title,description,release_year")
.param("filter", "film_id==1")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1), hasSize(1))))
.andExpect(jsonPath("$[0].title", notNullValue()))
.andExpect(jsonPath("$[0].description", notNullValue()))
.andExpect(jsonPath("$[0].release_year", notNullValue()))
.andDo(document("mysql-find-films-with-equals-operator"));
}
@Test
@DisplayName("Test find with Not Equals Operator")
void findWithNotEqualsOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/film")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "film_id!=2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(3), hasSize(3))))
.andExpect(jsonPath("$[0].film_id").value(1))
.andExpect(jsonPath("$[1].film_id").value(3))
.andExpect(jsonPath("$[2].film_id").value(4))
.andDo(document("mysql-find-films-with-not-equals-operator"));
}
@Test
@DisplayName("Test find with Greater than Operator")
void findWithGreaterThanOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/film;desc")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "film_id=gt=2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(2), hasSize(2))))
.andExpect(jsonPath("$[0].film_id").value(3))
.andExpect(jsonPath("$[1].film_id").value(4))
.andDo(document("mysql-find-films-with-greater-operator"));
}
@Test
@DisplayName("Test find with Greater than Equals Operator")
void findWithGreaterThanEqualsOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/film;desc")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "film_id=ge=2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(3), hasSize(3))))
.andExpect(jsonPath("$[0].film_id").value(2))
.andExpect(jsonPath("$[1].film_id").value(3))
.andExpect(jsonPath("$[2].film_id").value(4))
.andDo(document("mysql-find-films-with-greater-equals-operator"));
}
@Test
@DisplayName("Test find with Less than Operator")
void findWithLessThanOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/film;desc")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "film_id=lt=2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1), hasSize(1))))
.andExpect(jsonPath("$[0].film_id").value(1))
.andDo(document("mysql-find-films-with-less-operator"));
}
@Test
@DisplayName("Test find with Less than Equals Operator")
void findWithLessThanEqualsOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/film;desc")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "film_id=le=2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(2), hasSize(2))))
.andExpect(jsonPath("$[0].film_id").value(1))
.andExpect(jsonPath("$[1].film_id").value(2))
.andDo(document("mysql-find-films-with-less-equals-operator"));
}
@Test
@DisplayName("Test find with In Operator")
void findWithInOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/film;desc")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "film_id=in=(2,3,5)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(2), hasSize(2))))
.andExpect(jsonPath("$[0].film_id").value(2))
.andExpect(jsonPath("$[1].film_id").value(3))
.andDo(document("mysql-find-films-with-in-operator"));
}
@Test
@DisplayName("Test find with Not In Operator")
void findWithNotInOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/film;desc")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "film_id=out=(2,3,5)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(2), hasSize(2))))
.andExpect(jsonPath("$[0].film_id").value(1))
.andExpect(jsonPath("$[1].film_id").value(4))
.andDo(document("mysql-find-films-with-not-in-operator"));
}
@Test
@DisplayName("Test find with Not In Operator (Ext)")
void findWithNotInOperatorExt() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/film;desc")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "film_id=out=(2,3,5)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(2), hasSize(2))))
.andExpect(jsonPath("$[0].film_id").value(1))
.andExpect(jsonPath("$[1].film_id").value(4))
.andDo(document("mysql-find-films-with-not-in-operator-ext"));
}
@Test
@DisplayName("Test find with Like Operator")
void findWithLikeOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/film;desc")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "title=like=ACADEMY")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1), hasSize(1))))
.andExpect(jsonPath("$[0].film_id").value(1))
.andDo(document("mysql-find-films-with-like-operator"));
}
@Test
@DisplayName("Test find with Starts With Operator")
void findWithStartsWithOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/film;desc")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "title=startWith=ACAD")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1), hasSize(1))))
.andExpect(jsonPath("$[0].film_id").value(1))
.andDo(document("mysql-find-films-starts-with-operator"));
}
@Test
@DisplayName("Test find with Ends With Operator")
void findWithEndsWithOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/film;desc")
.accept(APPLICATION_JSON)
.param("fields", "film_id")
.param("filter", "title=endWith=DINOSAUR")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1), hasSize(1))))
.andExpect(jsonPath("$[0].film_id").value(1))
.andDo(document("mysql-find-films-ends-with-operator"));
}
@Test
@DisplayName("Should return 4xx when using equals operator with an invalid column")
void findWithEqualsOperator_givenInvalidColumn_shouldReturn4xx() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/film")
.accept(APPLICATION_JSON)
.param("filter", "actor_id==206")
)
.andExpect(status().is4xxClientError())
.andExpect(jsonPath("$.detail").value("Failed to parse RQL - Column not found film.actor_id"));
}
@Test
@DisplayName("Test find with Not Like Operator")
void findWithNotLikeOperator() throws Exception {
mockMvc.perform(get( VERSION+"/mysqldb/film")
.accept(MediaType.APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "title=nk=ACADEMY")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*", hasSize(3)))
.andExpect(jsonPath("$[0].film_id", equalTo(2)))
.andExpect(jsonPath("$[0].title", equalTo("ACE GOLDFINGER")))
.andExpect(jsonPath("$[1].film_id", equalTo(3)))
.andExpect(jsonPath("$[1].title", equalTo("ADAPTATION HOLES")))
.andExpect(jsonPath("$[2].film_id", equalTo(4)))
.andExpect(jsonPath("$[2].title", equalTo("AFFAIR PREJUDICE")))
.andDo(document("mysql-find-films-with-not-like-operator"));
}
@Test
@DisplayName("Test find with Equals OR StartWith Operator")
void findWithEqualsAndStartWithCombinationalOperator() throws Exception {
mockMvc.perform(get( VERSION+"/mysqldb/film")
.accept(MediaType.APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "film_id==2")
.param("filter", "title=like=ACADEMY")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*", hasSize(2)))
.andExpect(jsonPath("$[0].film_id", equalTo(1)))
.andExpect(jsonPath("$[0].title", equalTo("ACADEMY DINOSAUR")))
.andExpect(jsonPath("$[1].film_id", equalTo(2)))
.andExpect(jsonPath("$[1].title", equalTo("ACE GOLDFINGER")))
.andDo(document("mysql-find-films-with-equals-or-like-operator"));
}
@Test
@DisplayName("Test find with Equals AND Like Operator")
void findWithEqualsAndLikeCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/film")
.accept(APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "film_id==2;title=like=ACE")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$[0].film_id", equalTo(2)))
.andExpect(jsonPath("$[0].title", equalTo("ACE GOLDFINGER")))
.andDo(document("mysql-find-films-with-equals-and-like-operator"));
}
@Test
@DisplayName("Test find with Equals and Like and In Operator")
void findWithEqualsAndLikeAndInCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/film")
.accept(APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "film_id==2;title=like=ACE;rating=in=(G, mysqldb)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$[0].film_id", equalTo(2)))
.andExpect(jsonPath("$[0].title", equalTo("ACE GOLDFINGER")))
.andDo(document("mysql-find-films-with-equals-and-like-and-in-operator"));
}
@Test
@DisplayName("Test find with Equals OR Like OR In Operator")
void findWithEqualsOrLikeOrInCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/film")
.accept(APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "film_id==2")
.param("filter", "title=like=ACADEMY")
.param("filter", "rating=in=(G, mysqldb)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(3)))
.andExpect(jsonPath("$[0].film_id", equalTo(1)))
.andExpect(jsonPath("$[0].title", equalTo("ACADEMY DINOSAUR")))
.andExpect(jsonPath("$[1].film_id", equalTo(2)))
.andExpect(jsonPath("$[1].title", equalTo("ACE GOLDFINGER")))
.andExpect(jsonPath("$[2].film_id", equalTo(4)))
.andExpect(jsonPath("$[2].title", equalTo("AFFAIR PREJUDICE")))
.andDo(document("mysql-find-films-with-equals-or-like-or-in-operator"));
}
@Test
@DisplayName("Test find with Equals And Like And Not In Operator")
void findWithEqualsAndLikeAndNotInCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/film")
.accept(APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "film_id==2;title=like=ACE;rating=out=(G, mysqldb)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isEmpty())
.andDo(document("mysql-find-films-with-equals-and-like-and-out-operator"));
}
@Test
@DisplayName("Test find with Equals OR Like OR Not In Operator")
void findWithEqualsOrLikeOrNotInCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/film")
.accept(APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "film_id==2")
.param("filter", "title=like=ACADEMY")
.param("filter", "rating=out=(G, mysqldb)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(3)))
.andExpect(jsonPath("$[0].film_id", equalTo(1)))
.andExpect(jsonPath("$[0].title", equalTo("ACADEMY DINOSAUR")))
.andExpect(jsonPath("$[1].film_id", equalTo(2)))
.andExpect(jsonPath("$[1].title", equalTo("ACE GOLDFINGER")))
.andExpect(jsonPath("$[2].film_id", equalTo(3)))
.andExpect(jsonPath("$[2].title", equalTo("ADAPTATION HOLES")))
.andDo(document("mysql-find-films-with-equals-or-like-or-out-operator"));
}
@Test
@DisplayName("Test find with Equals and Like and In And Greater Than Equals Operator")
void findWithEqualsAndLikeAndInAbdGreaterThanEualsCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/film")
.accept(APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "film_id==2;title=like=ACE;rating=in=(G, mysqldb);language_id=ge=1")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$[0].film_id", equalTo(2)))
.andExpect(jsonPath("$[0].title", equalTo("ACE GOLDFINGER")))
.andDo(document("mysql-find-films-with-equals-and-like-and-in-and-greater-equal-operator"));
}
@Test
@DisplayName("Test find with Equals and Like and In And Greater Than Operator")
void findWithEqualsAndLikeAndInAbdGreaterThanCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/film")
.accept(APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "film_id==2;title=like=ACE;rating=in=(G, mysqldb);language_id=gt=1")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*", hasSize(0)))
.andDo(document("mysqldb-find-films-with-equals-and-like-and-in-and-greater-operator"));
}
@Test
@DisplayName("Test find with Equals and Like and In And Less Than Equals Operator")
void findWithEqualsAndLikeAndInAndLessThanEqualsCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/film")
.accept(APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "film_id==2;title=like=ACE;rating=in=(G, mysqldb);language_id=le=2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$[0].film_id", equalTo(2)))
.andExpect(jsonPath("$[0].title", equalTo("ACE GOLDFINGER")))
.andDo(document("mysql-find-films-with-equals-and-like-and-in-and-less-equal-operator"));
}
@Test
@DisplayName("Test find with Equals and Like and In And Less Than Operator")
void findWithEqualsAndLikeAndInAndLessThanCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/film")
.accept(APPLICATION_JSON)
.param("fields", "title,film_id")
.param("filter", "film_id==2;title=like=ACE;rating=in=(G, mysqldb);language_id=lt=1")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isEmpty())
.andExpect(jsonPath("$.*", hasSize(0)))
.andDo(document("mysql-find-films-with-equals-and-like-and-in-and-less-operator"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mysql/MySQLReadControllerDefaultFetchLimitTest.java
================================================
package com.homihq.db2rest.rest.mysql;
import com.homihq.db2rest.MySQLBaseIntegrationTest;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.springframework.http.MediaType;
import org.springframework.test.context.TestPropertySource;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.core.AnyOf.anyOf;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(3)
@TestPropertySource(properties = {"db2rest.defaultFetchLimit=5"})
public class MySQLReadControllerDefaultFetchLimitTest extends MySQLBaseIntegrationTest {
@Test
@DisplayName("Get all with default fetch limit set to 5")
void findAllPersonsWithDefaultFetchLimit5() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/person")
.accept(MediaType.APPLICATION_JSON)
)
.andExpect(status().isOk())
.andExpect(jsonPath("$", anyOf(hasSize(5))))
.andDo(document("mysqldb-find-all-persons-with-default-fetch-limit-5"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mysql/MySQLReadControllerTest.java
================================================
package com.homihq.db2rest.rest.mysql;
import com.homihq.db2rest.MySQLBaseIntegrationTest;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.springframework.http.MediaType;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.core.AnyOf.anyOf;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(1)
class MySQLReadControllerTest extends MySQLBaseIntegrationTest {
@Test
@DisplayName("Test find all films - all columns.")
void findAllFilms() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/film")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
//.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
//.andExpect(jsonPath("$.*", hasSize(4)))
.andExpect(jsonPath("$.*", anyOf(hasSize(4), hasSize(9), hasSize(8))))
.andExpect(jsonPath("$[0].*", hasSize(14)))
.andDo(document("mysql-get-all-films-all-columns"));
}
@Test
@DisplayName("Test find all films - 3 columns")
void findAllFilmsWithThreeCols() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/film")
.contentType(APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)
.param("fields", "title,description,release_year")
)
//.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(4), hasSize(9), hasSize(8))))
.andExpect(jsonPath("$[0].*", hasSize(3)))
.andDo(document("mysql-find-all-films-3-columns"));
}
@Test
@DisplayName("Test find all films - with column alias")
void findAllFilmsWithColumnAlias() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/film")
.contentType(APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)
.param("fields", "title,description,release_year:releaseYear")
)
//.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(4), hasSize(9), hasSize(8))))
.andExpect(jsonPath("$[0].title", notNullValue()))
.andExpect(jsonPath("$[0].description", notNullValue()))
.andExpect(jsonPath("$[0].releaseYear", notNullValue()))
.andDo(document("mysql-find-all-films-with-column-alias"));
}
@Test
@DisplayName("Get one")
void findOneFilm() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/film/one")
.accept(MediaType.APPLICATION_JSON)
.param("fields", "title")
.param("filter", "film_id==1"))
.andExpect(status().isOk())
.andDo(print())
.andDo(document("mysql-get-on-film"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mysql/MySQLTemplateControllerTest.java
================================================
package com.homihq.db2rest.rest.mysql;
import com.homihq.db2rest.MySQLBaseIntegrationTest;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.core.AnyOf.anyOf;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(9)
@DisplayName("Parameterized SQL template")
class MySQLTemplateControllerTest extends MySQLBaseIntegrationTest {
public final static int ID = 1;
@Test
@DisplayName("Test find all films with sql template")
void findAllFilms() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/sql/select_all")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(4), hasSize(9), hasSize(8))))
.andExpect(jsonPath("$[0].*", hasSize(14)))
.andDo(document("mysql-template-get-all-films-all-columns"));
}
@Test
@DisplayName("Find film by id with request param")
void findFilmByID() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/sql/select_by_id")
.param("film_id", String.valueOf(ID))
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(print())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1))))
.andDo(document("mysql-template-get-film-by-id-with-params"));
}
@Test
@DisplayName("Find film by id with headers")
void findFilmByIDWithHeader() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/sql/select_by_id")
.header("film_id", String.valueOf(ID))
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(print())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1))))
.andDo(document("mysql-template-get-film-by-id-with-headers"));
}
@Test
@DisplayName("Find film by id with custom path")
void findFilmByIDWithPath() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/sql/select_by_id/" + ID)
.header("paths", "film_id")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(print())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1))))
.andDo(document("mysql-template-get-film-by-id-with-user-path"));
}
@Test
@DisplayName("Failed to find film by id without provided param")
void findFilmByIDWithRequiredConstraint() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/sql/select_by_id_is_required")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().is4xxClientError())
.andDo(document("mysql-template-get-film-by-id-with-required-constraint"));
}
@Test
@DisplayName("Conditional render: select all when no request params")
void selectWithConditionalRenderNoRequestParams() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/sql/conditional_render_and_op")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(4), hasSize(9), hasSize(8))))
.andExpect(jsonPath("$[0].*", hasSize(14)))
.andDo(document("mysql-template-conditional-render-no-request-params"));
}
@Test
@DisplayName("Conditional render: select render one condition")
void selectWithConditionalRenderWithID() throws Exception {
var id = 4;
mockMvc.perform(get(VERSION + "/mysqldb/sql/conditional_render_and_op")
.param("film_id", String.valueOf(id))
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1))))
.andExpect(jsonPath("$[0].film_id").value(id))
.andDo(document("mysql-template-conditional-render-with-id-condition"));
}
@Test
@DisplayName("Conditional render: render both and operations")
void selectWithConditionalRenderWithField() throws Exception {
var id = 4;
var rating = "G";
mockMvc.perform(get(VERSION + "/mysqldb/sql/conditional_render_and_op")
.param("film_id", String.valueOf(id))
.param("rating", rating)
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1))))
.andExpect(jsonPath("$[0].film_id").value(id))
.andExpect(jsonPath("$[0].rating").value(rating))
.andDo(document("mysql-template-conditional-render-render-both-and-operations"));
}
@Test
@DisplayName("Conditional render join: skip render join, select film by id")
void selectWithConditionalRenderJoinWithoutInput() throws Exception {
var film_id = 1;
mockMvc.perform(get(VERSION + "/mysqldb/sql/conditional_render_join")
.param("film_id", String.valueOf(film_id))
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1))))
.andExpect(jsonPath("$[0].film_id").value(film_id))
.andDo(document("mysql-template-conditional-render-join-skip-render"));
}
@Test
@DisplayName("Conditional render join: execute rendered join")
void selectWithConditionalRenderJoin() throws Exception {
var film_id = 1;
var language_id = 1;
mockMvc.perform(get(VERSION + "/mysqldb/sql/conditional_render_join")
.param("film_id", String.valueOf(film_id))
.param("language_id", String.valueOf(language_id))
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1))))
.andExpect(jsonPath("$[0].film_id").value(film_id))
.andExpect(jsonPath("$[0].language_name").value("English"))
.andDo(document("mysql-template-conditional-render-join"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mysql/MySQLUpdateControllerTest.java
================================================
package com.homihq.db2rest.rest.mysql;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.MySQLBaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.equalTo;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.patch;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(70)
@TestWithResources
class MySQLUpdateControllerTest extends MySQLBaseIntegrationTest {
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@GivenJsonResource("/testdata/UPDATE_FILM_REQUEST.json")
Map UPDATE_FILM_REQUEST;
@GivenJsonResource("/testdata/UPDATE_NON_EXISTING_FILM_REQUEST.json")
Map UPDATE_NON_EXISTING_FILM_REQUEST;
@GivenJsonResource("/testdata/UPDATE_NON_EXISTING_TABLE.json")
Map UPDATE_NON_EXISTING_TABLE;
@GivenJsonResource("/testdata/UPDATE_FILMS_REQUEST.json")
Map UPDATE_FILMS_REQUEST;
@Test
@DisplayName("Update an existing film")
void updateExistingFilm() throws Exception {
mockMvc.perform(patch(VERSION + "/mysqldb/film")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("filter", "title==\"ACADEMY DINOSAUR\"")
.content(objectMapper.writeValueAsString(UPDATE_FILM_REQUEST))
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", equalTo(1)))
//.andDo(print())
.andDo(document("mysql-update-existing-film"));
}
@Test
@DisplayName("Update a non-existing film")
void updateNonExistingFilm() throws Exception {
mockMvc.perform(patch(VERSION + "/mysqldb/film")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("filter", "title==\"BAAHUBALI\"")
.content(objectMapper.writeValueAsString(UPDATE_NON_EXISTING_FILM_REQUEST))
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", equalTo(0)))
//.andDo(print())
.andDo(document("mysql-update-non-existing-film"));
}
@Test
@DisplayName("Update non-existing table")
void updateNonExistingTable() throws Exception {
mockMvc.perform(patch(VERSION + "/mysqldb/unknown_table")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("filter", "sample_col==\"sample value 1\"")
.content(objectMapper.writeValueAsString(UPDATE_NON_EXISTING_TABLE))
)
.andExpect(status().isNotFound())
//.andDo(print())
.andDo(document("mysql-update-non-existing-table"));
}
@Test
@DisplayName("Updating multiple films")
void updateMultipleColumns() throws Exception {
mockMvc.perform(patch(VERSION + "/mysqldb/film")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("filter", "rating==\"G\"")
.content(objectMapper.writeValueAsString(UPDATE_FILMS_REQUEST))
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", equalTo(2)))
//.andDo(print())
.andDo(document("mysql-update-multiple-films"));
}
//TODO - Add a test to update date field.
//TODO - Greater than, less than , equal to , between test for date
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mysql/ReadTwoTablesSameNameDiffSchemaTest.java
================================================
package com.homihq.db2rest.rest.mysql;
import com.homihq.db2rest.MySQLBaseIntegrationTest;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.hasSize;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(3)
class MySQLReadTwoTablesSameNameDiffSchemaTest extends MySQLBaseIntegrationTest {
@Test
@DisplayName("Test find all films - all columns - different schemas.")
void findUsersInTwoSchemas() throws Exception {
mockMvc.perform(get(VERSION + "/mysqldb/users")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.header("Accept-Profile", "sakila")
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(4)))
.andExpect(jsonPath("$[0].*", hasSize(5)))
.andDo(document("mysql-get-all-users-diff-schemas-sakila"));
mockMvc.perform(get(VERSION + "/mysqldb/users")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.header("Accept-Profile", "wakila")
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(4)))
.andExpect(jsonPath("$[0].*", hasSize(5)))
.andDo(document("mysql-get-all-users-diff-schemas-wakila"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/mysql/UpdateTwoTablesSameNameDiffSchemaTest.java
================================================
package com.homihq.db2rest.rest.mysql;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.MySQLBaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.equalTo;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.patch;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(71)
@TestWithResources
class MySQLUpdateTwoTablesSameNameDiffSchemaTest extends MySQLBaseIntegrationTest {
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@GivenJsonResource("/testdata/UPDATE_EMPLOYEE_REQUEST.json")
Map UPDATE_EMPLOYEE_REQUEST;
@Test
@DisplayName("Update employee diff schema")
void updateEmployee() throws Exception {
mockMvc.perform(patch(VERSION + "/mysqldb/employee")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.header("Content-Profile", "sakila")
.param("filter", "emp_id==1")
.content(objectMapper.writeValueAsString(UPDATE_EMPLOYEE_REQUEST))
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", equalTo(1)))
//.andDo(print())
.andDo(document("mysql-update-emp-sakila"));
mockMvc.perform(patch(VERSION + "/mysqldb/employee")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.header("Content-Profile", "wakila")
.param("filter", "emp_id==1")
.content(objectMapper.writeValueAsString(UPDATE_EMPLOYEE_REQUEST))
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", equalTo(1)))
//.andDo(print())
.andDo(document("mysql-update-emp-wakila"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/oracle/OracleBasicJoinControllerTest.java
================================================
package com.homihq.db2rest.rest.oracle;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.OracleBaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import java.util.List;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.nullValue;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(210)
@TestWithResources
@Disabled
class OracleBasicJoinControllerTest extends OracleBaseIntegrationTest {
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@GivenJsonResource("/testdata/LEFT_JOIN_ORACLE.json")
List> LEFT_JOIN;
@GivenJsonResource("/testdata/RIGHT_JOIN_ORACLE.json")
List> RIGHT_JOIN;
@Test
@DisplayName("Test left Join")
void testLeftJoin() throws Exception {
mockMvc.perform(post(VERSION + "/oradb/USERS/_expand")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(LEFT_JOIN))
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(4)))
.andExpect(jsonPath("$[0].*", hasSize(10)))
.andExpect(jsonPath("$[0].AUID", equalTo(1)))
.andExpect(jsonPath("$[0].APID", equalTo(1)))
.andExpect(jsonPath("$[1].AUID", equalTo(6)))
.andExpect(jsonPath("$[1].APID", nullValue()))
.andExpect(jsonPath("$[3].AUID", equalTo(4)))
.andExpect(jsonPath("$[3].APID", nullValue()))
.andExpect(jsonPath("$[3].FIRSTNAME", nullValue()))
.andDo(document("oracle-left-join"));
}
@Test
@DisplayName("Test right Join")
void testRightJoin() throws Exception {
mockMvc.perform(post(VERSION + "/oradb/USERS/_expand")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(RIGHT_JOIN))
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(4)))
.andExpect(jsonPath("$[0].*", hasSize(10)))
.andExpect(jsonPath("$[0].AUID", equalTo(1)))
.andExpect(jsonPath("$[0].APID", equalTo(1)))
.andExpect(jsonPath("$[0].USERNAME", equalTo("admin")))
.andExpect(jsonPath("$[0].FIRSTNAME", equalTo("Jack")))
.andExpect(jsonPath("$[1].AUID", equalTo(7)))
.andExpect(jsonPath("$[1].APID", equalTo(7)))
.andExpect(jsonPath("$[1].USERNAME", nullValue()))
.andExpect(jsonPath("$[1].FIRSTNAME", equalTo("Ivan")))
.andExpect(jsonPath("$[3].AUID", equalTo(3)))
.andExpect(jsonPath("$[3].APID", equalTo(2)))
.andExpect(jsonPath("$[3].USERNAME", nullValue()))
.andExpect(jsonPath("$[3].FIRSTNAME", equalTo("Tom")))
.andDo(document("oracle-right-join"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/oracle/OracleBulkCreateControllerTest.java
================================================
package com.homihq.db2rest.rest.oracle;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.OracleBaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.GivenTextResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import java.util.List;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasSize;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(281)
@TestWithResources
class OracleBulkCreateControllerTest extends OracleBaseIntegrationTest {
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@GivenJsonResource("/testdata/BULK_CREATE_FILM_REQUEST.json")
List> BULK_CREATE_FILM_REQUEST;
@GivenJsonResource("/testdata/BULK_CREATE_FILM_BAD_REQUEST.json")
List> BULK_CREATE_FILM_BAD_REQUEST;
@GivenTextResource("/testdata/CREATE_FILM_REQUEST_CSV.csv")
String CREATE_FILM_REQUEST_CSV;
@GivenTextResource("/testdata/CREATE_FILM_BAD_REQUEST_CSV.csv")
String CREATE_FILM_BAD_REQUEST_CSV;
@GivenJsonResource("/testdata/BULK_CREATE_DIRECTOR_REQUEST.json")
List> BULK_CREATE_DIRECTOR_REQUEST;
@GivenJsonResource("/testdata/BULK_CREATE_DIRECTOR_BAD_REQUEST.json")
List> BULK_CREATE_DIRECTOR_BAD_REQUEST;
@GivenJsonResource("/testdata/BULK_CREATE_REVIEW_REQUEST.json")
List> BULK_CREATE_REVIEW_REQUEST;
@Test
@DisplayName("Create many films.")
void create() throws Exception {
mockMvc.perform(post(VERSION + "/oradb/FILM/bulk")
.queryParam("sequences", "film_id:film_sequence")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(BULK_CREATE_FILM_REQUEST))
)
.andExpect(status().isCreated())
.andExpect(jsonPath("$.rows").isArray())
.andExpect(jsonPath("$.rows", hasSize(2)))
.andExpect(jsonPath("$.rows", hasItem(1)))
.andExpect(jsonPath("$.rows", hasItem(1)))
//.andExpect(jsonPath("$.generated_keys").isArray()) //TODO - push TSID columns
//.andExpect(jsonPath("$.generated_keys", hasSize(2)))
//.andExpect(jsonPath("$.generated_keys", allOf(notNullValue())))
//.andDo(print())
.andDo(document("oracle-bulk-create-films"));
}
@Test
@DisplayName("Create many films with CSV type.")
void createCSV() throws Exception {
mockMvc.perform(post(VERSION + "/oradb/FILM/bulk")
.queryParam("sequences", "film_id:film_sequence")
.contentType("text/csv").accept(APPLICATION_JSON)
.content(CREATE_FILM_REQUEST_CSV))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.rows", hasSize(2)))
.andExpect(jsonPath("$.rows", hasItem(1)))
//.andExpect(jsonPath("$.generated_keys", hasSize(2)))
//.andExpect(jsonPath("$.generated_keys", allOf(notNullValue())))
//.andDo(print())
.andDo(document("oracle-bulk-create-films-csv"));
}
@Test
@DisplayName("Create many films with CSV type resulting error.")
void createCSVWithError() throws Exception {
mockMvc.perform(post(VERSION + "/oradb/FILM/bulk")
.queryParam("sequences", "film_id:film_sequence")
.contentType("text/csv")
.accept(APPLICATION_JSON)
.content(CREATE_FILM_BAD_REQUEST_CSV))
.andExpect(status().isBadRequest())
//.andDo(print())
.andDo(document("oracle-bulk-create-films-csv-error"));
}
@Test
@DisplayName("Create many films with failure.")
void createError() throws Exception {
mockMvc.perform(post(VERSION + "/oradb/FILM/bulk")
.queryParam("sequences", "film_id:film_sequence")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(BULK_CREATE_FILM_BAD_REQUEST)))
.andExpect(status().isBadRequest())
// .andDo(print())
.andDo(document("oracle-bulk-create-films-error"));
}
@Test
@DisplayName("Create many directors.")
void createDirector() throws Exception {
mockMvc.perform(post(VERSION + "/oradb/DIRECTOR/bulk")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("tsIdEnabled", "true")
.content(objectMapper.writeValueAsString(BULK_CREATE_DIRECTOR_REQUEST))
)
.andExpect(status().isCreated())
//.andDo(print())
.andDo(document("oracle-bulk-create-directors"));
}
@Test
@DisplayName("Create many directors with wrong tsid type.")
void createDirectorWithWrongTsidType() throws Exception {
mockMvc.perform(post(VERSION + "/oradb/DIRECTOR/bulk")
.characterEncoding(UTF_8)
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.param("tsid", "director_id")
.param("tsidType", "string")
.header("Content-Profile", "sakila")
.content(objectMapper.writeValueAsString(BULK_CREATE_DIRECTOR_BAD_REQUEST))
)
.andExpect(status().isBadRequest())
//.andDo(print())
.andDo(document("oracle-bulk-create-directors-with-wrong-tsid-type"));
}
@Test
@DisplayName("Create reviews with default tsid type.")
void createReviewWithDefaultTsidType() throws Exception {
mockMvc.perform(post(VERSION + "/oradb/REVIEW/bulk")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("tsIdEnabled", "true")
.content(objectMapper.writeValueAsString(BULK_CREATE_REVIEW_REQUEST))
)
.andExpect(status().isCreated())
//.andDo(print())
.andDo(document("oracle-bulk-create-reviews-with-default-tsid-type"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/oracle/OracleCountControllerTest.java
================================================
package com.homihq.db2rest.rest.oracle;
import com.homihq.db2rest.OracleBaseIntegrationTest;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.springframework.http.MediaType;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(202)
class OracleCountControllerTest extends OracleBaseIntegrationTest {
@Test
@DisplayName("Get count")
void findFilmCount() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/FILM/count")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
//.andDo(print())
.andDo(document("oracle-get-film-count"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/oracle/OracleCreateControllerTest.java
================================================
package com.homihq.db2rest.rest.oracle;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.OracleBaseIntegrationTest;
import com.jayway.jsonpath.JsonPath;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(280)
@TestWithResources
class OracleCreateControllerTest extends OracleBaseIntegrationTest {
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@GivenJsonResource("/testdata/CREATE_FILM_REQUEST.json")
Map CREATE_FILM_REQUEST;
@GivenJsonResource("/testdata/CREATE_FILM_REQUEST_ERROR.json")
Map CREATE_FILM_REQUEST_ERROR;
@GivenJsonResource("/testdata/CREATE_VANITY_VAN_REQUEST.json")
Map CREATE_VANITY_VAN_REQUEST;
@GivenJsonResource("/testdata/CREATE_DIRECTOR_REQUEST.json")
Map CREATE_DIRECTOR_REQUEST;
@GivenJsonResource("/testdata/CREATE_FILM_REQUEST_MISSING_PAYLOAD.json")
Map CREATE_FILM_REQUEST_MISSING_PAYLOAD;
@Test
@DisplayName("Create a film.")
void create() throws Exception {
mockMvc.perform(post(VERSION + "/oradb/FILM")
.queryParam("sequences", "film_id:film_sequence")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST))
)
//.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
//.andExpect(jsonPath("$.keys.GENERATED_KEY").exists())
//.andExpect(jsonPath("$.keys.GENERATED_KEY", equalTo(5)))
.andDo(document("oracle-create-a-film"));
}
@Test
@DisplayName("Test Create a film with error.")
void createError() throws Exception {
mockMvc.perform(post(VERSION + "/oradb/FILM")
.queryParam("sequences", "film_id:film_sequence")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST_ERROR)))
//.andDo(print())
.andExpect(status().isBadRequest())
.andDo(document("oracle-create-a-film-error"));
}
@Test
@DisplayName("Test create a film - non existent table.")
void createNonExistentTable() throws Exception {
mockMvc.perform(post(VERSION + "/oradb/FILMS")
.queryParam("sequences", "film_id:film_sequence")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST)))
.andExpect(status().isNotFound())
//.andDo(print())
.andDo(document("oracle-create-a-film-no-table"));
}
@Test
@DisplayName("Test Create a director - TSID enabled")
void createDirectorWithTSIDEnabled() throws Exception {
mockMvc.perform(post(VERSION + "/oradb/DIRECTOR")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("tsIdEnabled", "true")
.content(objectMapper.writeValueAsString(CREATE_DIRECTOR_REQUEST)))
.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
//.andExpect(jsonPath("$.keys.director_id").exists())
// .andExpect(jsonPath("$.keys.director_id").isNumber())
.andDo(document("oracle-create-a-director-tsid-enabled"));
}
@Test
@DisplayName("Create a director - with TSID explicitly OFF")
void createDirectorWithTSIDOff() throws Exception {
mockMvc.perform(post(VERSION + "/oradb/DIRECTOR")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("tsIdEnabled", "false")
.content(objectMapper.writeValueAsString(CREATE_DIRECTOR_REQUEST)))
.andExpect(status().isBadRequest())
//.andDo(print())
.andDo(document("oracle-create-a-director-with-tsid-OFF"));
}
@Test
@DisplayName("Test Create a Vanity Van - with varchar tsid type")
void createVanityVanWithVarcharTsIdType() throws Exception {
//TODO - MySQL return keys not working
mockMvc.perform(post(VERSION + "/oradb/VANITY_VAN")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("tsIdEnabled", "true")
.content(objectMapper.writeValueAsString(CREATE_VANITY_VAN_REQUEST)))
//.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
//.andExpect(jsonPath("$.keys.vanity_van_id").exists())
//.andExpect(jsonPath("$.keys.vanity_van_id").isString())
.andDo(document("oracle-create-a-vanity-van-tsid-varchar"));
}
@Test
@DisplayName("Create a film with subset of columns")
void createFilmWithSubsetOfColumns() throws Exception {
var result = mockMvc.perform(post(VERSION + "/oradb/FILM")
.queryParam("sequences", "film_id:film_sequence")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.queryParam("columns", "title,description,language_id")
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST)))
.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
.andExpect(jsonPath("$.keys").exists())
//.andExpect(jsonPath("$.keys.GENERATED_KEY", equalTo(5)))
.andExpect(jsonPath("$.keys.FILM_ID").isNumber())
.andDo(document("oracle-create-a-film-col-subset"))
.andReturn();
var pk = JsonPath.read(result.getResponse().getContentAsString(), "$.keys.FILM_ID");
mockMvc.perform(get(VERSION + "/oradb/FILM")
.accept(APPLICATION_JSON)
.queryParam("fields", "title,release_year")
.queryParam("filter", String.format("film_id==%s", pk)))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$[0].TITLE", equalTo("Dunki")))
.andExpect(jsonPath("$[0].RELEASE_YEAR").doesNotExist());
// cleanup data
assertTrue(deleteRow("film", "film_id", (int) pk));
}
@Test
@DisplayName("Ignore if columns parameter is blank")
void shouldIgnoreWhenColumnsQueryParamIsEmpty() throws Exception {
var result = mockMvc.perform(post(VERSION + "/oradb/FILM")
.queryParam("sequences", "film_id:film_sequence")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.queryParam("columns", "")
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST)))
.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
.andExpect(jsonPath("$.keys").exists())
.andDo(document("oracle-create-a-film-columns-not-specified"))
.andReturn();
var pk = JsonPath.read(result.getResponse().getContentAsString(), "$.keys.FILM_ID");
mockMvc.perform(get(VERSION + "/oradb/FILM")
.accept(APPLICATION_JSON)
.queryParam("fields", "title,release_year")
.queryParam("filter", String.format("film_id==%s", pk)))
.andExpect(status().isOk())
.andExpect(jsonPath("$[0].TITLE", equalTo("Dunki")))
.andExpect(jsonPath("$[0].RELEASE_YEAR", equalTo("2023")))
.andDo(print())
;
// cleanup data
assertTrue(deleteRow("film", "film_id", (int) pk));
}
@Test
@DisplayName("Column is present in columns param but not in payload")
void columnIsPresentInColumnsQueryParamButNotInPayload() throws Exception {
mockMvc.perform(post(VERSION + "/oradb/FILM")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.queryParam("columns", "title,description,language_id")
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST_MISSING_PAYLOAD))) //description is not in payload will be set to null
.andExpect(status().isBadRequest())
//.andDo(print())
.andDo(document("oracle-create-a-film-missing-payload-attribute-error"));
}
@Test
@DisplayName("Column violates not-null constraint")
void column_violates_not_null_constraint() throws Exception {
mockMvc.perform(post(VERSION + "/oradb/FILM")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.queryParam("columns", "title,description")
.content(objectMapper.writeValueAsString(CREATE_FILM_REQUEST)))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.detail",
containsString("ORA-01400: cannot insert NULL")))
.andDo(print())
.andDo(document("oracle-create-a-film-not-null-constraint"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/oracle/OracleCrossJoinControllerTest.java
================================================
package com.homihq.db2rest.rest.oracle;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.OracleBaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import java.util.List;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(211)
@TestWithResources
@Disabled
class OracleCrossJoinControllerTest extends OracleBaseIntegrationTest {
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@GivenJsonResource("/testdata/CROSS_JOIN_USERS_ORACLE.json")
List> CROSS_JOIN;
@GivenJsonResource("/testdata/CROSS_JOIN_TOPS_ORACLE.json")
List> CROSS_JOIN_TOPS;
@Test
@DisplayName("Test cross Join - Users")
void testCrossJoin() throws Exception {
mockMvc.perform(post(VERSION + "/oradb/USERS/_expand")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(CROSS_JOIN))
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(16)))
.andExpect(jsonPath("$[0].*", hasSize(10)))
.andExpect(jsonPath("$[0].AUID", equalTo(1)))
.andExpect(jsonPath("$[0].APID", equalTo(1)))
.andExpect(jsonPath("$[0].FIRSTNAME", equalTo("Jack")))
.andExpect(jsonPath("$[1].AUID", equalTo(2)))
.andExpect(jsonPath("$[1].APID", equalTo(1)))
.andExpect(jsonPath("$[1].FIRSTNAME", equalTo("Jack")))
.andDo(document("oracle-cross-join-users"));
}
@Test
@DisplayName("Test cross Join - Tops")
void testCrossJoinTops() throws Exception {
mockMvc.perform(post(VERSION + "/oradb/TOPS/_expand")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(CROSS_JOIN_TOPS))
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(9)))
.andExpect(jsonPath("$[0].*", hasSize(6)))
.andExpect(jsonPath("$[0].TOP_ITEM", equalTo("sweater")))
.andExpect(jsonPath("$[0].BOTTOM_ITEM", equalTo("jeans")))
.andExpect(jsonPath("$[0].COLOR", equalTo("red")))
.andExpect(jsonPath("$[0].botColor", equalTo("blue")))
.andDo(document("oracle-cross-join-tops"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/oracle/OracleDateTimeAllTest.java
================================================
package com.homihq.db2rest.rest.oracle;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.OracleBaseIntegrationTest;
import com.homihq.db2rest.rest.DateTimeUtil;
import com.jayway.jsonpath.JsonPath;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.HashMap;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.patch;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(292)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class OracleDateTimeAllTest extends OracleBaseIntegrationTest {
private final String dateTime = "2024-03-15T10:30:45.000";
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@Test
@Order(1)
@DisplayName("Test Create a actor with datetime fields")
void createActorWithDateTimeFields() throws Exception {
// Prepare the request with datetime fields
Map actorRequestWithDateTime = new HashMap<>();
actorRequestWithDateTime.put("first_name", "Collective");
actorRequestWithDateTime.put("last_name", "Unconscious");
actorRequestWithDateTime.put("last_update", "2020-03-15T14:30:45.000");
mockMvc.perform(post(VERSION + "/oradb/ACTOR")
.queryParam("sequences", "actor_id:actor_sequence")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(actorRequestWithDateTime)))
.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
.andDo(document("oracle-create-an-actor-with-datetime"));
}
@Test
@Order(1)
@DisplayName("Test Create an actor with error timestamp field")
void createActorWithErrorDateTimeField() throws Exception {
Map actorRequestWithErrorDateTime = new HashMap<>();
actorRequestWithErrorDateTime.put("first_name", "Hero");
actorRequestWithErrorDateTime.put("last_name", "shadow");
actorRequestWithErrorDateTime.put("last_update", "2023-15-35T14:75:90");
mockMvc.perform(post(VERSION + "/oradb/ACTOR")
.queryParam("sequences", "actor_id:actor_sequence")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(actorRequestWithErrorDateTime)))
.andDo(print())
.andExpect(status().isBadRequest())
.andDo(document("oracle-create-an-actor-with-error-timestamp"));
}
@Test
@Order(2)
@DisplayName("Test update an actor with datetime field")
void updateActorWithDateTimeField() throws Exception {
// Prepare the request with datetime fields
Map updateActorRequestWithDateTime = new HashMap<>();
updateActorRequestWithDateTime.put("last_update", dateTime);
mockMvc.perform(patch(VERSION + "/oradb/ACTOR")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.param("filter", "last_name == Unconscious")
.content(objectMapper.writeValueAsString(updateActorRequestWithDateTime)))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", equalTo(1)))
.andDo(document("oracle-update-an-actor-with-datetime"));
}
@Test
@Order(3)
@DisplayName("Test get an actor with datetime fields")
void getActorWithDateTimeFields() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/ACTOR")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.param("filter", "first_name == Collective"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("[0].LAST_NAME", equalTo("Unconscious")))
.andDo(result -> assertEquals(dateTime, DateTimeUtil.utcToLocalTimestampStringOracle(result)))
.andDo(document("oracle-get-an-actor-with-datetime"));
}
//@Test
@Order(3)
@DisplayName("Test get an actor filter by timestamp")
void getActorFilterByTimeStamp() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/ACTOR")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.param("filter", "last_update <= \"2024-03-15T10:30:45.00Z\""))
.andDo(print())
.andExpect(status().isOk())
//.andExpect(jsonPath("$.*").isArray())
//.andExpect(jsonPath("[0].LAST_NAME", equalTo("Unconscious")))
.andDo(result -> assertEquals(dateTime, DateTimeUtil.utcToLocalTimestampStringOracle(result)))
.andDo(document("oracle-get-an-actor-filter-by-timestamp"));
}
//@Test
@Order(4)
@DisplayName("Test delete an actor by timestamp")
void deleteActorByTimeStamp() throws Exception {
mockMvc.perform(delete(VERSION + "/oradb/ACTOR")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.param("filter", "last_update <= \"2024-03-15T10:30:45.00Z\""))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.rows", equalTo(1)))
.andDo(document("oracle-delete-an-actor-by-timestamp"));
}
@ParameterizedTest
@MethodSource("isoDateTimeFormats")
@Order(5)
@DisplayName("Test ISO Date Time formats")
void createActorWithIsoDateTimeFormats(String isoDateTime) throws Exception {
// Prepare the request with datetime fields
Map actorRequestWithDateTime = new HashMap<>();
actorRequestWithDateTime.put("first_name", "Graeme");
actorRequestWithDateTime.put("last_name", "Smith");
actorRequestWithDateTime.put("last_update", isoDateTime);
var result = mockMvc.perform(post(VERSION + "/oradb/ACTOR")
.queryParam("sequences", "actor_id:actor_sequence")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(actorRequestWithDateTime)))
.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
.andDo(document("oracle-create-an-actor-with-datetime"))
.andReturn();
var pk = JsonPath.read(result.getResponse().getContentAsString(), "$.keys.ACTOR_ID");
assertTrue(deleteRow("actor", "actor_id", (int) pk));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/oracle/OracleDeleteAllTest.java
================================================
package com.homihq.db2rest.rest.oracle;
import com.homihq.db2rest.OracleBaseIntegrationTest;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.springframework.test.context.TestPropertySource;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(291)
@TestPropertySource(properties = {"db2rest.allowSafeDelete=false"})
class OracleDeleteAllTest extends OracleBaseIntegrationTest {
@Test
@DisplayName("Delete all records while allowSafeDelete=false")
void deleteAllWithAllowSafeDeleteFalse() throws Exception {
mockMvc.perform(delete(VERSION + "/oradb/COUNTRY")
.accept(APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", Matchers.equalTo(6)))
.andDo(document("oracle-delete-all"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/oracle/OracleDeleteControllerTest.java
================================================
package com.homihq.db2rest.rest.oracle;
import com.homihq.db2rest.OracleBaseIntegrationTest;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(290)
class OracleDeleteControllerTest extends OracleBaseIntegrationTest {
@Test
@DisplayName("Delete a Director")
void delete_single_record() throws Exception {
mockMvc.perform(delete(VERSION + "/oradb/DIRECTOR")
.accept(APPLICATION_JSON)
.param("filter", "first_name==\"Alex\""))
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", equalTo(1)))
//.andDo(print())
.andDo(document("oracle-delete-a-director"));
}
@Test
@DisplayName("Delete all records while allowSafeDelete=true")
void delete_all_records_with_allow_safe_delete_true() throws Exception {
mockMvc.perform(delete(VERSION + "/oradb/DIRECTOR")
.accept(APPLICATION_JSON))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.detail",
containsString("Invalid delete operation , safe set to true")))
//.andDo(print())
.andDo(document("oracle-delete-a-director"));
}
@Test
@DisplayName("Column Does Not Exist")
void column_does_not_exist() throws Exception {
mockMvc.perform(delete(VERSION + "/oradb/DIRECTOR")
.accept(APPLICATION_JSON)
.param("filter", "_name==\"Alex\""))
.andExpect(status().isNotFound())
.andDo(print())
.andExpect(jsonPath("$.detail",
containsString("Column not found DIRECTOR._name")))
.andDo(document("oracle-delete-a-director"));
}
@Disabled
@Test
@DisplayName("Foreign Key Constraint Violation")
void foreign_key_constraint_violation() throws Exception {
mockMvc.perform(delete(VERSION + "/oradb/LANGUAGE")
.accept(APPLICATION_JSON)
.param("filter", "name==\"English\""))
.andDo(print())
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.detail",
containsString("Cannot delete or update a parent row: a foreign key constraint fails")))
.andDo(document("oracle-delete-a-director"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/oracle/OracleInnerJoinControllerTest.java
================================================
package com.homihq.db2rest.rest.oracle;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.OracleBaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import java.util.List;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.anyOf;
import static org.hamcrest.Matchers.hasSize;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(212)
@TestWithResources
@Disabled
class OracleInnerJoinControllerTest extends OracleBaseIntegrationTest {
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@GivenJsonResource("/testdata/INNER_JOIN_ORACLE.json")
List> INNER_JOIN;
@Test
@DisplayName("Test inner Join")
void testInnerJoin() throws Exception {
mockMvc.perform(post(VERSION + "/oradb/REVIEW/_expand")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(INNER_JOIN))
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1), hasSize(3))))
.andExpect(jsonPath("$[0].*", hasSize(7)))
//.andExpect(jsonPath("$[0].review_id", equalTo("ABC123")))
//.andExpect(jsonPath("$[0].film_id", equalTo(1)))
//.andExpect(jsonPath("$[0].title", equalTo("ACADEMY DINOSAUR")))
.andDo(document("oracle-inner-join"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/oracle/OracleInnerJoinMultiTableControllerTest.java
================================================
package com.homihq.db2rest.rest.oracle;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.OracleBaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import java.util.List;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(213)
@TestWithResources
@Disabled
class OracleInnerJoinMultiTableControllerTest extends OracleBaseIntegrationTest {
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@GivenJsonResource("/testdata/INNER_JOIN_MULTI_TABLE_ORACLE.json")
List> INNER_JOIN_MULTI_TABLE;
@Test
@DisplayName("Test inner multi-table Join")
void testInnerMultiTable() throws Exception {
mockMvc.perform(post(VERSION + "/oradb/FILM/_expand")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(INNER_JOIN_MULTI_TABLE))
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$[0].*", hasSize(17)))
.andExpect(jsonPath("$[0].FILM_ID", equalTo(1)))
.andExpect(jsonPath("$[0].LANGUAGE_ID", equalTo(1)))
.andExpect(jsonPath("$[0].ACTOR_ID", equalTo(1)))
.andExpect(jsonPath("$[0].FIRST_NAME", equalTo("PENELOPE")))
.andExpect(jsonPath("$[0].LAST_NAME", equalTo("GUINESS")))
.andDo(document("oracle-inner-multi-table-join"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/oracle/OracleInnerSelfJoinControllerTest.java
================================================
package com.homihq.db2rest.rest.oracle;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.OracleBaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import java.util.List;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestWithResources
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(214)
@Disabled
class OracleInnerSelfJoinControllerTest extends OracleBaseIntegrationTest {
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@GivenJsonResource("/testdata/INNER_SELF_JOIN_ORACLE.json")
List> INNER_SELF_JOIN;
@Test
@DisplayName("Test inner self Join")
void testInnerSelfJoin() throws Exception {
mockMvc.perform(post(VERSION + "/oradb/FILM/_expand")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(INNER_SELF_JOIN))
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
//.andExpect(jsonPath("$.*", hasSize(1)))
//.andExpect(jsonPath("$[0].*", hasSize(17)))
//.andExpect(jsonPath("$[0].film_id", equalTo(1)))
//.andExpect(jsonPath("$[0].language_id", equalTo(1)))
//.andExpect(jsonPath("$[0].actor_id", equalTo(1)))
//.andExpect(jsonPath("$[0].first_name", equalTo("PENELOPE")))
//.andExpect(jsonPath("$[0].last_name", equalTo("GUINESS")))
.andDo(document("oracle-inner-multi-table-join"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/oracle/OracleJsonFileCreateControllerTest.java
================================================
package com.homihq.db2rest.rest.oracle;
import com.homihq.db2rest.OracleBaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.web.servlet.MvcResult;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(281)
@TestWithResources
class OracleJsonFileCreateControllerTest extends OracleBaseIntegrationTest {
Path dir = FileSystems.getDefault().getPath("src/test/resources/testdata");
Path actorFile = dir.resolve("actor.json");
Path filmFile = dir.resolve("BULK_CREATE_FILM_REQUEST.json");
Path nonArrayActorFile = dir.resolve("CREATE_ACTOR_REQUEST.json");
Path directorFile = dir.resolve("director.json");
@Test
@DisplayName("Create many actors via JSON file upload.")
void uploadActorsFile() throws Exception {
MockMultipartFile file = new MockMultipartFile("file", "actor.json",
"application/json", Files.readAllBytes(actorFile));
MvcResult mvcResult = mockMvc.perform(multipart(VERSION + "/oradb/ACTOR/upload")
.file(file)
.contentType("multipart/form-data")
.accept(APPLICATION_JSON))
.andDo(print())
.andReturn();
mockMvc.perform(asyncDispatch(mvcResult))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row").isNumber())
.andExpect(jsonPath("$.row").value(10000))
.andExpect(jsonPath("$.keys").value("Bulk insert completed successfully"))
.andDo(document("oracle-create-actors-file-upload"));
}
@Test
@DisplayName("Error create actor via JSON file upload.")
void uploadActorFileNonJsonArray() throws Exception {
MockMultipartFile file = new MockMultipartFile("file", nonArrayActorFile.toString(),
"application/json", Files.readAllBytes(nonArrayActorFile));
mockMvc.perform(multipart(VERSION + "/oradb/ACTOR/upload")
.file(file)
.contentType("multipart/form-data")
.accept(APPLICATION_JSON))
.andDo(print())
.andExpect(status().isBadRequest())
.andDo(document("oracle-error-create-actors-file-upload"));
}
@Test
@DisplayName("Create many directors via file upload.")
void createDirectorViaUpload() throws Exception {
MockMultipartFile file = new MockMultipartFile("file", "bulkDirector.json",
"application/json", Files.readAllBytes(directorFile));
MvcResult mvcResult = mockMvc.perform(multipart(VERSION + "/oradb/DIRECTOR/upload")
.file(file)
.contentType("multipart/form-data")
.accept(APPLICATION_JSON))
.andDo(print())
.andReturn();
mockMvc.perform(asyncDispatch(mvcResult))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row").isNumber())
.andExpect(jsonPath("$.row").value(600))
.andExpect(jsonPath("$.keys").value("Bulk insert completed successfully"))
.andDo(document("oracle-create-directors-file-upload"));
}
@Test
@DisplayName("Create many films via file upload.")
void createFilmsViaUpload() throws Exception {
MockMultipartFile file = new MockMultipartFile("file", "bulkFilm.json",
"application/json", Files.readAllBytes(filmFile));
MvcResult mvcResult = mockMvc.perform(multipart(VERSION + "/oradb/FILM/upload")
.file(file)
.queryParam("sequences", "film_id:film_sequence")
.contentType("multipart/form-data")
.accept(APPLICATION_JSON))
.andDo(print())
.andReturn();
mockMvc.perform(asyncDispatch(mvcResult))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row").isNumber())
.andExpect(jsonPath("$.row").value(2))
.andExpect(jsonPath("$.keys").value("Bulk insert completed successfully"))
.andDo(document("oracle-create-films-file-upload"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/oracle/OracleProcedureControllerTest.java
================================================
package com.homihq.db2rest.rest.oracle;
import com.homihq.db2rest.OracleBaseIntegrationTest;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.springframework.http.MediaType;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.instanceOf;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(250)
class OracleProcedureControllerTest extends OracleBaseIntegrationTest {
//@Test
@DisplayName("Execute stored procedure on oracle db")
void execute() throws Exception {
var json = """
{
"movieTitle": "ACADEMY DINOSAUR"
}
""";
mockMvc.perform(post(VERSION + "/oradb/procedure/GetMovieRentalRateProc")
.characterEncoding(UTF_8)
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.content(json))
.andExpect(status().isOk())
.andExpect(jsonPath("$", instanceOf(Map.class)))
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$.P_RENTAL_RATE", equalTo(0.99)))
//.andDo(print())
.andDo(document("oracle-execute-procedure"));
}
//@Test
@DisplayName("Execute stored procedure UpdateUserProc on oracle db ")
void executeUpdateUserProc() throws Exception {
var json = """
{
"userId": 1
}
""";
mockMvc.perform(post(VERSION + "/oradb/procedure/UpdateUserProc")
.characterEncoding(UTF_8)
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.content(json))
.andExpect(status().isOk())
.andDo(print())
.andExpect(jsonPath("$", instanceOf(Map.class)))
.andExpect(jsonPath("$.*", hasSize(1)))
.andDo(document("oracle-execute-update-user-proc"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/oracle/OracleRSqlOperatorReadControllerTest.java
================================================
package com.homihq.db2rest.rest.oracle;
import com.homihq.db2rest.OracleBaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.springframework.http.MediaType;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.core.AnyOf.anyOf;
import static org.hamcrest.Matchers.equalTo;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(204)
@TestWithResources
class OracleRSqlOperatorReadControllerTest extends OracleBaseIntegrationTest {
@Test
@DisplayName("Test find with Equals Operator")
void findWithEqualsOperator() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/FILM")
.accept(APPLICATION_JSON)
.param("fields", "TITLE,DESCRIPTION,RELEASE_YEAR")
.param("filter", "FILM_ID==2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1), hasSize(1))))
.andExpect(jsonPath("$[0].TITLE", notNullValue()))
.andExpect(jsonPath("$[0].DESCRIPTION", notNullValue()))
.andExpect(jsonPath("$[0].RELEASE_YEAR", notNullValue()))
.andDo(document("oracle-find-films-with-equals-operator"));
}
@Test
@DisplayName("Test find with Not Equals Operator")
void findWithNotEqualsOperator() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/FILM")
.accept(APPLICATION_JSON)
.param("fields", "FILM_ID")
.param("filter", "FILM_ID!=2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(3), hasSize(3))))
.andExpect(jsonPath("$[0].FILM_ID").value(1))
.andExpect(jsonPath("$[1].FILM_ID").value(3))
.andExpect(jsonPath("$[2].FILM_ID").value(4))
.andDo(document("oracle-find-films-with-not-equals-operator"));
}
@Test
@DisplayName("Test find with Greater than Operator")
void findWithGreaterThanOperator() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/FILM;desc")
.accept(APPLICATION_JSON)
.param("fields", "FILM_ID")
.param("filter", "FILM_ID=gt=2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(2), hasSize(2))))
.andExpect(jsonPath("$[0].FILM_ID").value(3))
.andExpect(jsonPath("$[1].FILM_ID").value(4))
.andDo(document("oracle-find-films-with-greater-operator"));
}
@Test
@DisplayName("Test find with Greater than Equals Operator")
void findWithGreaterThanEqualsOperator() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/FILM;desc")
.accept(APPLICATION_JSON)
.param("fields", "FILM_ID")
.param("filter", "FILM_ID=ge=2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(3), hasSize(3))))
.andExpect(jsonPath("$[0].FILM_ID").value(2))
.andExpect(jsonPath("$[1].FILM_ID").value(3))
.andExpect(jsonPath("$[2].FILM_ID").value(4))
.andDo(document("oracle-find-films-with-greater-equals-operator"));
}
@Test
@DisplayName("Test find with Less than Operator")
void findWithLessThanOperator() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/FILM;desc")
.accept(APPLICATION_JSON)
.param("fields", "FILM_ID")
.param("filter", "FILM_ID=lt=2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1), hasSize(1))))
.andExpect(jsonPath("$[0].FILM_ID").value(1))
.andDo(document("oracle-find-films-with-less-operator"));
}
@Test
@DisplayName("Test find with Less than Equals Operator")
void findWithLessThanEqualsOperator() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/FILM;desc")
.accept(APPLICATION_JSON)
.param("fields", "FILM_ID")
.param("filter", "FILM_ID=le=2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(2), hasSize(2))))
.andExpect(jsonPath("$[0].FILM_ID").value(1))
.andExpect(jsonPath("$[1].FILM_ID").value(2))
.andDo(document("oracle-find-films-with-less-equals-operator"));
}
@Test
@DisplayName("Test find with In Operator")
void findWithInOperator() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/FILM;desc")
.accept(APPLICATION_JSON)
.param("fields", "FILM_ID")
.param("filter", "FILM_ID=in=(2,3,5)")
)
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(2), hasSize(2))))
.andExpect(jsonPath("$[0].FILM_ID").value(2))
.andExpect(jsonPath("$[1].FILM_ID").value(3))
.andDo(document("oracle-find-films-with-in-operator"));
}
@Test
@DisplayName("Test find with Not In Operator")
void findWithNotInOperator() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/FILM;desc")
.accept(APPLICATION_JSON)
.param("fields", "FILM_ID")
.param("filter", "FILM_ID=out=(2,3,5)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(2), hasSize(2))))
.andExpect(jsonPath("$[0].FILM_ID").value(1))
.andExpect(jsonPath("$[1].FILM_ID").value(4))
.andDo(document("oracle-find-films-with-not-in-operator"));
}
@Test
@DisplayName("Test find with Not In Operator (Ext)")
void findWithNotInOperatorExt() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/FILM;desc")
.accept(APPLICATION_JSON)
.param("fields", "FILM_ID")
.param("filter", "film_id=out=(2,3,5)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(2), hasSize(2))))
.andExpect(jsonPath("$[0].FILM_ID").value(1))
.andExpect(jsonPath("$[1].FILM_ID").value(4))
.andDo(document("oracle-find-films-with-not-in-operator-ext"));
}
@Test
@DisplayName("Test find with Like Operator")
void findWithLikeOperator() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/FILM;desc")
.accept(APPLICATION_JSON)
.param("fields", "FILM_ID")
.param("filter", "TITLE=like=ACADEMY")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1), hasSize(1))))
.andExpect(jsonPath("$[0].FILM_ID").value(1))
.andDo(document("oracle-find-films-with-like-operator"));
}
@Test
@DisplayName("Test find with Starts With Operator")
void findWithStartsWithOperator() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/FILM;desc")
.accept(APPLICATION_JSON)
.param("fields", "FILM_ID")
.param("filter", "TITLE=startWith=ACAD")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1), hasSize(1))))
.andExpect(jsonPath("$[0].FILM_ID").value(1))
.andDo(document("oracle-find-films-starts-with-operator"));
}
@Test
@DisplayName("Test find with Ends With Operator")
void findWithEndsWithOperator() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/FILM;desc")
.accept(APPLICATION_JSON)
.param("fields", "FILM_ID")
.param("filter", "TITLE=endWith=DINOSAUR")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1), hasSize(1))))
.andExpect(jsonPath("$[0].FILM_ID").value(1))
.andDo(document("oracle-find-films-ends-with-operator"));
}
@Test
@DisplayName("Should return 4xx when using equals operator with an invalid column")
void findWithEqualsOperator_givenInvalidColumn_shouldReturn4xx() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/FILM")
.accept(APPLICATION_JSON)
.param("filter", "ACTOR_ID==206")
)
.andExpect(status().is4xxClientError())
.andExpect(jsonPath("$.detail").value("Failed to parse RQL - Column not found FILM.ACTOR_ID"));
}
@Test
@DisplayName("Test find with Not Like Operator")
void findWithNotLikeOperator() throws Exception {
mockMvc.perform(get( VERSION+"/oradb/FILM")
.accept(MediaType.APPLICATION_JSON)
.param("fields", "TITLE,FILM_ID")
.param("filter", "TITLE=nk=ACADEMY")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*", hasSize(3)))
.andExpect(jsonPath("$[0].FILM_ID", equalTo(2)))
.andExpect(jsonPath("$[0].TITLE", equalTo("ACE GOLDFINGER")))
.andExpect(jsonPath("$[1].FILM_ID", equalTo(3)))
.andExpect(jsonPath("$[1].TITLE", equalTo("ADAPTATION HOLES")))
.andExpect(jsonPath("$[2].FILM_ID", equalTo(4)))
.andExpect(jsonPath("$[2].TITLE", equalTo("AFFAIR PREJUDICE")))
.andDo(document("oracle-find-film-with-not-like-operator"));
}
@Test
@DisplayName("Test find with Equals OR StartWith Operator")
void findWithEqualsAndStartWithCombinationalOperator() throws Exception {
mockMvc.perform(get( VERSION+"/oradb/FILM")
.accept(MediaType.APPLICATION_JSON)
.param("fields", "TITLE,FILM_ID")
.param("filter", "FILM_ID==2")
.param("filter", "TITLE=like=ACADEMY")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*", hasSize(2)))
.andExpect(jsonPath("$[0].FILM_ID", equalTo(1)))
.andExpect(jsonPath("$[0].TITLE", equalTo("ACADEMY DINOSAUR")))
.andExpect(jsonPath("$[1].FILM_ID", equalTo(2)))
.andExpect(jsonPath("$[1].TITLE", equalTo("ACE GOLDFINGER")))
.andDo(document("oracle-find-film-with-equals-or-like-operator"));
}
@Test
@DisplayName("Test find with Equals AND Like Operator")
void findWithEqualsAndLikeCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/FILM")
.accept(APPLICATION_JSON)
.param("fields", "TITLE,FILM_ID")
.param("filter", "FILM_ID==2;TITLE=like=ACE")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$[0].FILM_ID", equalTo(2)))
.andExpect(jsonPath("$[0].TITLE", equalTo("ACE GOLDFINGER")))
.andDo(document("oracle-find-film-with-equals-and-like-operator"));
}
@Test
@DisplayName("Test find with Equals and Like and In Operator")
void findWithEqualsAndLikeAndInCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/FILM")
.accept(APPLICATION_JSON)
.param("fields", "TITLE,FILM_ID")
.param("filter", "FILM_ID==2;TITLE=like=ACE;rating=in=(G, oradb)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$[0].FILM_ID", equalTo(2)))
.andExpect(jsonPath("$[0].TITLE", equalTo("ACE GOLDFINGER")))
.andDo(document("oracle-find-film-with-equals-and-like-and-in-operator"));
}
@Test
@DisplayName("Test find with Equals OR Like OR In Operator")
void findWithEqualsOrLikeOrInCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/FILM")
.accept(APPLICATION_JSON)
.param("fields", "TITLE,FILM_ID")
.param("filter", "FILM_ID==2")
.param("filter", "TITLE=like=ACADEMY")
.param("filter", "rating=in=(G, oradb)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(3)))
.andExpect(jsonPath("$[0].FILM_ID", equalTo(1)))
.andExpect(jsonPath("$[0].TITLE", equalTo("ACADEMY DINOSAUR")))
.andExpect(jsonPath("$[1].FILM_ID", equalTo(2)))
.andExpect(jsonPath("$[1].TITLE", equalTo("ACE GOLDFINGER")))
.andExpect(jsonPath("$[2].FILM_ID", equalTo(4)))
.andExpect(jsonPath("$[2].TITLE", equalTo("AFFAIR PREJUDICE")))
.andDo(document("oracle-find-film-with-equals-or-like-or-in-operator"));
}
@Test
@DisplayName("Test find with Equals And Like And Not In Operator")
void findWithEqualsAndLikeAndNotInCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/FILM")
.accept(APPLICATION_JSON)
.param("fields", "TITLE,FILM_ID")
.param("filter", "FILM_ID==2;TITLE=like=ACE;RATING=out=(G, oradb)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isEmpty())
.andDo(document("oracle-find-film-with-equals-and-like-and-out-operator"));
}
@Test
@DisplayName("Test find with Equals OR Like OR Not In Operator")
void findWithEqualsOrLikeOrNotInCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/FILM")
.accept(APPLICATION_JSON)
.param("fields", "TITLE,FILM_ID")
.param("filter", "FILM_ID==2")
.param("filter", "TITLE=like=ACADEMY")
.param("filter", "RATING=out=(G, oradb)")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(3)))
.andExpect(jsonPath("$[0].FILM_ID", equalTo(1)))
.andExpect(jsonPath("$[0].TITLE", equalTo("ACADEMY DINOSAUR")))
.andExpect(jsonPath("$[1].FILM_ID", equalTo(2)))
.andExpect(jsonPath("$[1].TITLE", equalTo("ACE GOLDFINGER")))
.andExpect(jsonPath("$[2].FILM_ID", equalTo(3)))
.andExpect(jsonPath("$[2].TITLE", equalTo("ADAPTATION HOLES")))
.andDo(document("oracle-find-film-with-equals-or-like-or-out-operator"));
}
@Test
@DisplayName("Test find with Equals and Like and In And Greater Than Equals Operator")
void findWithEqualsAndLikeAndInAbdGreaterThanEqualsCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/FILM")
.accept(APPLICATION_JSON)
.param("fields", "TITLE,FILM_ID")
.param("filter", "FILM_ID==2;TITLE=like=ACE;RATING=in=(G, oradb);LANGUAGE_ID=ge=1")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$[0].FILM_ID", equalTo(2)))
.andExpect(jsonPath("$[0].TITLE", equalTo("ACE GOLDFINGER")))
.andDo(document("oracle-find-film-with-equals-and-like-and-in-and-greater-equal-operator"));
}
@Test
@DisplayName("Test find with Equals and Like and In And Greater Than Operator")
void findWithEqualsAndLikeAndInAbdGreaterThanCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/FILM")
.accept(APPLICATION_JSON)
.param("fields", "TITLE,FILM_ID")
.param("filter", "FILM_ID==2;TITLE=like=ACE;RATING=in=(G, oradb);LANGUAGE_ID=gt=1")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*", hasSize(0)))
.andDo(document("oradb-find-film-with-equals-and-like-and-in-and-greater-operator"));
}
@Test
@DisplayName("Test find with Equals and Like and In And Less Than Equals Operator")
void findWithEqualsAndLikeAndInAndLessThanEqualsCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/FILM")
.accept(APPLICATION_JSON)
.param("fields", "TITLE,FILM_ID")
.param("filter", "FILM_ID==2;TITLE=like=ACE;RATING=in=(G, oradb);LANGUAGE_ID=le=2")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(1)))
.andExpect(jsonPath("$[0].FILM_ID", equalTo(2)))
.andExpect(jsonPath("$[0].TITLE", equalTo("ACE GOLDFINGER")))
.andDo(document("oracle-find-film-with-equals-and-like-and-in-and-less-equal-operator"));
}
@Test
@DisplayName("Test find with Equals and Like and In And Less Than Operator")
void findWithEqualsAndLikeAndInAndLessThanCombinationalOperator() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/FILM")
.accept(APPLICATION_JSON)
.param("fields", "TITLE,FILM_ID")
.param("filter", "FILM_ID==2;TITLE=like=ACE;RATING=in=(G, oradb);LANGUAGE_ID=lt=1")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isEmpty())
.andExpect(jsonPath("$.*", hasSize(0)))
.andDo(document("oracle-find-film-with-equals-and-like-and-in-and-less-operator"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/oracle/OracleReadControllerDefaultFetchLimitTest.java
================================================
package com.homihq.db2rest.rest.oracle;
import com.homihq.db2rest.OracleBaseIntegrationTest;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.springframework.http.MediaType;
import org.springframework.test.context.TestPropertySource;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.core.AnyOf.anyOf;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
//@Order(203)
@TestPropertySource(properties = {"db2rest.defaultFetchLimit=5"})
class OracleReadControllerDefaultFetchLimitTest extends OracleBaseIntegrationTest {
@Test
@DisplayName("Get all with default fetch limit set to 5")
void findAllPersonsWithDefaultFetchLimit5() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/PERSON")
.accept(MediaType.APPLICATION_JSON)
)
.andExpect(status().isOk())
.andExpect(jsonPath("$", anyOf(hasSize(5))))
.andDo(document("oracle-find-all-persons-with-default-fetch-limit-5"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/oracle/OracleReadControllerTest.java
================================================
package com.homihq.db2rest.rest.oracle;
import com.homihq.db2rest.OracleBaseIntegrationTest;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.springframework.http.MediaType;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.core.AnyOf.anyOf;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(201)
class OracleReadControllerTest extends OracleBaseIntegrationTest {
@Test
@DisplayName("Test find all films - all columns.")
void findAllFilms() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/FILM")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
//.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
//.andExpect(jsonPath("$.*", hasSize(4)))
.andExpect(jsonPath("$.*", anyOf(hasSize(4), hasSize(9), hasSize(8))))
.andExpect(jsonPath("$[0].*", hasSize(14)))
.andDo(document("oracle-get-all-films-all-columns"));
}
@Test
@DisplayName("Test find all films - 3 columns")
void findAllFilmsWithThreeCols() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/FILM")
.contentType(APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)
.param("fields", "title,description,release_year")
)
//.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(4), hasSize(9), hasSize(8))))
.andExpect(jsonPath("$[0].*", hasSize(3)))
.andDo(document("oracle-find-all-films-3-columns"));
}
@Test
@DisplayName("Test find all films - with column alias")
void findAllFilmsWithColumnAlias() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/FILM")
.contentType(APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)
.param("fields", "title,description,release_year:releaseYear")
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(4), hasSize(9), hasSize(8))))
.andExpect(jsonPath("$[0].TITLE", notNullValue()))
.andExpect(jsonPath("$[0].DESCRIPTION", notNullValue()))
.andExpect(jsonPath("$[0].releaseYear", notNullValue()))
.andDo(document("oracle-find-all-films-with-column-alias"));
}
@Test
@DisplayName("Get one")
void findOneFilm() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/FILM/one")
.accept(MediaType.APPLICATION_JSON)
.param("fields", "title")
.param("filter", "film_id==1"))
.andExpect(status().isOk())
//.andDo(print())
.andDo(document("oracle-get-on-film"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/oracle/OracleTemplateControllerTest.java
================================================
package com.homihq.db2rest.rest.oracle;
import com.homihq.db2rest.OracleBaseIntegrationTest;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.core.AnyOf.anyOf;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(202)
@DisplayName("Parameterized SQL template")
class OracleTemplateControllerTest extends OracleBaseIntegrationTest {
public final static int ID = 1;
@Test
@DisplayName("Test find all films with sql template")
void findAllFilms() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/sql/select_all")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(4), hasSize(9), hasSize(8))))
.andExpect(jsonPath("$[0].*", hasSize(14)))
.andDo(document("ora-template-get-all-films-all-columns"));
}
@Test
@DisplayName("Find film by id with request param")
void findFilmByID() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/sql/select_by_id")
.param("film_id", String.valueOf(ID))
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(print())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1))))
.andDo(document("ora-template-get-film-by-id-with-params"));
}
@Test
@DisplayName("Find film by id with headers")
void findFilmByIDWithHeader() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/sql/select_by_id")
.header("film_id", String.valueOf(ID))
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(print())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1))))
.andDo(document("ora-template-get-film-by-id-with-headers"));
}
@Test
@DisplayName("Find film by id with custom path")
void findFilmByIDWithPath() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/sql/select_by_id/" + ID)
.header("paths", "film_id")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(print())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1))))
.andDo(document("ora-template-get-film-by-id-with-user-path"));
}
@Test
@DisplayName("Failed to find film by id without provided param")
void findFilmByIDWithRequiredConstraint() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/sql/select_by_id_is_required")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().is4xxClientError())
.andDo(document("ora-template-get-film-by-id-with-required-constraint"));
}
@Test
@DisplayName("Conditional render: select all when no request params")
void selectWithConditionalRenderNoRequestParams() throws Exception {
mockMvc.perform(get(VERSION + "/oradb/sql/conditional_render_and_op")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(4), hasSize(9), hasSize(8))))
.andExpect(jsonPath("$[0].*", hasSize(14)))
.andDo(document("ora-template-conditional-render-no-request-params"));
}
@Test
@DisplayName("Conditional render: select render one condition")
void selectWithConditionalRenderWithID() throws Exception {
var id = 4;
mockMvc.perform(get(VERSION + "/oradb/sql/conditional_render_and_op")
.param("film_id", String.valueOf(id))
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1))))
.andExpect(jsonPath("$[0].FILM_ID").value(id))
.andDo(document("ora-template-conditional-render-with-id-condition"));
}
@Test
@DisplayName("Conditional render: render both and operations")
void selectWithConditionalRenderWithField() throws Exception {
var id = 4;
var rating = "G";
mockMvc.perform(get(VERSION + "/oradb/sql/conditional_render_and_op")
.param("film_id", String.valueOf(id))
.param("rating", rating)
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1))))
.andExpect(jsonPath("$[0].FILM_ID").value(id))
.andExpect(jsonPath("$[0].RATING").value(rating))
.andDo(document("ora-template-conditional-render-render-both-and-operations"));
}
@Test
@DisplayName("Conditional render join: skip render join, select film by id")
void selectWithConditionalRenderJoinWithoutInput() throws Exception {
var film_id = 1;
mockMvc.perform(get(VERSION + "/oradb/sql/conditional_render_join")
.param("film_id", String.valueOf(film_id))
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1))))
.andExpect(jsonPath("$[0].FILM_ID").value(film_id))
.andDo(document("ora-template-conditional-render-join-skip-render"));
}
@Test
@DisplayName("Conditional render join: execute rendered join")
void selectWithConditionalRenderJoin() throws Exception {
var film_id = 1;
var language_id = 1;
mockMvc.perform(get(VERSION + "/oradb/sql/conditional_render_join")
.param("film_id", String.valueOf(film_id))
.param("language_id", String.valueOf(language_id))
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", anyOf(hasSize(1))))
.andExpect(jsonPath("$[0].FILM_ID").value(film_id))
//.andExpect(jsonPath("$[0].LANGUAGE_NAME").value("English")) //TODO Fix
.andDo(document("ora-template-conditional-render-join"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/oracle/OracleUpdateControllerTest.java
================================================
package com.homihq.db2rest.rest.oracle;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.OracleBaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.equalTo;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.patch;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(270)
@TestWithResources
class OracleUpdateControllerTest extends OracleBaseIntegrationTest {
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@GivenJsonResource("/testdata/UPDATE_FILM_REQUEST.json")
Map UPDATE_FILM_REQUEST;
@GivenJsonResource("/testdata/UPDATE_NON_EXISTING_FILM_REQUEST.json")
Map UPDATE_NON_EXISTING_FILM_REQUEST;
@GivenJsonResource("/testdata/UPDATE_NON_EXISTING_TABLE.json")
Map UPDATE_NON_EXISTING_TABLE;
@GivenJsonResource("/testdata/UPDATE_FILMS_REQUEST.json")
Map UPDATE_FILMS_REQUEST;
@Test
@DisplayName("Update an existing film")
void updateExistingFilm() throws Exception {
mockMvc.perform(patch(VERSION + "/oradb/FILM")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("filter", "title==\"ACADEMY DINOSAUR\"")
.content(objectMapper.writeValueAsString(UPDATE_FILM_REQUEST))
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", equalTo(1)))
.andDo(document("oracle-update-existing-film"));
}
@Test
@DisplayName("Update a non-existing film")
void updateNonExistingFilm() throws Exception {
mockMvc.perform(patch(VERSION + "/oradb/FILM")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("filter", "title==\"BAAHUBALI\"")
.content(objectMapper.writeValueAsString(UPDATE_NON_EXISTING_FILM_REQUEST))
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", equalTo(0)))
//.andDo(print())
.andDo(document("oracle-update-non-existing-film"));
}
@Test
@DisplayName("Update non-existing table")
void updateNonExistingTable() throws Exception {
mockMvc.perform(patch(VERSION + "/oradb/unknown_table")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("filter", "sample_col==\"sample value 1\"")
.content(objectMapper.writeValueAsString(UPDATE_NON_EXISTING_TABLE))
)
.andExpect(status().isNotFound())
//.andDo(print())
.andDo(document("mysql-update-non-existing-table"));
}
@Test
@DisplayName("Updating multiple films")
void updateMultipleColumns() throws Exception {
mockMvc.perform(patch(VERSION + "/oradb/FILM")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("filter", "rating==\"G\"")
.content(objectMapper.writeValueAsString(UPDATE_FILMS_REQUEST))
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", equalTo(2)))
//.andDo(print())
.andDo(document("mysql-update-multiple-films"));
}
//TODO - Add a test to update date field.
//TODO - Greater than, less than , equal to , between test for date
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/pg/PGDateTimeAllTest.java
================================================
package com.homihq.db2rest.rest.pg;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.PostgreSQLBaseIntegrationTest;
import com.homihq.db2rest.rest.DateTimeUtil;
import com.jayway.jsonpath.JsonPath;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.HashMap;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.patch;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(192)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class PGDateTimeAllTest extends PostgreSQLBaseIntegrationTest {
private final String dateTime = "2024-03-15T10:30:45.000";
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@Test
@Order(1)
@DisplayName("Test Create a actor with datetime fields")
void createActorWithDateTimeFields() throws Exception {
// Prepare the request with datetime fields
Map actorRequestWithDateTime = new HashMap<>();
actorRequestWithDateTime.put("first_name", "Collective");
actorRequestWithDateTime.put("last_name", "Unconscious");
actorRequestWithDateTime.put("last_update", "2020-03-15T14:30:45.000");
mockMvc.perform(post(VERSION + "/pgsqldb/actor")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(actorRequestWithDateTime)))
.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
.andDo(document("pg-create-an-actor-with-datetime"));
}
@Test
@Order(1)
@DisplayName("Test Create an actor with error timestamp field")
void createActorWithErrorDateTimeField() throws Exception {
Map actorRequestWithErrorDateTime = new HashMap<>();
actorRequestWithErrorDateTime.put("first_name", "Hero");
actorRequestWithErrorDateTime.put("last_name", "shadow");
actorRequestWithErrorDateTime.put("last_update", "2023-15-35T14:75:90");
mockMvc.perform(post(VERSION + "/pgsqldb/actor")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(actorRequestWithErrorDateTime)))
.andDo(print())
.andExpect(status().isBadRequest())
.andDo(document("pg-create-an-actor-with-error-timestamp"));
}
@Test
@Order(2)
@DisplayName("Test update an actor with datetime field")
void updateActorWithDateTimeField() throws Exception {
// Prepare the request with datetime fields
Map updateActorRequestWithDateTime = new HashMap<>();
updateActorRequestWithDateTime.put("last_update", dateTime);
mockMvc.perform(patch(VERSION + "/pgsqldb/actor")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.param("filter", "last_name == Unconscious")
.content(objectMapper.writeValueAsString(updateActorRequestWithDateTime)))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.rows", equalTo(1)))
.andDo(document("pg-update-an-actor-with-datetime"));
}
@Test
@Order(3)
@DisplayName("Test get an actor with datetime fields")
void getActorWithDateTimeFields() throws Exception {
mockMvc.perform(get(VERSION + "/pgsqldb/actor")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("filter", "first_name == Collective"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andDo(result -> assertEquals(dateTime, DateTimeUtil.utcToLocalTimestampString(result)))
.andDo(document("pg-get-an-actor-with-datetime"));
}
@Test
@Order(3)
@DisplayName("Test get an actor filter by timestamp")
void getActorFilterByTimeStamp() throws Exception {
mockMvc.perform(get(VERSION + "/pgsqldb/actor")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("filter", "last_update == \"2024-03-15T10:30:45.00Z\""))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("[0].last_name", equalTo("Unconscious")))
.andDo(result -> assertEquals(dateTime, DateTimeUtil.utcToLocalTimestampString(result)))
.andDo(document("pg-get-an-actor-filter-by-timestamp"));
}
@Test
@Order(4)
@DisplayName("Test delete an actor by timestamp")
void deleteActorByTimeStamp() throws Exception {
mockMvc.perform(delete(VERSION + "/pgsqldb/actor")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.param("filter", "last_update == \"2024-03-15T10:30:45.00Z\""))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.rows", equalTo(1)))
.andDo(document("pg-delete-an-actor-by-timestamp"));
}
@ParameterizedTest
@MethodSource("isoDateTimeFormats")
@Order(5)
@DisplayName("Test ISO Date Time formats")
void createActorWithIsoDateTimeFormats(String isoDateTime) throws Exception {
// Prepare the request with datetime fields
Map actorRequestWithDateTime = new HashMap<>();
actorRequestWithDateTime.put("first_name", "Graeme");
actorRequestWithDateTime.put("last_name", "Smith");
actorRequestWithDateTime.put("last_update", isoDateTime);
var result = mockMvc.perform(post(VERSION + "/pgsqldb/actor")
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(actorRequestWithDateTime)))
.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.row", equalTo(1)))
.andDo(document("pg-create-an-actor-with-datetime"))
.andReturn();
var pk = JsonPath.read(result.getResponse().getContentAsString(), "$.keys.actor_id");
assertTrue(deleteRow("actor", "actor_id", (int) pk));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/pg/PgBasicJoinControllerTest.java
================================================
package com.homihq.db2rest.rest.pg;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.PostgreSQLBaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import java.util.List;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.nullValue;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(110)
@TestWithResources
class PgBasicJoinControllerTest extends PostgreSQLBaseIntegrationTest {
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@GivenJsonResource("/testdata/LEFT_JOIN.json")
List> LEFT_JOIN;
@GivenJsonResource("/testdata/RIGHT_JOIN.json")
List> RIGHT_JOIN;
@Test
@DisplayName("Test left Join")
void testLeftJoin() throws Exception {
mockMvc.perform(post(VERSION + "/pgsqldb/users/_expand")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(LEFT_JOIN))
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(4)))
.andExpect(jsonPath("$[0].*", hasSize(11)))
.andExpect(jsonPath("$[0].auid", equalTo(1)))
.andExpect(jsonPath("$[0].apid", equalTo(1)))
.andExpect(jsonPath("$[1].auid", equalTo(2)))
.andExpect(jsonPath("$[1].apid", nullValue()))
.andExpect(jsonPath("$[3].auid", equalTo(6)))
.andExpect(jsonPath("$[3].apid", nullValue()))
.andExpect(jsonPath("$[3].firstname", nullValue()))
.andDo(document("pgsql-left-join"));
}
@Test
@DisplayName("Test right Join")
void testRightJoin() throws Exception {
mockMvc.perform(post(VERSION + "/pgsqldb/users/_expand")
.contentType(APPLICATION_JSON).accept(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(RIGHT_JOIN))
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.*").isArray())
.andExpect(jsonPath("$.*", hasSize(4)))
.andExpect(jsonPath("$[0].*", hasSize(11)))
.andExpect(jsonPath("$[0].auid", equalTo(1)))
.andExpect(jsonPath("$[0].apid", equalTo(1)))
.andExpect(jsonPath("$[0].apid", equalTo(1)))
.andExpect(jsonPath("$[0].firstname", equalTo("Jack")))
.andExpect(jsonPath("$[1].auid", equalTo(5)))
.andExpect(jsonPath("$[1].apid", equalTo(4)))
.andExpect(jsonPath("$[1].username", nullValue()))
.andExpect(jsonPath("$[1].firstname", equalTo("Bill")))
.andExpect(jsonPath("$[3].auid", equalTo(7)))
.andExpect(jsonPath("$[3].apid", equalTo(7)))
.andExpect(jsonPath("$[3].username", nullValue()))
.andExpect(jsonPath("$[3].firstname", equalTo("Ivan")))
.andDo(document("mysql-right-join"));
}
}
================================================
FILE: db2rest-api/api-rest/src/test/java/com/homihq/db2rest/rest/pg/PgBulkCreateControllerTest.java
================================================
package com.homihq.db2rest.rest.pg;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.homihq.db2rest.PostgreSQLBaseIntegrationTest;
import io.hosuaby.inject.resources.junit.jupiter.GivenJsonResource;
import io.hosuaby.inject.resources.junit.jupiter.GivenTextResource;
import io.hosuaby.inject.resources.junit.jupiter.TestWithResources;
import io.hosuaby.inject.resources.junit.jupiter.WithJacksonMapper;
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
import java.util.List;
import java.util.Map;
import static com.homihq.db2rest.rest.RdbmsRestApi.VERSION;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.notNullValue;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(182)
@TestWithResources
class PgBulkCreateControllerTest extends PostgreSQLBaseIntegrationTest {
@WithJacksonMapper
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
@GivenJsonResource("/testdata/BULK_CREATE_FILM_REQUEST.json")
List> BULK_CREATE_FILM_REQUEST;
@GivenJsonResource("/testdata/BULK_CREATE_FILM_BAD_REQUEST.json")
List> BULK_CREATE_FILM_BAD_REQUEST;
@GivenTextResource("/testdata/CREATE_FILM_REQUEST_CSV.csv")
String CREATE_FILM_REQUEST_CSV;
@GivenTextResource("/testdata/CREATE_FILM_BAD_REQUEST_CSV.csv")
String CREATE_FILM_BAD_REQUEST_CSV;
@GivenJsonResource("/testdata/BULK_CREATE_DIRECTOR_REQUEST.json")
List> BULK_CREATE_DIRECTOR_REQUEST;
@GivenJsonResource("/testdata/BULK_CREATE_DIRECTOR_BAD_REQUEST.json")
List