]> juplo.de Git - demos/kafka/chat/commitdiff
test: Intorduced a pact for ChatroomService
authorKai Moritz <kai@juplo.de>
Sat, 4 Oct 2025 15:57:26 +0000 (17:57 +0200)
committerKai Moritz <kai@juplo.de>
Sat, 11 Oct 2025 12:45:12 +0000 (14:45 +0200)
jest.config.ts
package-lock.json
package.json
src/app/chatroom/chatroom.service.pact.spec.ts [new file with mode: 0644]
src/app/index.ts

index a9c1cc9682e70c92987358473e6b60c0ae35ff19..227f916f3831527bb82af4ce847e16442d2149ff 100644 (file)
@@ -16,6 +16,9 @@ export default {
         '^rxjs': '<rootDir>/node_modules/rxjs/dist/bundles/rxjs.umd.js',
     },
     setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'],
+    watchPathIgnorePatterns: [
+        '<rootDir>/dist/',
+    ],
     transform: {
         '^.+\\.(ts|js|html|svg)$': [
             'jest-preset-angular',
index 5f3d9cfdd878f8e0210290a3730c212ced394606..8302dca161a8950fcfdd7120817994f1e30fe20a 100644 (file)
         "zone.js": "~0.15.0"
       },
       "devDependencies": {
-        "@angular/build": "^20.0.0",
-        "@angular/cli": "^20.0.0",
-        "@angular/compiler-cli": "^20.0.0",
+        "@angular/build": "^20.3.4",
+        "@angular/cli": "^20.3.4",
+        "@angular/compiler-cli": "^20.3.0",
+        "@pact-foundation/pact": "^16.0.0",
         "@types/jasmine": "~5.1.0",
         "@types/jest": "^30.0.0",
         "esbuild-register": "^3.6.0",
         "node": "^18.17.0 || >=20.5.0"
       }
     },
+    "node_modules/@pact-foundation/pact": {
+      "version": "16.0.0",
+      "resolved": "https://registry.npmjs.org/@pact-foundation/pact/-/pact-16.0.0.tgz",
+      "integrity": "sha512-QPjvu40M0vX5L6boUIPZt8JGsA+eL6G48XTtDAUGKA9wlgIjShaVF4bdkDGZmex3WLb1aht4P5BG+DGguR7NZQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@pact-foundation/pact-core": "^17.0.0",
+        "axios": "^1.12.2",
+        "body-parser": "^2.2.0",
+        "chalk": "4.1.2",
+        "express": "^5.1.0",
+        "graphql": "^16.11.0",
+        "graphql-tag": "^2.12.6",
+        "http-proxy": "^1.18.1",
+        "https-proxy-agent": "^7.0.6",
+        "js-base64": "^3.7.8",
+        "lodash": "^4.17.21",
+        "ramda": "^0.31.3",
+        "randexp": "^0.5.3",
+        "router": "^2.2.0"
+      },
+      "engines": {
+        "node": ">=20"
+      }
+    },
+    "node_modules/@pact-foundation/pact-core": {
+      "version": "17.0.0",
+      "resolved": "https://registry.npmjs.org/@pact-foundation/pact-core/-/pact-core-17.0.0.tgz",
+      "integrity": "sha512-H6uGvjIgiT1vcGFhFwF0wCCbX9t3w5/d+Q3UGrHSw0/hOEQdGcETSeMUIheW9oCvm9qkxPBV5YkwUwmDIUXnYg==",
+      "cpu": [
+        "x64",
+        "ia32",
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "os": [
+        "darwin",
+        "linux",
+        "win32"
+      ],
+      "dependencies": {
+        "check-types": "11.2.3",
+        "detect-libc": "^2.0.3",
+        "node-gyp-build": "^4.6.0",
+        "pino": "^9.9.0",
+        "pino-pretty": "^13.1.1",
+        "underscore": "1.13.7"
+      },
+      "engines": {
+        "node": ">=20"
+      },
+      "optionalDependencies": {
+        "@pact-foundation/pact-core-darwin-arm64": "17.0.0",
+        "@pact-foundation/pact-core-darwin-x64": "17.0.0",
+        "@pact-foundation/pact-core-linux-arm64-glibc": "17.0.0",
+        "@pact-foundation/pact-core-linux-arm64-musl": "17.0.0",
+        "@pact-foundation/pact-core-linux-x64-glibc": "17.0.0",
+        "@pact-foundation/pact-core-linux-x64-musl": "17.0.0",
+        "@pact-foundation/pact-core-windows-x64": "17.0.0"
+      }
+    },
+    "node_modules/@pact-foundation/pact-core-darwin-arm64": {
+      "version": "17.0.0",
+      "resolved": "https://registry.npmjs.org/@pact-foundation/pact-core-darwin-arm64/-/pact-core-darwin-arm64-17.0.0.tgz",
+      "integrity": "sha512-OSAwR7O4Nk6rHYhon9KUyIJHJuLaJmSughire74KZu7YbM/F0nZhlxGEMN5yxRcKgbDGHtHDBkmsJ44omGsvdw==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ]
+    },
+    "node_modules/@pact-foundation/pact-core-darwin-x64": {
+      "version": "17.0.0",
+      "resolved": "https://registry.npmjs.org/@pact-foundation/pact-core-darwin-x64/-/pact-core-darwin-x64-17.0.0.tgz",
+      "integrity": "sha512-UHDgCkZPSeUZMracPysHAfMsUBWpah9zZJfwPvGUkjOjHvrnRGP0y98wP7PmbXiJxbxHqaaV7EHRsLjaFdS50A==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ]
+    },
+    "node_modules/@pact-foundation/pact-core-linux-arm64-glibc": {
+      "version": "17.0.0",
+      "resolved": "https://registry.npmjs.org/@pact-foundation/pact-core-linux-arm64-glibc/-/pact-core-linux-arm64-glibc-17.0.0.tgz",
+      "integrity": "sha512-akoL9agQklL8iGxqr4yI4X11ufjeYxEGvCtiXhDH2KFoB60MsyTOeD9SGfM90cQ/W/PjusOKHmSlz1hPWRX9Vw==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@pact-foundation/pact-core-linux-arm64-musl": {
+      "version": "17.0.0",
+      "resolved": "https://registry.npmjs.org/@pact-foundation/pact-core-linux-arm64-musl/-/pact-core-linux-arm64-musl-17.0.0.tgz",
+      "integrity": "sha512-kjDukgS7hjfb/PB68CHNCHBnG7kID3lLq3HirGp2vJ7RfqC8IOD18KTTSaHJoi48ofILx1M3Vb8zODFmxVB1pQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@pact-foundation/pact-core-linux-x64-glibc": {
+      "version": "17.0.0",
+      "resolved": "https://registry.npmjs.org/@pact-foundation/pact-core-linux-x64-glibc/-/pact-core-linux-x64-glibc-17.0.0.tgz",
+      "integrity": "sha512-AVYwU0KRmjBcHVgQz9n15D4R8BQSgK4ophzYHG9qC8DVmQ1zM3VEt/e8JcRPyd8OifK3OMJpcvvFeIRgh/s5uQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@pact-foundation/pact-core-linux-x64-musl": {
+      "version": "17.0.0",
+      "resolved": "https://registry.npmjs.org/@pact-foundation/pact-core-linux-x64-musl/-/pact-core-linux-x64-musl-17.0.0.tgz",
+      "integrity": "sha512-3969TiqWc6r6qwaX/faNoEDCowhFCIygf5jOECDUfHX9uysS9qqZP+O7qMfGT6t0E3FIUqKS9G1bMln5e68LTQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@pact-foundation/pact-core-windows-x64": {
+      "version": "17.0.0",
+      "resolved": "https://registry.npmjs.org/@pact-foundation/pact-core-windows-x64/-/pact-core-windows-x64-17.0.0.tgz",
+      "integrity": "sha512-Oa9S1YEfaSO5wmxFw+3F6Jbvgy0CH3Wn1qcm0tGx+7pAPNj5SOp0k0myF2OC+Xg0+iC5Q6DXfS666oNHgZlEVQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ]
+    },
     "node_modules/@parcel/watcher": {
       "version": "2.5.1",
       "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz",
         "sprintf-js": "~1.0.2"
       }
     },
+    "node_modules/asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/atomic-sleep": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz",
+      "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/axios": {
+      "version": "1.12.2",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz",
+      "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "follow-redirects": "^1.15.6",
+        "form-data": "^4.0.4",
+        "proxy-from-env": "^1.1.0"
+      }
+    },
     "node_modules/babel-jest": {
       "version": "30.2.0",
       "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.2.0.tgz",
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/check-types": {
+      "version": "11.2.3",
+      "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.2.3.tgz",
+      "integrity": "sha512-+67P1GkJRaxQD6PKK0Et9DhwQB+vGg3PM5+aavopCpZT1lj9jeqfvpgTLAWErNj8qApkkmXlu/Ug74kmhagkXg==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/chokidar": {
       "version": "4.0.3",
       "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "delayed-stream": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
     "node_modules/concat-map": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
         "node": ">=4.0"
       }
     },
+    "node_modules/dateformat": {
+      "version": "4.6.3",
+      "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz",
+      "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": "*"
+      }
+    },
     "node_modules/debug": {
       "version": "4.4.3",
       "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
         "node": ">=0.10.0"
       }
     },
+    "node_modules/delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
     "node_modules/depd": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
       "integrity": "sha512-ecqj/sy1jcK1uWrwpR67UhYrIFQ+5WlGxth34WquCbamhFA6hkkwiu37o6J5xCHdo1oixJRfVRw+ywV+Hq/0Aw==",
       "dev": true,
       "license": "Apache-2.0",
-      "optional": true,
       "engines": {
         "node": ">=8"
       }
         "url": "https://github.com/fb55/domutils?sponsor=1"
       }
     },
+    "node_modules/drange": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/drange/-/drange-1.1.1.tgz",
+      "integrity": "sha512-pYxfDYpued//QpnLIm4Avk7rsNtAtQkUES2cwAYSvD/wd2pKD71gN2Ebj3e7klzXwjocvE8c5vx/1fxwpqmSxA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=4"
+      }
+    },
     "node_modules/dunder-proto": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
         "node": ">=0.10.0"
       }
     },
+    "node_modules/end-of-stream": {
+      "version": "1.4.5",
+      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz",
+      "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "once": "^1.4.0"
+      }
+    },
     "node_modules/engine.io": {
       "version": "6.6.4",
       "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.4.tgz",
         "node": ">= 0.4"
       }
     },
+    "node_modules/es-set-tostringtag": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+      "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0",
+        "get-intrinsic": "^1.2.6",
+        "has-tostringtag": "^1.0.2",
+        "hasown": "^2.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
     "node_modules/esbuild": {
       "version": "0.25.10",
       "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.10.tgz",
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/fast-copy": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-3.0.2.tgz",
+      "integrity": "sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/fast-deep-equal": {
       "version": "3.1.3",
       "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/fast-safe-stringify": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
+      "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/fast-uri": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz",
         "url": "https://github.com/sponsors/isaacs"
       }
     },
+    "node_modules/form-data": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
+      "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.8",
+        "es-set-tostringtag": "^2.1.0",
+        "hasown": "^2.0.2",
+        "mime-types": "^2.1.12"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/form-data/node_modules/mime-db": {
+      "version": "1.52.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/form-data/node_modules/mime-types": {
+      "version": "2.1.35",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "mime-db": "1.52.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
     "node_modules/forwarded": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
       "dev": true,
       "license": "ISC"
     },
+    "node_modules/graphql": {
+      "version": "16.11.0",
+      "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.11.0.tgz",
+      "integrity": "sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0"
+      }
+    },
+    "node_modules/graphql-tag": {
+      "version": "2.12.6",
+      "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz",
+      "integrity": "sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "tslib": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "peerDependencies": {
+        "graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
+      }
+    },
     "node_modules/handlebars": {
       "version": "4.7.8",
       "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz",
         "node": ">= 0.4"
       }
     },
+    "node_modules/help-me": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz",
+      "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/hosted-git-info": {
       "version": "9.0.0",
       "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.0.tgz",
         "url": "https://github.com/chalk/supports-color?sponsor=1"
       }
     },
+    "node_modules/joycon": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz",
+      "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/js-base64": {
+      "version": "3.7.8",
+      "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.8.tgz",
+      "integrity": "sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==",
+      "dev": true,
+      "license": "BSD-3-Clause"
+    },
     "node_modules/js-tokens": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
         "node": "^18.17.0 || >=20.5.0"
       }
     },
+    "node_modules/node-gyp-build": {
+      "version": "4.8.4",
+      "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz",
+      "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==",
+      "dev": true,
+      "license": "MIT",
+      "bin": {
+        "node-gyp-build": "bin.js",
+        "node-gyp-build-optional": "optional.js",
+        "node-gyp-build-test": "build-test.js"
+      }
+    },
     "node_modules/node-gyp-build-optional-packages": {
       "version": "5.2.2",
       "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz",
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/on-exit-leak-free": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz",
+      "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=14.0.0"
+      }
+    },
     "node_modules/on-finished": {
       "version": "2.4.1",
       "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
         "node": ">=6"
       }
     },
+    "node_modules/pino": {
+      "version": "9.13.1",
+      "resolved": "https://registry.npmjs.org/pino/-/pino-9.13.1.tgz",
+      "integrity": "sha512-Szuj+ViDTjKPQYiKumGmEn3frdl+ZPSdosHyt9SnUevFosOkMY2b7ipxlEctNKPmMD/VibeBI+ZcZCJK+4DPuw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "atomic-sleep": "^1.0.0",
+        "on-exit-leak-free": "^2.1.0",
+        "pino-abstract-transport": "^2.0.0",
+        "pino-std-serializers": "^7.0.0",
+        "process-warning": "^5.0.0",
+        "quick-format-unescaped": "^4.0.3",
+        "real-require": "^0.2.0",
+        "safe-stable-stringify": "^2.3.1",
+        "slow-redact": "^0.3.0",
+        "sonic-boom": "^4.0.1",
+        "thread-stream": "^3.0.0"
+      },
+      "bin": {
+        "pino": "bin.js"
+      }
+    },
+    "node_modules/pino-abstract-transport": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-2.0.0.tgz",
+      "integrity": "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "split2": "^4.0.0"
+      }
+    },
+    "node_modules/pino-pretty": {
+      "version": "13.1.2",
+      "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-13.1.2.tgz",
+      "integrity": "sha512-3cN0tCakkT4f3zo9RXDIhy6GTvtYD6bK4CRBLN9j3E/ePqN1tugAXD5rGVfoChW6s0hiek+eyYlLNqc/BG7vBQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "colorette": "^2.0.7",
+        "dateformat": "^4.6.3",
+        "fast-copy": "^3.0.2",
+        "fast-safe-stringify": "^2.1.1",
+        "help-me": "^5.0.0",
+        "joycon": "^3.1.1",
+        "minimist": "^1.2.6",
+        "on-exit-leak-free": "^2.1.0",
+        "pino-abstract-transport": "^2.0.0",
+        "pump": "^3.0.0",
+        "secure-json-parse": "^4.0.0",
+        "sonic-boom": "^4.0.1",
+        "strip-json-comments": "^5.0.2"
+      },
+      "bin": {
+        "pino-pretty": "bin.js"
+      }
+    },
+    "node_modules/pino-pretty/node_modules/strip-json-comments": {
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.3.tgz",
+      "integrity": "sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=14.16"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/pino-std-serializers": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.0.0.tgz",
+      "integrity": "sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/pirates": {
       "version": "4.0.7",
       "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz",
         "node": "^18.17.0 || >=20.5.0"
       }
     },
+    "node_modules/process-warning": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-5.0.0.tgz",
+      "integrity": "sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/fastify"
+        },
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/fastify"
+        }
+      ],
+      "license": "MIT"
+    },
     "node_modules/promise-retry": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz",
         "node": ">= 0.10"
       }
     },
+    "node_modules/proxy-from-env": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/prr": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
       "license": "MIT",
       "optional": true
     },
+    "node_modules/pump": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz",
+      "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "end-of-stream": "^1.1.0",
+        "once": "^1.3.1"
+      }
+    },
     "node_modules/punycode": {
       "version": "1.4.1",
       "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/quick-format-unescaped": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz",
+      "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/ramda": {
+      "version": "0.31.3",
+      "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.31.3.tgz",
+      "integrity": "sha512-xKADKRNnqmDdX59PPKLm3gGmk1ZgNnj3k7DryqWwkamp4TJ6B36DdpyKEQ0EoEYmH2R62bV4Q+S0ym2z8N2f3Q==",
+      "dev": true,
+      "license": "MIT",
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/ramda"
+      }
+    },
+    "node_modules/randexp": {
+      "version": "0.5.3",
+      "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.5.3.tgz",
+      "integrity": "sha512-U+5l2KrcMNOUPYvazA3h5ekF80FHTUG+87SEAmHZmolh1M+i/WyTCxVzmi+tidIa1tM4BSe8g2Y/D3loWDjj+w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "drange": "^1.0.2",
+        "ret": "^0.2.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
     "node_modules/range-parser": {
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
         "url": "https://paulmillr.com/funding/"
       }
     },
+    "node_modules/real-require": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz",
+      "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 12.13.0"
+      }
+    },
     "node_modules/reflect-metadata": {
       "version": "0.2.2",
       "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz",
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/ret": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/ret/-/ret-0.2.2.tgz",
+      "integrity": "sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=4"
+      }
+    },
     "node_modules/retry": {
       "version": "0.12.0",
       "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/safe-stable-stringify": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz",
+      "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/safer-buffer": {
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
         "node": ">=v12.22.7"
       }
     },
+    "node_modules/secure-json-parse": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-4.1.0.tgz",
+      "integrity": "sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/fastify"
+        },
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/fastify"
+        }
+      ],
+      "license": "BSD-3-Clause"
+    },
     "node_modules/semver": {
       "version": "7.7.2",
       "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
         "url": "https://github.com/chalk/ansi-styles?sponsor=1"
       }
     },
+    "node_modules/slow-redact": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/slow-redact/-/slow-redact-0.3.1.tgz",
+      "integrity": "sha512-NvFvl1GuLZNW4U046Tfi8b26zXo8aBzgCAS2f7yVJR/fArN93mOqSA99cB9uITm92ajSz01bsu1K7SCVVjIMpQ==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/smart-buffer": {
       "version": "4.2.0",
       "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
         "node": ">= 14"
       }
     },
+    "node_modules/sonic-boom": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.2.0.tgz",
+      "integrity": "sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "atomic-sleep": "^1.0.0"
+      }
+    },
     "node_modules/source-map": {
       "version": "0.7.6",
       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz",
       "dev": true,
       "license": "CC0-1.0"
     },
+    "node_modules/split2": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
+      "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
+      "dev": true,
+      "license": "ISC",
+      "engines": {
+        "node": ">= 10.x"
+      }
+    },
     "node_modules/sprintf-js": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
         "node": "*"
       }
     },
+    "node_modules/thread-stream": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-3.1.0.tgz",
+      "integrity": "sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "real-require": "^0.2.0"
+      }
+    },
     "node_modules/tinyglobby": {
       "version": "0.2.14",
       "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz",
         "node": ">=0.8.0"
       }
     },
+    "node_modules/underscore": {
+      "version": "1.13.7",
+      "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.7.tgz",
+      "integrity": "sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/undici-types": {
       "version": "7.13.0",
       "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.13.0.tgz",
index 72f3e2844858b535966b95929e1b16013c65f849..d158893f31852c68da26b622e817d9391c805361 100644 (file)
@@ -6,7 +6,7 @@
     "start": "ng serve",
     "build": "ng build",
     "watch": "ng build --watch --configuration development",
-    "test": "node --experimental-vm-modules --no-warnings node_modules/jest/bin/jest.js --no-cache"
+    "test": "node --experimental-vm-modules --no-warnings node_modules/jest/bin/jest.js --watch"
   },
   "prettier": {
     "printWidth": 100,
@@ -37,6 +37,7 @@
     "@angular/build": "^20.3.4",
     "@angular/cli": "^20.3.4",
     "@angular/compiler-cli": "^20.3.0",
+    "@pact-foundation/pact": "^16.0.0",
     "@types/jasmine": "~5.1.0",
     "@types/jest": "^30.0.0",
     "esbuild-register": "^3.6.0",
diff --git a/src/app/chatroom/chatroom.service.pact.spec.ts b/src/app/chatroom/chatroom.service.pact.spec.ts
new file mode 100644 (file)
index 0000000..4fd4f11
--- /dev/null
@@ -0,0 +1,55 @@
+import { Matchers, Pact, SpecificationVersion } from '@pact-foundation/pact';
+import { TestBed } from '@angular/core/testing';
+import { provideHttpClient } from '@angular/common/http';
+import { lastValueFrom } from 'rxjs';
+import { ChatroomService } from './chatroom.service';
+import { Chatroom } from './chatroom.model';
+import { APP_PROPS } from '..';
+
+
+describe('Pact between the ChatroomService and the backend', () => {
+
+  const provider = new Pact({
+    consumer: 'frontend.ChatroomService',
+    provider: 'backend',
+    spec: SpecificationVersion.SPECIFICATION_VERSION_V4,
+    dir: 'dist/pacts',
+    logLevel: 'debug',
+  });
+
+
+  const EXAMPLE_CHATROOM: Chatroom = {
+    id: "1",
+    name: "foo",
+    shard: 7
+  };
+
+
+  it('a request for /list returns an HTTP 200 and a list of chatrooms, if some chatrooms are known', async () => {
+
+    await provider
+      .addInteraction()
+      .given('some chatrooms are known')
+      .uponReceiving('a request for /list')
+      .withRequest('GET', '/list')
+      .willRespondWith(200, (builder) => {
+        builder.headers({ 'Content-Type': 'application/json' });
+        builder.jsonBody(Matchers.eachLike(EXAMPLE_CHATROOM));
+      })
+      .executeTest(async (mockserver) => {
+        await TestBed.configureTestingModule({
+          providers: [
+            ChatroomService,
+            {provide: APP_PROPS, useValue: {backendUri: mockserver.url + '/'}},
+            provideHttpClient(),
+          ]
+        });
+
+        const service = TestBed.inject(ChatroomService);
+        const chatrooms = await lastValueFrom(service.getChatrooms());
+
+        expect(chatrooms).toContainEqual(EXAMPLE_CHATROOM);
+        return chatrooms;
+      });
+  });
+});
index 9e301f492861656463afef7aaf17daf93a9c75c3..3539455b556c69078f36d9c309baf11e87926f4a 100644 (file)
@@ -1,2 +1,3 @@
 export * from './app.config'
 export * from './app.component'
+export * from './app.tokens'