diff --git a/bruno/README.md b/bruno/README.md index cb646fe8..a9d6ecbc 100644 --- a/bruno/README.md +++ b/bruno/README.md @@ -1,4 +1,8 @@ -# Patron Request API E2E test +# Bruno + +This directory files for running tests with Bruno. + +## Patron Request API E2E test The provided Bruno API test includes an end-to-end execution of a happy path exchange between the requester (borrower) and supplier (lender). @@ -14,5 +18,28 @@ docker compose up 3. In Bruno, load the `LocalDev` environment. -4. Run all steps in the Bruno runner. All HTTP response codes and validations should be green. +4. Run all steps in the Bruno runner in the `PR Happy Flow` folder. All HTTP response codes and validations should be green. + +## Reservoir (incomplete) + +This is similar to the E2E test with the twist that it uses holdings SRU lookup. + +The docker compose file `docker-compose-reservoir.yml` assumes reservoir in `../../reservoir`, ie `crosslink` and `reservoir` side by side. + +Start with: + +``` +docker compose -f docker-compose-reservoir.yml up +``` + +Load at least one MARC for reservoir with the `isxn` matcher with: + +``` +cd reservoir +./load-records.sh +``` + +Start Bruno and load the `LocalDev` environment. +Select the `Reservoir` folder in Bruno. Only the first parts of the Happy flow is currently in this holder. This +is merely to test that SRU lookup is operational. diff --git a/bruno/crosslink/Reservoir/Borrowing side send-request check.bru b/bruno/crosslink/Reservoir/Borrowing side send-request check.bru new file mode 100644 index 00000000..f3840d2f --- /dev/null +++ b/bruno/crosslink/Reservoir/Borrowing side send-request check.bru @@ -0,0 +1,40 @@ +meta { + name: Borrowing side send-request check + type: http + seq: 3 +} + +get { + url: {{host}}/patron_requests/{{prId}}?side=borrowing + body: json + auth: basic +} + +params:query { + side: borrowing +} + +headers { + X-Okapi-User-Id: {{userName}} + X-Okapi-Tenant: {{OkapiTenantReq}} +} + +auth:basic { + username: {{userName}} + password: {{userPassword}} +} + +script:post-response { + test("for send-request", function() { + const pr = res.getBody(); + expect(pr.lastAction).to.equal("send-request") + expect(pr.lastActionResult).to.equal("SUCCESS") + }); +} + +settings { + encodeUrl: true + timeout: 0 + followRedirects: true + maxRedirects: 5 +} diff --git a/bruno/crosslink/Reservoir/Borrowing side send-request.bru b/bruno/crosslink/Reservoir/Borrowing side send-request.bru new file mode 100644 index 00000000..d4a35373 --- /dev/null +++ b/bruno/crosslink/Reservoir/Borrowing side send-request.bru @@ -0,0 +1,45 @@ +meta { + name: Borrowing side send-request + type: http + seq: 2 +} + +post { + url: {{host}}/patron_requests/{{prId}}/action?side=borrowing + body: json + auth: basic +} + +params:query { + side: borrowing +} + +headers { + X-Okapi-User-Id: {{userName}} + X-Okapi-Tenant: {{OkapiTenantReq}} +} + +auth:basic { + username: {{userName}} + password: {{userPassword}} +} + +body:json { + { + "action": "send-request" + } +} + +script:post-response { + test("for success", function() { + const pr = res.getBody(); + expect(pr.result).to.equal("SUCCESS") + }); +} + +settings { + encodeUrl: true + timeout: 0 + followRedirects: true + maxRedirects: 5 +} diff --git a/bruno/crosslink/Reservoir/Create borrowing side PR.bru b/bruno/crosslink/Reservoir/Create borrowing side PR.bru new file mode 100644 index 00000000..e16c8061 --- /dev/null +++ b/bruno/crosslink/Reservoir/Create borrowing side PR.bru @@ -0,0 +1,60 @@ +meta { + name: Create borrowing side PR + type: http + seq: 1 +} + +post { + url: {{host}}/patron_requests + body: json + auth: basic +} + +headers { + X-Okapi-User-Id: {{userName}} + X-Okapi-Tenant: {{OkapiTenantReq}} +} + +auth:basic { + username: {{userName}} + password: {{userPassword}} +} + +body:json { + { + "illRequest": { + "bibliographicInfo": { + "supplierUniqueRecordId": "429e871b-9cd3-465a-8d94-a82bac2d9a44", + "title" : "my fake title", + "bibliographicItemId": [ + { + "bibliographicItemIdentifier": "9781172431779", + "bibliographicItemIdentifierCode": { + "#text": "ISBN" + } + } + ] + } + }, + "patron": "{{requesterPatron}}", + "side": "borrowing", + "state": "NEW", + "requesterSymbol": "{{requesterSymbol}}" + } +} + +script:post-response { + const responseData = res.getBody(); + + test("Capture patron request id", () => { + expect(responseData.id).to.be.a("string").and.not.empty; + bru.setVar("prId", responseData.id); + }); +} + +settings { + encodeUrl: true + timeout: 0 + followRedirects: true + maxRedirects: 5 +} diff --git a/bruno/docker-compose-reservoir.yml b/bruno/docker-compose-reservoir.yml new file mode 100644 index 00000000..daff8b13 --- /dev/null +++ b/bruno/docker-compose-reservoir.yml @@ -0,0 +1,91 @@ +services: + postgres: + image: postgres:16 + container_name: crosslink_postgres + environment: + POSTGRES_USER: crosslink + POSTGRES_PASSWORD: crosslink + POSTGRES_DB: crosslink + ports: + - "25432:5432" + healthcheck: + test: ["CMD-SHELL", "pg_isready -U crosslink -d crosslink"] + interval: 5s + timeout: 3s + retries: 20 + start_period: 5s + + broker: + build: + context: .. + dockerfile: broker/Dockerfile + container_name: crosslink_broker + depends_on: + postgres: + condition: service_healthy + environment: + HTTP_PORT: 8080 + DB_TYPE: postgres + DB_USER: crosslink + DB_PASSWORD: crosslink + DB_HOST: postgres + DB_DATABASE: crosslink + DB_PORT: 5432 + DB_PROVISION: "true" + DB_MIGRATE: "true" + HOLDINGS_ADAPTER: sru + HOLDINGS_ISXN_LOOKUP: "true" + SRU_URL: http://reservoir:8082/reservoir/sru + DIRECTORY_ADAPTER: api + DIRECTORY_API_URL: http://illmock:8081/directory/entries + TENANT_TO_SYMBOL: "ISIL:US-{tenant}" + ports: + - "8080:8080" + + illmock: + build: + context: .. + dockerfile: illmock/Dockerfile + container_name: crosslink_illmock + command: ["/illmock"] + environment: + HTTP_PORT: 8081 + MOCK_DIRECTORY_ENTRIES_PATH: /data/directory.json + volumes: + - ./:/data:ro + ports: + - "8081:8081" + + reservoir-init: + image: postgres:latest + container_name: reservoir_init + depends_on: + postgres: + condition: service_healthy + entrypoint: [ + "bash", "-c", + "psql -h postgres -U crosslink -d crosslink -c \"DO \\$\\$ BEGIN IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'reservoir') THEN CREATE ROLE reservoir NOLOGIN; END IF; END \\$\\$;\" && \ + psql -h postgres -U crosslink -d crosslink -c 'GRANT reservoir TO crosslink;' && \ + psql -h postgres -U crosslink -d crosslink -c \"DO \\$\\$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_namespace WHERE nspname = 'default_mod_reservoir') THEN CREATE SCHEMA default_mod_reservoir AUTHORIZATION reservoir; END IF; END \\$\\$;\"" + ] + environment: + PGPASSWORD: crosslink + + reservior: + build: + context: ../../reservoir + dockerfile: Dockerfile-jit + container_name: reservoir + depends_on: + reservoir-init: + condition: service_completed_successfully + environment: + HTTP_PORT: 8082 + DB_USERNAME: crosslink + DB_PASSWORD: crosslink + DB_HOST: postgres + DB_DATABASE: crosslink + DB_PORT: 5432 + TENANT_DEFAULT: default + ports: + - "8082:8082" diff --git a/bruno/reservoir/1.mrc b/bruno/reservoir/1.mrc new file mode 100644 index 00000000..43e22d2c --- /dev/null +++ b/bruno/reservoir/1.mrc @@ -0,0 +1 @@ +00990cam a2200229u 4500001001000000008004100010020001800051020001500069041000800084100003500092245003300127264003900160300002500199650003000224650002000254949008100274949008100355949008100436949008100517949008100598949008100679015630091250415t20102010 spa d a9781172431779 a1172431779 aspa1 aSaavedra Lamas, Carlos 1880- - aPor las provincias del norte 1aCharleston SC :bNabu Press,c2010 a134 pages ;c9.69 in 4aHistory / General History 4aHistory/General vIngram Book CompanyrWholesaleraIn stockp20.75cUSDyRRP excluding taxtUS vIngram Book CompanyrWholesaleraIn stockp14.99cGBPyRRP excluding taxtGB vIngram Book CompanyrWholesaleraIn stockp21.99cEURyRRP excluding taxtDE vIngram Book CompanyrWholesaleraIn stockp23.99cCADyRRP excluding taxtCA vIngram Book CompanyrWholesaleraIn stockp35.19cAUDyRRP including taxtAU vIngram Book CompanyrWholesaleraIn stockp31.99cAUDyRRP excluding taxtAU \ No newline at end of file diff --git a/bruno/reservoir/config-matchkeys-isxn.json b/bruno/reservoir/config-matchkeys-isxn.json new file mode 100644 index 00000000..909aae51 --- /dev/null +++ b/bruno/reservoir/config-matchkeys-isxn.json @@ -0,0 +1,5 @@ +{ + "id": "isxn-matcher", + "type": "javascript", + "url": "https://raw.githubusercontent.com/indexdata/reservoir/master/js/matchkeys/isxn/isxn.mjs" +} diff --git a/bruno/reservoir/config-pool-isxn.json b/bruno/reservoir/config-pool-isxn.json new file mode 100644 index 00000000..250c6d9c --- /dev/null +++ b/bruno/reservoir/config-pool-isxn.json @@ -0,0 +1,9 @@ +{ + "id": "isxn", + "matcher": "isxn-matcher::matchkey", + "cql": { + "isbn" : "isxn-matcher::normIsbn", + "issn" : "isxn-matcher::normIssn" + }, + "update": "ingest" +} diff --git a/bruno/reservoir/load-records.sh b/bruno/reservoir/load-records.sh new file mode 100755 index 00000000..770354a1 --- /dev/null +++ b/bruno/reservoir/load-records.sh @@ -0,0 +1,29 @@ +#!/bin/sh + +OKAPI_URL=http://localhost:8082 + +curl -w'\n' -HContent-type:application/json \ + $OKAPI_URL/reservoir/config/modules -d @marc-transformer-conf.json + +curl -HContent-Type:application/json \ + -XPUT $OKAPI_URL/reservoir/config/oai -d'{"transformer":"marc-transformer::cluster_transform"}' + +curl -w'\n' -HContent-type:application/json \ + $OKAPI_URL/reservoir/config/modules -d @config-matchkeys-isxn.json + +# configure pool +curl -w'\n' -HContent-type:application/json \ + $OKAPI_URL/reservoir/config/matchkeys -d @config-pool-isxn.json + +# initialize pool +curl -w '\n' -XPUT $OKAPI_URL/reservoir/config/matchkeys/isxn/initialize + +filename=1.mrc + +set -x + +curl -s \ + -HContent-Encoding:application/octet-stream \ + -T $filename "$OKAPI_URL/reservoir/upload?sourceId=US-RS3&sourceVersion=1&xmlFixing=true&fileName=$filename&localIdPath=%24.marc.fields%5B%2A%5D.001" + +curl -s "$OKAPI_URL/reservoir/sru?maximumRecords=1&query=isbn%3D9781172431779" diff --git a/bruno/reservoir/marc-transformer-conf.json b/bruno/reservoir/marc-transformer-conf.json new file mode 100644 index 00000000..430ecc89 --- /dev/null +++ b/bruno/reservoir/marc-transformer-conf.json @@ -0,0 +1 @@ +{"id":"marc-transformer","type":"javascript","url":"https://raw.githubusercontent.com/openlibraryenvironment/reshare-library-configurations/master/crosslink/transform.mjs"}