From 553049043ac70398e4efc7f03aff42abf7aecebb Mon Sep 17 00:00:00 2001 From: Luis Rojas Date: Sun, 2 Feb 2025 11:57:11 -0600 Subject: [PATCH 1/2] test(karate): add apartment tests --- .../features/apartments/apartment.feature | 156 ++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 tests/karate/features/apartments/apartment.feature diff --git a/tests/karate/features/apartments/apartment.feature b/tests/karate/features/apartments/apartment.feature new file mode 100644 index 0000000..bb53b2b --- /dev/null +++ b/tests/karate/features/apartments/apartment.feature @@ -0,0 +1,156 @@ +Feature: Apartment Management + +Background: + * url baseUrl + * print '=== Loading feature file ===' + * print 'URL set to:', baseUrl + * header x-hasura-admin-secret = adminSecret + +# Check GraphQL endpoint health +Scenario: Check GraphQL endpoint health + Given path '/' + And request { query: "query { __typename }" } + When method POST + Then status 200 + And match response == { data: { __typename: 'query_root' } } + +# Check apartments schema +Scenario: Check apartments schema + Given path '/' + And request + """ + { + "query": "query { __type(name: \"apartments\") { name fields { name type { name kind } } } }" + } + """ + When method POST + Then status 200 + And match response.errors == '#notpresent' + * print 'Schema:', response.data.__type + +# Create new apartment +Scenario: Create new apartment + Given path '/' + And request + """ + { + "query": "mutation($owner_id: String!, $name: String!, $price: Float!, $warranty_deposit: Float!, $coordinates: point!, $location_area: geometry!, $address: jsonb!, $available_from: timestamptz!) { + insert_apartments_one(object: { owner_id: $owner_id, name: $name, price: $price, warranty_deposit: $warranty_deposit, coordinates: $coordinates, location_area: $location_area, address: $address, available_from: $available_from }) { + id + } + }", + "variables": { + "owner_id": "user-123", + "name": "Cozy Apartment", + "price": 1200.00, + "warranty_deposit": 2400.00, + "coordinates": { "x": 40.7128, "y": -74.0060 }, + "location_area": "POLYGON((...))", + "address": { "street": "Main St", "city": "New York", "zip": "10001" }, + "available_from": "2025-02-02T00:00:00Z" + } + } + """ + When method POST + Then status 201 + And match response.errors == '#notpresent' + * def created_id = response.data.insert_apartments_one.id + +# Query apartment by ID +Scenario: Query apartment by ID + Given path '/' + And request + """ + { + "query": "query GetApartment($id: uuid!) { + apartments_by_pk(id: $id) { + id + name + price + warranty_deposit + coordinates + location_area + address + available_from + created_at + } + }", + "variables": { + "id": "#(created_id)" + } + } + """ + When method POST + Then status 200 + And match response.errors == '#notpresent' + And match response.data.apartments_by_pk != null + +# Update apartment details +Scenario: Update apartment details + Given path '/' + And request + """ + { + "query": "mutation UpdateApartment($id: uuid!, $price: Float!) { + update_apartments_by_pk( + pk_columns: {id: $id}, + _set: {price: $price} + ) { + id + price + } + }", + "variables": { + "id": "#(created_id)", + "price": 1300.00 + } + } + """ + When method POST + Then status 200 + And match response.errors == '#notpresent' + And match response.data.update_apartments_by_pk.price == 1300.00 + +# Delete apartment +Scenario: Delete apartment + Given path '/' + And request + """ + { + "query": "mutation DeleteApartment($id: uuid!) { + delete_apartments_by_pk(id: $id) { + id + } + }", + "variables": { + "id": "#(created_id)" + } + } + """ + When method POST + Then status 200 + And match response.errors == '#notpresent' + And match response.data.delete_apartments_by_pk.id == "#(created_id)" + +# List apartments +Scenario: List apartments + Given path '/' + And request + """ + { + "query": "query ListApartments { + apartments(limit: 10, order_by: {created_at: desc}) { + id + name + price + available_from + created_at + } + }" + } + """ + When method POST + Then status 200 + And match response.errors == '#notpresent' + And match response.data.apartments != null + And match response.data.apartments == '#[_ > 0]' From 5c1f102d7177450a777f7a5418201c590140eaa9 Mon Sep 17 00:00:00 2001 From: Luis Rojas Date: Wed, 5 Feb 2025 22:13:33 -0600 Subject: [PATCH 2/2] test(karate): fix karate config --- config.yaml | 3 + docker-compose-test.yml | 76 +++++++++++++++---- .../src/test/resources/karate-config.js | 12 +-- 3 files changed, 70 insertions(+), 21 deletions(-) diff --git a/config.yaml b/config.yaml index 725c800..bb13618 100644 --- a/config.yaml +++ b/config.yaml @@ -1,6 +1,9 @@ version: 3 endpoint: http://localhost:8080 +admin_secret: myadminsecretkey metadata_directory: metadata +migrations_directory: migrations +seeds_directory: seeds actions: kind: synchronous handler_webhook_baseurl: http://localhost:3000 diff --git a/docker-compose-test.yml b/docker-compose-test.yml index 922ac38..98f6362 100644 --- a/docker-compose-test.yml +++ b/docker-compose-test.yml @@ -1,38 +1,78 @@ services: postgres_test: - image: postgres:15 + image: postgis/postgis:15-3.3 restart: always + volumes: + - db_data:/var/lib/postgresql/data environment: POSTGRES_PASSWORD: postgrespassword ports: - - "5432:5432" - networks: - - test-network + - "5433:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 5s timeout: 5s retries: 5 + start_period: 10s + networks: + - test-network graphql-engine-test: - image: hasura/graphql-engine:latest + image: hasura/graphql-engine:v2.42.0 ports: - "8081:8080" - depends_on: - postgres_test: - condition: service_healthy + restart: always environment: - HASURA_GRAPHQL_DATABASE_URL: postgres://postgres:postgrespassword@postgres_test:5432/postgres + HASURA_GRAPHQL_METADATA_DATABASE_URL: postgres://postgres:postgrespassword@postgres_test:5432/postgres + PG_DATABASE_URL: postgres://postgres:postgrespassword@postgres_test:5432/postgres HASURA_GRAPHQL_ENABLE_CONSOLE: "true" HASURA_GRAPHQL_DEV_MODE: "true" + HASURA_GRAPHQL_ENABLED_LOG_TYPES: startup, http-log, webhook-log, websocket-log, query-log HASURA_GRAPHQL_ADMIN_SECRET: myadminsecretkey - HASURA_GRAPHQL_JWT_SECRET: '{"type":"HS256", "key": "12345678901234567890123456789012", "claims_format": "json", "claims_namespace": "https://hasura.io/jwt/claims"}' - HASURA_GRAPHQL_UNAUTHORIZED_ROLE: "anonymous" - HASURA_GRAPHQL_LOG_LEVEL: "debug" - HASURA_GRAPHQL_ENABLED_LOG_TYPES: "startup,http-log,webhook-log,websocket-log,query-log" - ACTION_BASE_URL: http://action-handler:3000 + HASURA_GRAPHQL_METADATA_DEFAULTS: '{"backend_configs":{"dataconnector":{"athena":{"uri":"http://data-connector-agent-test:8081/api/v1/athena"},"mariadb":{"uri":"http://data-connector-agent-test:8081/api/v1/mariadb"},"mysql8":{"uri":"http://data-connector-agent-test:8081/api/v1/mysql"},"oracle":{"uri":"http://data-connector-agent-test:8081/api/v1/oracle"},"snowflake":{"uri":"http://data-connector-agent-test:8081/api/v1/snowflake"}}}}' + depends_on: + postgres_test: + condition: service_healthy + data-connector-agent-test: + condition: service_healthy + networks: + - test-network + + data-connector-agent-test: + image: hasura/graphql-data-connector:v2.42.0 + restart: always + ports: + - "8082:8081" + environment: + QUARKUS_LOG_LEVEL: ERROR + QUARKUS_OPENTELEMETRY_ENABLED: "false" + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8081/api/v1/athena/health"] + interval: 5s + timeout: 10s + retries: 5 + start_period: 5s + networks: + - test-network + + hasura-cli-test: + build: + context: . + dockerfile: Dockerfile + tty: true volumes: - - ./tests/metadata:/hasura-metadata + - .:/app + environment: + HASURA_GRAPHQL_ENDPOINT: http://graphql-engine-test:8080 + PG_DATABASE_URL: postgres://postgres:postgrespassword@postgres_test:5432/postgres + HASURA_GRAPHQL_ADMIN_SECRET: myadminsecretkey + working_dir: /app + command: hasura console --address 0.0.0.0 --console-port 9696 + ports: + - "9696:9696" + depends_on: + graphql-engine-test: + condition: service_healthy networks: - test-network @@ -40,6 +80,9 @@ services: build: context: . dockerfile: Dockerfile.test + environment: + baseUrl: http://graphql-engine-test:8080/v1/graphql + HASURA_GRAPHQL_ADMIN_SECRET: myadminsecretkey volumes: - ./tests/results:/app/target/karate-reports depends_on: @@ -48,6 +91,9 @@ services: networks: - test-network +volumes: + db_data: + networks: test-network: driver: bridge diff --git a/tests/karate/src/test/resources/karate-config.js b/tests/karate/src/test/resources/karate-config.js index 304facf..259e43a 100644 --- a/tests/karate/src/test/resources/karate-config.js +++ b/tests/karate/src/test/resources/karate-config.js @@ -12,13 +12,13 @@ function fn() { }; // Token helper function - config.tokenHelper = function (claims) { + config.tokenHelper = function(claims) { var Base64 = Java.type("java.util.Base64"); var defaultClaims = { "https://hasura.io/jwt/claims": { "x-hasura-allowed-roles": ["user"], "x-hasura-default-role": "user", - "x-hasura-user-id": "00000000-0000-0000-0000-000000000000", + "x-hasura-user-id": claims.uid || "00000000-0000-0000-0000-000000000000", }, }; @@ -40,10 +40,10 @@ function fn() { }; // Set default headers - config.headers = { - "Content-Type": "application/json", - "X-Hasura-Admin-Secret": config.adminSecret, - }; + karate.configure('headers', { + 'Content-Type': 'application/json', + 'x-hasura-admin-secret': config.adminSecret + }); karate.log("Config initialized:", config); return config;