From d26f54ca971d5b2e72864b2bf522cfd03d0a49f9 Mon Sep 17 00:00:00 2001 From: Vera Kahn Date: Wed, 14 Jan 2026 15:36:06 -0500 Subject: [PATCH 01/10] wip --- config/production.env | 2 +- config/qa.env | 2 +- lib/available_delivery_location_types.js | 1 - lib/load_nypl_core.js | 2 ++ lib/models/Item.js | 1 - lib/models/Location.js | 6 +++++- lib/requestability-utils.js | 1 + lib/resources.js | 1 - 8 files changed, 10 insertions(+), 6 deletions(-) diff --git a/config/production.env b/config/production.env index f115ea4d..abf281a4 100644 --- a/config/production.env +++ b/config/production.env @@ -10,7 +10,7 @@ NYPL_OAUTH_URL=https://isso.nypl.org/ ENCRYPTED_NYPL_OAUTH_ID=AQECAHh7ea2tyZ6phZgT4B9BDKwguhlFtRC6hgt+7HbmeFsrsgAAAGswaQYJKoZIhvcNAQcGoFwwWgIBADBVBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDMLKVUQA58B6vprNcAIBEIAoaz0lI9EL2M9NyTuEwT8JDmPBt6aXfMiFs027DEuwsCN0wS0qWeFL1g== ENCRYPTED_NYPL_OAUTH_SECRET=AQECAHh7ea2tyZ6phZgT4B9BDKwguhlFtRC6hgt+7HbmeFsrsgAAAIcwgYQGCSqGSIb3DQEHBqB3MHUCAQAwcAYJKoZIhvcNAQcBMB4GCWCGSAFlAwQBLjARBAyWz91LOP2YP5fg0q0CARCAQ9inO9SV1M8R0Pkkx84r7UdwlU1FxfXvIjk/z6Qs81KBAVELhby2iD5LawQyDrR9tjhuMbotS6QnydwwMR/p8+qJXHI= -NYPL_CORE_VERSION=v2.35 +NYPL_CORE_VERSION=v2.37 LOG_LEVEL=info FEATURES=on-site-edd diff --git a/config/qa.env b/config/qa.env index f7cfb2f4..90b8f7c3 100644 --- a/config/qa.env +++ b/config/qa.env @@ -11,7 +11,7 @@ NYPL_OAUTH_URL=https://isso.nypl.org/ ENCRYPTED_NYPL_OAUTH_ID=AQECAHh7ea2tyZ6phZgT4B9BDKwguhlFtRC6hgt+7HbmeFsrsgAAAGswaQYJKoZIhvcNAQcGoFwwWgIBADBVBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDMLKVUQA58B6vprNcAIBEIAoaz0lI9EL2M9NyTuEwT8JDmPBt6aXfMiFs027DEuwsCN0wS0qWeFL1g== ENCRYPTED_NYPL_OAUTH_SECRET=AQECAHh7ea2tyZ6phZgT4B9BDKwguhlFtRC6hgt+7HbmeFsrsgAAAIcwgYQGCSqGSIb3DQEHBqB3MHUCAQAwcAYJKoZIhvcNAQcBMB4GCWCGSAFlAwQBLjARBAyWz91LOP2YP5fg0q0CARCAQ9inO9SV1M8R0Pkkx84r7UdwlU1FxfXvIjk/z6Qs81KBAVELhby2iD5LawQyDrR9tjhuMbotS6QnydwwMR/p8+qJXHI= -NYPL_CORE_VERSION=v2.35 +NYPL_CORE_VERSION=v2.37 LOG_LEVEL=debug FEATURES=on-site-edd diff --git a/lib/available_delivery_location_types.js b/lib/available_delivery_location_types.js index 16cf7bd6..1f3835ec 100644 --- a/lib/available_delivery_location_types.js +++ b/lib/available_delivery_location_types.js @@ -8,7 +8,6 @@ class AvailableDeliveryLocationTypes { if (!patronID) return null const patronType = await this._getPatronTypeOf(patronID) - if (this._isUnfamiliarPatronType(patronType)) { return null } diff --git a/lib/load_nypl_core.js b/lib/load_nypl_core.js index 6957cf7f..39dadfa7 100644 --- a/lib/load_nypl_core.js +++ b/lib/load_nypl_core.js @@ -1,6 +1,7 @@ const _data = {} const nyplCoreObjects = require('@nypl/nypl-core-objects') const loadNyplCoreData = () => { + console.log('Loading nypl core data from ', process.env.NYPL_CORE_VERSION || 'master') const vocabularies = { collections: 'by-collection', sierraLocations: 'by-sierra-location', @@ -11,6 +12,7 @@ const loadNyplCoreData = () => { } return Promise.all(Object.keys(vocabularies).map(async (vocab) => { const nyplCoreValues = await nyplCoreObjects(vocabularies[vocab]) + if (vocab === 'sierraLocations') console.log(nyplCoreValues) _data[vocab] = nyplCoreValues })) } diff --git a/lib/models/Item.js b/lib/models/Item.js index 2a868f29..f1e990ec 100644 --- a/lib/models/Item.js +++ b/lib/models/Item.js @@ -114,7 +114,6 @@ Item.withDeliveryLocationsByBarcode = async function (item, scholarRoom) { const model = new Item(item) item.eddRequestable = !!model.eddRequestable const filteredDeliveryLocationsWithScholarRoom = locationUtils.filterLocations(model.deliveryLocation, scholarRoom) - item.deliveryLocation = locationUtils.formatLocations(filteredDeliveryLocationsWithScholarRoom) return item } diff --git a/lib/models/Location.js b/lib/models/Location.js index 49592f09..b62254bb 100644 --- a/lib/models/Location.js +++ b/lib/models/Location.js @@ -2,7 +2,10 @@ const nyplCore = require('../load_nypl_core') class Location { constructor ({ holdingLocation, recapCustomerCode, m2CustomerCode }) { + console.log('location model constructor holdinglocation', holdingLocation) this.nyplCoreLocation = nyplCore.sierraLocations()[holdingLocation] + console.log('location model constructor nyplcore location data', this.nyplCoreLocation) + console.log(Object.keys(nyplCore.sierraLocations())) this.m2CustomerCode = m2CustomerCode this.recapCustomerCode = recapCustomerCode this.requestable = this.nyplCoreLocation?.requestable @@ -32,8 +35,9 @@ class Location { if (this.nyplCoreLocation?.sierraDeliveryLocations?.length) { // It's mapped, but the sierraDeliveryLocation entities only have `code` and `label` // Do a second lookup to populate `deliveryLocationTypes` + console.log(this.nyplCoreLocation.sierraDeliveryLocations) return this.nyplCoreLocation.sierraDeliveryLocations.map((deliveryLocation) => { - deliveryLocation.deliveryLocationTypes = this.nyplCoreLocation.deliveryLocationTypes + // deliveryLocation.deliveryLocationTypes = this.nyplCoreLocation.deliveryLocationTypes return deliveryLocation }) } diff --git a/lib/requestability-utils.js b/lib/requestability-utils.js index 56cb867c..2b1f5550 100644 --- a/lib/requestability-utils.js +++ b/lib/requestability-utils.js @@ -87,6 +87,7 @@ class DeliveryLocationsResolver { // Filter out anything not matching the specified deliveryLocationType return locations.filter((location) => { const locationIsNotScholarRoom = !location.deliveryLocationTypes.includes('Scholar') + console.log({ location, locationIsNotScholarRoom, locationCodeEqualsScholarRoom: location.code === scholarRoom }) return locationIsNotScholarRoom || (location.code === scholarRoom) }) } diff --git a/lib/resources.js b/lib/resources.js index f342cd3b..699d7ec1 100644 --- a/lib/resources.js +++ b/lib/resources.js @@ -305,7 +305,6 @@ module.exports = function (app, _private = null) { // The resolved values of Promise.all are strictly ordered based on original array of promises const items = resp[0] const scholarRoom = resp[1] - // Use HTC API and nypl-core mappings to ammend ES response with deliveryLocations: return Promise.all(items.map(async (item) => Item.withDeliveryLocationsByBarcode(item, scholarRoom))) .catch((e) => { From f4defb62cbeccd6d7199da52882f84fa1d574e95 Mon Sep 17 00:00:00 2001 From: Vera Kahn Date: Wed, 14 Jan 2026 15:48:10 -0500 Subject: [PATCH 02/10] fix delivery location type biz --- lib/load_nypl_core.js | 1 - lib/models/Location.js | 17 +---------------- package-lock.json | 1 + 3 files changed, 2 insertions(+), 17 deletions(-) diff --git a/lib/load_nypl_core.js b/lib/load_nypl_core.js index 39dadfa7..9d8a8b3a 100644 --- a/lib/load_nypl_core.js +++ b/lib/load_nypl_core.js @@ -12,7 +12,6 @@ const loadNyplCoreData = () => { } return Promise.all(Object.keys(vocabularies).map(async (vocab) => { const nyplCoreValues = await nyplCoreObjects(vocabularies[vocab]) - if (vocab === 'sierraLocations') console.log(nyplCoreValues) _data[vocab] = nyplCoreValues })) } diff --git a/lib/models/Location.js b/lib/models/Location.js index b62254bb..6cbbc634 100644 --- a/lib/models/Location.js +++ b/lib/models/Location.js @@ -2,10 +2,7 @@ const nyplCore = require('../load_nypl_core') class Location { constructor ({ holdingLocation, recapCustomerCode, m2CustomerCode }) { - console.log('location model constructor holdinglocation', holdingLocation) this.nyplCoreLocation = nyplCore.sierraLocations()[holdingLocation] - console.log('location model constructor nyplcore location data', this.nyplCoreLocation) - console.log(Object.keys(nyplCore.sierraLocations())) this.m2CustomerCode = m2CustomerCode this.recapCustomerCode = recapCustomerCode this.requestable = this.nyplCoreLocation?.requestable @@ -27,19 +24,7 @@ class Location { case 'm2-customer-code': return this.deliveryLocationsByM2CustomerCode default: - return this.deliveryLocationByHoldingLocation - } - } - - get deliveryLocationByHoldingLocation () { - if (this.nyplCoreLocation?.sierraDeliveryLocations?.length) { - // It's mapped, but the sierraDeliveryLocation entities only have `code` and `label` - // Do a second lookup to populate `deliveryLocationTypes` - console.log(this.nyplCoreLocation.sierraDeliveryLocations) - return this.nyplCoreLocation.sierraDeliveryLocations.map((deliveryLocation) => { - // deliveryLocation.deliveryLocationTypes = this.nyplCoreLocation.deliveryLocationTypes - return deliveryLocation - }) + return this.nyplCoreLocation?.sierraDeliveryLocations } } diff --git a/package-lock.json b/package-lock.json index 57dba3b4..e142a8e2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3712,6 +3712,7 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, "optional": true, "engines": { "node": ">=14" From 4f4e0e350f78a95ead48378e9f1073f0bdceb7f6 Mon Sep 17 00:00:00 2001 From: Vera Kahn Date: Wed, 14 Jan 2026 15:58:07 -0500 Subject: [PATCH 03/10] rm console.log --- lib/requestability-utils.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/requestability-utils.js b/lib/requestability-utils.js index 2b1f5550..56cb867c 100644 --- a/lib/requestability-utils.js +++ b/lib/requestability-utils.js @@ -87,7 +87,6 @@ class DeliveryLocationsResolver { // Filter out anything not matching the specified deliveryLocationType return locations.filter((location) => { const locationIsNotScholarRoom = !location.deliveryLocationTypes.includes('Scholar') - console.log({ location, locationIsNotScholarRoom, locationCodeEqualsScholarRoom: location.code === scholarRoom }) return locationIsNotScholarRoom || (location.code === scholarRoom) }) } From ec1ea45319145d0e4793f2f7820b1aad743d6f93 Mon Sep 17 00:00:00 2001 From: Vera Kahn Date: Wed, 14 Jan 2026 15:58:51 -0500 Subject: [PATCH 04/10] rm console log --- lib/load_nypl_core.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/load_nypl_core.js b/lib/load_nypl_core.js index 9d8a8b3a..6957cf7f 100644 --- a/lib/load_nypl_core.js +++ b/lib/load_nypl_core.js @@ -1,7 +1,6 @@ const _data = {} const nyplCoreObjects = require('@nypl/nypl-core-objects') const loadNyplCoreData = () => { - console.log('Loading nypl core data from ', process.env.NYPL_CORE_VERSION || 'master') const vocabularies = { collections: 'by-collection', sierraLocations: 'by-sierra-location', From 7a3448059c3bcaa8803230f596708fbb20e4cd19 Mon Sep 17 00:00:00 2001 From: Vera Kahn Date: Thu, 12 Feb 2026 10:28:24 -0500 Subject: [PATCH 05/10] update resources index --- config/production.env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/production.env b/config/production.env index abf281a4..42396637 100644 --- a/config/production.env +++ b/config/production.env @@ -1,5 +1,5 @@ ENCRYPTED_ELASTICSEARCH_URI=AQECAHh7ea2tyZ6phZgT4B9BDKwguhlFtRC6hgt+7HbmeFsrsgAAAJYwgZMGCSqGSIb3DQEHBqCBhTCBggIBADB9BgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDFWw8ECX9Pz81z0kvAIBEIBQGec9PCpwuvEgLH6imhqP6tx1fj8Vlf2ZipnUy06jzmpE262Qvk9LPAq7sIYPVkTCZctwilwcU9oC6yxasVoUlK87la77v03CeZsPIDwciFY= -ENCRYPTED_RESOURCES_INDEX=AQECAHh7ea2tyZ6phZgT4B9BDKwguhlFtRC6hgt+7HbmeFsrsgAAAHIwcAYJKoZIhvcNAQcGoGMwYQIBADBcBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDGw+4ALa5eFYzC4SWwIBEIAvOVuHGgflzmWLE6GBauPAiSQLmL4xaSfBFED+zyGnQ+jV0KS64aN45ZFR0xgaZS0= +ENCRYPTED_RESOURCES_INDEX=AQECAHh7ea2tyZ6phZgT4B9BDKwguhlFtRC6hgt+7HbmeFsrsgAAAHcwdQYJKoZIhvcNAQcGoGgwZgIBADBhBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDGWf4Ka9zGyw0zzPCAIBEIA0nAD58HXOOpXOUDY/xT5RYo9G7liIOPCVeq/W8EIEr1zerU4AnZr+A4y2kkLiBs99kfV4aw== ENCRYPTED_ELASTICSEARCH_API_KEY=AQECAHh7ea2tyZ6phZgT4B9BDKwguhlFtRC6hgt+7HbmeFsrsgAAAJ4wgZsGCSqGSIb3DQEHBqCBjTCBigIBADCBhAYJKoZIhvcNAQcBMB4GCWCGSAFlAwQBLjARBAyPOPaQCBbvKQhJoPQCARCAV2TlWlRh+xKnCegpprEQgfldZGcVW48RND0LVd/pQpVTJnRTtbCpP7damT7k8ziJVdWZ3jsfs5fw5YnKc/EIQ1M//DRUzOJL98ir5LTTxE7QhflKDtUY+Q== ENCRYPTED_SCSB_URL=AQECAHh7ea2tyZ6phZgT4B9BDKwguhlFtRC6hgt+7HbmeFsrsgAAAHwwegYJKoZIhvcNAQcGoG0wawIBADBmBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDKPFC8wFkVM5CyT6VQIBEIA5m4eLBkpChRA//ZNEWsRqIDGZmevb/thzI03a0NiAW6VfybSAYpFthh+bj/yAk1VEEBF6r1T4A2GP From 1474814fdc795853499d8e81b3023f8e12bb96e8 Mon Sep 17 00:00:00 2001 From: Vera Kahn Date: Fri, 13 Feb 2026 09:53:05 -0500 Subject: [PATCH 06/10] update index --- config/production.env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/production.env b/config/production.env index 42396637..be8cda54 100644 --- a/config/production.env +++ b/config/production.env @@ -1,5 +1,5 @@ ENCRYPTED_ELASTICSEARCH_URI=AQECAHh7ea2tyZ6phZgT4B9BDKwguhlFtRC6hgt+7HbmeFsrsgAAAJYwgZMGCSqGSIb3DQEHBqCBhTCBggIBADB9BgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDFWw8ECX9Pz81z0kvAIBEIBQGec9PCpwuvEgLH6imhqP6tx1fj8Vlf2ZipnUy06jzmpE262Qvk9LPAq7sIYPVkTCZctwilwcU9oC6yxasVoUlK87la77v03CeZsPIDwciFY= -ENCRYPTED_RESOURCES_INDEX=AQECAHh7ea2tyZ6phZgT4B9BDKwguhlFtRC6hgt+7HbmeFsrsgAAAHcwdQYJKoZIhvcNAQcGoGgwZgIBADBhBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDGWf4Ka9zGyw0zzPCAIBEIA0nAD58HXOOpXOUDY/xT5RYo9G7liIOPCVeq/W8EIEr1zerU4AnZr+A4y2kkLiBs99kfV4aw== +ENCRYPTED_RESOURCES_INDEX=AQECAHh7ea2tyZ6phZgT4B9BDKwguhlFtRC6hgt+7HbmeFsrsgAAAHcwdQYJKoZIhvcNAQcGoGgwZgIBADBhBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDGOwQk67wE9nnptNhgIBEIA0olICpuUjppBGfOeFMWkmnElVd6qfJXPlgezZDu08t+rt4kQzWBuK7DALwhCeGNl45UpfGg== ENCRYPTED_ELASTICSEARCH_API_KEY=AQECAHh7ea2tyZ6phZgT4B9BDKwguhlFtRC6hgt+7HbmeFsrsgAAAJ4wgZsGCSqGSIb3DQEHBqCBjTCBigIBADCBhAYJKoZIhvcNAQcBMB4GCWCGSAFlAwQBLjARBAyPOPaQCBbvKQhJoPQCARCAV2TlWlRh+xKnCegpprEQgfldZGcVW48RND0LVd/pQpVTJnRTtbCpP7damT7k8ziJVdWZ3jsfs5fw5YnKc/EIQ1M//DRUzOJL98ir5LTTxE7QhflKDtUY+Q== ENCRYPTED_SCSB_URL=AQECAHh7ea2tyZ6phZgT4B9BDKwguhlFtRC6hgt+7HbmeFsrsgAAAHwwegYJKoZIhvcNAQcGoG0wawIBADBmBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDKPFC8wFkVM5CyT6VQIBEIA5m4eLBkpChRA//ZNEWsRqIDGZmevb/thzI03a0NiAW6VfybSAYpFthh+bj/yAk1VEEBF6r1T4A2GP From b6dcd86bc4e396853067c3d7153b9c990a4a0e41 Mon Sep 17 00:00:00 2001 From: Vera Kahn Date: Mon, 16 Mar 2026 15:29:04 -0400 Subject: [PATCH 07/10] the tests --- .github/workflows/test-and-deploy.yml | 133 +++--------------- .../delivery-locations-by-barcode.test.js | 41 ++++-- .../delivery-locations-constants.js | 10 +- 3 files changed, 55 insertions(+), 129 deletions(-) diff --git a/.github/workflows/test-and-deploy.yml b/.github/workflows/test-and-deploy.yml index c9306ac6..a179ba4b 100644 --- a/.github/workflows/test-and-deploy.yml +++ b/.github/workflows/test-and-deploy.yml @@ -2,6 +2,11 @@ name: Unit Tests on: [push] +# Global environment variable based on the branch name +env: + ENV_TAG: ${{ github.ref_name }} + ECR_REPOSITORY: discovery-api + jobs: tests: runs-on: ubuntu-latest @@ -15,114 +20,15 @@ jobs: run: npm ci - name: Unit Tests run: npm test - integration-test-qa: - permissions: - id-token: write - contents: read - runs-on: ubuntu-latest - needs: tests - if: github.ref == 'refs/heads/qa' - steps: - - uses: actions/checkout@v4 - - name: Set Node version - uses: actions/setup-node@v4 - with: - node-version-file: '.nvmrc' - - name: Install dependencies - run: npm ci - - name: Start service - run: ENV=qa npm start & - - name: Run tests - run: npm run test-integration - deploy-qa: - permissions: - id-token: write - contents: read - runs-on: ubuntu-latest - needs: - - tests - if: github.ref == 'refs/heads/qa' - steps: - - name: Checkout repo - uses: actions/checkout@v3 - - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v2 - with: - role-to-assume: arn:aws:iam::946183545209:role/GithubActionsDeployerRole - aws-region: us-east-1 - - name: Log in to ECR - id: login-ecr - uses: aws-actions/amazon-ecr-login@v1 - - name: Back up previous image for rollback - env: - ECR_REPOSITORY: discovery-api - run: | - MANIFEST=$(aws ecr batch-get-image --repository-name $ECR_REPOSITORY --image-ids imageTag="qa-latest" --output json | jq --raw-output --join-output '.images[0].imageManifest') - PREVIOUS_MANIFEST=$(aws ecr batch-get-image --repository-name $ECR_REPOSITORY --image-ids imageTag="qa-previous" --output json | jq --raw-output --join-output '.images[0].imageManifest') - if [ "$MANIFEST" != "$PREVIOUS_MANIFEST" ]; then aws ecr put-image --repository-name $ECR_REPOSITORY --image-tag "qa-previous" --image-manifest "$MANIFEST"; fi - - name: Build, tag, and push image to Amazon ECR - env: - ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} - ECR_REPOSITORY: discovery-api - IMAGE_TAG: ${{ github.sha }} - run: | - docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG . - docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG - docker tag $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG $ECR_REGISTRY/$ECR_REPOSITORY:qa-latest - docker push $ECR_REGISTRY/$ECR_REPOSITORY:qa-latest - - name: Force ECS Update - run: | - aws ecs update-service --cluster discovery-api-qa --service discovery-api-qa --force-new-deployment - deploy-qa2: - permissions: - id-token: write - contents: read - runs-on: ubuntu-latest - needs: - - tests - if: github.ref == 'refs/heads/qa2' - steps: - - name: Checkout repo - uses: actions/checkout@v3 - - - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v2 - with: - role-to-assume: arn:aws:iam::946183545209:role/GithubActionsDeployerRole - aws-region: us-east-1 - - - name: Log in to ECR - id: login-ecr - uses: aws-actions/amazon-ecr-login@v1 - - name: Back up previous image for rollback - env: - ECR_REPOSITORY: discovery-api - run: | - MANIFEST=$(aws ecr batch-get-image --repository-name $ECR_REPOSITORY --image-ids imageTag="qa2-latest" --output json | jq --raw-output --join-output '.images[0].imageManifest') - PREVIOUS_MANIFEST=$(aws ecr batch-get-image --repository-name $ECR_REPOSITORY --image-ids imageTag="qa2-previous" --output json | jq --raw-output --join-output '.images[0].imageManifest') - if [ "$MANIFEST" != "$PREVIOUS_MANIFEST" ]; then aws ecr put-image --repository-name $ECR_REPOSITORY --image-tag "qa2-previous" --image-manifest "$MANIFEST"; fi - - name: Build, tag, and push image to Amazon ECR - env: - ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} - ECR_REPOSITORY: discovery-api - IMAGE_TAG: ${{ github.sha }} - run: | - docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG . - docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG - docker tag $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG $ECR_REGISTRY/$ECR_REPOSITORY:qa2-latest - docker push $ECR_REGISTRY/$ECR_REPOSITORY:qa2-latest - - - name: Force ECS Update - run: | - aws ecs update-service --cluster discovery-api-qa2 --service discovery-api-qa2 --force-new-deployment - deploy-production: + deploy: permissions: id-token: write contents: read runs-on: ubuntu-latest needs: tests - if: github.ref == 'refs/heads/production' + # Only run if it's one of our three deployment branches + if: contains(fromJSON('["qa", "qa2", "production"]'), github.ref_name) steps: - name: Checkout repo uses: actions/checkout@v3 @@ -138,22 +44,23 @@ jobs: uses: aws-actions/amazon-ecr-login@v1 - name: Back up previous image for rollback - env: - ECR_REPOSITORY: discovery-api run: | - MANIFEST=$(aws ecr batch-get-image --repository-name $ECR_REPOSITORY --image-ids imageTag="production-latest" --output json | jq --raw-output --join-output '.images[0].imageManifest') - PREVIOUS_MANIFEST=$(aws ecr batch-get-image --repository-name $ECR_REPOSITORY --image-ids imageTag="production-previous" --output json | jq --raw-output --join-output '.images[0].imageManifest') - if [ "$MANIFEST" != "$PREVIOUS_MANIFEST" ]; then aws ecr put-image --repository-name $ECR_REPOSITORY --image-tag "production-previous" --image-manifest "$MANIFEST"; fi + MANIFEST=$(aws ecr batch-get-image --repository-name ${{ env.ECR_REPOSITORY }} --image-ids imageTag="${{ env.ENV_TAG }}-latest" --output json | jq --raw-output --join-output '.images[0].imageManifest') + PREVIOUS_MANIFEST=$(aws ecr batch-get-image --repository-name ${{ env.ECR_REPOSITORY }} --image-ids imageTag="${{ env.ENV_TAG }}-previous" --output json | jq --raw-output --join-output '.images[0].imageManifest') + if [ "$MANIFEST" != "$PREVIOUS_MANIFEST" ]; then + aws ecr put-image --repository-name ${{ env.ECR_REPOSITORY }} --image-tag "${{ env.ENV_TAG }}-previous" --image-manifest "$MANIFEST" + fi + - name: Build, tag, and push image to Amazon ECR env: ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} - ECR_REPOSITORY: discovery-api IMAGE_TAG: ${{ github.sha }} run: | - docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG . - docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG - docker tag $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG $ECR_REGISTRY/$ECR_REPOSITORY:production-latest - docker push $ECR_REGISTRY/$ECR_REPOSITORY:production-latest + docker build -t $ECR_REGISTRY/${{ env.ECR_REPOSITORY }}:$IMAGE_TAG . + docker push $ECR_REGISTRY/${{ env.ECR_REPOSITORY }}:$IMAGE_TAG + docker tag $ECR_REGISTRY/${{ env.ECR_REPOSITORY }}:$IMAGE_TAG $ECR_REGISTRY/${{ env.ECR_REPOSITORY }}:${{ env.ENV_TAG }}-latest + docker push $ECR_REGISTRY/${{ env.ECR_REPOSITORY }}:${{ env.ENV_TAG }}-latest + - name: Force ECS Update run: | - aws ecs update-service --cluster discovery-api-production --service discovery-api-production --force-new-deployment + aws ecs update-service --cluster discovery-api-${{ env.ENV_TAG }} --service discovery-api-${{ env.ENV_TAG }} --force-new-deployment \ No newline at end of file diff --git a/test/integration/delivery-locations-by-barcode.test.js b/test/integration/delivery-locations-by-barcode.test.js index 2302b12b..9da42420 100644 --- a/test/integration/delivery-locations-by-barcode.test.js +++ b/test/integration/delivery-locations-by-barcode.test.js @@ -1,17 +1,25 @@ -require('dotenv').config('config/qa.env') -const axios = require('axios') +const { loadConfig } = require('../../lib/load-config') const { expectations, ptypes } = require('./delivery-locations-constants') +const { makeNyplDataApiClient } = require('../../lib/data-api-client') const checkLocationsForPtype = async (ptype) => { const problems = [] const match = [] - await Promise.all(Object.values(expectations).map(async (expectation) => { - const deliveryLocationsFromApi = await getDeliveryLocations(expectation.barcode, ptypes[ptype]) + + await Promise.all(Object.entries(expectations).map(async ([holdingLocation, expectation], i) => { + let deliveryLocationsFromApi let totalMatch = true const registerProblem = (problem) => { - problems.push({ barcode: expectation.barcode, deliveryLocationsFromApi, ...problem }) + problems.push({ holdingLocation, barcode: expectation.barcode, deliveryLocationsFromApi, ...problem }) totalMatch = false } + try { + deliveryLocationsFromApi = await getDeliveryLocations(expectation.barcode, ptypes[ptype]) + } catch (e) { + registerProblem({ lookUpFailed: true }) + return + } + const checkForValue = (expectedValue, action) => { const includedValueIncluded = deliveryLocationsFromApi.some((label) => label.includes(expectedValue)) const match = action === 'include' ? includedValueIncluded : !includedValueIncluded @@ -27,20 +35,31 @@ const checkLocationsForPtype = async (ptype) => { } const getDeliveryLocations = async (barcode, patronId) => { - const { data: { itemListElement: deliveryLocationsPerRecord } } = await axios.get(`http://localhost:8082/api/v0.1/request/deliveryLocationsByBarcode?barcodes[]=${barcode}&patronId=${patronId}`) - // per record - return deliveryLocationsPerRecord[0] - .deliveryLocation.map(loc => loc.prefLabel.toLowerCase()) + try { + // const { data: { itemListElement: deliveryLocationsPerRecord } } = await axios.get(`https://${process.env === 'qa' ? 'qa-' : ''}platform.nypl.org/api/v0.1/request/deliveryLocationsByBarcode?barcodes[]=${barcode}&patronId=${patronId}`) + const { itemListElement: itemData } = await makeNyplDataApiClient().get(`request/deliveryLocationsByBarcode?barcodes[]=${barcode}&patronId=${patronId}`) + // per record + return itemData[0] + .deliveryLocation.map(loc => loc.prefLabel.toLowerCase()) + } catch (e) { + console.error(e) + } } const theThing = async () => { + await loadConfig() const results = await Promise.all(Object.keys(ptypes).map((checkLocationsForPtype))) - Object.keys(ptypes).forEach((ptype, i) => { + const resultsHaveProblems = Object.keys(ptypes).some((ptype, i) => { const resultsForPtype = results[i] if (resultsForPtype.problems.length) { console.error(`Error with ${ptype} ptype delivery results, `, resultsForPtype.problems) - } else console.log(`All delivery location checks for ${ptype} patron type successful`) + return true + } else { + console.log(`All delivery location checks for ${ptype} patron type successful`) + return false + } }) + if (resultsHaveProblems) throw new Error('Delivery location checks failed.') } theThing() diff --git a/test/integration/delivery-locations-constants.js b/test/integration/delivery-locations-constants.js index b46d812c..bf079333 100644 --- a/test/integration/delivery-locations-constants.js +++ b/test/integration/delivery-locations-constants.js @@ -38,11 +38,11 @@ const expectations = { scholar: { includes: [schomburg], excludes: [scholar, sasb, lpa] }, general: { includes: [schomburg], excludes: [scholar, sasb, lpa] } }, - // nyplM1: { - // barcode: null, - // scholar: { includes: [sasb], excludes: [scholar, lpa, schomburg] }, - // general: { includes: [sasb], excludes: [scholar, lpa, schomburg] } - // }, + nyplM1: { + barcode: '33433084847221', + scholar: { includes: [sasb], excludes: [scholar, lpa, schomburg] }, + general: { includes: [sasb], excludes: [scholar, lpa, schomburg] } + }, nyplM2: { barcode: '33333069027734', scholar: { includes: [sasb, scholar], excludes: [lpa, schomburg] }, From 3aa92cd32e70effed78a390442e75267a1e8f570 Mon Sep 17 00:00:00 2001 From: Vera Kahn Date: Mon, 16 Mar 2026 15:32:56 -0400 Subject: [PATCH 08/10] add int test file --- .github/workflows/integration-tests.yml | 30 +++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/integration-tests.yml diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml new file mode 100644 index 00000000..f9d5f765 --- /dev/null +++ b/.github/workflows/integration-tests.yml @@ -0,0 +1,30 @@ +name: integration-test + +on: + pull_request: + branches: + - production + +jobs: + integration-test: + permissions: + id-token: write + contents: read + runs-on: ubuntu-latest + steps: + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v2 + with: + role-to-assume: arn:aws:iam::946183545209:role/GithubActionsDeployerRole + aws-region: us-east-1 + - uses: actions/checkout@v3 + - name: Set Node version + uses: actions/setup-node@v3 + with: + node-version-file: '.nvmrc' + - name: npm install + run: npm i + - name: Run integration tests + env: + ENV: 'qa' + run: node test/integration/delivery-locations-by-barcode.test.js From b62d8467b3c72929707e0bf000de2a98d0341096 Mon Sep 17 00:00:00 2001 From: Vera Kahn Date: Mon, 16 Mar 2026 15:42:38 -0400 Subject: [PATCH 09/10] rm commented code --- test/integration/delivery-locations-by-barcode.test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/integration/delivery-locations-by-barcode.test.js b/test/integration/delivery-locations-by-barcode.test.js index 9da42420..23245370 100644 --- a/test/integration/delivery-locations-by-barcode.test.js +++ b/test/integration/delivery-locations-by-barcode.test.js @@ -36,7 +36,6 @@ const checkLocationsForPtype = async (ptype) => { const getDeliveryLocations = async (barcode, patronId) => { try { - // const { data: { itemListElement: deliveryLocationsPerRecord } } = await axios.get(`https://${process.env === 'qa' ? 'qa-' : ''}platform.nypl.org/api/v0.1/request/deliveryLocationsByBarcode?barcodes[]=${barcode}&patronId=${patronId}`) const { itemListElement: itemData } = await makeNyplDataApiClient().get(`request/deliveryLocationsByBarcode?barcodes[]=${barcode}&patronId=${patronId}`) // per record return itemData[0] From 8f07bfca68f5a14e16f2f3be644b1e1aa1b3e39c Mon Sep 17 00:00:00 2001 From: Vera Kahn Date: Wed, 18 Mar 2026 10:44:56 -0400 Subject: [PATCH 10/10] test